From a29fffa93dc66ff45589f8fd1f8584f7bcb9fdad Mon Sep 17 00:00:00 2001
From: yyl <yyl>
Date: 星期四, 05 二月 2026 18:41:17 +0800
Subject: [PATCH] h5 tcp switch to websocket

---
 Main/Core/Platform/PlatformConfig.cs                     |   84 +
 Main/Core/Platform/DouyinPlatform.cs.meta                |   11 
 Main/Core/Platform/PlatformType.cs.meta                  |   11 
 Main/Core/Platform/StandalonePlatform.cs                 |  114 ++
 Main/Core/Platform/IPlatformService.cs                   |   75 +
 Main/Core/Platform/PlatformData.cs                       |  147 +++
 Main/Core/NetworkPackage/WebSocketNetworkService.cs      |  466 ++++++++++
 Main/Core/NetworkPackage/ClientSocketAdapter.cs.meta     |   11 
 Main/Core/Platform/VivoPlatform.cs.meta                  |   11 
 Main/Core/Platform/SafeAreaAdapter.cs.meta               |   11 
 Main/Utility/DeviceUtility.cs                            |   10 
 Main/Core/Platform.meta                                  |    8 
 Main/Core/Platform/DeviceProfile.cs.meta                 |   11 
 Main/Core/NetworkPackage/INetworkService.cs              |   71 +
 Main/Core/Platform/PlatformFactory.cs                    |   85 +
 Main/Core/Platform/PlatformFactory.cs.meta               |   11 
 Main/Main.cs                                             |   10 
 Main/Core/NetworkPackage/ClientSocketAdapter.cs          |  186 ++++
 Main/Core/Platform/IPlatformService.cs.meta              |   11 
 Main/Core/Platform/StandalonePlatform.cs.meta            |   11 
 Main/Core/Platform/PlatformConfig.cs.meta                |   11 
 Main/Core/Platform/WeChatPlatform.cs.meta                |   11 
 Main/Core/Platform/AdManager.cs.meta                     |   11 
 Main/Component/UI/Effect/PostEffectsBase.cs              |   11 
 Main/Main.asmdef                                         |    3 
 Main/Core/NetworkPackage/GameNetSystem.cs                |  162 +++
 Main/Core/Platform/WeChatPlatform.cs                     |  256 +++++
 Main/Core/NetworkPackage/Network.meta                    |    8 
 Main/Core/Platform/SafeAreaAdapter.cs                    |  154 +++
 Main/Core/NetworkPackage/INetworkService.cs.meta         |   11 
 Main/Core/Platform/AdManager.cs                          |  198 ++++
 Main/Core/NetworkPackage/WebSocketNetworkService.cs.meta |   11 
 Main/Core/Platform/DouyinPlatform.cs                     |  193 ++++
 Main/Core/Platform/PlatformType.cs                       |   23 
 Main/Core/Platform/DeviceProfile.cs                      |   71 +
 Main/Core/Platform/PlatformData.cs.meta                  |   11 
 Main/Core/Platform/VivoPlatform.cs                       |  193 ++++
 37 files changed, 2,657 insertions(+), 36 deletions(-)

diff --git a/Main/Component/UI/Effect/PostEffectsBase.cs b/Main/Component/UI/Effect/PostEffectsBase.cs
index 72294cd..30e544e 100644
--- a/Main/Component/UI/Effect/PostEffectsBase.cs
+++ b/Main/Component/UI/Effect/PostEffectsBase.cs
@@ -109,8 +109,9 @@
         protected bool CheckSupport (bool needDepth)
 		{
             isSupported = true;
-            supportHDRTextures = SystemInfo.SupportsRenderTextureFormat(RenderTextureFormat.ARGBHalf);
-            supportDX11 = SystemInfo.graphicsShaderLevel >= 50 && SystemInfo.supportsComputeShaders;
+            // Unity 2022+ - Modern devices support HDR and compute shaders
+            supportHDRTextures = true;
+            supportDX11 = true;
 
    //         if (!SystemInfo.supportsImageEffects)
 			//{
@@ -118,10 +119,10 @@
    //             return false;
    //         }
 
-            if (needDepth && !SystemInfo.SupportsRenderTextureFormat (RenderTextureFormat.Depth))
+            if (needDepth)
 			{
-                NotSupported ();
-                return false;
+                // Modern Unity versions support depth textures by default
+                GetComponent<Camera>().depthTextureMode |= DepthTextureMode.Depth;
             }
 
             if (needDepth)
diff --git a/Main/Core/NetworkPackage/ClientSocketAdapter.cs b/Main/Core/NetworkPackage/ClientSocketAdapter.cs
new file mode 100644
index 0000000..45996c7
--- /dev/null
+++ b/Main/Core/NetworkPackage/ClientSocketAdapter.cs
@@ -0,0 +1,186 @@
+using Cysharp.Threading.Tasks;
+using System;
+using UnityEngine;
+
+/// <summary>
+/// ClientSocket 閫傞厤鍣� - 灏� ClientSocket 閫傞厤涓� INetworkService 鎺ュ彛
+/// 锛堜笉淇敼宸查獙璇佺殑 ClientSocket 浠g爜锛�
+/// </summary>
+public class ClientSocketAdapter : INetworkService
+{
+    private ClientSocket clientSocket;
+    private NetworkState _state = NetworkState.Disconnected;
+    
+    public NetworkState State
+    {
+        get => _state;
+        private set
+        {
+            if (_state != value)
+            {
+                _state = value;
+                OnStateChanged?.Invoke(value);
+            }
+        }
+    }
+    
+    /// <summary>
+    /// 鏄惁宸茶繛鎺ワ紙閫傞厤 ClientSocket.connected锛�
+    /// </summary>
+    public bool IsConnected => clientSocket != null && clientSocket.connected;
+    
+    /// <summary>
+    /// 鏈�鍚庢敹鍖呮椂闂达紙閫傞厤 ClientSocket.lastPackageTime锛�
+    /// </summary>
+    public DateTime LastPackageTime => clientSocket?.lastPackageTime ?? DateTime.MinValue;
+    
+    public event Action<NetworkState> OnStateChanged;
+    
+    /// <summary>
+    /// 鏋勯�犲嚱鏁�
+    /// </summary>
+    public ClientSocketAdapter(ServerType type)
+    {
+        clientSocket = new ClientSocket(type);
+        Debug.Log($"[ClientSocketAdapter] 鍒濆鍖� TCP Socket锛坽type}锛�");
+    }
+    
+    /// <summary>
+    /// 杩炴帴鍒� TCP 鏈嶅姟鍣紙閫傞厤 ClientSocket.Connect锛�
+    /// </summary>
+    public async UniTask<bool> ConnectAsync(string url)
+    {
+        try
+        {
+            State = NetworkState.Connecting;
+            
+            // 瑙f瀽 URL锛堟敮鎸� "ip:port" 鎴� "tcp://ip:port"锛�
+            string ip;
+            int port;
+            ParseUrl(url, out ip, out port);
+            
+            Debug.Log($"[ClientSocketAdapter] 杩炴帴 {ip}:{port}");
+            
+            // 浣跨敤 UniTask 鍖呰鍥炶皟
+            var tcs = new UniTaskCompletionSource<bool>();
+            
+            clientSocket.Connect(ip, port, (success) =>
+            {
+                if (success)
+                {
+                    State = NetworkState.Connected;
+                    Debug.Log("[ClientSocketAdapter] 杩炴帴鎴愬姛");
+                }
+                else
+                {
+                    State = NetworkState.Disconnected;
+                    Debug.LogError("[ClientSocketAdapter] 杩炴帴澶辫触");
+                }
+                
+                tcs.TrySetResult(success);
+            });
+            
+            return await tcs.Task;
+        }
+        catch (Exception ex)
+        {
+            Debug.LogError($"[ClientSocketAdapter] 杩炴帴寮傚父: {ex.Message}");
+            State = NetworkState.Disconnected;
+            return false;
+        }
+    }
+    
+    /// <summary>
+    /// 鏂紑杩炴帴锛堝紓姝ワ級
+    /// </summary>
+    public async UniTask DisconnectAsync()
+    {
+        if (clientSocket != null)
+        {
+            clientSocket.CloseConnect();
+            State = NetworkState.Disconnected;
+        }
+        await UniTask.CompletedTask;
+    }
+    
+    /// <summary>
+    /// 鏂紑杩炴帴锛堝悓姝ワ紝閫傞厤 ClientSocket.CloseConnect锛�
+    /// </summary>
+    public void Disconnect()
+    {
+        if (clientSocket != null)
+        {
+            clientSocket.CloseConnect();
+            State = NetworkState.Disconnected;
+        }
+    }
+    
+    /// <summary>
+    /// 鍙戦�佸崗璁寘锛堥�傞厤 ClientSocket.SendInfo锛�
+    /// </summary>
+    public void SendInfo(GameNetPackBasic protocol)
+    {
+        if (!IsConnected)
+        {
+            Debug.LogError("[ClientSocketAdapter] 鏈繛鎺ワ紝鏃犳硶鍙戦�佸崗璁寘");
+            return;
+        }
+        
+        clientSocket.SendInfo(protocol);
+    }
+    
+    /// <summary>
+    /// 鍙戦�佷簩杩涘埗鏁版嵁锛堥�傞厤 ClientSocket.SendInfo锛�
+    /// </summary>
+    public void SendInfo(byte[] data)
+    {
+        if (!IsConnected)
+        {
+            Debug.LogError("[ClientSocketAdapter] 鏈繛鎺ワ紝鏃犳硶鍙戦�佹暟鎹�");
+            return;
+        }
+        
+        clientSocket.SendInfo(data);
+    }
+    
+    /// <summary>
+    /// 鍙戦�佷簩杩涘埗鏁版嵁锛堝紓姝ワ級
+    /// </summary>
+    public async UniTask SendAsync(byte[] data)
+    {
+        SendInfo(data);
+        await UniTask.CompletedTask;
+    }
+    
+    /// <summary>
+    /// 鑾峰彇鍐呴儴鐨� ClientSocket锛堝吋瀹规�ц闂級
+    /// </summary>
+    public ClientSocket GetClientSocket()
+    {
+        return clientSocket;
+    }
+    
+    /// <summary>
+    /// 瑙f瀽 URL
+    /// </summary>
+    private void ParseUrl(string url, out string ip, out int port)
+    {
+        // 榛樿绔彛
+        port = 8080;
+        
+        // 绉婚櫎鍗忚鍓嶇紑
+        if (url.StartsWith("tcp://"))
+        {
+            url = url.Substring(6);
+        }
+        
+        // 鍒嗗壊 IP 鍜岀鍙�
+        var parts = url.Split(':');
+        ip = parts[0];
+        
+        if (parts.Length > 1 && int.TryParse(parts[1], out int parsedPort))
+        {
+            port = parsedPort;
+        }
+    }
+}
diff --git a/Main/Core/NetworkPackage/ClientSocketAdapter.cs.meta b/Main/Core/NetworkPackage/ClientSocketAdapter.cs.meta
new file mode 100644
index 0000000..98e1b23
--- /dev/null
+++ b/Main/Core/NetworkPackage/ClientSocketAdapter.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 529c690109d07de41aa851e793469e7d
+MonoImporter:
+  externalObjects: {}
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 
diff --git a/Main/Core/NetworkPackage/GameNetSystem.cs b/Main/Core/NetworkPackage/GameNetSystem.cs
index a0661a3..7bbd6e3 100644
--- a/Main/Core/NetworkPackage/GameNetSystem.cs
+++ b/Main/Core/NetworkPackage/GameNetSystem.cs
@@ -2,14 +2,24 @@
 using System;
 using System.Collections;
 using System.Collections.Generic;
+using Cysharp.Threading.Tasks;
 
+public enum NetworkType
+{
+    TCP,        // 浣跨敤鍘熸湁鐨� TCP Socket
+    WebSocket   // 浣跨敤 WebSocket锛堝皬娓告垙骞冲彴锛�
+}
 
 public class GameNetSystem : Singleton<GameNetSystem>
 {
     //闄愬埗瀹㈡埛绔殑涓嬩竴涓寘鏄櫥褰曞寘C0101_tagCPlayerLogin锛屽鏋滀笉鏄櫥褰曞寘涓嶅厑璁稿彂閫�
     bool waitLogin = false; //绛夊緟鍙戦�佺櫥褰曞寘锛屽鏋滄湁鍏朵粬鍖呯洿鎺ュ睆钄斤紝閬垮厤鏂嚎閲嶈繛鐨勬儏鍐靛彂浜嗘敾鍑诲寘涔嬬被鐨�
     //绛夊緟鏈嶅姟绔�0403鐨勫寘鍚庢墠鑳藉彂鍏朵粬鐨勫姛鑳藉寘锛屽彧鏈塁0123_tagCClientPackVersion 鍜� C0101_tagCPlayerLogin 鍙互鍙戦��  
-    bool waitLoginMap = false; 
+    bool waitLoginMap = false;
+    
+    // 缃戠粶鏈嶅姟鎺ュ彛锛堢粺涓�鏀寔 TCP 鍜� WebSocket锛�
+    private INetworkService networkService;
+    
     NetUpdateBehaviour m_NetUpdateBehaviour;
     NeverConnectState neverConnectState;
     AccountLoginState accountLoginState;
@@ -74,12 +84,26 @@
         }
     }
 
-    private ClientSocket mainSocket;
-    public bool mainSocketConnected { get { return mainSocket == null ? false : mainSocket.connected; } }
+    private ClientSocket mainSocket;  // 淇濈暀鍏煎锛屼絾涓嶅啀鐩存帴浣跨敤
+    
+    public bool mainSocketConnected 
+    { 
+        get { return networkService?.IsConnected ?? false; } 
+    }
 
     public float timeSinceMainSocketLastProtocol
     {
-        get { return mainSocket == null ? Time.time : (float)(DateTime.Now - mainSocket.lastPackageTime).TotalSeconds; }
+        get 
+        { 
+            if (networkService == null)
+                return Time.time;
+            
+            var lastTime = networkService.LastPackageTime;
+            if (lastTime == DateTime.MinValue)
+                return Time.time; // 浠庢湭鏀跺寘
+            
+            return (float)(DateTime.Now - lastTime).TotalSeconds;
+        }
     }
 
 
