Added: LatencyTracker - Credits to Mike

This commit is contained in:
duckietm 2024-04-08 13:41:42 +02:00
parent 7e68e1c4b6
commit 05af8c2160
6 changed files with 100 additions and 10 deletions

View File

@ -8,5 +8,5 @@
</list> </list>
</option> </option>
</component> </component>
<component name="ProjectRootManager" version="2" project-jdk-name="openjdk-21" project-jdk-type="JavaSDK" /> <component name="ProjectRootManager" version="2" languageLevel="JDK_X" default="true" project-jdk-name="19" project-jdk-type="JavaSDK" />
</project> </project>

View File

@ -0,0 +1,47 @@
package com.eu.habbo.habbohotel;
import com.eu.habbo.habbohotel.gameclients.GameClient;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.concurrent.TimeUnit;
public class LatencyTracker {
private static final Logger LOGGER = LoggerFactory.getLogger(GameClient.class);
private boolean initialPing;
private long last;
private long average;
public LatencyTracker() {
this.initialPing = true;
this.average = 0;
}
public void update(long latencyInNano) {
this.last = latencyInNano;
if (this.initialPing) {
this.initialPing = false;
this.average = latencyInNano;
return;
}
this.average = (long) (this.average * .7f + latencyInNano * .3f);
}
public boolean hasInitialized() {
return !this.initialPing;
}
public long getLastMs() {
return TimeUnit.NANOSECONDS.toMillis(this.last);
}
public long getAverageMs() {
return TimeUnit.NANOSECONDS.toMillis(this.average);
}
}

View File

@ -230,6 +230,7 @@ public class CommandHandler {
addCommand(new MutePetsCommand()); addCommand(new MutePetsCommand());
addCommand(new PetInfoCommand()); addCommand(new PetInfoCommand());
addCommand(new PickallCommand()); addCommand(new PickallCommand());
addCommand(new PingCommand());
addCommand(new PixelCommand()); addCommand(new PixelCommand());
addCommand(new PluginsCommand()); addCommand(new PluginsCommand());
addCommand(new PointsCommand()); addCommand(new PointsCommand());

View File

@ -0,0 +1,29 @@
package com.eu.habbo.habbohotel.commands;
import com.eu.habbo.habbohotel.LatencyTracker;
import com.eu.habbo.habbohotel.gameclients.GameClient;
public class PingCommand extends Command {
public PingCommand() {
super(null, new String[]{"ping"});
}
@Override
public boolean handle(GameClient gameClient, String[] params) throws Exception {
if (gameClient.getHabbo().getRoomUnit() == null) {
return true;
}
final LatencyTracker latencyTracker = gameClient.getLatencyTracker();
if (latencyTracker.hasInitialized()) {
gameClient.getHabbo().whisper(String.format("Average ping %dms, last ping %dms",
latencyTracker.getAverageMs(),
latencyTracker.getLastMs()));
} else {
gameClient.getHabbo().whisper("\n" + "Ping speed has not been calculated yet, please try again in a minute.");
}
return true;
}
}

View File

@ -2,6 +2,7 @@ package com.eu.habbo.habbohotel.gameclients;
import com.eu.habbo.Emulator; import com.eu.habbo.Emulator;
import com.eu.habbo.crypto.HabboEncryption; import com.eu.habbo.crypto.HabboEncryption;
import com.eu.habbo.habbohotel.LatencyTracker;
import com.eu.habbo.habbohotel.users.Habbo; import com.eu.habbo.habbohotel.users.Habbo;
import com.eu.habbo.messages.ServerMessage; import com.eu.habbo.messages.ServerMessage;
import com.eu.habbo.messages.incoming.MessageHandler; import com.eu.habbo.messages.incoming.MessageHandler;
@ -10,9 +11,6 @@ import io.netty.channel.Channel;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentHashMap;
@ -22,7 +20,7 @@ public class GameClient {
private final Channel channel; private final Channel channel;
private final HabboEncryption encryption; private final HabboEncryption encryption;
private final LatencyTracker latencyTracker;
private Habbo habbo; private Habbo habbo;
private boolean handshakeFinished; private boolean handshakeFinished;
private String machineId = ""; private String machineId = "";
@ -39,6 +37,7 @@ public class GameClient {
Emulator.getCrypto().getModulus(), Emulator.getCrypto().getModulus(),
Emulator.getCrypto().getPrivateExponent()) Emulator.getCrypto().getPrivateExponent())
: null; : null;
this.latencyTracker = new LatencyTracker();
} }
public Channel getChannel() { public Channel getChannel() {
@ -49,6 +48,8 @@ public class GameClient {
return encryption; return encryption;
} }
public LatencyTracker getLatencyTracker() { return latencyTracker; }
public Habbo getHabbo() { public Habbo getHabbo() {
return this.habbo; return this.habbo;
} }

View File

@ -18,7 +18,9 @@ public class IdleTimeoutHandler extends ChannelDuplexHandler {
private final long pongTimeoutNanos; private final long pongTimeoutNanos;
volatile ScheduledFuture<?> pingScheduleFuture; volatile ScheduledFuture<?> pingScheduleFuture;
volatile long lastPongTime;// in nanoseconds volatile boolean sentPing;
volatile long lastPingTime; // in nanoseconds
volatile long lastPongTime; // in nanoseconds
private volatile int state; // 0 - none, 1 - initialized, 2 - destroyed private volatile int state; // 0 - none, 1 - initialized, 2 - destroyed
@ -97,10 +99,18 @@ public class IdleTimeoutHandler extends ChannelDuplexHandler {
@Override @Override
public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception { public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
// check if its a pong message // check if its a pong message
if(msg instanceof ClientMessage) { if (msg instanceof ClientMessage) {
ClientMessage packet = (ClientMessage) msg; ClientMessage packet = (ClientMessage) msg;
if(packet.getMessageId() == Incoming.PongEvent) { if (packet.getMessageId() == Incoming.PongEvent) {
this.lastPongTime = System.nanoTime(); this.lastPongTime = System.nanoTime();
final GameClient client = ctx.channel().attr(GameServerAttributes.CLIENT).get();
if (client != null) {
if (sentPing) {
sentPing = false;
client.getLatencyTracker().update(lastPongTime - lastPingTime);
}
}
} }
} }
super.channelRead(ctx, msg); super.channelRead(ctx, msg);
@ -120,13 +130,15 @@ public class IdleTimeoutHandler extends ChannelDuplexHandler {
} }
long currentTime = System.nanoTime(); long currentTime = System.nanoTime();
if(currentTime - lastPongTime > pongTimeoutNanos) { if (currentTime - lastPongTime > pongTimeoutNanos) {
ctx.close();// add a promise here ? ctx.close();// add a promise here ?
return; return;
} }
GameClient client = ctx.channel().attr(GameServerAttributes.CLIENT).get(); final GameClient client = ctx.channel().attr(GameServerAttributes.CLIENT).get();
if (client != null) { if (client != null) {
lastPingTime = System.nanoTime();
sentPing = true;
client.sendResponse(new PingComposer()); client.sendResponse(new PingComposer());
} }