Files
5.24BuYu/Assets/MyGame/Scripts/Net/WebSocketManager_Message.cs
T
2026-07-21 04:36:52 +08:00

681 lines
34 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
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<WebSocketManager>
{
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<WebSocketResponseBase<object>>(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<object> v)
{
var roomMainPanel = UIManager.Instance.Get<ChineseChessMainPanel>(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<WebSocketResponseBase<ChessGameRoom>>(msg.ToString()).arguments[0];
roomMainPanel.subUIManager.CloseAll();
roomMainPanel.StartGame(msg);
roomMainPanel.UpdateUserData(va);
}
break;
case "CreateRoomNotice":
{
var va = JsonConvert.DeserializeObject<WebSocketResponseBase<ChessGameRoom>>(msg.ToString()).arguments[0];
var panel = roomMainPanel.subUIManager.Get<UIChineseChessDistrict>(UIPanel.ZGXQDistrict);
if (panel != null)
{
panel.UpdataRoom(va);
}
}
break;
case "JoinRoomNotice":
{
var va = JsonConvert.DeserializeObject<WebSocketResponseBase<ChessGameRoom>>(msg.ToString()).arguments[0];
var panel = roomMainPanel.subUIManager.Get<UIChineseChessDistrict>(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<WebSocketResponseBase<string>>(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<WebSocketResponseBase<Dictionary<string, object>>>(msg).arguments[0];
roomMainPanel.IsShowHint(va["data"].ToString(), Convert.ToInt32(va["type"]));
}
break;
case "EndGameSuccess":
{
var va = JsonConvert.DeserializeObject<WebSocketResponseBase<string>>(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<WebSocketResponseBase<string>>(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<WebSocketResponseBase<ChessGameRoom>>(msg.ToString()).arguments[0];
var panel = roomMainPanel.subUIManager.Get<UIChineseChessDistrict>(UIPanel.ZGXQDistrict);
if (panel != null)
{
panel.UpdataRoom(va);
}
}
}
break;
case "Disconnect":
roomMainPanel.subUIManager.ShowAsync(UIPanel.ZGXQWin);
break;
case "GameError":
{
var va = JsonConvert.DeserializeObject<WebSocketResponseBase<string>>(msg).arguments[0];
if (va == "只有代理才能配置密码")
{
UIManager.Instance.Get<ChineseChessMainPanel>(UIPanel.MainGamePanelZGXQ).subUIManager.Get<UIChineseChessCreateRoom>(UIPanel.ZGXQCreateRoom).ShowTiShi();
}
else
UIManager.Instance.ShowBoardError(va);
}
break;
// ======== 新增缺失事件 ========
case "JoinRoom":
{
var va = JsonConvert.DeserializeObject<WebSocketResponseBase<ChessGameRoom>>(msg).arguments[0];
// 调用者自身加入成功
if (roomMainPanel != null) roomMainPanel.UpdateUserData(va);
}
break;
case "Reconnect":
{
var va = JsonConvert.DeserializeObject<WebSocketResponseBase<Dictionary<string, object>>>(msg).arguments[0];
Debug.Log($"[Chess] 重连: userId={va["userId"]}, userName={va["userName"]}");
}
break;
case "AllBeginTime":
{
var va = JsonConvert.DeserializeObject<WebSocketResponseBase<ChessGameRoom>>(msg).arguments[0];
Debug.Log("[Chess] 双方已准备,开始计时");
}
break;
case "GameEnd":
{
var va = JsonConvert.DeserializeObject<WebSocketResponseBase<Dictionary<string, object>>>(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<WebSocketResponseBase<string>>(msg).arguments[0];
Debug.Log("[Chess] 结束请求已发送: " + va);
}
break;
case "OpponentRequestEnd":
{
var va = JsonConvert.DeserializeObject<WebSocketResponseBase<string>>(msg).arguments[0];
Debug.Log("[Chess] 对手请求结束: " + va);
}
break;
case "RestartGameSuccess":
{
var va = JsonConvert.DeserializeObject<WebSocketResponseBase<ChessGameRoom>>(msg).arguments[0];
if (roomMainPanel != null) roomMainPanel.StartGame(msg);
}
break;
case "RestartRoomNotice":
{
var va = JsonConvert.DeserializeObject<WebSocketResponseBase<ChessGameRoom>>(msg).arguments[0];
var panel = roomMainPanel?.subUIManager.Get<UIChineseChessDistrict>(UIPanel.ZGXQDistrict);
if (panel != null) panel.UpdataRoom(va);
}
break;
case "SyncGameData":
{
var va = JsonConvert.DeserializeObject<WebSocketResponseBase<Dictionary<string, object>>>(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<object> v)
{
switch ((MessageType)v.type)
{
case MessageType.Invocation:
switch (v.target)
{
// 发起会话回调(用户端):服务端返回 {isOk, msg, conversation}
case "OnConversationStarted":
{
var result = JsonConvert.DeserializeObject<WebSocketResponseBase<CustomerConversationStartedResult>>(msg).arguments[0];
WebSocketReponseList.Customer_OnConversationStarted(result);
}
break;
// 消息接收回调(用户端 & 客服端)
case "OnMessageReceived":
{
var result = JsonConvert.DeserializeObject<WebSocketResponseBase<CustomerMessageReceived>>(msg).arguments[0];
WebSocketReponseList.Customer_OnMessageReceived(result);
}
break;
// 新会话通知(客服端)
case "OnNewConversation":
{
var result = JsonConvert.DeserializeObject<WebSocketResponseBase<CustomerNewConversationNotice>>(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;
}
}
/// <summary>
/// LoginHub 消息处理(Broadcast / AssetUpdated / BackpackUpdated / NewEmail / KillAnnouncement)
/// </summary>
private static void LoginMSG(string msg, WebSocketResponseBase<object> 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<object> v)
{
switch ((MessageType)v.type)
{
case MessageType.Invocation:
switch (v.target)
{
case "GetRoomListResult":
//UIManager.Instance.Get<UIHome_BY_SelectRoomLevelPanel>(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<WebSocketResponseBase<string>>(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<WebSocketResponseBase<string>>(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<WebSocketResponseBase<string>>(msg).arguments[0];
Debug.Log("[FishGameHub] BindSuccess: " + msgText);
}
break;
case "SendPlayerInfoResult":
{
var gold = JsonConvert.DeserializeObject<WebSocketResponseBase<long?>>(msg).arguments[0];
// 发送玩家信息结果,gold 为当前金币数(可为 null)
if (gold.HasValue)
WebSocketReponseList.SyncPlayerGold(JsonConvert.DeserializeObject<WebSocketResponseBase<long>>(msg).arguments[0].ToString());
}
break;
case "RoomDisconnectNotice":
{
var userIdDisc = JsonConvert.DeserializeObject<WebSocketResponseBase<string>>(msg).arguments[0];
Debug.Log("[FishGameHub] 玩家断线: " + userIdDisc);
}
break;
case "ChangeGunMultipleNotice":
{
var data = JsonConvert.DeserializeObject<WebSocketResponseBase<Dictionary<string, object>>>(msg).arguments[0];
// { userId, multiple }
if (data != null)
Debug.Log($"[FishGameHub] 炮倍变更: userId={data["userId"]}, multiple={data["multiple"]}");
}
break;
case "UsePropNotice":
{
var data = JsonConvert.DeserializeObject<WebSocketResponseBase<Dictionary<string, object>>>(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<WebSocketResponseBase<Dictionary<string, object>>>(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<WebSocketResponseBase<int[]>>(msg).arguments[0];
Debug.Log($"[FishGameHub] 鱼过期: {string.Join(",", fishIds)}");
}
break;
case "OnFishList":
{
var fishList = JsonConvert.DeserializeObject<WebSocketResponseBase<object[]>>(msg).arguments[0];
Debug.Log($"[FishGameHub] 鱼列表刷新, 数量={fishList?.Length}");
}
break;
// ======== FishGameHub / FishRoomHub 补充事件 ========
case "BotLeaveRoomNoticeNEW":
{
// 机器人退出房间,数据 { userId }
var data = JsonConvert.DeserializeObject<WebSocketResponseBase<Dictionary<string, object>>>(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<WebSocketResponseBase<Dictionary<string, object>>>(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;
}
}
}
}