You've already forked Arcturus-Morningstar-Extended
mirror of
https://github.com/duckietm/Arcturus-Morningstar-Extended.git
synced 2026-06-20 23:36:19 +00:00
🆙 Added packet rate limit ==> 50 p/s & youtube fixes
This commit is contained in:
@@ -0,0 +1 @@
|
|||||||
|
INSERT INTO emulator_settings (`key`, `value`) VALUES ('packet.global.rate.limit', '50');
|
||||||
@@ -176,6 +176,8 @@ public class Room implements Comparable<Room>, ISerialize, Runnable {
|
|||||||
private RoomSpecialTypes roomSpecialTypes;
|
private RoomSpecialTypes roomSpecialTypes;
|
||||||
private TraxManager traxManager;
|
private TraxManager traxManager;
|
||||||
|
|
||||||
|
// YouTube room broadcast state: tracks the current video being broadcast
|
||||||
|
// by the room owner, the owner's playlist, and which users have the player open.
|
||||||
private String youtubeCurrentVideo = "";
|
private String youtubeCurrentVideo = "";
|
||||||
private String youtubeSenderName = "";
|
private String youtubeSenderName = "";
|
||||||
private final java.util.List<String> youtubePlaylist = new java.util.concurrent.CopyOnWriteArrayList<>();
|
private final java.util.List<String> youtubePlaylist = new java.util.concurrent.CopyOnWriteArrayList<>();
|
||||||
@@ -1797,13 +1799,21 @@ public class Room implements Comparable<Room>, ISerialize, Runnable {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void removeHabbo(Habbo habbo) {
|
public void removeHabbo(Habbo habbo) {
|
||||||
|
this.cleanupYoutubeWatcher(habbo);
|
||||||
this.unitManager.removeHabbo(habbo);
|
this.unitManager.removeHabbo(habbo);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void removeHabbo(Habbo habbo, boolean sendRemovePacket) {
|
public void removeHabbo(Habbo habbo, boolean sendRemovePacket) {
|
||||||
|
this.cleanupYoutubeWatcher(habbo);
|
||||||
this.unitManager.removeHabbo(habbo, sendRemovePacket);
|
this.unitManager.removeHabbo(habbo, sendRemovePacket);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void cleanupYoutubeWatcher(Habbo habbo) {
|
||||||
|
if (habbo != null && this.youtubeWatchers.remove(habbo.getHabboInfo().getId())) {
|
||||||
|
this.sendComposer(new com.eu.habbo.messages.outgoing.rooms.youtube.YouTubeRoomWatchersComposer(this.youtubeWatchers).compose());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public void addBot(Bot bot) {
|
public void addBot(Bot bot) {
|
||||||
this.unitManager.addBot(bot);
|
this.unitManager.addBot(bot);
|
||||||
}
|
}
|
||||||
|
|||||||
+33
-8
@@ -9,6 +9,17 @@ import java.util.ArrayList;
|
|||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
public class YouTubeRoomPlayEvent extends MessageHandler {
|
public class YouTubeRoomPlayEvent extends MessageHandler {
|
||||||
|
|
||||||
|
private static final int MAX_VIDEO_ID_LENGTH = 100;
|
||||||
|
private static final int MAX_PLAYLIST_ITEM_LENGTH = 200;
|
||||||
|
private static final int MAX_PLAYLIST_SIZE = 50;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getRatelimit() {
|
||||||
|
// Max 1 broadcast every 2 seconds per client
|
||||||
|
return 2000;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void handle() throws Exception {
|
public void handle() throws Exception {
|
||||||
Habbo habbo = this.client.getHabbo();
|
Habbo habbo = this.client.getHabbo();
|
||||||
@@ -21,17 +32,31 @@ public class YouTubeRoomPlayEvent extends MessageHandler {
|
|||||||
if (!room.isOwner(habbo) && !room.hasRights(habbo)) return;
|
if (!room.isOwner(habbo) && !room.hasRights(habbo)) return;
|
||||||
|
|
||||||
String videoId = this.packet.readString();
|
String videoId = this.packet.readString();
|
||||||
|
if (videoId.length() > MAX_VIDEO_ID_LENGTH) {
|
||||||
int playlistCount = this.packet.readInt();
|
videoId = videoId.substring(0, MAX_VIDEO_ID_LENGTH);
|
||||||
List<String> playlist = new ArrayList<>();
|
|
||||||
for (int i = 0; i < playlistCount && i < 50; i++) {
|
|
||||||
playlist.add(this.packet.readString());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Store the current video + playlist on the room
|
int playlistCount = this.packet.readInt();
|
||||||
room.setYoutubeVideo(videoId, habbo.getHabboInfo().getUsername(), playlist);
|
if (playlistCount > MAX_PLAYLIST_SIZE) playlistCount = MAX_PLAYLIST_SIZE;
|
||||||
|
if (playlistCount < 0) playlistCount = 0;
|
||||||
|
|
||||||
// Broadcast to everyone in the room
|
List<String> playlist = new ArrayList<>();
|
||||||
|
for (int i = 0; i < playlistCount; i++) {
|
||||||
|
String item = this.packet.readString();
|
||||||
|
if (item.length() > MAX_PLAYLIST_ITEM_LENGTH) {
|
||||||
|
item = item.substring(0, MAX_PLAYLIST_ITEM_LENGTH);
|
||||||
|
}
|
||||||
|
playlist.add(item);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Store the current video + playlist on the room, or clear if empty
|
||||||
|
if (videoId.isEmpty()) {
|
||||||
|
room.clearYoutubeVideo();
|
||||||
|
} else {
|
||||||
|
room.setYoutubeVideo(videoId, habbo.getHabboInfo().getUsername(), playlist);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Broadcast to everyone in the room (empty videoId = stop)
|
||||||
room.sendComposer(
|
room.sendComposer(
|
||||||
new YouTubeRoomBroadcastComposer(videoId, habbo.getHabboInfo().getUsername(), playlist).compose()
|
new YouTubeRoomBroadcastComposer(videoId, habbo.getHabboInfo().getUsername(), playlist).compose()
|
||||||
);
|
);
|
||||||
|
|||||||
+12
-3
@@ -6,6 +6,12 @@ import com.eu.habbo.messages.incoming.MessageHandler;
|
|||||||
import com.eu.habbo.messages.outgoing.rooms.youtube.YouTubeRoomWatchersComposer;
|
import com.eu.habbo.messages.outgoing.rooms.youtube.YouTubeRoomWatchersComposer;
|
||||||
|
|
||||||
public class YouTubeRoomWatchingEvent extends MessageHandler {
|
public class YouTubeRoomWatchingEvent extends MessageHandler {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getRatelimit() {
|
||||||
|
return 500;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void handle() throws Exception {
|
public void handle() throws Exception {
|
||||||
Habbo habbo = this.client.getHabbo();
|
Habbo habbo = this.client.getHabbo();
|
||||||
@@ -14,17 +20,20 @@ public class YouTubeRoomWatchingEvent extends MessageHandler {
|
|||||||
Room room = habbo.getHabboInfo().getCurrentRoom();
|
Room room = habbo.getHabboInfo().getCurrentRoom();
|
||||||
if (room == null) return;
|
if (room == null) return;
|
||||||
|
|
||||||
boolean watching = this.packet.readBoolean();
|
boolean watching = this.packet.readInt() == 1;
|
||||||
int userId = habbo.getHabboInfo().getId();
|
int userId = habbo.getHabboInfo().getId();
|
||||||
|
|
||||||
|
boolean changed;
|
||||||
if (watching) {
|
if (watching) {
|
||||||
room.getYoutubeWatchers().add(userId);
|
changed = room.getYoutubeWatchers().add(userId);
|
||||||
} else {
|
} else {
|
||||||
room.getYoutubeWatchers().remove(userId);
|
changed = room.getYoutubeWatchers().remove(userId);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (changed) {
|
||||||
room.sendComposer(
|
room.sendComposer(
|
||||||
new YouTubeRoomWatchersComposer(room.getYoutubeWatchers()).compose()
|
new YouTubeRoomWatchersComposer(room.getYoutubeWatchers()).compose()
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+20
-5
@@ -6,13 +6,18 @@ import com.eu.habbo.messages.ClientMessage;
|
|||||||
import com.eu.habbo.networking.gameserver.GameServerAttributes;
|
import com.eu.habbo.networking.gameserver.GameServerAttributes;
|
||||||
import io.netty.channel.ChannelHandlerContext;
|
import io.netty.channel.ChannelHandlerContext;
|
||||||
import io.netty.handler.codec.MessageToMessageDecoder;
|
import io.netty.handler.codec.MessageToMessageDecoder;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
public class GameMessageRateLimit extends MessageToMessageDecoder<ClientMessage> {
|
public class GameMessageRateLimit extends MessageToMessageDecoder<ClientMessage> {
|
||||||
|
|
||||||
|
private static final Logger LOGGER = LoggerFactory.getLogger(GameMessageRateLimit.class);
|
||||||
|
|
||||||
private static final int RESET_TIME = 1;
|
private static final int RESET_TIME = 1;
|
||||||
private static final int MAX_COUNTER = 10;
|
private static final int MAX_COUNTER = 10;
|
||||||
|
private static final int DEFAULT_GLOBAL_MAX = 50;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void decode(ChannelHandlerContext ctx, ClientMessage message, List<Object> out) throws Exception {
|
protected void decode(ChannelHandlerContext ctx, ClientMessage message, List<Object> out) throws Exception {
|
||||||
@@ -23,26 +28,36 @@ public class GameMessageRateLimit extends MessageToMessageDecoder<ClientMessage>
|
|||||||
}
|
}
|
||||||
|
|
||||||
int count = 0;
|
int count = 0;
|
||||||
|
int globalCount = 0;
|
||||||
|
|
||||||
// Check if reset time has passed.
|
|
||||||
int timestamp = Emulator.getIntUnixTimestamp();
|
int timestamp = Emulator.getIntUnixTimestamp();
|
||||||
if (timestamp - client.lastPacketCounterCleared > RESET_TIME) {
|
if (timestamp - client.lastPacketCounterCleared > RESET_TIME) {
|
||||||
// Reset counter.
|
|
||||||
client.incomingPacketCounter.clear();
|
client.incomingPacketCounter.clear();
|
||||||
client.lastPacketCounterCleared = timestamp;
|
client.lastPacketCounterCleared = timestamp;
|
||||||
} else {
|
} else {
|
||||||
// Get stored count for message id.
|
|
||||||
count = client.incomingPacketCounter.getOrDefault(message.getMessageId(), 0);
|
count = client.incomingPacketCounter.getOrDefault(message.getMessageId(), 0);
|
||||||
|
for (int c : client.incomingPacketCounter.values()) {
|
||||||
|
globalCount += c;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// If we exceeded the counter, drop the packet.
|
|
||||||
if (count > MAX_COUNTER) {
|
if (count > MAX_COUNTER) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int globalMax = Emulator.getConfig().getInt("packet.global.rate.limit", DEFAULT_GLOBAL_MAX);
|
||||||
|
if (globalCount > globalMax) {
|
||||||
|
if (globalCount == globalMax + 1) {
|
||||||
|
String username = (client.getHabbo() != null && client.getHabbo().getHabboInfo() != null)
|
||||||
|
? client.getHabbo().getHabboInfo().getUsername() : "unauthenticated";
|
||||||
|
LOGGER.warn("Global packet rate limit exceeded for {} ({} packets/sec) — dropping excess packets",
|
||||||
|
username, globalCount);
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
client.incomingPacketCounter.put(message.getMessageId(), ++count);
|
client.incomingPacketCounter.put(message.getMessageId(), ++count);
|
||||||
|
|
||||||
// Continue processing.
|
|
||||||
out.add(message);
|
out.add(message);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user