package electrosphere.net.synchronization.client; import electrosphere.entity.state.item.ClientChargeState; import electrosphere.entity.state.movement.editor.ClientEditorMovementTree; import electrosphere.entity.state.equip.ClientToolbarState; import electrosphere.entity.state.stance.ClientStanceComponent; import electrosphere.entity.state.movement.sprint.ClientSprintTree; import electrosphere.entity.state.movement.jump.ClientJumpTree; import electrosphere.entity.state.movement.walk.ClientWalkTree; import electrosphere.entity.state.life.ClientLifeTree; import electrosphere.entity.state.block.ClientBlockTree; import electrosphere.entity.state.movement.groundmove.ClientGroundMovementTree; import electrosphere.logger.LoggerInterface; import electrosphere.entity.state.attack.ClientAttackTree; import electrosphere.entity.state.gravity.ClientGravityTree; import electrosphere.entity.state.idle.ClientIdleTree; import java.util.HashMap; import java.util.LinkedList; import java.util.List; import java.util.Map; import java.util.concurrent.CopyOnWriteArrayList; import electrosphere.engine.Globals; import electrosphere.entity.Entity; import electrosphere.net.parser.net.message.SynchronizationMessage; import electrosphere.net.synchronization.enums.BehaviorTreeIdEnums; import electrosphere.net.synchronization.enums.FieldIdEnums; /** * Takes in raw behavior tree packets from server and pushes their values into respective behavior trees in entities */ public class ClientSynchronizationManager { /** * The list of messages to loop through */ List messages = new CopyOnWriteArrayList(); /** * Map that tracks the number of times a network message bounces */ Map messageBounceCount = new HashMap(); /** * The count at which to warn about a message bouncing */ static final int MESSAGE_BOUNCE_WARNING_COUNT = 10; /** * Pushes a message into the queue to be processed * @param message The message */ public void pushMessage(SynchronizationMessage message){ this.messages.add(message); } /** * Processes all messages in the queue and then clears the queue */ public void processMessages(){ List messagesToClear = new LinkedList(); for(SynchronizationMessage message : messages){ //track number of times this message has bounced if(messageBounceCount.containsKey(message)){ messageBounceCount.put(message, messageBounceCount.get(message) + 1); } else { messageBounceCount.put(message, 0); } //attempt to handle the message if(Globals.clientSceneWrapper.containsServerId(message.getentityId()) && Globals.clientSceneWrapper.getEntityFromServerId(message.getentityId()) != null){ messagesToClear.add(message); messageBounceCount.remove(message); switch(message.getMessageSubtype()){ case UPDATECLIENTSTATE: case UPDATECLIENTDOUBLESTATE: case UPDATECLIENTFLOATSTATE: case UPDATECLIENTINTSTATE: case UPDATECLIENTLONGSTATE: case UPDATECLIENTSTRINGSTATE:{ int bTreeId = message.getbTreeId(); int entityId = message.getentityId(); Entity targetEntity = Globals.clientSceneWrapper.getEntityFromServerId(entityId); this.updateEntityState(targetEntity,bTreeId,message); } break; case SERVERNOTIFYBTREETRANSITION: { int bTreeId = message.getbTreeId(); int entityId = message.getentityId(); Entity targetEntity = Globals.clientSceneWrapper.getEntityFromServerId(entityId); this.transitionBTree(targetEntity, bTreeId, message); } break; case ATTACHTREE:{ // int bTreeId = message.getbTreeId(); // int bTreeValue = message.getbTreeValue(); // int entityId = message.getentityId(); throw new UnsupportedOperationException("Not implemented yet!"); } case DETATCHTREE:{ // int bTreeId = message.getbTreeId(); // int entityId = message.getentityId(); throw new UnsupportedOperationException("Not implemented yet!"); } case LOADSCENE: { throw new UnsupportedOperationException("Not implemented yet!"); } case CLIENTREQUESTBTREEACTION: //silently ignore break; } } else if(Globals.clientSceneWrapper.containsServerId(message.getentityId()) && Globals.clientSceneWrapper.getEntityFromServerId(message.getentityId()) == null){ String errorMessage = "Client received synchronization packet for entity that does not exists on client!\n" + "Specifically, the synchronization manager thinks this id is registered, but there is no entity at that key\n" + "Entity id in network message: " + message.getentityId() ; Globals.clientSceneWrapper.dumpTranslationLayerStatus(); Globals.clientSceneWrapper.dumpIdData(message.getentityId()); Globals.clientSceneWrapper.getScene().describeScene(); throw new IllegalStateException(errorMessage); } else if(!Globals.clientSceneWrapper.containsServerId(message.getentityId()) && !Globals.clientSceneWrapper.hasBeenDeleted(message.getentityId())){ //TODO: have client send query to server to resend this entity // 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); } //warn if a message has bounced a certain number of times if(messageBounceCount.containsKey(message) && messageBounceCount.get(message) > MESSAGE_BOUNCE_WARNING_COUNT){ String warningMessage = "A synchronization message has bounced at least " + MESSAGE_BOUNCE_WARNING_COUNT + "times!"; LoggerInterface.loggerNetworking.WARNING(warningMessage); } } for(SynchronizationMessage message : messagesToClear){ messages.remove(message); Globals.clientConnection.release(message); } } /** *

Automatically generated

*

* Updates the state of a given behavior tree on a given entity *

* @param entity The entity * @param bTreeId The id of the behavior tree * @param message The raw synchronization message holding the update data */ private void updateEntityState(Entity entity, int bTreeId, SynchronizationMessage message){ switch(bTreeId){ case BehaviorTreeIdEnums.BTREE_SERVERATTACKTREE_ID: { switch(message.getfieldId()){ case FieldIdEnums.TREE_SERVERATTACKTREE_SYNCEDFIELD_STATE_ID:{ ClientAttackTree tree = ClientAttackTree.getClientAttackTree(entity); tree.setState(ClientAttackTree.getAttackTreeStateShortAsEnum((short)message.getbTreeValue())); } break; case FieldIdEnums.TREE_SERVERATTACKTREE_SYNCEDFIELD_DRIFTSTATE_ID:{ ClientAttackTree tree = ClientAttackTree.getClientAttackTree(entity); tree.setDriftState(ClientAttackTree.getAttackTreeDriftStateShortAsEnum((short)message.getbTreeValue())); } break; case FieldIdEnums.TREE_SERVERATTACKTREE_SYNCEDFIELD_CURRENTMOVEID_ID:{ ClientAttackTree tree = ClientAttackTree.getClientAttackTree(entity); tree.setCurrentMoveId(message.getstringValue()); } break; } } break; case BehaviorTreeIdEnums.BTREE_SERVERBLOCKTREE_ID: { switch(message.getfieldId()){ case FieldIdEnums.TREE_SERVERBLOCKTREE_SYNCEDFIELD_STATE_ID:{ ClientBlockTree tree = ClientBlockTree.getClientBlockTree(entity); tree.setState(ClientBlockTree.getBlockStateShortAsEnum((short)message.getbTreeValue())); } break; case FieldIdEnums.TREE_SERVERBLOCKTREE_SYNCEDFIELD_CURRENTBLOCKVARIANT_ID:{ ClientBlockTree tree = ClientBlockTree.getClientBlockTree(entity); tree.setCurrentBlockVariant(message.getstringValue()); } break; } } break; case BehaviorTreeIdEnums.BTREE_SERVEREQUIPSTATE_ID: { switch(message.getfieldId()){ } } break; case BehaviorTreeIdEnums.BTREE_SERVERTOOLBARSTATE_ID: { switch(message.getfieldId()){ case FieldIdEnums.TREE_SERVERTOOLBARSTATE_SYNCEDFIELD_SELECTEDSLOT_ID:{ ClientToolbarState tree = ClientToolbarState.getClientToolbarState(entity); tree.setSelectedSlot(message.getintValue()); } break; } } break; case BehaviorTreeIdEnums.BTREE_SERVERGRAVITY_ID: { switch(message.getfieldId()){ case FieldIdEnums.TREE_SERVERGRAVITY_SYNCEDFIELD_STATE_ID:{ ClientGravityTree tree = ClientGravityTree.getClientGravityTree(entity); tree.setState(ClientGravityTree.getGravityTreeStateShortAsEnum((short)message.getbTreeValue())); } break; } } break; case BehaviorTreeIdEnums.BTREE_SERVERIDLE_ID: { switch(message.getfieldId()){ case FieldIdEnums.TREE_SERVERIDLE_SYNCEDFIELD_STATE_ID:{ ClientIdleTree tree = ClientIdleTree.getClientIdleTree(entity); tree.setState(ClientIdleTree.getIdleTreeStateShortAsEnum((short)message.getbTreeValue())); } break; } } break; case BehaviorTreeIdEnums.BTREE_SERVERCHARGESTATE_ID: { switch(message.getfieldId()){ case FieldIdEnums.TREE_SERVERCHARGESTATE_SYNCEDFIELD_CHARGES_ID:{ ClientChargeState tree = ClientChargeState.getClientChargeState(entity); tree.setCharges(message.getintValue()); } break; } } break; case BehaviorTreeIdEnums.BTREE_SERVERLIFETREE_ID: { switch(message.getfieldId()){ case FieldIdEnums.TREE_SERVERLIFETREE_SYNCEDFIELD_STATE_ID:{ ClientLifeTree tree = ClientLifeTree.getClientLifeTree(entity); tree.setState(ClientLifeTree.getLifeStateEnumShortAsEnum((short)message.getbTreeValue())); } break; } } break; case BehaviorTreeIdEnums.BTREE_SERVERSTANCECOMPONENT_ID: { switch(message.getfieldId()){ case FieldIdEnums.TREE_SERVERSTANCECOMPONENT_SYNCEDFIELD_STATE_ID:{ ClientStanceComponent tree = ClientStanceComponent.getClientStanceComponent(entity); tree.setState(ClientStanceComponent.getCombatStanceShortAsEnum((short)message.getbTreeValue())); } break; } } break; case BehaviorTreeIdEnums.BTREE_SERVEREDITORMOVEMENTTREE_ID: { switch(message.getfieldId()){ case FieldIdEnums.TREE_SERVEREDITORMOVEMENTTREE_SYNCEDFIELD_FACING_ID:{ ClientEditorMovementTree tree = ClientEditorMovementTree.getClientEditorMovementTree(entity); tree.setFacing(ClientEditorMovementTree.getEditorMovementRelativeFacingShortAsEnum((short)message.getbTreeValue())); } break; } } break; case BehaviorTreeIdEnums.BTREE_SERVERGROUNDMOVEMENTTREE_ID: { switch(message.getfieldId()){ case FieldIdEnums.TREE_SERVERGROUNDMOVEMENTTREE_SYNCEDFIELD_FACING_ID:{ ClientGroundMovementTree tree = ClientGroundMovementTree.getClientGroundMovementTree(entity); tree.setFacing(ClientGroundMovementTree.getMovementRelativeFacingShortAsEnum((short)message.getbTreeValue())); } break; } } break; case BehaviorTreeIdEnums.BTREE_SERVERJUMPTREE_ID: { switch(message.getfieldId()){ case FieldIdEnums.TREE_SERVERJUMPTREE_SYNCEDFIELD_STATE_ID:{ ClientJumpTree tree = ClientJumpTree.getClientJumpTree(entity); tree.setState(ClientJumpTree.getJumpStateShortAsEnum((short)message.getbTreeValue())); } break; case FieldIdEnums.TREE_SERVERJUMPTREE_SYNCEDFIELD_CURRENTFRAME_ID:{ ClientJumpTree tree = ClientJumpTree.getClientJumpTree(entity); tree.setCurrentFrame(message.getintValue()); } break; case FieldIdEnums.TREE_SERVERJUMPTREE_SYNCEDFIELD_CURRENTJUMPFORCE_ID:{ ClientJumpTree tree = ClientJumpTree.getClientJumpTree(entity); tree.setCurrentJumpForce(message.getfloatValue()); } break; } } break; case BehaviorTreeIdEnums.BTREE_SERVERSPRINTTREE_ID: { switch(message.getfieldId()){ case FieldIdEnums.TREE_SERVERSPRINTTREE_SYNCEDFIELD_STATE_ID:{ ClientSprintTree tree = ClientSprintTree.getClientSprintTree(entity); tree.setState(ClientSprintTree.getSprintTreeStateShortAsEnum((short)message.getbTreeValue())); } break; } } break; case BehaviorTreeIdEnums.BTREE_SERVERWALKTREE_ID: { switch(message.getfieldId()){ case FieldIdEnums.TREE_SERVERWALKTREE_SYNCEDFIELD_STATE_ID:{ ClientWalkTree tree = ClientWalkTree.getClientWalkTree(entity); tree.setState(ClientWalkTree.getWalkStateShortAsEnum((short)message.getbTreeValue())); } break; } } break; } } /** *

Automatically generated

*

* Transitions a behavior tree to a new state *

* @param entity The entity * @param bTreeId The id of the behavior tree * @param message The raw synchronization message holding the update data */ private void transitionBTree(Entity entity, int bTreeId, SynchronizationMessage message){ switch(bTreeId){ case BehaviorTreeIdEnums.BTREE_SERVERATTACKTREE_ID: { switch(message.getfieldId()){ case FieldIdEnums.TREE_SERVERATTACKTREE_SYNCEDFIELD_STATE_ID:{ ClientAttackTree tree = ClientAttackTree.getClientAttackTree(entity); tree.transitionState(ClientAttackTree.getAttackTreeStateShortAsEnum((short)message.getbTreeValue())); } break; } } break; case BehaviorTreeIdEnums.BTREE_SERVERBLOCKTREE_ID: { switch(message.getfieldId()){ case FieldIdEnums.TREE_SERVERBLOCKTREE_SYNCEDFIELD_STATE_ID:{ ClientBlockTree tree = ClientBlockTree.getClientBlockTree(entity); tree.transitionState(ClientBlockTree.getBlockStateShortAsEnum((short)message.getbTreeValue())); } break; } } break; case BehaviorTreeIdEnums.BTREE_SERVERJUMPTREE_ID: { switch(message.getfieldId()){ case FieldIdEnums.TREE_SERVERJUMPTREE_SYNCEDFIELD_STATE_ID:{ ClientJumpTree tree = ClientJumpTree.getClientJumpTree(entity); tree.transitionState(ClientJumpTree.getJumpStateShortAsEnum((short)message.getbTreeValue())); } break; } } break; } } }