Skip to content

Commit

Permalink
#122: Client data managed by server, which is the only one reference.
Browse files Browse the repository at this point in the history
  • Loading branch information
DjThunder committed Apr 24, 2022
1 parent ab06071 commit f67de69
Show file tree
Hide file tree
Showing 9 changed files with 149 additions and 221 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,8 @@ else if (length >= ARG_NAME)
private final OptionalInt port;
private final Optional<String> name;

private Integer clientId;

/**
* Create network.
*
Expand Down Expand Up @@ -191,4 +193,24 @@ public Optional<String> getName()
{
return name;
}

/**
* Get the client id.
*
* @return The client id.
*/
public Integer getClientId()
{
return clientId;
}

/**
* Set the client id.
*
* @param clientId The client id.
*/
public void setClientId(Integer clientId)
{
this.clientId = clientId;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -153,7 +153,7 @@ public int getInt(int index)
*/
public Media getMedia(int index)
{
final int size = UtilConversion.toUnsignedByte(buffer.get());
final int size = readByteUnsigned();
final byte[] data = new byte[size];
buffer.get(data, index + 1, size);
return Medias.create(StandardCharsets.UTF_8.decode(ByteBuffer.wrap(data)).toString());
Expand All @@ -166,7 +166,7 @@ public Media getMedia(int index)
*/
public String readString()
{
final int size = UtilConversion.toUnsignedByte(buffer.get());
final int size = readByteUnsigned();
final byte[] data = new byte[size];
buffer.get(data);
return StandardCharsets.UTF_8.decode(ByteBuffer.wrap(data)).toString();
Expand All @@ -189,7 +189,7 @@ public Media readMedia()
*/
public boolean readBool()
{
return UtilConversion.toUnsignedByte(buffer.get()) == 1 ? true : false;
return readByteUnsigned() == 1 ? true : false;
}

/**
Expand All @@ -202,6 +202,16 @@ public byte readByte()
return buffer.get();
}

/**
* Read next byte.
*
* @return The value read.
*/
public int readByteUnsigned()
{
return UtilConversion.toUnsignedByte(buffer.get());
}

/**
* Read next integer.
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,10 @@
package com.b3dgs.lionengine.game.feature.networkable;

import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

Expand All @@ -31,6 +33,7 @@
import com.b3dgs.lionengine.game.feature.HandlerListener;
import com.b3dgs.lionengine.game.feature.Identifiable;
import com.b3dgs.lionengine.game.feature.Services;
import com.b3dgs.lionengine.game.feature.Transformable;
import com.b3dgs.lionengine.network.Channel;
import com.b3dgs.lionengine.network.Message;
import com.b3dgs.lionengine.network.MessageAbstract;
Expand All @@ -50,13 +53,11 @@ public class ComponentNetwork implements ComponentUpdater, HandlerListener
public static final int MODE_IDENTIFIABLE_GET = UtilNetwork.MODE_DISCONNECT + 1;
/** Mode identifiable create. */
public static final int MODE_IDENTIFIABLE_CREATE = MODE_IDENTIFIABLE_GET + 1;
/** Mode identifiable set. */
public static final int MODE_IDENTIFIABLE_SET = MODE_IDENTIFIABLE_CREATE + 1;

/** Client by data. */
private final Map<Integer, Map<Integer, Networkable>> networkables = new HashMap<>();
/** Networkable by dataId. */
private final Map<Integer, Networkable> networkables = new HashMap<>();
/** Client by pending id. */
private final Map<Integer, Set<Integer>> synced = new HashMap<>();
private final Set<Integer> synced = new HashSet<>();
/** Server reference (<code>null</code> if unavailable). */
private final Server server;
/** Client reference (<code>null</code> if unavailable). */
Expand Down Expand Up @@ -107,6 +108,7 @@ public void notifyServerStopped()
{
client.addListener(new ClientListener()
{

@Override
public void notifyConnected(String ip, int port, Integer id)
{
Expand All @@ -118,6 +120,7 @@ public void notifyDisconnected(String ip, int port, Integer id)
{
clearAll();
}

});
}
}
Expand All @@ -127,9 +130,9 @@ public void notifyDisconnected(String ip, int port, Integer id)
*/
private void clearAll()
{
for (final Map<Integer, Networkable> networkable : networkables.values())
for (final Networkable networkable : networkables.values())
{
networkable.values().forEach(Networkable::onDisconnected);
networkable.onDisconnected();
}
networkables.clear();
}
Expand Down Expand Up @@ -158,156 +161,92 @@ private void send(Message message)
}
}

private void setNetworkable(Integer clientId, Integer dataId, Networkable networkable)
{
Map<Integer, Networkable> map = networkables.get(clientId);
if (map == null)
{
map = new HashMap<>();
networkables.put(clientId, map);
}
map.put(dataId, networkable);
}

private Networkable getNetworkable(Integer clientId, Integer dataId)
private void setNetworkable(Integer dataId, Networkable networkable)
{
Map<Integer, Networkable> map = networkables.get(clientId);
if (map == null)
{
map = new HashMap<>();
networkables.put(clientId, map);
}
return map.get(dataId);
networkables.put(dataId, networkable);
}

private boolean containsSynced(Integer clientId, Integer dataId)
private Networkable getNetworkable(Integer dataId)
{
final Set<Integer> pending = synced.get(clientId);
if (pending != null)
{
return pending.contains(dataId);
}
return false;
}

private void addSynced(Integer clientId, Integer dataId)
{
Set<Integer> pending = synced.get(clientId);
if (pending == null)
{
pending = new HashSet<>();
synced.put(clientId, pending);
}
pending.add(dataId);
return networkables.get(dataId);
}

private void handleDisconnect(Packet packet)
{
final Integer clientId = Integer.valueOf(packet.getDataId());
final Map<Integer, Networkable> map = networkables.get(clientId);
if (map != null)
final List<Integer> toRemove = new ArrayList<>();
for (final Networkable networkable : networkables.values())
{
for (final Networkable networkable : map.values())
if (clientId.equals(networkable.getClientId()))
{
toRemove.add(Integer.valueOf(networkable.getDataId()));
networkable.onDisconnected();
}
networkables.remove(clientId);
}
for (final Integer id : toRemove)
{
networkables.remove(id);
}
}

private void handleIdentifiableGet(Packet packet)
{
final int dataId = packet.getDataId();
final Integer dataIdKey = Integer.valueOf(dataId);
final Featurable featurable = handler.get(dataIdKey);
if (featurable != null)
final Featurable featurable = handler.get(Integer.valueOf(dataId));
if (featurable != null && server != null && featurable.getFeature(Networkable.class).isSynced())
{
if (server != null && featurable.getFeature(Networkable.class).isSynced())
{
send(new IdentifiableCreate(UtilNetwork.SERVER_ID,
packet.getClientSourceId(),
dataId,
featurable.getMedia()),
packet.getClientId());
}
else if (client != null && !featurable.getFeature(Networkable.class).isSynced())
{
send(new IdentifiableCreate(client.getClientId(),
packet.getClientSourceId(),
dataId,
featurable.getMedia()));
}
send(new IdentifiableCreate(featurable.getFeature(Networkable.class).getClientId(), featurable),
packet.getClientId());
}
}

private void handleIdentifiableCreate(Packet packet)
{
packet.buffer().position(MessageAbstract.SIZE_MIN + UtilNetwork.INDEX_MODE);
int dataId = packet.readInt();
final Integer clientSourceId = packet.getClientSourceId();
final int dataId = packet.readInt();
final Integer dataIdKey = Integer.valueOf(dataId);
if (!containsSynced(packet.getClientSourceId(), dataIdKey))
if (!synced.contains(dataIdKey))
{
addSynced(packet.getClientSourceId(), dataIdKey);
synced.add(dataIdKey);

final float x = packet.readFloat();
final float y = packet.readFloat();
final Featurable featurable = factory.create(packet.readMedia());
final Networkable networkable = featurable.getFeature(Networkable.class);
if (server != null)
{
dataId = featurable.getFeature(Identifiable.class).getId().intValue();
send(new IdentifiableSet(UtilNetwork.SERVER_ID, packet.getClientSourceId(), packet.getDataId(), dataId),
packet.getClientId());
networkable.setSynced(true);
}
else if (client != null && !packet.getClientId().equals(packet.getClientSourceId()))

if (client != null)
{
setNetworkable(Integer.valueOf(dataId), networkable);
networkable.setDataId(dataId);
networkable.setClientId(clientSourceId);
networkable.setSynced(true);
networkable.ifIs(Transformable.class, t -> t.teleport(x, y));
handler.add(featurable);
}

setNetworkable(packet.getClientSourceId(), Integer.valueOf(dataId), networkable);
networkable.setClientId(packet.getClientSourceId());
networkable.setDataId(dataId);
handler.add(featurable);
}
}

private void handleIdentifiableSet(Packet packet)
{
if (client != null)
{
packet.buffer().position(MessageAbstract.SIZE_MIN + UtilNetwork.INDEX_MODE);
final Integer clientDataId = Integer.valueOf(packet.readInt());
final Networkable networkable = handler.get(clientDataId).getFeature(Networkable.class);
final int serverDataId = packet.readInt();
networkable.setDataId(serverDataId);
networkable.setSynced(true);

networkables.get(packet.getClientSourceId()).remove(clientDataId);
setNetworkable(packet.getClientSourceId(), Integer.valueOf(serverDataId), networkable);
}
}

private void handleData(Packet packet)
{
packet.buffer().position(MessageAbstract.SIZE_MIN + UtilNetwork.INDEX_DATA_ID + 2);
final Integer clientId = packet.getClientSourceId();

final Integer dataId = Integer.valueOf(packet.getDataId());
final Networkable networkable = getNetworkable(dataId);

final Networkable networkable = getNetworkable(clientId, dataId);
if (networkable != null)
{
networkable.onReceived(packet);
}
else
else if (client != null)
{
if (server != null)
{
send(new IdentifiableGet(UtilNetwork.SERVER_ID, packet.getClientSourceId(), packet.getDataId()),
packet.getClientId());
}
else if (client != null)
{
send(new IdentifiableGet(client.getClientId(), packet.getClientSourceId(), packet.getDataId()));
}
send(new IdentifiableGet(client.getClientId(), packet.getDataId()));
}
else if (server != null)
{
Verbose.critical(getClass(),
"handleData",
"Unknown id: " + client.getClientId() + " " + packet.getDataId());
}
}

Expand All @@ -326,10 +265,6 @@ else if (mode == MODE_IDENTIFIABLE_GET)
{
handleIdentifiableGet(packet);
}
else if (mode == MODE_IDENTIFIABLE_SET)
{
handleIdentifiableSet(packet);
}
else if (mode == MODE_IDENTIFIABLE_CREATE)
{
handleIdentifiableCreate(packet);
Expand All @@ -352,19 +287,10 @@ public void notifyHandlableAdded(Featurable featurable)
if (n.getClientId() == null)
{
n.setClientId(UtilNetwork.SERVER_ID);
n.setDataId(id.intValue());
n.setSynced(true);
setNetworkable(UtilNetwork.SERVER_ID, id, n);
}
}
else if (client != null)
{
if (n.getClientId() == null)
{
n.setClientId(client.getClientId());
n.setDataId(id.intValue());
setNetworkable(client.getClientId(), id, n);
}
n.setDataId(id.intValue());
n.setSynced(true);
setNetworkable(id, n);
}
});
}
Expand All @@ -376,12 +302,9 @@ public void notifyHandlableRemoved(Featurable featurable)
{
n.setDataId(-1);
final Integer id = featurable.getFeature(Identifiable.class).getId();
final Map<Integer, Networkable> map = networkables.get(n.getClientId());
if (map != null)
{
map.remove(id);
}
networkables.remove(id);
n.setClientId(null);
n.setSynced(false);
});
}
}
Loading

0 comments on commit f67de69

Please # to comment.