From 0ebb303e0cc987575291902e88b1e8cf82982fe4 Mon Sep 17 00:00:00 2001 From: DuckieTM Date: Sun, 29 Mar 2026 16:04:52 +0200 Subject: [PATCH] =?UTF-8?q?=F0=9F=86=99=20Small=20security=20fix=20Forum?= =?UTF-8?q?=20Groups=20&=20better=20cache?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit GuildChangeSettingsEvent 2000ms - Write GuildForumPostThreadEvent 2000ms - Write ModerateMessage/Thread 2000ms - Write ThreadUpdate 2000ms -Write UpdateSettings 2000ms- Write MarkAsRead 2000ms - Write Data/List/Threads/Messages - 500ms Read-only --- .../guilds/GuildChangeSettingsEvent.java | 41 ++++++++++++++----- .../forums/GuildForumMarkAsReadEvent.java | 2 +- .../GuildForumModerateMessageEvent.java | 2 +- .../forums/GuildForumModerateThreadEvent.java | 2 +- .../forums/GuildForumPostThreadEvent.java | 2 +- .../forums/GuildForumThreadUpdateEvent.java | 2 +- .../guilds/forums/GuildForumThreadsEvent.java | 2 +- .../forums/GuildForumUpdateSettingsEvent.java | 2 +- 8 files changed, 38 insertions(+), 17 deletions(-) diff --git a/Emulator/src/main/java/com/eu/habbo/messages/incoming/guilds/GuildChangeSettingsEvent.java b/Emulator/src/main/java/com/eu/habbo/messages/incoming/guilds/GuildChangeSettingsEvent.java index d46de9f2..5ad35f21 100644 --- a/Emulator/src/main/java/com/eu/habbo/messages/incoming/guilds/GuildChangeSettingsEvent.java +++ b/Emulator/src/main/java/com/eu/habbo/messages/incoming/guilds/GuildChangeSettingsEvent.java @@ -2,12 +2,14 @@ package com.eu.habbo.messages.incoming.guilds; import com.eu.habbo.Emulator; import com.eu.habbo.habbohotel.guilds.Guild; +import com.eu.habbo.habbohotel.guilds.GuildMember; import com.eu.habbo.habbohotel.guilds.GuildState; import com.eu.habbo.habbohotel.permissions.Permission; import com.eu.habbo.habbohotel.rooms.Room; import com.eu.habbo.messages.incoming.MessageHandler; import com.eu.habbo.habbohotel.guilds.forums.ForumThread; import com.eu.habbo.messages.incoming.guilds.forums.GuildForumListEvent; +import com.eu.habbo.messages.outgoing.guilds.GuildInfoComposer; import com.eu.habbo.messages.outgoing.guilds.forums.GuildForumDataComposer; import com.eu.habbo.plugin.events.guilds.GuildChangedSettingsEvent; import org.slf4j.Logger; @@ -16,13 +18,18 @@ import org.slf4j.LoggerFactory; import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.SQLException; +import java.util.concurrent.ConcurrentHashMap; public class GuildChangeSettingsEvent extends MessageHandler { private static final Logger LOGGER = LoggerFactory.getLogger(GuildChangeSettingsEvent.class); + // Cooldown for forum toggle per guild: guildId -> last toggle timestamp + private static final ConcurrentHashMap forumToggleCooldown = new ConcurrentHashMap<>(); + private static final long FORUM_TOGGLE_COOLDOWN_MS = 30_000; // 30 seconds + @Override public int getRatelimit() { - return 500; + return 2000; // 2 seconds between settings saves } @Override @@ -47,17 +54,27 @@ public class GuildChangeSettingsEvent extends MessageHandler { boolean wasForumEnabled = guild.hasForum(); if (forumEnabled != wasForumEnabled) { - guild.setForum(forumEnabled); + // Enforce cooldown on forum toggle to prevent rapid enable/disable spam + Long lastToggle = forumToggleCooldown.get(guildId); + long now = System.currentTimeMillis(); - if (!forumEnabled) { - // Delete all threads and comments for this guild - ForumThread.clearCacheForGuild(guildId); - deleteForumData(guildId); + if (lastToggle != null && (now - lastToggle) < FORUM_TOGGLE_COOLDOWN_MS) { + LOGGER.warn("Forum toggle cooldown for guild {} by user {}", guildId, this.client.getHabbo().getHabboInfo().getUsername()); + } else { + forumToggleCooldown.put(guildId, now); + guild.setForum(forumEnabled); + + if (!forumEnabled) { + // Delete all threads and comments for this guild + ForumThread.clearCacheForGuild(guildId); + deleteForumData(guildId); + } + + // Invalidate caches + GuildForumDataComposer.invalidateUnreadCache(guildId); + GuildForumListEvent.invalidateActiveForumsCache(); + GuildForumListEvent.invalidateMyForumsCache(this.client.getHabbo().getHabboInfo().getId()); } - - // Invalidate caches - GuildForumDataComposer.invalidateUnreadCache(guildId); - GuildForumListEvent.invalidateActiveForumsCache(); } Room room = Emulator.getGameEnvironment().getRoomManager().getRoom(guild.getRoomId()); @@ -68,6 +85,10 @@ public class GuildChangeSettingsEvent extends MessageHandler { guild.needsUpdate = true; Emulator.getThreading().run(guild); + + // Send updated group info back to client so hasForum flag refreshes immediately + GuildMember member = Emulator.getGameEnvironment().getGuildManager().getGuildMember(guild, this.client.getHabbo()); + this.client.sendResponse(new GuildInfoComposer(guild, this.client, false, member)); } } } diff --git a/Emulator/src/main/java/com/eu/habbo/messages/incoming/guilds/forums/GuildForumMarkAsReadEvent.java b/Emulator/src/main/java/com/eu/habbo/messages/incoming/guilds/forums/GuildForumMarkAsReadEvent.java index 0ea0f49d..ace83232 100644 --- a/Emulator/src/main/java/com/eu/habbo/messages/incoming/guilds/forums/GuildForumMarkAsReadEvent.java +++ b/Emulator/src/main/java/com/eu/habbo/messages/incoming/guilds/forums/GuildForumMarkAsReadEvent.java @@ -15,7 +15,7 @@ public class GuildForumMarkAsReadEvent extends MessageHandler { @Override public int getRatelimit() { - return 500; + return 2000; } @Override diff --git a/Emulator/src/main/java/com/eu/habbo/messages/incoming/guilds/forums/GuildForumModerateMessageEvent.java b/Emulator/src/main/java/com/eu/habbo/messages/incoming/guilds/forums/GuildForumModerateMessageEvent.java index 6851d0fd..51b9ec0b 100644 --- a/Emulator/src/main/java/com/eu/habbo/messages/incoming/guilds/forums/GuildForumModerateMessageEvent.java +++ b/Emulator/src/main/java/com/eu/habbo/messages/incoming/guilds/forums/GuildForumModerateMessageEvent.java @@ -18,7 +18,7 @@ import com.eu.habbo.messages.outgoing.handshake.ConnectionErrorComposer; public class GuildForumModerateMessageEvent extends MessageHandler { @Override public int getRatelimit() { - return 500; + return 2000; } @Override diff --git a/Emulator/src/main/java/com/eu/habbo/messages/incoming/guilds/forums/GuildForumModerateThreadEvent.java b/Emulator/src/main/java/com/eu/habbo/messages/incoming/guilds/forums/GuildForumModerateThreadEvent.java index c5021046..3fa8905b 100644 --- a/Emulator/src/main/java/com/eu/habbo/messages/incoming/guilds/forums/GuildForumModerateThreadEvent.java +++ b/Emulator/src/main/java/com/eu/habbo/messages/incoming/guilds/forums/GuildForumModerateThreadEvent.java @@ -27,7 +27,7 @@ public class GuildForumModerateThreadEvent extends MessageHandler { @Override public int getRatelimit() { - return 500; + return 2000; } @Override diff --git a/Emulator/src/main/java/com/eu/habbo/messages/incoming/guilds/forums/GuildForumPostThreadEvent.java b/Emulator/src/main/java/com/eu/habbo/messages/incoming/guilds/forums/GuildForumPostThreadEvent.java index e5d213ac..ae021b5c 100644 --- a/Emulator/src/main/java/com/eu/habbo/messages/incoming/guilds/forums/GuildForumPostThreadEvent.java +++ b/Emulator/src/main/java/com/eu/habbo/messages/incoming/guilds/forums/GuildForumPostThreadEvent.java @@ -18,7 +18,7 @@ public class GuildForumPostThreadEvent extends MessageHandler { @Override public int getRatelimit() { - return 1000; + return 2000; } @Override diff --git a/Emulator/src/main/java/com/eu/habbo/messages/incoming/guilds/forums/GuildForumThreadUpdateEvent.java b/Emulator/src/main/java/com/eu/habbo/messages/incoming/guilds/forums/GuildForumThreadUpdateEvent.java index 908ff2a0..741a818f 100644 --- a/Emulator/src/main/java/com/eu/habbo/messages/incoming/guilds/forums/GuildForumThreadUpdateEvent.java +++ b/Emulator/src/main/java/com/eu/habbo/messages/incoming/guilds/forums/GuildForumThreadUpdateEvent.java @@ -17,7 +17,7 @@ import com.eu.habbo.messages.outgoing.handshake.ConnectionErrorComposer; public class GuildForumThreadUpdateEvent extends MessageHandler { @Override public int getRatelimit() { - return 500; + return 2000; } @Override diff --git a/Emulator/src/main/java/com/eu/habbo/messages/incoming/guilds/forums/GuildForumThreadsEvent.java b/Emulator/src/main/java/com/eu/habbo/messages/incoming/guilds/forums/GuildForumThreadsEvent.java index 009a2cee..3672a62a 100644 --- a/Emulator/src/main/java/com/eu/habbo/messages/incoming/guilds/forums/GuildForumThreadsEvent.java +++ b/Emulator/src/main/java/com/eu/habbo/messages/incoming/guilds/forums/GuildForumThreadsEvent.java @@ -20,7 +20,7 @@ public class GuildForumThreadsEvent extends MessageHandler { Guild guild = Emulator.getGameEnvironment().getGuildManager().getGuild(guildId); - if (guild == null || !guild.hasForum()) { + if (guild == null) { this.client.sendResponse(new ConnectionErrorComposer(404)); return; } diff --git a/Emulator/src/main/java/com/eu/habbo/messages/incoming/guilds/forums/GuildForumUpdateSettingsEvent.java b/Emulator/src/main/java/com/eu/habbo/messages/incoming/guilds/forums/GuildForumUpdateSettingsEvent.java index 91a46b09..11916a7b 100644 --- a/Emulator/src/main/java/com/eu/habbo/messages/incoming/guilds/forums/GuildForumUpdateSettingsEvent.java +++ b/Emulator/src/main/java/com/eu/habbo/messages/incoming/guilds/forums/GuildForumUpdateSettingsEvent.java @@ -12,7 +12,7 @@ import com.eu.habbo.messages.outgoing.handshake.ConnectionErrorComposer; public class GuildForumUpdateSettingsEvent extends MessageHandler { @Override public int getRatelimit() { - return 500; + return 2000; } @Override