Added: LatencyTracker - Credits to Mike
This commit is contained in:
parent
7e68e1c4b6
commit
05af8c2160
2
Emulator/.idea/misc.xml
generated
2
Emulator/.idea/misc.xml
generated
@ -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>
|
@ -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);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -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());
|
||||||
|
@ -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;
|
||||||
|
}
|
||||||
|
}
|
@ -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;
|
||||||
}
|
}
|
||||||
|
@ -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());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user