From daf475467c10cd77c8d3027c173808f709965a4e Mon Sep 17 00:00:00 2001 From: bzx <496597135@qq.com> Date: Wed, 14 Jan 2026 18:17:11 +0800 Subject: [PATCH] =?UTF-8?q?add=EF=BC=9A=E6=B7=BB=E5=8A=A0=E4=B8=AD?= =?UTF-8?q?=E6=8E=A7=E8=84=9A=E6=9C=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Assets/Scripts/GameInit.cs | 3 + Assets/Scripts/GameManager.cs | 30 +- Assets/Scripts/HttpServer.cs | 304 ++++++++++++++++++ Assets/Scripts/HttpServer.cs.meta | 11 + .../_MechanicalAge/Scenes/Company1Floor.unity | 46 +++ 5 files changed, 392 insertions(+), 2 deletions(-) create mode 100644 Assets/Scripts/HttpServer.cs create mode 100644 Assets/Scripts/HttpServer.cs.meta diff --git a/Assets/Scripts/GameInit.cs b/Assets/Scripts/GameInit.cs index eb152f9c..1e5d1b24 100644 --- a/Assets/Scripts/GameInit.cs +++ b/Assets/Scripts/GameInit.cs @@ -42,6 +42,8 @@ public class GameInit : MonoBehaviour /// 游戏场地 /// huan public GamePlace gamePlace = GamePlace.LiaoningAnShan; + + public GameKey gameId; [NonSerialized] public Player self; @@ -69,6 +71,7 @@ public class GameInit : MonoBehaviour private void Start() { movePos = movePoses; + gameId = GameKey.XMen; // if (Runing && Test) // { // Runing.SetActive(true); diff --git a/Assets/Scripts/GameManager.cs b/Assets/Scripts/GameManager.cs index 9594e6b6..49c508fc 100644 --- a/Assets/Scripts/GameManager.cs +++ b/Assets/Scripts/GameManager.cs @@ -21,7 +21,21 @@ using XPlugin.Data.JsonLiteDB; using static XPlugin.Data.JsonLiteDB.JsonLiteDB; using Random = UnityEngine.Random; - +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,//三星堆之谜 +} /// /// 游戏场地 /// @@ -135,6 +149,8 @@ public class GameManager : NetworkBehaviour //总共游玩时间 // 总游玩时长 public int vistAllTime; + + public float curGameTime = 0; // json数据库 private JsonLiteDB DB; // 怪物详情 @@ -325,6 +341,10 @@ public class GameManager : NetworkBehaviour { // 更新指引箭头位置 UpdateGuideArrowPosition(); + if (GameStart) + { + curGameTime+= Time.deltaTime; + } // if (isServer && enemyList.Count > 0) // { // List vectors = new List(); @@ -402,7 +422,7 @@ public class GameManager : NetworkBehaviour //authInfo.shop = 0; - authInfo.gameId = 2; + authInfo.gameId = (int)GameInit.Ins.gameId; string authJson = JsonUtility.ToJson(authInfo); Debug.Log("发送数据 -> " + authJson); request.RawData = System.Text.Encoding.UTF8.GetBytes(authJson); @@ -433,6 +453,12 @@ public class GameManager : NetworkBehaviour //RequestNotifyEnd(); } + + public int GetNowTime() + { + return Mathf.FloorToInt(curGameTime); + } + /// /// 通知服务器已开始游戏 /// diff --git a/Assets/Scripts/HttpServer.cs b/Assets/Scripts/HttpServer.cs new file mode 100644 index 00000000..a4f7896e --- /dev/null +++ b/Assets/Scripts/HttpServer.cs @@ -0,0 +1,304 @@ +using System; +using System.IO; +using System.Net; +using System.Text; +using System.Threading; +using System.Collections.Concurrent; +using UnityEngine; + +[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 GameInit.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/Scripts/HttpServer.cs.meta b/Assets/Scripts/HttpServer.cs.meta new file mode 100644 index 00000000..36362cb8 --- /dev/null +++ b/Assets/Scripts/HttpServer.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 7c9382bc21edc6641baafefa9e930df8 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/_MechanicalAge/Scenes/Company1Floor.unity b/Assets/_MechanicalAge/Scenes/Company1Floor.unity index 0db77150..79c8d2f4 100644 --- a/Assets/_MechanicalAge/Scenes/Company1Floor.unity +++ b/Assets/_MechanicalAge/Scenes/Company1Floor.unity @@ -3891,6 +3891,50 @@ Camera: m_OcclusionCulling: 1 m_StereoConvergence: 10 m_StereoSeparation: 0.022 +--- !u!1 &523384109 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 523384111} + - component: {fileID: 523384110} + m_Layer: 0 + m_Name: HttpServer + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!114 &523384110 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 523384109} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 7c9382bc21edc6641baafefa9e930df8, type: 3} + m_Name: + m_EditorClassIdentifier: +--- !u!4 &523384111 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 523384109} + serializedVersion: 2 + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 21.374298, y: 3.2485352, z: 92.547455} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: [] + m_Father: {fileID: 0} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} --- !u!1 &528436888 GameObject: m_ObjectHideFlags: 0 @@ -4742,6 +4786,7 @@ MonoBehaviour: Runing: {fileID: 0} Test: {fileID: 0} gamePlace: 0 + gameId: 0 SpiderPos: - {fileID: 1694933855} - {fileID: 907550078} @@ -22819,3 +22864,4 @@ SceneRoots: - {fileID: 1791954939} - {fileID: 803607310} - {fileID: 93085230} + - {fileID: 523384111}