Package limits

check if the code is working correctly
This commit is contained in:
OurLobanov 2024-06-18 00:07:49 +03:00
parent be4a8e6906
commit ea6dd5d4e5
4 changed files with 118 additions and 1 deletions

View file

@ -39,13 +39,26 @@ import org.geysermc.geyser.session.GeyserSession;
public class LoggingPacketHandler implements BedrockPacketHandler {
protected final GeyserImpl geyser;
protected final GeyserSession session;
protected final PacketCooldownManager cooldownHandler;
LoggingPacketHandler(GeyserImpl geyser, GeyserSession session) {
this.geyser = geyser;
this.session = session;
this.cooldownHandler = new PacketCooldownManager(session, 1000);
}
public boolean handleLimit(BedrockPacket packet) {
boolean safePacket = this.cooldownHandler.handle(packet);
if (!safePacket) {
session.disconnect("many Packets " + packet.getClass().getSimpleName());
}
return !safePacket;
}
PacketSignal defaultHandler(BedrockPacket packet) {
if (handleLimit(packet)) {
return PacketSignal.UNHANDLED;
}
geyser.getLogger().debug("Handled packet: " + packet.getClass().getSimpleName());
return PacketSignal.HANDLED;
}

View file

@ -0,0 +1,94 @@
package org.geysermc.geyser.network;
import lombok.Getter;
import lombok.Setter;
import org.cloudburstmc.protocol.bedrock.packet.*;
import org.geysermc.geyser.session.GeyserSession;
import java.util.HashMap;
import java.util.Map;
public class PacketCooldownManager {
private static final Map<String, CooldownSettings> PACKET_COOLDOWN_SETTINGS = new HashMap<>();
static {
setPacketCooldown(LoginPacket.class, -1, 2);
setPacketCooldown(TextPacket.class, 1000, 10);
setPacketCooldown(CommandRequestPacket.class, 1000, 10);
setPacketCooldown(ModalFormResponsePacket.class, 1000, 10);
}
private final GeyserSession session;
@Setter
private long cooldownMillisDebug;
private long expiryTimeMillisDebug;
public static void setPacketCooldown(Class<? extends BedrockPacket> packetClass, int cooldownMillis, int maxCount) {
PACKET_COOLDOWN_SETTINGS.put(packetClass.getSimpleName(), new CooldownSettings(cooldownMillis, maxCount));
}
private final Map<String, CooldownTracker> activeCooldowns = new HashMap<>();
private boolean isCooldownActive(String packetName) {
CooldownTracker tracker = activeCooldowns.get(packetName);
if (tracker != null && tracker.getCount() >= PACKET_COOLDOWN_SETTINGS.get(packetName).maxCount()) {
if (tracker.getExpiryTime() <= System.currentTimeMillis()) {
activeCooldowns.remove(packetName);
} else {
return true;
}
}
return false;
}
private void updateCooldown(String packetName, long cooldownMillis) {
activeCooldowns.computeIfAbsent(packetName, k -> new CooldownTracker());
CooldownTracker tracker = activeCooldowns.get(packetName);
tracker.incrementCount();
tracker.setExpiryTime(System.currentTimeMillis() + cooldownMillis);
}
public boolean handle(BedrockPacket packet) {
String packetName = packet.getClass().getSimpleName();
if (PACKET_COOLDOWN_SETTINGS.containsKey(packetName)) {
CooldownSettings settings = PACKET_COOLDOWN_SETTINGS.get(packetName);
updateCooldown(packetName, settings.cooldownMillis());
if (isCooldownActive(packetName)) {
if (expiryTimeMillisDebug <= System.currentTimeMillis()) {
CooldownTracker tracker = activeCooldowns.get(packetName);
String message = session.getSocketAddress().getAddress().toString() + " -> Attempted to send too many packets " + packet.getClass().getSimpleName() + "count " + tracker.getCount();
if (session.isLoggedIn()) {
message += " by user " + session.bedrockUsername();
}
session.getGeyser().getLogger().debug(message);
}
this.expiryTimeMillisDebug = System.currentTimeMillis() + cooldownMillisDebug;
return false;
}
}
return true;
}
public PacketCooldownManager(GeyserSession session, long cooldownMillisDebug) {
this.session = session;
this.setCooldownMillisDebug(cooldownMillisDebug);
this.expiryTimeMillisDebug = 0;
}
@Getter
private record CooldownSettings(int cooldownMillis, int maxCount) {
}
@Getter
private static class CooldownTracker {
private long count;
@Setter
private long expiryTime;
public void incrementCount() {
this.count++;
}
}
}

View file

@ -101,6 +101,9 @@ public class UpstreamPacketHandler extends LoggingPacketHandler {
@Override
PacketSignal defaultHandler(BedrockPacket packet) {
if (handleLimit(packet)) {
return PacketSignal.UNHANDLED;
}
return translateAndDefault(packet);
}
@ -169,6 +172,9 @@ public class UpstreamPacketHandler extends LoggingPacketHandler {
@Override
public PacketSignal handle(LoginPacket loginPacket) {
if(this.handleLimit(loginPacket)){
return PacketSignal.UNHANDLED;
}
if (geyser.isShuttingDown() || geyser.isReloading()) {
// Don't allow new players in if we're no longer operating
session.disconnect(GeyserLocale.getLocaleStringLog("geyser.core.shutdown.kick.message"));
@ -268,6 +274,9 @@ public class UpstreamPacketHandler extends LoggingPacketHandler {
@Override
public PacketSignal handle(ModalFormResponsePacket packet) {
if(this.handleLimit(packet)){
return PacketSignal.UNHANDLED;
}
session.executeInEventLoop(() -> session.getFormCache().handleResponse(packet));
return PacketSignal.HANDLED;
}

View file

@ -80,7 +80,6 @@ import org.geysermc.geyser.api.network.AuthType;
import org.geysermc.geyser.api.network.RemoteServer;
import org.geysermc.geyser.api.util.PlatformType;
import org.geysermc.geyser.command.GeyserCommandSource;
import org.geysermc.geyser.configuration.EmoteOffhandWorkaroundOption;
import org.geysermc.geyser.configuration.GeyserConfiguration;
import org.geysermc.geyser.entity.EntityDefinitions;
import org.geysermc.geyser.entity.GeyserEntityData;
@ -275,7 +274,9 @@ public class GeyserSession implements GeyserConnection, GeyserCommandSource {
// Exposed for GeyserConnect usage
protected boolean sentSpawnPacket;
@Getter
private boolean loggedIn;
@Getter
private boolean loggingIn;
@Setter