diff options
Diffstat (limited to 'Client/Assembly-CSharp/GameData.cs')
-rw-r--r-- | Client/Assembly-CSharp/GameData.cs | 556 |
1 files changed, 556 insertions, 0 deletions
diff --git a/Client/Assembly-CSharp/GameData.cs b/Client/Assembly-CSharp/GameData.cs new file mode 100644 index 0000000..4941bd6 --- /dev/null +++ b/Client/Assembly-CSharp/GameData.cs @@ -0,0 +1,556 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using Assets.CoreScripts; +using Hazel; +using InnerNet; +using UnityEngine; + +public class GameData : InnerNetObject, IDisconnectHandler +{ + public int PlayerCount + { + get + { + return this.AllPlayers.Count; + } + } + + public static GameData Instance; + + // 所有角色数据 + public List<GameData.PlayerInfo> AllPlayers = new List<GameData.PlayerInfo>(); + + public int TotalTasks; + + public int CompletedTasks; + + public const byte InvalidPlayerId = 255; + + public const byte DisconnectedPlayerId = 254; + + public class TaskInfo + { + public uint Id; + + public bool Complete; + + public void Serialize(MessageWriter writer) + { + writer.WritePacked(this.Id); + writer.Write(this.Complete); + } + + public void Deserialize(MessageReader reader) + { + this.Id = reader.ReadPackedUInt32(); + this.Complete = reader.ReadBoolean(); + } + } + + //c 角色数据,包括外观、装饰、是否是imposter、是否死亡 + public class PlayerInfo + { + public PlayerControl Object + { + get + { + if (!this._object) + { + this._object = PlayerControl.AllPlayerControls.FirstOrDefault((PlayerControl p) => p.PlayerId == this.PlayerId); + } + return this._object; + } + } + + public readonly byte PlayerId; + + public string PlayerName = string.Empty; + + public byte ColorId; + + public uint HatId; + + public uint PetId; + + public uint SkinId; + + public bool Disconnected; + + public List<GameData.TaskInfo> Tasks; + + public bool IsImpostor; + + public bool IsDead; + + private PlayerControl _object; + + public PlayerInfo(byte playerId) + { + this.PlayerId = playerId; + } + + public PlayerInfo(PlayerControl pc) : this(pc.PlayerId) + { + this._object = pc; + } + + public void Serialize(MessageWriter writer) + { + writer.Write(this.PlayerName); + writer.Write(this.ColorId); + writer.WritePacked(this.HatId); + writer.WritePacked(this.PetId); + writer.WritePacked(this.SkinId); + byte b = 0; + if (this.Disconnected) + { + b |= 1; + } + if (this.IsImpostor) + { + b |= 2; + } + if (this.IsDead) + { + b |= 4; + } + writer.Write(b); + if (this.Tasks != null) + { + writer.Write((byte)this.Tasks.Count); + for (int i = 0; i < this.Tasks.Count; i++) + { + this.Tasks[i].Serialize(writer); + } + return; + } + writer.Write(0); + } + + public void Deserialize(MessageReader reader) + { + this.PlayerName = reader.ReadString(); + this.ColorId = reader.ReadByte(); + this.HatId = reader.ReadPackedUInt32(); + this.PetId = reader.ReadPackedUInt32(); + this.SkinId = reader.ReadPackedUInt32(); + byte b = reader.ReadByte(); + this.Disconnected = ((b & 1) > 0); + this.IsImpostor = ((b & 2) > 0); + this.IsDead = ((b & 4) > 0); + byte b2 = reader.ReadByte(); + this.Tasks = new List<GameData.TaskInfo>((int)b2); + for (int i = 0; i < (int)b2; i++) + { + this.Tasks.Add(new GameData.TaskInfo()); + this.Tasks[i].Deserialize(reader); + } + } + + public GameData.TaskInfo FindTaskById(uint taskId) + { + for (int i = 0; i < this.Tasks.Count; i++) + { + if (this.Tasks[i].Id == taskId) + { + return this.Tasks[i]; + } + } + return null; + } + } + + private enum RpcCalls + { + SetTasks + } + + public void Awake() + { + if (GameData.Instance && GameData.Instance != this) + { + UnityEngine.Object.Destroy(base.gameObject); + return; + } + GameData.Instance = this; + if (AmongUsClient.Instance) + { + AmongUsClient.Instance.DisconnectHandlers.AddUnique(this); + } + } + + internal void SetDirty() + { + base.SetDirtyBit(uint.MaxValue); + } + + public GameData.PlayerInfo GetHost() + { + ClientData host = AmongUsClient.Instance.GetHost(); + if (host != null && host.Character) + { + return host.Character.Data; + } + return null; + } + + public sbyte GetAvailableId() + { + sbyte i; + sbyte j; + for (i = 0; i < 10; i = j + 1) + { + if (!this.AllPlayers.Any((GameData.PlayerInfo p) => p.PlayerId == (byte)i)) + { + return i; + } + j = i; + } + return -1; + } + + public GameData.PlayerInfo GetPlayerById(byte id) + { + if (id == 255) + { + return null; + } + for (int i = 0; i < this.AllPlayers.Count; i++) + { + if (this.AllPlayers[i].PlayerId == id) + { + return this.AllPlayers[i]; + } + } + return null; + } + + public void UpdateName(byte playerId, string name) + { + GameData.PlayerInfo playerById = this.GetPlayerById(playerId); + if (playerById != null) + { + playerById.PlayerName = name; + } + base.SetDirtyBit(1U << (int)playerId); + } + + public void UpdateColor(byte playerId, byte color) + { + GameData.PlayerInfo playerById = this.GetPlayerById(playerId); + if (playerById != null) + { + playerById.ColorId = color; + } + base.SetDirtyBit(1U << (int)playerId); + } + + public void UpdateHat(byte playerId, uint hat) + { + GameData.PlayerInfo playerById = this.GetPlayerById(playerId); + if (playerById != null) + { + playerById.HatId = hat; + } + base.SetDirtyBit(1U << (int)playerId); + } + + public void UpdatePet(byte playerId, uint petId) + { + GameData.PlayerInfo playerById = this.GetPlayerById(playerId); + if (playerById != null) + { + playerById.PetId = petId; + } + base.SetDirtyBit(1U << (int)playerId); + } + + public void UpdateSkin(byte playerId, uint skin) + { + GameData.PlayerInfo playerById = this.GetPlayerById(playerId); + if (playerById != null) + { + playerById.SkinId = skin; + } + base.SetDirtyBit(1U << (int)playerId); + } + + public void AddPlayer(PlayerControl pc) + { + GameData.PlayerInfo item = new GameData.PlayerInfo(pc); + this.AllPlayers.Add(item); + base.SetDirtyBit(1U << (int)pc.PlayerId); + } + + public bool RemovePlayer(byte playerId) + { + for (int i = 0; i < this.AllPlayers.Count; i++) + { + if (this.AllPlayers[i].PlayerId == playerId) + { + this.SetDirty(); + this.AllPlayers.RemoveAt(i); + return true; + } + } + return false; + } + + public void RecomputeTaskCounts() + { + this.TotalTasks = 0; + this.CompletedTasks = 0; + for (int i = 0; i < this.AllPlayers.Count; i++) + { + GameData.PlayerInfo playerInfo = this.AllPlayers[i]; + if (!playerInfo.Disconnected && playerInfo.Tasks != null && playerInfo.Object && (PlayerControl.GameOptions.GhostsDoTasks || !playerInfo.IsDead) && !playerInfo.IsImpostor) + { + for (int j = 0; j < playerInfo.Tasks.Count; j++) + { + this.TotalTasks++; + if (playerInfo.Tasks[j].Complete) + { + this.CompletedTasks++; + } + } + } + } + } + + public void TutOnlyRemoveTask(byte playerId, uint taskId) + { + GameData.PlayerInfo playerById = this.GetPlayerById(playerId); + GameData.TaskInfo item = playerById.FindTaskById(taskId); + playerById.Tasks.Remove(item); + this.RecomputeTaskCounts(); + } + + public void TutOnlyAddTask(byte playerId, uint taskId) + { + this.GetPlayerById(playerId).Tasks.Add(new GameData.TaskInfo + { + Id = taskId + }); + this.TotalTasks++; + } + + private void SetTasks(byte playerId, byte[] taskTypeIds) + { + GameData.PlayerInfo playerById = this.GetPlayerById(playerId); + if (playerById == null) + { + Debug.Log("Could not set tasks for player id: " + playerId); + return; + } + if (playerById.Disconnected) + { + return; + } + if (!playerById.Object) + { + Debug.Log(string.Concat(new object[] + { + "Could not set tasks for player (", + playerById.PlayerName, + "): ", + playerId + })); + return; + } + playerById.Tasks = new List<GameData.TaskInfo>(taskTypeIds.Length); + for (int i = 0; i < taskTypeIds.Length; i++) + { + playerById.Tasks.Add(new GameData.TaskInfo()); + playerById.Tasks[i].Id = (uint)i; + } + playerById.Object.SetTasks(taskTypeIds); + base.SetDirtyBit(1U << (int)playerById.PlayerId); + } + + public void CompleteTask(PlayerControl pc, uint taskId) + { + GameData.TaskInfo taskInfo = pc.Data.FindTaskById(taskId); + if (taskInfo == null) + { + Debug.LogWarning("Couldn't find task: " + taskId); + return; + } + if (!taskInfo.Complete) + { + taskInfo.Complete = true; + this.CompletedTasks++; + return; + } + Debug.LogWarning("Double complete task: " + taskId); + } + + public void HandleDisconnect(PlayerControl player, DisconnectReasons reason) + { + if (!player) + { + return; + } + GameData.PlayerInfo playerById = this.GetPlayerById(player.PlayerId); + if (playerById == null) + { + return; + } + if (AmongUsClient.Instance.IsGameStarted) + { + if (!playerById.Disconnected) + { + playerById.Disconnected = true; + TempData.LastDeathReason = DeathReason.Disconnect; + this.ShowNotification(playerById.PlayerName, reason); + } + } + else if (this.RemovePlayer(player.PlayerId)) + { + this.ShowNotification(playerById.PlayerName, reason); + } + this.RecomputeTaskCounts(); + } + + private void ShowNotification(string playerName, DisconnectReasons reason) + { + if (string.IsNullOrEmpty(playerName)) + { + return; + } + if (reason <= DisconnectReasons.Banned) + { + if (reason == DisconnectReasons.ExitGame) + { + DestroyableSingleton<HudManager>.Instance.Notifier.AddItem(playerName + " left the game."); + return; + } + if (reason == DisconnectReasons.Banned) + { + GameData.PlayerInfo data = AmongUsClient.Instance.GetHost().Character.Data; + DestroyableSingleton<HudManager>.Instance.Notifier.AddItem(playerName + " was banned by " + data.PlayerName + "."); + return; + } + } + else if (reason == DisconnectReasons.Kicked) + { + GameData.PlayerInfo data2 = AmongUsClient.Instance.GetHost().Character.Data; + DestroyableSingleton<HudManager>.Instance.Notifier.AddItem(playerName + " was kicked by " + data2.PlayerName + "."); + return; + } + DestroyableSingleton<HudManager>.Instance.Notifier.AddItem(playerName + " left the game due to error."); + } + + public void HandleDisconnect() + { + if (!AmongUsClient.Instance.IsGameStarted) + { + for (int i = this.AllPlayers.Count - 1; i >= 0; i--) + { + if (!this.AllPlayers[i].Object) + { + this.AllPlayers.RemoveAt(i); + } + } + } + } + + public override bool Serialize(MessageWriter writer, bool initialState) + { + if (initialState) + { + if (!DestroyableSingleton<Telemetry>.Instance.IsInitialized) + { + DestroyableSingleton<Telemetry>.Instance.Initialize(); + } + writer.WriteBytesAndSize(DestroyableSingleton<Telemetry>.Instance.CurrentGuid.ToByteArray()); + writer.WritePacked(this.AllPlayers.Count); + for (int i = 0; i < this.AllPlayers.Count; i++) + { + GameData.PlayerInfo playerInfo = this.AllPlayers[i]; + writer.Write(playerInfo.PlayerId); + playerInfo.Serialize(writer); + } + } + else + { + int position = writer.Position; + byte b = 0; + writer.Write(b); + for (int j = 0; j < this.AllPlayers.Count; j++) + { + GameData.PlayerInfo playerInfo2 = this.AllPlayers[j]; + if ((this.DirtyBits & 1U << (int)playerInfo2.PlayerId) != 0U) + { + writer.Write(playerInfo2.PlayerId); + playerInfo2.Serialize(writer); + b += 1; + } + } + writer.Position = position; + writer.Write(b); + writer.Position = writer.Length; + this.DirtyBits = 0U; + } + return true; + } + + public override void Deserialize(MessageReader reader, bool initialState) + { + if (initialState) + { + Guid gameGuid = new Guid(reader.ReadBytesAndSize()); + if (!DestroyableSingleton<Telemetry>.Instance.IsInitialized) + { + DestroyableSingleton<Telemetry>.Instance.Initialize(gameGuid); + } + int num = reader.ReadPackedInt32(); + for (int i = 0; i < num; i++) + { + GameData.PlayerInfo playerInfo = new GameData.PlayerInfo(reader.ReadByte()); + playerInfo.Deserialize(reader); + this.AllPlayers.Add(playerInfo); + } + } + else + { + byte b = reader.ReadByte(); + for (int j = 0; j < (int)b; j++) + { + byte b2 = reader.ReadByte(); + GameData.PlayerInfo playerInfo2 = this.GetPlayerById(b2); + if (playerInfo2 != null) + { + playerInfo2.Deserialize(reader); + } + else + { + playerInfo2 = new GameData.PlayerInfo(b2); + playerInfo2.Deserialize(reader); + this.AllPlayers.Add(playerInfo2); + } + } + } + this.RecomputeTaskCounts(); + } + + public void RpcSetTasks(byte playerId, byte[] taskTypeIds) + { + if (AmongUsClient.Instance.AmClient) + { + this.SetTasks(playerId, taskTypeIds); + } + MessageWriter messageWriter = AmongUsClient.Instance.StartRpc(this.NetId, 0, SendOption.Reliable); + messageWriter.Write(playerId); + messageWriter.WriteBytesAndSize(taskTypeIds); + messageWriter.EndMessage(); + } + + public override void HandleRpc(byte callId, MessageReader reader) + { + if (callId == 0) + { + this.SetTasks(reader.ReadByte(), reader.ReadBytesAndSize()); + } + } +} |