diff --git a/Assets/Scripts/GameMode/GameMode.cs b/Assets/Scripts/GameMode/GameMode.cs index bbd1ab7..8062247 100644 --- a/Assets/Scripts/GameMode/GameMode.cs +++ b/Assets/Scripts/GameMode/GameMode.cs @@ -102,3 +102,25 @@ public abstract class GameMode : ScriptableObject OnGameOverEvent?.Invoke(); } } + + +/* --- Calls we need --- + * + * PreGameSetup(); - //Called once before the game actually starts + * GameStart(PlayerData[] AllPlayers); //Called once after players have Spawned + * + * OnInputStart(PlayerData[] AllPlayers) //Called when players enter input mode + * OnInputEnd(PlayerData[] AllPlayers) //Called when player input mode has finished + * + * OnRoundStart(PlayerData[] AllPlayers) //Just before Players start moving + * + * OnPlayerMoved(PlayerData player) //Called after each player moves + * IsGameOver(PlayerData[] AllPlayers) //Called after each player moves + * + * AllPlayersMoved(); + * + * + * + * + * + * / \ No newline at end of file diff --git a/Assets/Scripts/Managers/GameManager.cs b/Assets/Scripts/Managers/GameManager.cs index ee215ab..1c19e0c 100644 --- a/Assets/Scripts/Managers/GameManager.cs +++ b/Assets/Scripts/Managers/GameManager.cs @@ -34,19 +34,26 @@ public class GameManager : MonoBehaviour #region Private Variables private Dictionary playerData; - private GameMode gamemode; #endregion Private Variables #region Read Only - private IEnumerable playerArray { get { return playerData.Values; } } + /// + /// Easy access to IEnumerable in playerData so we can Enumerate through it + /// + private IEnumerable playerDataAsArray { get { return playerData.Values; } } + + /// + /// Easy access to GameMode value in CurrentGameMode reference + /// + private GameMode gameMode {get { return CurrentGameMode.Value; } } #endregion Read Only public GameObject levelInfo; public blockSpawn bspawn; + #region Unity Functions public void Awake() { - gamemode = CurrentGameMode.Value; RegisterHandlers(); SpawnCharacters(); ClientList.ForEach(p => p.ChangeScene("ClientScene")); @@ -54,38 +61,32 @@ public class GameManager : MonoBehaviour private void Start() { - StartCoroutine(displayforSeconds(levelInfo, 5.0f)); - gamemode.GameStart(playerArray.ToArray()); + StartCoroutine(displayforSeconds(levelInfo, 5.0f)); + gameMode.GameStart(playerDataAsArray.ToArray()); StartRound(); } private void Update() { + //This is required so that the server can continue to recieve client messages + //(it is a unity thing) server.ServerUpdate(); } - IEnumerator displayforSeconds(GameObject display, float time) + private void OnDisable() + { + //Let server know to not send messages this way + UnRegisterHandlers(); + } + #endregion Unity Functions + + IEnumerator displayforSeconds(GameObject display, float time) { display.SetActive (true); yield return new WaitForSeconds(time); display.SetActive (false); } - private void RecieveLogicList(NetworkMessage msg) - { - LogicProtocols.LogicMsg logicMsg; - if (!msg.TryRead(out logicMsg)) - return; - - Debug.Log("Recieved function from " + msg.conn.connectionId); - - playerData[msg.conn.connectionId].blockReader.LogicChain = new List(logicMsg.elements); - playerData[msg.conn.connectionId].recievedList = true; - - if (playerData.All(p => p.Value.recievedList)) - DoRoundRoutine(); - } - private void DoRoundRoutine() { Debug.Log("Starting Round"); @@ -94,22 +95,22 @@ public class GameManager : MonoBehaviour private void StartRound() { - gamemode.RoundStart(playerArray.ToArray()); - LogicProtocols.FloatMsg RoundTime = new LogicProtocols.FloatMsg( gamemode.GetRoundTime()); + gameMode.RoundStart(playerDataAsArray.ToArray()); + LogicProtocols.FloatMsg RoundTime = new LogicProtocols.FloatMsg( gameMode.GetRoundTime()); bspawn.Spawn(); - playerArray.ForEach(p => p.client.conn.Send(LogicProtocols.SendRoundTime, RoundTime)); + playerDataAsArray.ForEach(p => p.client.conn.Send(LogicProtocols.SendRoundTime, RoundTime)); } private IEnumerator RoundRoutine() { - playerArray.ForEach(p => p.recievedList = false); + playerDataAsArray.ForEach(p => p.recievedList = false); //Debug.Log("Doing Round Routine"); - while (playerArray.Any(p => !p.blockReader.Finished)) + while (playerDataAsArray.Any(p => !p.blockReader.Finished)) { //Debug.Log("One Move"); - foreach (PlayerData player in playerArray) + foreach (PlayerData player in playerDataAsArray) { Debug.Log(player.client.Name); StartCoroutine(RunOnce(player)); @@ -120,20 +121,20 @@ public class GameManager : MonoBehaviour //wait until all players have finished //yield return new WaitUntil(() => playerArray.All(p => p.waiting)); - gamemode.FinishedMove(playerArray.ToArray()); - playerArray.ForEach(p => p.client.SendScore()); + gameMode.FinishedMove(playerDataAsArray.ToArray()); + playerDataAsArray.ForEach(p => p.client.SendScore()); } - if (gamemode.isGameOver(playerArray.ToArray())) + if (gameMode.isGameOver(playerDataAsArray.ToArray())) { Debug.Log("Game Over"); SceneManager.LoadScene("ScoreBoards"); } - gamemode.RoundEnd(playerArray.ToArray()); + gameMode.RoundEnd(playerDataAsArray.ToArray()); - foreach (PlayerData player in playerArray) + foreach (PlayerData player in playerDataAsArray) { player.blockReader.Reset(); player.waiting = false; @@ -163,10 +164,50 @@ public class GameManager : MonoBehaviour } } + + #region Networking Functions + + /// + /// Registers functions which should deal with incoming messages from clients + /// private void RegisterHandlers() { server.server.RegisterHandler(LogicProtocols.SendLogicList, RecieveLogicList); - } + } + + /// + /// Clears any functions from server register which the manager would deal with + /// + private void UnRegisterHandlers() + { + server.server.UnregisterHandler(LogicProtocols.SendLogicList); + } + + /// + /// Called when server recieves moves from client + /// + /// messages passed by server + private void RecieveLogicList(NetworkMessage msg) + { + + //try to read base message as a logic message + LogicProtocols.LogicMsg logicMsg; + if (!msg.TryRead(out logicMsg)) + return; + + //Debug that we have recieved it + Debug.Log("Recieved function from " + ClientList[msg.conn.connectionId].Name); + + //Update player Data with recieved list + playerData[msg.conn.connectionId].blockReader.LogicChain = new List(logicMsg.elements); + playerData[msg.conn.connectionId].recievedList = true; + + //if we have recieved all moves start round + if (playerData.All(p => p.Value.recievedList)) + DoRoundRoutine(); + } + + #endregion Networking Functions private IEnumerator RunOnce(PlayerData data) { @@ -187,7 +228,7 @@ public class GameManager : MonoBehaviour //Debug.Log("Waiting: " + waitTime); yield return new WaitForSeconds(waitTime); - gamemode.OnePlayerMoved(data); + gameMode.OnePlayerMoved(data); } data.waiting = true; } diff --git a/Assets/Scripts/Networking/Server/ClientList.cs b/Assets/Scripts/Networking/Server/ClientList.cs index 6ef4ebc..cc5d879 100644 --- a/Assets/Scripts/Networking/Server/ClientList.cs +++ b/Assets/Scripts/Networking/Server/ClientList.cs @@ -165,6 +165,8 @@ namespace Networking.Server } + + #region IEnumerable Implementation public IEnumerator GetEnumerator() { @@ -176,6 +178,17 @@ namespace Networking.Server return ((IEnumerable)ConnectedClients).GetEnumerator(); } #endregion IEnumerable Implementation + + /// + /// Returns client with id + /// + /// id to find client with + /// client with provided id else null + public ClientData this[int id] { + get { + return ConnectedClients.FirstOrDefault(p => p.ID == id); + } + } } [System.Serializable]