using Animancer; using Logic; using Logic.Action; using Logic.CrashSight; using RuntimeData; using Steamworks; using TH1_Core.Events; using TH1_Core.Managers; using TH1_Logic.Core; using TH1_Logic.Net; using UnityEngine; namespace TH1_Logic.Steam { public class GameNetReceiver { public static GameNetReceiver Instance { get; } = new GameNetReceiver(); public void OnMessageReceived(byte[] data) { var message = MemoryPack.MemoryPackSerializer.Deserialize(data); if (message == null) return; if (message.MessageType == P2PMsgType.String) OnReceivedString((StringMessage)message); if (message.MessageType == P2PMsgType.GameStart) OnReceivedGameStart((GameStartMessage)message); if (message.MessageType == P2PMsgType.ActionConfirm) OnReceivedActionConfirm((ActionConfirmMessage)message); if (message.MessageType == P2PMsgType.ActionExcute) OnReceivedActionExcute((ActionExcuteMessage)message); if (message.MessageType == P2PMsgType.TurnEnd) OnReceivedTurnEnd((TurnEndMessage)message); if (message.MessageType == P2PMsgType.MapConfirm) OnReceivedMapConfirm((MapConfirmMessage)message); if (message.MessageType == P2PMsgType.ForceUpdate) OnReceivedForceUpdate((ForceUpdateMessage)message); if (message.MessageType == P2PMsgType.ChangeCiv) OnReceivedChangeCiv((ChangeCivMessage)message); if (message.MessageType == P2PMsgType.UpdateLobbyData) OnReceivedUpdateLobbyData((UpdateLobbyDataMessage)message); if (message.MessageType == P2PMsgType.RequestLobbyData) OnReceivedRequestLobbyData((RequestLobbyDataMessage)message); if (message.MessageType == P2PMsgType.Heartbeat) OnReceivedHeartbeat((HeartbeatMessage)message); } // 基础字符串消息 private void OnReceivedString(StringMessage message) { if (message == null) { LogSystem.LogError($"消息解析失败: OnReceivedString"); return; } if (string.IsNullOrEmpty(message.Content)) return; LogSystem.LogInfo($"收到消息 : {message.Content}"); } // 只有玩家会收到 private void OnReceivedGameStart(GameStartMessage message) { if (message == null) { LogSystem.LogError($"消息解析失败: OnReceivedGameStart"); return; } if (message.MapData == null) return; if (LobbyManager.Instance.Lobby.IsLobbyOwner()) return; LogSystem.LogWarning($"OnReceivedGameStart : {NetData.GetMapDataHash(message.MapData)}"); //客户端开启游戏 //如果loading失败 直接开始游戏并关闭当前页面 UIManager.Instance.ShowLoading(); Main.Instance.NetStartGame(message.MapData); EventManager.Publish(new HideUIOutsideMultiplay(){}); } // 只有房主会收到 private void OnReceivedActionConfirm(ActionConfirmMessage message) { if (message == null) { LogSystem.LogError($"消息解析失败: OnReceivedActionConfirm"); return; } if (!LobbyManager.Instance.Lobby.IsLobbyOwner()) return; if (message.ActionData == null) return; // if (message.ActionData.MapHash != Main.MapData.Net.MapHash) // { // LogSystem.LogError($"OnReceivedActionConfirm MapHash不一致"); // return; // } if (message.ActionData.Version != Main.MapData.Net.GetActionVersion()) { LogSystem.LogError($"OnReceivedActionConfirm Version 不一致"); return; } message.ActionData.Param.MapData = Main.MapData; message.ActionData.Param.RefreshParams(); var action = ActionLogicFactory.GetActionLogic(message.ActionData.ActionId); if (action == null) { LogSystem.LogError($"OnReceivedActionConfirm 找不到对应 Action"); return; } action.CompleteExecute(message.ActionData.Param); } // 只有玩家会收到 private void OnReceivedActionExcute(ActionExcuteMessage message) { if (message == null) { LogSystem.LogError($"消息解析失败: OnReceivedActionExcute"); return; } if (LobbyManager.Instance.Lobby.IsLobbyOwner()) return; if (message.ActionData == null) return; // if (message.ActionData.MapHash != Main.MapData.Net.MapHash) // { // LogSystem.LogError($"OnReceivedActionConfirm MapHash不一致"); // return; // } if (NetData.GetMapDataHash(Main.MapData) != message.ActionData.MapHash) { // TODO 这里来校验不同之处 if (message.Map != null) { Main.MapData.CompareEqual(message.Map); var diff = MapData.FindDifferences(Main.MapData, message.Map); foreach (var str in diff) LogSystem.LogError($"{str}"); } // MapData.CompareWithDetails(Main.MapData, message.Map); } if (message.ActionData.Version != Main.MapData.Net.GetActionVersion()) { LogSystem.LogError($"OnReceivedActionConfirm Version 不一致"); return; } message.ActionData.Param.MapData = Main.MapData; message.ActionData.Param.RefreshParams(); var action = ActionLogicFactory.GetActionLogic(message.ActionData.ActionId); if (action == null) { LogSystem.LogError($"OnReceivedActionConfirm 找不到对应 Action"); return; } action.NetCompleteExecute(message.ActionData.Param); } // 只有房主会收到 private void OnReceivedTurnEnd(TurnEndMessage message) { if (message == null) { LogSystem.LogError($"消息解析失败: OnReceivedTurnEnd"); return; } if (!LobbyManager.Instance.Lobby.IsLobbyOwner()) return; Main.PlayerLogic.EndPlayerTurn(Main.MapData, message.PlayerId); } // 只有房主会收到心跳校验 private void OnReceivedMapConfirm(MapConfirmMessage message) { if (message == null) { LogSystem.LogError($"消息解析失败: OnReceivedMapConfirm"); return; } if (Main.MapData?.Net == null) return; if (!LobbyManager.Instance.Lobby.IsLobbyOwner()) return; if (Main.MapData.Net.Actions.Count == 0 || message.Index == 0) return; if (!Main.MapData.Net.PlayerConfirm.TryGetValue(message.MemberId, out var value)) return; value.GameConfirmTime = Time.time; if (message.Index > Main.MapData.Net.Actions.Count) { LogSystem.LogError($"action index error message.Index : {message.Index}, Main.MapData.Net.Actions.Count : {Main.MapData.Net.Actions.Count}"); value.State = MemberNetState.Error; return; } else if (!Main.MapData.Net.Actions[message.Index - 1].IsEqual(message.ActionData)) { LogSystem.LogError($"self action hash : {Main.MapData.Net.Actions[message.Index - 1].MapHash}, message map hash : {message.ActionData.MapHash}"); value.State = MemberNetState.Error; } else { value.State = MemberNetState.OK; LogSystem.LogInfo($"self action hash : {Main.MapData.Net.Actions[message.Index - 1].MapHash}, message map hash : {message.ActionData.MapHash}"); } } // 只有玩家会收到 private void OnReceivedForceUpdate(ForceUpdateMessage message) { if (message == null) { LogSystem.LogError($"消息解析失败: OnReceivedActionExcute"); return; } if (LobbyManager.Instance.Lobby.IsLobbyOwner()) return; Main.MapData.CompareEqual(message.MapData); var diff = MapData.FindDifferences(Main.MapData, message.MapData); foreach (var str in diff) LogSystem.LogError($"{str}"); // Main.Instance.NetContinueGame(message.MapData); for (int i = 0; i < Main.MapData.Net.Actions.Count; i++) { if (i >= message.MapData.Net.Actions.Count) continue; if (Main.MapData.Net.Actions[i].MapHash == message.MapData.Net.Actions[i].MapHash) continue; if (i == 0) LogSystem.LogError($"初始 Map 校验失败!!!"); else { LogSystem.LogError($"Map不一致前后Action : {Main.MapData.Net.Actions[i - 1].ActionId.GetStringLog()}" + $"{Main.MapData.Net.Actions[i].ActionId.GetStringLog()}"); } break; } // TODO 强制断线重连在这里实现 // Step #1 强制结束当前游戏对局 Main.Instance.GameLogic.ChangeState(GameState.Menu); // Step #2 强制关闭当前所有UI UIManager.Instance.GameUI.CloseAllGameUI(); UIManager.Instance.GameUI.NetHint.SetActive(true); Timer.Instance.TimerRegister(this, () => { UIManager.Instance.GameUI.NetHint.SetActive(false); },2f,"NetHint Wrong"); // Step #3 强制继续联机对局 Main.Instance.NetContinueGame(message.MapData); // Main.MapData = message.MapData; } // 只有房主会收到 private void OnReceivedChangeCiv(ChangeCivMessage message) { if (message == null) { LogSystem.LogError($"消息解析失败: OnReceivedChangeCiv"); return; } if (!LobbyManager.Instance.Lobby.IsLobbyOwner()) return; if (message.Civ == null) return; Main.Instance.MapConfig.UpdateMemberCiv(message.Civ); Main.Instance.MapConfig.CheckMapConfigChanged(); } // 只有玩家会收到 private void OnReceivedUpdateLobbyData(UpdateLobbyDataMessage message) { if (message == null) { LogSystem.LogError($"消息解析失败: OnReceivedUpdateLobbyData"); return; } if (LobbyManager.Instance.Lobby.IsLobbyOwner()) return; if (message.Config == null) return; Main.Instance.MapConfig = message.Config; Main.Instance.MapConfig.CheckMapConfigChanged(); } // 只有房主会收到 private void OnReceivedRequestLobbyData(RequestLobbyDataMessage message) { if (message == null) { LogSystem.LogError($"消息解析失败: OnReceivedRequestLobbyData"); return; } if (!LobbyManager.Instance.Lobby.IsLobbyOwner()) return; GameNetSender.Instance.SendLobbyData(Main.Instance.MapConfig, message.MemberId); } // 只有房主会收到 private void OnReceivedHeartbeat(HeartbeatMessage message) { if (message == null) { LogSystem.LogError($"消息解析失败: OnReceivedHeartbeat"); return; } if (Main.MapData == null) return; if (!LobbyManager.Instance.Lobby.IsLobbyOwner()) return; if (Main.MapData == null) return; if (!Main.MapData.Net.PlayerConfirm.TryGetValue(message.MemberId, out var value)) return; value.ConfirmTime = Time.time; } } }