| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315 | 
							- using System.Collections;
 
- using System.Collections.Generic;
 
- using UnityEngine;
 
- using UnityEngine.UI;
 
- namespace Mirror.Examples.MultipleMatch
 
- {
 
- #pragma warning disable 618
 
-     [RequireComponent(typeof(NetworkMatchChecker))]
 
- #pragma warning restore 618
 
-     public class MatchController : NetworkBehaviour
 
-     {
 
-         internal readonly SyncDictionary<NetworkIdentity, MatchPlayerData> matchPlayerData = new SyncDictionary<NetworkIdentity, MatchPlayerData>();
 
-         internal readonly Dictionary<CellValue, CellGUI> MatchCells = new Dictionary<CellValue, CellGUI>();
 
-         CellValue boardScore = CellValue.None;
 
-         bool playAgain = false;
 
-         [Header("GUI References")]
 
-         public CanvasGroup canvasGroup;
 
-         public Text gameText;
 
-         public Button exitButton;
 
-         public Button playAgainButton;
 
-         public Text winCountLocal;
 
-         public Text winCountOpponent;
 
-         [Header("Diagnostics - Do Not Modify")]
 
-         public CanvasController canvasController;
 
-         public NetworkIdentity player1;
 
-         public NetworkIdentity player2;
 
-         public NetworkIdentity startingPlayer;
 
-         [SyncVar(hook = nameof(UpdateGameUI))]
 
-         public NetworkIdentity currentPlayer;
 
-         void Awake()
 
-         {
 
-             canvasController = FindObjectOfType<CanvasController>();
 
-         }
 
-         public override void OnStartServer()
 
-         {
 
-             StartCoroutine(AddPlayersToMatchController());
 
-         }
 
-         // For the SyncDictionary to properly fire the update callback, we must
 
-         // wait a frame before adding the players to the already spawned MatchController
 
-         IEnumerator AddPlayersToMatchController()
 
-         {
 
-             yield return null;
 
-             matchPlayerData.Add(player1, new MatchPlayerData { playerIndex = CanvasController.playerInfos[player1.connectionToClient].playerIndex });
 
-             matchPlayerData.Add(player2, new MatchPlayerData { playerIndex = CanvasController.playerInfos[player2.connectionToClient].playerIndex });
 
-         }
 
-         public override void OnStartClient()
 
-         {
 
-             matchPlayerData.Callback += UpdateWins;
 
-             canvasGroup.alpha = 1f;
 
-             canvasGroup.interactable = true;
 
-             canvasGroup.blocksRaycasts = true;
 
-             exitButton.gameObject.SetActive(false);
 
-             playAgainButton.gameObject.SetActive(false);
 
-         }
 
-         public void UpdateGameUI(NetworkIdentity _, NetworkIdentity newPlayerTurn)
 
-         {
 
-             if (!newPlayerTurn) return;
 
-             if (newPlayerTurn.gameObject.GetComponent<NetworkIdentity>().isLocalPlayer)
 
-             {
 
-                 gameText.text = "Your Turn";
 
-                 gameText.color = Color.blue;
 
-             }
 
-             else
 
-             {
 
-                 gameText.text = "Their Turn";
 
-                 gameText.color = Color.red;
 
-             }
 
-         }
 
-         public void UpdateWins(SyncDictionary<NetworkIdentity, MatchPlayerData>.Operation op, NetworkIdentity key, MatchPlayerData matchPlayerData)
 
-         {
 
-             if (key.gameObject.GetComponent<NetworkIdentity>().isLocalPlayer)
 
-             {
 
-                 winCountLocal.text = $"Player {matchPlayerData.playerIndex}\n{matchPlayerData.wins}";
 
-             }
 
-             else
 
-             {
 
-                 winCountOpponent.text = $"Player {matchPlayerData.playerIndex}\n{matchPlayerData.wins}";
 
-             }
 
-         }
 
-         [Command(requiresAuthority = false)]
 
-         public void CmdMakePlay(CellValue cellValue, NetworkConnectionToClient sender = null)
 
-         {
 
-             // If wrong player or cell already taken, ignore
 
-             if (sender.identity != currentPlayer || MatchCells[cellValue].playerIdentity != null)
 
-                 return;
 
-             MatchCells[cellValue].playerIdentity = currentPlayer;
 
-             RpcUpdateCell(cellValue, currentPlayer);
 
-             MatchPlayerData mpd = matchPlayerData[currentPlayer];
 
-             mpd.currentScore = mpd.currentScore | cellValue;
 
-             matchPlayerData[currentPlayer] = mpd;
 
-             boardScore = boardScore | cellValue;
 
-             if (CheckWinner(mpd.currentScore))
 
-             {
 
-                 mpd.wins += 1;
 
-                 matchPlayerData[currentPlayer] = mpd;
 
-                 RpcShowWinner(currentPlayer);
 
-                 currentPlayer = null;
 
-             }
 
-             else if (boardScore == CellValue.Full)
 
-             {
 
-                 RpcShowWinner(null);
 
-                 currentPlayer = null;
 
-             }
 
-             else
 
-             {
 
-                 // Set currentPlayer SyncVar so clients know whose turn it is
 
-                 currentPlayer = currentPlayer == player1 ? player2 : player1;
 
-             }
 
-         }
 
-         bool CheckWinner(CellValue currentScore)
 
-         {
 
-             if ((currentScore & CellValue.TopRow) == CellValue.TopRow)
 
-                 return true;
 
-             if ((currentScore & CellValue.MidRow) == CellValue.MidRow)
 
-                 return true;
 
-             if ((currentScore & CellValue.BotRow) == CellValue.BotRow)
 
-                 return true;
 
-             if ((currentScore & CellValue.LeftCol) == CellValue.LeftCol)
 
-                 return true;
 
-             if ((currentScore & CellValue.MidCol) == CellValue.MidCol)
 
-                 return true;
 
-             if ((currentScore & CellValue.RightCol) == CellValue.RightCol)
 
-                 return true;
 
-             if ((currentScore & CellValue.Diag1) == CellValue.Diag1)
 
-                 return true;
 
-             if ((currentScore & CellValue.Diag2) == CellValue.Diag2)
 
-                 return true;
 
-             return false;
 
-         }
 
-         [ClientRpc]
 
-         public void RpcUpdateCell(CellValue cellValue, NetworkIdentity player)
 
-         {
 
-             MatchCells[cellValue].SetPlayer(player);
 
-         }
 
-         [ClientRpc]
 
-         public void RpcShowWinner(NetworkIdentity winner)
 
-         {
 
-             foreach (CellGUI cellGUI in MatchCells.Values)
 
-                 cellGUI.GetComponent<Button>().interactable = false;
 
-             if (winner == null)
 
-             {
 
-                 gameText.text = "Draw!";
 
-                 gameText.color = Color.yellow;
 
-             }
 
-             else if (winner.gameObject.GetComponent<NetworkIdentity>().isLocalPlayer)
 
-             {
 
-                 gameText.text = "Winner!";
 
-                 gameText.color = Color.blue;
 
-             }
 
-             else
 
-             {
 
-                 gameText.text = "Loser!";
 
-                 gameText.color = Color.red;
 
-             }
 
-             exitButton.gameObject.SetActive(true);
 
-             playAgainButton.gameObject.SetActive(true);
 
-         }
 
-         // Assigned in inspector to ReplayButton::OnClick
 
-         [Client]
 
-         public void RequestPlayAgain()
 
-         {
 
-             playAgainButton.gameObject.SetActive(false);
 
-             CmdPlayAgain();
 
-         }
 
-         [Command(requiresAuthority = false)]
 
-         public void CmdPlayAgain(NetworkConnectionToClient sender = null)
 
-         {
 
-             if (!playAgain)
 
-             {
 
-                 playAgain = true;
 
-             }
 
-             else
 
-             {
 
-                 playAgain = false;
 
-                 RestartGame();
 
-             }
 
-         }
 
-         [Server]
 
-         public void RestartGame()
 
-         {
 
-             foreach (CellGUI cellGUI in MatchCells.Values)
 
-                 cellGUI.SetPlayer(null);
 
-             boardScore = CellValue.None;
 
-             NetworkIdentity[] keys = new NetworkIdentity[matchPlayerData.Keys.Count];
 
-             matchPlayerData.Keys.CopyTo(keys, 0);
 
-             foreach (NetworkIdentity identity in keys)
 
-             {
 
-                 MatchPlayerData mpd = matchPlayerData[identity];
 
-                 mpd.currentScore = CellValue.None;
 
-                 matchPlayerData[identity] = mpd;
 
-             }
 
-             RpcRestartGame();
 
-             startingPlayer = startingPlayer == player1 ? player2 : player1;
 
-             currentPlayer = startingPlayer;
 
-         }
 
-         [ClientRpc]
 
-         public void RpcRestartGame()
 
-         {
 
-             foreach (CellGUI cellGUI in MatchCells.Values)
 
-                 cellGUI.SetPlayer(null);
 
-             exitButton.gameObject.SetActive(false);
 
-             playAgainButton.gameObject.SetActive(false);
 
-         }
 
-         // Assigned in inspector to BackButton::OnClick
 
-         [Client]
 
-         public void RequestExitGame()
 
-         {
 
-             exitButton.gameObject.SetActive(false);
 
-             playAgainButton.gameObject.SetActive(false);
 
-             CmdRequestExitGame();
 
-         }
 
-         [Command(requiresAuthority = false)]
 
-         public void CmdRequestExitGame(NetworkConnectionToClient sender = null)
 
-         {
 
-             StartCoroutine(ServerEndMatch(sender, false));
 
-         }
 
-         public void OnPlayerDisconnected(NetworkConnection conn)
 
-         {
 
-             // Check that the disconnecting client is a player in this match
 
-             if (player1 == conn.identity || player2 == conn.identity)
 
-             {
 
-                 StartCoroutine(ServerEndMatch(conn, true));
 
-             }
 
-         }
 
-         public IEnumerator ServerEndMatch(NetworkConnection conn, bool disconnected)
 
-         {
 
-             canvasController.OnPlayerDisconnected -= OnPlayerDisconnected;
 
-             RpcExitGame();
 
-             // Skip a frame so the message goes out ahead of object destruction
 
-             yield return null;
 
-             // Mirror will clean up the disconnecting client so we only need to clean up the other remaining client.
 
-             // If both players are just returning to the Lobby, we need to remove both connection Players
 
-             if (!disconnected)
 
-             {
 
-                 NetworkServer.RemovePlayerForConnection(player1.connectionToClient, true);
 
-                 CanvasController.waitingConnections.Add(player1.connectionToClient);
 
-                 NetworkServer.RemovePlayerForConnection(player2.connectionToClient, true);
 
-                 CanvasController.waitingConnections.Add(player2.connectionToClient);
 
-             }
 
-             else if (conn == player1.connectionToClient)
 
-             {
 
-                 // player1 has disconnected - send player2 back to Lobby
 
-                 NetworkServer.RemovePlayerForConnection(player2.connectionToClient, true);
 
-                 CanvasController.waitingConnections.Add(player2.connectionToClient);
 
-             }
 
-             else if (conn == player2.connectionToClient)
 
-             {
 
-                 // player2 has disconnected - send player1 back to Lobby
 
-                 NetworkServer.RemovePlayerForConnection(player1.connectionToClient, true);
 
-                 CanvasController.waitingConnections.Add(player1.connectionToClient);
 
-             }
 
-             // Skip a frame to allow the Removal(s) to complete
 
-             yield return null;
 
-             // Send latest match list
 
-             canvasController.SendMatchList();
 
-             NetworkServer.Destroy(gameObject);
 
-         }
 
-         [ClientRpc]
 
-         public void RpcExitGame()
 
-         {
 
-             canvasController.OnMatchEnded();
 
-         }
 
-     }
 
- }
 
 
  |