private void SendMessageToOtherManagers(byte[] message, int type) { GameSystemData data = new GameSystemData(SystemID, message); MultiBaseRequest baseRequest = new MultiBaseRequest(MultiPossibleRequest.MultiGameData, MessagePackSerializer.Serialize(data)); client.SendMessageToServer(MessagePackSerializer.Serialize(baseRequest)); }
protected void SendSyncMessage(byte[] message) { if (ClientID == client._ClientID) { MultiSyncPlayer syncPlayer = new MultiSyncPlayer(ClientID, message); MultiBaseRequest baseRequest = new MultiBaseRequest(MultiPossibleRequest.MultiSyncPlayer, MessagePackSerializer.Serialize(syncPlayer)); client.SendMessageToServer(MessagePackSerializer.Serialize(baseRequest)); } }
public void OnDestroy() { Debug.Log(String.Format("{0} Destroyed!", gameObject.name)); //if we're locally owned, send a destroy object request if (localOwned) { MultiDespawnObject destroyObject = new MultiDespawnObject(ID); MultiBaseRequest baseRequest = new MultiBaseRequest(MultiPossibleRequest.MultiDespawnObject, MessagePackSerializer.Serialize(destroyObject)); client.SendMessageToServer(MessagePackSerializer.Serialize(baseRequest)); } }
//sends a sync message public void SyncObject() { //only sync to this instance of the object if it's locally owned if (localOwned) { //create sync and base requests MultiSyncRequest syncRequest = new MultiSyncRequest(ID, syncedTransforms); MultiBaseRequest baseRequest = new MultiBaseRequest(MultiPossibleRequest.MultiSyncObject, MessagePackSerializer.Serialize(syncRequest)); //send the message away client.SendMessageToServer(MessagePackSerializer.Serialize(baseRequest)); Debug.Log("Object " + ID.ToString() + " sent sync request"); } //sync again after syncInterval seconds Invoke("SyncObject", syncInterval); }
//sends a request to all team managers to tell them to select a team public void SendSelectTeamRequest() { if (client.hostAuthority) { //store the system id and request type in the gamesystemdata object GameSystemData systemData = new GameSystemData(SystemID, new byte[1] { (byte)TeamSystemRequest.SelectTeamRequest }); //create the base request with the serialized gamesystemdata object MultiBaseRequest baseRequest = new MultiBaseRequest(MultiPossibleRequest.MultiGameData, MessagePackSerializer.Serialize <GameSystemData>(systemData)); //send the serialized request client.SendMessageToServer(MessagePackSerializer.Serialize <MultiBaseRequest>(baseRequest)); } }
//spawns a local object public GameObject LocalSpawnObject(int index) { //spawn in the new synced object instance GameObject instance = Instantiate(spawnableObjects[index]); MultiSyncedObject syncedObject = instance.GetComponent <MultiSyncedObject>(); //store its index and its local status syncedObject.localOwned = true; syncedObject.index = index; //send a request to all other clients to spawn in this object MultiSpawnRequest spawnRequest = new MultiSpawnRequest(index); MultiBaseRequest baseRequest = new MultiBaseRequest(MultiPossibleRequest.MultiSpawnObject, MessagePackSerializer.Serialize(spawnRequest)); SendMessageToServer(MessagePackSerializer.Serialize(baseRequest)); return(instance); }
public IEnumerator ChangeScene(int sceneIndex, bool forceSceneChange = false) { //only order a scene change if we're host or it is forced(basically only in MultiNetworkHandler.cs:75) if (hostAuthority | forceSceneChange) { //change the scene SceneManager.LoadScene(possibleScenes[sceneIndex].name); currentScene = possibleScenes[sceneIndex]; //send a change scene request MultiChangeSceneRequest sceneRequest = new MultiChangeSceneRequest(sceneIndex); MultiBaseRequest baseRequest = new MultiBaseRequest(MultiPossibleRequest.MultiChangeScene, MessagePackSerializer.Serialize(sceneRequest)); SendMessageToServer(MessagePackSerializer.Serialize(baseRequest)); yield return(new WaitForEndOfFrame()); //spawn our prefab on the network MultiSpawnPlayer spawnPlayer = new MultiSpawnPlayer((int)inputMethod, _ClientID, TeamSystem.Team.A, PlayerName); //FindObjectOfType<TeamSystem>().localTeam); MultiBaseRequest spawnPlayerBase = new MultiBaseRequest(MultiPossibleRequest.MultiSpawnPlayer, MessagePackSerializer.Serialize(spawnPlayer)); SendMessageToServer(MessagePackSerializer.Serialize(spawnPlayerBase)); actions.Enqueue(() => { //spawn in the new synced object instance GameObject instance = Instantiate(possibleScenes[sceneIndex].PlayerPrefabs[(int)inputMethod]); GamePlayer player = instance.GetComponent <GamePlayer>(); //store it gamePlayers[_ClientID] = player; //do setup player.PlayerSetup(_ClientID, TeamSystem.Team.A, PlayerName); //FindObjectOfType<TeamSystem>().localTeam); }); 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>()); } }); } }
//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); } } }
protected void SendRequest <T>(T request, int requestType) { //get the team request as bytes byte[] serializedRequest = MessagePackSerializer.Serialize(request); //store the request with type List <byte> serializedRequestWType = new List <byte>(serializedRequest.Length + 1); serializedRequestWType.Add((byte)requestType); //store the rest of the request for (int i = 0; i < serializedRequest.Length; i++) { serializedRequestWType.Add(serializedRequest[i]); } //create the systemData request GameSystemData systemData = new GameSystemData(SystemID, serializedRequestWType.ToArray()); //create the base request with the serialized gamesystemdata object MultiBaseRequest baseRequest = new MultiBaseRequest(MultiPossibleRequest.MultiGameData, MessagePackSerializer.Serialize(systemData)); //send the serialized request client.SendMessageToServer(MessagePackSerializer.Serialize(baseRequest)); }
/// <summary> /// Runs in background TcpServerThread; Handles incomming TcpClient requests and sets them up with a handler thread /// </summary> private void ClientListenerThread(object nThread) { //get the thread key for the dictionary int threadKey = (int)nThread; //wait for an incomming connection Debug.Log(String.Format("<<<Thread {0}>>>: Waiting for a connection...", threadKey)); Socket handler = listener.Accept(); //Found! Debug.Log(String.Format("<<<Thread {0}>>>: Connection Accepted", threadKey)); //now that we have our socket, replace the null value in our dictionary tuple listenerThreads[threadKey] = new Tuple <Thread, Socket, bool>(listenerThreads[threadKey].Item1, handler, listenerThreads[threadKey].Item3); mostRecentConnection = threadKey; //create a new thread to listen out for a new connection once we've connected Thread newThread = new Thread(ClientListenerThread); listenerThreads.Add(threadKey + 1, new Tuple <Thread, Socket, bool>(newThread, null, false)); newThread.Start(threadKey + 1); // Incoming data from the client. byte[] bytes = null; //if this client is supposed to be host, tell them MultiBaseRequest baseRequest_HAC = new MultiBaseRequest(MultiPossibleRequest.MultiHostAuthChange, null); if (listenerThreads[threadKey].Item3) { SendMessageToClient(MessagePackSerializer.Serialize(baseRequest_HAC), threadKey); } //now that we definitely have a host present, do all the stuff for a new connection if (threadKey != 0) { MultiNewConnection newConnection = new MultiNewConnection(threadKey); MultiBaseRequest baseRequest_NC = new MultiBaseRequest(MultiPossibleRequest.MultiNewConnection, MessagePackSerializer.Serialize(newConnection)); SendMessageToClient(MessagePackSerializer.Serialize(baseRequest_NC), listenerThreads.Keys.ElementAt(0)); } //listen only while connected while (handler.Connected) { bytes = new byte[2048]; int bytesRec = handler.Receive(bytes); messageReceivedListener(bytes, threadKey);//Encoding.ASCII.GetString(Convert.FromBase64String(data)), threadKey); } //shutdown the socket once the client disconnects handler.Shutdown(SocketShutdown.Both); handler.Close(); //remove ourselves from the thread list once we've disconnected listenerThreads.Remove((int)threadKey); //change host authority to the next client in the dict(not necessarily the oldest!) int nextHostIndex = listenerThreads.Keys.ElementAt <int>(0); SendMessageToClient(MessagePackSerializer.Serialize(baseRequest_HAC), nextHostIndex); listenerThreads[nextHostIndex] = new Tuple <Thread, Socket, bool>( listenerThreads[nextHostIndex].Item1, listenerThreads[nextHostIndex].Item2, true); }
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); } }