using Assets.MyGame.Scripts.Net.WebResponses; using Best.WebSockets; using Newtonsoft.Json; using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using UnityEngine; using static Assets.MyGame.Scripts.Net.WebResponses.ChineseChess.ChineseChessGameClassList; namespace Assets.MyGame.Scripts.Net { public partial class WebSocketManager : MonoSingleton { public void OnMessage(WebSocket web, string msg, SocketType type) { #if UNITY_EDITOR Debug.Log($"[WebSocket] {type} 收到消息: {msg}"); #endif string[] msgs = msg.Split('\u001e'); foreach (var item in msgs) { if (string.IsNullOrWhiteSpace(item)) continue; if (item.Trim() == "{}") { OnHandshakeCompleted(type); continue; } var v = JsonConvert.DeserializeObject>(item); if (v == null) { continue; } // TODO: 这里可以做统一消息分发 #region 消息处理 switch (type) { case SocketType.login: LoginMSG(item, v); break; case SocketType.room: case SocketType.game: FishMSG(item, v); break; case SocketType.chess: ChineseChess(item, v); break; case SocketType.customer: CustomerMSG(item, v); break; default: break; } } #endregion } private static void ChineseChess(string msg, WebSocketResponseBase v) { var roomMainPanel = UIManager.Instance.Get(UIPanel.MainGamePanelZGXQ); switch ((MessageType)v.type) { case MessageType.Invocation: switch (v.target) { case "GetRoomList": UIManager.Instance.ShowAsync(UIPanel.MainGamePanelZGXQ, msg); Screen.orientation = ScreenOrientation.Portrait; break; case "BeginGame": { var va = JsonConvert.DeserializeObject>(msg.ToString()).arguments[0]; roomMainPanel.subUIManager.CloseAll(); roomMainPanel.StartGame(msg); roomMainPanel.UpdateUserData(va); } break; case "CreateRoomNotice": { var va = JsonConvert.DeserializeObject>(msg.ToString()).arguments[0]; var panel = roomMainPanel.subUIManager.Get(UIPanel.ZGXQDistrict); if (panel != null) { panel.UpdataRoom(va); } } break; case "JoinRoomNotice": { var va = JsonConvert.DeserializeObject>(msg.ToString()).arguments[0]; var panel = roomMainPanel.subUIManager.Get(UIPanel.ZGXQDistrict); if (panel != null) { panel.UpdataRoom(va); } } break; //所有人 case "GoldConfigRoomNotice": roomMainPanel.subUIManager.CloseAll(); roomMainPanel.subUIManager.ShowAsync(UIPanel.ZGXQGameExplain, msg); break; // 房主开始游戏 → 通知红方配金币 case "GoldConfigRequired": roomMainPanel.OnGoldConfigRequired(msg); break; //单发给触发人 case "GoldConfigSuccess": break; case "ReadyNotice": { // ReadyNotice arguments[0] 是用户ID字符串,不是房间对象 var userId = JsonConvert.DeserializeObject>(msg).arguments[0]; // 标记该玩家已准备 if (roomMainPanel.roomData != null && roomMainPanel.roomData.users != null) { var u = roomMainPanel.roomData.users.Find(x => x.userId == userId); if (u != null) u.isReady = true; // 只有双方都准备好才进入游戏 if (roomMainPanel.roomData.users.Count >= 2 && roomMainPanel.roomData.users.TrueForAll(x => x.isReady)) { roomMainPanel.InitRoomData(); } } } break; case "GameOperation": { var va = JsonConvert.DeserializeObject>>(msg).arguments[0]; roomMainPanel.IsShowHint(va["data"].ToString(), Convert.ToInt32(va["type"])); } break; case "EndGameSuccess": { var va = JsonConvert.DeserializeObject>(msg).arguments[0]; if (va == null || va == "") { roomMainPanel.subUIManager.ShowAsync(UIPanel.ZGXQHe); } else if (va == GameManager.Instance.user.id) { roomMainPanel.subUIManager.ShowAsync(UIPanel.ZGXQWin); } else { roomMainPanel.subUIManager.ShowAsync(UIPanel.ZGXQDefeated); } } break; case "ExitRoomSuccess": { var va = JsonConvert.DeserializeObject>(msg).arguments[0]; if (GameManager.Instance.user.id == va) { WebSocketSendList.GetRoomListChineseChess(1); } else { for (int i = 0; i < roomMainPanel.roomData.users.Count; i++) { var item = roomMainPanel.roomData.users[i]; if (item.userId != va) { roomMainPanel.roomData.users.Remove(item); roomMainPanel.UpdateUserData(roomMainPanel.roomData); i--; } } } } break; case "ExitRoomNotice": { { var va = JsonConvert.DeserializeObject>(msg.ToString()).arguments[0]; var panel = roomMainPanel.subUIManager.Get(UIPanel.ZGXQDistrict); if (panel != null) { panel.UpdataRoom(va); } } } break; case "Disconnect": roomMainPanel.subUIManager.ShowAsync(UIPanel.ZGXQWin); break; case "GameError": { var va = JsonConvert.DeserializeObject>(msg).arguments[0]; if (va == "只有代理才能配置密码") { UIManager.Instance.Get(UIPanel.MainGamePanelZGXQ).subUIManager.Get(UIPanel.ZGXQCreateRoom).ShowTiShi(); } else UIManager.Instance.ShowBoardError(va); } break; // ======== 新增缺失事件 ======== case "JoinRoom": { var va = JsonConvert.DeserializeObject>(msg).arguments[0]; // 调用者自身加入成功 if (roomMainPanel != null) roomMainPanel.UpdateUserData(va); } break; case "Reconnect": { var va = JsonConvert.DeserializeObject>>(msg).arguments[0]; Debug.Log($"[Chess] 重连: userId={va["userId"]}, userName={va["userName"]}"); } break; case "AllBeginTime": { var va = JsonConvert.DeserializeObject>(msg).arguments[0]; Debug.Log("[Chess] 双方已准备,开始计时"); } break; case "GameEnd": { var va = JsonConvert.DeserializeObject>>(msg).arguments[0]; string winUserId = va["winUserId"]?.ToString(); if (string.IsNullOrEmpty(winUserId)) roomMainPanel.subUIManager.ShowAsync(UIPanel.ZGXQHe); else if (winUserId == GameManager.Instance.user.BaseInfo.number) roomMainPanel.subUIManager.ShowAsync(UIPanel.ZGXQWin); else roomMainPanel.subUIManager.ShowAsync(UIPanel.ZGXQDefeated); } break; case "EndGameRequestSent": { var va = JsonConvert.DeserializeObject>(msg).arguments[0]; Debug.Log("[Chess] 结束请求已发送: " + va); } break; case "OpponentRequestEnd": { var va = JsonConvert.DeserializeObject>(msg).arguments[0]; Debug.Log("[Chess] 对手请求结束: " + va); } break; case "RestartGameSuccess": { var va = JsonConvert.DeserializeObject>(msg).arguments[0]; if (roomMainPanel != null) roomMainPanel.StartGame(msg); } break; case "RestartRoomNotice": { var va = JsonConvert.DeserializeObject>(msg).arguments[0]; var panel = roomMainPanel?.subUIManager.Get(UIPanel.ZGXQDistrict); if (panel != null) panel.UpdataRoom(va); } break; case "SyncGameData": { var va = JsonConvert.DeserializeObject>>(msg).arguments[0]; string data = va["data"]?.ToString(); Debug.Log("[Chess] 同步数据: " + data); } break; default: break; } break; case MessageType.StreamItem: break; case MessageType.Completion: break; case MessageType.StreamInvocation: break; case MessageType.CancelInvocation: break; case MessageType.Ping: break; case MessageType.Close: break; default: break; } } private static void CustomerMSG(string msg, WebSocketResponseBase v) { switch ((MessageType)v.type) { case MessageType.Invocation: switch (v.target) { // 发起会话回调(用户端):服务端返回 {isOk, msg, conversation} case "OnConversationStarted": { var result = JsonConvert.DeserializeObject>(msg).arguments[0]; WebSocketReponseList.Customer_OnConversationStarted(result); } break; // 消息接收回调(用户端 & 客服端) case "OnMessageReceived": { var result = JsonConvert.DeserializeObject>(msg).arguments[0]; WebSocketReponseList.Customer_OnMessageReceived(result); } break; // 新会话通知(客服端) case "OnNewConversation": { var result = JsonConvert.DeserializeObject>(msg).arguments[0]; WebSocketReponseList.Customer_OnNewConversation(result); } break; default: break; } break; case MessageType.StreamItem: break; case MessageType.Completion: break; case MessageType.StreamInvocation: break; case MessageType.CancelInvocation: break; case MessageType.Ping: break; case MessageType.Close: break; default: break; } } /// /// LoginHub 消息处理(Broadcast / AssetUpdated / BackpackUpdated / NewEmail / KillAnnouncement) /// private static void LoginMSG(string msg, WebSocketResponseBase v) { switch ((MessageType)v.type) { case MessageType.Invocation: switch (v.target) { case "Broadcast": WebSocketReponseList.LoginBroadcast(msg); break; case "AssetUpdated": WebSocketReponseList.AssetUpdated(msg); break; case "BackpackUpdated": WebSocketReponseList.BackpackUpdated(msg); break; case "NewEmail": WebSocketReponseList.NewEmail(msg); break; case "KillAnnouncement": WebSocketReponseList.KillAnnouncement(msg); break; case "LevelChangedNEW": WebSocketReponseList.LevelChanged(msg); break; default: break; } break; } } private static void FishMSG(string msg, WebSocketResponseBase v) { switch ((MessageType)v.type) { case MessageType.Invocation: switch (v.target) { case "GetRoomListResult": //UIManager.Instance.Get(UIPanel.SelectRoomPenel); WebSocketReponseList.GetRoomListResult(msg); break; case "RoomJoinNotice": WebSocketReponseList.RoomJoinNotice(msg); break; case "RoomInfo": WebSocketReponseList.RoomInfo(msg); break; case "RoomFireNotice": WebSocketReponseList.RoomFireNotice(msg); break; case "RoomKillNotice": WebSocketReponseList.RoomKillNotice(msg); break; case "SyncPlayerGold": WebSocketReponseList.SyncPlayerGold(msg); break; case "GetRoomInfoResult": WebSocketReponseList.GetRoomInfoResult(msg); break; case "SyncGameData": WebSocketReponseList.SyncGameDataResult(msg); break; case "RoomLeaveNotice": WebSocketReponseList.LeaveRoomResult(msg); //WebSocketManager.Instance.Close(SocketType.game); break; case "ChangeControllerUser": { var userId = JsonConvert.DeserializeObject>(msg).arguments[0]; if (userId == GameManager.Instance.user.id) { // 本地玩家成为房主:开启出鱼 + 同步本地房主引用 CreateFishManager.Instance.fangzhu = true; if (SitPosData.localPlayerSit != null) SitPosData.roomOwnerSit = SitPosData.localPlayerSit; } else if (userId != null && userId.StartsWith("bot_")) { // 房主是人机:人机无法真正发包,由本地首个非人机玩家代发 SitPosData.TransferRoomOwner(); CreateFishManager.Instance.fangzhu = SitPosData.roomOwnerSit != null && SitPosData.roomOwnerSit.user == GameManager.Instance.user.id; } else { // ⭐ 只在 userId 非空且确实是真人玩家时才停止本地出鱼 // userId 为空(异常情况)时保持原状,避免误关出鱼导致 bot 退出后不出鱼 if (!string.IsNullOrEmpty(userId)) CreateFishManager.Instance.fangzhu = false; } } break; case "Exception": { var va = JsonConvert.DeserializeObject>(msg).arguments[0]; UIManager.Instance.ShowBoardError(va); switch (va) { case "房间人数已满": switch (GameManager.Instance.gameData.currGameType) { case GameType.JQQD: break; case GameType.defaultPanel: UIManager.Instance.ShowAsync(UIPanel.HomeMainPanel, UIPanel.MainGamePanelDefault, null, (panel) => { WebSocketSendList.GetRoomListFish(GameManager.Instance.gameData.currRoomData.roomLevel, 1); }); break; case GameType.FLZY: UIManager.Instance.ShowAsync(UIPanel.HomeMainPanel, UIPanel.MainGamePanelFLZY, null, (panel) => { WebSocketSendList.GetRoomListFish(GameManager.Instance.gameData.currRoomData.roomLevel, 1); }); break; case GameType.YYSC: UIManager.Instance.ShowAsync(UIPanel.HomeMainPanel, UIPanel.MainGamePanelYYSC, null, (panel) => { WebSocketSendList.GetRoomListFish(GameManager.Instance.gameData.currRoomData.roomLevel, 1); }); break; case GameType.ZGXQ: UIManager.Instance.ShowAsync(UIPanel.HomeMainPanel, UIPanel.MainGamePanelZGXQ, null, (panel) => { WebSocketSendList.GetRoomListFish(GameManager.Instance.gameData.currRoomData.roomLevel, 1); }); break; case GameType.XJMH: UIManager.Instance.ShowAsync(UIPanel.HomeMainPanel, UIPanel.MainGamePanelXJMH, null, (panel) => { WebSocketSendList.GetRoomListFish(GameManager.Instance.gameData.currRoomData.roomLevel, 1); }); break; case GameType.HHWK: UIManager.Instance.ShowAsync(UIPanel.HomeMainPanel, UIPanel.MainGamePanelHHWK, null, (panel) => { WebSocketSendList.GetRoomListFish(GameManager.Instance.gameData.currRoomData.roomLevel, 1); }); break; default: break; } break; default: break; } } break; // ======== 新增 FishGameHub 缺失事件 ======== case "BindSuccess": { var msgText = JsonConvert.DeserializeObject>(msg).arguments[0]; Debug.Log("[FishGameHub] BindSuccess: " + msgText); } break; case "SendPlayerInfoResult": { var gold = JsonConvert.DeserializeObject>(msg).arguments[0]; // 发送玩家信息结果,gold 为当前金币数(可为 null) if (gold.HasValue) WebSocketReponseList.SyncPlayerGold(JsonConvert.DeserializeObject>(msg).arguments[0].ToString()); } break; case "RoomDisconnectNotice": { var userIdDisc = JsonConvert.DeserializeObject>(msg).arguments[0]; Debug.Log("[FishGameHub] 玩家断线: " + userIdDisc); } break; case "ChangeGunMultipleNotice": { var data = JsonConvert.DeserializeObject>>(msg).arguments[0]; // { userId, multiple } if (data != null) Debug.Log($"[FishGameHub] 炮倍变更: userId={data["userId"]}, multiple={data["multiple"]}"); } break; case "UsePropNotice": { var data = JsonConvert.DeserializeObject>>(msg).arguments[0]; var userId = data["userId"]?.ToString(); string propNumber = data["propNumber"]?.ToString(); Debug.Log($"[FishGameHub] 使用道具: userId={userId}, prop={propNumber}"); var panel = CreateFishManager.Instance.currGameType; if (panel != null) panel.OnUsePropNotice(userId, propNumber); } break; case "KillNotice": { var data = JsonConvert.DeserializeObject>>(msg).arguments[0]; if (data == null) break; // { FishId, userName, gold } string userName = data.TryGetValue("userName", out var un) ? un?.ToString() : ""; string fishId = data.TryGetValue("FishId", out var fi) ? fi?.ToString() : ""; long gold = data.TryGetValue("gold", out var g) ? Convert.ToInt64(g) : 0; string roomName = GameManager.Instance.gameData.currRoomData?.roomName ?? ""; string roomLevel = GameManager.Instance.gameData.currRoomData?.roomLevel.ToString() ?? ""; string msgText = $"恭喜用户{userName} 在 {roomName} {roomLevel}场 捕获了{fishId}*{gold}倍"; //UIManager.Instance.ShowBoardGongGao(msgText); } break; case "OnFishExpired": { var fishIds = JsonConvert.DeserializeObject>(msg).arguments[0]; Debug.Log($"[FishGameHub] 鱼过期: {string.Join(",", fishIds)}"); } break; case "OnFishList": { var fishList = JsonConvert.DeserializeObject>(msg).arguments[0]; Debug.Log($"[FishGameHub] 鱼列表刷新, 数量={fishList?.Length}"); } break; // ======== FishGameHub / FishRoomHub 补充事件 ======== case "BotLeaveRoomNoticeNEW": { // 机器人退出房间,数据 { userId } var data = JsonConvert.DeserializeObject>>(msg).arguments[0]; string botUserId = data != null && data.TryGetValue("userId", out var buid) ? buid?.ToString() : ""; Debug.Log($"[FishGameHub] 机器人退出: {botUserId}"); WebSocketReponseList.BotLeaveRoom(botUserId); } break; case "HostDisconnectNEW": { // 房主断线,其他玩家可接受机器人控制权 Debug.Log("[FishGameHub] 房主断线,可接受机器人控制权"); WebSocketReponseList.HostDisconnect(); } break; case "OnSeatChange": { // 座位变更 { type, userId, position, showWaiting? } var data = JsonConvert.DeserializeObject>>(msg).arguments[0]; if (data != null) { int seatType = data.TryGetValue("type", out var t) ? Convert.ToInt32(t) : 0; string userId = data.TryGetValue("userId", out var u) ? u?.ToString() : ""; int position = data.TryGetValue("position", out var p) ? Convert.ToInt32(p) : -1; bool showWaiting = data.TryGetValue("showWaiting", out var sw) && Convert.ToBoolean(sw); Debug.Log($"[FishGameHub] 座位变更: type={seatType}, userId={userId}, position={position}, showWaiting={showWaiting}"); WebSocketReponseList.SeatChange(seatType, userId, position, showWaiting); } } break; case "RoomChange": { // FishRoomHub 房间变化通知(人数/状态变更),更新房间列表 Debug.Log("[FishRoomHub] 房间变化通知"); WebSocketReponseList.RoomChangeNotice(msg); } break; default: break; } break; case MessageType.StreamItem: break; case MessageType.Completion: break; case MessageType.StreamInvocation: break; case MessageType.CancelInvocation: break; case MessageType.Ping: break; case MessageType.Close: break; default: break; } } } }