using System.Collections; using System.Collections.Generic; using System; using TMPro; using UnityEngine; using UnityEngine.Networking; using UnityEngine.UI; using Mirror; using Mirror.SimpleWeb; using UnityEngine.SceneManagement; public class ClientKickstarter : MonoBehaviour { public bool start_on_dummy = false; public const string GAME_NAME = "snakes"; public GameObject loadingScreen; public GameObject helperScreen; public TMP_Text txtLoadingStatus; public Image masterImage, clientImage; public TMP_Text masterNameTxt, clientNameTxt; public Image masterFrame, clientFrame; public Color playerColor = Color.green, enemyColor = Color.red; private bool isReconnecting = false; private const float RECONNECT_DELAY = 3f; private const int MAX_RECONNECT_ATTEMPTS = 1; private int reconnectAttempts = 0; void Start() { #if UNITY_SERVER && !UNITY_EDITOR return; #endif string url = Application.absoluteURL; if (!string.IsNullOrEmpty(url)) { // Extract query parameters string betId = GetQueryParam(url, "betId"); string owner = GetQueryParam(url, "owner"); string joiner = GetQueryParam(url, "joiner"); string address = GetQueryParam(url, "address"); string user_id = GetQueryParam(url, "uid"); string pubkey = GetQueryParam(url, "pubkey"); int wager = int.Parse(GetQueryParam(url, "wager")); string isDev = GetQueryParam(url, "isDev"); GameData.id = betId; GameData.ownerId = owner; GameData.joinerId = joiner; GameData.address = address; GameData.user_id = user_id; GameData.pubkey = pubkey; GameData.wager = wager; GameData.isDev = isDev == "true"; StartCoroutine(CoroutineKickstarterWatcher()); StartCoroutine(CoroutineUpdateGameData()); } else { if(Application.dataPath.Contains("clone")){ GameData.DummyData(); }else{ GameData.DummyData(2); } Debug.Log("Dummy Data"); if(start_on_dummy){ StartCoroutine(CoroutineKickstarterWatcher()); StartCoroutine(CoroutineUpdateGameData()); }else{ NetworkManager.singleton.networkAddress = "localhost"; NetworkManager.singleton.GetComponent().port = (ushort)GameData.port; } } } void Update() { #if UNITY_EDITOR if (Input.GetKeyDown(KeyCode.PageDown)) { StartCoroutine(startTest(1)); } else if (Input.GetKeyDown(KeyCode.PageUp)) { StartCoroutine(startTest(2)); } if (Input.GetKeyDown(KeyCode.Insert)) { StartCoroutine(NetGameManager.instance.StartGame()); } #endif } IEnumerator startTest(int user_id = 1) { WWW www = new WWW(Constants.MATCHMAKER_URL + "getGamePort?address=" + GameData.address + "&gameName=" + GAME_NAME + "&isDev=" + (GameData.isDev ? "true" : "false")); yield return www; Debug.Log("test port: " + www.text); string port = www.text; GameData.port = int.Parse(port); GameData.DummyData(user_id); NetworkManager.singleton.StartClient(); } IEnumerator CoroutineKickstarterWatcher() { yield return new WaitForSeconds(10f); SnakeController[] players = FindObjectsOfType(); if(players.Length == 0){ txtLoadingStatus.text = "Connection failed. Retrying..."; yield return new WaitForSeconds(3f); SceneManager.LoadScene(0); }else{ loadingScreen.SetActive(false); } } IEnumerator CoroutineUpdateGameData() { loadingScreen.SetActive(true); txtLoadingStatus.text = "Connecting..."; reconnectAttempts = 0; while (reconnectAttempts < MAX_RECONNECT_ATTEMPTS) { WWW www = new WWW(Constants.MATCHMAKER_URL + "getGamePort?address=" + GameData.address + "&gameName=" + GAME_NAME + "&isDev=" + (GameData.isDev ? "true" : "false")); yield return www; if (string.IsNullOrEmpty(www.error)) { string port = www.text; GameData.port = int.Parse(port); NetworkManager.singleton.GetComponent().port = (ushort)GameData.port; NetworkManager.singleton.StartClient(); // Request user profile data for both owner and joiner UnityWebRequest ownerDataReq = UnityWebRequest.Get($"{Constants.API_URL}get_user_by_id.php?id={GameData.ownerId}"); UnityWebRequest joinerDataReq = UnityWebRequest.Get($"{Constants.API_URL}get_user_by_id.php?id={GameData.joinerId}"); // Wait for both requests to finish yield return ownerDataReq.SendWebRequest(); yield return joinerDataReq.SendWebRequest(); // Handle errors if any if (ownerDataReq.result != UnityWebRequest.Result.Success || joinerDataReq.result != UnityWebRequest.Result.Success) { Debug.LogError($"Error fetching data: {ownerDataReq.error}, {joinerDataReq.error}"); break; } try { // Parse JSON response UserProfile ownerProfile = JsonUtility.FromJson(ownerDataReq.downloadHandler.text); UserProfile joinerProfile = JsonUtility.FromJson(joinerDataReq.downloadHandler.text); // Update UI elements masterNameTxt.text = ownerProfile.username; clientNameTxt.text = joinerProfile.username; // Load the profile images using UnityWebRequest StartCoroutine(LoadProfileImage(ownerProfile.x_profile_url, masterImage)); StartCoroutine(LoadProfileImage(joinerProfile.x_profile_url, clientImage)); } catch (Exception e) { Debug.LogError($"Error fetching data: {e.Message}"); break; } yield return new WaitForSeconds(3f); float connectionTimeout = 10f; float startTime = Time.time; while (!NetworkClient.isConnected) { if (Time.time - startTime > connectionTimeout) { txtLoadingStatus.text = "Connection failed. Please try again later."; break; } yield return null; } }else{ txtLoadingStatus.text = "Server error 500"; } // If we get here, connection failed if(!NetworkClient.isConnected){ reconnectAttempts++; if (reconnectAttempts < MAX_RECONNECT_ATTEMPTS) { txtLoadingStatus.text = $"Reconnecting... Attempt {reconnectAttempts}/{MAX_RECONNECT_ATTEMPTS}"; yield return new WaitForSeconds(RECONNECT_DELAY); } } } loadingScreen.SetActive(false); if(masterFrame != null){ if (GameData.isMaster) { masterFrame.color = playerColor; clientFrame.color = enemyColor; } else { masterFrame.color = enemyColor; clientFrame.color = playerColor; } } if(helperScreen != null){ helperScreen.SetActive(true); } yield return new WaitForSeconds(3f); if(helperScreen != null){ helperScreen.SetActive(false); } } IEnumerator LoadProfileImage(string url, Image imageComponent) { UnityWebRequest imageRequest = UnityWebRequestTexture.GetTexture(url); yield return imageRequest.SendWebRequest(); if (imageRequest.result == UnityWebRequest.Result.Success) { Texture2D texture = ((DownloadHandlerTexture)imageRequest.downloadHandler).texture; Sprite sprite = Sprite.Create(texture, new Rect(0, 0, texture.width, texture.height), new Vector2(0.5f, 0.5f)); imageComponent.sprite = sprite; } else { Debug.LogError($"Error loading image from {url}: {imageRequest.error}"); } } string GetQueryParam(string url, string key) { if (!url.Contains("?")) return null; string[] queries = url.Split('?')[1].Split('&'); foreach (string query in queries) { string[] pair = query.Split('='); if (pair.Length == 2 && pair[0] == key) return pair[1]; } return null; } }