snakes_mp/Assets/Scripts/Utils/ClientKickstarter.cs
2025-05-27 23:50:42 +05:30

253 lines
8.9 KiB
C#

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<SimpleWebTransport>().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<SnakeController>();
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<SimpleWebTransport>().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<UserProfile>(ownerDataReq.downloadHandler.text);
UserProfile joinerProfile = JsonUtility.FromJson<UserProfile>(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;
}
}