#if XW_DEVTEST using System.Collections.Generic; using UnityEngine; using XGame; using XWorld.Framework.Protocol; namespace XGame.MiniGame { public sealed class DevServerSwitchUI : MonoBehaviour { public string Token = "xw-dev"; public bool DiscoverOnStart = true; private DevServerDiscovery _discovery; private List _found = new List(); private bool _prompting; private void Start() { if (DiscoverOnStart && !MiniGameTestOverride.IsActive) BeginDiscovery(); } private void OnDestroy() { _discovery?.Stop(); } public void BeginDiscovery() { _found.Clear(); _prompting = false; _discovery = new DevServerDiscovery(Token); _discovery.Begin(1200); } private void Update() { if (_discovery != null && !_discovery.IsRunning && !_prompting) { _found = _discovery.TakeResults(); _discovery = null; if (_found.Count > 0) _prompting = true; } } private void OnGUI() { if (MiniGameTestOverride.IsActive) { GUI.color = new Color(1f, 0.85f, 0.2f); GUILayout.BeginArea(new Rect(8, 8, 760, 30)); GUILayout.BeginHorizontal(GUI.skin.box); GUILayout.Label($"DEV TEST -> {MiniGameTestOverride.ServerName} ({MiniGameTestOverride.GatewayUrl})"); if (GUILayout.Button("Reset", GUILayout.Width(90))) { MiniGameTestOverride.Clear(); GlobalData.CurNode = XData.GetString("CurNode"); GlobalData.CurCDN = XData.GetString("CurCDN"); CSharpClientApp.RestartCurrent(); } GUILayout.EndHorizontal(); GUILayout.EndArea(); GUI.color = Color.white; return; } if (!_prompting) return; GUILayout.BeginArea(new Rect(8, 8, 760, 52 + _found.Count * 34), GUI.skin.box); GUILayout.Label("LAN dev server found. Switch gateway and minigame resources?"); for (int i = 0; i < _found.Count; i++) { DevDiscoveryReply r = _found[i]; GUILayout.BeginHorizontal(); GUILayout.Label($"{r.ServerName} {r.GatewayUrl}"); if (GUILayout.Button("Switch", GUILayout.Width(80))) { MiniGameTestOverride.Apply(r.GatewayUrl, r.ResourceBaseUrl, r.ServerName); GlobalData.CurNode = WithPid(r.GatewayUrl); GlobalData.CurCDN = r.ResourceBaseUrl; CSharpClientApp.RestartCurrent(); _prompting = false; } GUILayout.EndHorizontal(); } if (GUILayout.Button("Ignore", GUILayout.Width(80))) _prompting = false; GUILayout.EndArea(); } private static string WithPid(string gatewayUrl) { if (string.IsNullOrWhiteSpace(gatewayUrl)) { return gatewayUrl; } int pid = GetLocalPlayerId(); int queryStart = gatewayUrl.IndexOf('?'); if (queryStart < 0) { return gatewayUrl + "?pid=" + pid; } string head = gatewayUrl.Substring(0, queryStart); string query = gatewayUrl.Substring(queryStart + 1); string[] parts = query.Split('&'); bool replaced = false; for (int i = 0; i < parts.Length; i++) { if (parts[i].StartsWith("pid=", System.StringComparison.OrdinalIgnoreCase)) { parts[i] = "pid=" + pid; replaced = true; break; } } return head + "?" + (replaced ? string.Join("&", parts) : query + "&pid=" + pid); } private static int GetLocalPlayerId() { const string key = "LocalClientId"; string id = XData.GetString(key, string.Empty); if (string.IsNullOrEmpty(id)) { id = SystemInfo.deviceUniqueIdentifier; if (string.IsNullOrEmpty(id) || id == "unsupported") { id = System.Guid.NewGuid().ToString("N"); } XData.SetString(key, id); XData.Save(); } unchecked { uint hash = 2166136261u; for (int i = 0; i < id.Length; i++) { hash ^= id[i]; hash *= 16777619u; } return (int)(hash % 2000000000u) + 1; } } } } #endif