mirror of
https://github.com/collinsmith/riiablo.git
synced 2025-03-03 22:21:53 +07:00
Added networking support for monster entities
Added networking support for dynamic object entities Fixed issues with multiple packets in stream by prepending packet size Fixed connection protocol for clients to wait until response received Created Box2DDisposer system to destroy box2d bodies when an entity has Box2DBody removed Created EntitySystemAdapter to simplify systems which are aspect event based (insert, removed, etc) Removed Entity reference from Connection and changed to entity id instead Renamed transform and alpha flag variables to tFlags and aFlags to remain consistent with elsewhere Added DS1ObjectWrapperP to network DS1 objects (DS1 object reference is needed only for server-side/host)
This commit is contained in:
parent
6b729c4350
commit
b8a5049adb
38
core/gen/com/riiablo/net/packet/d2gs/DS1ObjectWrapperP.java
Normal file
38
core/gen/com/riiablo/net/packet/d2gs/DS1ObjectWrapperP.java
Normal file
@ -0,0 +1,38 @@
|
||||
// automatically generated by the FlatBuffers compiler, do not modify
|
||||
|
||||
package com.riiablo.net.packet.d2gs;
|
||||
|
||||
import com.google.flatbuffers.FlatBufferBuilder;
|
||||
import com.google.flatbuffers.Table;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.ByteOrder;
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
public final class DS1ObjectWrapperP extends Table {
|
||||
public static DS1ObjectWrapperP getRootAsDS1ObjectWrapperP(ByteBuffer _bb) { return getRootAsDS1ObjectWrapperP(_bb, new DS1ObjectWrapperP()); }
|
||||
public static DS1ObjectWrapperP getRootAsDS1ObjectWrapperP(ByteBuffer _bb, DS1ObjectWrapperP 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 DS1ObjectWrapperP __assign(int _i, ByteBuffer _bb) { __init(_i, _bb); return this; }
|
||||
|
||||
public int act() { int o = __offset(4); return o != 0 ? bb.get(o + bb_pos) & 0xFF : 0; }
|
||||
public int id() { int o = __offset(6); return o != 0 ? bb.get(o + bb_pos) & 0xFF : 0; }
|
||||
|
||||
public static int createDS1ObjectWrapperP(FlatBufferBuilder builder,
|
||||
int act,
|
||||
int id) {
|
||||
builder.startObject(2);
|
||||
DS1ObjectWrapperP.addId(builder, id);
|
||||
DS1ObjectWrapperP.addAct(builder, act);
|
||||
return DS1ObjectWrapperP.endDS1ObjectWrapperP(builder);
|
||||
}
|
||||
|
||||
public static void startDS1ObjectWrapperP(FlatBufferBuilder builder) { builder.startObject(2); }
|
||||
public static void addAct(FlatBufferBuilder builder, int act) { builder.addByte(0, (byte)act, (byte)0); }
|
||||
public static void addId(FlatBufferBuilder builder, int id) { builder.addByte(1, (byte)id, (byte)0); }
|
||||
public static int endDS1ObjectWrapperP(FlatBufferBuilder builder) {
|
||||
int o = builder.endObject();
|
||||
return o;
|
||||
}
|
||||
}
|
||||
|
@ -13,8 +13,9 @@ public final class SyncData {
|
||||
public static final byte VelocityP = 6;
|
||||
public static final byte AngleP = 7;
|
||||
public static final byte PlayerP = 8;
|
||||
public static final byte DS1ObjectWrapperP = 9;
|
||||
|
||||
public static final String[] names = { "NONE", "ClassP", "CofComponentsP", "CofTransformsP", "CofAlphasP", "PositionP", "VelocityP", "AngleP", "PlayerP", };
|
||||
public static final String[] names = { "NONE", "ClassP", "CofComponentsP", "CofTransformsP", "CofAlphasP", "PositionP", "VelocityP", "AngleP", "PlayerP", "DS1ObjectWrapperP", };
|
||||
|
||||
public static String name(int e) { return names[e]; }
|
||||
}
|
||||
|
7
core/src/com/riiablo/engine/EntitySystemAdapter.java
Normal file
7
core/src/com/riiablo/engine/EntitySystemAdapter.java
Normal file
@ -0,0 +1,7 @@
|
||||
package com.riiablo.engine;
|
||||
|
||||
import com.artemis.BaseEntitySystem;
|
||||
|
||||
public class EntitySystemAdapter extends BaseEntitySystem {
|
||||
@Override protected void processSystem() {}
|
||||
}
|
@ -1,5 +1,7 @@
|
||||
package com.riiablo.engine.client;
|
||||
|
||||
import com.google.flatbuffers.ByteBufferUtil;
|
||||
|
||||
import com.artemis.ComponentMapper;
|
||||
import com.artemis.annotations.All;
|
||||
import com.artemis.annotations.Wire;
|
||||
@ -21,6 +23,7 @@ import com.riiablo.engine.server.component.Box2DBody;
|
||||
import com.riiablo.engine.server.component.Class;
|
||||
import com.riiablo.engine.server.component.CofAlphas;
|
||||
import com.riiablo.engine.server.component.CofComponents;
|
||||
import com.riiablo.engine.server.component.CofReference;
|
||||
import com.riiablo.engine.server.component.CofTransforms;
|
||||
import com.riiablo.engine.server.component.Player;
|
||||
import com.riiablo.engine.server.component.Position;
|
||||
@ -47,6 +50,7 @@ import com.riiablo.widget.TextArea;
|
||||
|
||||
import java.io.InputStream;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.ByteOrder;
|
||||
import java.nio.channels.Channels;
|
||||
import java.nio.channels.ReadableByteChannel;
|
||||
import java.util.Arrays;
|
||||
@ -54,8 +58,12 @@ import java.util.Arrays;
|
||||
@All
|
||||
public class ClientNetworkReceiver extends IntervalSystem {
|
||||
private static final String TAG = "ClientNetworkReceiver";
|
||||
private static final boolean DEBUG = true;
|
||||
private static final boolean DEBUG_PACKET = DEBUG && !true;
|
||||
private static final boolean DEBUG_SYNC = DEBUG && !true;
|
||||
|
||||
// protected ComponentMapper<Networked> mNetworked;
|
||||
protected ComponentMapper<CofReference> mCofReference;
|
||||
protected ComponentMapper<CofComponents> mCofComponents;
|
||||
protected ComponentMapper<CofTransforms> mCofTransforms;
|
||||
protected ComponentMapper<CofAlphas> mCofAlphas;
|
||||
@ -80,7 +88,7 @@ public class ClientNetworkReceiver extends IntervalSystem {
|
||||
@Wire(name = "output")
|
||||
protected TextArea output;
|
||||
|
||||
private final ByteBuffer buffer = ByteBuffer.allocate(8192);
|
||||
private final ByteBuffer buffer = ByteBuffer.allocate(1 << 20).order(ByteOrder.LITTLE_ENDIAN);
|
||||
|
||||
public ClientNetworkReceiver() {
|
||||
super(null, 1 / 60f);
|
||||
@ -90,14 +98,21 @@ public class ClientNetworkReceiver extends IntervalSystem {
|
||||
protected void processSystem() {
|
||||
InputStream in = socket.getInputStream();
|
||||
try {
|
||||
while (in.available() > 0) {
|
||||
if (in.available() > 0) {
|
||||
ReadableByteChannel channel = Channels.newChannel(in);
|
||||
buffer.clear();
|
||||
channel.read(buffer);
|
||||
buffer.limit(buffer.position()).rewind();
|
||||
D2GS packet = D2GS.getRootAsD2GS(buffer);
|
||||
System.out.println("packet type " + D2GSData.name(packet.dataType()));
|
||||
process(packet);
|
||||
int i = channel.read(buffer);
|
||||
buffer.rewind().limit(i);
|
||||
D2GS d2gs = new D2GS();
|
||||
int p = 0;
|
||||
while (buffer.hasRemaining()) {
|
||||
int size = ByteBufferUtil.getSizePrefix(buffer);
|
||||
D2GS.getRootAsD2GS(ByteBufferUtil.removeSizePrefix(buffer), d2gs);
|
||||
if (DEBUG_PACKET) Gdx.app.debug(TAG, p++ + " packet type " + D2GSData.name(d2gs.dataType()) + ":" + size + "B");
|
||||
process(d2gs);
|
||||
// System.out.println(buffer.position() + "->" + (buffer.position() + size + 4));
|
||||
buffer.position(buffer.position() + size + 4);
|
||||
}
|
||||
}
|
||||
} catch (Throwable t) {
|
||||
Gdx.app.error(TAG, t.getMessage(), t);
|
||||
@ -145,8 +160,6 @@ public class ClientNetworkReceiver extends IntervalSystem {
|
||||
|
||||
int alphaFlags = Dirty.NONE;
|
||||
int transformFlags = Dirty.NONE;
|
||||
cofs.setMode(entityId, Engine.Player.MODE_TN);
|
||||
cofs.setWClass(entityId, Engine.WEAPON_1HS); // TODO...
|
||||
for (int i = 0; i < 16; i++) {
|
||||
cofs.setComponent(entityId, i, connection.cofComponents(i));
|
||||
}
|
||||
@ -158,6 +171,7 @@ public class ClientNetworkReceiver extends IntervalSystem {
|
||||
cofs.updateAlpha(entityId, alphaFlags);
|
||||
cofs.updateTransform(entityId, transformFlags);
|
||||
cofs.setMode(entityId, Engine.Player.MODE_TN, true);
|
||||
cofs.setWClass(entityId, Engine.WEAPON_1HS); // TODO...
|
||||
|
||||
System.out.println(" " + DebugUtils.toByteArray(ArrayUtils.toByteArray(component)));
|
||||
System.out.println(" " + Arrays.toString(alpha));
|
||||
@ -176,6 +190,8 @@ public class ClientNetworkReceiver extends IntervalSystem {
|
||||
output.appendText("\n");
|
||||
|
||||
world.delete(entityId);
|
||||
Body body = mBox2DBody.get(entityId).body;
|
||||
if (body != null) ;
|
||||
}
|
||||
|
||||
private int findType(Sync s) {
|
||||
@ -259,9 +275,9 @@ public class ClientNetworkReceiver extends IntervalSystem {
|
||||
syncIds.put(sync.entityId(), entityId = createEntity(sync));
|
||||
}
|
||||
|
||||
int flags1 = Dirty.NONE;
|
||||
int flags2 = Dirty.NONE;
|
||||
Gdx.app.log(TAG, "syncing " + entityId);
|
||||
int tFlags = Dirty.NONE;
|
||||
int aFlags = Dirty.NONE;
|
||||
if (DEBUG_SYNC) Gdx.app.debug(TAG, "syncing " + entityId);
|
||||
for (int i = 0, len = sync.dataTypeLength(); i < len; i++) {
|
||||
switch (sync.dataType(i)) {
|
||||
case SyncData.ClassP:
|
||||
@ -278,14 +294,14 @@ public class ClientNetworkReceiver extends IntervalSystem {
|
||||
case SyncData.CofTransformsP: {
|
||||
CofTransformsP data = (CofTransformsP) sync.data(new CofTransformsP(), i);
|
||||
for (int j = 0, s0 = data.transformLength(); j < s0; j++) {
|
||||
flags1 |= cofs.setTransform(entityId, j, (byte) data.transform(j));
|
||||
tFlags |= cofs.setTransform(entityId, j, (byte) data.transform(j));
|
||||
}
|
||||
break;
|
||||
}
|
||||
case SyncData.CofAlphasP: {
|
||||
CofAlphasP data = (CofAlphasP) sync.data(new CofAlphasP(), i);
|
||||
for (int j = 0, s0 = data.alphaLength(); j < s0; j++) {
|
||||
flags2 |= cofs.setAlpha(entityId, j, data.alpha(j));
|
||||
aFlags |= cofs.setAlpha(entityId, j, data.alpha(j));
|
||||
}
|
||||
break;
|
||||
}
|
||||
@ -294,8 +310,10 @@ public class ClientNetworkReceiver extends IntervalSystem {
|
||||
PositionP data = (PositionP) sync.data(new PositionP(), i);
|
||||
position.x = data.x();
|
||||
position.y = data.y();
|
||||
Body body = mBox2DBody.get(entityId).body;
|
||||
if (body != null) body.setTransform(position, body.getAngle());
|
||||
if (mBox2DBody.has(entityId)) {
|
||||
Body body = mBox2DBody.get(entityId).body;
|
||||
if (body != null) body.setTransform(position, body.getAngle());
|
||||
}
|
||||
//Gdx.app.log(TAG, " " + position);
|
||||
break;
|
||||
}
|
||||
@ -320,7 +338,7 @@ public class ClientNetworkReceiver extends IntervalSystem {
|
||||
}
|
||||
}
|
||||
|
||||
cofs.updateTransform(entityId, flags1);
|
||||
cofs.updateAlpha(entityId, flags2);
|
||||
cofs.updateTransform(entityId, tFlags);
|
||||
cofs.updateAlpha(entityId, aFlags);
|
||||
}
|
||||
}
|
||||
|
@ -1,9 +1,9 @@
|
||||
package com.riiablo.engine.client;
|
||||
|
||||
import com.google.flatbuffers.ByteBufferUtil;
|
||||
import com.google.flatbuffers.FlatBufferBuilder;
|
||||
|
||||
import com.artemis.ComponentMapper;
|
||||
import com.artemis.Entity;
|
||||
import com.artemis.annotations.All;
|
||||
import com.artemis.annotations.Wire;
|
||||
import com.artemis.systems.IntervalSystem;
|
||||
@ -32,6 +32,7 @@ import com.riiablo.net.packet.d2gs.VelocityP;
|
||||
|
||||
import java.io.OutputStream;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.ByteOrder;
|
||||
import java.nio.channels.Channels;
|
||||
import java.nio.channels.ReadableByteChannel;
|
||||
import java.nio.channels.WritableByteChannel;
|
||||
@ -39,6 +40,9 @@ import java.nio.channels.WritableByteChannel;
|
||||
@All
|
||||
public class ClientNetworkSyncronizer extends IntervalSystem {
|
||||
private static final String TAG = "ClientNetworkSyncronizer";
|
||||
private static final boolean DEBUG = true;
|
||||
private static final boolean DEBUG_PACKET = DEBUG && !true;
|
||||
private static final boolean DEBUG_CONNECT = DEBUG && !true;
|
||||
|
||||
protected ComponentMapper<Networked> mNetworked;
|
||||
protected ComponentMapper<CofComponents> mCofComponents;
|
||||
@ -73,16 +77,16 @@ public class ClientNetworkSyncronizer extends IntervalSystem {
|
||||
FlatBufferBuilder builder = new FlatBufferBuilder();
|
||||
int charNameOffset = builder.createString(Riiablo.charData.getD2S().header.name);
|
||||
|
||||
Entity player = world.getEntity(Riiablo.game.player);
|
||||
int[] component = player.getComponent(CofComponents.class).component;
|
||||
int entityId = Riiablo.game.player;
|
||||
int[] component = mCofComponents.get(entityId).component;
|
||||
builder.startVector(1, component.length, 1);
|
||||
for (int i = component.length - 1; i >= 0; i--) builder.addByte((byte) component[i]);
|
||||
int componentsOffset = builder.endVector();
|
||||
|
||||
float[] alphas = player.getComponent(CofAlphas.class).alpha;
|
||||
float[] alphas = mCofAlphas.get(entityId).alpha;
|
||||
int alphasOffset = Connection.createCofAlphasVector(builder, alphas);
|
||||
|
||||
byte[] transforms = player.getComponent(CofTransforms.class).transform;
|
||||
byte[] transforms = mCofTransforms.get(entityId).transform;
|
||||
int transformsOffset = Connection.createCofTransformsVector(builder, transforms);
|
||||
|
||||
Connection.startConnection(builder);
|
||||
@ -93,38 +97,46 @@ public class ClientNetworkSyncronizer extends IntervalSystem {
|
||||
Connection.addCofTransforms(builder, transformsOffset);
|
||||
int connectionOffset = Connection.endConnection(builder);
|
||||
int offset = D2GS.createD2GS(builder, D2GSData.Connection, connectionOffset);
|
||||
builder.finish(offset);
|
||||
ByteBuffer data = builder.dataBuffer();
|
||||
D2GS.finishSizePrefixedD2GSBuffer(builder, offset);
|
||||
|
||||
OutputStream out = socket.getOutputStream();
|
||||
WritableByteChannel channelOut = Channels.newChannel(out);
|
||||
channelOut.write(data);
|
||||
channelOut.write(builder.dataBuffer());
|
||||
|
||||
boolean connected = false;
|
||||
ByteBuffer buffer = ByteBuffer.allocate(4096);
|
||||
ByteBuffer buffer = ByteBuffer.allocate(1 << 20).order(ByteOrder.LITTLE_ENDIAN);
|
||||
while (!connected) {
|
||||
try {
|
||||
buffer.clear();
|
||||
ReadableByteChannel channelIn = Channels.newChannel(socket.getInputStream());
|
||||
int i = channelIn.read(buffer);
|
||||
System.out.println("read " + i + ": " + buffer.position());
|
||||
buffer.rewind();
|
||||
D2GS response = D2GS.getRootAsD2GS(buffer);
|
||||
System.out.println("packet type " + D2GSData.name(response.dataType()));
|
||||
connected = response.dataType() == D2GSData.Connection;
|
||||
if (!connected) {
|
||||
System.out.println("dropping...");
|
||||
continue;
|
||||
buffer.rewind().limit(i);
|
||||
D2GS d2gs = new D2GS();
|
||||
while (buffer.hasRemaining()) {
|
||||
int size = ByteBufferUtil.getSizePrefix(buffer);
|
||||
D2GS.getRootAsD2GS(ByteBufferUtil.removeSizePrefix(buffer), d2gs);
|
||||
if (DEBUG_PACKET) Gdx.app.debug(TAG, "packet type " + D2GSData.name(d2gs.dataType()) + ":" + ByteBufferUtil.getSizePrefix(buffer) + "B");
|
||||
connected = d2gs.dataType() == D2GSData.Connection;
|
||||
if (!connected) {
|
||||
if (DEBUG_CONNECT) Gdx.app.debug(TAG, "dropping... ");
|
||||
// System.out.println(buffer.position() + "->" + (buffer.position() + size + 4));
|
||||
buffer.position(buffer.position() + size + 4);
|
||||
continue;
|
||||
}
|
||||
Connection connection = (Connection) d2gs.data(new Connection());
|
||||
connected = connection.charName() == null;
|
||||
if (!connected) {
|
||||
if (DEBUG_CONNECT) Gdx.app.debug(TAG, "dropping... ");
|
||||
// System.out.println(buffer.position() + "->" + (buffer.position() + size + 4));
|
||||
buffer.position(buffer.position() + size + 4);
|
||||
continue;
|
||||
}
|
||||
|
||||
int serverId = connection.entityId();
|
||||
Gdx.app.log(TAG, "assign " + entityId + " to " + serverId);
|
||||
idManager.put(connection.entityId(), Riiablo.game.player);
|
||||
break;
|
||||
}
|
||||
Connection connection = (Connection) response.data(new Connection());
|
||||
connected = connection.charName() == null;
|
||||
if (!connected) {
|
||||
System.out.println("dropping...");
|
||||
continue;
|
||||
}
|
||||
int serverId = connection.entityId();
|
||||
System.out.println("assign " + player + " to " + serverId);
|
||||
idManager.put(connection.entityId(), Riiablo.game.player);
|
||||
} catch (Throwable t) {
|
||||
Gdx.app.error(TAG, t.getMessage(), t);
|
||||
}
|
||||
@ -181,7 +193,7 @@ public class ClientNetworkSyncronizer extends IntervalSystem {
|
||||
|
||||
//int syncOffset = Sync.createSync(builder, entityId, dataTypesOffset, dataOffset);
|
||||
int root = D2GS.createD2GS(builder, D2GSData.Sync, syncOffset);
|
||||
builder.finish(root);
|
||||
D2GS.finishSizePrefixedD2GSBuffer(builder, root);
|
||||
|
||||
try {
|
||||
OutputStream out = socket.getOutputStream();
|
||||
|
22
core/src/com/riiablo/engine/server/Box2DDisposer.java
Normal file
22
core/src/com/riiablo/engine/server/Box2DDisposer.java
Normal file
@ -0,0 +1,22 @@
|
||||
package com.riiablo.engine.server;
|
||||
|
||||
import com.artemis.ComponentMapper;
|
||||
import com.artemis.annotations.All;
|
||||
import com.badlogic.gdx.physics.box2d.Body;
|
||||
import com.riiablo.engine.EntitySystemAdapter;
|
||||
import com.riiablo.engine.server.component.Box2DBody;
|
||||
import com.riiablo.map.Box2DPhysics;
|
||||
|
||||
@All(Box2DBody.class)
|
||||
public class Box2DDisposer extends EntitySystemAdapter {
|
||||
protected ComponentMapper<Box2DBody> mBox2DBody;
|
||||
|
||||
protected Box2DPhysics box2d;
|
||||
|
||||
@Override
|
||||
protected void removed(int entityId) {
|
||||
if (!mBox2DBody.has(entityId)) return;
|
||||
Body body = mBox2DBody.get(entityId).body;
|
||||
if (body != null) box2d.getPhysics().destroyBody(body);
|
||||
}
|
||||
}
|
@ -113,7 +113,7 @@ public class ServerEntityFactory extends EntityFactory {
|
||||
int id = createMonster(map, zone, monstats, x, y);
|
||||
mDS1ObjectWrapper.create(id).set(preset.getDS1(), object);
|
||||
if (object.path != null) mPathWrapper.create(id).path = object.path;
|
||||
// mNetworked.create(id);
|
||||
mNetworked.create(id);
|
||||
return id;
|
||||
}
|
||||
|
||||
|
@ -78,6 +78,7 @@ import com.riiablo.engine.server.AIStepper;
|
||||
import com.riiablo.engine.server.AngularVelocity;
|
||||
import com.riiablo.engine.server.AnimDataResolver;
|
||||
import com.riiablo.engine.server.AnimStepper;
|
||||
import com.riiablo.engine.server.Box2DDisposer;
|
||||
import com.riiablo.engine.server.Box2DSynchronizerPre;
|
||||
import com.riiablo.engine.server.Box2DSynchronizerPost;
|
||||
import com.riiablo.engine.server.CofManager;
|
||||
@ -552,6 +553,7 @@ public class GameScreen extends ScreenAdapter implements GameLoadingScreen.Loada
|
||||
|
||||
.with(new VelocityModeChanger())
|
||||
// .with(new VelocityAdder())
|
||||
.with(new Box2DDisposer())
|
||||
.with(new Box2DSynchronizerPre())
|
||||
.with(new Box2DPhysics(1 / 60f))
|
||||
.with(new Box2DSynchronizerPost())
|
||||
|
@ -1,5 +1,6 @@
|
||||
package com.riiablo.server.d2gs;
|
||||
|
||||
import com.google.flatbuffers.ByteBufferUtil;
|
||||
import com.google.flatbuffers.FlatBufferBuilder;
|
||||
|
||||
import com.artemis.ComponentMapper;
|
||||
@ -146,6 +147,7 @@ public class D2GS extends ApplicationAdapter {
|
||||
ThreadGroup clientThreads;
|
||||
final Client[] clients = new Client[MAX_CLIENTS];
|
||||
int numClients = 0;
|
||||
int connected = 0;
|
||||
|
||||
final BlockingQueue<Packet> packets = new ArrayBlockingQueue<>(32);
|
||||
final Collection<Packet> cache = new ArrayList<>();
|
||||
@ -162,7 +164,6 @@ public class D2GS extends ApplicationAdapter {
|
||||
EntityFactory factory;
|
||||
MapManager mapManager;
|
||||
NetworkSynchronizer sync;
|
||||
SerializationManager serializer;
|
||||
|
||||
protected ComponentMapper<Networked> mNetworked;
|
||||
|
||||
@ -281,6 +282,7 @@ public class D2GS extends ApplicationAdapter {
|
||||
Gdx.app.log(TAG, "assigned " + socket.getRemoteAddress() + " to " + id);
|
||||
Client client = clients[id] = new Client(id, socket);
|
||||
numClients++;
|
||||
connected |= (1 << id);
|
||||
client.start();
|
||||
}
|
||||
} catch (Throwable t) {
|
||||
@ -302,6 +304,7 @@ public class D2GS extends ApplicationAdapter {
|
||||
}
|
||||
}
|
||||
numClients = 0;
|
||||
connected = 0;
|
||||
}
|
||||
|
||||
Gdx.app.log(TAG, "killing thread...");
|
||||
@ -339,12 +342,12 @@ public class D2GS extends ApplicationAdapter {
|
||||
for (Packet packet : cache) {
|
||||
Gdx.app.log(TAG, "dispatching " + D2GSData.name(packet.data.dataType()) + " packet to " + String.format("0x%08X", packet.id));
|
||||
for (int i = 0, flag = 1; i < MAX_CLIENTS; i++, flag <<= 1) {
|
||||
if ((packet.id & flag) == flag) {
|
||||
if ((packet.id & flag) == flag && (connected & flag) == flag) {
|
||||
Client client = clients[i];
|
||||
if (client == null) continue;
|
||||
try {
|
||||
System.out.println(" dispatching packet to " + i);
|
||||
client.send(packet.data);
|
||||
client.send(packet);
|
||||
} catch (Throwable t) {
|
||||
Gdx.app.error(TAG, t.getMessage(), t);
|
||||
}
|
||||
@ -400,10 +403,8 @@ public class D2GS extends ApplicationAdapter {
|
||||
Connection.addEntityId(builder, entityId);
|
||||
int connectionOffset = Connection.endConnection(builder);
|
||||
int offset = com.riiablo.net.packet.d2gs.D2GS.createD2GS(builder, D2GSData.Connection, connectionOffset);
|
||||
builder.finish(offset);
|
||||
ByteBuffer buffer = builder.dataBuffer();
|
||||
com.riiablo.net.packet.d2gs.D2GS responseData = com.riiablo.net.packet.d2gs.D2GS.getRootAsD2GS(buffer);
|
||||
Packet response = Packet.obtain(1 << packet.id, responseData);
|
||||
com.riiablo.net.packet.d2gs.D2GS.finishSizePrefixedD2GSBuffer(builder, offset);
|
||||
Packet response = Packet.obtain(1 << packet.id, builder.dataBuffer());
|
||||
outPackets.offer(response);
|
||||
|
||||
Synchronize(packet.id, entityId);
|
||||
@ -439,10 +440,9 @@ public class D2GS extends ApplicationAdapter {
|
||||
Connection.addCofTransforms(builder, transformsOffset);
|
||||
int connectionOffset = Connection.endConnection(builder);
|
||||
int offset = com.riiablo.net.packet.d2gs.D2GS.createD2GS(builder, D2GSData.Connection, connectionOffset);
|
||||
builder.finish(offset);
|
||||
com.riiablo.net.packet.d2gs.D2GS data = com.riiablo.net.packet.d2gs.D2GS.getRootAsD2GS(builder.dataBuffer());
|
||||
com.riiablo.net.packet.d2gs.D2GS.finishSizePrefixedD2GSBuffer(builder, offset);
|
||||
|
||||
Packet broadcast = Packet.obtain(~(1 << id), data);
|
||||
Packet broadcast = Packet.obtain(~(1 << id), builder.dataBuffer());
|
||||
boolean success = outPackets.offer(broadcast);
|
||||
assert success;
|
||||
}
|
||||
@ -453,10 +453,8 @@ public class D2GS extends ApplicationAdapter {
|
||||
FlatBufferBuilder builder = new FlatBufferBuilder();
|
||||
int disconnectOffset = Disconnect.createDisconnect(builder, entityId);
|
||||
int offset = com.riiablo.net.packet.d2gs.D2GS.createD2GS(builder, D2GSData.Disconnect, disconnectOffset);
|
||||
builder.finish(offset);
|
||||
ByteBuffer buffer = builder.dataBuffer();
|
||||
com.riiablo.net.packet.d2gs.D2GS responseData = com.riiablo.net.packet.d2gs.D2GS.getRootAsD2GS(buffer);
|
||||
Packet broadcast = Packet.obtain(~(1 << id), responseData);
|
||||
com.riiablo.net.packet.d2gs.D2GS.finishSizePrefixedD2GSBuffer(builder, offset);
|
||||
Packet broadcast = Packet.obtain(~(1 << id), builder.dataBuffer());
|
||||
outPackets.offer(broadcast);
|
||||
|
||||
world.delete(entityId);
|
||||
@ -464,6 +462,7 @@ public class D2GS extends ApplicationAdapter {
|
||||
synchronized (clients) {
|
||||
clients[id] = null;
|
||||
numClients--;
|
||||
connected &= ~(1 << id);
|
||||
}
|
||||
}
|
||||
|
||||
@ -492,10 +491,11 @@ public class D2GS extends ApplicationAdapter {
|
||||
this.socket = socket;
|
||||
}
|
||||
|
||||
public void send(com.riiablo.net.packet.d2gs.D2GS data) throws IOException {
|
||||
ByteBuffer buffer = data.getByteBuffer();
|
||||
public void send(Packet packet) throws IOException {
|
||||
WritableByteChannel out = Channels.newChannel(socket.getOutputStream());
|
||||
out.write(buffer);
|
||||
packet.buffer.mark();
|
||||
out.write(packet.buffer);
|
||||
packet.buffer.reset();
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -513,9 +513,9 @@ public class D2GS extends ApplicationAdapter {
|
||||
buffer.reset();
|
||||
|
||||
ByteBuffer copy = (ByteBuffer) ByteBuffer.wrap(new byte[buffer.limit()]).put(buffer).rewind();
|
||||
com.riiablo.net.packet.d2gs.D2GS data = com.riiablo.net.packet.d2gs.D2GS.getRootAsD2GS(copy);
|
||||
Gdx.app.log(TAG, "received " + D2GSData.name(data.dataType()) + " packet from " + socket.getRemoteAddress());
|
||||
boolean success = packets.offer(Packet.obtain(id, data), 5, TimeUnit.MILLISECONDS);
|
||||
Packet packet = Packet.obtain(id, copy);
|
||||
Gdx.app.log(TAG, "received " + D2GSData.name(packet.data.dataType()) + " packet from " + socket.getRemoteAddress());
|
||||
boolean success = packets.offer(packet, 5, TimeUnit.MILLISECONDS);
|
||||
if (!success) {
|
||||
Gdx.app.log(TAG, "failed to add to queue -- closing " + socket.getRemoteAddress());
|
||||
kill = true;
|
||||
@ -533,13 +533,15 @@ public class D2GS extends ApplicationAdapter {
|
||||
}
|
||||
|
||||
public static class Packet {
|
||||
int id;
|
||||
com.riiablo.net.packet.d2gs.D2GS data;
|
||||
public int id;
|
||||
public ByteBuffer buffer;
|
||||
public com.riiablo.net.packet.d2gs.D2GS data;
|
||||
|
||||
public static Packet obtain(int id, com.riiablo.net.packet.d2gs.D2GS data) {
|
||||
public static Packet obtain(int id, ByteBuffer buffer) {
|
||||
Packet packet = new Packet();
|
||||
packet.id = id;
|
||||
packet.data = data;
|
||||
packet.buffer = buffer;
|
||||
packet.data = com.riiablo.net.packet.d2gs.D2GS.getRootAsD2GS(ByteBufferUtil.removeSizePrefix(buffer));
|
||||
return packet;
|
||||
}
|
||||
}
|
||||
|
@ -12,6 +12,7 @@ import com.riiablo.engine.server.component.Networked;
|
||||
import com.riiablo.net.packet.d2gs.D2GS;
|
||||
import com.riiablo.net.packet.d2gs.D2GSData;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
import java.util.concurrent.BlockingQueue;
|
||||
|
||||
@All(Networked.class)
|
||||
@ -33,18 +34,19 @@ public class NetworkSynchronizer extends IteratingSystem {
|
||||
|
||||
@Override
|
||||
protected void process(int entityId) {
|
||||
D2GS sync = sync(entityId);
|
||||
ByteBuffer sync = sync(entityId);
|
||||
int id = players.findKey(entityId, -1);
|
||||
boolean success = outPackets.offer(com.riiablo.server.d2gs.D2GS.Packet.obtain(id != -1 ? ~(1 << id) : 0xFFFFFFFF, sync));
|
||||
boolean success = outPackets.offer(com.riiablo.server.d2gs.D2GS.Packet
|
||||
.obtain(id != -1 ? ~(1 << id) : 0xFFFFFFFF, sync));
|
||||
assert success;
|
||||
}
|
||||
|
||||
public D2GS sync(int entityId) {
|
||||
public ByteBuffer sync(int entityId) {
|
||||
FlatBufferBuilder builder = new FlatBufferBuilder(0);
|
||||
int syncOffset = serializer.serialize(builder, entityId);
|
||||
int root = D2GS.createD2GS(builder, D2GSData.Sync, syncOffset);
|
||||
builder.finish(root);
|
||||
return D2GS.getRootAsD2GS(builder.dataBuffer());
|
||||
D2GS.finishSizePrefixedD2GSBuffer(builder, root);
|
||||
return builder.dataBuffer();
|
||||
}
|
||||
|
||||
public void sync(int entityId, D2GS packet) {
|
||||
|
Loading…
Reference in New Issue
Block a user