//listen for requests void messageReceivedListener(byte[] _message, int clientID) { Debug.Log(String.Format("<<<Thread {0}>>>: Recieved \"{1}\"", clientID, MessagePackSerializer.ConvertToJson(_message))); //test if we've recieved a sceneObjects request if ((MultiPossibleRequest)MessagePackSerializer.Deserialize <MultiBaseRequest>(_message).RT == MultiPossibleRequest.MultiInitialData) { //we have, relay it to the thread requesting it(the most recent connection) MultiBaseRequest baseRequest = MessagePackSerializer.Deserialize <MultiBaseRequest>(_message); MultiInitialData sceneObjects = MessagePackSerializer.Deserialize <MultiInitialData>(baseRequest.R); SendMessageToClient(_message, sceneObjects.tN); return; } //relay the message to all other clients foreach (int key in listenerThreads.Keys) { if (key != clientID) { SendMessageToClient(_message, key); } } }
private IEnumerator HandleMultiInitialData(MultiInitialData multiSceneObjects) { //clear the old synced objects dict and destroy the old synced objects foreach (int key in syncedObjects.Keys) { Debug.Log(String.Format("MultiClient.cs:269 Destroying {0}", syncedObjects[key].gameObject.name)); Destroy(syncedObjects[key].gameObject); syncedObjects.Remove(key); } //queue the scene change(maybe) SceneManager.LoadScene(possibleScenes[multiSceneObjects.sI].name); currentScene = possibleScenes[multiSceneObjects.sI]; yield return(new WaitForSeconds(0.1f)); //queue spawning the new objects Dictionary <int, int> newSyncedObjects = multiSceneObjects.syncedObjDict(); foreach (int key in newSyncedObjects.Keys) { SpawnObjectWithoutSetup(newSyncedObjects[key], key); } //reset the synced objects total syncedObjectsTotal = newSyncedObjects.Count; actions.Enqueue(() => { //get all of the systems in this scene GameObject[] systems = GameObject.FindGameObjectsWithTag("GameSystem"); //iterate through them, storing a reference to each of them foreach (GameObject system in systems) { if (gameSystems.TryGetValue(system.GetComponent <GameSystem>().SystemID, out _)) { gameSystems[system.GetComponent <GameSystem>().SystemID] = system.GetComponent <GameSystem>(); } else { gameSystems.Add(system.GetComponent <GameSystem>().SystemID, system.GetComponent <GameSystem>()); } } }); //spawn our prefab on the network MultiSpawnPlayer spawnPlayerScene = new MultiSpawnPlayer((int)inputMethod, _ClientID, TeamSystem.Team.A, PlayerName); //FindObjectOfType<TeamSystem>().localTeam); MultiBaseRequest spawnPlayerBaseScene = new MultiBaseRequest(MultiPossibleRequest.MultiSpawnPlayer, MessagePackSerializer.Serialize(spawnPlayerScene)); SendMessageToServer(MessagePackSerializer.Serialize(spawnPlayerBaseScene)); //spawn our prefab here actions.Enqueue(() => { //spawn in the new synced object instance GameObject instance = Instantiate(possibleScenes[multiSceneObjects.sI].PlayerPrefabs[(int)inputMethod]); GamePlayer player = instance.GetComponent <GamePlayer>(); //store its index and its local status player.LocalOwned = true; //store it gamePlayers[_ClientID] = player; //do setup player.PlayerSetup(_ClientID, TeamSystem.Team.A, PlayerName); //FindObjectOfType<TeamSystem>().localTeam); }); //spawn the rest of the players in Dictionary <int, Tuple <int, int, string> > newGamePlayers = multiSceneObjects.gamePlayerDict(); foreach (int key in newGamePlayers.Keys) { actions.Enqueue(() => { //spawn in the new synced object instance GameObject instance = Instantiate(possibleScenes[multiSceneObjects.sI].PlayerPrefabs[newGamePlayers[key].Item1]); GamePlayer newPlayer = instance.GetComponent <GamePlayer>(); //store it gamePlayers[key] = newPlayer; //do setup newPlayer.PlayerSetup(key, (TeamSystem.Team)newGamePlayers[key].Item2, newGamePlayers[key].Item3); }); } }
//listen for requests void messageReceivedListener(byte[] _message) { try { //get the base request object MultiBaseRequest baseRequest = MessagePackSerializer.Deserialize <MultiBaseRequest>(_message); Debug.Log(String.Format("<<<Client>>>: Recieved \"{0}\"", MessagePackSerializer.ConvertToJson(_message))); switch ((MultiPossibleRequest)baseRequest.RT) { //initial data for setup case MultiPossibleRequest.MultiInitialData: MultiInitialData initialData = MessagePackSerializer.Deserialize <MultiInitialData>(baseRequest.R); //store the thread key as the client id, they're the same thing _ClientID = initialData.T; actions.Enqueue(() => StartCoroutine(HandleMultiInitialData(initialData))); break; //the server would like to spawn an object case MultiPossibleRequest.MultiSpawnObject: MultiSpawnRequest multiSpawnRequest = MessagePackSerializer.Deserialize <MultiSpawnRequest>(baseRequest.R); //queue spawning the object actions.Enqueue(() => SpawnObject(multiSpawnRequest.I)); break; //the server would like to sync an object case MultiPossibleRequest.MultiSyncObject: MultiSyncRequest multiSyncRequest = MessagePackSerializer.Deserialize <MultiSyncRequest>(baseRequest.R); //queue the synced object handle actions.Enqueue(() => syncedObjects[multiSyncRequest.ID].HandleSyncRequest(multiSyncRequest)); break; //the server would like to change scenes case MultiPossibleRequest.MultiChangeScene: MultiChangeSceneRequest multiChangeScene = MessagePackSerializer.Deserialize <MultiChangeSceneRequest>(baseRequest.R); //queue the scene change actions.Enqueue(() => SceneManager.LoadScene(possibleScenes[multiChangeScene.N].name)); currentScene = possibleScenes[multiChangeScene.N]; actions.Enqueue(() => { //get all of the systems in this scene GameObject[] systems = GameObject.FindGameObjectsWithTag("GameSystem"); //iterate through them, storing a reference to each of them foreach (GameObject system in systems) { gameSystems.Add(system.GetComponent <GameSystem>().SystemID, system.GetComponent <GameSystem>()); } }); //reset the dictionary of players gamePlayers = new Dictionary <int, GamePlayer>(); //spawn our prefab on the network MultiSpawnPlayer spawnPlayerScene = new MultiSpawnPlayer((int)inputMethod, _ClientID, TeamSystem.Team.A, PlayerName); //FindObjectOfType<TeamSystem>().localTeam); MultiBaseRequest spawnPlayerBaseScene = new MultiBaseRequest(MultiPossibleRequest.MultiSpawnPlayer, MessagePackSerializer.Serialize(spawnPlayerScene)); SendMessageToServer(MessagePackSerializer.Serialize(spawnPlayerBaseScene)); //spawn our prefab here actions.Enqueue(() => { //spawn in the new synced object instance GameObject instance = Instantiate(possibleScenes[multiChangeScene.N].PlayerPrefabs[(int)inputMethod]); GamePlayer player = instance.GetComponent <GamePlayer>(); //store its index and its local status player.LocalOwned = true; //store it gamePlayers[_ClientID] = player; //do setup player.PlayerSetup(_ClientID, TeamSystem.Team.A, PlayerName); //FindObjectOfType<TeamSystem>().localTeam); }); break; //the server would like to sync a scene object case MultiPossibleRequest.MultiSceneSyncObject: MultiSyncRequest multiSceneSync = MessagePackSerializer.Deserialize <MultiSyncRequest>(baseRequest.R); //queue the synced object handle actions.Enqueue(() => sceneSyncedObjects[multiSceneSync.ID].HandleSyncRequest(multiSceneSync)); break; //the server wants us to take host authority case MultiPossibleRequest.MultiHostAuthChange: hostAuthority = true; break; //there's new connection to the game, send a dict of id's and indexes case MultiPossibleRequest.MultiNewConnection: MultiNewConnection newConnection = MessagePackSerializer.Deserialize <MultiNewConnection>(baseRequest.R); //dictionary of the sceneobjects with non negative indices(root objects) Dictionary <int, int> idIndexes = new Dictionary <int, int>(); foreach (int key in syncedObjects.Keys) { idIndexes.Add(key, syncedObjects[key].index); } //Send the request MultiInitialData sceneObjects = new MultiInitialData(newConnection.tN, idIndexes, gamePlayers, possibleScenes.IndexOf(currentScene), syncedObjectsTotal, newConnection.tN); MultiBaseRequest request = new MultiBaseRequest(MultiPossibleRequest.MultiInitialData, MessagePackSerializer.Serialize(sceneObjects)); SendMessageToServer(MessagePackSerializer.Serialize(request)); break; //the server would like us to despawn an object case MultiPossibleRequest.MultiDespawnObject: MultiDespawnObject despawnObject = MessagePackSerializer.Deserialize <MultiDespawnObject>(baseRequest.R); //destroy the object Debug.Log(String.Format("MultiClient.cs:291 Destroying {0}", syncedObjects[despawnObject.ID].gameObject.name)); actions.Enqueue(() => Destroy(syncedObjects[despawnObject.ID].gameObject)); break; case MultiPossibleRequest.MultiGameData: GameSystemData systemData = MessagePackSerializer.Deserialize <GameSystemData>(baseRequest.R); //pass on this data, the game system knows what to do with it actions.Enqueue(() => gameSystems[systemData.S].HandleMessage(systemData)); break; case MultiPossibleRequest.MultiSpawnPlayer: MultiSpawnPlayer spawnPlayer = MessagePackSerializer.Deserialize <MultiSpawnPlayer>(baseRequest.R); //spawn in the player and ensure it knows which client it belongs to actions.Enqueue(() => { GameObject instance = Instantiate(currentScene.PlayerPrefabs[spawnPlayer.T]); GamePlayer gamePlayer = instance.GetComponent <GamePlayer>(); //store it gamePlayers[spawnPlayer.C] = gamePlayer; //do setup gamePlayer.PlayerSetup(spawnPlayer.C, (TeamSystem.Team)spawnPlayer.t, spawnPlayer.P); }); break; case MultiPossibleRequest.MultiSyncPlayer: MultiSyncPlayer syncPlayer = MessagePackSerializer.Deserialize <MultiSyncPlayer>(baseRequest.R); actions.Enqueue(() => gamePlayers[syncPlayer.C].HandleMessage(syncPlayer.S)); break; } } catch (Exception ex) { Debug.LogError(ex); Debug.LogError(_message); } }