using OWML.Common; using QSB.Messaging; using QSB.TransformSync; using QSB.Utility; using System; using System.Collections.Generic; using System.Linq; using UnityEngine.Networking; namespace QSB { public static class PlayerRegistry { public static uint LocalPlayerId => PlayerTransformSync.LocalInstance.GetComponent()?.netId.Value ?? 0; public static PlayerInfo LocalPlayer => GetPlayer(LocalPlayerId); public static List PlayerList { get; } = new List(); public static List PlayerSyncObjects { get; } = new List(); public static PlayerInfo GetPlayer(uint id) { var player = PlayerList.FirstOrDefault(x => x.PlayerId == id); if (player != null) { return player; } DebugLog.DebugWrite($"Creating player with id {id}", MessageType.Info); player = new PlayerInfo(id); PlayerList.Add(player); return player; } public static void RemovePlayer(uint id) { DebugLog.DebugWrite($"Removing player with id {id}", MessageType.Info); PlayerList.Remove(GetPlayer(id)); } public static bool PlayerExists(uint id) { return PlayerList.Any(x => x.PlayerId == id); } public static void HandleFullStateMessage(PlayerStateMessage message) { DebugLog.DebugWrite($"Handle full state message for player {message.AboutId}"); var player = GetPlayer(message.AboutId); player.Name = message.PlayerName; player.IsReady = message.PlayerReady; DebugLog.DebugWrite($"* Is ready? : {player.IsReady}"); player.State = message.PlayerState; DebugLog.DebugWrite($"* Suit is on? : {FlagsHelper.IsSet(player.State, State.Suit)}"); //DebugLog.DebugWrite($"Updating state of player {player.NetId} to : {Environment.NewLine}" + // $"{DebugLog.GenerateTable(Enum.GetNames(typeof(State)).ToList(), FlagsHelper.FlagsToListSet(player.State))}"); if (LocalPlayer.IsReady) { player.UpdateStateObjects(); } } public static IEnumerable GetSyncObjects() where T : PlayerSyncObject { return PlayerSyncObjects.OfType().Where(x => x != null); } public static T GetSyncObject(uint id) where T : PlayerSyncObject { return GetSyncObjects().FirstOrDefault(x => x != null && x.NetId == id); } public static bool IsBelongingToLocalPlayer(uint id) { return id == LocalPlayerId || PlayerSyncObjects.Any(x => x != null && x.NetId == id && x.PlayerId == LocalPlayerId); } public static List GetPlayerNetIds(PlayerInfo player) { return Enumerable.Range((int)player.PlayerId, PlayerSyncObjects.DistinctBy(x => x.NetId).Count(x => x.PlayerId == player.PlayerId)).Select(x => (uint)x).ToList(); } private static IEnumerable DistinctBy(this IEnumerable source, Func keySelector) { HashSet seenKeys = new HashSet(); foreach (TSource element in source) { if (seenKeys.Add(keySelector(element))) { yield return element; } } } } }