diff --git a/.idea/.idea.Loong/.idea/workspace.xml b/.idea/.idea.Loong/.idea/workspace.xml index 7c952ed6..9d08590d 100644 --- a/.idea/.idea.Loong/.idea/workspace.xml +++ b/.idea/.idea.Loong/.idea/workspace.xml @@ -6,17 +6,8 @@ - - - - - - - - - - - + + diff --git a/Assets/Plugins/Android/AndroidManifest.xml b/Assets/Plugins/Android/AndroidManifest.xml index b8826a91..bb70e3bd 100644 --- a/Assets/Plugins/Android/AndroidManifest.xml +++ b/Assets/Plugins/Android/AndroidManifest.xml @@ -10,7 +10,7 @@ - + diff --git a/Assets/_Loong/Scripts/GameLocal.cs b/Assets/_Loong/Scripts/GameLocal.cs index fa3dfef4..7cec7f25 100644 --- a/Assets/_Loong/Scripts/GameLocal.cs +++ b/Assets/_Loong/Scripts/GameLocal.cs @@ -6,6 +6,21 @@ using TMPro; using Unity.XR.PXR; using UnityEngine; +public enum GameKey +{ + DinosaurPark2=0,//重返侏罗纪 + SpongeBob=1,//深海冒险 + XMen=2,//银河守护者 + KOF=3,//幻影交锋 + Valheim=4,//小小幻宠 + FutureMen=5,//未来战警 + AliceBall=6,//爱丽丝的舞会 + Zombie=7,//僵尸来了 + DefendNJ=8,//保卫金陵 + Loong=9, //巨龙猎人 + MRCS=10,//火力对决 + SXDMystery=11,//三星堆之谜 +} public enum Place { Company1Floor=0, @@ -104,6 +119,8 @@ public class GameLocal : MonoBehaviour [Header("场地")] public Place place = Place.Company1Floor; + public GameKey gameId; + public GameObject Scene; public GameObject Settle; @@ -122,6 +139,7 @@ public class GameLocal : MonoBehaviour Ins = this; Application.targetFrameRate = 60; gameEndEffect.SetActive(false); + gameId = GameKey.Loong; #if !UNITY_EDITOR && UNITY_ANDROID && PICO PXRManager.enabled = true; ChangeMaterial(true); @@ -205,7 +223,7 @@ public class GameLocal : MonoBehaviour if (place == Place. Company1FloorShinwai) authInfo.shop = 0; #endif - authInfo.gameId = 9; + authInfo.gameId = (int)gameId; string authJson = JsonUtility.ToJson(authInfo); Debug.Log("发送数据 -> " + authJson); request.RawData = System.Text.Encoding.UTF8.GetBytes(authJson); diff --git a/Assets/_Loong/Scripts/GameManager.cs b/Assets/_Loong/Scripts/GameManager.cs index c15df76e..6b7cd99a 100644 --- a/Assets/_Loong/Scripts/GameManager.cs +++ b/Assets/_Loong/Scripts/GameManager.cs @@ -100,6 +100,8 @@ public class GameManager : MonoBehaviour // 总游玩时长 [NonSerialized] public int vistAllTime = (int)(60 * 10f); + + public float curGameTime = 0; public string settleData = ""; public bool isGameEnd = false; @@ -159,15 +161,16 @@ public class GameManager : MonoBehaviour void Update() { - // if (gameState == GameState.Introduce) - // { - // _frame++; - // if (_frame >= 60 * 3.8f) - // { - // _frame = 0; - // MasterAudio.PlaySound(says[1]); - // } - // } + if (gameState == GameState.Playing) + { + curGameTime+=Time.deltaTime; + } + } + + + public int GetNowTime() + { + return Mathf.RoundToInt(curGameTime); } /// diff --git a/Assets/_Loong/Scripts/HttpServer.cs b/Assets/_Loong/Scripts/HttpServer.cs new file mode 100644 index 00000000..cbf6dd93 --- /dev/null +++ b/Assets/_Loong/Scripts/HttpServer.cs @@ -0,0 +1,305 @@ +using System; +using System.IO; +using System.Net; +using System.Text; +using System.Threading; +using System.Collections.Concurrent; +using UnityEngine; +using Valheim; + +[Serializable] +public class IntentMessage +{ + public string intent; +} + +[Serializable] +public class PlayingStatusResponse +{ + public int code; + public ServerData data; + public string message; +} + +[Serializable] +public class ServerData +{ + public string gameName; + public int gameTotalTime; + public int currentPlayTime; +} + +public class HttpServer : MonoBehaviour +{ + private HttpListener listener; + private Thread serverThread; + private volatile bool isRunning; + + private const string SERVER_URL = "http://+:12345/"; + + // 子线程 → 主线程 + private static ConcurrentQueue messageQueue = new ConcurrentQueue(); + + void Awake() + { + DontDestroyOnLoad(gameObject); + } + + void Start() + { + StartServer(); + } + + #region HTTP Server + + private void StartServer() + { + try + { + listener = new HttpListener(); + listener.Prefixes.Add(SERVER_URL); + listener.Start(); + + isRunning = true; + serverThread = new Thread(ListenLoop) + { + IsBackground = true + }; + serverThread.Start(); + + Debug.Log($"✅ HTTP Server 启动成功:{SERVER_URL}"); + } + catch (Exception e) + { + Debug.LogError("❌ HTTP Server 启动失败:" + e); + } + } + + private void ListenLoop() + { + while (isRunning && listener.IsListening) + { + try + { + var context = listener.GetContext(); + ThreadPool.QueueUserWorkItem(ProcessRequest, context); + } + catch (HttpListenerException) + { + break; + } + catch (Exception e) + { + Debug.LogError(e); + } + } + } + + private void ProcessRequest(object state) + { + var context = (HttpListenerContext)state; + var request = context.Request; + var response = context.Response; + + response.AddHeader("Access-Control-Allow-Origin", "*"); + response.AddHeader("Access-Control-Allow-Methods", "POST, GET, OPTIONS"); + response.AddHeader("Access-Control-Allow-Headers", "Content-Type"); + response.ContentType = "application/json; charset=utf-8"; + + try + { + if (request.HttpMethod == "POST") + { + string raw; + using (var reader = new StreamReader( + request.InputStream, + request.ContentEncoding ?? Encoding.UTF8)) + { + raw = reader.ReadToEnd(); + } + + Debug.Log($"📩 收到原始 JSON:{raw}"); + + // 解析 intent + IntentMessage intentMsg = null; + try + { + intentMsg = JsonUtility.FromJson(raw); + } + catch (Exception e) + { + Debug.LogError("JSON 解析失败:" + e); + } + + // 只处理 is_playing + if (intentMsg != null && intentMsg.intent == "is_playing") + { + var resp = new PlayingStatusResponse + { + code = 200, + data = new ServerData() + { + gameName = GetCurrentGameName(), + gameTotalTime = GetGameTotalTime(), + currentPlayTime = GetCurrentPlayTime() + }, + message = "请求成功" + }; + + string json = JsonUtility.ToJson(resp); + byte[] data = Encoding.UTF8.GetBytes(json); + response.OutputStream.Write(data, 0, data.Length); + } + else + { + // 未知 intent + string err = "{\"code\":400,\"msg\":\"unknown intent\"}"; + byte[] data = Encoding.UTF8.GetBytes(err); + response.OutputStream.Write(data, 0, data.Length); + } + + response.Close(); + return; + } + } + catch (Exception e) + { + Debug.LogError(e); + WriteResponse(response, 500, "error"); + } + finally + { + response.Close(); + } + } + + private void WriteResponse(HttpListenerResponse response, int code, string msg) + { + string json = $"{{\"code\":{code},\"msg\":\"{msg}\"}}"; + byte[] data = Encoding.UTF8.GetBytes(json); + response.OutputStream.Write(data, 0, data.Length); + } + + #endregion + + #region Unity Main Thread + + void Update() + { + while (messageQueue.TryDequeue(out var msg)) + { + Debug.Log($"📩 来自 [{msg.sender}] 指令 [{msg.command}]"); + HandleMessage(msg); + } + } + + #endregion + + #region Message Logic + + [Serializable] + public class NetMessage + { + public string sender; + public string command; + } + + private NetMessage ParseMessage(string raw) + { + if (string.IsNullOrEmpty(raw)) + return null; + + try + { + raw = raw.Replace("\"", "").Trim(); + var parts = raw.Split(':'); + if (parts.Length != 2) + { + Debug.LogWarning($"消息格式错误:{raw}"); + return null; + } + + return new NetMessage + { + sender = parts[0].Trim(), + command = parts[1].Trim() + }; + } + catch (Exception e) + { + Debug.LogError($"解析失败:{raw}\n{e}"); + return null; + } + } + + private void HandleMessage(NetMessage msg) + { + switch (msg.command) + { + case "isStart": + OnStartCommand(msg.sender); + break; + + default: + Debug.LogWarning($"未知指令:{msg.command}"); + break; + } + } + + private void OnStartCommand(string sender) + { + Debug.Log($"🚀 Start 指令来自:{sender}"); + + // ✅ 在这里安全调用 Unity API + // GameManager.Ins.QuitGame(); + } + + + private string GetCurrentGameName() + { + return GameLocal.Ins.gameId.ToString(); // 或你自己的 GameManager + } + + private int GetGameTotalTime() + { + return Mathf.FloorToInt(GameManager.Ins.vistAllTime); // 举例:1 小时(秒) + } + + private int GetCurrentPlayTime() + { + return GameManager.Ins.GetNowTime(); + } + + + #endregion + + #region Shutdown + + void OnDestroy() + { + StopServer(); + } + + private void StopServer() + { + isRunning = false; + + try + { + listener?.Stop(); + listener?.Close(); + } + catch { } + + try + { + if (serverThread != null && serverThread.IsAlive) + serverThread.Join(300); + } + catch { } + + Debug.Log("🛑 HTTP Server 已关闭"); + } + + #endregion +} diff --git a/Assets/_Loong/Scripts/HttpServer.cs.meta b/Assets/_Loong/Scripts/HttpServer.cs.meta new file mode 100644 index 00000000..45835b9d --- /dev/null +++ b/Assets/_Loong/Scripts/HttpServer.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: ef73e005cfa474c45a151f81b2a8b64c +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/ProjectSettings/EditorBuildSettings.asset b/ProjectSettings/EditorBuildSettings.asset index 605bc1a6..0cd81b82 100644 --- a/ProjectSettings/EditorBuildSettings.asset +++ b/ProjectSettings/EditorBuildSettings.asset @@ -5,7 +5,7 @@ EditorBuildSettings: m_ObjectHideFlags: 0 serializedVersion: 2 m_Scenes: - - enabled: 0 + - enabled: 1 path: Assets/_Loong/Scenes/Company1Floor.unity guid: 386a8fdea01af8a4e8d4a9835407ddec - enabled: 0 @@ -149,7 +149,7 @@ EditorBuildSettings: - enabled: 0 path: Assets/_Loong/Scenes/Shandong_Weifang_Linqu_WandaGuangchang.unity guid: ff6e77e2bb3beec4f81c0756a7477bca - - enabled: 1 + - enabled: 0 path: Assets/_Loong/Scenes/Jilin_Changchun_Chaoyang_OuyaMaichang.unity guid: c871685f69fdf7340aedcf914905bf7c - enabled: 0 diff --git a/ProjectSettings/ProjectSettings.asset b/ProjectSettings/ProjectSettings.asset index 29a4af0c..6b4350bf 100644 --- a/ProjectSettings/ProjectSettings.asset +++ b/ProjectSettings/ProjectSettings.asset @@ -142,7 +142,9 @@ PlayerSettings: visionOSBundleVersion: 1.0 tvOSBundleVersion: 1.0 bundleVersion: 2.0.2 - preloadedAssets: [] + preloadedAssets: + - {fileID: 1814176829808956018, guid: 58f40b12bbc864f3c96c6505a9a1e1e3, type: 2} + - {fileID: 11400000, guid: d0f8149c48842b4488cf6fb974cff9a2, type: 2} metroInputSource: 0 wsaTransparentSwapchain: 0 m_HolographicPauseOnTrackingLoss: 1 @@ -163,7 +165,7 @@ PlayerSettings: androidSupportedAspectRatio: 1 androidMaxAspectRatio: 2.1 applicationIdentifier: - Android: com.pineappletech.loong.jilinchangchunchaoyangouyamaichang + Android: com.pineappletech.loong.gongsi1lou Standalone: com.DefaultCompany.com.unity.template.ar buildNumber: Standalone: 0