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 {
|
public class LoggingPacketHandler implements BedrockPacketHandler {
|
||||||
protected final GeyserImpl geyser;
|
protected final GeyserImpl geyser;
|
||||||
protected final GeyserSession session;
|
protected final GeyserSession session;
|
||||||
|
protected final PacketCooldownManager cooldownHandler;
|
||||||
|
|
||||||
LoggingPacketHandler(GeyserImpl geyser, GeyserSession session) {
|
LoggingPacketHandler(GeyserImpl geyser, GeyserSession session) {
|
||||||
this.geyser = geyser;
|
this.geyser = geyser;
|
||||||
this.session = session;
|
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) {
|
PacketSignal defaultHandler(BedrockPacket packet) {
|
||||||
|
if (handleLimit(packet)) {
|
||||||
|
return PacketSignal.UNHANDLED;
|
||||||
|
}
|
||||||
geyser.getLogger().debug("Handled packet: " + packet.getClass().getSimpleName());
|
geyser.getLogger().debug("Handled packet: " + packet.getClass().getSimpleName());
|
||||||
return PacketSignal.HANDLED;
|
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
|
@Override
|
||||||
PacketSignal defaultHandler(BedrockPacket packet) {
|
PacketSignal defaultHandler(BedrockPacket packet) {
|
||||||
|
if (handleLimit(packet)) {
|
||||||
|
return PacketSignal.UNHANDLED;
|
||||||
|
}
|
||||||
return translateAndDefault(packet);
|
return translateAndDefault(packet);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -169,6 +172,9 @@ public class UpstreamPacketHandler extends LoggingPacketHandler {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public PacketSignal handle(LoginPacket loginPacket) {
|
public PacketSignal handle(LoginPacket loginPacket) {
|
||||||
|
if(this.handleLimit(loginPacket)){
|
||||||
|
return PacketSignal.UNHANDLED;
|
||||||
|
}
|
||||||
if (geyser.isShuttingDown() || geyser.isReloading()) {
|
if (geyser.isShuttingDown() || geyser.isReloading()) {
|
||||||
// Don't allow new players in if we're no longer operating
|
// Don't allow new players in if we're no longer operating
|
||||||
session.disconnect(GeyserLocale.getLocaleStringLog("geyser.core.shutdown.kick.message"));
|
session.disconnect(GeyserLocale.getLocaleStringLog("geyser.core.shutdown.kick.message"));
|
||||||
|
|
@ -268,6 +274,9 @@ public class UpstreamPacketHandler extends LoggingPacketHandler {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public PacketSignal handle(ModalFormResponsePacket packet) {
|
public PacketSignal handle(ModalFormResponsePacket packet) {
|
||||||
|
if(this.handleLimit(packet)){
|
||||||
|
return PacketSignal.UNHANDLED;
|
||||||
|
}
|
||||||
session.executeInEventLoop(() -> session.getFormCache().handleResponse(packet));
|
session.executeInEventLoop(() -> session.getFormCache().handleResponse(packet));
|
||||||
return PacketSignal.HANDLED;
|
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.network.RemoteServer;
|
||||||
import org.geysermc.geyser.api.util.PlatformType;
|
import org.geysermc.geyser.api.util.PlatformType;
|
||||||
import org.geysermc.geyser.command.GeyserCommandSource;
|
import org.geysermc.geyser.command.GeyserCommandSource;
|
||||||
import org.geysermc.geyser.configuration.EmoteOffhandWorkaroundOption;
|
|
||||||
import org.geysermc.geyser.configuration.GeyserConfiguration;
|
import org.geysermc.geyser.configuration.GeyserConfiguration;
|
||||||
import org.geysermc.geyser.entity.EntityDefinitions;
|
import org.geysermc.geyser.entity.EntityDefinitions;
|
||||||
import org.geysermc.geyser.entity.GeyserEntityData;
|
import org.geysermc.geyser.entity.GeyserEntityData;
|
||||||
|
|
@ -275,7 +274,9 @@ public class GeyserSession implements GeyserConnection, GeyserCommandSource {
|
||||||
// Exposed for GeyserConnect usage
|
// Exposed for GeyserConnect usage
|
||||||
protected boolean sentSpawnPacket;
|
protected boolean sentSpawnPacket;
|
||||||
|
|
||||||
|
@Getter
|
||||||
private boolean loggedIn;
|
private boolean loggedIn;
|
||||||
|
@Getter
|
||||||
private boolean loggingIn;
|
private boolean loggingIn;
|
||||||
|
|
||||||
@Setter
|
@Setter
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue