minigame-tuanjie-transform-sdk/Runtime/WXPCHPInitScript.cs

973 lines
34 KiB
C#
Raw Normal View History

2026-03-25 11:24:23 +08:00
using System;
using System.Collections.Generic;
using System.Collections.Concurrent;
using System.Runtime.InteropServices;
using UnityEngine;
using LitJson;
namespace WeChatWASM
{
#region Message Protocol Models
/// <summary>
/// PC高性能方案通信协议 - 请求消息
/// C# -> DLL -> 内核 -> 基础库
/// </summary>
[Serializable]
public class PCHPRequestMessage
{
/// <summary>
/// 消息类型: "request" | "event_register" | "event_unregister"
/// </summary>
public string type;
/// <summary>
/// 请求ID用于匹配回调
/// </summary>
public string requestId;
/// <summary>
/// API名称如 "showToast", "login" 等
/// </summary>
public string api;
/// <summary>
/// API参数JSON格式
/// </summary>
public string data;
/// <summary>
/// 时间戳
/// </summary>
public long timestamp;
}
/// <summary>
/// PC高性能方案通信协议 - 响应消息
/// 基础库 -> 内核 -> DLL -> C#
/// </summary>
[Serializable]
public class PCHPResponseMessage
{
/// <summary>
/// 消息类型: "response" | "event"
/// </summary>
public string type;
/// <summary>
/// 请求ID与请求消息匹配
/// </summary>
public string requestId;
/// <summary>
/// 回调类型: "success" | "fail" | "complete"
/// </summary>
public string callbackType;
/// <summary>
/// API名称事件类型时使用
/// </summary>
public string api;
/// <summary>
/// 响应数据JSON格式
/// </summary>
public string data;
/// <summary>
/// 错误信息(失败时)
/// </summary>
public string errMsg;
/// <summary>
/// 时间戳
/// </summary>
public long timestamp;
}
/// <summary>
/// 通用回调结果
/// </summary>
[Serializable]
public class PCHPGeneralCallbackResult
{
public string errMsg;
}
/// <summary>
/// ShowToast 参数
/// </summary>
[Serializable]
public class PCHPShowToastOption
{
public string title;
public string icon;
public string image;
public int duration;
public bool mask;
}
/// <summary>
/// ShowModal 参数
/// </summary>
[Serializable]
public class PCHPShowModalOption
{
public string title;
public string content;
public bool showCancel;
public string cancelText;
public string cancelColor;
public string confirmText;
public string confirmColor;
public bool editable;
public string placeholderText;
}
/// <summary>
/// ShowModal 成功回调结果
/// </summary>
[Serializable]
public class PCHPShowModalSuccessCallbackResult
{
public bool confirm;
public bool cancel;
public string content;
public string errMsg;
}
#endregion
/// <summary>
/// PC高性能小游戏初始化脚本
/// 负责与宿主程序的 direct_applet_sdk.dll 进行交互
/// </summary>
public class WXPCHPInitScript : MonoBehaviour
{
#region DLL Imports
private const string DLL_NAME = "direct_applet_sdk.dll";
// 初始化SDK
[DllImport(DLL_NAME, CallingConvention = CallingConvention.Cdecl)]
private static extern bool InitEmbeddedGameSDK();
// 注册异步消息处理器
[DllImport(DLL_NAME, CallingConvention = CallingConvention.Cdecl)]
private static extern void RegisterAsyncMsgHandler(AsyncMsgHandlerDelegate handler);
// 建立Mojo连接
[DllImport(DLL_NAME, CallingConvention = CallingConvention.Cdecl)]
private static extern bool EstablishConnection();
// 初始化游戏窗口 - 传入窗口句柄
[DllImport(DLL_NAME, CallingConvention = CallingConvention.Cdecl)]
private static extern bool InitGameWindow(ulong hwnd);
// 异步发送消息
[DllImport(DLL_NAME, CallingConvention = CallingConvention.Cdecl)]
private static extern bool SendMsgAsync(IntPtr data, int len);
// 清理资源
[DllImport(DLL_NAME, CallingConvention = CallingConvention.Cdecl)]
private static extern bool Cleanup();
// 获取当前活动窗口句柄
[DllImport("user32.dll")]
private static extern IntPtr GetActiveWindow();
// Windows MessageBox
[DllImport("user32.dll", CharSet = CharSet.Unicode)]
private static extern int MessageBox(IntPtr hWnd, string text, string caption, uint type);
#endregion
#region Delegate Definition
// 异步消息处理器委托
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
private delegate void AsyncMsgHandlerDelegate(IntPtr data, int len);
// 保持委托引用防止被GC回收
private static AsyncMsgHandlerDelegate asyncMsgHandler;
#endregion
#region Singleton
private static WXPCHPInitScript instance;
public static WXPCHPInitScript Instance => instance;
#endregion
#region Callback Management
/// <summary>
/// 回调信息封装
/// </summary>
private class CallbackInfo
{
public Action<string> OnSuccess;
public Action<string> OnFail;
public Action<string> OnComplete;
public string ApiName;
public long Timestamp;
}
// 待处理的回调字典 <requestId, CallbackInfo>
private readonly Dictionary<string, CallbackInfo> _pendingCallbacks = new Dictionary<string, CallbackInfo>();
// 事件监听器字典 <eventName, List<Action<string>>>
private readonly Dictionary<string, List<Action<string>>> _eventListeners = new Dictionary<string, List<Action<string>>>();
// 请求ID计数器
private int _requestIdCounter = 0;
// 线程安全的消息队列,用于主线程处理
private readonly ConcurrentQueue<PCHPResponseMessage> _messageQueue = new ConcurrentQueue<PCHPResponseMessage>();
#endregion
#region Events
// 收到异步消息时触发的事件(原始字节)
public event Action<byte[]> OnMessageReceived;
#endregion
#region Properties
// SDK是否已初始化
public bool IsInitialized { get; private set; }
// 是否已连接
public bool IsConnected { get; private set; }
// 窗口句柄
public IntPtr WindowHandle { get; private set; }
#endregion
#region Unity Lifecycle
private void Awake()
{
Debug.Log("[WXPCHPInitScript] ========== Awake 被调用 ==========");
Debug.Log($"[WXPCHPInitScript] GameObject 名称: {gameObject.name}");
Debug.Log($"[WXPCHPInitScript] 场景名称: {UnityEngine.SceneManagement.SceneManager.GetActiveScene().name}");
if (instance != null && instance != this)
{
Debug.LogWarning("[WXPCHPInitScript] 检测到重复实例,销毁当前对象");
Destroy(gameObject);
return;
}
instance = this;
DontDestroyOnLoad(gameObject);
Debug.Log("[WXPCHPInitScript] 单例创建成功,已设置 DontDestroyOnLoad");
// 初始化SDK
Initialize();
}
private void Update()
{
// 在主线程中处理消息队列
ProcessMessageQueue();
}
private void OnDestroy()
{
if (instance == this)
{
CleanupSDK();
instance = null;
}
}
private void OnApplicationQuit()
{
CleanupSDK();
}
#endregion
#region Public Methods - SDK Lifecycle
/// <summary>
/// 初始化SDK并建立连接
/// </summary>
public void Initialize()
{
if (IsInitialized)
{
Debug.LogWarning("[WXPCHPInitScript] SDK已经初始化");
return;
}
Debug.Log("[WXPCHPInitScript] ========== 开始初始化 ==========");
Debug.Log($"[WXPCHPInitScript] 当前工作目录: {System.IO.Directory.GetCurrentDirectory()}");
Debug.Log($"[WXPCHPInitScript] DLL 搜索路径: {DLL_NAME}");
ShowStepInfo("SDK 初始化开始", "即将执行 PC 高性能模式 SDK 初始化流程...\n\n共 5 个步骤:\n1. InitEmbeddedGameSDK\n2. RegisterAsyncMsgHandler\n3. EstablishConnection\n4. GetActiveWindow\n5. InitGameWindow");
try
{
// 1. 初始化SDK
Debug.Log("[WXPCHPInitScript] Step 1: 调用 InitEmbeddedGameSDK");
ShowStepInfo("步骤 1/5 - InitEmbeddedGameSDK", "正在初始化嵌入式游戏 SDK...");
if (!InitEmbeddedGameSDK())
{
ShowError("InitEmbeddedGameSDK 返回 false");
return;
}
ShowStepInfo("步骤 1/5 - InitEmbeddedGameSDK ✅", "InitEmbeddedGameSDK 调用成功!");
// 2. 注册消息处理器
Debug.Log("[WXPCHPInitScript] Step 2: 调用 RegisterAsyncMsgHandler");
ShowStepInfo("步骤 2/5 - RegisterAsyncMsgHandler", "正在注册异步消息处理器...");
asyncMsgHandler = HandleAsyncMessage;
RegisterAsyncMsgHandler(asyncMsgHandler);
ShowStepInfo("步骤 2/5 - RegisterAsyncMsgHandler ✅", "异步消息处理器注册成功!");
// 3. 建立连接
Debug.Log("[WXPCHPInitScript] Step 3: 调用 EstablishConnection");
ShowStepInfo("步骤 3/5 - EstablishConnection", "正在建立 Mojo 连接...");
if (!EstablishConnection())
{
ShowError("EstablishConnection 返回 false");
IsConnected = false;
return;
}
IsConnected = true;
ShowStepInfo("步骤 3/5 - EstablishConnection ✅", "Mojo 连接建立成功!");
// 4. 获取窗口句柄并初始化游戏窗口
Debug.Log("[WXPCHPInitScript] Step 4: 获取窗口句柄");
ShowStepInfo("步骤 4/5 - GetActiveWindow", "正在获取游戏窗口句柄...");
WindowHandle = GetActiveWindow();
if (WindowHandle == IntPtr.Zero)
{
ShowError("GetActiveWindow 返回空句柄");
return;
}
Debug.Log($"获取窗口句柄成功: 0x{WindowHandle.ToInt64():X}");
ShowStepInfo("步骤 4/5 - GetActiveWindow ✅", $"窗口句柄获取成功: 0x{WindowHandle.ToInt64():X}");
// 5. 通知内核获取窗口句柄
Debug.Log("[WXPCHPInitScript] Step 5: 调用 InitGameWindow");
ShowStepInfo("步骤 5/5 - InitGameWindow", $"正在初始化游戏窗口...\n窗口句柄: 0x{WindowHandle.ToInt64():X}");
if (!InitGameWindow((ulong)WindowHandle.ToInt64()))
{
ShowError("InitGameWindow 返回 false");
return;
}
ShowStepInfo("步骤 5/5 - InitGameWindow ✅", "游戏窗口初始化成功!");
IsInitialized = true;
Debug.Log("[WXPCHPInitScript] ========== 初始化完成 ==========");
ShowStepInfo("🎉 SDK 初始化完成", "PC 高性能模式 SDK 所有步骤均已成功完成!\n\n✅ InitEmbeddedGameSDK\n✅ RegisterAsyncMsgHandler\n✅ EstablishConnection\n✅ GetActiveWindow\n✅ InitGameWindow");
}
catch (DllNotFoundException e)
{
ShowError($"找不到DLL: {e.Message}\n\n请确保 {DLL_NAME} 在以下位置之一:\n- 与 .exe 同级目录\n- System32 目录\n- PATH 环境变量包含的路径");
Debug.LogError($"[WXPCHPInitScript] DLL 加载失败,请确保 {DLL_NAME} 在以下位置之一:");
Debug.LogError($" - 与 .exe 同级目录");
Debug.LogError($" - System32 目录");
Debug.LogError($" - PATH 环境变量包含的路径");
}
catch (EntryPointNotFoundException e)
{
ShowError($"找不到函数入口: {e.Message}\n\n可能是 DLL 版本不匹配");
Debug.LogError($"[WXPCHPInitScript] 函数入口点错误,可能是 DLL 版本不匹配");
}
catch (Exception e)
{
ShowError($"初始化异常: {e.Message}\n{e.StackTrace}");
Debug.LogError($"[WXPCHPInitScript] 未知异常: {e}");
}
}
#endregion
#region Public Methods - WX API Calls
/// <summary>
/// 调用微信API通用方法
/// </summary>
/// <param name="apiName">API名称如 "showToast"</param>
/// <param name="data">API参数对象</param>
/// <param name="onSuccess">成功回调</param>
/// <param name="onFail">失败回调</param>
/// <param name="onComplete">完成回调</param>
/// <returns>请求ID</returns>
public string CallWXAPI(string apiName, object data, Action<string> onSuccess = null, Action<string> onFail = null, Action<string> onComplete = null)
{
if (!IsInitialized || !IsConnected)
{
Debug.LogWarning($"[WXPCHPInitScript] SDK未初始化或未连接无法调用 {apiName}");
onFail?.Invoke(JsonMapper.ToJson(new PCHPGeneralCallbackResult { errMsg = "SDK not initialized" }));
onComplete?.Invoke(JsonMapper.ToJson(new PCHPGeneralCallbackResult { errMsg = "SDK not initialized" }));
return null;
}
string requestId = GenerateRequestId();
string dataJson = data != null ? JsonMapper.ToJson(data) : "{}";
// 注册回调
var callbackInfo = new CallbackInfo
{
OnSuccess = onSuccess,
OnFail = onFail,
OnComplete = onComplete,
ApiName = apiName,
Timestamp = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds()
};
_pendingCallbacks[requestId] = callbackInfo;
// 构建请求消息
var request = new PCHPRequestMessage
{
type = "request",
requestId = requestId,
api = apiName,
data = dataJson,
timestamp = callbackInfo.Timestamp
};
string requestJson = JsonMapper.ToJson(request);
Debug.Log($"[WXPCHPInitScript] 发送API请求: {apiName}, requestId: {requestId}");
if (!SendMessageInternal(requestJson))
{
_pendingCallbacks.Remove(requestId);
onFail?.Invoke(JsonMapper.ToJson(new PCHPGeneralCallbackResult { errMsg = "Failed to send message" }));
onComplete?.Invoke(JsonMapper.ToJson(new PCHPGeneralCallbackResult { errMsg = "Failed to send message" }));
return null;
}
return requestId;
}
/// <summary>
/// 显示消息提示框
/// </summary>
public void ShowToast(PCHPShowToastOption option, Action<PCHPGeneralCallbackResult> success = null, Action<PCHPGeneralCallbackResult> fail = null, Action<PCHPGeneralCallbackResult> complete = null)
{
CallWXAPI("showToast", option,
res => success?.Invoke(JsonMapper.ToObject<PCHPGeneralCallbackResult>(res)),
res => fail?.Invoke(JsonMapper.ToObject<PCHPGeneralCallbackResult>(res)),
res => complete?.Invoke(JsonMapper.ToObject<PCHPGeneralCallbackResult>(res))
);
}
/// <summary>
/// 隐藏消息提示框
/// </summary>
public void HideToast(Action<PCHPGeneralCallbackResult> success = null, Action<PCHPGeneralCallbackResult> fail = null, Action<PCHPGeneralCallbackResult> complete = null)
{
CallWXAPI("hideToast", null,
res => success?.Invoke(JsonMapper.ToObject<PCHPGeneralCallbackResult>(res)),
res => fail?.Invoke(JsonMapper.ToObject<PCHPGeneralCallbackResult>(res)),
res => complete?.Invoke(JsonMapper.ToObject<PCHPGeneralCallbackResult>(res))
);
}
/// <summary>
/// 显示模态对话框
/// </summary>
public void ShowModal(PCHPShowModalOption option, Action<PCHPShowModalSuccessCallbackResult> success = null, Action<PCHPGeneralCallbackResult> fail = null, Action<PCHPGeneralCallbackResult> complete = null)
{
CallWXAPI("showModal", option,
res => success?.Invoke(JsonMapper.ToObject<PCHPShowModalSuccessCallbackResult>(res)),
res => fail?.Invoke(JsonMapper.ToObject<PCHPGeneralCallbackResult>(res)),
res => complete?.Invoke(JsonMapper.ToObject<PCHPGeneralCallbackResult>(res))
);
}
/// <summary>
/// 显示 loading 提示框
/// </summary>
public void ShowLoading(string title, bool mask = false, Action<PCHPGeneralCallbackResult> success = null, Action<PCHPGeneralCallbackResult> fail = null, Action<PCHPGeneralCallbackResult> complete = null)
{
CallWXAPI("showLoading", new { title, mask },
res => success?.Invoke(JsonMapper.ToObject<PCHPGeneralCallbackResult>(res)),
res => fail?.Invoke(JsonMapper.ToObject<PCHPGeneralCallbackResult>(res)),
res => complete?.Invoke(JsonMapper.ToObject<PCHPGeneralCallbackResult>(res))
);
}
/// <summary>
/// 隐藏 loading 提示框
/// </summary>
public void HideLoading(Action<PCHPGeneralCallbackResult> success = null, Action<PCHPGeneralCallbackResult> fail = null, Action<PCHPGeneralCallbackResult> complete = null)
{
CallWXAPI("hideLoading", null,
res => success?.Invoke(JsonMapper.ToObject<PCHPGeneralCallbackResult>(res)),
res => fail?.Invoke(JsonMapper.ToObject<PCHPGeneralCallbackResult>(res)),
res => complete?.Invoke(JsonMapper.ToObject<PCHPGeneralCallbackResult>(res))
);
}
#endregion
#region Public Methods - Event Listeners
/// <summary>
/// 注册事件监听器
/// </summary>
/// <param name="eventName">事件名称,如 "onShow", "onHide"</param>
/// <param name="callback">回调函数</param>
public void RegisterEventListener(string eventName, Action<string> callback)
{
if (!_eventListeners.ContainsKey(eventName))
{
_eventListeners[eventName] = new List<Action<string>>();
// 发送事件注册消息到基础库
var request = new PCHPRequestMessage
{
type = "event_register",
requestId = GenerateRequestId(),
api = eventName,
data = "{}",
timestamp = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds()
};
SendMessageInternal(JsonMapper.ToJson(request));
}
_eventListeners[eventName].Add(callback);
Debug.Log($"[WXPCHPInitScript] 注册事件监听: {eventName}");
}
/// <summary>
/// 移除事件监听器
/// </summary>
/// <param name="eventName">事件名称</param>
/// <param name="callback">要移除的回调函数为null则移除所有</param>
public void UnregisterEventListener(string eventName, Action<string> callback = null)
{
if (!_eventListeners.ContainsKey(eventName))
{
return;
}
if (callback == null)
{
_eventListeners.Remove(eventName);
}
else
{
_eventListeners[eventName].Remove(callback);
if (_eventListeners[eventName].Count == 0)
{
_eventListeners.Remove(eventName);
}
}
// 如果没有监听器了,通知基础库取消注册
if (!_eventListeners.ContainsKey(eventName))
{
var request = new PCHPRequestMessage
{
type = "event_unregister",
requestId = GenerateRequestId(),
api = eventName,
data = "{}",
timestamp = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds()
};
SendMessageInternal(JsonMapper.ToJson(request));
}
Debug.Log($"[WXPCHPInitScript] 移除事件监听: {eventName}");
}
#endregion
#region Public Methods - Raw Message
/// <summary>
/// 发送原始消息字符串
/// </summary>
/// <param name="message">消息内容</param>
/// <returns>是否发送成功</returns>
public bool SendRawMessage(string message)
{
return SendMessageInternal(message);
}
/// <summary>
/// 发送原始消息字节数组
/// </summary>
/// <param name="data">消息数据</param>
/// <returns>是否发送成功</returns>
public bool SendMessage(byte[] data)
{
if (!IsInitialized || !IsConnected)
{
Debug.LogWarning("[WXPCHPInitScript] SDK未初始化或未连接");
return false;
}
if (data == null || data.Length == 0)
{
Debug.LogWarning("[WXPCHPInitScript] 发送的数据为空");
return false;
}
try
{
IntPtr ptr = Marshal.AllocHGlobal(data.Length);
try
{
Marshal.Copy(data, 0, ptr, data.Length);
return SendMsgAsync(ptr, data.Length);
}
finally
{
Marshal.FreeHGlobal(ptr);
}
}
catch (Exception e)
{
Debug.LogError($"[WXPCHPInitScript] 发送消息异常: {e.Message}");
return false;
}
}
#endregion
#region Private Methods
/// <summary>
/// 生成唯一请求ID
/// </summary>
private string GenerateRequestId()
{
return $"pchp_{++_requestIdCounter}_{DateTimeOffset.UtcNow.ToUnixTimeMilliseconds()}";
}
/// <summary>
/// 内部发送消息方法
/// </summary>
private bool SendMessageInternal(string message)
{
if (!IsInitialized || !IsConnected)
{
Debug.LogWarning("[WXPCHPInitScript] SDK未初始化或未连接");
return false;
}
try
{
byte[] data = System.Text.Encoding.UTF8.GetBytes(message);
return SendMessage(data);
}
catch (Exception e)
{
Debug.LogError($"[WXPCHPInitScript] 发送消息异常: {e.Message}");
return false;
}
}
/// <summary>
/// 显示步骤信息弹窗Windows 使用 MessageBox其他平台使用 Debug.Log
/// </summary>
private void ShowStepInfo(string title, string message)
{
Debug.Log($"[WXPCHPInitScript] [{title}] {message}");
#if UNITY_STANDALONE_WIN
try
{
// MB_OK | MB_ICONINFORMATION = 0x40
MessageBox(IntPtr.Zero, message, $"PC高性能模式 - {title}", 0x40);
}
catch (System.Exception e)
{
Debug.LogWarning($"[WXPCHPInitScript] MessageBox 调用失败: {e.Message}");
}
#endif
}
/// <summary>
/// 显示错误弹窗(仅 Windows
/// </summary>
private void ShowError(string message)
{
Debug.LogError($"[WXPCHPInitScript] {message}");
#if UNITY_STANDALONE_WIN
try
{
// MB_OK | MB_ICONERROR = 0x10
MessageBox(IntPtr.Zero, message, "WXPCHPInitScript Error", 0x10);
}
catch (System.Exception e)
{
Debug.LogWarning($"[WXPCHPInitScript] MessageBox 调用失败: {e.Message}");
}
#endif
}
/// <summary>
/// 清理SDK资源
/// </summary>
private void CleanupSDK()
{
if (!IsInitialized)
{
return;
}
try
{
// 清理待处理回调
_pendingCallbacks.Clear();
_eventListeners.Clear();
Cleanup();
Debug.Log("[WXPCHPInitScript] SDK清理完成");
}
catch (Exception e)
{
Debug.LogError($"[WXPCHPInitScript] 清理异常: {e.Message}");
}
finally
{
IsInitialized = false;
IsConnected = false;
}
}
/// <summary>
/// 在主线程中处理消息队列
/// </summary>
private void ProcessMessageQueue()
{
while (_messageQueue.TryDequeue(out var response))
{
try
{
ProcessResponse(response);
}
catch (Exception e)
{
Debug.LogError($"[WXPCHPInitScript] 处理响应消息异常: {e.Message}");
}
}
}
/// <summary>
/// 处理响应消息
/// </summary>
private void ProcessResponse(PCHPResponseMessage response)
{
if (response.type == "response")
{
// 处理API回调
if (_pendingCallbacks.TryGetValue(response.requestId, out var callbackInfo))
{
Debug.Log($"[WXPCHPInitScript] 收到API响应: {callbackInfo.ApiName}, callbackType: {response.callbackType}");
switch (response.callbackType)
{
case "success":
callbackInfo.OnSuccess?.Invoke(response.data ?? "{}");
break;
case "fail":
callbackInfo.OnFail?.Invoke(response.data ?? $"{{\"errMsg\":\"{response.errMsg}\"}}");
break;
case "complete":
callbackInfo.OnComplete?.Invoke(response.data ?? "{}");
// complete 后移除回调
_pendingCallbacks.Remove(response.requestId);
break;
}
}
else
{
Debug.LogWarning($"[WXPCHPInitScript] 未找到对应的回调: requestId={response.requestId}");
}
}
else if (response.type == "event")
{
// 处理事件通知
string eventName = response.api;
if (_eventListeners.TryGetValue(eventName, out var listeners))
{
Debug.Log($"[WXPCHPInitScript] 收到事件: {eventName}");
foreach (var listener in listeners.ToArray())
{
try
{
listener?.Invoke(response.data ?? "{}");
}
catch (Exception e)
{
Debug.LogError($"[WXPCHPInitScript] 事件回调异常: {eventName}, {e.Message}");
}
}
}
}
}
/// <summary>
/// 异步消息处理回调从DLL回调可能在非主线程
/// </summary>
[AOT.MonoPInvokeCallback(typeof(AsyncMsgHandlerDelegate))]
private static void HandleAsyncMessage(IntPtr data, int len)
{
if (data == IntPtr.Zero || len <= 0)
{
return;
}
try
{
byte[] buffer = new byte[len];
Marshal.Copy(data, buffer, 0, len);
if (instance != null)
{
// 触发原始消息事件
instance.OnMessageReceived?.Invoke(buffer);
// 解析消息
string message = System.Text.Encoding.UTF8.GetString(buffer);
Debug.Log($"[WXPCHPInitScript] 收到原始消息: {message}");
try
{
// 尝试解析为响应消息
var response = JsonMapper.ToObject<PCHPResponseMessage>(message);
if (response != null && !string.IsNullOrEmpty(response.type))
{
// 加入消息队列,在主线程中处理
instance._messageQueue.Enqueue(response);
}
}
catch (Exception parseEx)
{
Debug.LogWarning($"[WXPCHPInitScript] 消息解析失败,可能是非标准格式: {parseEx.Message}");
}
}
}
catch (Exception e)
{
Debug.LogError($"[WXPCHPInitScript] 处理消息异常: {e.Message}");
}
}
#endregion
}
/// <summary>
/// PC高性能小游戏管理器
/// 提供类似 wx.getPCHighPerformanceManager() 的接口
/// </summary>
public class WXPCHighPerformanceManager
{
private static WXPCHighPerformanceManager _instance;
private WXPCHPInitScript _initScript;
/// <summary>
/// 获取 PC 高性能管理器实例
/// </summary>
public static WXPCHighPerformanceManager GetInstance()
{
if (_instance == null)
{
_instance = new WXPCHighPerformanceManager();
}
return _instance;
}
private WXPCHighPerformanceManager()
{
_initScript = WXPCHPInitScript.Instance;
}
/// <summary>
/// 是否支持PC高性能模式
/// </summary>
public bool IsSupported => _initScript != null && _initScript.IsInitialized && _initScript.IsConnected;
/// <summary>
/// 调用微信API
/// </summary>
public string CallWXAPI(string apiName, object data, Action<string> onSuccess = null, Action<string> onFail = null, Action<string> onComplete = null)
{
if (_initScript == null)
{
Debug.LogError("[WXPCHighPerformanceManager] InitScript 未初始化");
return null;
}
return _initScript.CallWXAPI(apiName, data, onSuccess, onFail, onComplete);
}
/// <summary>
/// 显示 Toast
/// </summary>
public void ShowToast(PCHPShowToastOption option, Action<PCHPGeneralCallbackResult> success = null, Action<PCHPGeneralCallbackResult> fail = null, Action<PCHPGeneralCallbackResult> complete = null)
{
_initScript?.ShowToast(option, success, fail, complete);
}
/// <summary>
/// 隐藏 Toast
/// </summary>
public void HideToast(Action<PCHPGeneralCallbackResult> success = null, Action<PCHPGeneralCallbackResult> fail = null, Action<PCHPGeneralCallbackResult> complete = null)
{
_initScript?.HideToast(success, fail, complete);
}
/// <summary>
/// 显示模态对话框
/// </summary>
public void ShowModal(PCHPShowModalOption option, Action<PCHPShowModalSuccessCallbackResult> success = null, Action<PCHPGeneralCallbackResult> fail = null, Action<PCHPGeneralCallbackResult> complete = null)
{
_initScript?.ShowModal(option, success, fail, complete);
}
/// <summary>
/// 显示 Loading
/// </summary>
public void ShowLoading(string title, bool mask = false, Action<PCHPGeneralCallbackResult> success = null, Action<PCHPGeneralCallbackResult> fail = null, Action<PCHPGeneralCallbackResult> complete = null)
{
_initScript?.ShowLoading(title, mask, success, fail, complete);
}
/// <summary>
/// 隐藏 Loading
/// </summary>
public void HideLoading(Action<PCHPGeneralCallbackResult> success = null, Action<PCHPGeneralCallbackResult> fail = null, Action<PCHPGeneralCallbackResult> complete = null)
{
_initScript?.HideLoading(success, fail, complete);
}
/// <summary>
/// 注册事件监听
/// </summary>
public void On(string eventName, Action<string> callback)
{
_initScript?.RegisterEventListener(eventName, callback);
}
/// <summary>
/// 移除事件监听
/// </summary>
public void Off(string eventName, Action<string> callback = null)
{
_initScript?.UnregisterEventListener(eventName, callback);
}
/// <summary>
/// 发送原始消息
/// </summary>
public bool SendRawMessage(string message)
{
return _initScript?.SendRawMessage(message) ?? false;
}
}
}