TH1/Unity/Assets/Scripts/TH1_Logic/Steam/GameNetReceiver.cs
2025-11-03 16:43:04 +08:00

285 lines
12 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 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<BaseMessage>(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 (message.ActionData.Version != Main.MapData.Net.GetActionVersion())
{
LogSystem.LogError($"OnReceivedActionConfirm Version 不一致");
return;
}
if (NetData.GetMapDataHash(Main.MapData) != message.ActionData.MapHash)
{
// TODO 这里来校验不同之处
if (message.Map != null)
{
Main.MapData.CompareEqual(message.Map);
MapData.FindDifferences(Main.MapData, message.Map);
}
// MapData.CompareWithDetails(Main.MapData, message.Map);
}
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;
// TODO 强制断线重连在这里实现
// Main.Instance.NetContinueGame(message.MapData);
//Step #1 强制结束当前游戏对局
//Main.Instance.GameLogic.ChangeState(GameState.Menu);
//Step #2 强制关闭当前所有UI
//UIManager.Instance.GameUI.CloseAllGameUI();
//Step #3 强制继续联机对局
//Main.Instance.NetContinueGame(message.MapData);
// Main.MapData = message.MapData;
Main.MapData.CompareEqual(message.MapData);
MapData.FindDifferences(Main.MapData, message.MapData);
// 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;
}
}
// 只有房主会收到
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;
}
}
}