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 ;
2020-08-20 21:07:40 +02:00
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 ;
2020-08-23 21:01:09 +02:00
using UnityEngine.Networking ;
2020-07-28 00:13:43 +01:00
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 ) ;
2020-07-30 21:57:39 +02:00
public static List < PlayerInfo > PlayerList { get ; } = new List < PlayerInfo > ( ) ;
2020-08-05 21:59:50 +02:00
2020-08-21 22:31:42 +02:00
public static List < PlayerSyncObject > PlayerSyncObjects { get ; } = new List < PlayerSyncObject > ( ) ;
2020-08-07 21:57:29 +02:00
2020-09-02 11:17:04 +01:00
public static PlayerInfo GetPlayer ( NetworkInstanceId id )
2020-07-28 00:13:43 +01:00
{
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-07-28 00:13:43 +01:00
{
2020-08-17 18:58:45 +02:00
return player ;
2020-07-28 00:13:43 +01:00
}
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 ) ;
2020-07-30 21:57:39 +02:00
return player ;
2020-07-28 00:13:43 +01:00
}
2020-09-02 11:17:04 +01:00
public static void RemovePlayer ( NetworkInstanceId id )
2020-07-28 00:13:43 +01:00
{
2020-09-02 11:17:04 +01:00
DebugLog . DebugWrite ( $"Removing player with id {id.Value}" , MessageType . Info ) ;
2020-07-30 21:57:39 +02:00
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-07-28 00:13:43 +01:00
{
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 ) ;
2020-07-30 21:57:39 +02:00
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 ( ) ;
}
2020-07-28 00:13:43 +01:00
}
2020-08-21 22:31:42 +02:00
public static IEnumerable < T > GetSyncObjects < T > ( ) where T : PlayerSyncObject
2020-08-05 21:45:48 +02:00
{
2020-08-23 12:53:11 +02:00
return PlayerSyncObjects . OfType < T > ( ) . Where ( x = > x ! = null ) ;
2020-08-05 21:45:48 +02:00
}
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-08-07 21:57:29 +02:00
{
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-08-07 21:57:29 +02:00
}
2020-08-20 21:07:40 +02:00
2020-09-02 11:17:04 +01:00
public static List < NetworkInstanceId > GetPlayerNetIds ( PlayerInfo player )
2020-08-20 21:07:40 +02:00
{
2020-09-02 11:22:08 +01:00
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 ;
}
}
2020-08-20 21:07:40 +02:00
}
2020-07-28 00:13:43 +01:00
}
}