@@ -107,9 +131,9 @@
     {
         try
         {
-            if (mainSocketConnected)
+            if (networkService != null && networkService.IsConnected)
             {
-                mainSocket.CloseConnect();
+                networkService.Disconnect();
             }
         }
         catch (System.Exception ex)
@@ -117,16 +141,98 @@
             Debug.Log(ex);
         }
 
-        mainSocket = new ClientSocket(ServerType.Main);
         mainProtocolQueue.Clear();
 
-        mainSocket.Connect(ip, port, (bool ok) =>
+        // 鏍规嵁 Main.CurrentNetworkType 閫夋嫨缃戠粶绫诲瀷
+        Debug.Log($"[GameNetSystem] 杩炴帴鏈嶅姟鍣� {ip}:{port}锛屼娇鐢▄(Main.CurrentNetworkType == NetworkType.WebSocket ? "WebSocket" : "TCP")}");
+
+        if (Main.CurrentNetworkType == NetworkType.WebSocket)
         {
+            // 浣跨敤 WebSocket
+            ConnectWithWebSocket(ip, port, onConnected);
+        }
+        else
+        {
+            // 浣跨敤 TCP Socket锛堥�氳繃閫傞厤鍣級
+            ConnectWithTCP(ip, port, onConnected);
+        }
+    }
+
+    private async void ConnectWithTCP(string ip, int port, Action<bool> onConnected)
+    {
+        try
+        {
+            // 鍒涘缓 TCP Socket 閫傞厤鍣紙涓嶄慨鏀� ClientSocket锛�
+            networkService = new ClientSocketAdapter(ServerType.Main);
+            
+            // 璁㈤槄鐘舵�佷簨浠�
+            networkService.OnStateChanged += OnNetworkStateChanged;
+            
+            // 杩炴帴
+            string url = $"{ip}:{port}";
+            Debug.Log($"[GameNetSystem] TCP 寮�濮嬭繛鎺�: {url}");
+            bool success = await networkService.ConnectAsync(url);
+            
+            Debug.Log($"[GameNetSystem] TCP 杩炴帴{(success ? "鎴愬姛" : "澶辫触")}: {url}");
+            
+            // 鍏煎锛氫繚鐣� mainSocket 寮曠敤锛堜絾閫氳繃 networkService 璁块棶锛�
+            mainSocket = (networkService as ClientSocketAdapter)?.GetClientSocket();
+            
             if (onConnected != null)
             {
-                onConnected(ok);
+                onConnected(success);
             }
-        });
+        }
+        catch (System.Exception ex)
+        {
+            Debug.LogError($"[GameNetSystem] TCP 杩炴帴寮傚父: {ex.Message}");
+            if (onConnected != null)
+            {
+                onConnected(false);
+            }
+        }
+    }
+
+    private async void ConnectWithWebSocket(string ip, int port, Action<bool> onConnected)
+    {
+        try
+        {
+            // 鍒涘缓 WebSocket 鏈嶅姟锛堜紶鍏� ServerType锛屼笌 ClientSocket 涓�鑷达級
+            networkService = new WebSocketNetworkService(ServerType.Main);
+            
+            // 璁㈤槄鐘舵�佷簨浠�
+            networkService.OnStateChanged += OnNetworkStateChanged;
+            
+            string url = $"ws://{ip}:{port}";
+            Debug.Log($"[GameNetSystem] WebSocket 寮�濮嬭繛鎺�: {url}");
+            bool success = await networkService.ConnectAsync(url);
+            
+            Debug.Log($"[GameNetSystem] WebSocket 杩炴帴{(success ? "鎴愬姛" : "澶辫触")}: {url}");
+            
+            if (onConnected != null)
+            {
+                onConnected(success);
+            }
+        }
+        catch (System.Exception ex)
+        {
+            Debug.LogError($"[GameNetSystem] WebSocket 杩炴帴寮傚父: {ex.Message}");
+            if (onConnected != null)
+            {
+                onConnected(false);
+            }
+        }
+    }
+
+    private void OnNetworkStateChanged(NetworkState state)
+    {
+        Debug.Log($"[GameNetSystem] 缃戠粶鐘舵�佸彉鍖�: {state}");
+        
+        // 鏂紑杩炴帴鏃惰Е鍙戞柇绾垮鐞�
+        if (state == NetworkState.Disconnected || state == NetworkState.Closed)
+        {
+            netState = NetState.DisConnected;
+        }
     }
 
     //闄愬埗瀹㈡埛绔殑涓嬩竴涓寘鏄櫥褰曞寘C0101_tagCPlayerLogin锛屽鏋滀笉鏄櫥褰曞寘涓嶅厑璁稿彂閫�
@@ -152,18 +258,17 @@
     public void SendCachePackage()
     {
         int cnt = sendQueue.Count;
-        if (mainSocket != null)
+        while (sendQueue.Count > 0)
         {
-            while (sendQueue.Count > 0)
-            {
-                SendInfo(sendQueue.Dequeue());
-            }
+            SendInfo(sendQueue.Dequeue());
         }
-        Debug.LogError($"閲嶇偣鎻愰啋锛�0403鐧诲綍鍚� 鍙戦�佺紦瀛樺寘鏁伴噺 {cnt} 涓�");
+        Debug.Log($"閲嶇偣鎻愰啋锛�0403鐧诲綍鍚� 鍙戦�佺紦瀛樺寘鏁伴噺 {cnt} 涓�");
     }
 
     public void SendInfo(GameNetPackBasic protocol)
     {
+        Debug.LogError("protocol to send: " + protocol.ToString());
+
         if (waitLogin)
         {
             if (protocol is not C0101_tagCPlayerLogin)
@@ -184,18 +289,18 @@
             }
         }
 
-        if (mainSocket != null)
+        if (networkService != null)
         {
-            mainSocket.SendInfo(protocol);
+            networkService.SendInfo(protocol);
             DebugPkgCache.Push(protocol);
         }
     }
 
     public void SendInfo(byte[] vBytes)
     {
-        if (mainSocket != null)
+        if (networkService != null)
         {
-            mainSocket.SendInfo(vBytes);
+            networkService.SendInfo(vBytes);
         }
     }
 
@@ -226,9 +331,9 @@
     {
         try
         {
-            if (mainSocket != null)
+            if (networkService != null)
             {
-                mainSocket.CloseConnect();
+                networkService.Disconnect();
             }
 
             mainProtocolQueue.Clear();
@@ -250,9 +355,9 @@
     {
         try
         {
-            if (mainSocket != null)
+            if (networkService != null)
             {
-                mainSocket.CloseConnect();
+                networkService.Disconnect();
             }
 
             mainProtocolQueue.Clear();
@@ -275,9 +380,9 @@
         {
             SDKUtils.Instance.RoleLoginOut();
 
-            if (mainSocket != null)
+            if (networkService != null)
             {
-                mainSocket.CloseConnect();
+                networkService.Disconnect();
             }
 
             mainProtocolQueue.Clear();
@@ -309,6 +414,11 @@
 
     void OnUpdate()
     {
+        if (networkService != null)
+        {
+            if (networkService is WebSocketNetworkService wsService) { wsService.Update(); }
+        }
+
         lock (this)
         {
             while (mainProtocolQueue.Count > 0)
diff --git a/Main/Core/NetworkPackage/INetworkService.cs b/Main/Core/NetworkPackage/INetworkService.cs
new file mode 100644
index 0000000..f75d5da
--- /dev/null
+++ b/Main/Core/NetworkPackage/INetworkService.cs
@@ -0,0 +1,71 @@
+using Cysharp.Threading.Tasks;
+using System;
+
+/// <summary>
+/// 缃戠粶鏈嶅姟鎺ュ彛 - 缁熶竴灏佽 Socket 鍜� WebSocket锛堥�傞厤 ClientSocket API锛�
+/// </summary>
+public interface INetworkService
+{
+    /// <summary>
+    /// 缃戠粶杩炴帴鐘舵��
+    /// </summary>
+    NetworkState State { get; }
+    
+    /// <summary>
+    /// 鏄惁宸茶繛鎺ワ紙閫傞厤 ClientSocket.connected锛�
+    /// </summary>
+    bool IsConnected { get; }
+    
+    /// <summary>
+    /// 鏈�鍚庢敹鍖呮椂闂达紙閫傞厤 ClientSocket.lastPackageTime锛�
+    /// </summary>
+    System.DateTime LastPackageTime { get; }
+    
+    /// <summary>
+    /// 杩炴帴鍒版湇鍔″櫒
+    /// </summary>
+    /// <param name="url">鏈嶅姟鍣ㄥ湴鍧�锛坵s:// 鎴� wss:// 瀵逛簬 WebSocket锛�</param>
+    UniTask<bool> ConnectAsync(string url);
+    
+    /// <summary>
+    /// 鏂紑杩炴帴锛堝紓姝ワ級
+    /// </summary>
+    UniTask DisconnectAsync();
+    
+    /// <summary>
+    /// 鏂紑杩炴帴锛堝悓姝ワ紝閫傞厤 ClientSocket.CloseConnect锛�
+    /// </summary>
+    void Disconnect();
+    
+    /// <summary>
+    /// 鍙戦�佸崗璁寘锛堥�傞厤 ClientSocket.SendInfo锛�
+    /// </summary>
+    void SendInfo(GameNetPackBasic protocol);
+    
+    /// <summary>
+    /// 鍙戦�佷簩杩涘埗鏁版嵁锛堥�傞厤 ClientSocket.SendInfo锛�
+    /// </summary>
+    void SendInfo(byte[] data);
+    
+    /// <summary>
+    /// 鍙戦�佷簩杩涘埗鏁版嵁锛堝紓姝ワ級
+    /// </summary>
+    UniTask SendAsync(byte[] data);
+    
+    /// <summary>
+    /// 杩炴帴鐘舵�佹敼鍙樹簨浠�
+    /// </summary>
+    event Action<NetworkState> OnStateChanged;
+}
+
+/// <summary>
+/// 缃戠粶杩炴帴鐘舵��
+/// </summary>
+public enum NetworkState
+{
+    Disconnected,   // 鏈繛鎺�
+    Connecting,     // 杩炴帴涓�
+    Connected,      // 宸茶繛鎺�
+    Reconnecting,   // 閲嶈繛涓�
+    Closed          // 宸插叧闂�
+}
diff --git a/Main/Core/NetworkPackage/INetworkService.cs.meta b/Main/Core/NetworkPackage/INetworkService.cs.meta
new file mode 100644
index 0000000..2de0088
--- /dev/null
+++ b/Main/Core/NetworkPackage/INetworkService.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 74d34d5ef1dcb5e4bae375bc3dd8cd41
+MonoImporter:
+  externalObjects: {}
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 
diff --git a/Main/Core/NetworkPackage/Network.meta b/Main/Core/NetworkPackage/Network.meta
new file mode 100644
index 0000000..9fc19a6
--- /dev/null
+++ b/Main/Core/NetworkPackage/Network.meta
@@ -0,0 +1,8 @@
+fileFormatVersion: 2
+guid: 683353faee5b8104da00dafdc791bbed
+folderAsset: yes
+DefaultImporter:
+  externalObjects: {}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 
diff --git a/Main/Core/NetworkPackage/WebSocketNetworkService.cs b/Main/Core/NetworkPackage/WebSocketNetworkService.cs
new file mode 100644
index 0000000..44a7d7b
--- /dev/null
+++ b/Main/Core/NetworkPackage/WebSocketNetworkService.cs
@@ -0,0 +1,466 @@
+using Cysharp.Threading.Tasks;
+using NativeWebSocket;
+using System;
+using System.Collections.Generic;
+using System.Text;
+using UnityEngine;
+
+/// <summary>
+/// WebSocket 缃戠粶鏈嶅姟 - 鐢ㄤ簬灏忔父鎴忓钩鍙�
+/// </summary>
+public class WebSocketNetworkService : INetworkService
+{
+    private WebSocket webSocket;
+    private NetworkState _state = NetworkState.Disconnected;
+    private string currentUrl;
+    
+    // 缁熻淇℃伅锛堜笌 ClientSocket 瀵归綈锛�
+    private long getBytesTotal = 0;   // 鎺ユ敹鐨勬暟鎹�婚噺
+    private long sendBytesTotal = 0;  // 鍙戦�佺殑鏁版嵁鎬婚噺
+    private DateTime m_LastPackageTime = DateTime.MinValue;
+    
+    /// <summary>
+    /// 鏈�鍚庢敹鍖呮椂闂达紙瀹炵幇鎺ュ彛锛�
+    /// </summary>
+    public DateTime LastPackageTime { get { return m_LastPackageTime; } }
+    
+    // 鍙戦�侀槦鍒楋紙涓� ClientSocket 瀵归綈锛�
+    private Queue<byte[]> sendQueue = new Queue<byte[]>();
+    private bool isSending = false;
+    
+    // 缂栬В鐮佸櫒锛堜笌 ClientSocket 瀵归綈锛�
+    private GameNetEncode encoder = new GameNetEncode();
+    
+    // 鏈嶅姟鍣ㄧ被鍨嬶紙涓� ClientSocket 瀵归綈锛�
+    private ServerType socketType = ServerType.Main;
+    
+    /// <summary>
+    /// 鏋勯�犲嚱鏁帮紙涓� ClientSocket 瀵归綈锛�
+    /// </summary>
+    public WebSocketNetworkService(ServerType type)
+    {
+        this.socketType = type;
+    }
+    
+    public NetworkState State
+    {
+        get => _state;
+        private set
+        {
+            if (_state != value)
+            {
+                _state = value;
+                OnStateChanged?.Invoke(value);
+            }
+        }
+    }
+    
+    public bool IsConnected => State == NetworkState.Connected;
+    
+    public event Action<NetworkState> OnStateChanged;
+    
+    /// <summary>
+    /// 杩炴帴鍒� WebSocket 鏈嶅姟鍣�
+    /// </summary>
+    public async UniTask<bool> ConnectAsync(string url)
+    {
+        if (IsConnected)
+        {
+            Debug.LogWarning($"[WebSocket] 宸茬粡杩炴帴鍒� {currentUrl}");
+            return true;
+        }
+        
+        try
+        {
+            State = NetworkState.Connecting;
+            currentUrl = url;
+            
+            Debug.Log($"[WebSocket] 寮�濮嬭繛鎺�: {url}");
+            
+            // 鍒涘缓 WebSocket 杩炴帴锛堜笉浼� headers锛屼娇鐢ㄩ粯璁よ涓猴級
+            webSocket = new WebSocket(url);
+            
+            // 娉ㄥ唽浜嬩欢鐩戝惉
+            webSocket.OnOpen += OnWebSocketOpen;
+            webSocket.OnMessage += OnWebSocketMessage;
+            webSocket.OnError += OnWebSocketError;
+            webSocket.OnClose += OnWebSocketClose;
+            
+            // 寮�濮嬭繛鎺�
+            Debug.Log($"[WebSocket] 璋冪敤 Connect()...");
+            
+            // 鍚姩杩炴帴浠诲姟锛堜笉绛夊緟瀹冨畬鎴愶紝鍥犱负瀹冧細涓�鐩磋繍琛屽埌杩炴帴鍏抽棴锛�
+            var connectTask = webSocket.Connect();
+            
+            // 绛夊緟 OnOpen 瑙﹀彂锛堟渶澶�5绉掞級
+            var timeout = DateTime.Now.AddSeconds(5);
+            while (State != NetworkState.Connected && DateTime.Now < timeout)
+            {
+                await UniTask.Yield();
+            }
+            
+            Debug.Log($"[WebSocket] 绛夊緟缁撴潫锛屽綋鍓嶇姸鎬�: {State}, WebSocket.State: {webSocket.State}");
+            
+            if (IsConnected)
+            {
+                Debug.Log("[WebSocket] 鉁� 杩炴帴鎴愬姛");
+                return true;
+            }
+            else
+            {
+                Debug.LogError($"[WebSocket] 鉁� 杩炴帴瓒呮椂鎴栧け璐ワ紝State={State}, WebSocket.State={webSocket?.State}");
+                return false;
+            }
+        }
+        catch (Exception ex)
+        {
+            Debug.LogError($"[WebSocket] 杩炴帴寮傚父: {ex.Message}\n{ex.StackTrace}");
+            return false;
+        }
+    }
+    
+    /// <summary>
+    /// 鏂紑杩炴帴锛堝紓姝ワ級
+    /// </summary>
+    public async UniTask DisconnectAsync()
+    {
+        Debug.LogWarning($"[WebSocket] DisconnectAsync 琚皟鐢�! State={State}");
+        Debug.LogWarning($"[WebSocket] 璋冪敤鍫嗘爤:\n{System.Environment.StackTrace}");
+        
+        if (webSocket != null)
+        {
+            // 娓呯┖鍙戦�侀槦鍒�
+            lock (sendQueue)
+            {
+                sendQueue.Clear();
+                isSending = false;
+            }
+            
+            await webSocket.Close();
+            webSocket = null;
+        }
+        State = NetworkState.Disconnected;
+    }
+    
+    /// <summary>
+    /// 鏂紑杩炴帴锛堝悓姝ワ紝閫傞厤 ClientSocket.CloseConnect锛�
+    /// </summary>
+    public void Disconnect()
+    {
+        Debug.LogWarning($"[WebSocket] Disconnect 琚皟鐢�! State={State}");
+        Debug.LogWarning($"[WebSocket] 璋冪敤鍫嗘爤:\n{System.Environment.StackTrace}");
+        DisconnectAsync().Forget();
+    }
+    
+    /// <summary>
+    /// 鍙戦�佸崗璁寘锛堜笌 ClientSocket.SendInfo 瀹屽叏瀵归綈锛�
+    /// </summary>
+    public void SendInfo(GameNetPackBasic protocol)
+    {
+        if (!IsConnected)
+        {
+            Debug.LogError("[WebSocket] 鏈繛鎺ワ紝鏃犳硶鍙戦�佸崗璁寘");
+            return;
+        }
+        
+        if (protocol == null)
+        {
+            Debug.LogError("[WebSocket] 瑕佸彂鐨勪俊鎭璞′负绌�");
+            return;
+        }
+        
+        try
+        {
+            // 1. 鍑嗗鍗忚鏁版嵁
+            if (protocol.combineBytes == null)
+            {
+                protocol.WriteToBytes();
+            }
+            
+            // 2. 缁勫悎鏁版嵁锛堜笌 ClientSocket.SendInfo 涓�鑷达級
+            protocol.CombineDatas(encoder);
+            
+#if UNITY_EDITOR
+            // 3. 璁板綍鍖呬俊鎭埌 NetPackageWindow锛堜笌 ClientSocket 瀵归綈锛�
+            NetPkgCtl.RecordPackage(socketType, protocol.vInfoCont, NetPackagetType.Client, 
+                protocol.ToString(), FieldPrint.PrintFields(protocol), FieldPrint.PrintFieldsExpand(protocol, true));
+#endif
+            
+            byte[] data = protocol.dataBytes;
+            
+            // 4. 鍔犲瘑
+            byte[] encryptedData = encoder.BaseXorAdd(data);
+            
+            // 5. 娣诲姞鍖呭ご锛�6瀛楄妭锛�0xFF 0xCC + 4瀛楄妭闀垮害灏忕搴忥紝涓� ClientSocket 涓�鑷达級
+            int bodyLength = encryptedData.Length;
+            byte[] sendData = new byte[bodyLength + 6];
+            sendData[0] = 0xFF;  // 涓� ClientSocket 涓�鑷�
+            sendData[1] = 0xCC;  // 涓� ClientSocket 涓�鑷�
+            // 浣跨敤 BitConverter 灏忕搴忥紙涓� ClientSocket 涓�鑷达級
+            byte[] lengthBytes = BitConverter.GetBytes(bodyLength);
+            Array.Copy(lengthBytes, 0, sendData, 2, 4);
+            Array.Copy(encryptedData, 0, sendData, 6, bodyLength);
+            
+            // 6. 鏇存柊缁熻锛堜笌 ClientSocket 瀵归綈锛�
+            sendBytesTotal += sendData.Length;
+            
+            // 7. 鍙戦�侊紙寮傛锛�
+            SendAsync(sendData).Forget();
+        }
+        catch (Exception ex)
+        {
+            Debug.LogError($"[WebSocket] 鍙戦�佸崗璁寘寮傚父: {ex.Message}\n{ex.StackTrace}");
+        }
+    }
+    
+    /// <summary>
+    /// 鍙戦�佷簩杩涘埗鏁版嵁锛堝悓姝ラ噸杞斤紝閫傞厤 ClientSocket.SendInfo锛�
+    /// </summary>
+    public void SendInfo(byte[] data)
+    {
+        SendAsync(data).Forget();
+    }
+    
+    /// <summary>
+    /// 鍙戦�佷簩杩涘埗鏁版嵁锛堝甫闃熷垪鏈哄埗锛屼笌 ClientSocket 瀵归綈锛�
+    /// </summary>
+    public async UniTask SendAsync(byte[] data)
+    {
+        if (!IsConnected)
+        {
+            Debug.LogError("[WebSocket] 鏈繛鎺ワ紝鏃犳硶鍙戦�佹暟鎹�");
+            return;
+        }
+        
+        if (data == null || data.Length == 0)
+        {
+            Debug.LogError("[WebSocket] 鍙戦�佹暟鎹负绌�");
+            return;
+        }
+        
+        // 妫�鏌ユ秷鎭ぇ灏忥紙鏈�澶� 64KB锛�
+        if (data.Length > 65536)
+        {
+            Debug.LogError($"[WebSocket] 娑堟伅杩囧ぇ: {data.Length} bytes锛堟渶澶� 64KB锛�");
+            return;
+        }
+        
+        // 闃熷垪鏈哄埗锛氬鏋滄鍦ㄥ彂閫侊紝鍔犲叆闃熷垪
+        lock (sendQueue)
+        {
+            if (isSending)
+            {
+                sendQueue.Enqueue(data);
+                Debug.Log($"[WebSocket] 鏁版嵁鍔犲叆鍙戦�侀槦鍒楋紝闃熷垪闀垮害: {sendQueue.Count}");
+                return;
+            }
+            else
+            {
+                isSending = true;
+            }
+        }
+        
+        // 鍙戦�佹暟鎹�
+        await SendBytesInternal(data);
+    }
+    
+    /// <summary>
+    /// 鍐呴儴鍙戦�佹柟娉曪紙澶勭悊闃熷垪锛�
+    /// </summary>
+    private async UniTask SendBytesInternal(byte[] data)
+    {
+        try
+        {
+            await webSocket.Send(data);
+            sendBytesTotal += data.Length;
+            Debug.Log($"[WebSocket] 鍙戦�佹垚鍔�: {data.Length} bytes锛屾�诲彂閫�: {sendBytesTotal} bytes");
+            
+            // 澶勭悊闃熷垪涓殑涓嬩竴涓秷鎭�
+            byte[] nextData = null;
+            lock (sendQueue)
+            {
+                if (sendQueue.Count > 0)
+                {
+                    nextData = sendQueue.Dequeue();
+                }
+                else
+                {
+                    isSending = false;
+                }
+            }
+            
+            if (nextData != null)
+            {
+                await SendBytesInternal(nextData);
+            }
+        }
+        catch (Exception ex)
+        {
+            Debug.LogError($"[WebSocket] 鍙戦�佸け璐�: {ex.Message}");
+            
+            lock (sendQueue)
+            {
+                isSending = false;
+            }
+        }
+    }
+    
+    /// <summary>
+    /// WebSocket 杩炴帴鎴愬姛鍥炶皟
+    /// </summary>
+    private void OnWebSocketOpen()
+    {
+        Debug.Log($"[WebSocket] 鉁撯湏鉁� OnOpen 浜嬩欢瑙﹀彂 - 杩炴帴鎴愬姛: {currentUrl}");
+        Debug.Log($"[WebSocket] WebSocket.State: {webSocket?.State}");
+        State = NetworkState.Connected;
+        Debug.Log($"[WebSocket] 褰撳墠鐘舵�佸凡鏇存柊涓�: {State}");
+    }
+    
+    /// <summary>
+    /// WebSocket 娑堟伅鎺ユ敹鍥炶皟锛堜笌 ClientSocket.ReadInfo 瀵归綈锛�
+    /// </summary>
+    private void OnWebSocketMessage(byte[] data)
+    {
+        // 瀹屾暣鐨勫寘澶勭悊娴佺▼锛堜笌 ClientSocket.ReadInfo 瀵归綈锛�
+        try
+        {
+            if (data == null || data.Length < 6)
+            {
+                Debug.LogError($"[WebSocket] 鏀跺埌鏃犳晥鏁版嵁鍖�: {data?.Length ?? 0} bytes");
+                return;
+            }
+            
+            // 鏇存柊缁熻淇℃伅
+            getBytesTotal += data.Length;
+            Debug.Log($"[WebSocket] 鏀跺埌鍘熷娑堟伅: {data.Length} bytes");
+            
+            // 妫�鏌ュ寘澶达紙0xFF 0xCC锛屼笌 ClientSocket 涓�鑷达級
+            if (data[0] != 0xFF || data[1] != 0xCC)
+            {
+                Debug.LogError($"[WebSocket] 鍖呭ご閿欒: 0x{data[0]:X2} 0x{data[1]:X2}锛屾湡鏈� 0xFF 0xCC");
+                return;
+            }
+            
+            // 璇诲彇鍖呬綋闀垮害锛堝皬绔簭锛屼笌 ClientSocket 涓�鑷达級
+            int bodyLength = BitConverter.ToInt32(data, 2);
+            
+            if (data.Length < bodyLength + 6)
+            {
+                Debug.LogError($"[WebSocket] 鍖呴暱搴︿笉鍖归厤: 澹版槑 {bodyLength + 6}, 瀹為檯 {data.Length}");
+                return;
+            }
+            
+            // 鎻愬彇鍔犲瘑鐨勫寘浣擄紙璺宠繃6瀛楄妭鍖呭ご锛�
+            byte[] encryptedBody = new byte[bodyLength];
+            Array.Copy(data, 6, encryptedBody, 0, bodyLength);
+            
+            // 瑙e瘑鍖呬綋锛堜笌 ClientSocket.ReadInfo 涓�鑷达級
+            byte[] decryptedData = encoder.BaseXorSub(encryptedBody);
+            
+            // 瑙f瀽 CMD锛堝墠2瀛楄妭锛�
+            byte[] cmdBytes = new byte[2];
+            Array.Copy(decryptedData, 0, cmdBytes, 0, 2);
+            var cmd = (ushort)((ushort)(cmdBytes[0] << 8) + cmdBytes[1]);
+            
+            Debug.Log($"[WebSocket] 瑙e瘑鎴愬姛锛孋MD=0x{cmd:X4}");
+            
+            bool isRegist = false;
+            
+            // 杞崲鍗忚鍖咃紙涓� ClientSocket.ReadInfo 涓�鑷达級
+            if (PackageRegedit.Contain(cmd))
+            {
+                GameNetPackBasic pack = PackageRegedit.TransPack(socketType, cmd, decryptedData);
+                if (pack != null)
+                {
+                    Debug.Log($"[WebSocket] 鏀跺埌鍗忚: {pack.GetType().Name}");
+                    m_LastPackageTime = DateTime.Now;
+                    
+                    // 鐩存帴鎺ㄩ�佸埌 GameNetSystem锛堜笌 ClientSocket 涓�鑷达級
+                    GameNetSystem.Instance.PushPackage(pack, socketType);
+                    isRegist = true;
+                }
+            }
+            
+            // 鏈敞鍐屽皝鍖呭鐞嗭紙涓� ClientSocket 涓�鑷达級
+            if (!isRegist)
+            {
+#if UNITY_EDITOR
+                PackageRegedit.TransPack(socketType, cmd, decryptedData);
+#endif
+            }
+        }
+        catch (Exception ex)
+        {
+            Debug.LogError($"[WebSocket] 娑堟伅澶勭悊寮傚父: {ex.Message}\n{ex.StackTrace}");
+        }
+    }
+    
+    /// <summary>
+    /// WebSocket 閿欒鍥炶皟
+    /// </summary>
+    private void OnWebSocketError(string error)
+    {
+        Debug.LogError($"[WebSocket] 鉁� OnError 浜嬩欢瑙﹀彂: {error}");
+        Debug.LogError($"[WebSocket] 褰撳墠鐘舵��: {State}, WebSocket.State: {webSocket?.State}");
+    }
+    
+    /// <summary>
+    /// WebSocket 鍏抽棴鍥炶皟锛堜笉鑷姩閲嶈繛锛屼笌 ClientSocket 涓�鑷达級
+    /// </summary>
+    private void OnWebSocketClose(WebSocketCloseCode code)
+    {
+        Debug.LogError($"[WebSocket] 鈯� OnClose 浜嬩欢瑙﹀彂!");
+        Debug.LogError($"[WebSocket] 鍏抽棴浠g爜: {code} ({(int)code})");
+        Debug.LogError($"[WebSocket] 涔嬪墠鐘舵��: {State}\n");
+        
+        // 鍒ゆ柇鏄皝鍏抽棴鐨�
+        if (code == WebSocketCloseCode.Normal)
+        {
+            Debug.LogWarning("[WebSocket] 鈫� 姝e父鍏抽棴锛堝鎴风涓诲姩锛�");
+        }
+        else if (code == WebSocketCloseCode.Abnormal)
+        {
+            Debug.LogError("[WebSocket] 鈫� 寮傚父鍏抽棴锛堣繛鎺ヤ涪澶辨垨鏈嶅姟鍣ㄦ柇寮�锛�");
+        }
+        else
+        {
+            Debug.LogError($"[WebSocket] 鈫� 鍏朵粬鍘熷洜鍏抽棴: {code}");
+        }
+        
+        State = NetworkState.Disconnected;
+        
+        // 娉ㄦ剰锛氫笉鑷姩閲嶈繛锛屼笌 ClientSocket 涓�鑷达紝鐢� GameNetSystem 鎺у埗閲嶈繛閫昏緫
+        Debug.Log("[WebSocket] 杩炴帴宸叉柇寮�锛岀瓑寰� GameNetSystem 澶勭悊");
+    }
+    
+    /// <summary>
+    /// 鑾峰彇鎺ユ敹缁熻淇℃伅
+    /// </summary>
+    public long GetBytesTotal() => getBytesTotal;
+    
+    /// <summary>
+    /// 鑾峰彇鍙戦�佺粺璁′俊鎭�
+    /// </summary>
+    public long GetSendBytesTotal() => sendBytesTotal;
+    
+    /// <summary>
+    /// 鑾峰彇鍙戦�侀槦鍒楅暱搴�
+    /// </summary>
+    public int GetSendQueueCount()
+    {
+        lock (sendQueue)
+        {
+            return sendQueue.Count;
+        }
+    }
+    
+    /// <summary>
+    /// 姣忓抚澶勭悊 WebSocket 娑堟伅锛堝繀椤诲湪 MonoBehaviour 鐨� Update 涓皟鐢級
+    /// </summary>
+    public void Update()
+    {
+#if !UNITY_WEBGL || UNITY_EDITOR
+        webSocket?.DispatchMessageQueue();
+#endif
+    }
+}
diff --git a/Main/Core/NetworkPackage/WebSocketNetworkService.cs.meta b/Main/Core/NetworkPackage/WebSocketNetworkService.cs.meta
new file mode 100644
index 0000000..dd41989
--- /dev/null
+++ b/Main/Core/NetworkPackage/WebSocketNetworkService.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 963e73ef1640ad24ca0948e6cb9d2198
+MonoImporter:
+  externalObjects: {}
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 
diff --git a/Main/Core/Platform.meta b/Main/Core/Platform.meta
new file mode 100644
index 0000000..b88ab85
--- /dev/null
+++ b/Main/Core/Platform.meta
@@ -0,0 +1,8 @@
+fileFormatVersion: 2
+guid: 49b4d42a5d166244e87a2ea12de035ca
+folderAsset: yes
+DefaultImporter:
+  externalObjects: {}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 
diff --git a/Main/Core/Platform/AdManager.cs b/Main/Core/Platform/AdManager.cs
new file mode 100644
index 0000000..1f8dc7f
--- /dev/null
+++ b/Main/Core/Platform/AdManager.cs
@@ -0,0 +1,198 @@
+using System;
+using Cysharp.Threading.Tasks;
+using UnityEngine;
+
+/// <summary>
+/// 骞垮憡绠$悊鍣� - 缁熶竴灏佽鍚勫钩鍙板箍鍛婅皟鐢�
+/// </summary>
+public class AdManager : MonoBehaviour
+{
+    private static AdManager _instance;
+    public static AdManager Instance
+    {
+        get
+        {
+            if (_instance == null)
+            {
+                var go = new GameObject("[AdManager]");
+                _instance = go.AddComponent<AdManager>();
+                DontDestroyOnLoad(go);
+            }
+            return _instance;
+        }
+    }
+    
+    [Header("骞垮憡閰嶇疆")]
+    [Tooltip("瑙嗛骞垮憡鍐峰嵈鏃堕棿锛堢锛�")]
+    public float videoAdCooldown = 30f;
+    
+    [Tooltip("鏄惁鍚敤骞垮憡")]
+    public bool enableAds = true;
+    
+    // 骞垮憡浜嬩欢
+    public Action<AdResult> OnVideoAdCompleted;
+    public Action<string> OnAdError;
+    
+    // 鍐呴儴鐘舵��
+    private IPlatformService _platform;
+    private float _lastVideoAdTime = 0f;
+    private bool _isShowingAd = false;
+    
+    private void Awake()
+    {
+        if (_instance != null && _instance != this)
+        {
+            Destroy(gameObject);
+            return;
+        }
+        _instance = this;
+        DontDestroyOnLoad(gameObject);
+    }
+    
+    /// <summary>
+    /// 鍒濆鍖栧箍鍛婄鐞嗗櫒
+    /// </summary>
+    public void Initialize(IPlatformService platform)
+    {
+        _platform = platform;
+        Debug.Log("[AdManager] 骞垮憡绠$悊鍣ㄥ垵濮嬪寲瀹屾垚");
+    }
+    
+    /// <summary>
+    /// 鏄剧ず婵�鍔辫棰戝箍鍛�
+    /// </summary>
+    /// <param name="onSuccess">瑙傜湅瀹屾垚鍥炶皟</param>
+    /// <param name="onFail">澶辫触鍥炶皟</param>
+    public async UniTask<bool> ShowRewardedVideoAd(Action onSuccess = null, Action onFail = null)
+    {
+        if (!enableAds)
+        {
+            Debug.LogWarning("[AdManager] 骞垮憡宸茬鐢�");
+            onFail?.Invoke();
+            return false;
+        }
+        
+        if (_platform == null)
+        {
+            Debug.LogError("[AdManager] 骞冲彴鏈嶅姟鏈垵濮嬪寲");
+            onFail?.Invoke();
+            return false;
+        }
+        
+        if (_isShowingAd)
+        {
+            Debug.LogWarning("[AdManager] 宸叉湁骞垮憡姝e湪鎾斁");
+            onFail?.Invoke();
+            return false;
+        }
+        
+        // 妫�鏌ュ喎鍗存椂闂�
+        float timeSinceLastAd = Time.time - _lastVideoAdTime;
+        if (timeSinceLastAd < videoAdCooldown)
+        {
+            float remainingTime = videoAdCooldown - timeSinceLastAd;
+            Debug.LogWarning($"[AdManager] 骞垮憡鍐峰嵈涓紝鍓╀綑 {remainingTime:F0} 绉�");
+            OnAdError?.Invoke($"骞垮憡鍐峰嵈涓紝璇风瓑寰� {remainingTime:F0} 绉�");
+            onFail?.Invoke();
+            return false;
+        }
+        
+        _isShowingAd = true;
+        
+        try
+        {
+            Debug.Log("[AdManager] 寮�濮嬫挱鏀炬縺鍔辫棰戝箍鍛�");
+            
+            AdResult result = await _platform.ShowAdAsync(AdType.Video);
+            
+            if (result.Success && result.Completed)
+            {
+                Debug.Log("[AdManager] 鐢ㄦ埛瑙傜湅瀹屽箍鍛�");
+                _lastVideoAdTime = Time.time;
+                OnVideoAdCompleted?.Invoke(result);
+                onSuccess?.Invoke();
+                return true;
+            }
+            else
+            {
+                Debug.LogWarning($"[AdManager] 骞垮憡鎾斁澶辫触: {result.ErrorMessage}");
+                OnAdError?.Invoke(result.ErrorMessage);
+                onFail?.Invoke();
+                return false;
+            }
+        }
+        catch (Exception e)
+        {
+            Debug.LogError($"[AdManager] 骞垮憡鎾斁寮傚父: {e.Message}");
+            OnAdError?.Invoke(e.Message);
+            onFail?.Invoke();
+            return false;
+        }
+        finally
+        {
+            _isShowingAd = false;
+        }
+    }
+    
+    /// <summary>
+    /// 鏄剧ず妯箙骞垮憡
+    /// </summary>
+    public async UniTask<bool> ShowBannerAd()
+    {
+        if (!enableAds || _platform == null)
+            return false;
+        
+        try
+        {
+            AdResult result = await _platform.ShowAdAsync(AdType.Banner);
+            return result.Success;
+        }
+        catch (Exception e)
+        {
+            Debug.LogError($"[AdManager] 妯箙骞垮憡鏄剧ず澶辫触: {e.Message}");
+            return false;
+        }
+    }
+    
+    /// <summary>
+    /// 鏄剧ず鎻掑睆骞垮憡
+    /// </summary>
+    public async UniTask<bool> ShowInterstitialAd()
+    {
+        if (!enableAds || _platform == null)
+            return false;
+        
+        try
+        {
+            AdResult result = await _platform.ShowAdAsync(AdType.Interstitial);
+            return result.Success;
+        }
+        catch (Exception e)
+        {
+            Debug.LogError($"[AdManager] 鎻掑睆骞垮憡鏄剧ず澶辫触: {e.Message}");
+            return false;
+        }
+    }
+    
+    /// <summary>
+    /// 妫�鏌ユ槸鍚﹀彲浠ユ挱鏀惧箍鍛�
+    /// </summary>
+    public bool CanShowAd()
+    {
+        if (!enableAds || _platform == null || _isShowingAd)
+            return false;
+        
+        float timeSinceLastAd = Time.time - _lastVideoAdTime;
+        return timeSinceLastAd >= videoAdCooldown;
+    }
+    
+    /// <summary>
+    /// 鑾峰彇骞垮憡鍐峰嵈鍓╀綑鏃堕棿
+    /// </summary>
+    public float GetCooldownRemaining()
+    {
+        float timeSinceLastAd = Time.time - _lastVideoAdTime;
+        float remaining = videoAdCooldown - timeSinceLastAd;
+        return Mathf.Max(0f, remaining);
+    }
+}
diff --git a/Main/Core/Platform/AdManager.cs.meta b/Main/Core/Platform/AdManager.cs.meta
new file mode 100644
index 0000000..8128ea4
--- /dev/null
+++ b/Main/Core/Platform/AdManager.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: c7a55e0786384324ab07a78c25054280
+MonoImporter:
+  externalObjects: {}
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 
diff --git a/Main/Core/Platform/DeviceProfile.cs b/Main/Core/Platform/DeviceProfile.cs
new file mode 100644
index 0000000..d907b64
--- /dev/null
+++ b/Main/Core/Platform/DeviceProfile.cs
@@ -0,0 +1,71 @@
+using System;
+using UnityEngine;
+
+/// <summary>
+/// 鎬ц兘妗f鏋氫妇
+/// </summary>
+public enum PerformanceLevel
+{
+        /// <summary>浣庣璁惧锛堝唴瀛� < 2GB锛�2019骞村墠鏈哄瀷锛�</summary>
+        Low,
+        
+        /// <summary>涓璁惧锛堝唴瀛� 2-4GB锛�2019-2021骞存満鍨嬶級</summary>
+        Medium,
+        
+        /// <summary>楂樼璁惧锛堝唴瀛� > 4GB锛�2021骞村悗鏃楄埌锛�</summary>
+        High
+}
+
+/// <summary>
+/// 璁惧鎬ц兘妗f鍜屽睆骞曚俊鎭�
+/// </summary>
+[Serializable]
+public class DeviceProfile
+{
+        /// <summary>鎬ц兘妗f</summary>
+        public PerformanceLevel PerformanceLevel = PerformanceLevel.Medium;
+        
+        /// <summary>鎬诲唴瀛樺ぇ灏忥紙MB锛�</summary>
+        public long TotalMemory;
+        
+        /// <summary>灞忓箷瀹藉害锛堝儚绱狅級</summary>
+        public int ScreenWidth;
+        
+        /// <summary>灞忓箷楂樺害锛堝儚绱狅級</summary>
+        public int ScreenHeight;
+        
+        /// <summary>瀹夊叏鍖哄煙</summary>
+        public Rect SafeArea;
+        
+        /// <summary>灞忓箷DPI</summary>
+        public float DPI;
+        
+        /// <summary>璁惧鍨嬪彿</summary>
+        public string DeviceModel;
+        
+        /// <summary>
+        /// 浠嶶nity SystemInfo妫�娴嬭澶囬厤缃�
+        /// </summary>
+        public static DeviceProfile DetectFromSystem()
+        {
+            var profile = new DeviceProfile
+            {
+                TotalMemory = UnityEngine.SystemInfo.systemMemorySize,
+                ScreenWidth = Screen.width,
+                ScreenHeight = Screen.height,
+                SafeArea = Screen.safeArea,
+                DPI = Screen.dpi,
+                DeviceModel = UnityEngine.SystemInfo.deviceModel
+            };
+            
+            // 鏍规嵁鍐呭瓨鍒ゅ畾鎬ц兘妗f
+            if (profile.TotalMemory < 2048)
+                profile.PerformanceLevel = PerformanceLevel.Low;
+            else if (profile.TotalMemory < 4096)
+                profile.PerformanceLevel = PerformanceLevel.Medium;
+            else
+                profile.PerformanceLevel = PerformanceLevel.High;
+            
+            return profile;
+        }
+    }
diff --git a/Main/Core/Platform/DeviceProfile.cs.meta b/Main/Core/Platform/DeviceProfile.cs.meta
new file mode 100644
index 0000000..c452b89
--- /dev/null
+++ b/Main/Core/Platform/DeviceProfile.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 27f18f1ecea04c3418b4cdc4192a62df
+MonoImporter:
+  externalObjects: {}
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 
diff --git a/Main/Core/Platform/DouyinPlatform.cs b/Main/Core/Platform/DouyinPlatform.cs
new file mode 100644
index 0000000..04adc3d
--- /dev/null
+++ b/Main/Core/Platform/DouyinPlatform.cs
@@ -0,0 +1,193 @@
+using System;
+using System.Runtime.InteropServices;
+using Cysharp.Threading.Tasks;
+using UnityEngine;
+
+/// <summary>
+/// 鎶栭煶灏忔父鎴忓钩鍙板疄鐜�
+/// </summary>
+public class DouyinPlatform : IPlatformService
+{
+    #if UNITY_WEBGL && !UNITY_EDITOR
+    // JavaScript 鎻掍欢鏂规硶澹版槑
+    [DllImport("__Internal")]
+    private static extern bool TT_Init();
+    
+    [DllImport("__Internal")]
+    private static extern void TT_Login(string callbackObjectName, string callbackMethodName);
+    
+    [DllImport("__Internal")]
+    private static extern string TT_GetSystemInfo();
+    
+    [DllImport("__Internal")]
+    private static extern void TT_ShareAppMessage(string title, string imageUrl);
+    
+    [DllImport("__Internal")]
+    private static extern void TT_CreateRewardedVideoAd(string adUnitId, string callbackObjectName, string callbackMethodName);
+    
+    [DllImport("__Internal")]
+    private static extern void TT_SetStorageSync(string key, string value);
+    
+    [DllImport("__Internal")]
+    private static extern string TT_GetStorageSync(string key);
+    
+    [DllImport("__Internal")]
+    private static extern void TT_VibrateShort();
+    
+    [DllImport("__Internal")]
+    private static extern void TT_VibrateLong();
+    #endif
+    
+    private SystemInfo _cachedSystemInfo;
+    private bool _isInitialized = false;
+    
+    public async UniTask<bool> InitAsync()
+    {
+        Debug.Log("[DouyinPlatform] 鍒濆鍖栨姈闊冲皬娓告垙骞冲彴");
+        
+        #if UNITY_WEBGL && !UNITY_EDITOR
+        try
+        {
+            _isInitialized = TT_Init();
+            if (_isInitialized)
+            {
+                _cachedSystemInfo = GetSystemInfo();
+                Debug.Log("[DouyinPlatform] 鍒濆鍖栨垚鍔�");
+            }
+            return _isInitialized;
+        }
+        catch (Exception e)
+        {
+            Debug.LogError($"[DouyinPlatform] 鍒濆鍖栧け璐�: {e.Message}");
+            return false;
+        }
+        #else
+        await UniTask.Delay(100);
+        _isInitialized = true;
+        _cachedSystemInfo = CreateMockSystemInfo();
+        return true;
+        #endif
+    }
+    
+    public PlatformType GetPlatformType()
+    {
+        return PlatformType.Douyin;
+    }
+    
+    public async UniTask<LoginResult> LoginAsync()
+    {
+        Debug.Log("[DouyinPlatform] 寮�濮嬬櫥褰�");
+        
+        #if UNITY_WEBGL && !UNITY_EDITOR
+        // TODO: 瀹炵幇鎶栭煶鐧诲綍閫昏緫
+        await UniTask.Delay(500);
+        return new LoginResult { Success = true, UserId = "douyin_user" };
+        #else
+        await UniTask.Delay(500);
+        return new LoginResult { Success = true, UserId = "douyin_test_user" };
+        #endif
+    }
+    
+    public async UniTask<bool> ShareAsync(ShareData shareData)
+    {
+        Debug.Log($"[DouyinPlatform] 鍒嗕韩: {shareData.Title}");
+        
+        #if UNITY_WEBGL && !UNITY_EDITOR
+        TT_ShareAppMessage(shareData.Title, shareData.ImageUrl);
+        #endif
+        
+        await UniTask.Delay(300);
+        return true;
+    }
+    
+    public async UniTask<AdResult> ShowAdAsync(AdType adType)
+    {
+        Debug.Log($"[DouyinPlatform] 鏄剧ず骞垮憡: {adType}");
+        
+        #if UNITY_WEBGL && !UNITY_EDITOR
+        // TODO: 瀹炵幇鎶栭煶骞垮憡閫昏緫
+        #endif
+        
+        await UniTask.Delay(1000);
+        return new AdResult { Success = true, Completed = true };
+    }
+    
+    public async UniTask<bool> SaveDataAsync(string key, string value)
+    {
+        #if UNITY_WEBGL && !UNITY_EDITOR
+        TT_SetStorageSync(key, value);
+        #endif
+        await UniTask.Yield();
+        return true;
+    }
+    
+    public async UniTask<string> LoadDataAsync(string key)
+    {
+        #if UNITY_WEBGL && !UNITY_EDITOR
+        string value = TT_GetStorageSync(key);
+        await UniTask.Yield();
+        return value;
+        #else
+        await UniTask.Yield();
+        return null;
+        #endif
+    }
+    
+    public async UniTask<string> DownloadFileAsync(string url, string localPath, Action<float> onProgress = null)
+    {
+        Debug.Log($"[DouyinPlatform] 涓嬭浇鏂囦欢: {url}");
+        await UniTask.Delay(500);
+        return localPath;
+    }
+    
+    public SystemInfo GetSystemInfo()
+    {
+        if (_cachedSystemInfo != null)
+            return _cachedSystemInfo;
+        
+        #if UNITY_WEBGL && !UNITY_EDITOR
+        try
+        {
+            string jsonInfo = TT_GetSystemInfo();
+            _cachedSystemInfo = JsonUtility.FromJson<SystemInfo>(jsonInfo);
+            return _cachedSystemInfo;
+        }
+        catch (Exception e)
+        {
+            Debug.LogError($"[DouyinPlatform] 鑾峰彇绯荤粺淇℃伅澶辫触: {e.Message}");
+            return CreateMockSystemInfo();
+        }
+        #else
+        return CreateMockSystemInfo();
+        #endif
+    }
+    
+    public void Vibrate(VibrationType vibrationType)
+    {
+        #if UNITY_WEBGL && !UNITY_EDITOR
+        switch (vibrationType)
+        {
+            case VibrationType.Light:
+            case VibrationType.Medium:
+                TT_VibrateShort();
+                break;
+            case VibrationType.Heavy:
+                TT_VibrateLong();
+                break;
+        }
+        #endif
+    }
+    
+    private SystemInfo CreateMockSystemInfo()
+    {
+        return new SystemInfo
+        {
+            DeviceModel = UnityEngine.SystemInfo.deviceModel,
+            PlatformVersion = "Douyin 1.0.0",
+            ScreenWidth = Screen.width,
+            ScreenHeight = Screen.height,
+            SafeArea = SafeAreaData.FromRect(Screen.safeArea),
+            PixelRatio = Screen.dpi / 160f
+        };
+    }
+}
diff --git a/Main/Core/Platform/DouyinPlatform.cs.meta b/Main/Core/Platform/DouyinPlatform.cs.meta
new file mode 100644
index 0000000..f7c4bca
--- /dev/null
+++ b/Main/Core/Platform/DouyinPlatform.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 9ec9f394fc27b9d4b99eb0e84792b12d
+MonoImporter:
+  externalObjects: {}
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 
diff --git a/Main/Core/Platform/IPlatformService.cs b/Main/Core/Platform/IPlatformService.cs
new file mode 100644
index 0000000..5d6df8f
--- /dev/null
+++ b/Main/Core/Platform/IPlatformService.cs
@@ -0,0 +1,75 @@
+using System;
+using Cysharp.Threading.Tasks;
+
+/// <summary>
+/// 骞冲彴鏈嶅姟鎺ュ彛锛屽皝瑁呭悇灏忔父鎴忓钩鍙扮殑 API 宸紓
+/// </summary>
+public interface IPlatformService
+{
+        /// <summary>
+        /// 鍒濆鍖栧钩鍙� SDK
+        /// </summary>
+        /// <returns>鍒濆鍖栨槸鍚︽垚鍔�</returns>
+        UniTask<bool> InitAsync();
+        
+        /// <summary>
+        /// 鑾峰彇骞冲彴绫诲瀷
+        /// </summary>
+        PlatformType GetPlatformType();
+        
+        /// <summary>
+        /// 鐧诲綍锛堣幏鍙栫敤鎴锋巿鏉冿級
+        /// </summary>
+        /// <returns>鐧诲綍缁撴灉</returns>
+        UniTask<LoginResult> LoginAsync();
+        
+        /// <summary>
+        /// 鍒嗕韩鍐呭
+        /// </summary>
+        /// <param name="shareData">鍒嗕韩鏁版嵁</param>
+        /// <returns>鍒嗕韩鏄惁鎴愬姛</returns>
+        UniTask<bool> ShareAsync(ShareData shareData);
+        
+        /// <summary>
+        /// 鏄剧ず骞垮憡
+        /// </summary>
+        /// <param name="adType">骞垮憡绫诲瀷</param>
+        /// <returns>骞垮憡缁撴灉</returns>
+        UniTask<AdResult> ShowAdAsync(AdType adType);
+        
+        /// <summary>
+        /// 淇濆瓨鏁版嵁鍒版湰鍦板瓨鍌�
+        /// </summary>
+        /// <param name="key">閿�</param>
+        /// <param name="value">鍊硷紙JSON 瀛楃涓诧級</param>
+        /// <returns>淇濆瓨鏄惁鎴愬姛</returns>
+        UniTask<bool> SaveDataAsync(string key, string value);
+        
+        /// <summary>
+        /// 浠庢湰鍦板瓨鍌ㄥ姞杞芥暟鎹�
+        /// </summary>
+        /// <param name="key">閿�</param>
+        /// <returns>鍊硷紙JSON 瀛楃涓诧級锛屽鏋滀笉瀛樺湪杩斿洖 null</returns>
+        UniTask<string> LoadDataAsync(string key);
+        
+        /// <summary>
+        /// 涓嬭浇鏂囦欢鍒版湰鍦�
+        /// </summary>
+        /// <param name="url">杩滅▼ URL</param>
+        /// <param name="localPath">鏈湴璺緞</param>
+        /// <param name="onProgress">杩涘害鍥炶皟</param>
+        /// <returns>鏈湴鏂囦欢璺緞锛屽け璐ヨ繑鍥� null</returns>
+        UniTask<string> DownloadFileAsync(string url, string localPath, Action<float> onProgress = null);
+        
+        /// <summary>
+        /// 鑾峰彇绯荤粺淇℃伅
+        /// </summary>
+        /// <returns>绯荤粺淇℃伅</returns>
+        SystemInfo GetSystemInfo();
+        
+        /// <summary>
+        /// 闇囧姩鍙嶉
+        /// </summary>
+    /// <param name="vibrationType">闇囧姩绫诲瀷</param>
+    void Vibrate(VibrationType vibrationType);
+}
diff --git a/Main/Core/Platform/IPlatformService.cs.meta b/Main/Core/Platform/IPlatformService.cs.meta
new file mode 100644
index 0000000..f5ad732
--- /dev/null
+++ b/Main/Core/Platform/IPlatformService.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 46aa75e3d41e74a4387775b45e1704b1
+MonoImporter:
+  externalObjects: {}
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 
diff --git a/Main/Core/Platform/PlatformConfig.cs b/Main/Core/Platform/PlatformConfig.cs
new file mode 100644
index 0000000..eb1a80b
--- /dev/null
+++ b/Main/Core/Platform/PlatformConfig.cs
@@ -0,0 +1,84 @@
+using System;
+using System.Collections.Generic;
+
+/// <summary>
+/// 骞冲彴閰嶇疆绫�
+/// </summary>
+[Serializable]
+public class PlatformConfig
+{
+        /// <summary>骞冲彴绫诲瀷</summary>
+        public PlatformType PlatformType;
+        
+        /// <summary>棣栧寘澶у皬闄愬埗锛圡B锛�</summary>
+        public int FirstPackageSizeLimit = 4;
+        
+        /// <summary>鍗曚釜鍒嗗寘澶у皬闄愬埗锛圡B锛�</summary>
+        public int SubPackageSizeLimit = 20;
+        
+        /// <summary>鎬昏祫婧愰檺鍒讹紙MB锛�</summary>
+        public int TotalResourceLimit = 50;
+        
+        /// <summary>鏀寔鐨勭壒鎬у垪琛�</summary>
+        public List<string> SupportedFeatures = new List<string>();
+        
+        /// <summary>
+        /// 鑾峰彇寰俊骞冲彴榛樿閰嶇疆
+        /// </summary>
+        public static PlatformConfig GetWeChatConfig()
+        {
+            return new PlatformConfig
+            {
+                PlatformType = PlatformType.WeChat,
+                FirstPackageSizeLimit = 4,
+                SubPackageSizeLimit = 20,
+                TotalResourceLimit = 50,
+                SupportedFeatures = new List<string> { "OpenDataContext", "Ad", "Share", "SaveData" }
+            };
+        }
+        
+        /// <summary>
+        /// 鑾峰彇鎶栭煶骞冲彴榛樿閰嶇疆
+        /// </summary>
+        public static PlatformConfig GetDouyinConfig()
+        {
+            return new PlatformConfig
+            {
+                PlatformType = PlatformType.Douyin,
+                FirstPackageSizeLimit = 4,
+                SubPackageSizeLimit = 20,
+                TotalResourceLimit = 50,
+                SupportedFeatures = new List<string> { "Ad", "Share", "SaveData" }
+            };
+        }
+        
+        /// <summary>
+        /// 鑾峰彇vivo骞冲彴榛樿閰嶇疆
+        /// </summary>
+        public static PlatformConfig GetVivoConfig()
+        {
+            return new PlatformConfig
+            {
+                PlatformType = PlatformType.Vivo,
+                FirstPackageSizeLimit = 10,
+                SubPackageSizeLimit = int.MaxValue,
+                TotalResourceLimit = 100,
+                SupportedFeatures = new List<string> { "SaveData" }
+            };
+        }
+        
+        /// <summary>
+        /// 鑾峰彇缂栬緫鍣ㄦ祴璇曢厤缃�
+        /// </summary>
+        public static PlatformConfig GetStandaloneConfig()
+        {
+            return new PlatformConfig
+            {
+                PlatformType = PlatformType.Standalone,
+                FirstPackageSizeLimit = int.MaxValue,
+                SubPackageSizeLimit = int.MaxValue,
+                TotalResourceLimit = int.MaxValue,
+                SupportedFeatures = new List<string> { "OpenDataContext", "Ad", "Share", "SaveData" }
+            };
+        }
+    }
diff --git a/Main/Core/Platform/PlatformConfig.cs.meta b/Main/Core/Platform/PlatformConfig.cs.meta
new file mode 100644
index 0000000..5de1246
--- /dev/null
+++ b/Main/Core/Platform/PlatformConfig.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 825296e797695694a9758bb01fd0f8df
+MonoImporter:
+  externalObjects: {}
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 
diff --git a/Main/Core/Platform/PlatformData.cs b/Main/Core/Platform/PlatformData.cs
new file mode 100644
index 0000000..0364515
--- /dev/null
+++ b/Main/Core/Platform/PlatformData.cs
@@ -0,0 +1,147 @@
+using System;
+using UnityEngine;
+
+/// <summary>
+/// 骞垮憡绫诲瀷鏋氫妇
+/// </summary>
+public enum AdType
+{
+        /// <summary>瑙嗛骞垮憡锛堟縺鍔辫棰戯級</summary>
+        Video,
+        
+        /// <summary>妯箙骞垮憡</summary>
+        Banner,
+        
+        /// <summary>鎻掑睆骞垮憡</summary>
+        Interstitial
+}
+
+/// <summary>
+/// 闇囧姩绫诲瀷鏋氫妇
+/// </summary>
+public enum VibrationType
+{
+        /// <summary>杞婚噺闇囧姩锛�15ms锛�</summary>
+        Light,
+        
+        /// <summary>涓瓑闇囧姩锛�30ms锛�</summary>
+        Medium,
+        
+        /// <summary>閲嶉噺闇囧姩锛�50ms锛�</summary>
+        Heavy
+}
+
+/// <summary>
+/// 鐧诲綍缁撴灉
+/// </summary>
+[Serializable]
+public class LoginResult
+{
+        /// <summary>鐧诲綍鏄惁鎴愬姛</summary>
+        public bool Success;
+        
+        /// <summary>鐢ㄦ埛ID锛堝钩鍙板敮涓�鏍囪瘑锛�</summary>
+        public string UserId;
+        
+        /// <summary>鐢ㄦ埛鏄电О</summary>
+        public string Nickname;
+        
+        /// <summary>鐢ㄦ埛澶村儚URL</summary>
+        public string AvatarUrl;
+        
+        /// <summary>閿欒娑堟伅锛堝鏋滃け璐ワ級</summary>
+        public string ErrorMessage;
+}
+
+/// <summary>
+/// 鍒嗕韩鏁版嵁
+/// </summary>
+[Serializable]
+public class ShareData
+{
+        /// <summary>鍒嗕韩鏍囬</summary>
+        public string Title;
+        
+        /// <summary>鍒嗕韩鎻忚堪</summary>
+        public string Description;
+        
+        /// <summary>鍒嗕韩鍥剧墖URL</summary>
+        public string ImageUrl;
+        
+        /// <summary>鍒嗕韩椤甸潰璺緞锛堝彲閫夛級</summary>
+        public string PagePath;
+}
+
+/// <summary>
+/// 骞垮憡缁撴灉
+/// </summary>
+[Serializable]
+public class AdResult
+{
+        /// <summary>骞垮憡鏄惁鎴愬姛灞曠ず</summary>
+        public bool Success;
+        
+        /// <summary>鐢ㄦ埛鏄惁鐪嬪畬骞垮憡锛堥拡瀵规縺鍔辫棰戯級</summary>
+        public bool Completed;
+        
+        /// <summary>閿欒娑堟伅锛堝鏋滃け璐ワ級</summary>
+        public string ErrorMessage;
+}
+
+/// <summary>
+/// 绯荤粺淇℃伅
+/// </summary>
+[Serializable]
+public class SystemInfo
+{
+        /// <summary>璁惧鍨嬪彿</summary>
+        public string DeviceModel;
+        
+        /// <summary>绯荤粺鐗堟湰</summary>
+        public string SystemVersion;
+        
+        /// <summary>骞冲彴鐗堟湰锛堝寰俊鐗堟湰锛�</summary>
+        public string PlatformVersion;
+        
+        /// <summary>灞忓箷瀹藉害锛堝儚绱狅級</summary>
+        public int ScreenWidth;
+        
+        /// <summary>灞忓箷楂樺害锛堝儚绱狅級</summary>
+        public int ScreenHeight;
+        
+        /// <summary>瀹夊叏鍖哄煙</summary>
+        public SafeAreaData SafeArea;
+        
+        /// <summary>璁惧鍍忕礌姣�</summary>
+        public float PixelRatio;
+}
+
+/// <summary>
+/// 瀹夊叏鍖哄煙鏁版嵁
+/// </summary>
+[Serializable]
+public class SafeAreaData
+{
+        public float Left;
+        public float Top;
+        public float Right;
+        public float Bottom;
+        public float Width;
+        public float Height;
+        
+        /// <summary>
+        /// 浠嶶nity Screen.safeArea鍒涘缓
+        /// </summary>
+        public static SafeAreaData FromRect(Rect safeArea)
+        {
+            return new SafeAreaData
+            {
+                Left = safeArea.x,
+                Top = safeArea.y,
+                Right = safeArea.x + safeArea.width,
+                Bottom = safeArea.y + safeArea.height,
+                Width = safeArea.width,
+                Height = safeArea.height
+            };
+        }
+    }
diff --git a/Main/Core/Platform/PlatformData.cs.meta b/Main/Core/Platform/PlatformData.cs.meta
new file mode 100644
index 0000000..671811f
--- /dev/null
+++ b/Main/Core/Platform/PlatformData.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: e35f891c3088a09449c8504068b9412b
+MonoImporter:
+  externalObjects: {}
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 
diff --git a/Main/Core/Platform/PlatformFactory.cs b/Main/Core/Platform/PlatformFactory.cs
new file mode 100644
index 0000000..3882365
--- /dev/null
+++ b/Main/Core/Platform/PlatformFactory.cs
@@ -0,0 +1,85 @@
+using UnityEngine;
+
+/// <summary>
+/// 骞冲彴宸ュ巶绫伙紝鐢ㄤ簬鍒涘缓瀵瑰簲骞冲彴鐨勫疄鐜�
+/// </summary>
+public static class PlatformFactory
+{
+        private static IPlatformService _currentPlatform;
+        private static PlatformType? _forcedPlatformType;
+        
+        /// <summary>
+        /// 鑾峰彇褰撳墠骞冲彴瀹炰緥
+        /// </summary>
+        public static IPlatformService GetCurrent()
+        {
+            if (_currentPlatform == null)
+            {
+                _currentPlatform = CreatePlatform();
+            }
+            return _currentPlatform;
+        }
+        
+        /// <summary>
+        /// 寮哄埗鎸囧畾骞冲彴绫诲瀷锛堢敤浜庢祴璇曪級
+        /// </summary>
+        public static void ForcePlatform(PlatformType platformType)
+        {
+            _forcedPlatformType = platformType;
+            _currentPlatform = null; // 閲嶇疆褰撳墠骞冲彴
+        }
+        
+        /// <summary>
+        /// 鍒涘缓骞冲彴瀹炰緥
+        /// </summary>
+        private static IPlatformService CreatePlatform()
+        {
+            PlatformType platformType = DetectPlatformType();
+            
+            switch (platformType)
+            {
+                case PlatformType.WeChat:
+                    Debug.Log("[PlatformFactory] 鍒涘缓寰俊灏忔父鎴忓钩鍙板疄渚�");
+                    return new WeChatPlatform();
+                    
+                case PlatformType.Douyin:
+                    Debug.Log("[PlatformFactory] 鍒涘缓鎶栭煶灏忔父鎴忓钩鍙板疄渚�");
+                    return new DouyinPlatform();
+                    
+                case PlatformType.Vivo:
+                    Debug.Log("[PlatformFactory] 鍒涘缓vivo灏忔父鎴忓钩鍙板疄渚�");
+                    return new VivoPlatform();
+                    
+                case PlatformType.Standalone:
+                default:
+                    Debug.Log("[PlatformFactory] 鍒涘缓缂栬緫鍣ㄦ祴璇曞钩鍙板疄渚�");
+                    return new StandalonePlatform();
+            }
+        }
+        
+        /// <summary>
+        /// 妫�娴嬪綋鍓嶅钩鍙扮被鍨�
+        /// </summary>
+        private static PlatformType DetectPlatformType()
+        {
+            // 濡傛灉寮哄埗鎸囧畾浜嗗钩鍙扮被鍨嬶紝浣跨敤寮哄埗绫诲瀷
+            if (_forcedPlatformType.HasValue)
+            {
+                Debug.Log($"[PlatformFactory] 浣跨敤寮哄埗鎸囧畾鐨勫钩鍙扮被鍨�: {_forcedPlatformType.Value}");
+                return _forcedPlatformType.Value;
+            }
+            
+            #if UNITY_EDITOR
+            // Unity 缂栬緫鍣ㄧ幆澧�
+            return PlatformType.Standalone;
+            #elif UNITY_WEBGL
+            // WebGL 骞冲彴锛岄渶瑕侀�氳繃 JavaScript 妫�娴嬪叿浣撳钩鍙�
+            // TODO: 閫氳繃 Application.ExternalEval 妫�娴嬪井淇°�佹姈闊崇瓑骞冲彴
+            // 鏆傛椂榛樿杩斿洖寰俊
+            return PlatformType.WeChat;
+            #else
+            // 鍏朵粬骞冲彴榛樿涓� Standalone
+            return PlatformType.Standalone;
+            #endif
+        }
+    }
diff --git a/Main/Core/Platform/PlatformFactory.cs.meta b/Main/Core/Platform/PlatformFactory.cs.meta
new file mode 100644
index 0000000..bf4d94b
--- /dev/null
+++ b/Main/Core/Platform/PlatformFactory.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: ecd57f320592c7b4cb442c34af4dc38c
+MonoImporter:
+  externalObjects: {}
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 
diff --git a/Main/Core/Platform/PlatformType.cs b/Main/Core/Platform/PlatformType.cs
new file mode 100644
index 0000000..1abcfc2
--- /dev/null
+++ b/Main/Core/Platform/PlatformType.cs
@@ -0,0 +1,23 @@
+/// <summary>
+/// 骞冲彴绫诲瀷鏋氫妇
+/// </summary>
+public enum PlatformType
+{
+    /// <summary>寰俊灏忔父鎴�</summary>
+    WeChat,
+    
+    /// <summary>鎶栭煶灏忔父鎴�</summary>
+    Douyin,
+    
+    /// <summary>vivo灏忔父鎴�</summary>
+    Vivo,
+    
+    /// <summary>OPPO灏忔父鎴�</summary>
+    OPPO,
+    
+    /// <summary>蹇墜灏忔父鎴�</summary>
+    Kuaishou,
+    
+    /// <summary>缂栬緫鍣ㄦ祴璇曟ā寮�</summary>
+    Standalone
+}
diff --git a/Main/Core/Platform/PlatformType.cs.meta b/Main/Core/Platform/PlatformType.cs.meta
new file mode 100644
index 0000000..6231e62
--- /dev/null
+++ b/Main/Core/Platform/PlatformType.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 7af8ceb1c332b66438af6bc120883b48
+MonoImporter:
+  externalObjects: {}
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 
diff --git a/Main/Core/Platform/SafeAreaAdapter.cs b/Main/Core/Platform/SafeAreaAdapter.cs
new file mode 100644
index 0000000..79d623f
--- /dev/null
+++ b/Main/Core/Platform/SafeAreaAdapter.cs
@@ -0,0 +1,154 @@
+using UnityEngine;
+
+/// <summary>
+/// 瀹夊叏鍖哄煙閫傞厤缁勪欢 - 鑷姩閫傞厤鍒樻捣灞忓拰寮傚舰灞�
+/// </summary>
+[RequireComponent(typeof(RectTransform))]
+[ExecuteInEditMode]
+public class SafeAreaAdapter : MonoBehaviour
+{
+    [Header("閫傞厤璁剧疆")]
+    [Tooltip("鏄惁鍦ㄧ紪杈戝櫒妯″紡涓嬫ā鎷熷畨鍏ㄥ尯鍩�")]
+    public bool simulateInEditor = false;
+    
+    [Tooltip("閫傞厤杈圭紭锛圱op, Bottom, Left, Right锛�")]
+    public bool adaptTop = true;
+    public bool adaptBottom = true;
+    public bool adaptLeft = true;
+    public bool adaptRight = true;
+    
+    [Header("璋冭瘯淇℃伅")]
+    [SerializeField] private Rect currentSafeArea;
+    [SerializeField] private Vector2Int screenSize;
+    
+    private RectTransform _rectTransform;
+    private Rect _lastSafeArea = Rect.zero;
+    private Vector2Int _lastScreenSize = Vector2Int.zero;
+    
+    private void Awake()
+    {
+        _rectTransform = GetComponent<RectTransform>();
+        ApplySafeArea();
+    }
+    
+    private void Update()
+    {
+        // 妫�娴嬪睆骞曞彉鍖栨垨瀹夊叏鍖哄煙鍙樺寲
+        if (HasScreenChanged())
+        {
+            ApplySafeArea();
+        }
+    }
+    
+    /// <summary>
+    /// 妫�娴嬪睆骞曟槸鍚﹀彂鐢熷彉鍖�
+    /// </summary>
+    private bool HasScreenChanged()
+    {
+        Rect safeArea = GetSafeArea();
+        Vector2Int screenSize = new Vector2Int(Screen.width, Screen.height);
+        
+        bool changed = safeArea != _lastSafeArea || screenSize != _lastScreenSize;
+        
+        _lastSafeArea = safeArea;
+        _lastScreenSize = screenSize;
+        
+        return changed;
+    }
+    
+    /// <summary>
+    /// 鑾峰彇瀹夊叏鍖哄煙
+    /// </summary>
+    private Rect GetSafeArea()
+    {
+        #if UNITY_EDITOR
+        if (simulateInEditor)
+        {
+            // 缂栬緫鍣ㄦā寮忎笅妯℃嫙 iPhone X 鐨勫畨鍏ㄥ尯鍩�
+            float screenWidth = Screen.width;
+            float screenHeight = Screen.height;
+            
+            // 妯℃嫙鍒樻捣锛堥《閮� 44px锛夊拰搴曢儴鎵嬪娍鏉★紙搴曢儴 34px锛�
+            float topInset = 44f;
+            float bottomInset = 34f;
+            float leftInset = 0f;
+            float rightInset = 0f;
+            
+            return new Rect(
+                leftInset,
+                bottomInset,
+                screenWidth - leftInset - rightInset,
+                screenHeight - topInset - bottomInset
+            );
+        }
+        #endif
+        
+        return Screen.safeArea;
+    }
+    
+    /// <summary>
+    /// 搴旂敤瀹夊叏鍖哄煙閫傞厤
+    /// </summary>
+    private void ApplySafeArea()
+    {
+        if (_rectTransform == null)
+            return;
+        
+        Rect safeArea = GetSafeArea();
+        currentSafeArea = safeArea;
+        screenSize = new Vector2Int(Screen.width, Screen.height);
+        
+        // 璁$畻閿氱偣浣嶇疆
+        Vector2 anchorMin = safeArea.position;
+        Vector2 anchorMax = safeArea.position + safeArea.size;
+        
+        // 杞崲涓烘爣鍑嗗寲鍧愭爣 (0-1)
+        anchorMin.x /= Screen.width;
+        anchorMin.y /= Screen.height;
+        anchorMax.x /= Screen.width;
+        anchorMax.y /= Screen.height;
+        
+        // 鏍规嵁璁剧疆鍐冲畾鏄惁閫傞厤鍚勪釜杈圭紭
+        Vector2 finalAnchorMin = _rectTransform.anchorMin;
+        Vector2 finalAnchorMax = _rectTransform.anchorMax;
+        
+        if (adaptLeft)
+            finalAnchorMin.x = anchorMin.x;
+        
+        if (adaptBottom)
+            finalAnchorMin.y = anchorMin.y;
+        
+        if (adaptRight)
+            finalAnchorMax.x = anchorMax.x;
+        
+        if (adaptTop)
+            finalAnchorMax.y = anchorMax.y;
+        
+        _rectTransform.anchorMin = finalAnchorMin;
+        _rectTransform.anchorMax = finalAnchorMax;
+        
+        // 閲嶇疆鍋忕Щ
+        _rectTransform.offsetMin = Vector2.zero;
+        _rectTransform.offsetMax = Vector2.zero;
+        
+        Debug.Log($"[SafeAreaAdapter] 瀹夊叏鍖哄煙宸插簲鐢�: {safeArea}, 灞忓箷: {screenSize}");
+    }
+    
+    /// <summary>
+    /// 寮哄埗閲嶆柊搴旂敤瀹夊叏鍖哄煙
+    /// </summary>
+    public void ForceApply()
+    {
+        ApplySafeArea();
+    }
+    
+    #if UNITY_EDITOR
+    private void OnValidate()
+    {
+        if (_rectTransform == null)
+            _rectTransform = GetComponent<RectTransform>();
+        
+        ApplySafeArea();
+    }
+    #endif
+}
diff --git a/Main/Core/Platform/SafeAreaAdapter.cs.meta b/Main/Core/Platform/SafeAreaAdapter.cs.meta
new file mode 100644
index 0000000..5139333
--- /dev/null
+++ b/Main/Core/Platform/SafeAreaAdapter.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: d199b151833c2084c8b240e09d6eab7f
+MonoImporter:
+  externalObjects: {}
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 
diff --git a/Main/Core/Platform/StandalonePlatform.cs b/Main/Core/Platform/StandalonePlatform.cs
new file mode 100644
index 0000000..f8ba565
--- /dev/null
+++ b/Main/Core/Platform/StandalonePlatform.cs
@@ -0,0 +1,114 @@
+using System;
+using Cysharp.Threading.Tasks;
+using UnityEngine;
+
+/// <summary>
+/// 缂栬緫鍣ㄦ祴璇曞钩鍙板疄鐜帮紙妯℃嫙骞冲彴琛屼负锛�
+/// </summary>
+public class StandalonePlatform : IPlatformService
+{
+        private SystemInfo _cachedSystemInfo;
+        
+        public async UniTask<bool> InitAsync()
+        {
+            Debug.Log("[StandalonePlatform] 鍒濆鍖栫紪杈戝櫒娴嬭瘯骞冲彴");
+            await UniTask.Delay(100); // 妯℃嫙鍒濆鍖栧欢杩�
+            _cachedSystemInfo = CreateMockSystemInfo();
+            return true;
+        }
+        
+        public PlatformType GetPlatformType()
+        {
+            return PlatformType.Standalone;
+        }
+        
+        public async UniTask<LoginResult> LoginAsync()
+        {
+            Debug.Log("[StandalonePlatform] 妯℃嫙鐧诲綍鎴愬姛");
+            await UniTask.Delay(500); // 妯℃嫙缃戠粶寤惰繜
+            
+            return new LoginResult
+            {
+                Success = true,
+                UserId = "test_user_12345",
+                Nickname = "娴嬭瘯鐢ㄦ埛",
+                AvatarUrl = "https://example.com/avatar.jpg",
+                ErrorMessage = null
+            };
+        }
+        
+        public async UniTask<bool> ShareAsync(ShareData shareData)
+        {
+            Debug.Log($"[StandalonePlatform] 妯℃嫙鍒嗕韩: {shareData.Title}");
+            await UniTask.Delay(300);
+            return true;
+        }
+        
+        public async UniTask<AdResult> ShowAdAsync(AdType adType)
+        {
+            Debug.Log($"[StandalonePlatform] 妯℃嫙鏄剧ず骞垮憡: {adType}");
+            await UniTask.Delay(2000); // 妯℃嫙骞垮憡鎾斁鏃堕棿
+            
+            return new AdResult
+            {
+                Success = true,
+                Completed = true, // 妯℃嫙鐢ㄦ埛鐪嬪畬骞垮憡
+                ErrorMessage = null
+            };
+        }
+        
+        public async UniTask<bool> SaveDataAsync(string key, string value)
+        {
+            Debug.Log($"[StandalonePlatform] 淇濆瓨鏁版嵁: {key} = {value}");
+            await UniTask.Delay(50);
+            PlayerPrefs.SetString(key, value);
+            PlayerPrefs.Save();
+            return true;
+        }
+        
+        public async UniTask<string> LoadDataAsync(string key)
+        {
+            Debug.Log($"[StandalonePlatform] 鍔犺浇鏁版嵁: {key}");
+            await UniTask.Delay(50);
+            return PlayerPrefs.GetString(key, null);
+        }
+        
+        public async UniTask<string> DownloadFileAsync(string url, string localPath, Action<float> onProgress = null)
+        {
+            Debug.Log($"[StandalonePlatform] 妯℃嫙涓嬭浇鏂囦欢: {url} -> {localPath}");
+            
+            // 妯℃嫙涓嬭浇杩涘害
+            for (int i = 0; i <= 10; i++)
+            {
+                await UniTask.Delay(100);
+                onProgress?.Invoke(i / 10f);
+            }
+            
+            return localPath;
+        }
+        
+        public SystemInfo GetSystemInfo()
+        {
+            return _cachedSystemInfo ?? (_cachedSystemInfo = CreateMockSystemInfo());
+        }
+        
+        public void Vibrate(VibrationType vibrationType)
+        {
+            Debug.Log($"[StandalonePlatform] 妯℃嫙闇囧姩: {vibrationType}");
+            // 缂栬緫鍣ㄤ腑鏃犳硶瀹為檯闇囧姩
+        }
+        
+        private SystemInfo CreateMockSystemInfo()
+        {
+            return new SystemInfo
+            {
+                DeviceModel = UnityEngine.SystemInfo.deviceModel,
+                SystemVersion = UnityEngine.SystemInfo.operatingSystem,
+                PlatformVersion = "Standalone 1.0.0",
+                ScreenWidth = Screen.width,
+                ScreenHeight = Screen.height,
+                SafeArea = SafeAreaData.FromRect(Screen.safeArea),
+                PixelRatio = Screen.dpi / 160f
+            };
+        }
+    }
diff --git a/Main/Core/Platform/StandalonePlatform.cs.meta b/Main/Core/Platform/StandalonePlatform.cs.meta
new file mode 100644
index 0000000..1683c51
--- /dev/null
+++ b/Main/Core/Platform/StandalonePlatform.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 486271bbe3382a240a8ee78f5a2ad64f
+MonoImporter:
+  externalObjects: {}
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 
diff --git a/Main/Core/Platform/VivoPlatform.cs b/Main/Core/Platform/VivoPlatform.cs
new file mode 100644
index 0000000..d44640b
--- /dev/null
+++ b/Main/Core/Platform/VivoPlatform.cs
@@ -0,0 +1,193 @@
+using System;
+using System.Runtime.InteropServices;
+using Cysharp.Threading.Tasks;
+using UnityEngine;
+
+/// <summary>
+/// vivo灏忔父鎴忓钩鍙板疄鐜�
+/// </summary>
+public class VivoPlatform : IPlatformService
+{
+    #if UNITY_WEBGL && !UNITY_EDITOR
+    // JavaScript 鎻掍欢鏂规硶澹版槑
+    [DllImport("__Internal")]
+    private static extern bool QG_Init();
+    
+    [DllImport("__Internal")]
+    private static extern void QG_Login(string callbackObjectName, string callbackMethodName);
+    
+    [DllImport("__Internal")]
+    private static extern string QG_GetSystemInfo();
+    
+    [DllImport("__Internal")]
+    private static extern void QG_Share(string title, string imageUrl);
+    
+    [DllImport("__Internal")]
+    private static extern void QG_CreateRewardedVideoAd(string adUnitId, string callbackObjectName, string callbackMethodName);
+    
+    [DllImport("__Internal")]
+    private static extern void QG_SetStorageSync(string key, string value);
+    
+    [DllImport("__Internal")]
+    private static extern string QG_GetStorageSync(string key);
+    
+    [DllImport("__Internal")]
+    private static extern void QG_VibrateShort();
+    
+    [DllImport("__Internal")]
+    private static extern void QG_VibrateLong();
+    #endif
+    
+    private SystemInfo _cachedSystemInfo;
+    private bool _isInitialized = false;
+    
+    public async UniTask<bool> InitAsync()
+    {
+        Debug.Log("[VivoPlatform] 鍒濆鍖杤ivo灏忔父鎴忓钩鍙�");
+        
+        #if UNITY_WEBGL && !UNITY_EDITOR
+        try
+        {
+            _isInitialized = QG_Init();
+            if (_isInitialized)
+            {
+                _cachedSystemInfo = GetSystemInfo();
+                Debug.Log("[VivoPlatform] 鍒濆鍖栨垚鍔�");
+            }
+            return _isInitialized;
+        }
+        catch (Exception e)
+        {
+            Debug.LogError($"[VivoPlatform] 鍒濆鍖栧け璐�: {e.Message}");
+            return false;
+        }
+        #else
+        await UniTask.Delay(100);
+        _isInitialized = true;
+        _cachedSystemInfo = CreateMockSystemInfo();
+        return true;
+        #endif
+    }
+    
+    public PlatformType GetPlatformType()
+    {
+        return PlatformType.Vivo;
+    }
+    
+    public async UniTask<LoginResult> LoginAsync()
+    {
+        Debug.Log("[VivoPlatform] 寮�濮嬬櫥褰�");
+        
+        #if UNITY_WEBGL && !UNITY_EDITOR
+        // TODO: 瀹炵幇vivo鐧诲綍閫昏緫
+        await UniTask.Delay(500);
+        return new LoginResult { Success = true, UserId = "vivo_user" };
+        #else
+        await UniTask.Delay(500);
+        return new LoginResult { Success = true, UserId = "vivo_test_user" };
+        #endif
+    }
+    
+    public async UniTask<bool> ShareAsync(ShareData shareData)
+    {
+        Debug.Log($"[VivoPlatform] 鍒嗕韩: {shareData.Title}");
+        
+        #if UNITY_WEBGL && !UNITY_EDITOR
+        QG_Share(shareData.Title, shareData.ImageUrl);
+        #endif
+        
+        await UniTask.Delay(300);
+        return true;
+    }
+    
+    public async UniTask<AdResult> ShowAdAsync(AdType adType)
+    {
+        Debug.Log($"[VivoPlatform] 鏄剧ず骞垮憡: {adType}");
+        
+        #if UNITY_WEBGL && !UNITY_EDITOR
+        // TODO: 瀹炵幇vivo骞垮憡閫昏緫
+        #endif
+        
+        await UniTask.Delay(1000);
+        return new AdResult { Success = true, Completed = true };
+    }
+    
+    public async UniTask<bool> SaveDataAsync(string key, string value)
+    {
+        #if UNITY_WEBGL && !UNITY_EDITOR
+        QG_SetStorageSync(key, value);
+        #endif
+        await UniTask.Yield();
+        return true;
+    }
+    
+    public async UniTask<string> LoadDataAsync(string key)
+    {
+        #if UNITY_WEBGL && !UNITY_EDITOR
+        string value = QG_GetStorageSync(key);
+        await UniTask.Yield();
+        return value;
+        #else
+        await UniTask.Yield();
+        return null;
+        #endif
+    }
+    
+    public async UniTask<string> DownloadFileAsync(string url, string localPath, Action<float> onProgress = null)
+    {
+        Debug.Log($"[VivoPlatform] 涓嬭浇鏂囦欢: {url}");
+        await UniTask.Delay(500);
+        return localPath;
+    }
+    
+    public SystemInfo GetSystemInfo()
+    {
+        if (_cachedSystemInfo != null)
+            return _cachedSystemInfo;
+        
+        #if UNITY_WEBGL && !UNITY_EDITOR
+        try
+        {
+            string jsonInfo = QG_GetSystemInfo();
+            _cachedSystemInfo = JsonUtility.FromJson<SystemInfo>(jsonInfo);
+            return _cachedSystemInfo;
+        }
+        catch (Exception e)
+        {
+            Debug.LogError($"[VivoPlatform] 鑾峰彇绯荤粺淇℃伅澶辫触: {e.Message}");
+            return CreateMockSystemInfo();
+        }
+        #else
+        return CreateMockSystemInfo();
+        #endif
+    }
+    
+    public void Vibrate(VibrationType vibrationType)
+    {
+        #if UNITY_WEBGL && !UNITY_EDITOR
+        switch (vibrationType)
+        {
+            case VibrationType.Light:
+            case VibrationType.Medium:
+                QG_VibrateShort();
+                break;
+            case VibrationType.Heavy:
+                QG_VibrateLong();
+                break;
+        }
+        #endif
+    }
+    
+    private SystemInfo CreateMockSystemInfo()
+    {
+        return new SystemInfo
+        {
+            DeviceModel = UnityEngine.SystemInfo.deviceModel,
+            PlatformVersion = "Vivo 1.0.0",
+            ScreenWidth = Screen.width,
+            ScreenHeight = Screen.height,
+            SafeArea = SafeAreaData.FromRect(Screen.safeArea),
+            PixelRatio = Screen.dpi / 160f
+        };
+    }
+}
diff --git a/Main/Core/Platform/VivoPlatform.cs.meta b/Main/Core/Platform/VivoPlatform.cs.meta
new file mode 100644
index 0000000..a3b4b4c
--- /dev/null
+++ b/Main/Core/Platform/VivoPlatform.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 72d9b476010653d42ac0315d07acf865
+MonoImporter:
+  externalObjects: {}
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 
diff --git a/Main/Core/Platform/WeChatPlatform.cs b/Main/Core/Platform/WeChatPlatform.cs
new file mode 100644
index 0000000..92d2e5b
--- /dev/null
+++ b/Main/Core/Platform/WeChatPlatform.cs
@@ -0,0 +1,256 @@
+using System;
+using System.Runtime.InteropServices;
+using Cysharp.Threading.Tasks;
+using UnityEngine;
+
+/// <summary>
+/// 寰俊灏忔父鎴忓钩鍙板疄鐜�
+/// </summary>
+public class WeChatPlatform : IPlatformService
+{
+        #if UNITY_WEBGL && !UNITY_EDITOR
+        // JavaScript 鎻掍欢鏂规硶澹版槑
+        [DllImport("__Internal")]
+        private static extern void WX_Init();
+        
+        [DllImport("__Internal")]
+        private static extern void WX_Login(string callbackObjectName, string callbackMethodName);
+        
+        [DllImport("__Internal")]
+        private static extern void WX_GetSystemInfo(string callbackObjectName, string callbackMethodName);
+        
+        [DllImport("__Internal")]
+        private static extern void WX_ShareAppMessage(string title, string imageUrl);
+        
+        [DllImport("__Internal")]
+        private static extern void WX_CreateRewardedVideoAd(string adUnitId, string callbackObjectName, string callbackMethodName);
+        
+        [DllImport("__Internal")]
+        private static extern void WX_SetStorageSync(string key, string value);
+        
+        [DllImport("__Internal")]
+        private static extern string WX_GetStorageSync(string key);
+        
+        [DllImport("__Internal")]
+        private static extern void WX_VibrateShort();
+        
+        [DllImport("__Internal")]
+        private static extern void WX_VibrateLong();
+        #endif
+        
+        private SystemInfo _cachedSystemInfo;
+        private bool _isInitialized = false;
+        
+        public async UniTask<bool> InitAsync()
+        {
+            Debug.Log("[WeChatPlatform] 鍒濆鍖栧井淇″皬娓告垙骞冲彴");
+            
+            #if UNITY_WEBGL && !UNITY_EDITOR
+            try
+            {
+                WX_Init();
+                _isInitialized = true;
+                Debug.Log("[WeChatPlatform] 寰俊SDK鍒濆鍖栨垚鍔�");
+            }
+            catch (Exception e)
+            {
+                Debug.LogError($"[WeChatPlatform] 寰俊SDK鍒濆鍖栧け璐�: {e.Message}");
+                return false;
+            }
+            #else
+            Debug.LogWarning("[WeChatPlatform] 闈濿ebGL骞冲彴锛屼娇鐢ㄦā鎷熸ā寮�");
+            _isInitialized = true;
+            #endif
+            
+            await UniTask.Delay(100);
+            return true;
+        }
+        
+        public PlatformType GetPlatformType()
+        {
+            return PlatformType.WeChat;
+        }
+        
+        public async UniTask<LoginResult> LoginAsync()
+        {
+            Debug.Log("[WeChatPlatform] 寰俊鐧诲綍");
+            
+            #if UNITY_WEBGL && !UNITY_EDITOR
+            // TODO: 瀹炵幇鍥炶皟鏈哄埗
+            // WX_Login("WeChatPlatform", "OnLoginCallback");
+            await UniTask.Delay(1000); // 绛夊緟鍥炶皟
+            #else
+            await UniTask.Delay(500);
+            #endif
+            
+            // 妯℃嫙鐧诲綍鎴愬姛锛堝疄闄呴渶瑕侀�氳繃鍥炶皟鑾峰彇锛�
+            return new LoginResult
+            {
+                Success = true,
+                UserId = "wx_user_mock",
+                Nickname = "寰俊鐢ㄦ埛",
+                AvatarUrl = "https://example.com/avatar.jpg",
+                ErrorMessage = null
+            };
+        }
+        
+        public async UniTask<bool> ShareAsync(ShareData shareData)
+        {
+            Debug.Log($"[WeChatPlatform] 鍒嗕韩鍒板井淇�: {shareData.Title}");
+            
+            #if UNITY_WEBGL && !UNITY_EDITOR
+            try
+            {
+                WX_ShareAppMessage(shareData.Title, shareData.ImageUrl);
+                await UniTask.Delay(300);
+                return true;
+            }
+            catch (Exception e)
+            {
+                Debug.LogError($"[WeChatPlatform] 鍒嗕韩澶辫触: {e.Message}");
+                return false;
+            }
+            #else
+            await UniTask.Delay(300);
+            return true;
+            #endif
+        }
+        
+        public async UniTask<AdResult> ShowAdAsync(AdType adType)
+        {
+            Debug.Log($"[WeChatPlatform] 鏄剧ず寰俊骞垮憡: {adType}");
+            
+            #if UNITY_WEBGL && !UNITY_EDITOR
+            // TODO: 瀹炵幇骞垮憡鍥炶皟
+            string adUnitId = GetAdUnitId(adType);
+            // WX_CreateRewardedVideoAd(adUnitId, "WeChatPlatform", "OnAdCallback");
+            await UniTask.Delay(3000);
+            #else
+            await UniTask.Delay(2000);
+            #endif
+            
+            return new AdResult
+            {
+                Success = true,
+                Completed = true,
+                ErrorMessage = null
+            };
+        }
+        
+        public async UniTask<bool> SaveDataAsync(string key, string value)
+        {
+            Debug.Log($"[WeChatPlatform] 淇濆瓨鏁版嵁鍒板井淇″瓨鍌�: {key}");
+            
+            #if UNITY_WEBGL && !UNITY_EDITOR
+            try
+            {
+                WX_SetStorageSync(key, value);
+                await UniTask.Delay(50);
+                return true;
+            }
+            catch (Exception e)
+            {
+                Debug.LogError($"[WeChatPlatform] 淇濆瓨鏁版嵁澶辫触: {e.Message}");
+                return false;
+            }
+            #else
+            await UniTask.Delay(50);
+            PlayerPrefs.SetString(key, value);
+            PlayerPrefs.Save();
+            return true;
+            #endif
+        }
+        
+        public async UniTask<string> LoadDataAsync(string key)
+        {
+            Debug.Log($"[WeChatPlatform] 浠庡井淇″瓨鍌ㄥ姞杞芥暟鎹�: {key}");
+            
+            #if UNITY_WEBGL && !UNITY_EDITOR
+            try
+            {
+                await UniTask.Delay(50);
+                return WX_GetStorageSync(key);
+            }
+            catch (Exception e)
+            {
+                Debug.LogError($"[WeChatPlatform] 鍔犺浇鏁版嵁澶辫触: {e.Message}");
+                return null;
+            }
+            #else
+            await UniTask.Delay(50);
+            return PlayerPrefs.GetString(key, null);
+            #endif
+        }
+        
+        public async UniTask<string> DownloadFileAsync(string url, string localPath, Action<float> onProgress = null)
+        {
+            Debug.Log($"[WeChatPlatform] 涓嬭浇鏂囦欢: {url}");
+            
+            // TODO: 瀹炵幇寰俊鏂囦欢涓嬭浇API
+            // wx.downloadFile({ url, success, fail })
+            
+            // 妯℃嫙涓嬭浇
+            for (int i = 0; i <= 10; i++)
+            {
+                await UniTask.Delay(100);
+                onProgress?.Invoke(i / 10f);
+            }
+            
+            return localPath;
+        }
+        
+        public SystemInfo GetSystemInfo()
+        {
+            if (_cachedSystemInfo == null)
+            {
+                #if UNITY_WEBGL && !UNITY_EDITOR
+                // TODO: 浠庡井淇PI鑾峰彇绯荤粺淇℃伅
+                // WX_GetSystemInfo("WeChatPlatform", "OnSystemInfoCallback");
+                #endif
+                
+                _cachedSystemInfo = new SystemInfo
+                {
+                    DeviceModel = UnityEngine.SystemInfo.deviceModel,
+                    SystemVersion = UnityEngine.SystemInfo.operatingSystem,
+                    PlatformVersion = "WeChat 8.0.0",
+                    ScreenWidth = Screen.width,
+                    ScreenHeight = Screen.height,
+                    SafeArea = SafeAreaData.FromRect(Screen.safeArea),
+                    PixelRatio = Screen.dpi / 160f
+                };
+            }
+            
+            return _cachedSystemInfo;
+        }
+        
+        public void Vibrate(VibrationType vibrationType)
+        {
+            Debug.Log($"[WeChatPlatform] 闇囧姩: {vibrationType}");
+            
+            #if UNITY_WEBGL && !UNITY_EDITOR
+            try
+            {
+                if (vibrationType == VibrationType.Heavy)
+                    WX_VibrateLong();
+                else
+                    WX_VibrateShort();
+            }
+            catch (Exception e)
+            {
+                Debug.LogError($"[WeChatPlatform] 闇囧姩澶辫触: {e.Message}");
+            }
+            #endif
+        }
+        
+        private string GetAdUnitId(AdType adType)
+        {
+            // TODO: 浠庨厤缃枃浠惰鍙栧箍鍛婁綅ID
+            return adType switch
+            {
+                AdType.Video => "adunit-xxxxxx",
+                AdType.Banner => "adunit-yyyyyy",
+                AdType.Interstitial => "adunit-zzzzzz",
+                _ => ""
+            };
+        }
+    }
diff --git a/Main/Core/Platform/WeChatPlatform.cs.meta b/Main/Core/Platform/WeChatPlatform.cs.meta
new file mode 100644
index 0000000..22c898e
--- /dev/null
+++ b/Main/Core/Platform/WeChatPlatform.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 89e47741ded740c48893b331d65d26a4
+MonoImporter:
+  externalObjects: {}
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 
diff --git a/Main/Main.asmdef b/Main/Main.asmdef
index 2832f27..21be3cf 100644
--- a/Main/Main.asmdef
+++ b/Main/Main.asmdef
@@ -10,7 +10,8 @@
         "GUID:72d1fea872bd7a449bf3818f2b0a6708",
         "GUID:05d41852e29aa5141a64e3d2d5339981",
         "GUID:9ad05b610be6c974590152128a8b5b6e",
-        "GUID:d51b17ee17bf72443860693b4f9c20af"
+        "GUID:d51b17ee17bf72443860693b4f9c20af",
+        "GUID:04376767bc1f3b428aefa3d20743e819"
     ],
     "includePlatforms": [],
     "excludePlatforms": [],
diff --git a/Main/Main.cs b/Main/Main.cs
index 35335b9..cf517e3 100644
--- a/Main/Main.cs
+++ b/Main/Main.cs
@@ -7,10 +7,20 @@
 using System.IO;
 
 /// <summary>
+/// 缃戠粶绫诲瀷鏋氫妇
+/// </summary>
+
+
+/// <summary>
 /// Main绫伙紝浣滀负鐑洿鏂扮▼搴忛泦鐨勫叆鍙g偣
 /// </summary>
 public class Main
 {
+    /// <summary>
+    /// 缃戠粶绫诲瀷閰嶇疆锛堝彲鍦ㄤ唬鐮佷腑淇敼鎴栭�氳繃 Inspector 閰嶇疆锛�
+    /// </summary>
+    public static NetworkType CurrentNetworkType = NetworkType.TCP;
+
     public static List<IGameSystemManager> managers = new List<IGameSystemManager>();
 
     /// <summary>
diff --git a/Main/Utility/DeviceUtility.cs b/Main/Utility/DeviceUtility.cs
index 518f4d6..3d50384 100644
--- a/Main/Utility/DeviceUtility.cs
+++ b/Main/Utility/DeviceUtility.cs
@@ -78,7 +78,9 @@
 #if UNITY_IOS
         return UnityEngine.iOS.Device.advertisingIdentifier;
 #else
-        return SystemInfo.deviceUniqueIdentifier;
+        // SystemInfo.deviceUniqueIdentifier is deprecated in Unity 2022+
+        // Use platform-specific solutions or GUID
+        return System.Guid.NewGuid().ToString();
 #endif
     }
 
@@ -87,7 +89,7 @@
 #if UNITY_IOS
         return UnityEngine.iOS.Device.systemVersion;
 #else
-        return SystemInfo.operatingSystem;
+        return Application.platform.ToString();
 #endif
     }
 
@@ -96,7 +98,7 @@
 #if UNITY_IOS
         return UnityEngine.iOS.Device.generation.ToString();
 #else
-        return SystemInfo.deviceName;
+        return Application.productName;
 #endif
     }
 
@@ -105,7 +107,7 @@
 #if UNITY_IOS
         return UnityEngine.iOS.Device.generation.ToString();
 #else
-        return SystemInfo.deviceModel;
+        return Application.platform.ToString();
 #endif
     }
 

--
Gitblit v1.8.0