network entity id translation fixes
Some checks failed
studiorailgun/Renderer/pipeline/head There was a failure building this commit

This commit is contained in:
austin 2024-08-28 12:20:30 -04:00
parent ab00782e93
commit 0a74bed5d6
11 changed files with 59 additions and 13 deletions

View File

@ -26,6 +26,9 @@ public class ClientSceneWrapper {
Map<Integer,Integer> clientToServerIdMap = new ConcurrentHashMap<Integer,Integer>();
Map<Integer,Integer> serverToClientIdMap = new ConcurrentHashMap<Integer,Integer>();
//The list of server IDs that have been deleted
Map<Integer,Boolean> deletedServerIds = new ConcurrentHashMap<Integer,Boolean>();
//The scene backing the wrapper
Scene scene;
@ -52,7 +55,7 @@ public class ClientSceneWrapper {
* @param serverId The server's provided ID
*/
public void mapIdToId(int clientId, int serverId){
LoggerInterface.loggerNetworking.DEBUG("MapID: " + clientId + " <===> " + serverId);
LoggerInterface.loggerNetworking.DEBUG("[CLIENT] MapID: " + clientId + " <===> " + serverId);
clientToServerIdMap.put(clientId, serverId);
serverToClientIdMap.put(serverId, clientId);
}
@ -103,6 +106,30 @@ public class ClientSceneWrapper {
return clientToServerIdMap.containsKey(id);
}
/**
* Deregisters the translation mapping for this entity
* @param clientEntity The client entity
*/
public void deregisterTranslationMapping(Entity clientEntity){
if(clientToServerMapContainsId(clientEntity.getId())){
//remove from client->server map
int serverId = clientToServerIdMap.remove(clientEntity.getId());
//remove from server->client map
serverToClientIdMap.remove(serverId);
deletedServerIds.put(serverId,true);
LoggerInterface.loggerNetworking.DEBUG("[CLIENT] Remove scene from client<->server translation layer: " + clientEntity.getId() + "<->" + serverId);
}
}
/**
* Checks if the client scene wrapper has deleted this id or not
* @param serverId The server id
* @return true if it was registered at one point and has since been deleted, false otherwise
*/
public boolean hasBeenDeleted(int serverId){
return deletedServerIds.containsKey(serverId);
}
/**
* Gets the entity provided a server-provided id
@ -139,7 +166,7 @@ public class ClientSceneWrapper {
if(clientToServerIdMap.containsKey(id)){
LoggerInterface.loggerNetworking.WARNING("Client->Server Map entity: " + clientToServerIdMap.get(id));
}
if(clientToServerIdMap.containsKey(id)){
if(serverToClientIdMap.containsKey(id)){
LoggerInterface.loggerNetworking.WARNING("Server->Client Map entity: " + serverToClientIdMap.get(id));
}
}

View File

@ -120,6 +120,7 @@ public class EntityUtils {
public static void cleanUpEntity(Entity e){
//remove from client
Globals.clientSceneWrapper.getScene().deregisterEntity(e);
Globals.clientSceneWrapper.deregisterTranslationMapping(e);
//remove from all server classes
if(Globals.realmManager != null){
Realm realm = Globals.realmManager.getEntityRealm(e);

View File

@ -3,6 +3,7 @@ package electrosphere.entity;
import electrosphere.engine.Globals;
import electrosphere.entity.btree.BehaviorTree;
import electrosphere.entity.types.attach.AttachUtils;
import electrosphere.logger.LoggerInterface;
import java.util.List;
import java.util.Map;
@ -158,4 +159,14 @@ public class Scene {
return entityList;
}
/**
* Describes the scene in log messages
*/
public void describeScene(){
LoggerInterface.loggerEngine.WARNING("Entities present in scene:");
for(Entity entity : this.entityList){
LoggerInterface.loggerEngine.WARNING(entity.getId() + "");
}
}
}

View File

@ -12,6 +12,7 @@ import electrosphere.entity.state.equip.ServerEquipState;
import electrosphere.entity.state.gravity.GravityUtils;
import electrosphere.entity.types.creature.CreatureUtils;
import electrosphere.entity.types.item.ItemUtils;
import electrosphere.logger.LoggerInterface;
import electrosphere.net.parser.net.message.EntityMessage;
import electrosphere.net.parser.net.message.InventoryMessage;
import electrosphere.net.parser.net.message.NetworkMessage;
@ -103,7 +104,6 @@ public class InventoryUtils {
//if we are the server, immediately send required packets
ServerDataCell dataCell = DataCellSearchUtils.getEntityDataCell(item);
// ServerDataCell dataCell = Globals.dataCellLocationResolver.getDataCellAtPoint(EntityUtils.getPosition(item),item);
dataCell.getScene().deregisterEntity(item);
//broadcast destroy entity
dataCell.broadcastNetworkMessage(EntityMessage.constructDestroyMessage(item.getId()));
//tell controlling player that they have an item in their inventory
@ -166,6 +166,7 @@ public class InventoryUtils {
UnrelationalInventoryState inventory = getNaturalInventory(parentContainer);
//create item
//TODO: optimize by directly creating the container item instead of first spawning regular item
LoggerInterface.loggerNetworking.DEBUG("[CLIENT] Spawning temporary in-world item before placing into inventory");
Entity spawnedItem = ItemUtils.clientSpawnBasicItem(type);
//convert to in-inventory
Entity inventoryItem = ItemUtils.clientRecreateContainerItem(spawnedItem, parentContainer);

View File

@ -30,7 +30,7 @@ public class LoggerInterface {
*/
public static void initLoggers(){
loggerStartup = new Logger("Startup", LogLevel.WARNING);
loggerNetworking = new Logger("Networking", LogLevel.WARNING);
loggerNetworking = new Logger("Networking", LogLevel.DEBUG);
loggerFileIO = new Logger("File IO", LogLevel.WARNING);
loggerGameLogic = new Logger("Game Logic", LogLevel.WARNING);
loggerRenderer = new Logger("Renderer", LogLevel.WARNING);

View File

@ -21,7 +21,7 @@ public class NetUtils {
// }
public static EntityMessage createSetCreatureControllerIdEntityMessage(Entity e){
LoggerInterface.loggerNetworking.DEBUG("Entity " + e.getId() + " set controller id: " + CreatureUtils.getControllerPlayerId(e));
LoggerInterface.loggerNetworking.DEBUG("[CLIENT] Entity " + e.getId() + " set controller id: " + CreatureUtils.getControllerPlayerId(e));
EntityMessage rVal = EntityMessage.constructsetPropertyMessage(e.getId(), System.currentTimeMillis(), 0, CreatureUtils.getControllerPlayerId(e));
return rVal;
}

View File

@ -91,7 +91,7 @@ public class EntityProtocol implements ClientProtocolTemplate<EntityMessage> {
}
break;
case SPAWNCREATURE: {
LoggerInterface.loggerNetworking.DEBUG("Spawn Creature " + message.getentityID() + " at " + message.getpositionX() + " " + message.getpositionY() + " " + message.getpositionZ());
LoggerInterface.loggerNetworking.DEBUG("[CLIENT] Spawn Creature " + message.getentityID() + " at " + message.getpositionX() + " " + message.getpositionY() + " " + message.getpositionZ());
CreatureTemplate template = Utilities.deserialize(message.getcreatureTemplate(), CreatureTemplate.class);
newlySpawnedEntity = CreatureUtils.clientSpawnBasicCreature(template.getCreatureType(),template);
ClientEntityUtils.initiallyPositionEntity(
@ -122,7 +122,7 @@ public class EntityProtocol implements ClientProtocolTemplate<EntityMessage> {
}
} break;
case SPAWNITEM: {
LoggerInterface.loggerNetworking.DEBUG("Spawn Item " + message.getentityID() + " at " + message.getpositionX() + " " + message.getpositionY() + " " + message.getpositionZ());
LoggerInterface.loggerNetworking.DEBUG("[CLIENT] Spawn Item " + message.getentityID() + " at " + message.getpositionX() + " " + message.getpositionY() + " " + message.getpositionZ());
//spawn item
String itemType = message.getcreatureTemplate();
newlySpawnedEntity = ItemUtils.clientSpawnBasicItem(itemType);
@ -135,7 +135,7 @@ public class EntityProtocol implements ClientProtocolTemplate<EntityMessage> {
Globals.clientSceneWrapper.mapIdToId(newlySpawnedEntity.getId(), message.getentityID());
} break;
case SPAWNFOLIAGESEED: {
LoggerInterface.loggerNetworking.DEBUG("Spawn foliage " + message.getentityID() + " at " + message.getpositionX() + " " + message.getpositionY() + " " + message.getpositionZ());
LoggerInterface.loggerNetworking.DEBUG("[CLIENT] Spawn foliage " + message.getentityID() + " at " + message.getpositionX() + " " + message.getpositionY() + " " + message.getpositionZ());
String type = message.getcreatureTemplate();
newlySpawnedEntity = FoliageUtils.spawnBasicFoliage(type,message.getfoliageSeed());
ClientEntityUtils.initiallyPositionEntity(
@ -146,7 +146,7 @@ public class EntityProtocol implements ClientProtocolTemplate<EntityMessage> {
Globals.clientSceneWrapper.mapIdToId(newlySpawnedEntity.getId(), message.getentityID());
} break;
case SPAWNOBJECT: {
LoggerInterface.loggerNetworking.DEBUG("Spawn object " + message.getentityID() + " at " + message.getpositionX() + " " + message.getpositionY() + " " + message.getpositionZ());
LoggerInterface.loggerNetworking.DEBUG("[CLIENT] Spawn object " + message.getentityID() + " at " + message.getpositionX() + " " + message.getpositionY() + " " + message.getpositionZ());
//spawn item
String objectType = message.getcreatureTemplate();
newlySpawnedEntity = ObjectUtils.clientSpawnBasicObject(objectType);

View File

@ -24,7 +24,7 @@ public class PlayerProtocol implements ClientProtocolTemplate<PlayerMessage> {
switch(message.getMessageSubtype()){
case SET_ID:
Globals.clientPlayer = new Player(message.getplayerID());
LoggerInterface.loggerNetworking.DEBUG("Player ID is " + Globals.clientPlayer.getId());
LoggerInterface.loggerNetworking.DEBUG("[CLIENT] Player ID is " + Globals.clientPlayer.getId());
break;
case SETINITIALDISCRETEPOSITION:
Globals.clientPlayerData.setWorldPos(new Vector3i(message.getinitialDiscretePositionX(), message.getinitialDiscretePositionY(), message.getinitialDiscretePositionZ()));

View File

@ -94,7 +94,7 @@ public class ServerConnectionHandler implements Runnable {
public ServerConnectionHandler(Socket socket) {
this.socket = socket;
this.playerID = Player.getNewId();
LoggerInterface.loggerNetworking.INFO("Player ID: " + playerID);
LoggerInterface.loggerNetworking.INFO("[SERVER] Player ID: " + playerID);
this.messageProtocol = new MessageProtocol(this);
}
@ -106,7 +106,7 @@ public class ServerConnectionHandler implements Runnable {
public ServerConnectionHandler(InputStream serverInputStream, OutputStream serverOutputStream){
this.local = true;
this.playerID = Player.getNewId();
LoggerInterface.loggerNetworking.INFO("Player ID: " + playerID);
LoggerInterface.loggerNetworking.INFO("[SERVER] Player ID: " + playerID);
inputStream = serverInputStream;
outputStream = serverOutputStream;
this.messageProtocol = new MessageProtocol(this);

View File

@ -108,14 +108,17 @@ public class ClientSynchronizationManager {
;
Globals.clientSceneWrapper.dumpTranslationLayerStatus();
Globals.clientSceneWrapper.dumpIdData(message.getentityId());
Globals.clientSceneWrapper.getScene().describeScene();
throw new IllegalStateException(errorMessage);
} else if(!Globals.clientSceneWrapper.containsServerId(message.getentityId())){
} else if(!Globals.clientSceneWrapper.containsServerId(message.getentityId()) && !Globals.clientSceneWrapper.hasBeenDeleted(message.getentityId())){
String errorMessage =
"Client received synchronization packet for entity that does not exists on client!\n" +
"This ID was never created on the client, yet the client is receiving a synchronization packet for it!\n" +
"Entity id in network message: " + message.getentityId()
;
Globals.clientSceneWrapper.dumpTranslationLayerStatus();
Globals.clientSceneWrapper.dumpIdData(message.getentityId());
Globals.clientSceneWrapper.getScene().describeScene();
throw new IllegalStateException(errorMessage);
}

View File

@ -73,6 +73,9 @@ public class ServerEquipStateTests extends EntityTestTemplate {
ServerEquipState serverEquipState = ServerEquipState.getServerEquipState(creature);
serverEquipState.commandAttemptEquip(inInventoryItem, serverEquipState.getEquipPoint("handsCombined"));
//render a frame so network propagates to client
TestEngineUtils.simulateFrames(1);
//attempt to equip second katana
Entity inInventoryItem2 = InventoryUtils.serverAttemptStoreItem(creature, katana2);
serverEquipState.commandAttemptEquip(inInventoryItem2, serverEquipState.getEquipPoint("handsCombined"));