diff --git a/core/gen/com/riiablo/net/packet/d2gs/DS1ObjectWrapperP.java b/core/gen/com/riiablo/net/packet/d2gs/DS1ObjectWrapperP.java new file mode 100644 index 00000000..e318a380 --- /dev/null +++ b/core/gen/com/riiablo/net/packet/d2gs/DS1ObjectWrapperP.java @@ -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; + } +} + diff --git a/core/gen/com/riiablo/net/packet/d2gs/SyncData.java b/core/gen/com/riiablo/net/packet/d2gs/SyncData.java index 5189b38e..35985b28 100644 --- a/core/gen/com/riiablo/net/packet/d2gs/SyncData.java +++ b/core/gen/com/riiablo/net/packet/d2gs/SyncData.java @@ -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]; } } diff --git a/core/src/com/riiablo/engine/EntitySystemAdapter.java b/core/src/com/riiablo/engine/EntitySystemAdapter.java new file mode 100644 index 00000000..2ec18692 --- /dev/null +++ b/core/src/com/riiablo/engine/EntitySystemAdapter.java @@ -0,0 +1,7 @@ +package com.riiablo.engine; + +import com.artemis.BaseEntitySystem; + +public class EntitySystemAdapter extends BaseEntitySystem { + @Override protected void processSystem() {} +} diff --git a/core/src/com/riiablo/engine/client/ClientNetworkReceiver.java b/core/src/com/riiablo/engine/client/ClientNetworkReceiver.java index 789b1d5b..d4aca944 100644 --- a/core/src/com/riiablo/engine/client/ClientNetworkReceiver.java +++ b/core/src/com/riiablo/engine/client/ClientNetworkReceiver.java @@ -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 mNetworked; + protected ComponentMapper mCofReference; protected ComponentMapper mCofComponents; protected ComponentMapper mCofTransforms; protected ComponentMapper 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); } } diff --git a/core/src/com/riiablo/engine/client/ClientNetworkSyncronizer.java b/core/src/com/riiablo/engine/client/ClientNetworkSyncronizer.java index 9f87d1e4..fd6dcd65 100644 --- a/core/src/com/riiablo/engine/client/ClientNetworkSyncronizer.java +++ b/core/src/com/riiablo/engine/client/ClientNetworkSyncronizer.java @@ -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 mNetworked; protected ComponentMapper 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(); diff --git a/core/src/com/riiablo/engine/server/Box2DDisposer.java b/core/src/com/riiablo/engine/server/Box2DDisposer.java new file mode 100644 index 00000000..e843cad4 --- /dev/null +++ b/core/src/com/riiablo/engine/server/Box2DDisposer.java @@ -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 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); + } +} diff --git a/core/src/com/riiablo/engine/server/ServerEntityFactory.java b/core/src/com/riiablo/engine/server/ServerEntityFactory.java index cff5659b..4f00a27d 100644 --- a/core/src/com/riiablo/engine/server/ServerEntityFactory.java +++ b/core/src/com/riiablo/engine/server/ServerEntityFactory.java @@ -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; } diff --git a/core/src/com/riiablo/screen/GameScreen.java b/core/src/com/riiablo/screen/GameScreen.java index 79d2ef4c..c7ca561d 100644 --- a/core/src/com/riiablo/screen/GameScreen.java +++ b/core/src/com/riiablo/screen/GameScreen.java @@ -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()) diff --git a/server/d2gs/src/com/riiablo/server/d2gs/D2GS.java b/server/d2gs/src/com/riiablo/server/d2gs/D2GS.java index 22dc48f5..dd46aae2 100644 --- a/server/d2gs/src/com/riiablo/server/d2gs/D2GS.java +++ b/server/d2gs/src/com/riiablo/server/d2gs/D2GS.java @@ -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 packets = new ArrayBlockingQueue<>(32); final Collection cache = new ArrayList<>(); @@ -162,7 +164,6 @@ public class D2GS extends ApplicationAdapter { EntityFactory factory; MapManager mapManager; NetworkSynchronizer sync; - SerializationManager serializer; protected ComponentMapper 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; } } diff --git a/server/d2gs/src/com/riiablo/server/d2gs/NetworkSynchronizer.java b/server/d2gs/src/com/riiablo/server/d2gs/NetworkSynchronizer.java index e7e8d061..e3e6fa9d 100644 --- a/server/d2gs/src/com/riiablo/server/d2gs/NetworkSynchronizer.java +++ b/server/d2gs/src/com/riiablo/server/d2gs/NetworkSynchronizer.java @@ -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) {