This commit is contained in:
2026-09-15 22:38:11 +08:00
parent a1a4beac5b
commit e709a4a7ab
6 changed files with 197 additions and 32 deletions
+131 -17
View File
@@ -57,18 +57,32 @@ namespace Assets.MyGame.Scripts.Net
/// <param name="msg"></param>
public static void RoomJoinNotice(string msg)
{
// ⭐ 只反序列化一次复用(金币流水 / currRoomData.players 补齐 / 座位激活)
RoomJoinNotice notice = null;
try
{
notice = JsonConvert.DeserializeObject<WebSocketResponseBase<RoomJoinNotice>>(msg).arguments[0];
}
catch { }
// ⭐ 记录金币流水:收到加钱信息(RoomJoinNotice 推送,尚未执行)—— 只记录自己
try
{
var notice = JsonConvert.DeserializeObject<WebSocketResponseBase<RoomJoinNotice>>(msg).arguments[0];
string myId = GameManager.Instance.user?.id;
if (!string.IsNullOrEmpty(myId) && notice.UserId == myId)
if (notice != null && !string.IsNullOrEmpty(myId) && notice.UserId == myId)
{
GameManager.LogGoldFlowReceiveGain("RoomJoinNotice", $"推送金币={notice.Gold} 钻石={notice.Diamond} 炮台消耗={notice.CannonMultiple} 座位={notice.Position}");
}
}
catch { }
// ⭐ 修复:把加入玩家 upsert 进 currRoomData.players。
// JoinGame 里 SetUserInfo 按 userId 从 currRoomData.players 查显示信息
// (昵称/头像/VIP/短编号),而 currRoomData 只在本地进房收到 RoomInfo 时写一次,
// 后加入的玩家不在快照里 → 老客户端把他显示成匿名(无昵称/默认头像/原始32位长ID)。
// RoomJoinNotice 自带完整玩家数据,这里补进快照后再走 JoinGame。
UpsertPlayerToCurrRoom(notice);
string sceneName = "";
UIPanel uIPanel = UIPanel.None;
switch (GameManager.Instance.gameData.currGameType)
@@ -132,29 +146,65 @@ namespace Assets.MyGame.Scripts.Net
{
// 面板已存在 → 新玩家加入,转发给现有面板激活座位
var panel = UIManager.Instance.Get<GameMainPanel_Base>(uIPanel);
if (panel is GameMainPanel_FishBase fishPanel)
if (panel is GameMainPanel_FishBase fishPanel && notice != null)
{
var v = JsonConvert.DeserializeObject<WebSocketResponseBase<RoomJoinNotice>>(msg);
if (v.arguments.Count > 0)
// 如果座位被bot占用则替换
var targetSit = fishPanel.list_Sits.Find(s => s.posID == notice.Position);
if (targetSit != null && targetSit.isBot)
{
var notice = v.arguments[0];
// 如果座位被bot占用则替换
var targetSit = fishPanel.list_Sits.Find(s => s.posID == notice.Position);
if (targetSit != null && targetSit.isBot)
{
targetSit.isBot = false;
targetSit.ShowWaiting();
}
fishPanel.JoinGame(notice.Position, notice.Gold, notice.Diamond, notice.CannonMultiple, 0, notice.UserId, notice.CannonId, notice.WingsId, notice.WarGodId);
// 后端动态加入的机器人也要标记
if (targetSit != null && !string.IsNullOrEmpty(notice.UserId) && notice.UserId.StartsWith("bot_"))
targetSit.isBot = true;
targetSit.isBot = false;
targetSit.ShowWaiting();
}
fishPanel.JoinGame(notice.Position, notice.Gold, notice.Diamond, notice.CannonMultiple, 0, notice.UserId, notice.CannonId, notice.WingsId, notice.WarGodId);
// 后端动态加入的机器人也要标记
if (targetSit != null && !string.IsNullOrEmpty(notice.UserId) && notice.UserId.StartsWith("bot_"))
targetSit.isBot = true;
}
}
}
/// <summary>
/// 把 RoomJoinNotice 玩家数据写入 currRoomData.players(存在则更新,不存在则添加)。
/// JoinGame 里 SetUserInfo 按 userId 从 currRoomData.players 查显示信息
/// (昵称/头像/VIP/短编号),后加入的玩家不在快照里会显示成匿名玩家。
/// </summary>
private static void UpsertPlayerToCurrRoom(RoomJoinNotice notice)
{
if (notice == null || string.IsNullOrEmpty(notice.UserId)) return;
var roomData = GameManager.Instance.gameData?.currRoomData;
if (roomData == null) return;
if (roomData.players == null) roomData.players = new List<RoomPlayerInfo>();
var p = roomData.players.Find(x => x.userId == notice.UserId);
if (p == null)
{
p = new RoomPlayerInfo();
roomData.players.Add(p);
}
p.userId = notice.UserId;
p.userName = notice.UserName;
p.userNumber = notice.UserNumber;
p.avatar = notice.Avatar;
p.isRedName = notice.IsRedName;
p.level = notice.Level;
p.exp = notice.Exp;
p.vipLevel = notice.VipLevel;
p.cId = notice.CId;
p.gold = notice.Gold;
p.diamond = notice.Diamond;
p.position = notice.Position;
p.cannonId = notice.CannonId;
p.wingsId = notice.WingsId;
p.warGodId = notice.WarGodId;
p.cannonMultiple = notice.CannonMultiple;
p.beginCoin = notice.BeginCoin;
p.beginTime = notice.BeginTime;
p.state = notice.State;
p.isBot = notice.IsBot;
}
/// <summary>
/// 房间列表 room
/// </summary>
@@ -992,6 +1042,14 @@ namespace Assets.MyGame.Scripts.Net
{
var roomData = JsonConvert.DeserializeObject<WebSocketResponseBase<RoomChangeResponse>>(msg).arguments[0];
if (roomData == null) return;
// ⭐ 修复:游戏中收到本房间的 RoomChange(players 是全量最新数据)→ 同步座位。
// room socket 进游戏后仍保持连接,玩家加入/离开时都会推 RoomChange;
// 若 game socket 侧没收到(或没处理)RoomJoinNotice/RoomLeaveNotice,
// 老客户端就识别不到新玩家。这里按 players 与 currRoomData.players 全量比对:
// 新加入的入座(JoinGame),离开的释放座位(ShowWaiting),幂等可重复。
SyncSeatsFromRoomChange(roomData);
// 通知手动选座面板刷新(若开启)
var homeMain = UIManager.Instance.Get<UIHomeMain>(UIPanel.HomeMainPanel);
if (homeMain == null) return;
@@ -1007,6 +1065,62 @@ namespace Assets.MyGame.Scripts.Net
}
}
/// <summary>
/// 游戏中收到本房间 RoomChange 时同步座位:players 与 currRoomData.players 全量比对。
/// 新加入(列表有、快照无)→ JoinGame 入座;离开(快照有、列表无)→ ShowWaiting 释放座位。
/// 与 RoomJoinNotice/RoomLeaveNotice 处理幂等(快照里已有的玩家不会重复入座)。
/// </summary>
private static void SyncSeatsFromRoomChange(RoomChangeResponse roomData)
{
var currRoom = GameManager.Instance.gameData?.currRoomData;
// 只处理当前所在房间(房间列表里其他房间的 RoomChange 不关心)
if (currRoom == null || roomData.roomId != currRoom.roomId) return;
if (roomData.players == null) return;
if (currRoom.players == null) currRoom.players = new List<RoomPlayerInfo>();
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);
// 1. 新加入:列表有、快照无 → 写入快照并入座
foreach (var p in roomData.players)
{
if (string.IsNullOrEmpty(p.userId)) continue;
if (currRoom.players.Exists(x => x.userId == p.userId)) continue;
currRoom.players.Add(p);
if (panel == null) continue; // 不在游戏中只补数据,进房流程自己会建座位
bool isBot = p.isBot || p.userId.StartsWith("bot_");
var targetSit = panel.list_Sits.Find(s => s.posID == p.position);
// 真人顶掉 bot 座位时先替换(与 RoomJoinNotice 分支同逻辑)
if (targetSit != null && targetSit.isBot && !isBot)
{
targetSit.isBot = false;
targetSit.ShowWaiting();
}
panel.JoinGame(p.position, p.gold, p.diamond, p.cannonMultiple, 0, p.userId, p.cannonId, p.wingsId, p.warGodId);
}
// 2. 离开:快照有、列表无 → 释放座位并移出快照
for (int i = currRoom.players.Count - 1; i >= 0; i--)
{
var p = currRoom.players[i];
if (string.IsNullOrEmpty(p.userId)) continue;
if (roomData.players.Exists(x => x.userId == p.userId)) continue;
currRoom.players.RemoveAt(i);
if (panel == null) continue;
foreach (var sit in panel.list_Sits)
{
if (sit.user == p.userId)
sit.ShowWaiting();
}
}
}
/// <summary>
/// LoginHub LevelChanged 数据(字段名对齐后端大写首字母)
/// </summary>