quantum-space-buddies/QSB/PlayerRegistry.cs

123 lines
5.0 KiB
C#
Raw Normal View History

2020-08-22 18:08:25 +01:00
using OWML.Common;
using QSB.Messaging;
2020-08-21 14:04:13 +01:00
using QSB.TransformSync;
using QSB.Utility;
2020-08-26 20:50:30 +01:00
using System;
2020-08-21 14:04:13 +01:00
using System.Collections.Generic;
using System.Linq;
2020-09-02 11:17:04 +01:00
using UnityEngine;
using UnityEngine.Networking;
namespace QSB
{
public static class PlayerRegistry
{
2020-09-02 11:17:04 +01:00
public static NetworkInstanceId LocalPlayerId => PlayerTransformSync.LocalInstance.GetComponent<NetworkIdentity>()?.netId ?? NetworkInstanceId.Invalid;
2020-08-14 20:54:15 +02:00
public static PlayerInfo LocalPlayer => GetPlayer(LocalPlayerId);
public static List<PlayerInfo> PlayerList { get; } = new List<PlayerInfo>();
2020-08-05 21:59:50 +02:00
public static List<PlayerSyncObject> PlayerSyncObjects { get; } = new List<PlayerSyncObject>();
2020-09-02 11:17:04 +01:00
public static PlayerInfo GetPlayer(NetworkInstanceId id)
{
2020-09-02 11:17:04 +01:00
if (id == NetworkInstanceId.Invalid)
{
return default;
}
2020-08-26 20:50:30 +01:00
var player = PlayerList.FirstOrDefault(x => x.PlayerId == id);
2020-08-17 18:58:45 +02:00
if (player != null)
{
2020-08-17 18:58:45 +02:00
return player;
}
2020-08-22 20:21:13 +01:00
DebugLog.DebugWrite($"Creating player with id {id}", MessageType.Info);
2020-08-17 18:58:45 +02:00
player = new PlayerInfo(id);
2020-07-28 15:59:24 +02:00
PlayerList.Add(player);
return player;
}
2020-09-02 11:17:04 +01:00
public static void RemovePlayer(NetworkInstanceId id)
{
2020-09-02 11:17:04 +01:00
DebugLog.DebugWrite($"Removing player with id {id.Value}", MessageType.Info);
PlayerList.Remove(GetPlayer(id));
2020-07-29 22:04:50 +01:00
}
2020-09-02 11:17:04 +01:00
public static bool PlayerExists(NetworkInstanceId id)
2020-08-18 21:29:31 +01:00
{
2020-09-02 11:17:04 +01:00
if (id == NetworkInstanceId.Invalid)
{
return false;
}
2020-08-26 20:50:30 +01:00
return PlayerList.Any(x => x.PlayerId == id);
2020-08-18 21:29:31 +01:00
}
2020-08-09 21:46:51 +01:00
public static void HandleFullStateMessage(PlayerStateMessage message)
{
2020-08-24 15:51:12 +01:00
DebugLog.DebugWrite($"Handle full state message for player {message.AboutId}");
2020-08-17 19:25:28 +02:00
var player = GetPlayer(message.AboutId);
player.Name = message.PlayerName;
2020-08-10 11:45:24 +01:00
player.IsReady = message.PlayerReady;
2020-08-24 15:51:12 +01:00
DebugLog.DebugWrite($"* Is ready? : {player.IsReady}");
2020-08-10 11:45:24 +01:00
player.State = message.PlayerState;
2020-08-24 15:51:12 +01:00
DebugLog.DebugWrite($"* Suit is on? : {FlagsHelper.IsSet(player.State, State.Suit)}");
2020-08-22 20:21:13 +01:00
//DebugLog.DebugWrite($"Updating state of player {player.NetId} to : {Environment.NewLine}" +
// $"{DebugLog.GenerateTable(Enum.GetNames(typeof(State)).ToList(), FlagsHelper.FlagsToListSet(player.State))}");
2020-08-13 19:25:12 +02:00
if (LocalPlayer.IsReady)
2020-08-09 21:46:51 +01:00
{
2020-08-10 11:45:24 +01:00
player.UpdateStateObjects();
}
}
public static IEnumerable<T> GetSyncObjects<T>() where T : PlayerSyncObject
{
2020-08-23 12:53:11 +02:00
return PlayerSyncObjects.OfType<T>().Where(x => x != null);
}
2020-09-02 11:17:04 +01:00
public static T GetSyncObject<T>(NetworkInstanceId id) where T : PlayerSyncObject
2020-08-14 20:54:15 +02:00
{
2020-08-23 12:53:11 +02:00
return GetSyncObjects<T>().FirstOrDefault(x => x != null && x.NetId == id);
2020-08-14 20:54:15 +02:00
}
2020-09-02 11:17:04 +01:00
public static bool IsBelongingToLocalPlayer(NetworkInstanceId id)
{
2020-09-02 11:17:04 +01:00
var behaviours = Resources.FindObjectsOfTypeAll<NetworkBehaviour>();
return behaviours.Where(x => x.netId == id).First().isLocalPlayer;
}
public static NetworkInstanceId GetPlayerOfObject(this NetworkBehaviour behaviour)
{
var playerIds = PlayerList.Select(x => x.PlayerId).ToList();
var lowerPlayerIds = playerIds.Where(x => x.Value <= behaviour.netId.Value);
var lowerBound = lowerPlayerIds.ToList().Find(x => x.Value == lowerPlayerIds.Select(n => n.Value).Max());
if (PlayerList.Count != PlayerSyncObjects.Count(x => x.GetType() == behaviour.GetType()))
{
2020-09-02 11:36:40 +01:00
DebugLog.ToConsole($"Error - Mismatch between player count ({PlayerList.Count}) and syncobject count ({PlayerSyncObjects.Count(x => x.GetType() == behaviour.GetType())}). Assuming new player has joined...");
2020-09-02 11:17:04 +01:00
if (behaviour.GetType() == typeof(PlayerTransformSync))
{
return GetPlayer(behaviour.netId).PlayerId;
}
return NetworkInstanceId.Invalid;
}
return lowerBound;
}
2020-09-02 11:17:04 +01:00
public static List<NetworkInstanceId> GetPlayerNetIds(PlayerInfo player)
{
var ints = Enumerable.Range((int)player.PlayerId.Value, PlayerSyncObjects.DistinctBy(x => x.NetId).Count(x => x.Player.PlayerId == player.PlayerId)).Select(x => (uint)x).ToList();
2020-09-02 11:17:04 +01:00
var networkInstances = Resources.FindObjectsOfTypeAll<NetworkIdentity>().Select(x => x.netId).DistinctBy(x => x.Value);
return networkInstances.Where(x => ints.Contains(x.Value)).ToList();
2020-08-26 20:50:30 +01:00
}
private static IEnumerable<TSource> DistinctBy<TSource, TKey>(this IEnumerable<TSource> source, Func<TSource, TKey> keySelector)
{
2020-09-02 11:17:04 +01:00
var seenKeys = new HashSet<TKey>();
foreach (var element in source)
2020-08-26 20:50:30 +01:00
{
if (seenKeys.Add(keySelector(element)))
{
yield return element;
}
}
}
}
}