Merge remote-tracking branch 'origin/feat/inport-props' into feat/craft-discovery
# Conflicts: # Assets/External/Animated PBR Chest Demo/Materials/WoodChest.mat # Packages/com.distantlands.cozy.core/Content/Integration/Import for BiRP.unitypackage.meta # Packages/com.distantlands.cozy.core/Content/Integration/Import for HDRP.unitypackage.meta # Packages/com.distantlands.cozy.core/Content/Integration/Import for URP.unitypackage.meta
This commit is contained in:
@@ -0,0 +1,48 @@
|
||||
using FishNet.Connection;
|
||||
using FishNet.Object;
|
||||
using Ashwild.Inventory;
|
||||
|
||||
namespace Ashwild.Network
|
||||
{
|
||||
/// <summary>
|
||||
/// Server-side lookup of the player systems belonging to a connection. Every server-authoritative
|
||||
/// interaction (pickup, harvest, chest, cooking station, build refund) needs the requesting player's
|
||||
/// inventory, and they all used to resolve it through <c>conn.FirstObject</c>.
|
||||
///
|
||||
/// That is unsafe: a connection owns more than one NetworkObject (the build ghost is spawned with the
|
||||
/// player as owner), FishNet stores them in an unordered <c>HashSet</c>, and it re-picks FirstObject
|
||||
/// from that set whenever the current one is despawned. FirstObject can therefore resolve to the ghost
|
||||
/// instead of the player — a null inventory, and a silently lost grant. Scanning the connection's
|
||||
/// objects for the component we actually want removes the guesswork.
|
||||
/// </summary>
|
||||
public static class NetworkPlayerLookup
|
||||
{
|
||||
#region Public API
|
||||
|
||||
/// <summary>
|
||||
/// Returns the inventory of the player owned by this connection, or null when the connection has
|
||||
/// no player object (disconnecting, or not spawned yet).
|
||||
/// </summary>
|
||||
public static PlayerInventory ResolveInventory(NetworkConnection conn) => Resolve<PlayerInventory>(conn);
|
||||
|
||||
/// <summary>
|
||||
/// Returns the first component of the requested type found on any NetworkObject this connection
|
||||
/// owns. Checks FirstObject before scanning, since it is the right answer in the common case.
|
||||
/// </summary>
|
||||
public static T Resolve<T>(NetworkConnection conn) where T : class
|
||||
{
|
||||
if (conn == null) return null;
|
||||
|
||||
NetworkObject first = conn.FirstObject;
|
||||
if (first != null && first.TryGetComponent(out T fromFirst)) return fromFirst;
|
||||
|
||||
foreach (NetworkObject nob in conn.Objects)
|
||||
{
|
||||
if (nob != null && nob.TryGetComponent(out T component)) return component;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user