2026-07-27 23:30:25 +08:00
|
|
|
|
using Assets.MyGame.Scripts.Net.API;
|
2026-07-10 23:26:42 +08:00
|
|
|
|
using Assets.MyGame.Scripts.Net.WebResponses;
|
2026-02-03 11:35:19 +08:00
|
|
|
|
using Newtonsoft.Json;
|
|
|
|
|
|
using System;
|
|
|
|
|
|
using System.Collections.Generic;
|
|
|
|
|
|
using System.Linq;
|
|
|
|
|
|
using System.Text;
|
|
|
|
|
|
using System.Threading.Tasks;
|
|
|
|
|
|
using UnityEngine;
|
|
|
|
|
|
using UnityEngine.SceneManagement;
|
|
|
|
|
|
|
|
|
|
|
|
namespace Assets.MyGame.Scripts.Net
|
|
|
|
|
|
{
|
|
|
|
|
|
public class WebSocketReponseList
|
|
|
|
|
|
{
|
2026-07-13 02:24:32 +08:00
|
|
|
|
/// <summary>已加载(或正在加载)的游戏场景名集合,防止人机 RoomJoinNotice 触发重复 LoadSceneAsync</summary>
|
|
|
|
|
|
private static readonly HashSet<string> _loadedGameScenes = new HashSet<string>();
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>清除指定场景的加载标记(退出游戏时调用,下次进入可重新加载)</summary>
|
|
|
|
|
|
public static void ClearLoadedGameScene(string sceneName)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (!string.IsNullOrEmpty(sceneName))
|
|
|
|
|
|
_loadedGameScenes.Remove(sceneName);
|
|
|
|
|
|
}
|
2026-02-13 19:23:01 +08:00
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 获取房间列表 room
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
/// <param name="msg"></param>
|
|
|
|
|
|
public static void GetRoomListChineseChessResult(string msg)
|
|
|
|
|
|
{
|
2026-03-09 09:25:01 +08:00
|
|
|
|
var var1 = UIManager.Instance.Show<UIChineseChessDistrict>(UIPanel.MainGamePanelZGXQ, msg);
|
2026-02-13 19:23:01 +08:00
|
|
|
|
}
|
2026-02-26 11:05:56 +08:00
|
|
|
|
public static void GetGoldConfigSuccessChineseChessResult(string msg)
|
|
|
|
|
|
{
|
|
|
|
|
|
UIManager.Instance.Get<ChineseChessMainPanel>(UIPanel.MainGamePanelZGXQ).subUIManager.ShowAsync(UIPanel.ZGXQGameExplain);
|
|
|
|
|
|
}
|
2026-03-09 09:25:01 +08:00
|
|
|
|
|
2026-02-03 11:35:19 +08:00
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 获取房间列表 room
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
/// <param name="msg"></param>
|
|
|
|
|
|
public static void GetRoomListResult(string msg)
|
|
|
|
|
|
{
|
|
|
|
|
|
var var1 = UIManager.Instance.Get<UIHomeMain>(UIPanel.HomeMainPanel);
|
2026-03-09 09:25:01 +08:00
|
|
|
|
|
2026-03-18 17:26:14 +08:00
|
|
|
|
var selectRoomPanel = var1.subUIManager.Get<UIHome_BY_SelectRoomLevelPanel>(UIPanel.SelectRoomLeavePenel);
|
2026-03-09 09:25:01 +08:00
|
|
|
|
if (selectRoomPanel != null && selectRoomPanel.isMySelectRoom)
|
|
|
|
|
|
{
|
2026-07-20 22:32:52 +08:00
|
|
|
|
// 手动选座:显示房间列表给玩家选
|
|
|
|
|
|
selectRoomPanel.panel_UIHome_BY_MySelectRoomPenel.Show(msg);
|
2026-03-09 09:25:01 +08:00
|
|
|
|
}
|
2026-07-20 22:32:52 +08:00
|
|
|
|
// 快速加入分支已迁移到 OnSelectRoom → /api/Room/QuickJoin,不再走 GetRoomList
|
2026-02-03 11:35:19 +08:00
|
|
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 加入房间 room
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
/// <param name="msg"></param>
|
|
|
|
|
|
public static void RoomJoinNotice(string msg)
|
|
|
|
|
|
{
|
2026-07-29 22:59:26 +08:00
|
|
|
|
// ⭐ 记录金币流水:收到加钱信息(RoomJoinNotice 推送,尚未执行)—— 只记录自己
|
2026-07-29 17:17:14 +08:00
|
|
|
|
try
|
|
|
|
|
|
{
|
|
|
|
|
|
var notice = JsonConvert.DeserializeObject<WebSocketResponseBase<RoomJoinNotice>>(msg).arguments[0];
|
2026-07-29 22:59:26 +08:00
|
|
|
|
string myId = GameManager.Instance.user?.id;
|
2026-09-13 01:40:32 +08:00
|
|
|
|
if (!string.IsNullOrEmpty(myId) && notice.UserId == myId)
|
2026-07-29 22:59:26 +08:00
|
|
|
|
{
|
2026-09-13 01:40:32 +08:00
|
|
|
|
GameManager.LogGoldFlowReceiveGain("RoomJoinNotice", $"推送金币={notice.Gold} 钻石={notice.Diamond} 炮台消耗={notice.CannonMultiple} 座位={notice.Position}");
|
2026-07-29 22:59:26 +08:00
|
|
|
|
}
|
2026-07-29 17:17:14 +08:00
|
|
|
|
}
|
|
|
|
|
|
catch { }
|
|
|
|
|
|
|
2026-03-09 09:25:01 +08:00
|
|
|
|
string sceneName = "";
|
2026-02-03 11:35:19 +08:00
|
|
|
|
UIPanel uIPanel = UIPanel.None;
|
|
|
|
|
|
switch (GameManager.Instance.gameData.currGameType)
|
|
|
|
|
|
{
|
|
|
|
|
|
case GameType.JQQD:
|
|
|
|
|
|
break;
|
|
|
|
|
|
case GameType.defaultPanel:
|
|
|
|
|
|
break;
|
2026-03-12 10:48:53 +08:00
|
|
|
|
case GameType.FLZY:
|
|
|
|
|
|
sceneName = "FLZY";
|
|
|
|
|
|
uIPanel = UIPanel.MainGamePanelFLZY;
|
2026-02-03 11:35:19 +08:00
|
|
|
|
break;
|
2026-05-07 03:46:03 +08:00
|
|
|
|
case GameType.YYSC:
|
|
|
|
|
|
sceneName = "YYSC";
|
|
|
|
|
|
|
|
|
|
|
|
uIPanel = UIPanel.MainGamePanelYYSC;
|
|
|
|
|
|
|
2026-02-03 11:35:19 +08:00
|
|
|
|
break;
|
|
|
|
|
|
case GameType.ZGXQ:
|
|
|
|
|
|
break;
|
|
|
|
|
|
case GameType.XJMH:
|
|
|
|
|
|
sceneName = "XJMH";
|
2026-03-09 09:25:01 +08:00
|
|
|
|
uIPanel = UIPanel.MainGamePanelXJMH;
|
2026-02-03 11:35:19 +08:00
|
|
|
|
break;
|
|
|
|
|
|
case GameType.HHWK:
|
2026-03-18 17:26:14 +08:00
|
|
|
|
sceneName = "HHWK";
|
|
|
|
|
|
uIPanel = UIPanel.MainGamePanelHHWK;
|
2026-02-03 11:35:19 +08:00
|
|
|
|
break;
|
|
|
|
|
|
default:
|
|
|
|
|
|
break;
|
|
|
|
|
|
}
|
2026-07-13 02:24:32 +08:00
|
|
|
|
if (UIManager.Instance.Get<GameMainPanel_Base>(uIPanel)==null)
|
2026-03-09 09:25:01 +08:00
|
|
|
|
{
|
2026-07-13 02:24:32 +08:00
|
|
|
|
UIManager.Instance.ShowAsync(uIPanel, UIPanel.HomeMainPanel, msg);
|
2026-07-13 00:12:44 +08:00
|
|
|
|
// 卸载所有已加载的游戏地图场景(保证场景唯一性)
|
2026-06-28 16:48:18 +08:00
|
|
|
|
string[] gameScenes = { "FLZY", "YYSC", "XJMH", "HHWK" };
|
|
|
|
|
|
foreach (var sn in gameScenes)
|
|
|
|
|
|
{
|
2026-07-13 00:12:44 +08:00
|
|
|
|
// 不卸载即将加载的目标场景
|
|
|
|
|
|
if (sn == sceneName) continue;
|
2026-06-28 16:48:18 +08:00
|
|
|
|
var s = SceneManager.GetSceneByName(sn);
|
|
|
|
|
|
if (s.IsValid() && s.isLoaded)
|
2026-07-13 02:24:32 +08:00
|
|
|
|
{
|
2026-06-28 16:48:18 +08:00
|
|
|
|
SceneManager.UnloadSceneAsync(sn);
|
2026-07-13 02:24:32 +08:00
|
|
|
|
_loadedGameScenes.Remove(sn);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
// 目标场景仅加载一次:标记已加载后不再重复 LoadSceneAsync(防止人机通知触发重复加载)
|
|
|
|
|
|
if (!string.IsNullOrEmpty(sceneName) && !_loadedGameScenes.Contains(sceneName))
|
|
|
|
|
|
{
|
|
|
|
|
|
_loadedGameScenes.Add(sceneName);
|
|
|
|
|
|
var targetScene = SceneManager.GetSceneByName(sceneName);
|
|
|
|
|
|
if (!targetScene.IsValid() || !targetScene.isLoaded)
|
|
|
|
|
|
SceneManager.LoadSceneAsync(sceneName, LoadSceneMode.Additive);
|
2026-06-28 16:48:18 +08:00
|
|
|
|
}
|
2026-03-09 09:25:01 +08:00
|
|
|
|
|
2026-06-28 16:48:18 +08:00
|
|
|
|
UIManager.Instance.Close(UIPanel.HomeMainPanel);
|
|
|
|
|
|
WebSocketManager.Instance.isGame = true;
|
|
|
|
|
|
}
|
2026-07-13 02:24:32 +08:00
|
|
|
|
else
|
2026-06-30 01:31:53 +08:00
|
|
|
|
{
|
|
|
|
|
|
// 面板已存在 → 新玩家加入,转发给现有面板激活座位
|
|
|
|
|
|
var panel = UIManager.Instance.Get<GameMainPanel_Base>(uIPanel);
|
|
|
|
|
|
if (panel is GameMainPanel_FishBase fishPanel)
|
|
|
|
|
|
{
|
|
|
|
|
|
var v = JsonConvert.DeserializeObject<WebSocketResponseBase<RoomJoinNotice>>(msg);
|
|
|
|
|
|
if (v.arguments.Count > 0)
|
|
|
|
|
|
{
|
|
|
|
|
|
var notice = v.arguments[0];
|
|
|
|
|
|
// 如果座位被bot占用则替换
|
2026-09-13 01:40:32 +08:00
|
|
|
|
var targetSit = fishPanel.list_Sits.Find(s => s.posID == notice.Position);
|
2026-06-30 01:31:53 +08:00
|
|
|
|
if (targetSit != null && targetSit.isBot)
|
|
|
|
|
|
{
|
|
|
|
|
|
targetSit.isBot = false;
|
2026-07-02 18:28:50 +08:00
|
|
|
|
targetSit.ShowWaiting();
|
2026-06-30 01:31:53 +08:00
|
|
|
|
}
|
2026-09-13 01:40:32 +08:00
|
|
|
|
fishPanel.JoinGame(notice.Position, notice.Gold, notice.Diamond, notice.CannonMultiple, 0, notice.UserId, notice.CannonId, notice.WingsId, notice.WarGodId);
|
2026-07-02 19:09:00 +08:00
|
|
|
|
// 后端动态加入的机器人也要标记
|
2026-09-13 01:40:32 +08:00
|
|
|
|
if (targetSit != null && !string.IsNullOrEmpty(notice.UserId) && notice.UserId.StartsWith("bot_"))
|
2026-07-02 19:09:00 +08:00
|
|
|
|
targetSit.isBot = true;
|
2026-06-30 01:31:53 +08:00
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
2026-06-28 16:48:18 +08:00
|
|
|
|
|
2026-03-09 09:25:01 +08:00
|
|
|
|
|
2026-02-03 11:35:19 +08:00
|
|
|
|
}
|
|
|
|
|
|
/// <summary>
|
2026-03-09 09:25:01 +08:00
|
|
|
|
/// 房间列表 room
|
2026-02-03 11:35:19 +08:00
|
|
|
|
/// </summary>
|
|
|
|
|
|
/// <param name="msg"></param>
|
|
|
|
|
|
public static void RoomInfo(string msg)
|
|
|
|
|
|
{
|
2026-03-18 17:26:14 +08:00
|
|
|
|
WebSocketManager.Instance.isGame = false;
|
2026-02-03 11:35:19 +08:00
|
|
|
|
var roomData = JsonConvert.DeserializeObject<WebSocketResponseBase<RoomChangeResponse>>(msg).arguments[0];
|
|
|
|
|
|
if (roomData != null)
|
|
|
|
|
|
{
|
|
|
|
|
|
GameManager.Instance.gameData.currRoomData = roomData;
|
|
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
|
|
|
|
|
Debug.LogError("roomdata是空:" + msg);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
public static void RoomKillNotice(string msg)
|
|
|
|
|
|
{
|
2026-07-12 00:26:17 +08:00
|
|
|
|
// 离开倒计时期间不触发击杀/爆奖特效
|
|
|
|
|
|
var panel = UIManager.Instance.Get<GameMainPanel_FishBase>(UIPanel.MainGamePanelDefault)
|
|
|
|
|
|
?? UIManager.Instance.Get<GameMainPanel_FishBase>(UIPanel.MainGamePanelFLZY)
|
|
|
|
|
|
?? UIManager.Instance.Get<GameMainPanel_FishBase>(UIPanel.MainGamePanelYYSC)
|
|
|
|
|
|
?? UIManager.Instance.Get<GameMainPanel_FishBase>(UIPanel.MainGamePanelXJMH)
|
|
|
|
|
|
?? UIManager.Instance.Get<GameMainPanel_FishBase>(UIPanel.MainGamePanelHHWK);
|
|
|
|
|
|
if (panel != null && panel.IsLeavingCountdown()) return;
|
2026-03-31 17:00:05 +08:00
|
|
|
|
CreateFishManager.Instance.Ws_DieFish(msg);
|
2026-02-03 11:35:19 +08:00
|
|
|
|
}
|
2026-05-27 19:47:06 +08:00
|
|
|
|
public static void RoomFireNotice(string msg)
|
|
|
|
|
|
{
|
|
|
|
|
|
FireCannonSendData fireCannonSendData = JsonConvert.DeserializeObject<WebSocketResponseBase<FireCannonSendData>>(msg).arguments[0];
|
|
|
|
|
|
var syncGameData = fireCannonSendData.extra;
|
|
|
|
|
|
|
|
|
|
|
|
EventCenter.Instance.EventTrigger<FireCannonSendData>(ConstEventString.SyncGameData_FireBullet, fireCannonSendData);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2026-02-09 10:44:38 +08:00
|
|
|
|
public static void SyncPlayerGold(string msg)
|
|
|
|
|
|
{
|
2026-03-10 15:36:10 +08:00
|
|
|
|
var gold = JsonConvert.DeserializeObject<WebSocketResponseBase<long>>(msg).arguments[0];
|
2026-04-22 23:08:46 +08:00
|
|
|
|
switch (GameManager.Instance.gameData.currGameType)
|
|
|
|
|
|
{
|
|
|
|
|
|
case GameType.JQQD:
|
|
|
|
|
|
break;
|
|
|
|
|
|
case GameType.defaultPanel:
|
2026-07-29 00:31:59 +08:00
|
|
|
|
UpdateLocalPlayerGold(UIPanel.MainGamePanelDefault, gold);
|
2026-04-22 23:08:46 +08:00
|
|
|
|
break;
|
|
|
|
|
|
case GameType.FLZY:
|
2026-07-29 00:31:59 +08:00
|
|
|
|
UpdateLocalPlayerGold(UIPanel.MainGamePanelFLZY, gold);
|
2026-04-22 23:08:46 +08:00
|
|
|
|
break;
|
2026-05-07 03:46:03 +08:00
|
|
|
|
case GameType.YYSC:
|
2026-07-29 00:31:59 +08:00
|
|
|
|
UpdateLocalPlayerGold(UIPanel.MainGamePanelYYSC, gold);
|
2026-04-22 23:08:46 +08:00
|
|
|
|
break;
|
|
|
|
|
|
case GameType.ZGXQ:
|
|
|
|
|
|
break;
|
|
|
|
|
|
case GameType.XJMH:
|
2026-07-29 00:31:59 +08:00
|
|
|
|
UpdateLocalPlayerGold(UIPanel.MainGamePanelXJMH, gold);
|
2026-04-22 23:08:46 +08:00
|
|
|
|
break;
|
|
|
|
|
|
case GameType.HHWK:
|
2026-07-29 00:31:59 +08:00
|
|
|
|
UpdateLocalPlayerGold(UIPanel.MainGamePanelHHWK, gold);
|
2026-04-22 23:08:46 +08:00
|
|
|
|
break;
|
|
|
|
|
|
default:
|
|
|
|
|
|
break;
|
|
|
|
|
|
}
|
2026-02-09 10:44:38 +08:00
|
|
|
|
}
|
2026-07-29 00:31:59 +08:00
|
|
|
|
|
2026-07-30 23:54:35 +08:00
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 炮倍变更通知:服务端确认玩家炮倍切换后广播给房间内所有玩家。
|
|
|
|
|
|
/// 客户端收到后才应用新炮倍到 consumeGoldNum 和 UI,避免开火扣费不一致。
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
public static void ChangeGunMultipleNotice(string msg)
|
|
|
|
|
|
{
|
|
|
|
|
|
var data = JsonConvert.DeserializeObject<WebSocketResponseBase<ChangeGunMultipleNotice>>(msg).arguments[0];
|
|
|
|
|
|
var panel = UIManager.Instance.Get<GameMainPanel_FishBase>(UIPanel.MainGamePanelDefault)
|
|
|
|
|
|
?? UIManager.Instance.Get<GameMainPanel_FishBase>(UIPanel.MainGamePanelFLZY)
|
|
|
|
|
|
?? UIManager.Instance.Get<GameMainPanel_FishBase>(UIPanel.MainGamePanelYYSC)
|
|
|
|
|
|
?? UIManager.Instance.Get<GameMainPanel_FishBase>(UIPanel.MainGamePanelXJMH)
|
|
|
|
|
|
?? UIManager.Instance.Get<GameMainPanel_FishBase>(UIPanel.MainGamePanelHHWK);
|
|
|
|
|
|
if (panel == null) return;
|
|
|
|
|
|
panel.ApplyCannonMultiple(data.userId, data.multiple);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2026-07-29 00:31:59 +08:00
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 后端推送 SyncPlayerGold 时同步本地玩家金币(底层值 + UI 显示)。
|
|
|
|
|
|
/// 之前只更新 goldNum 不刷新 tMP_GoldNum.text,导致 UI 显示和后端 authoritative 值不同步,
|
|
|
|
|
|
/// 后续杀鱼累加基于修正值但 UI 显示旧值,差距越拉越大。
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
private static void UpdateLocalPlayerGold(UIPanel panelType, long gold)
|
|
|
|
|
|
{
|
|
|
|
|
|
var panel = UIManager.Instance.Get<GameMainPanel_FishBase>(panelType);
|
|
|
|
|
|
if (panel == null || panel.currSitData == null) return;
|
2026-07-29 17:17:14 +08:00
|
|
|
|
long oldGold = panel.currSitData.goldNum;
|
2026-07-29 22:59:26 +08:00
|
|
|
|
long diff = gold - oldGold;
|
|
|
|
|
|
// ⭐ 记录金币流水:收到后端推送 SyncPlayerGold(尚未执行)
|
|
|
|
|
|
if (diff > 0)
|
|
|
|
|
|
GameManager.LogGoldFlowReceiveGain("SyncPlayerGold", $"推送金币={gold} 修正前金币={oldGold} 差值=+{diff} 座位={panel.currSitData.posID}");
|
|
|
|
|
|
else if (diff < 0)
|
|
|
|
|
|
GameManager.LogGoldFlowReceiveCost("SyncPlayerGold", $"推送金币={gold} 修正前金币={oldGold} 差值={diff} 座位={panel.currSitData.posID}");
|
|
|
|
|
|
|
2026-07-29 00:31:59 +08:00
|
|
|
|
panel.currSitData.goldNum = gold;
|
|
|
|
|
|
if (panel.currSitData.tMP_GoldNum != null)
|
|
|
|
|
|
panel.currSitData.tMP_GoldNum.text = gold.ToString();
|
2026-07-29 22:59:26 +08:00
|
|
|
|
|
|
|
|
|
|
// ⭐ 记录金币流水:已执行修正(本地已写入)
|
|
|
|
|
|
if (diff > 0)
|
|
|
|
|
|
GameManager.LogGoldFlowAppliedGain("SyncPlayerGold", $"已修正金币={gold} 修正前金币={oldGold} 增加金币=+{diff} 座位={panel.currSitData.posID}");
|
|
|
|
|
|
else if (diff < 0)
|
|
|
|
|
|
GameManager.LogGoldFlowAppliedCost("SyncPlayerGold", $"已修正金币={gold} 修正前金币={oldGold} 扣除金币={diff} 座位={panel.currSitData.posID}");
|
2026-07-29 00:31:59 +08:00
|
|
|
|
}
|
2026-03-09 09:25:01 +08:00
|
|
|
|
public static void GetRoomInfoResult(string msg)
|
|
|
|
|
|
{
|
|
|
|
|
|
//GameManager.Instance.StartGame();RoomChangeResponse
|
|
|
|
|
|
var roomData = JsonConvert.DeserializeObject<WebSocketResponseBase<RoomChangeResponse>>(msg).arguments[0];
|
2026-07-29 22:59:26 +08:00
|
|
|
|
// ⭐ 记录金币流水:收到加钱信息(RoomInfo 推送玩家金币,尚未执行)—— 只记录自己
|
2026-07-29 17:17:14 +08:00
|
|
|
|
if (roomData?.players != null)
|
|
|
|
|
|
{
|
2026-07-29 22:59:26 +08:00
|
|
|
|
string myId = GameManager.Instance.user?.id;
|
2026-07-29 17:17:14 +08:00
|
|
|
|
foreach (var p in roomData.players)
|
|
|
|
|
|
{
|
2026-07-29 22:59:26 +08:00
|
|
|
|
if (string.IsNullOrEmpty(myId) || p.userId != myId) continue;
|
|
|
|
|
|
GameManager.LogGoldFlowReceiveGain("RoomInfo", $"推送金币={p.gold} 钻石={p.diamond} 炮台消耗={p.cannonMultiple} 座位={p.position} 房间={roomData.roomId}");
|
2026-07-29 17:17:14 +08:00
|
|
|
|
}
|
|
|
|
|
|
}
|
2026-03-09 09:25:01 +08:00
|
|
|
|
UIHome_BY_SelectRoomLevelPanel.StartGame(roomData);
|
|
|
|
|
|
}
|
|
|
|
|
|
public static void SyncGameDataResult(string msg)
|
|
|
|
|
|
{
|
|
|
|
|
|
var syncGameData = JsonConvert.DeserializeObject<WebSocketResponseBase<SyncGameData>>(msg).arguments[0];
|
|
|
|
|
|
switch (syncGameData.frameType)
|
|
|
|
|
|
{
|
|
|
|
|
|
case FrameDataType.none:
|
|
|
|
|
|
break;
|
|
|
|
|
|
case FrameDataType.rotateTurrect:
|
|
|
|
|
|
EventCenter.Instance.EventTrigger<SyncGameData>(ConstEventString.SyncGameData_Rotate, syncGameData);
|
|
|
|
|
|
break;
|
|
|
|
|
|
case FrameDataType.fireBullet:
|
2026-07-02 18:28:50 +08:00
|
|
|
|
// 机器人角度同步:SyncFire_ForBot 发出的 SyncGameData(fireBullet)
|
|
|
|
|
|
// 与 RoomFireNotice(FireCannonSendData) 分开处理,仅用于存储角度到 botLastAngle
|
|
|
|
|
|
EventCenter.Instance.EventTrigger<SyncGameData>(ConstEventString.SyncGameData_BotFireAngle, syncGameData);
|
2026-03-09 09:25:01 +08:00
|
|
|
|
break;
|
2026-07-25 23:05:24 +08:00
|
|
|
|
// createFish=3 已废弃:鱼创建改由服务端 OnFishSpawn 事件下发
|
2026-03-18 17:26:14 +08:00
|
|
|
|
case FrameDataType.changeAutoTarget:
|
2026-03-09 09:25:01 +08:00
|
|
|
|
EventCenter.Instance.EventTrigger<SyncGameData>(ConstEventString.SyncGameData_ChangeTargetMonster, syncGameData);
|
2026-04-22 16:22:28 +08:00
|
|
|
|
break;
|
|
|
|
|
|
case FrameDataType.randomDieFish:
|
2026-04-22 18:15:22 +08:00
|
|
|
|
EventCenter.Instance.EventTrigger<SyncGameData>(ConstEventString.SyncGameData_RendromDieFish, syncGameData);
|
2026-03-09 09:25:01 +08:00
|
|
|
|
break;
|
2026-05-28 18:16:45 +08:00
|
|
|
|
case FrameDataType.freezeFish:
|
|
|
|
|
|
EventCenter.Instance.EventTrigger<SyncGameData>(ConstEventString.SyncGameData_FreezeFish, syncGameData);
|
2026-06-13 18:23:25 +08:00
|
|
|
|
break;
|
|
|
|
|
|
case FrameDataType.changeTurretState:
|
|
|
|
|
|
EventCenter.Instance.EventTrigger<SyncGameData>(ConstEventString.SyncGameData_TurretState, syncGameData);
|
|
|
|
|
|
|
2026-06-13 22:34:43 +08:00
|
|
|
|
break;
|
|
|
|
|
|
case FrameDataType.changeTurret:
|
|
|
|
|
|
EventCenter.Instance.EventTrigger<SyncGameData>(ConstEventString.SyncGameData_ChangeTurret, syncGameData);
|
2026-05-28 18:16:45 +08:00
|
|
|
|
break;
|
2026-06-19 18:18:04 +08:00
|
|
|
|
case FrameDataType.changeCannonMultiple:
|
|
|
|
|
|
EventCenter.Instance.EventTrigger<SyncGameData>(ConstEventString.SyncGameData_ChangeCannonMultiple, syncGameData);
|
|
|
|
|
|
break;
|
2026-06-30 01:31:53 +08:00
|
|
|
|
case FrameDataType.changeWing:
|
|
|
|
|
|
EventCenter.Instance.EventTrigger<SyncGameData>(ConstEventString.SyncGameData_ChangeWing, syncGameData);
|
|
|
|
|
|
break;
|
2026-08-28 22:33:35 +08:00
|
|
|
|
case FrameDataType.changeZhanShen:
|
|
|
|
|
|
EventCenter.Instance.EventTrigger<SyncGameData>(ConstEventString.SyncGameData_ChangeZhanShen, syncGameData);
|
|
|
|
|
|
break;
|
2026-09-04 23:38:33 +08:00
|
|
|
|
case FrameDataType.biaoQing:
|
|
|
|
|
|
EventCenter.Instance.EventTrigger<SyncGameData>(ConstEventString.SyncGameData_BiaoQing, syncGameData);
|
|
|
|
|
|
break;
|
2026-07-25 23:05:24 +08:00
|
|
|
|
// requestSyncFish=11 已废弃:鱼同步改由服务端 OnFishSpawn(type=sync) 下发
|
2026-07-30 22:09:55 +08:00
|
|
|
|
case FrameDataType.baoJiangEnd:
|
|
|
|
|
|
EventCenter.Instance.EventTrigger<SyncGameData>(ConstEventString.BaoJiangEnd, syncGameData);
|
|
|
|
|
|
break;
|
2026-03-09 09:25:01 +08:00
|
|
|
|
default:
|
|
|
|
|
|
break;
|
|
|
|
|
|
}
|
2026-02-03 11:35:19 +08:00
|
|
|
|
|
2026-03-09 09:25:01 +08:00
|
|
|
|
|
|
|
|
|
|
}
|
2026-07-25 23:05:24 +08:00
|
|
|
|
|
|
|
|
|
|
// ================================================================
|
|
|
|
|
|
// 新协议事件分发 (OnFishSpawn / PlayerAfk / FishFrozen / KillNotice 等)
|
|
|
|
|
|
// ================================================================
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 服务端出鱼事件 OnFishSpawn 处理。
|
|
|
|
|
|
/// 破坏性替代旧 createFish 帧同步:服务端统一出鱼,客户端只接收并生成。
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
public static void OnFishSpawn(string msg)
|
|
|
|
|
|
{
|
|
|
|
|
|
var data = JsonConvert.DeserializeObject<WebSocketResponseBase<OnFishSpawnData>>(msg).arguments[0];
|
|
|
|
|
|
if (data == null) return;
|
|
|
|
|
|
EventCenter.Instance.EventTrigger<OnFishSpawnData>(ConstEventString.OnFishSpawn, data);
|
2026-08-04 21:20:56 +08:00
|
|
|
|
NetLog.Log("出鱼:", msg);
|
2026-07-25 23:05:24 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>鱼列表刷新</summary>
|
|
|
|
|
|
public static void OnFishList(string msg)
|
|
|
|
|
|
{
|
|
|
|
|
|
var fishList = JsonConvert.DeserializeObject<WebSocketResponseBase<object[]>>(msg).arguments[0];
|
|
|
|
|
|
EventCenter.Instance.EventTrigger<object[]>(ConstEventString.OnFishList, fishList);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 冰冻道具(40003)生效事件 FishFrozen。
|
|
|
|
|
|
/// 鱼存活时间延长 15 秒,客户端写死 15s 倒计时。
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
public static void FishFrozen(string msg)
|
|
|
|
|
|
{
|
|
|
|
|
|
EventCenter.Instance.EventTrigger(ConstEventString.FishFrozen);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2026-09-10 01:07:35 +08:00
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// FishGameHub TorpedoResultNotice — 鱼雷使用结果(房间广播)。
|
|
|
|
|
|
/// 所有客户端都播爆奖流程(与 Boss 爆奖 RoomKillNotice 全端实例化同惯例):
|
|
|
|
|
|
/// 随机炸死场上小鱼 + 红包分包爆金币 + 分数面板 + 飞回使用者座位结算。
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
public static void TorpedoResultNotice(string msg)
|
|
|
|
|
|
{
|
|
|
|
|
|
var data = JsonConvert.DeserializeObject<WebSocketResponseBase<TorpedoResultNotice>>(msg).arguments[0];
|
|
|
|
|
|
Debug.Log($"[FishGameHub] 鱼雷结果: userId={data?.userId} prop={data?.propNumber} gold={data?.gold} color={data?.color}");
|
|
|
|
|
|
|
|
|
|
|
|
var panel = CreateFishManager.Instance.currGameType;
|
|
|
|
|
|
if (panel != null)
|
|
|
|
|
|
panel.OnTorpedoResult(data);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// FishGameHub ErrorMessage — 错误通知兜底
|
|
|
|
|
|
/// (鱼雷等新接口失败时推送:房间不存在/道具配置不存在/用户不存在;老接口走 Exception 错误码)。
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
public static void ErrorMessage(string msg)
|
|
|
|
|
|
{
|
|
|
|
|
|
var data = JsonConvert.DeserializeObject<WebSocketResponseBase<ErrorMessage>>(msg).arguments[0];
|
|
|
|
|
|
if (!string.IsNullOrEmpty(data?.message))
|
|
|
|
|
|
UIManager.Instance.ShowBoardError(data.message);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2026-07-25 23:05:24 +08:00
|
|
|
|
/// <summary>玩家挂机通知</summary>
|
|
|
|
|
|
public static void PlayerAfkNotice(string msg)
|
|
|
|
|
|
{
|
|
|
|
|
|
var data = JsonConvert.DeserializeObject<WebSocketResponseBase<PlayerAfkNoticeData>>(msg).arguments[0];
|
|
|
|
|
|
if (data == null) return;
|
|
|
|
|
|
EventCenter.Instance.EventTrigger<PlayerAfkNoticeData>(ConstEventString.PlayerAfkNotice, data);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>玩家取消挂机通知</summary>
|
|
|
|
|
|
public static void PlayerCancelAfkNotice(string msg)
|
|
|
|
|
|
{
|
|
|
|
|
|
var data = JsonConvert.DeserializeObject<WebSocketResponseBase<PlayerAfkNoticeData>>(msg).arguments[0];
|
|
|
|
|
|
if (data == null) return;
|
|
|
|
|
|
EventCenter.Instance.EventTrigger<PlayerAfkNoticeData>(ConstEventString.PlayerCancelAfkNotice, data);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 全局击杀公告 KillNotice。
|
|
|
|
|
|
/// 真人击杀/机器人模拟,机器人模拟时额外带 fishName/multiplier/sceneName。
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
public static void KillNotice(string msg)
|
|
|
|
|
|
{
|
|
|
|
|
|
var data = JsonConvert.DeserializeObject<WebSocketResponseBase<KillNoticeData>>(msg).arguments[0];
|
|
|
|
|
|
if (data == null) return;
|
|
|
|
|
|
EventCenter.Instance.EventTrigger<KillNoticeData>(ConstEventString.KillNotice, data);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>机器人退出房间通知</summary>
|
|
|
|
|
|
public static void BotLeaveRoomNotice(string msg)
|
|
|
|
|
|
{
|
|
|
|
|
|
var data = JsonConvert.DeserializeObject<WebSocketResponseBase<BotLeaveRoomNoticeData>>(msg).arguments[0];
|
|
|
|
|
|
if (data == null) return;
|
|
|
|
|
|
WebSocketReponseList.BotLeaveRoom(data.userId);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>房主断线</summary>
|
|
|
|
|
|
public static void HostDisconnectNotice(string msg)
|
|
|
|
|
|
{
|
|
|
|
|
|
EventCenter.Instance.EventTrigger(ConstEventString.HostDisconnect);
|
|
|
|
|
|
WebSocketReponseList.HostDisconnect();
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 座位变更 OnSeatChange。
|
|
|
|
|
|
/// 数据: { type, userId, position, showWaiting? }
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
public static void OnSeatChange(string msg)
|
|
|
|
|
|
{
|
|
|
|
|
|
var data = JsonConvert.DeserializeObject<WebSocketResponseBase<Dictionary<string, object>>>(msg).arguments[0];
|
|
|
|
|
|
if (data == null) return;
|
|
|
|
|
|
// JSON 字段可能是 long/double/string/bool 等任意类型,统一 ToString()+TryParse 容错
|
|
|
|
|
|
int seatType = data.TryGetValue("type", out var t) && int.TryParse(t?.ToString(), out var st) ? st : 0;
|
|
|
|
|
|
string userId = data.TryGetValue("userId", out var u) ? u?.ToString() : "";
|
|
|
|
|
|
int position = data.TryGetValue("position", out var p) && int.TryParse(p?.ToString(), out var pos) ? pos : -1;
|
|
|
|
|
|
bool showWaiting = data.TryGetValue("showWaiting", out var sw) && (sw is bool b ? b : (sw != null && bool.TryParse(sw.ToString(), out var bv) && bv));
|
|
|
|
|
|
WebSocketReponseList.SeatChange(seatType, userId, position, showWaiting);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 房主控制权移交 ChangeControllerUser。
|
|
|
|
|
|
/// 仅维护 SitPosData.roomOwnerSit,不再设置 fangzhu(鱼创建已由服务端统一出鱼)。
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
public static void ChangeControllerUser(string msg)
|
|
|
|
|
|
{
|
|
|
|
|
|
var userId = JsonConvert.DeserializeObject<WebSocketResponseBase<string>>(msg).arguments[0];
|
|
|
|
|
|
if (userId == GameManager.Instance.user.id)
|
|
|
|
|
|
{
|
|
|
|
|
|
// 本地玩家成为房主:同步本地房主引用
|
|
|
|
|
|
if (SitPosData.localPlayerSit != null)
|
|
|
|
|
|
SitPosData.roomOwnerSit = SitPosData.localPlayerSit;
|
|
|
|
|
|
}
|
|
|
|
|
|
else if (userId != null && userId.StartsWith("bot_"))
|
|
|
|
|
|
{
|
|
|
|
|
|
// 房主是人机:人机无法真正发包,由本地首个非人机玩家代行房主显示职责
|
|
|
|
|
|
SitPosData.TransferRoomOwner();
|
|
|
|
|
|
}
|
|
|
|
|
|
// 其他真人玩家成为房主时无需本地操作(roomOwnerSit 由 TransferRoomOwner/ShowPlayer 维护)
|
|
|
|
|
|
}
|
2026-03-09 09:25:01 +08:00
|
|
|
|
public static void LeaveRoomResult(string msg)
|
|
|
|
|
|
{
|
2026-03-18 17:26:14 +08:00
|
|
|
|
//WebSocketManager.Instance.isGame = false;
|
2026-06-26 19:28:39 +08:00
|
|
|
|
|
2026-03-09 09:25:01 +08:00
|
|
|
|
//GameManager.Instance.StartGame();RoomChangeResponse
|
2026-07-17 17:50:31 +08:00
|
|
|
|
var response = JsonConvert.DeserializeObject<WebSocketResponseBase<string>>(msg);
|
|
|
|
|
|
// ⭐ 数据保护:arguments 为空直接返回,避免抛异常
|
|
|
|
|
|
if (response?.arguments == null || response.arguments.Count == 0)
|
|
|
|
|
|
{
|
|
|
|
|
|
#if UNITY_EDITOR
|
|
|
|
|
|
Debug.LogWarning("[LeaveRoomResult] arguments 为空,忽略");
|
|
|
|
|
|
#endif
|
|
|
|
|
|
return;
|
|
|
|
|
|
}
|
|
|
|
|
|
var userid = response.arguments[0];
|
2026-03-18 17:26:14 +08:00
|
|
|
|
switch (GameManager.Instance.gameData.currGameType)
|
2026-03-09 09:25:01 +08:00
|
|
|
|
{
|
2026-03-18 17:26:14 +08:00
|
|
|
|
case GameType.JQQD:
|
|
|
|
|
|
break;
|
|
|
|
|
|
case GameType.defaultPanel:
|
|
|
|
|
|
break;
|
|
|
|
|
|
case GameType.FLZY:
|
|
|
|
|
|
{
|
|
|
|
|
|
var panel = UIManager.Instance.Get<GameMainPanel_FLZY>(UIPanel.MainGamePanelFLZY);
|
2026-07-17 17:50:31 +08:00
|
|
|
|
if (panel == null || panel.currSitData == null) break;
|
2026-06-26 19:28:39 +08:00
|
|
|
|
if (panel.currSitData.user == userid)
|
2026-05-01 06:26:50 +08:00
|
|
|
|
{
|
2026-07-18 18:16:35 +08:00
|
|
|
|
ExitFishingGame(UIPanel.MainGamePanelFLZY);
|
2026-05-01 06:26:50 +08:00
|
|
|
|
break;
|
|
|
|
|
|
}
|
2026-03-18 17:26:14 +08:00
|
|
|
|
foreach (var item in panel.list_Sits)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (item.user == userid)
|
|
|
|
|
|
{
|
2026-07-02 18:28:50 +08:00
|
|
|
|
item.ShowWaiting();
|
2026-03-18 17:26:14 +08:00
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
2026-06-26 19:28:39 +08:00
|
|
|
|
|
2026-03-18 17:26:14 +08:00
|
|
|
|
break;
|
2026-05-07 03:46:03 +08:00
|
|
|
|
case GameType.YYSC:
|
|
|
|
|
|
{
|
|
|
|
|
|
var panel = UIManager.Instance.Get<GameMainPanel_YYSC>(UIPanel.MainGamePanelYYSC);
|
2026-07-17 17:50:31 +08:00
|
|
|
|
if (panel == null || panel.currSitData == null) break;
|
2026-05-07 03:46:03 +08:00
|
|
|
|
if (panel.currSitData.user == userid)
|
|
|
|
|
|
{
|
2026-07-18 18:16:35 +08:00
|
|
|
|
ExitFishingGame(UIPanel.MainGamePanelYYSC);
|
2026-05-07 03:46:03 +08:00
|
|
|
|
break;
|
|
|
|
|
|
}
|
|
|
|
|
|
foreach (var item in panel.list_Sits)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (item.user == userid)
|
|
|
|
|
|
{
|
2026-07-02 18:28:50 +08:00
|
|
|
|
item.ShowWaiting();
|
2026-05-07 03:46:03 +08:00
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
2026-03-18 17:26:14 +08:00
|
|
|
|
break;
|
|
|
|
|
|
case GameType.ZGXQ:
|
2026-06-26 19:28:39 +08:00
|
|
|
|
|
2026-03-18 17:26:14 +08:00
|
|
|
|
break;
|
|
|
|
|
|
case GameType.XJMH:
|
|
|
|
|
|
{
|
|
|
|
|
|
var panel = UIManager.Instance.Get<GameMainPanel_XJMH>(UIPanel.MainGamePanelXJMH);
|
2026-07-17 17:50:31 +08:00
|
|
|
|
if (panel == null || panel.currSitData == null) break;
|
2026-05-01 06:26:50 +08:00
|
|
|
|
if (panel.currSitData.user == userid)
|
|
|
|
|
|
{
|
2026-07-18 18:16:35 +08:00
|
|
|
|
ExitFishingGame(UIPanel.MainGamePanelXJMH);
|
2026-05-01 06:26:50 +08:00
|
|
|
|
break;
|
|
|
|
|
|
}
|
2026-03-18 17:26:14 +08:00
|
|
|
|
foreach (var item in panel.list_Sits)
|
|
|
|
|
|
{
|
2026-06-26 19:28:39 +08:00
|
|
|
|
Debug.Log(item.user + "---" + userid);
|
2026-03-18 17:26:14 +08:00
|
|
|
|
if (item.user == userid)
|
|
|
|
|
|
{
|
|
|
|
|
|
Debug.Log("推出星际迷航");
|
2026-07-02 18:28:50 +08:00
|
|
|
|
item.ShowWaiting();
|
2026-03-18 17:26:14 +08:00
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
break;
|
|
|
|
|
|
case GameType.HHWK:
|
|
|
|
|
|
{
|
|
|
|
|
|
var panel = UIManager.Instance.Get<GameMainPanel_HHWK>(UIPanel.MainGamePanelHHWK);
|
2026-07-17 17:50:31 +08:00
|
|
|
|
if (panel == null || panel.currSitData == null) break;
|
2026-05-01 06:26:50 +08:00
|
|
|
|
if (panel.currSitData.user == userid)
|
|
|
|
|
|
{
|
2026-07-18 18:16:35 +08:00
|
|
|
|
ExitFishingGame(UIPanel.MainGamePanelHHWK);
|
2026-05-01 06:26:50 +08:00
|
|
|
|
break;
|
|
|
|
|
|
}
|
2026-03-18 17:26:14 +08:00
|
|
|
|
foreach (var item in panel.list_Sits)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (item.user == userid)
|
|
|
|
|
|
{
|
2026-07-02 18:28:50 +08:00
|
|
|
|
item.ShowWaiting();
|
2026-03-18 17:26:14 +08:00
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
break;
|
|
|
|
|
|
default:
|
|
|
|
|
|
break;
|
2026-03-09 09:25:01 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
2026-03-18 17:26:14 +08:00
|
|
|
|
|
2026-03-09 09:25:01 +08:00
|
|
|
|
}
|
2026-04-15 18:30:37 +08:00
|
|
|
|
|
2026-07-18 18:16:35 +08:00
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 统一退出捕鱼游戏流程:
|
|
|
|
|
|
/// 1. 关闭 game socket(自己的离房通知已收到,可以正常关闭)
|
|
|
|
|
|
/// 2. 拉取最新用户数据并触发 OnUserDataChanged 事件,同步大厅金币/钻石/等级等 UI
|
2026-07-30 01:06:55 +08:00
|
|
|
|
/// 3. 通知游戏面板 socket 已返回 → 解除进度条 0.9 的等待 → 走完剩余进度后自动切回 home
|
2026-07-18 18:16:35 +08:00
|
|
|
|
/// </summary>
|
|
|
|
|
|
private static void ExitFishingGame(UIPanel gamePanel)
|
|
|
|
|
|
{
|
|
|
|
|
|
// 标记游戏已结束
|
|
|
|
|
|
WebSocketManager.Instance.isGame = false;
|
2026-07-29 17:17:14 +08:00
|
|
|
|
// ⭐ 记录金币流水:退出房间
|
|
|
|
|
|
GameManager.LogGoldFlow("ExitRoom", $"退出房间 房间={GameManager.Instance.gameData?.currRoomData?.roomId}");
|
2026-07-18 18:16:35 +08:00
|
|
|
|
// 关闭游戏连接
|
|
|
|
|
|
WebSocketManager.Instance.Close(SocketType.game);
|
|
|
|
|
|
// 拉取最新用户数据,触发 UI 同步更新(金币/钻石/等级/VIP等)
|
|
|
|
|
|
APIRequestList.GetUser((user) =>
|
|
|
|
|
|
{
|
|
|
|
|
|
GameManager.Instance.UpdataUserData(user);
|
|
|
|
|
|
});
|
2026-07-25 02:17:19 +08:00
|
|
|
|
|
2026-07-30 01:06:55 +08:00
|
|
|
|
// ⭐ 通知面板 socket 已返回 → 进度条从 0.9 走到 1.0 → 切回 home
|
2026-07-25 02:17:19 +08:00
|
|
|
|
var panel = UIManager.Instance.Get<GameMainPanel_FishBase>(gamePanel);
|
|
|
|
|
|
if (panel != null)
|
|
|
|
|
|
{
|
2026-07-30 01:06:55 +08:00
|
|
|
|
panel.OnLeaveRoomResultReceived(gamePanel);
|
2026-07-25 02:17:19 +08:00
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
|
|
|
|
|
// 兜底:拿不到面板直接切换
|
|
|
|
|
|
UIManager.Instance.ShowAsync(UIPanel.HomeMainPanel, gamePanel);
|
|
|
|
|
|
}
|
2026-07-18 18:16:35 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
2026-06-26 19:28:39 +08:00
|
|
|
|
// ---------------- LoginHub ----------------
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// LoginHub Broadcast — 大厅公告广播
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
public static void LoginBroadcast(string msg)
|
|
|
|
|
|
{
|
|
|
|
|
|
var data = JsonConvert.DeserializeObject<WebSocketResponseBase<LoginBroadcastData>>(msg).arguments[0];
|
|
|
|
|
|
UIManager.Instance.ShowBoardGongGao(data.message);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// LoginHub AssetUpdated — 资产变动通知
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
public static void AssetUpdated(string msg)
|
|
|
|
|
|
{
|
|
|
|
|
|
var data = JsonConvert.DeserializeObject<WebSocketResponseBase<LoginAssetData>>(msg).arguments[0];
|
|
|
|
|
|
// 触发用户数据刷新
|
|
|
|
|
|
var userId = GameManager.Instance?.user?.id;
|
|
|
|
|
|
if (!string.IsNullOrEmpty(userId))
|
|
|
|
|
|
APIRequestList.GetUser(userId, a => GameManager.Instance.UpdataUserData(a));
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// LoginHub BackpackUpdated — 背包变动通知
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
public static void BackpackUpdated(string msg)
|
|
|
|
|
|
{
|
|
|
|
|
|
var data = JsonConvert.DeserializeObject<WebSocketResponseBase<LoginBackpackData>>(msg).arguments[0];
|
|
|
|
|
|
// 刷新用户数据(道具列表在 GetUser 返回中)
|
|
|
|
|
|
var userId = GameManager.Instance?.user?.id;
|
|
|
|
|
|
if (!string.IsNullOrEmpty(userId))
|
|
|
|
|
|
APIRequestList.GetUser(userId, a => GameManager.Instance.UpdataUserData(a));
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// LoginHub NewEmail — 新邮件通知
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
public static void NewEmail(string msg)
|
|
|
|
|
|
{
|
|
|
|
|
|
var data = JsonConvert.DeserializeObject<WebSocketResponseBase<LoginNewEmailData>>(msg).arguments[0];
|
|
|
|
|
|
UIManager.Instance.ShowBoardError($"收到新邮件:{data.title}");
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2026-07-10 23:26:42 +08:00
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// LoginHub KillAnnouncement — 全局击杀公告(特殊 Boss 击杀全服推送)
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
public static void KillAnnouncement(string msg)
|
|
|
|
|
|
{
|
|
|
|
|
|
var data = JsonConvert.DeserializeObject<WebSocketResponseBase<KillAnnouncementData>>(msg).arguments[0];
|
|
|
|
|
|
// 服务端已拼好 text(格式:恭喜玩家*****在风雷之渊 高级场捕获 人鱼公主*2000倍 150000000大奖)
|
|
|
|
|
|
if (data != null && !string.IsNullOrEmpty(data.text))
|
|
|
|
|
|
UIManager.Instance.ShowBoardGongGao(data.text);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2026-07-21 04:36:52 +08:00
|
|
|
|
/// <summary>
|
2026-07-22 15:01:41 +08:00
|
|
|
|
/// LoginHub LevelChanged — 后台修改玩家等级
|
2026-07-21 04:36:52 +08:00
|
|
|
|
/// 直接调用 GetUser 刷新用户数据,触发 OnUserDataChanged 同步 UI
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
public static void LevelChanged(string msg)
|
|
|
|
|
|
{
|
|
|
|
|
|
var data = JsonConvert.DeserializeObject<WebSocketResponseBase<LevelChangedData>>(msg).arguments[0];
|
|
|
|
|
|
var userId = GameManager.Instance?.user?.id;
|
|
|
|
|
|
if (!string.IsNullOrEmpty(userId))
|
|
|
|
|
|
APIRequestList.GetUser(userId, a => GameManager.Instance.UpdataUserData(a));
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2026-07-22 15:01:41 +08:00
|
|
|
|
// ---------------- LoginHub 断线房间 ----------------
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>当前是否有待处理的断线房间弹窗(防止重复弹)</summary>
|
|
|
|
|
|
private static bool _pendingRoomActive;
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// LoginHub PendingRoomNotice — 登录后检测到有未完成的断线游戏
|
|
|
|
|
|
/// 弹窗提示用户选择"返回房间"(调 Reconnect)或"离开"(调 DismissPendingRoom)
|
|
|
|
|
|
/// 60 秒无操作自动离开
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
public static void PendingRoomNotice(string msg)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (_pendingRoomActive) return; // 防重复
|
|
|
|
|
|
var data = JsonConvert.DeserializeObject<WebSocketResponseBase<PendingRoomData>>(msg).arguments[0];
|
|
|
|
|
|
if (data == null) return;
|
|
|
|
|
|
|
|
|
|
|
|
_pendingRoomActive = true;
|
|
|
|
|
|
var userId = GameManager.Instance?.user?.id;
|
|
|
|
|
|
if (string.IsNullOrEmpty(userId)) return;
|
|
|
|
|
|
|
|
|
|
|
|
// 创建 TiShi 弹窗(直接 Instantiate 拿引用,方便 60 秒后销毁)
|
|
|
|
|
|
var prefab = UIManager.Instance.TiShiParefab;
|
|
|
|
|
|
if (prefab == null)
|
|
|
|
|
|
{
|
|
|
|
|
|
Debug.LogWarning("[PendingRoomNotice] TiShiParefab 未赋值,自动离开");
|
|
|
|
|
|
WebSocketSendList.DismissPendingRoom(userId);
|
|
|
|
|
|
_pendingRoomActive = false;
|
|
|
|
|
|
return;
|
|
|
|
|
|
}
|
|
|
|
|
|
var obj = UnityEngine.Object.Instantiate(prefab, UIManager.Instance.uiRoot);
|
|
|
|
|
|
obj.transform.SetAsLastSibling();
|
|
|
|
|
|
var tishi = obj.GetComponent<TiShi>();
|
|
|
|
|
|
if (tishi == null)
|
|
|
|
|
|
{
|
|
|
|
|
|
UnityEngine.Object.Destroy(obj);
|
|
|
|
|
|
_pendingRoomActive = false;
|
|
|
|
|
|
return;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 标记用户是否已操作
|
|
|
|
|
|
bool acted = false;
|
|
|
|
|
|
|
|
|
|
|
|
// 确认 = 返回房间
|
|
|
|
|
|
tishi.Init($"检测到您在 {data.gameType} {data.roomName} 有未完成的游戏,是否返回房间?", () =>
|
|
|
|
|
|
{
|
|
|
|
|
|
acted = true;
|
|
|
|
|
|
WebSocketSendList.Reconnect(userId);
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
// 关闭 = 离开(额外给 btn_Close 加监听;TiShi.Close 本身只销毁不触发 action)
|
|
|
|
|
|
if (tishi.btn_Close != null)
|
|
|
|
|
|
{
|
|
|
|
|
|
tishi.btn_Close.onClick.AddListener(() =>
|
|
|
|
|
|
{
|
|
|
|
|
|
if (acted) return;
|
|
|
|
|
|
acted = true;
|
|
|
|
|
|
WebSocketSendList.DismissPendingRoom(userId);
|
|
|
|
|
|
});
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 60 秒无操作自动离开
|
|
|
|
|
|
WebSocketManager.Instance.StartCoroutine(PendingRoomCountdown(
|
|
|
|
|
|
60f, () => acted, () =>
|
|
|
|
|
|
{
|
|
|
|
|
|
acted = true;
|
|
|
|
|
|
WebSocketSendList.DismissPendingRoom(userId);
|
|
|
|
|
|
if (obj != null) UnityEngine.Object.Destroy(obj);
|
|
|
|
|
|
_pendingRoomActive = false;
|
|
|
|
|
|
}));
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>断线房间弹窗倒计时协程(到时检查是否已操作,未操作则触发回调)</summary>
|
|
|
|
|
|
private static System.Collections.IEnumerator PendingRoomCountdown(
|
|
|
|
|
|
float seconds, System.Func<bool> hasActed, System.Action onTimeout)
|
|
|
|
|
|
{
|
|
|
|
|
|
yield return new UnityEngine.WaitForSeconds(seconds);
|
|
|
|
|
|
if (!hasActed())
|
|
|
|
|
|
onTimeout?.Invoke();
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// LoginHub PendingRoomNotice 数据
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
[Serializable]
|
|
|
|
|
|
public class PendingRoomData
|
|
|
|
|
|
{
|
|
|
|
|
|
public string roomId;
|
|
|
|
|
|
public string gameType;
|
|
|
|
|
|
public string roomName;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// LoginHub AccountKicked — 账号被顶通知
|
|
|
|
|
|
/// 该账号在其他设备登录时,旧连接收到此事件。
|
|
|
|
|
|
/// 前端应提示"账号已在其他地方登录"并清空房间 UI、断开游戏连接。
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
public static void AccountKicked(string msg)
|
|
|
|
|
|
{
|
|
|
|
|
|
try
|
|
|
|
|
|
{
|
|
|
|
|
|
var data = JsonConvert.DeserializeObject<WebSocketResponseBase<AccountKickedData>>(msg).arguments[0];
|
|
|
|
|
|
var userId = GameManager.Instance?.user?.id;
|
|
|
|
|
|
// 只处理当前登录用户被顶的情况
|
|
|
|
|
|
if (data != null && !string.IsNullOrEmpty(data.userId)
|
2026-07-26 22:00:38 +08:00
|
|
|
|
&& !string.IsNullOrEmpty(userId) && data.userId == userId)
|
2026-07-24 23:47:50 +08:00
|
|
|
|
{
|
|
|
|
|
|
UIManager.Instance.ShowTiShi("账号已在其他地方登录", () =>
|
|
|
|
|
|
{
|
|
|
|
|
|
GameManager.Instance.Logout();
|
|
|
|
|
|
return;
|
2026-07-28 15:00:26 +08:00
|
|
|
|
}, showClose: false);
|
2026-07-24 23:47:50 +08:00
|
|
|
|
}
|
2026-07-22 15:01:41 +08:00
|
|
|
|
}
|
|
|
|
|
|
catch (Exception e)
|
|
|
|
|
|
{
|
|
|
|
|
|
Debug.LogWarning("[AccountKicked] 解析失败: " + e.Message);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// LoginHub AccountKicked 数据
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
[Serializable]
|
|
|
|
|
|
public class AccountKickedData
|
|
|
|
|
|
{
|
|
|
|
|
|
public string userId;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2026-07-27 23:30:25 +08:00
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// LoginHub ChangeConfig — 后台活动配置或游戏配置保存发布后广播
|
|
|
|
|
|
/// changeType: 1=活动配置更新 2=游戏配置更新
|
|
|
|
|
|
/// 前端按 changeType 重新请求对应配置
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
public static void ChangeConfig(string msg)
|
|
|
|
|
|
{
|
|
|
|
|
|
try
|
|
|
|
|
|
{
|
|
|
|
|
|
var changeType = JsonConvert.DeserializeObject<WebSocketResponseBase<int>>(msg).arguments[0];
|
|
|
|
|
|
switch (changeType)
|
|
|
|
|
|
{
|
|
|
|
|
|
case 1:
|
|
|
|
|
|
// 活动配置更新
|
|
|
|
|
|
APIRequestList.GetActivityConfig(res =>
|
|
|
|
|
|
{
|
|
|
|
|
|
if (res != null) GameManager.Instance.activityConfig = res;
|
|
|
|
|
|
});
|
|
|
|
|
|
break;
|
|
|
|
|
|
case 2:
|
|
|
|
|
|
// 游戏配置更新
|
|
|
|
|
|
APIManager.Response<GameConfig>(APIType.GameConfig_Get, res =>
|
|
|
|
|
|
{
|
|
|
|
|
|
if (res != null)
|
|
|
|
|
|
{
|
|
|
|
|
|
GameManager.Instance.gameConfig = res;
|
|
|
|
|
|
var v = GameManager.Instance.dic_fishTypeConfigs;
|
|
|
|
|
|
if (v != null)
|
|
|
|
|
|
{
|
|
|
|
|
|
v.Clear();
|
|
|
|
|
|
foreach (var item in res.fishTypeConfigs)
|
|
|
|
|
|
v[item.fishNumber] = item;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
});
|
|
|
|
|
|
break;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
catch (Exception e)
|
|
|
|
|
|
{
|
|
|
|
|
|
Debug.LogWarning("[ChangeConfig] 解析失败: " + e.Message);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// LoginHub KickToMainPage — 强制退出到主页面
|
|
|
|
|
|
/// 当前账号连接已失效(被顶号/用户不匹配),前端应立即清除所有游戏 UI 并导航到主页面/登录页
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
public static void KickToMainPage(string msg)
|
|
|
|
|
|
{
|
|
|
|
|
|
try
|
|
|
|
|
|
{
|
|
|
|
|
|
var data = JsonConvert.DeserializeObject<WebSocketResponseBase<KickToMainPageData>>(msg).arguments[0];
|
|
|
|
|
|
var userId = GameManager.Instance?.user?.id;
|
|
|
|
|
|
// 只处理当前登录用户被踢的情况
|
|
|
|
|
|
if (data != null && !string.IsNullOrEmpty(data.userId)
|
|
|
|
|
|
&& !string.IsNullOrEmpty(userId) && data.userId != userId)
|
|
|
|
|
|
return;
|
|
|
|
|
|
}
|
|
|
|
|
|
catch (Exception e)
|
|
|
|
|
|
{
|
|
|
|
|
|
Debug.LogWarning("[KickToMainPage] 解析失败: " + e.Message);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
UIManager.Instance.ShowTiShi("连接已失效,请重新登录", () =>
|
|
|
|
|
|
{
|
|
|
|
|
|
GameManager.Instance.Logout();
|
2026-07-28 15:00:26 +08:00
|
|
|
|
}, showClose: false);
|
2026-07-27 23:30:25 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// LoginHub KickToMainPage 数据
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
[Serializable]
|
|
|
|
|
|
public class KickToMainPageData
|
|
|
|
|
|
{
|
|
|
|
|
|
public string userId;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2026-07-21 04:36:52 +08:00
|
|
|
|
// ---------------- FishGameHub 补充 ----------------
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
2026-07-22 15:01:41 +08:00
|
|
|
|
/// FishGameHub BotLeaveRoomNotice — 机器人退出房间
|
2026-07-21 04:36:52 +08:00
|
|
|
|
/// 仅触发对应座位显示等待,不影响本地玩家(自己退出走 LeaveRoomResult)
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
public static void BotLeaveRoom(string botUserId)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (string.IsNullOrEmpty(botUserId)) return;
|
|
|
|
|
|
switch (GameManager.Instance.gameData.currGameType)
|
|
|
|
|
|
{
|
|
|
|
|
|
case GameType.FLZY:
|
|
|
|
|
|
ReleaseBotSit(UIPanel.MainGamePanelFLZY, botUserId);
|
|
|
|
|
|
break;
|
|
|
|
|
|
case GameType.YYSC:
|
|
|
|
|
|
ReleaseBotSit(UIPanel.MainGamePanelYYSC, botUserId);
|
|
|
|
|
|
break;
|
|
|
|
|
|
case GameType.XJMH:
|
|
|
|
|
|
ReleaseBotSit(UIPanel.MainGamePanelXJMH, botUserId);
|
|
|
|
|
|
break;
|
|
|
|
|
|
case GameType.HHWK:
|
|
|
|
|
|
ReleaseBotSit(UIPanel.MainGamePanelHHWK, botUserId);
|
|
|
|
|
|
break;
|
|
|
|
|
|
default:
|
|
|
|
|
|
break;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>释放机器人座位(显示等待界面,标记为 bot)</summary>
|
|
|
|
|
|
private static void ReleaseBotSit(UIPanel panelName, string botUserId)
|
|
|
|
|
|
{
|
|
|
|
|
|
var panel = UIManager.Instance.Get<GameMainPanel_FishBase>(panelName);
|
|
|
|
|
|
if (panel == null) return;
|
|
|
|
|
|
foreach (var sit in panel.list_Sits)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (sit.user == botUserId)
|
|
|
|
|
|
{
|
|
|
|
|
|
sit.isBot = true;
|
|
|
|
|
|
sit.ShowWaiting();
|
|
|
|
|
|
break;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
2026-07-22 15:01:41 +08:00
|
|
|
|
/// FishGameHub HostDisconnect — 房主断线
|
2026-07-21 04:36:52 +08:00
|
|
|
|
/// 其他玩家可接受机器人控制权。本地房主引用若已断线则转移给本地首个非人机玩家。
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
public static void HostDisconnect()
|
|
|
|
|
|
{
|
|
|
|
|
|
// 房主断线 → 触发房主转移(SitPosData 已封装好转移逻辑)
|
|
|
|
|
|
SitPosData.TransferRoomOwner();
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// FishGameHub OnSeatChange — 座位变更
|
|
|
|
|
|
/// { type, userId, position, showWaiting? }
|
|
|
|
|
|
/// type 字段后端未明确定义,先按 showWaiting 决定显示状态
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
public static void SeatChange(int seatType, string userId, int position, bool showWaiting)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (string.IsNullOrEmpty(userId) || position < 0) return;
|
|
|
|
|
|
|
|
|
|
|
|
GameMainPanel_FishBase panel = null;
|
|
|
|
|
|
switch (GameManager.Instance.gameData.currGameType)
|
|
|
|
|
|
{
|
|
|
|
|
|
case GameType.FLZY:
|
|
|
|
|
|
panel = UIManager.Instance.Get<GameMainPanel_FishBase>(UIPanel.MainGamePanelFLZY);
|
|
|
|
|
|
break;
|
|
|
|
|
|
case GameType.YYSC:
|
|
|
|
|
|
panel = UIManager.Instance.Get<GameMainPanel_FishBase>(UIPanel.MainGamePanelYYSC);
|
|
|
|
|
|
break;
|
|
|
|
|
|
case GameType.XJMH:
|
|
|
|
|
|
panel = UIManager.Instance.Get<GameMainPanel_FishBase>(UIPanel.MainGamePanelXJMH);
|
|
|
|
|
|
break;
|
|
|
|
|
|
case GameType.HHWK:
|
|
|
|
|
|
panel = UIManager.Instance.Get<GameMainPanel_FishBase>(UIPanel.MainGamePanelHHWK);
|
|
|
|
|
|
break;
|
|
|
|
|
|
default:
|
|
|
|
|
|
break;
|
|
|
|
|
|
}
|
|
|
|
|
|
if (panel == null) return;
|
|
|
|
|
|
|
|
|
|
|
|
var targetSit = panel.list_Sits.Find(s => s.posID == position);
|
|
|
|
|
|
if (targetSit == null) return;
|
|
|
|
|
|
|
|
|
|
|
|
if (showWaiting)
|
|
|
|
|
|
{
|
|
|
|
|
|
// 显示等待界面(玩家离开该座位)
|
|
|
|
|
|
targetSit.ShowWaiting();
|
|
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
|
|
|
|
|
// 玩家进入该座位
|
|
|
|
|
|
targetSit.isBot = !string.IsNullOrEmpty(userId) && userId.StartsWith("bot_");
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// FishRoomHub RoomChange — 房间变化通知
|
|
|
|
|
|
/// 房间列表界面收到时刷新显示。当前仅在房间列表 UI 开启时更新数据,
|
|
|
|
|
|
/// 具体刷新逻辑由 UIHome_BY_SelectRoomLevelPanel / 手动选座面板按需实现。
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
public static void RoomChangeNotice(string msg)
|
|
|
|
|
|
{
|
|
|
|
|
|
try
|
|
|
|
|
|
{
|
|
|
|
|
|
var roomData = JsonConvert.DeserializeObject<WebSocketResponseBase<RoomChangeResponse>>(msg).arguments[0];
|
|
|
|
|
|
if (roomData == null) return;
|
|
|
|
|
|
// 通知手动选座面板刷新(若开启)
|
|
|
|
|
|
var homeMain = UIManager.Instance.Get<UIHomeMain>(UIPanel.HomeMainPanel);
|
|
|
|
|
|
if (homeMain == null) return;
|
|
|
|
|
|
var selectRoomPanel = homeMain.subUIManager.Get<UIHome_BY_SelectRoomLevelPanel>(UIPanel.SelectRoomLeavePenel);
|
|
|
|
|
|
if (selectRoomPanel != null && selectRoomPanel.isMySelectRoom)
|
|
|
|
|
|
{
|
|
|
|
|
|
selectRoomPanel.panel_UIHome_BY_MySelectRoomPenel?.OnRoomChange(roomData);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
catch (Exception e)
|
|
|
|
|
|
{
|
|
|
|
|
|
Debug.LogWarning("[RoomChangeNotice] 解析失败: " + e.Message);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
2026-07-22 15:01:41 +08:00
|
|
|
|
/// LoginHub LevelChanged 数据(字段名对齐后端大写首字母)
|
2026-07-21 04:36:52 +08:00
|
|
|
|
/// </summary>
|
|
|
|
|
|
[Serializable]
|
|
|
|
|
|
public class LevelChangedData
|
|
|
|
|
|
{
|
2026-07-22 15:01:41 +08:00
|
|
|
|
public int NewLevel;
|
|
|
|
|
|
public long NewExp;
|
|
|
|
|
|
public long NewGold;
|
|
|
|
|
|
public int NewDiamond;
|
|
|
|
|
|
public string Source;
|
|
|
|
|
|
public string Remark;
|
2026-07-21 04:36:52 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
2026-04-15 18:30:37 +08:00
|
|
|
|
// ---------------- Customer ----------------
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 发起会话回调(用户端)
|
|
|
|
|
|
/// isOk=false 时弹错误提示;isOk=true 时自动加入会话房间
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
public static void Customer_OnConversationStarted(CustomerConversationStartedResult result)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (!result.isOk)
|
|
|
|
|
|
{
|
|
|
|
|
|
UIManager.Instance.ShowBoardError(result.msg);
|
|
|
|
|
|
return;
|
|
|
|
|
|
}
|
|
|
|
|
|
// 加入会话房间,之后才能收发消息
|
|
|
|
|
|
//WebSocketSendList.Customer_JoinConversation(result.conversation.id);
|
2026-08-09 17:57:46 +08:00
|
|
|
|
GetActiveServicePanel()?.OnConversationStarted(result);
|
2026-04-15 18:30:37 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 消息接收回调(用户端 & 客服端)
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
public static void Customer_OnMessageReceived(CustomerMessageReceived msg)
|
|
|
|
|
|
{
|
2026-08-09 17:57:46 +08:00
|
|
|
|
GetActiveServicePanel()?.OnMessageReceived(msg);
|
2026-04-15 18:30:37 +08:00
|
|
|
|
Debug.Log($"[Customer] 收到消息 from {msg.senderName}({msg.senderType}): {msg.content}");
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2026-08-09 17:57:46 +08:00
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 获取当前活动的客服面板(主界面或登录界面打开的)
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
private static UIHome_BY_ServicePanel GetActiveServicePanel()
|
|
|
|
|
|
{
|
|
|
|
|
|
// 先尝试主界面
|
|
|
|
|
|
var home = UIManager.Instance.Get<UIHomeMain>(UIPanel.HomeMainPanel);
|
|
|
|
|
|
if (home != null && home.subUIManager != null)
|
|
|
|
|
|
{
|
|
|
|
|
|
var panel = home.subUIManager.Get<UIHome_BY_ServicePanel>(UIPanel.ServicePanel);
|
|
|
|
|
|
if (panel != null) return panel;
|
|
|
|
|
|
}
|
|
|
|
|
|
// 再尝试登录界面(游客模式)
|
|
|
|
|
|
var login = UIManager.Instance.Get<UILoginPanel>(UIPanel.LoginPanel);
|
|
|
|
|
|
if (login != null && login.uIManager != null)
|
|
|
|
|
|
{
|
|
|
|
|
|
return login.uIManager.Get<UIHome_BY_ServicePanel>(UIPanel.ServicePanel);
|
|
|
|
|
|
}
|
|
|
|
|
|
return null;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2026-04-15 18:30:37 +08:00
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 新会话通知(客服端)
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
public static void Customer_OnNewConversation(CustomerNewConversationNotice notice)
|
|
|
|
|
|
{
|
|
|
|
|
|
// 客服端自动加入会话房间
|
|
|
|
|
|
WebSocketSendList.Customer_JoinConversation(notice.conversationId);
|
|
|
|
|
|
// TODO: 通知客服端 UI 显示新会话(替换为你的实际 Panel 调用)
|
|
|
|
|
|
// UIManager.Instance.Get<UICustomerServicePanel>(UIPanel.CustomerServicePanel)?.OnNewConversation(notice);
|
|
|
|
|
|
Debug.Log($"[Customer] 新会话来了,userId={notice.userId},userName={notice.userName}");
|
|
|
|
|
|
}
|
2026-06-26 19:28:39 +08:00
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// LoginHub Broadcast 数据
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
[Serializable]
|
|
|
|
|
|
public class LoginBroadcastData
|
|
|
|
|
|
{
|
|
|
|
|
|
public string userName;
|
|
|
|
|
|
public string avatarUrl;
|
|
|
|
|
|
public int level;
|
|
|
|
|
|
public int vipLevel;
|
|
|
|
|
|
public string message;
|
|
|
|
|
|
public long time;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2026-07-10 23:26:42 +08:00
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// LoginHub KillAnnouncement 数据(全局击杀公告)
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
[Serializable]
|
|
|
|
|
|
public class KillAnnouncementData
|
|
|
|
|
|
{
|
|
|
|
|
|
/// <summary>公告文本(服务端已拼接:恭喜玩家*****在风雷之渊 高级场捕获 人鱼公主*2000倍 150000000大奖)</summary>
|
|
|
|
|
|
public string text;
|
|
|
|
|
|
/// <summary>玩家名(已脱敏,全部替换为*)</summary>
|
|
|
|
|
|
public string userName;
|
|
|
|
|
|
/// <summary>游戏类型名(如:风雷之渊)</summary>
|
|
|
|
|
|
public string gameTypeName;
|
|
|
|
|
|
/// <summary>房间名(如:高级场)</summary>
|
|
|
|
|
|
public string roomName;
|
|
|
|
|
|
/// <summary>鱼名称(如:人鱼公主)</summary>
|
|
|
|
|
|
public string fishName;
|
|
|
|
|
|
/// <summary>炮台倍数</summary>
|
|
|
|
|
|
public int multiple;
|
|
|
|
|
|
/// <summary>获得金币</summary>
|
|
|
|
|
|
public long gold;
|
|
|
|
|
|
/// <summary>时间戳(Unix秒)</summary>
|
|
|
|
|
|
public long time;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2026-06-26 19:28:39 +08:00
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// LoginHub AssetUpdated 数据
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
[Serializable]
|
|
|
|
|
|
public class LoginAssetData
|
|
|
|
|
|
{
|
|
|
|
|
|
public int currencyType;
|
|
|
|
|
|
public int changeType;
|
|
|
|
|
|
public long amount;
|
|
|
|
|
|
public long newGold;
|
|
|
|
|
|
public int newDiamond;
|
|
|
|
|
|
public string source;
|
|
|
|
|
|
public string remark;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// LoginHub BackpackUpdated 数据
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
[Serializable]
|
|
|
|
|
|
public class LoginBackpackData
|
|
|
|
|
|
{
|
|
|
|
|
|
public string action;
|
|
|
|
|
|
public string propNumber;
|
|
|
|
|
|
public int count;
|
|
|
|
|
|
public List<object> props;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// LoginHub NewEmail 数据
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
[Serializable]
|
|
|
|
|
|
public class LoginNewEmailData
|
|
|
|
|
|
{
|
|
|
|
|
|
public string title;
|
|
|
|
|
|
public string emailId;
|
|
|
|
|
|
}
|
2026-07-29 22:59:26 +08:00
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// FishGameHub Exception 数据({code, message})
|
|
|
|
|
|
/// code: 0=未知错误
|
|
|
|
|
|
/// 1001=房间已满 1002=金币不足 1003=房间不存在 1004=玩家不在房间
|
|
|
|
|
|
/// 1005=签名错误 1006=请求已过期 1007=鱼配置不存在 1008=子弹参数无效
|
|
|
|
|
|
/// 1009=金币参数超出范围 1011=用户不存在 1012=道具配置不存在
|
|
|
|
|
|
/// 1013=道具数量不足 1014=钻石不足 1015=炮倍参数无效
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
[Serializable]
|
|
|
|
|
|
public class FishGameExceptionData
|
|
|
|
|
|
{
|
|
|
|
|
|
public int code;
|
|
|
|
|
|
public string message;
|
|
|
|
|
|
}
|
2026-02-03 11:35:19 +08:00
|
|
|
|
}
|
|
|
|
|
|
}
|
2026-06-26 19:28:39 +08:00
|
|
|
|
|
|
|
|
|
|
// end namespace
|