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}