Added support for Ping packet

Added Ping to Networking fbs
Created Riiablo.ping long to store current ping in ms
Changed Client draw fps to draw Riiablo.ping below fps
Created Pinger system which manages Riiablo.ping and sending and receiving Ping packets
Riiablo.ping is really more like RTT+frame_time and should be ironed out better
Created issue #77 related to the work done in this commit and deficiencies to be addressed
This commit is contained in:
Collin Smith 2020-06-07 00:23:00 -07:00
parent da152ff5c6
commit cdc73e12d6
10 changed files with 143 additions and 15 deletions

View File

@ -11,20 +11,21 @@ public final class D2GSData {
public static final byte RunToEntity = 4;
public static final byte Connection = 5;
public static final byte Disconnect = 6;
public static final byte EntitySync = 7;
public static final byte GroundToCursor = 8;
public static final byte CursorToGround = 9;
public static final byte StoreToCursor = 10;
public static final byte CursorToStore = 11;
public static final byte SwapStoreItem = 12;
public static final byte BodyToCursor = 13;
public static final byte CursorToBody = 14;
public static final byte SwapBodyItem = 15;
public static final byte BeltToCursor = 16;
public static final byte CursorToBelt = 17;
public static final byte SwapBeltItem = 18;
public static final byte Ping = 7;
public static final byte EntitySync = 8;
public static final byte GroundToCursor = 9;
public static final byte CursorToGround = 10;
public static final byte StoreToCursor = 11;
public static final byte CursorToStore = 12;
public static final byte SwapStoreItem = 13;
public static final byte BodyToCursor = 14;
public static final byte CursorToBody = 15;
public static final byte SwapBodyItem = 16;
public static final byte BeltToCursor = 17;
public static final byte CursorToBelt = 18;
public static final byte SwapBeltItem = 19;
public static final String[] names = { "NONE", "WalkToLocation", "WalkToEntity", "RunToLocation", "RunToEntity", "Connection", "Disconnect", "EntitySync", "GroundToCursor", "CursorToGround", "StoreToCursor", "CursorToStore", "SwapStoreItem", "BodyToCursor", "CursorToBody", "SwapBodyItem", "BeltToCursor", "CursorToBelt", "SwapBeltItem", };
public static final String[] names = { "NONE", "WalkToLocation", "WalkToEntity", "RunToLocation", "RunToEntity", "Connection", "Disconnect", "Ping", "EntitySync", "GroundToCursor", "CursorToGround", "StoreToCursor", "CursorToStore", "SwapStoreItem", "BodyToCursor", "CursorToBody", "SwapBodyItem", "BeltToCursor", "CursorToBelt", "SwapBeltItem", };
public static String name(int e) { return names[e]; }
}

View File

@ -0,0 +1,37 @@
// automatically generated by the FlatBuffers compiler, do not modify
package com.riiablo.net.packet.d2gs;
import java.nio.*;
import java.lang.*;
import java.util.*;
import com.google.flatbuffers.*;
@SuppressWarnings("unused")
public final class Ping extends Table {
public static Ping getRootAsPing(ByteBuffer _bb) { return getRootAsPing(_bb, new Ping()); }
public static Ping getRootAsPing(ByteBuffer _bb, Ping obj) { _bb.order(ByteOrder.LITTLE_ENDIAN); return (obj.__assign(_bb.getInt(_bb.position()) + _bb.position(), _bb)); }
public void __init(int _i, ByteBuffer _bb) { bb_pos = _i; bb = _bb; vtable_start = bb_pos - bb.getInt(bb_pos); vtable_size = bb.getShort(vtable_start); }
public Ping __assign(int _i, ByteBuffer _bb) { __init(_i, _bb); return this; }
public int tickCount() { int o = __offset(4); return o != 0 ? bb.getInt(o + bb_pos) : 0; }
public long time() { int o = __offset(6); return o != 0 ? bb.getLong(o + bb_pos) : 0L; }
public static int createPing(FlatBufferBuilder builder,
int tickCount,
long time) {
builder.startObject(2);
Ping.addTime(builder, time);
Ping.addTickCount(builder, tickCount);
return Ping.endPing(builder);
}
public static void startPing(FlatBufferBuilder builder) { builder.startObject(2); }
public static void addTickCount(FlatBufferBuilder builder, int tickCount) { builder.addInt(0, tickCount, 0); }
public static void addTime(FlatBufferBuilder builder, long time) { builder.addLong(1, time, 0L); }
public static int endPing(FlatBufferBuilder builder) {
int o = builder.endObject();
return o;
}
}

View File

