Fixed some issues with connecting players -- connection protocol needs to be cleaned up more

ClientNetworkReceiver is disabled until Connection response is received
ClientNetworkSynchronizer will block until Connection response is received and drop other packets
Added ClassSerializer and DS1ObjectWrapperSerializer to transfer entity type and object data
Disabled networking on dynamic entities while I can determine issues with packet transfer
Added fix for AIStepper to make renderer bounds check optional -- will come up with a better solution to remove this client-only code
This commit is contained in:
Collin Smith 2019-12-23 03:10:45 -08:00
parent ea040c318e
commit 6b729c4350
9 changed files with 161 additions and 28 deletions

View File

@ -11,6 +11,7 @@ import com.badlogic.gdx.physics.box2d.Body;
import com.riiablo.CharData;
import com.riiablo.CharacterClass;
import com.riiablo.Riiablo;
import com.riiablo.codec.excel.MonStats;
import com.riiablo.engine.Dirty;
import com.riiablo.engine.Engine;
import com.riiablo.engine.EntityFactory;
@ -21,7 +22,6 @@ 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.CofTransforms;
import com.riiablo.engine.server.component.Networked;
import com.riiablo.engine.server.component.Player;
import com.riiablo.engine.server.component.Position;
import com.riiablo.engine.server.component.Velocity;
@ -34,6 +34,7 @@ import com.riiablo.net.packet.d2gs.CofTransformsP;
import com.riiablo.net.packet.d2gs.Connection;
import com.riiablo.net.packet.d2gs.D2GS;
import com.riiablo.net.packet.d2gs.D2GSData;
import com.riiablo.net.packet.d2gs.DS1ObjectWrapperP;
import com.riiablo.net.packet.d2gs.Disconnect;
import com.riiablo.net.packet.d2gs.PlayerP;
import com.riiablo.net.packet.d2gs.PositionP;
@ -50,11 +51,11 @@ import java.nio.channels.Channels;
import java.nio.channels.ReadableByteChannel;
import java.util.Arrays;
@All(Networked.class)
@All
public class ClientNetworkReceiver extends IntervalSystem {
private static final String TAG = "ClientNetworkReceiver";
protected ComponentMapper<Networked> mNetworked;
// protected ComponentMapper<Networked> mNetworked;
protected ComponentMapper<CofComponents> mCofComponents;
protected ComponentMapper<CofTransforms> mCofTransforms;
protected ComponentMapper<CofAlphas> mCofAlphas;
@ -187,6 +188,16 @@ public class ClientNetworkReceiver extends IntervalSystem {
return -1;
}
private DS1ObjectWrapperP findDS1ObjectWrapper(Sync s) {
for (int i = 0, len = s.dataTypeLength(); i < len; i++) {
if (s.dataType(i) == SyncData.DS1ObjectWrapperP) {
return (DS1ObjectWrapperP) s.data(new DS1ObjectWrapperP(), i);
}
}
return null;
}
private PlayerP findPlayer(Sync s) {
for (int i = 0, len = s.dataTypeLength(); i < len; i++) {
if (s.dataType(i) == SyncData.PlayerP) {
@ -197,15 +208,28 @@ public class ClientNetworkReceiver extends IntervalSystem {
return null;
}
private void createEntity(Sync sync) {
private int createEntity(Sync sync) {
assert syncIds.get(sync.entityId()) == Engine.INVALID_ENTITY;
Class.Type type = Class.Type.valueOf(findType(sync));
switch (type) {
case OBJ:
break;
return Engine.INVALID_ENTITY;
case MON:
DS1ObjectWrapperP ds1ObjectWrapper = findDS1ObjectWrapper(sync);
if (ds1ObjectWrapper != null) {
Vector2 origin = map.find(Map.ID.TOWN_ENTRY_1);
if (origin == null) origin = map.find(Map.ID.TOWN_ENTRY_2);
if (origin == null) origin = map.find(Map.ID.TP_LOCATION);
Map.Zone zone = map.getZone(origin);
String objectType = Riiablo.files.obj.getType1(ds1ObjectWrapper.act(), ds1ObjectWrapper.id());
MonStats.Entry monstats = Riiablo.files.monstats.get(objectType);
int entityId = factory.createMonster(map, zone, monstats, 0, 0);
// syncIds.put(sync.entityId(), entityId);
System.out.println("testa creating monster " + monstats.Code);
return entityId;
}
break;
return Engine.INVALID_ENTITY;
case PLR: {
PlayerP player = findPlayer(sync);
CharData charData = new CharData().createD2S(player.charName(), CharacterClass.get(player.charClass()));
@ -217,12 +241,14 @@ public class ClientNetworkReceiver extends IntervalSystem {
if (origin == null) origin = map.find(Map.ID.TP_LOCATION);
Map.Zone zone = map.getZone(origin);
int entityId = factory.createPlayer(map, zone, charData, origin);
syncIds.put(sync.entityId(), entityId);
// syncIds.put(sync.entityId(), entityId);
cofs.setMode(entityId, Engine.Player.MODE_TN);
cofs.setWClass(entityId, Engine.WEAPON_1HS); // TODO...
break;
return entityId;
}
default:
return Engine.INVALID_ENTITY;
}
}
@ -230,7 +256,7 @@ public class ClientNetworkReceiver extends IntervalSystem {
Sync sync = (Sync) packet.data(new Sync());
int entityId = syncIds.get(sync.entityId());
if (entityId == Engine.INVALID_ENTITY) {
createEntity(sync);
syncIds.put(sync.entityId(), entityId = createEntity(sync));
}
int flags1 = Dirty.NONE;
@ -240,6 +266,7 @@ public class ClientNetworkReceiver extends IntervalSystem {
switch (sync.dataType(i)) {
case SyncData.ClassP:
case SyncData.PlayerP:
case SyncData.DS1ObjectWrapperP:
break;
case SyncData.CofComponentsP: {
CofComponentsP data = (CofComponentsP) sync.data(new CofComponentsP(), i);
@ -268,7 +295,7 @@ public class ClientNetworkReceiver extends IntervalSystem {
position.x = data.x();
position.y = data.y();
Body body = mBox2DBody.get(entityId).body;
body.setTransform(position, body.getAngle());
if (body != null) body.setTransform(position, body.getAngle());
//Gdx.app.log(TAG, " " + position);
break;
}

View File

@ -36,7 +36,7 @@ import java.nio.channels.Channels;
import java.nio.channels.ReadableByteChannel;
import java.nio.channels.WritableByteChannel;
@All(Networked.class)
@All
public class ClientNetworkSyncronizer extends IntervalSystem {
private static final String TAG = "ClientNetworkSyncronizer";
@ -49,6 +49,7 @@ public class ClientNetworkSyncronizer extends IntervalSystem {
protected ComponentMapper<Angle> mAngle;
protected NetworkIdManager idManager;
protected ClientNetworkReceiver receiver;
boolean init = false;
@Wire(name="client.socket") Socket socket;
@ -59,7 +60,7 @@ public class ClientNetworkSyncronizer extends IntervalSystem {
@Override
protected void initialize() {
super.initialize();
receiver.setEnabled(false);
}
@Override
@ -99,20 +100,36 @@ public class ClientNetworkSyncronizer extends IntervalSystem {
WritableByteChannel channelOut = Channels.newChannel(out);
channelOut.write(data);
ByteBuffer buffer = com.badlogic.gdx.utils.BufferUtils.newByteBuffer(4096);
buffer.clear();
buffer.mark();
ReadableByteChannel channelIn = Channels.newChannel(socket.getInputStream());
channelIn.read(buffer);
buffer.limit(buffer.position());
buffer.reset();
D2GS response = D2GS.getRootAsD2GS(buffer);
System.out.println("packet type " + D2GSData.name(response.dataType()));
assert response.dataType() == D2GSData.Connection;
Connection connection = (Connection) response.data(new Connection());
int serverId = connection.entityId();
System.out.println("assign " + player + " to " + serverId);
idManager.put(connection.entityId(), Riiablo.game.player);
boolean connected = false;
ByteBuffer buffer = ByteBuffer.allocate(4096);
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;
}
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);
}
}
receiver.setEnabled(true);
} catch (Throwable t) {
Gdx.app.error(TAG, t.getMessage(), t);
}

View File

@ -2,12 +2,14 @@ package com.riiablo.engine.server;
import com.artemis.ComponentMapper;
import com.artemis.annotations.All;
import com.artemis.annotations.Wire;
import com.artemis.systems.IteratingSystem;
import com.riiablo.engine.server.component.AIWrapper;
import com.riiablo.engine.server.component.Monster;
import com.riiablo.engine.server.component.Position;
import com.riiablo.map.RenderSystem;
@Wire(failOnNull = false)
@All({AIWrapper.class, Position.class, Monster.class})
public class AIStepper extends IteratingSystem {
protected ComponentMapper<AIWrapper> mAIWrapper;
@ -34,7 +36,7 @@ public class AIStepper extends IteratingSystem {
@Override
protected void process(int entityId) {
if (!renderer.withinRadius(mPosition.get(entityId).position)) return;
if (renderer != null && !renderer.withinRadius(mPosition.get(entityId).position)) return;
mAIWrapper.get(entityId).ai.update(world.delta);
}
}

View File

@ -14,13 +14,16 @@ import com.riiablo.engine.server.component.Angle;
import com.riiablo.engine.server.component.CofAlphas;
import com.riiablo.engine.server.component.CofComponents;
import com.riiablo.engine.server.component.CofTransforms;
import com.riiablo.engine.server.component.DS1ObjectWrapper;
import com.riiablo.engine.server.component.Player;
import com.riiablo.engine.server.component.Position;
import com.riiablo.engine.server.component.Velocity;
import com.riiablo.engine.server.component.serializer.AngleSerializer;
import com.riiablo.engine.server.component.serializer.ClassSerializer;
import com.riiablo.engine.server.component.serializer.CofAlphasSerializer;
import com.riiablo.engine.server.component.serializer.CofComponentsSerializer;
import com.riiablo.engine.server.component.serializer.CofTransformsSerializer;
import com.riiablo.engine.server.component.serializer.DS1ObjectWrapperSerializer;
import com.riiablo.engine.server.component.serializer.FlatBuffersSerializer;
import com.riiablo.engine.server.component.serializer.PlayerSerializer;
import com.riiablo.engine.server.component.serializer.PositionSerializer;
@ -48,12 +51,14 @@ public class SerializationManager extends PassiveSystem {
private Class<? extends Component>[] deserializers;
private final Sync sync = new Sync();
protected ComponentMapper<com.riiablo.engine.server.component.Class> mClass;
protected ComponentMapper<CofComponents> mCofComponents;
protected ComponentMapper<CofTransforms> mCofTransforms;
protected ComponentMapper<CofAlphas> mCofAlphas;
protected ComponentMapper<Position> mPosition;
protected ComponentMapper<Velocity> mVelocity;
protected ComponentMapper<Angle> mAngle;
protected ComponentMapper<DS1ObjectWrapper> mDS1ObjectWrapper;
protected ComponentMapper[] cm;
protected ComponentManager componentManager;
@ -63,6 +68,7 @@ public class SerializationManager extends PassiveSystem {
@SuppressWarnings("unchecked")
protected void initialize() {
serializers = new ObjectMap<>();
serializers.put(com.riiablo.engine.server.component.Class.class, new ClassSerializer());
serializers.put(CofComponents.class, new CofComponentsSerializer());
serializers.put(CofTransforms.class, new CofTransformsSerializer());
serializers.put(CofAlphas.class, new CofAlphasSerializer());
@ -70,8 +76,10 @@ public class SerializationManager extends PassiveSystem {
serializers.put(Velocity.class, new VelocitySerializer());
serializers.put(Angle.class, new AngleSerializer());
serializers.put(Player.class, new PlayerSerializer());
serializers.put(DS1ObjectWrapper.class, new DS1ObjectWrapperSerializer());
deserializers = (Class<? extends Component>[]) new Class[SyncData.names.length];
deserializers[SyncData.ClassP] = com.riiablo.engine.server.component.Class.class;
deserializers[SyncData.CofComponentsP] = CofComponents.class;
deserializers[SyncData.CofTransformsP] = CofTransforms.class;
deserializers[SyncData.CofAlphasP] = CofAlphas.class;
@ -79,8 +87,10 @@ public class SerializationManager extends PassiveSystem {
deserializers[SyncData.VelocityP] = Velocity.class;
deserializers[SyncData.AngleP] = Angle.class;
deserializers[SyncData.PlayerP] = Player.class;
deserializers[SyncData.DS1ObjectWrapperP] = DS1ObjectWrapper.class;
cm = new ComponentMapper[SyncData.names.length];
cm[SyncData.ClassP] = mClass;
cm[SyncData.CofComponentsP] = null;
cm[SyncData.CofTransformsP] = null;
cm[SyncData.CofAlphasP] = null;
@ -88,6 +98,7 @@ public class SerializationManager extends PassiveSystem {
cm[SyncData.VelocityP] = mVelocity;
cm[SyncData.AngleP] = mAngle;
cm[SyncData.PlayerP] = null;
cm[SyncData.DS1ObjectWrapperP] = mDS1ObjectWrapper;
}
@SuppressWarnings("unchecked")
@ -167,6 +178,7 @@ public class SerializationManager extends PassiveSystem {
}
case SyncData.ClassP:
case SyncData.PlayerP:
case SyncData.DS1ObjectWrapperP:
break;
default: {
Class<? extends Component> clazz = deserializers[dataType];

View File

@ -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;
}

View File

@ -0,0 +1,35 @@
package com.riiablo.engine.server.component.serializer;
import com.google.flatbuffers.FlatBufferBuilder;
import com.riiablo.engine.server.component.Class;
import com.riiablo.net.packet.d2gs.ClassP;
import com.riiablo.net.packet.d2gs.Sync;
import com.riiablo.net.packet.d2gs.SyncData;
public class ClassSerializer implements FlatBuffersSerializer<Class, ClassP> {
public static final ClassP table = new ClassP();
@Override
public byte getDataType() {
return SyncData.ClassP;
}
@Override
public int putData(FlatBufferBuilder builder, Class c) {
return ClassP.createClassP(builder, c.type.ordinal());
}
@Override
public ClassP getTable(Sync sync, int j) {
sync.data(table, j);
return table;
}
@Override
public Class getData(Sync sync, int j, Class c) {
getTable(sync, j);
c.type = Class.Type.valueOf(table.type());
return c;
}
}

View File

@ -0,0 +1,33 @@
package com.riiablo.engine.server.component.serializer;
import com.google.flatbuffers.FlatBufferBuilder;
import com.riiablo.engine.server.component.DS1ObjectWrapper;
import com.riiablo.net.packet.d2gs.DS1ObjectWrapperP;
import com.riiablo.net.packet.d2gs.Sync;
import com.riiablo.net.packet.d2gs.SyncData;
public class DS1ObjectWrapperSerializer implements FlatBuffersSerializer<DS1ObjectWrapper, DS1ObjectWrapperP> {
public static final DS1ObjectWrapperP table = new DS1ObjectWrapperP();
@Override
public byte getDataType() {
return SyncData.DS1ObjectWrapperP;
}
@Override
public int putData(FlatBufferBuilder builder, DS1ObjectWrapper c) {
return DS1ObjectWrapperP.createDS1ObjectWrapperP(builder, c.ds1.getAct(), c.object.id);
}
@Override
public DS1ObjectWrapperP getTable(Sync sync, int j) {
sync.data(table, j);
return table;
}
@Override
public DS1ObjectWrapper getData(Sync sync, int j, DS1ObjectWrapper c) {
throw new UnsupportedOperationException("Not supported!");
}
}

View File

@ -9,6 +9,7 @@ union SyncData {
VelocityP,
AngleP,
PlayerP,
DS1ObjectWrapperP,
}
table Sync {
@ -50,4 +51,9 @@ table AngleP {
table PlayerP {
charClass:uint8;
charName:string;
}
table DS1ObjectWrapperP {
act:uint8;
id:uint8;
}

View File

@ -235,6 +235,7 @@ public class D2GS extends ApplicationAdapter {
.with(new ObjectInitializer())
.with(new ObjectInteractor(), new WarpInteractor(), new ItemInteractor())
// .with(new AIStepper())
.with(new Pathfinder())
.with(factory)