using System.Collections; using System.Collections.Generic; using Mirror; using UnityEngine; using TMPro; public class NetGameManager : NetworkBehaviour { public const int WAITING_TIME = 120; public static NetGameManager instance; void Awake() { instance = this; } [SyncVar] public bool gameStarted = false; [SyncVar] public bool playerSpawned = false; [SyncVar] public int masterScore=0; [SyncVar] public int clientScore= 0; PlayerType winner; public TMP_Text statusText; public GameOverScreen gameOverScreen; float waitingTimer = WAITING_TIME; void Start(){ } void Update() { if(isServer){ UpdateServer(); } } float gameTimer =0f; void UpdateServer(){ PlayerController[] players = FindObjectsOfType(); if(!gameStarted){ if(players.Length > 1){ gameStarted=true; RpcSetGameStarted(true); StartCoroutine(StartGame()); }else{ if(players.Length == 1){ if(waitingTimer > 0){ waitingTimer -= Time.deltaTime; SetStatusText("Waiting for another player...\nRemaining time: " + waitingTimer.ToString("F0") + " seconds"); }else{ SetStatusText("Opponent abandoned the game"); GameOver(players[0].playerType); } } } }else{ if(players.Length == 1){ if(playerSpawned){ SetStatusText("Opponent left the game"); GameOver(players[0].playerType); }else{ gameStarted=false; SetStatusText("Waiting for another player..."); } } if(playerSpawned && !gameOver){ gameTimer += Time.deltaTime; } } } [ClientRpc] void RpcSetGameStarted(bool started){ gameStarted = started; } void SetStatusText(string text) { if (!isServer) { return; } statusText.text = text; RpcSetStatusText(text); } [ClientRpc] void RpcSetStatusText(string text) { statusText.text = text; } public IEnumerator StartGame() { int counter = 10; PlayerController[] players = FindObjectsOfType(); while (counter > 0) { players = FindObjectsOfType(); if (players.Length <= 1) { yield break; } SetStatusText("Game starts in " + counter); yield return new WaitForSeconds(1f); counter--; } SetStatusText("Game Started"); playerSpawned = true; yield return new WaitForSeconds(1f); SetStatusText(""); } bool gameOver = false; public void GameOver(PlayerController player){ winner = player.playerType; GameOver(winner); } public void GameOver(PlayerType winner){ if(gameOver){return;} SetStatusText($"Player {(winner == PlayerType.Master ? "1" : "2")} wins!"); Debug.Log("Game Over " + winner); gameOver = true; string winnerKey = winner == PlayerType.Master ? "master" : "client"; StartCoroutine(CoroutineGameOver(winnerKey)); RpcGameOver(winnerKey); } [ClientRpc] void RpcGameOver(string winnerKey){ bool won = (winnerKey == "master" && GameData.isMaster) || (winnerKey == "client" && !GameData.isMaster); gameOverScreen.Show(won); Debug.Log("Game Over " + winnerKey); } IEnumerator CoroutineGameOver(string winnerKey){ string winnerPubkey = winnerKey == "master" ? GameData.betData.owner : GameData.betData.joiner; string winnerId = winnerKey == "master" ? GameData.betData.owner_id : GameData.betData.joiner_id; int masterScore=0, clientScore =0; Dictionary data = new Dictionary(){ {"gameAddress", GameData.address}, {"winnerPublicKey", winnerPubkey}, {"winnerUsername", winnerId}, {"wager", (GameData.betData.wager * 1e8).ToString()}, {"game_id", GameData.betData.id.ToString()}, {"loserUsername", winnerKey == "master" ? GameData.betData.joiner_id : GameData.betData.owner_id}, {"masterScore", masterScore.ToString()}, {"clientScore", clientScore.ToString()}, {"masterId", GameData.betData.owner_id}, {"clientId", GameData.betData.joiner_id} }; string queryString = "?"; foreach(KeyValuePair entry in data) { queryString += entry.Key + "=" + WWW.EscapeURL(entry.Value) + "&"; } queryString = queryString.TrimEnd('&'); string validator_url = GameData.isDev ? Constants.VALIDATOR_URL_DEV : Constants.VALIDATOR_URL_PROD; string url = validator_url + "finalize" + queryString; Debug.Log("Finalizing game on " + url); WWW www = new WWW(url); yield return www; if(www.error == null){ RpcProcessed(); } Debug.Log("Processed game, quitting in 10 seconds..."); yield return new WaitForSeconds(10f); Application.Quit(); } [ClientRpc] void RpcProcessed(){ gameOverScreen.Processed(); } }