@ -441,7 +441,12 @@ public class Client extends Game {
BitmapFont font = console.getFont();
if (font == null) return;
fps.setText(font, Integer.toString(Gdx.graphics.getFramesPerSecond()));
StringBuilder builder = new StringBuilder(64);
builder
.append(Gdx.graphics.getFramesPerSecond())
.append('\n').append(Riiablo.ping).append(" ms")
;
fps.setText(font, builder.toString());
int drawFpsMethod = this.drawFpsMethod;
if (forceDrawFps && drawFpsMethod == FPS_NONE) {
drawFpsMethod = FPS_TOPLEFT;

View File

@ -67,4 +67,5 @@ public class Riiablo {
public static World engine;
public static GameScreen game;
public static D2 anim;
public static long ping;
}

View File

@ -54,6 +54,7 @@ import com.riiablo.net.packet.d2gs.EntitySync;
import com.riiablo.net.packet.d2gs.GroundToCursor;
import com.riiablo.net.packet.d2gs.ItemP;
import com.riiablo.net.packet.d2gs.MonsterP;
import com.riiablo.net.packet.d2gs.Ping;
import com.riiablo.net.packet.d2gs.PlayerP;
import com.riiablo.net.packet.d2gs.PositionP;
import com.riiablo.net.packet.d2gs.StoreToCursor;
@ -97,6 +98,7 @@ public class ClientNetworkReceiver extends IntervalSystem {
protected CofManager cofs;
protected NetworkIdManager syncIds;
protected ItemManager items;
protected Pinger pinger;
@Wire(name="client.socket")
protected Socket socket;
@ -150,6 +152,9 @@ public class ClientNetworkReceiver extends IntervalSystem {
case D2GSData.Disconnect:
Disconnect(packet);
break;
case D2GSData.Ping:
pinger.Ping((Ping) packet.data(new Ping()));
break;
case D2GSData.EntitySync:
Synchronize(packet);
break;

View File

@ -0,0 +1,59 @@
package com.riiablo.engine.client;
import com.google.flatbuffers.FlatBufferBuilder;
import com.artemis.annotations.All;
import com.artemis.annotations.Wire;
import com.artemis.systems.IntervalSystem;
import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.net.Socket;
import com.badlogic.gdx.utils.TimeUtils;
import com.riiablo.Riiablo;
import com.riiablo.net.packet.d2gs.D2GS;
import com.riiablo.net.packet.d2gs.D2GSData;
import com.riiablo.net.packet.d2gs.Ping;
import java.io.OutputStream;
import java.nio.channels.Channels;
import java.nio.channels.WritableByteChannel;
@All
public class Pinger extends IntervalSystem {
private static final String TAG = "Pinger";
private static final boolean DEBUG = !true;
@Wire(name = "client.socket")
protected Socket socket;
// TODO: this system depends on a 32-bit int -- at some point will need to figure out if this will become an issue
// it may be possible to use Gdx.graphics.getFrameId() -- but that isn't related to engine tick
private int tick;
// TODO: provide a running average of past N RTTs
// private final double deltas[] = new double[5];
// private int deltaCount;
public Pinger() {
super(null, 1.0f);
}
@Override
protected void processSystem() {
FlatBufferBuilder builder = new FlatBufferBuilder(0);
int dataOffset = Ping.createPing(builder, tick++, TimeUtils.millis());
int root = D2GS.createD2GS(builder, D2GSData.Ping, dataOffset);
D2GS.finishSizePrefixedD2GSBuffer(builder, root);
try {
OutputStream out = socket.getOutputStream();
WritableByteChannel channelOut = Channels.newChannel(out);
channelOut.write(builder.dataBuffer());
} catch (Throwable t) {
Gdx.app.error(TAG, t.getMessage(), t);
}
}
public void Ping(Ping packet) {
Riiablo.ping = TimeUtils.timeSinceMillis(packet.time());
}
}

View File

@ -12,6 +12,7 @@ union D2GSData {
RunToEntity,
Connection,
Disconnect,
Ping,
EntitySync,
GroundToCursor,
CursorToGround,

View File

@ -17,5 +17,13 @@ table Disconnect {
// request
entityId:int32;
// response
}
table Ping {
// request
tickCount:int32;
time:int64;
// response
}

View File

@ -2,9 +2,10 @@ package com.riiablo.screen;
import com.artemis.WorldConfigurationBuilder;
import com.badlogic.gdx.net.Socket;
import com.riiablo.save.CharData;
import com.riiablo.engine.client.ClientNetworkReceiver;
import com.riiablo.engine.client.ClientNetworkSyncronizer;
import com.riiablo.engine.client.Pinger;
import com.riiablo.save.CharData;
public class NetworkedGameScreen extends GameScreen {
private static final String TAG = "NetworkedGameScreen";
@ -22,6 +23,7 @@ public class NetworkedGameScreen extends GameScreen {
WorldConfigurationBuilder builder = super.getWorldConfigurationBuilder();
builder.with(WorldConfigurationBuilder.Priority.HIGH, new ClientNetworkReceiver());
builder.with(new ClientNetworkSyncronizer());
builder.with(new Pinger());
return builder;
}

View File

@ -427,6 +427,9 @@ public class D2GS extends ApplicationAdapter {
case D2GSData.SwapBeltItem:
SwapBeltItem(packet);
break;
case D2GSData.Ping:
Ping(packet);
break;
default:
Gdx.app.error(TAG, "Unknown packet type: " + packet.data.dataType());
}
@ -531,6 +534,12 @@ public class D2GS extends ApplicationAdapter {
}
}
private void Ping(Packet packet) {
// Ping ping = (Ping) packet.data.data(new Ping());
packet.id = (1 << packet.id);
outPackets.offer(packet);
}
private void Synchronize(Packet packet) {
int entityId = player.get(packet.id, Engine.INVALID_ENTITY);
assert entityId != Engine.INVALID_ENTITY;