290 lines
		
	
	
		
			15 KiB
		
	
	
	
		
			Java
		
	
	
	
	
	
			
		
		
	
	
			290 lines
		
	
	
		
			15 KiB
		
	
	
	
		
			Java
		
	
	
	
	
	
| package electrosphere.net.synchronization.client;
 | |
| 
 | |
| 
 | |
| import electrosphere.entity.state.movement.sprint.ClientSprintTree;
 | |
| import electrosphere.entity.state.equip.ClientEquipState;
 | |
| 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<SynchronizationMessage> messages = new CopyOnWriteArrayList<SynchronizationMessage>();
 | |
| 
 | |
|     //Map that tracks the number of times a network message bounces
 | |
|     Map<SynchronizationMessage,Integer> messageBounceCount = new HashMap<SynchronizationMessage,Integer>();
 | |
| 
 | |
|     //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<SynchronizationMessage> messagesToClear = new LinkedList<SynchronizationMessage>();
 | |
|         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);
 | |
|                         updateEntityState(targetEntity,bTreeId,message);
 | |
|                     } break;
 | |
|                     case SERVERNOTIFYBTREETRANSITION: {
 | |
|                         int bTreeId = message.getbTreeId();
 | |
|                         int entityId = message.getentityId();
 | |
|                         Entity targetEntity = Globals.clientSceneWrapper.getEntityFromServerId(entityId);
 | |
|                         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);
 | |
|         }
 | |
|     }
 | |
| 
 | |
|     /**
 | |
|      * <p> Automatically generated </p>
 | |
|      * <p>
 | |
|      * Updates the state of a given behavior tree on a given entity
 | |
|      * </p>
 | |
|      * @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_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_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_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;
 | |
|     
 | |
|         }
 | |
|     }
 | |
| 
 | |
|     /**
 | |
|      * <p> Automatically generated </p>
 | |
|      * <p>
 | |
|      * Transitions a behavior tree to a new state
 | |
|      * </p>
 | |
|      * @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;
 | |
|     
 | |
|         }
 | |
|     }
 | |
|     
 | |
| }
 |