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