mirror of
https://github.com/GeyserMC/Geyser.git
synced 2024-08-14 23:57:35 +00:00
Package limits
check if the code is working correctly
This commit is contained in:
parent
be4a8e6906
commit
ea6dd5d4e5
4 changed files with 118 additions and 1 deletions
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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++;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue