2025-09-09 11:50:19 +08:00

104 lines
3.3 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.

/*
* @Author: 白哉
* @Description:
* @Date: 2025年04月03日 星期四 11:04:31
* @Modify:
*/
using System.Collections.Generic;
using Logic.AI;
using MemoryPack;
using Steamworks;
using TH1_Logic.Steam;
using UnityEngine;
namespace RuntimeData
{
// 网络信息
[MemoryPackable]
public partial class NetData
{
// 地图哈希
public string MapHash;
// PlayerId => SteamId 的索引
public Dictionary<uint, ulong> Players;
// 所有玩家行为的序列
public List<ActionNetData> Actions;
// 随机数种子 开始游戏时由房主进行初始化,整局游戏不可变
public int RandomSeed;
private System.Random _random;
[MemoryPackConstructor]
public NetData()
{
Players = new Dictionary<uint, ulong>();
Actions = new List<ActionNetData>();
// 生成确定性种子(由房主生成并广播)
RandomSeed = System.Environment.TickCount;
}
// 这里单纯是因为深拷贝目前只用于 AI 演算,故不对 Players 和 Actions 赋值
public NetData(NetData copyData)
{
MapHash = copyData.MapHash;
RandomSeed = copyData.RandomSeed;
Players = new Dictionary<uint, ulong>();
Actions = new List<ActionNetData>();
}
// 这里单纯是因为深拷贝目前只用于 AI 演算,故不对 Players 和 Actions 赋值
public void DeepCopy(NetData copyData)
{
MapHash = copyData.MapHash;
RandomSeed = copyData.RandomSeed;
Players = new Dictionary<uint, ulong>();
Actions = new List<ActionNetData>();
}
public System.Random GetRandom()
{
if (_random == null) _random = new System.Random(RandomSeed);
return _random;
}
public void RefreshMapNet(MapData mapData)
{
if (!SteamLobbyManager.Instance.IsLobbyOwner) return;
// 地图初始哈希
MapHash = GetMapDataHash(mapData);
// 添加自己
if (!Players.ContainsKey(mapData.PlayerMap.SelfPlayerId))
{
Players[mapData.PlayerMap.SelfPlayerId] = SteamUser.GetSteamID().m_SteamID;
}
// 添加其他人
foreach (var cSteamID in SteamLobbyManager.Instance.EnumerateMembers())
{
if (Players.ContainsValue(cSteamID.m_SteamID)) continue;
foreach (var player in mapData.PlayerMap.PlayerDataList)
{
if (player.Id == mapData.PlayerMap.SelfPlayerId) continue;
if (Players.ContainsKey(player.Id)) return;
Players[player.Id] = cSteamID.m_SteamID;
}
}
}
public uint GetActionVersion()
{
if (Actions.Count == 0) return 0;
return Actions[^1].Version + 1;
}
public static string GetMapDataHash(MapData mapData)
{
byte[] bytes = MemoryPackSerializer.Serialize(mapData);
// 使用 Unity 的 Hash128性能很好且稳定
var hash128 = new Hash128();
hash128.Append(bytes);
return hash128.ToString();
}
}
}