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-21 14:04:13 +01:00
using System.Collections.Generic ;
2020-10-22 21:21:41 +01:00
using System.Diagnostics ;
2020-08-21 14:04:13 +01:00
using System.Linq ;
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-04 20:09:25 +01:00
public static uint LocalPlayerId = > PlayerTransformSync . LocalInstance . GetComponent < NetworkIdentity > ( ) ? . netId . Value ? ? uint . MaxValue ;
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-04 20:09:25 +01:00
public static PlayerInfo GetPlayer ( uint id )
2020-07-28 00:13:43 +01:00
{
2020-09-04 20:32:30 +01:00
if ( id = = uint . MaxValue | | id = = 0 U )
{
2020-10-22 21:21:41 +01:00
var stacktrace = new StackTrace ( ) ;
DebugLog . ToConsole ( $"GetPlayer() got uint.MaxValue or 0 - returning default. Ran from {stacktrace.GetFrame(1).GetMethod().DeclaringType.Name}.{stacktrace.GetFrame(1).GetMethod().Name}." , MessageType . Warning ) ;
2020-09-04 20:32:30 +01:00
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-09-03 17:09:38 +01:00
DebugLog . DebugWrite ( $"Creating player 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-04 20:09:25 +01:00
public static void RemovePlayer ( uint id )
2020-07-28 00:13:43 +01:00
{
2020-09-04 20:09:25 +01:00
DebugLog . DebugWrite ( $"Removing player {GetPlayer(id).Name} id {id}" , MessageType . Info ) ;
2020-07-30 21:57:39 +02:00
PlayerList . Remove ( GetPlayer ( id ) ) ;
2020-07-29 22:04:50 +01:00
}
2020-10-22 21:21:41 +01:00
public static void RemoveAllPlayers ( )
{
DebugLog . DebugWrite ( $"Removing all players." , MessageType . Info ) ;
PlayerList . Clear ( ) ;
}
2020-09-04 20:09:25 +01:00
public static bool PlayerExists ( uint id )
2020-08-18 21:29:31 +01:00
{
2020-09-07 19:57:43 +02:00
return id ! = uint . MaxValue & & 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-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 ;
player . State = message . PlayerState ;
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-04 20:09:25 +01:00
public static T GetSyncObject < T > ( uint id ) where T : PlayerSyncObject
2020-08-14 20:54:15 +02:00
{
2020-09-04 20:36:25 +01:00
return GetSyncObjects < T > ( ) . FirstOrDefault ( x = > x ! = null & & x . AttachedNetId = = id ) ;
2020-08-14 20:54:15 +02:00
}
2020-09-04 20:09:25 +01:00
public static bool IsBelongingToLocalPlayer ( uint id )
2020-08-07 21:57:29 +02:00
{
2020-09-04 20:36:25 +01:00
return id = = LocalPlayerId | |
PlayerSyncObjects . Any ( x = > x ! = null & & x . AttachedNetId = = id & & x . isLocalPlayer ) ;
2020-09-02 11:17:04 +01:00
}
2020-09-04 20:09:25 +01:00
public static uint GetPlayerOfObject ( this PlayerSyncObject syncObject )
2020-09-02 11:17:04 +01:00
{
2020-09-29 21:34:46 +01:00
if ( PlayerList . Count = = 0 )
{
2020-10-22 21:21:41 +01:00
DebugLog . ToConsole ( $"Error - No players exist to find owner of object. (Attached NetID : {syncObject.AttachedNetId})" , MessageType . Error ) ;
syncObject . PreviousPlayerId = uint . MaxValue ;
2020-09-29 21:34:46 +01:00
return uint . MaxValue ;
}
2020-10-22 21:21:41 +01:00
// Get all Player IDs
2020-09-02 11:17:04 +01:00
var playerIds = PlayerList . Select ( x = > x . PlayerId ) . ToList ( ) ;
2020-10-22 21:21:41 +01:00
// Get highest ID below the given syncobject's netid. A netid cannot belong to a netid above it, only below or equal to it.
2020-09-04 20:52:06 +01:00
var lowerBound = playerIds . Where ( x = > x < = syncObject . AttachedNetId ) . ToList ( ) . Max ( ) ;
2020-10-22 21:21:41 +01:00
if ( playerIds . Min ( ) > syncObject . AttachedNetId )
{
DebugLog . ToConsole ( $"Warning - Minimum playerid is greater than syncobject's netid. (Attached NetID : {syncObject.AttachedNetId})" , MessageType . Warning ) ;
syncObject . PreviousPlayerId = uint . MaxValue ;
return uint . MaxValue ;
}
// If the player list count is not the same as the count of the same type syncobject (eg. 3 players and 4 PlayerTransformSyncs)
// and the highest ID below the syncobject's id is the same as the highest player id.
2020-09-04 20:52:06 +01:00
if ( PlayerList . Count ! = PlayerSyncObjects . Count ( x = > x . GetType ( ) = = syncObject . GetType ( ) ) & & lowerBound = = playerIds . Max ( ) )
2020-09-02 11:17:04 +01:00
{
2020-10-22 21:21:41 +01:00
// If the previous player id was not the error value, return it. To smooth over discrepancies between player list and object list.
2020-09-04 20:09:25 +01:00
if ( syncObject . PreviousPlayerId ! = uint . MaxValue )
2020-09-04 18:54:53 +01:00
{
return syncObject . PreviousPlayerId ;
}
2020-10-22 21:21:41 +01:00
// If the syncobject is a PlayerTransformSync, make a player.
2020-09-04 20:52:06 +01:00
if ( syncObject . GetType ( ) = = typeof ( PlayerTransformSync ) & & syncObject . AttachedNetId ! = 0 U )
2020-09-02 11:17:04 +01:00
{
2020-09-04 20:52:06 +01:00
return GetPlayer ( syncObject . AttachedNetId ) . PlayerId ;
2020-09-02 11:17:04 +01:00
}
2020-10-22 21:21:41 +01:00
DebugLog . ToConsole ( $"Warning - Unequal player:syncobject count. ({PlayerList.Count}:{PlayerSyncObjects.Count(x => x.GetType() == syncObject.GetType())}) (Attached NetID : {syncObject.AttachedNetId})" , MessageType . Warning ) ;
2020-09-04 20:09:25 +01:00
syncObject . PreviousPlayerId = uint . MaxValue ;
return uint . MaxValue ;
2020-09-02 11:17:04 +01:00
}
2020-10-22 21:21:41 +01:00
if ( syncObject . PreviousPlayerId = = uint . MaxValue )
{
DebugLog . ToConsole ( $"Warning - Syncobject previously had uint.MaxValue as it's playerid. (Attached NetID : {syncObject.AttachedNetId})" , MessageType . Warning ) ;
}
2020-09-04 18:54:53 +01:00
syncObject . PreviousPlayerId = lowerBound ;
2020-09-02 11:17:04 +01:00
return lowerBound ;
2020-08-07 21:57:29 +02:00
}
2020-08-20 21:07:40 +02:00
2020-09-04 20:09:25 +01:00
public static List < uint > GetPlayerNetIds ( PlayerInfo player )
2020-08-20 21:07:40 +02:00
{
2020-09-29 21:34:46 +01:00
if ( PlayerSyncObjects . Count = = 0 )
{
return default ;
}
int count = 0 ;
2020-10-22 21:21:41 +01:00
int totalCount = PlayerSyncObjects . Count ;
2020-09-29 21:34:46 +01:00
PlayerSyncObjects . RemoveAll ( x = > x = = null ) ;
PlayerSyncObjects . RemoveAll ( x = > x . GetComponent < NetworkIdentity > ( ) = = null ) ;
2020-10-22 21:21:41 +01:00
if ( PlayerSyncObjects . Count ! = totalCount )
{
DebugLog . ToConsole ( $"Warning - Removed {totalCount - PlayerSyncObjects.Count} items from PlayerSyncObjects." , MessageType . Warning ) ;
}
2020-09-29 21:34:46 +01:00
foreach ( var item in PlayerSyncObjects . DistinctBy ( x = > x . AttachedNetId ) )
{
if ( item . PlayerId = = player . PlayerId )
{
count + + ;
}
}
2020-09-07 19:57:43 +02:00
return Enumerable . Range ( ( int ) player . PlayerId , count ) . Select ( x = > ( uint ) x ) . ToList ( ) ;
2020-08-20 21:07:40 +02:00
}
2020-07-28 00:13:43 +01:00
}
}