2020-08-22 17:08:25 +00:00
using OWML.Common ;
2020-11-03 21:33:48 +00:00
using QSB.Player.Events ;
2020-08-21 13:04:13 +00:00
using QSB.TransformSync ;
2020-08-20 19:07:40 +00:00
using QSB.Utility ;
2020-08-21 13:04:13 +00:00
using System.Collections.Generic ;
2020-10-22 20:21:41 +00:00
using System.Diagnostics ;
2020-08-21 13:04:13 +00:00
using System.Linq ;
2020-08-23 19:01:09 +00:00
using UnityEngine.Networking ;
2020-07-27 23:13:43 +00:00
2020-11-03 21:33:48 +00:00
namespace QSB.Player
2020-07-27 23:13:43 +00:00
{
2020-11-03 21:18:40 +00:00
public static class QSBPlayerManager
2020-07-27 23:13:43 +00:00
{
2020-09-04 19:09:25 +00:00
public static uint LocalPlayerId = > PlayerTransformSync . LocalInstance . GetComponent < NetworkIdentity > ( ) ? . netId . Value ? ? uint . MaxValue ;
2020-08-14 18:54:15 +00:00
public static PlayerInfo LocalPlayer = > GetPlayer ( LocalPlayerId ) ;
2020-07-30 19:57:39 +00:00
public static List < PlayerInfo > PlayerList { get ; } = new List < PlayerInfo > ( ) ;
2020-08-05 19:59:50 +00:00
2020-08-21 20:31:42 +00:00
public static List < PlayerSyncObject > PlayerSyncObjects { get ; } = new List < PlayerSyncObject > ( ) ;
2020-08-07 19:57:29 +00:00
2020-09-04 19:09:25 +00:00
public static PlayerInfo GetPlayer ( uint id )
2020-07-27 23:13:43 +00:00
{
2020-09-04 19:32:30 +00:00
if ( id = = uint . MaxValue | | id = = 0 U )
{
2020-10-22 20:21:41 +00: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 19:32:30 +00:00
return default ;
}
2020-08-26 19:50:30 +00:00
var player = PlayerList . FirstOrDefault ( x = > x . PlayerId = = id ) ;
2020-08-17 16:58:45 +00:00
if ( player ! = null )
2020-07-27 23:13:43 +00:00
{
2020-08-17 16:58:45 +00:00
return player ;
2020-07-27 23:13:43 +00:00
}
2020-09-03 16:09:38 +00:00
DebugLog . DebugWrite ( $"Creating player id {id}" , MessageType . Info ) ;
2020-08-17 16:58:45 +00:00
player = new PlayerInfo ( id ) ;
2020-07-28 13:59:24 +00:00
PlayerList . Add ( player ) ;
2020-07-30 19:57:39 +00:00
return player ;
2020-07-27 23:13:43 +00:00
}
2020-09-04 19:09:25 +00:00
public static void RemovePlayer ( uint id )
2020-07-27 23:13:43 +00:00
{
2020-09-04 19:09:25 +00:00
DebugLog . DebugWrite ( $"Removing player {GetPlayer(id).Name} id {id}" , MessageType . Info ) ;
2020-07-30 19:57:39 +00:00
PlayerList . Remove ( GetPlayer ( id ) ) ;
2020-07-29 21:04:50 +00:00
}
2020-10-22 20:21:41 +00:00
public static void RemoveAllPlayers ( )
{
DebugLog . DebugWrite ( $"Removing all players." , MessageType . Info ) ;
PlayerList . Clear ( ) ;
}
2020-09-04 19:09:25 +00:00
public static bool PlayerExists ( uint id )
2020-08-18 20:29:31 +00:00
{
2020-09-07 17:57:43 +00:00
return id ! = uint . MaxValue & & PlayerList . Any ( x = > x . PlayerId = = id ) ;
2020-08-18 20:29:31 +00:00
}
2020-08-09 20:46:51 +00:00
public static void HandleFullStateMessage ( PlayerStateMessage message )
2020-07-27 23:13:43 +00:00
{
2020-08-17 17:25:28 +00:00
var player = GetPlayer ( message . AboutId ) ;
2020-07-30 19:57:39 +00:00
player . Name = message . PlayerName ;
2020-08-10 10:45:24 +00:00
player . IsReady = message . PlayerReady ;
player . State = message . PlayerState ;
2020-08-13 17:25:12 +00:00
if ( LocalPlayer . IsReady )
2020-08-09 20:46:51 +00:00
{
2020-08-10 10:45:24 +00:00
player . UpdateStateObjects ( ) ;
}
2020-07-27 23:13:43 +00:00
}
2020-08-21 20:31:42 +00:00
public static IEnumerable < T > GetSyncObjects < T > ( ) where T : PlayerSyncObject
2020-08-05 19:45:48 +00:00
{
2020-08-23 10:53:11 +00:00
return PlayerSyncObjects . OfType < T > ( ) . Where ( x = > x ! = null ) ;
2020-08-05 19:45:48 +00:00
}
2020-09-04 19:09:25 +00:00
public static T GetSyncObject < T > ( uint id ) where T : PlayerSyncObject
2020-08-14 18:54:15 +00:00
{
2020-09-04 19:36:25 +00:00
return GetSyncObjects < T > ( ) . FirstOrDefault ( x = > x ! = null & & x . AttachedNetId = = id ) ;
2020-08-14 18:54:15 +00:00
}
2020-09-04 19:09:25 +00:00
public static bool IsBelongingToLocalPlayer ( uint id )
2020-08-07 19:57:29 +00:00
{
2020-09-04 19:36:25 +00:00
return id = = LocalPlayerId | |
PlayerSyncObjects . Any ( x = > x ! = null & & x . AttachedNetId = = id & & x . isLocalPlayer ) ;
2020-09-02 10:17:04 +00:00
}
2020-09-04 19:09:25 +00:00
public static uint GetPlayerOfObject ( this PlayerSyncObject syncObject )
2020-09-02 10:17:04 +00:00
{
2020-09-29 20:34:46 +00:00
if ( PlayerList . Count = = 0 )
{
2020-10-22 20:21:41 +00: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 20:34:46 +00:00
return uint . MaxValue ;
}
2020-10-22 20:21:41 +00:00
// Get all Player IDs
2020-09-02 10:17:04 +00:00
var playerIds = PlayerList . Select ( x = > x . PlayerId ) . ToList ( ) ;
2020-10-22 20:21:41 +00: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 19:52:06 +00:00
var lowerBound = playerIds . Where ( x = > x < = syncObject . AttachedNetId ) . ToList ( ) . Max ( ) ;
2020-10-22 20:21:41 +00: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 19:52:06 +00:00
if ( PlayerList . Count ! = PlayerSyncObjects . Count ( x = > x . GetType ( ) = = syncObject . GetType ( ) ) & & lowerBound = = playerIds . Max ( ) )
2020-09-02 10:17:04 +00:00
{
2020-10-22 20:21:41 +00: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 19:09:25 +00:00
if ( syncObject . PreviousPlayerId ! = uint . MaxValue )
2020-09-04 17:54:53 +00:00
{
return syncObject . PreviousPlayerId ;
}
2020-10-22 20:21:41 +00:00
// If the syncobject is a PlayerTransformSync, make a player.
2020-09-04 19:52:06 +00:00
if ( syncObject . GetType ( ) = = typeof ( PlayerTransformSync ) & & syncObject . AttachedNetId ! = 0 U )
2020-09-02 10:17:04 +00:00
{
2020-09-04 19:52:06 +00:00
return GetPlayer ( syncObject . AttachedNetId ) . PlayerId ;
2020-09-02 10:17:04 +00:00
}
2020-10-22 20:21:41 +00: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 19:09:25 +00:00
syncObject . PreviousPlayerId = uint . MaxValue ;
return uint . MaxValue ;
2020-09-02 10:17:04 +00:00
}
2020-10-22 20:21:41 +00: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 17:54:53 +00:00
syncObject . PreviousPlayerId = lowerBound ;
2020-09-02 10:17:04 +00:00
return lowerBound ;
2020-08-07 19:57:29 +00:00
}
2020-08-20 19:07:40 +00:00
2020-09-04 19:09:25 +00:00
public static List < uint > GetPlayerNetIds ( PlayerInfo player )
2020-08-20 19:07:40 +00:00
{
2020-09-29 20:34:46 +00:00
if ( PlayerSyncObjects . Count = = 0 )
{
return default ;
}
int count = 0 ;
2020-10-22 20:21:41 +00:00
int totalCount = PlayerSyncObjects . Count ;
2020-09-29 20:34:46 +00:00
PlayerSyncObjects . RemoveAll ( x = > x = = null ) ;
PlayerSyncObjects . RemoveAll ( x = > x . GetComponent < NetworkIdentity > ( ) = = null ) ;
2020-10-22 20:21:41 +00:00
if ( PlayerSyncObjects . Count ! = totalCount )
{
DebugLog . ToConsole ( $"Warning - Removed {totalCount - PlayerSyncObjects.Count} items from PlayerSyncObjects." , MessageType . Warning ) ;
}
2020-09-29 20:34:46 +00:00
foreach ( var item in PlayerSyncObjects . DistinctBy ( x = > x . AttachedNetId ) )
{
if ( item . PlayerId = = player . PlayerId )
{
count + + ;
}
}
2020-09-07 17:57:43 +00:00
return Enumerable . Range ( ( int ) player . PlayerId , count ) . Select ( x = > ( uint ) x ) . ToList ( ) ;
2020-08-20 19:07:40 +00:00
}
2020-07-27 23:13:43 +00:00
}
}