🆙 Fix Catalog Edit

This commit is contained in:
duckietm
2026-05-21 17:01:56 +02:00
parent d321ff3b85
commit 9126396973
4 changed files with 122 additions and 10 deletions
@@ -36,8 +36,21 @@ public class CatalogAdminCreatePageEvent extends MessageHandler {
pageLayout = CatalogPageLayouts.default_3x3; pageLayout = CatalogPageLayouts.default_3x3;
} }
if (parentId != -1 && Emulator.getGameEnvironment().getCatalogManager().getCatalogPage(parentId) == null) {
this.client.sendResponse(new CatalogAdminResultComposer(false, "Parent page not found: " + parentId));
return;
}
if (iconType < 0) iconType = 0;
if (minRank < 1) minRank = 1;
if (orderNum < 0) orderNum = 0;
if (caption == null) caption = "";
if (caption2 == null) caption2 = "";
if (caption.length() > 128) caption = caption.substring(0, 128);
if (caption2.length() > 25) caption2 = caption2.substring(0, 25);
CatalogPage page = Emulator.getGameEnvironment().getCatalogManager().createCatalogPage( CatalogPage page = Emulator.getGameEnvironment().getCatalogManager().createCatalogPage(
caption, caption2, 0, iconType, pageLayout, minRank, parentId, pageType, catalogMode caption, caption2, 0, iconType, pageLayout, minRank, parentId, pageType, catalogMode
); );
if (page == null) { if (page == null) {
@@ -1,6 +1,7 @@
package com.eu.habbo.messages.incoming.catalog.catalogadmin; package com.eu.habbo.messages.incoming.catalog.catalogadmin;
import com.eu.habbo.Emulator; import com.eu.habbo.Emulator;
import com.eu.habbo.habbohotel.catalog.CatalogPage;
import com.eu.habbo.habbohotel.catalog.CatalogPageType; import com.eu.habbo.habbohotel.catalog.CatalogPageType;
import com.eu.habbo.habbohotel.permissions.Permission; import com.eu.habbo.habbohotel.permissions.Permission;
import com.eu.habbo.messages.incoming.MessageHandler; import com.eu.habbo.messages.incoming.MessageHandler;
@@ -11,6 +12,9 @@ import java.sql.PreparedStatement;
public class CatalogAdminMovePageEvent extends MessageHandler { public class CatalogAdminMovePageEvent extends MessageHandler {
private static final int MAX_PARENT_WALK = 64;
private static final int ROOT_PARENT_ID = -1;
@Override @Override
public void handle() throws Exception { public void handle() throws Exception {
if (!this.client.getHabbo().hasPermission(Permission.ACC_CATALOGFURNI)) { if (!this.client.getHabbo().hasPermission(Permission.ACC_CATALOGFURNI)) {
@@ -24,12 +28,10 @@ public class CatalogAdminMovePageEvent extends MessageHandler {
CatalogPageType pageType = CatalogPageType.fromString(this.packet.readString()); CatalogPageType pageType = CatalogPageType.fromString(this.packet.readString());
String tableName = (pageType == CatalogPageType.BUILDER) ? "catalog_pages_bc" : "catalog_pages"; String tableName = (pageType == CatalogPageType.BUILDER) ? "catalog_pages_bc" : "catalog_pages";
// Special values: -1 = toggle enabled, -2 = toggle visible
if (newParentId == -1) { if (newParentId == -1) {
// Toggle enabled
try (Connection connection = Emulator.getDatabase().getDataSource().getConnection(); try (Connection connection = Emulator.getDatabase().getDataSource().getConnection();
PreparedStatement statement = connection.prepareStatement( PreparedStatement statement = connection.prepareStatement(
"UPDATE " + tableName + " SET enabled = IF(enabled = '1', '0', '1') WHERE id = ?")) { "UPDATE " + tableName + " SET enabled = IF(enabled = '1', '0', '1') WHERE id = ?")) {
statement.setInt(1, pageId); statement.setInt(1, pageId);
statement.execute(); statement.execute();
} }
@@ -38,21 +40,43 @@ public class CatalogAdminMovePageEvent extends MessageHandler {
} }
if (newParentId == -2) { if (newParentId == -2) {
// Toggle visible
try (Connection connection = Emulator.getDatabase().getDataSource().getConnection(); try (Connection connection = Emulator.getDatabase().getDataSource().getConnection();
PreparedStatement statement = connection.prepareStatement( PreparedStatement statement = connection.prepareStatement(
"UPDATE " + tableName + " SET visible = IF(visible = '1', '0', '1') WHERE id = ?")) { "UPDATE " + tableName + " SET visible = IF(visible = '1', '0', '1') WHERE id = ?")) {
statement.setInt(1, pageId); statement.setInt(1, pageId);
statement.execute(); statement.execute();
} }
this.client.sendResponse(new CatalogAdminResultComposer(true, "Visibility toggled")); this.client.sendResponse(new CatalogAdminResultComposer(true, "Visibility toggled"));
return; return;
} }
CatalogPage page = Emulator.getGameEnvironment().getCatalogManager().getCatalogPage(pageId, pageType);
if (page == null) {
this.client.sendResponse(new CatalogAdminResultComposer(false, "Page not found: " + pageId));
return;
}
if (newParentId == pageId) {
this.client.sendResponse(new CatalogAdminResultComposer(false, "A page cannot be its own parent"));
return;
}
CatalogPage parent = Emulator.getGameEnvironment().getCatalogManager().getCatalogPage(newParentId);
if (parent == null) {
this.client.sendResponse(new CatalogAdminResultComposer(false, "Parent page not found: " + newParentId));
return;
}
if (this.wouldCreateCycle(pageId, newParentId)) {
this.client.sendResponse(new CatalogAdminResultComposer(false, "Refusing to move: that would create a cycle"));
return;
}
if (newIndex < 0) newIndex = 0;
// Normal move: update parent and order
try (Connection connection = Emulator.getDatabase().getDataSource().getConnection(); try (Connection connection = Emulator.getDatabase().getDataSource().getConnection();
PreparedStatement statement = connection.prepareStatement( PreparedStatement statement = connection.prepareStatement(
"UPDATE " + tableName + " SET parent_id = ?, order_num = ? WHERE id = ?")) { "UPDATE " + tableName + " SET parent_id = ?, order_num = ? WHERE id = ?")) {
statement.setInt(1, newParentId); statement.setInt(1, newParentId);
statement.setInt(2, newIndex); statement.setInt(2, newIndex);
statement.setInt(3, pageId); statement.setInt(3, pageId);
@@ -61,4 +85,16 @@ public class CatalogAdminMovePageEvent extends MessageHandler {
this.client.sendResponse(new CatalogAdminResultComposer(true, "Page moved")); this.client.sendResponse(new CatalogAdminResultComposer(true, "Page moved"));
} }
private boolean wouldCreateCycle(int pageId, int parentId) {
int current = parentId;
for (int hops = 0; hops < MAX_PARENT_WALK; hops++) {
if (current == ROOT_PARENT_ID) return false;
if (current == pageId) return true;
CatalogPage parent = Emulator.getGameEnvironment().getCatalogManager().getCatalogPage(current);
if (parent == null) return false;
current = parent.getParentId();
}
return true;
}
} }
@@ -2,6 +2,7 @@ package com.eu.habbo.messages.incoming.catalog.catalogadmin;
import com.eu.habbo.Emulator; import com.eu.habbo.Emulator;
import com.eu.habbo.habbohotel.catalog.CatalogPage; import com.eu.habbo.habbohotel.catalog.CatalogPage;
import com.eu.habbo.habbohotel.catalog.CatalogPageLayouts;
import com.eu.habbo.habbohotel.catalog.CatalogPageType; import com.eu.habbo.habbohotel.catalog.CatalogPageType;
import com.eu.habbo.habbohotel.permissions.Permission; import com.eu.habbo.habbohotel.permissions.Permission;
import com.eu.habbo.messages.incoming.MessageHandler; import com.eu.habbo.messages.incoming.MessageHandler;
@@ -12,6 +13,14 @@ import java.sql.PreparedStatement;
public class CatalogAdminSavePageEvent extends MessageHandler { public class CatalogAdminSavePageEvent extends MessageHandler {
private static final int MAX_CAPTION_LENGTH = 128;
private static final int MAX_CAPTION_SAVE_LENGTH = 25;
private static final int MAX_HEADLINE_LENGTH = 1024;
private static final int MAX_TEASER_LENGTH = 64;
private static final int MAX_TEXT_LENGTH = 8192;
private static final int MAX_PARENT_WALK = 64;
private static final int ROOT_PARENT_ID = -1;
@Override @Override
public void handle() throws Exception { public void handle() throws Exception {
if (!this.client.getHabbo().hasPermission(Permission.ACC_CATALOGFURNI)) { if (!this.client.getHabbo().hasPermission(Permission.ACC_CATALOGFURNI)) {
@@ -34,7 +43,6 @@ public class CatalogAdminSavePageEvent extends MessageHandler {
String textDetails = this.packet.readString(); String textDetails = this.packet.readString();
CatalogPageType pageType = CatalogPageType.fromString(this.packet.readString()); CatalogPageType pageType = CatalogPageType.fromString(this.packet.readString());
CatalogPageType catalogMode = CatalogPageType.fromString(this.packet.readString()); CatalogPageType catalogMode = CatalogPageType.fromString(this.packet.readString());
CatalogPage page = Emulator.getGameEnvironment().getCatalogManager().getCatalogPage(pageId, pageType); CatalogPage page = Emulator.getGameEnvironment().getCatalogManager().getCatalogPage(pageId, pageType);
if (page == null) { if (page == null) {
@@ -42,6 +50,41 @@ public class CatalogAdminSavePageEvent extends MessageHandler {
return; return;
} }
try {
CatalogPageLayouts.valueOf(layout);
} catch (IllegalArgumentException | NullPointerException e) {
this.client.sendResponse(new CatalogAdminResultComposer(false, "Invalid layout: " + layout));
return;
}
if (parentId != ROOT_PARENT_ID) {
if (parentId == pageId) {
this.client.sendResponse(new CatalogAdminResultComposer(false, "A page cannot be its own parent"));
return;
}
CatalogPage parent = Emulator.getGameEnvironment().getCatalogManager().getCatalogPage(parentId);
if (parent == null) {
this.client.sendResponse(new CatalogAdminResultComposer(false, "Parent page not found: " + parentId));
return;
}
if (this.wouldCreateCycle(pageId, parentId)) {
this.client.sendResponse(new CatalogAdminResultComposer(false, "Refusing to re-parent: that would create a cycle"));
return;
}
}
if (iconType < 0) iconType = 0;
if (minRank < 1) minRank = 1;
if (orderNum < 0) orderNum = 0;
caption = this.clampLength(caption, MAX_CAPTION_LENGTH);
caption2 = this.clampLength(caption2, MAX_CAPTION_SAVE_LENGTH);
headline = this.clampLength(headline, MAX_HEADLINE_LENGTH);
teaser = this.clampLength(teaser, MAX_TEASER_LENGTH);
textDetails = this.clampLength(textDetails, MAX_TEXT_LENGTH);
String query = (pageType == CatalogPageType.BUILDER) String query = (pageType == CatalogPageType.BUILDER)
? "UPDATE catalog_pages_bc SET caption = ?, page_layout = ?, icon_image = ?, visible = ?, enabled = ?, order_num = ?, parent_id = ?, page_headline = ?, page_teaser = ?, page_text_details = ? WHERE id = ?" ? "UPDATE catalog_pages_bc SET caption = ?, page_layout = ?, icon_image = ?, visible = ?, enabled = ?, order_num = ?, parent_id = ?, page_headline = ?, page_teaser = ?, page_text_details = ? WHERE id = ?"
: "UPDATE catalog_pages SET caption = ?, caption_save = ?, page_layout = ?, icon_image = ?, min_rank = ?, visible = ?, enabled = ?, order_num = ?, parent_id = ?, page_headline = ?, page_teaser = ?, page_text_details = ?, catalog_mode = ? WHERE id = ?"; : "UPDATE catalog_pages SET caption = ?, caption_save = ?, page_layout = ?, icon_image = ?, min_rank = ?, visible = ?, enabled = ?, order_num = ?, parent_id = ?, page_headline = ?, page_teaser = ?, page_text_details = ?, catalog_mode = ? WHERE id = ?";
@@ -82,4 +125,22 @@ public class CatalogAdminSavePageEvent extends MessageHandler {
this.client.sendResponse(new CatalogAdminResultComposer(true, "Page saved")); this.client.sendResponse(new CatalogAdminResultComposer(true, "Page saved"));
} }
private boolean wouldCreateCycle(int pageId, int parentId) {
int current = parentId;
for (int hops = 0; hops < MAX_PARENT_WALK; hops++) {
if (current == ROOT_PARENT_ID) return false;
if (current == pageId) return true;
CatalogPage parent = Emulator.getGameEnvironment().getCatalogManager().getCatalogPage(current);
if (parent == null) return false;
current = parent.getParentId();
}
return true;
}
private String clampLength(String value, int max) {
if (value == null) return "";
if (value.length() <= max) return value;
return value.substring(0, max);
}
} }
@@ -41,6 +41,7 @@ public class CatalogPagesListComposer extends MessageComposer {
this.response.appendBoolean(true); this.response.appendBoolean(true);
this.response.appendInt(0); this.response.appendInt(0);
this.response.appendInt(-1); this.response.appendInt(-1);
this.response.appendInt(-1);
this.response.appendString("root"); this.response.appendString("root");
this.response.appendString(""); this.response.appendString("");
this.response.appendInt(0); this.response.appendInt(0);
@@ -68,7 +69,8 @@ public class CatalogPagesListComposer extends MessageComposer {
this.response.appendBoolean(category.isVisible()); this.response.appendBoolean(category.isVisible());
this.response.appendInt(category.getIconImage()); this.response.appendInt(category.getIconImage());
this.response.appendInt(category.isEnabled() ? category.getId() : -1); this.response.appendInt(category.isEnabled() || this.hasPermission ? category.getId() : -1);
this.response.appendInt(category.getParentId());
this.response.appendString(category.getPageName()); this.response.appendString(category.getPageName());
this.response.appendString(category.getCaption() + (this.hasPermission ? " (" + category.getId() + ")" : "")); this.response.appendString(category.getCaption() + (this.hasPermission ? " (" + category.getId() + ")" : ""));