586 lines
25 KiB
C#
586 lines
25 KiB
C#
|
using FishNet.Connection;
|
|||
|
using FishNet.Managing;
|
|||
|
using FishNet.Managing.Logging;
|
|||
|
using FishNet.Managing.Server;
|
|||
|
using FishNet.Object;
|
|||
|
using FishNet.Observing;
|
|||
|
using FishNet.Utility.Extension;
|
|||
|
using FishNet.Utility.Performance;
|
|||
|
using System.Collections.Generic;
|
|||
|
using System.Linq;
|
|||
|
using System.Runtime.CompilerServices;
|
|||
|
using UnityEngine;
|
|||
|
|
|||
|
namespace FishNet.Component.Observing
|
|||
|
{
|
|||
|
/// <summary>
|
|||
|
/// When this observer condition is placed on an object, a client must be within the same match to view the object.
|
|||
|
/// </summary>
|
|||
|
[CreateAssetMenu(menuName = "FishNet/Observers/Match Condition", fileName = "New Match Condition")]
|
|||
|
public class MatchCondition : ObserverCondition
|
|||
|
{
|
|||
|
#region Private.
|
|||
|
/// <summary>
|
|||
|
///
|
|||
|
/// </summary>
|
|||
|
private static Dictionary<int, HashSet<NetworkConnection>> _matchConnections = new Dictionary<int, HashSet<NetworkConnection>>();
|
|||
|
/// <summary>
|
|||
|
/// Matches and connections in each match.
|
|||
|
/// </summary>
|
|||
|
public static IReadOnlyDictionary<int, HashSet<NetworkConnection>> MatchConnections => _matchConnections;
|
|||
|
/// <summary>
|
|||
|
///
|
|||
|
/// </summary>
|
|||
|
/// //todo this needs to hold hashset so conns can be in multiple matches.
|
|||
|
private static Dictionary<NetworkConnection, int> _connectionMatch = new Dictionary<NetworkConnection, int>();
|
|||
|
/// <summary>
|
|||
|
/// Match a connection is in.
|
|||
|
/// </summary>
|
|||
|
public static IReadOnlyDictionary<NetworkConnection, int> ConnectionMatch => _connectionMatch;
|
|||
|
/// <summary>
|
|||
|
///
|
|||
|
/// </summary>
|
|||
|
private static Dictionary<int, HashSet<NetworkObject>> _matchObjects = new Dictionary<int, HashSet<NetworkObject>>();
|
|||
|
/// <summary>
|
|||
|
/// Matches and connections in each match.
|
|||
|
/// </summary>
|
|||
|
public static IReadOnlyDictionary<int, HashSet<NetworkObject>> MatchObjects => _matchObjects;
|
|||
|
/// <summary>
|
|||
|
///
|
|||
|
/// </summary>
|
|||
|
/// //todo this needs to hold hashset so conns can be in multiple matches.
|
|||
|
private static Dictionary<NetworkObject, int> _objectMatch = new Dictionary<NetworkObject, int>();
|
|||
|
/// <summary>
|
|||
|
/// Match a connection is in.
|
|||
|
/// </summary>
|
|||
|
public static IReadOnlyDictionary<NetworkObject, int> ObjectMatch => _objectMatch;
|
|||
|
#endregion
|
|||
|
|
|||
|
public void ConditionConstructor() { }
|
|||
|
|
|||
|
#region Add to match NetworkConnection.
|
|||
|
/// <summary>
|
|||
|
/// Adds a connection to a match.
|
|||
|
/// </summary>
|
|||
|
/// <param name="match">Match to add conn to.</param>
|
|||
|
/// <param name="conn">Connection to add to match.</param>
|
|||
|
/// <param name="manager">NetworkManager to rebuild observers on. If null InstanceFinder.NetworkManager will be used.</param>
|
|||
|
/// <param name="replaceMatch">True to replace other matches with the new match.</param>
|
|||
|
public static void AddToMatch(int match, NetworkConnection conn, NetworkManager manager = null, bool replaceMatch = false)
|
|||
|
{
|
|||
|
if (replaceMatch)
|
|||
|
RemoveFromMatchWithoutRebuild(conn, manager);
|
|||
|
|
|||
|
HashSet<NetworkConnection> results;
|
|||
|
if (!_matchConnections.TryGetValueIL2CPP(match, out results))
|
|||
|
{
|
|||
|
results = new HashSet<NetworkConnection>();
|
|||
|
_matchConnections.Add(match, results);
|
|||
|
}
|
|||
|
|
|||
|
bool r = results.Add(conn);
|
|||
|
_connectionMatch[conn] = match;
|
|||
|
if (r)
|
|||
|
FinalizeChange(match, results, manager);
|
|||
|
}
|
|||
|
/// <summary>
|
|||
|
/// Adds connections to a match.
|
|||
|
/// </summary>
|
|||
|
/// <param name="match">Match to add conns to.</param>
|
|||
|
/// <param name="conns">Connections to add to match.</param>
|
|||
|
/// <param name="manager">NetworkManager to rebuild observers on. If null InstanceFinder.NetworkManager will be used.</param>
|
|||
|
/// <param name="replaceMatch">True to replace other matches with the new match.</param>
|
|||
|
public static void AddToMatch(int match, NetworkConnection[] conns, NetworkManager manager = null, bool replaceMatch = false)
|
|||
|
{
|
|||
|
AddToMatch(match, conns.ToList(), manager, replaceMatch);
|
|||
|
}
|
|||
|
/// <summary>
|
|||
|
/// Adds connections to a match.
|
|||
|
/// </summary>
|
|||
|
/// <param name="match">Match to add conns to.</param>
|
|||
|
/// <param name="conns">Connections to add to match.</param>
|
|||
|
/// <param name="manager">NetworkManager to rebuild observers on. If null InstanceFinder.NetworkManager will be used.</param>
|
|||
|
/// <param name="replaceMatch">True to replace other matches with the new match.</param>
|
|||
|
public static void AddToMatch(int match, List<NetworkConnection> conns, NetworkManager manager = null, bool replaceMatch = false)
|
|||
|
{
|
|||
|
if (replaceMatch)
|
|||
|
{
|
|||
|
foreach (NetworkConnection nc in conns)
|
|||
|
RemoveFromMatchWithoutRebuild(nc, manager);
|
|||
|
}
|
|||
|
|
|||
|
HashSet<NetworkConnection> results;
|
|||
|
if (!_matchConnections.TryGetValueIL2CPP(match, out results))
|
|||
|
{
|
|||
|
results = new HashSet<NetworkConnection>();
|
|||
|
_matchConnections.Add(match, results);
|
|||
|
}
|
|||
|
|
|||
|
bool r = false;
|
|||
|
for (int i = 0; i < conns.Count; i++)
|
|||
|
{
|
|||
|
NetworkConnection c = conns[i];
|
|||
|
r |= results.Add(c);
|
|||
|
_connectionMatch[c] = match;
|
|||
|
}
|
|||
|
|
|||
|
if (r)
|
|||
|
FinalizeChange(match, results, manager);
|
|||
|
}
|
|||
|
#endregion
|
|||
|
|
|||
|
#region Add to match NetworkObject.
|
|||
|
/// <summary>
|
|||
|
/// Adds an object to a match.
|
|||
|
/// </summary>
|
|||
|
/// <param name="match">Match to add conn to.</param>
|
|||
|
/// <param name="nob">Connection to add to match.</param>
|
|||
|
/// <param name="manager">NetworkManager to rebuild observers on. If null InstanceFinder.NetworkManager will be used.</param>
|
|||
|
/// <param name="replaceMatch">True to replace other matches with the new match.</param>
|
|||
|
public static void AddToMatch(int match, NetworkObject nob, NetworkManager manager = null, bool replaceMatch = false)
|
|||
|
{
|
|||
|
if (replaceMatch)
|
|||
|
RemoveFromMatchWithoutRebuild(nob, manager);
|
|||
|
|
|||
|
HashSet<NetworkObject> results;
|
|||
|
if (!_matchObjects.TryGetValueIL2CPP(match, out results))
|
|||
|
{
|
|||
|
results = new HashSet<NetworkObject>();
|
|||
|
_matchObjects.Add(match, results);
|
|||
|
}
|
|||
|
|
|||
|
bool r = results.Add(nob);
|
|||
|
_objectMatch[nob] = match;
|
|||
|
|
|||
|
if (r)
|
|||
|
FinalizeChange(match, results, nob, manager);
|
|||
|
}
|
|||
|
/// <summary>
|
|||
|
/// Adds objects to a match.
|
|||
|
/// </summary>
|
|||
|
/// <param name="match">Match to add conns to.</param>
|
|||
|
/// <param name="nobs">Connections to add to match.</param>
|
|||
|
/// <param name="manager">NetworkManager to rebuild observers on. If null InstanceFinder.NetworkManager will be used.</param>
|
|||
|
/// <param name="replaceMatch">True to replace other matches with the new match.</param>
|
|||
|
public static void AddToMatch(int match, NetworkObject[] nobs, NetworkManager manager = null, bool replaceMatch = false)
|
|||
|
{
|
|||
|
AddToMatch(match, nobs.ToList(), manager, replaceMatch);
|
|||
|
}
|
|||
|
/// <summary>
|
|||
|
/// Adds objects to a match.
|
|||
|
/// </summary>
|
|||
|
/// <param name="match">Match to add conns to.</param>
|
|||
|
/// <param name="nobs">Connections to add to match.</param>
|
|||
|
/// <param name="manager">NetworkManager to rebuild observers on. If null InstanceFinder.NetworkManager will be used.</param>
|
|||
|
/// <param name="replaceMatch">True to replace other matches with the new match.</param>
|
|||
|
public static void AddToMatch(int match, List<NetworkObject> nobs, NetworkManager manager = null, bool replaceMatch = false)
|
|||
|
{
|
|||
|
if (replaceMatch)
|
|||
|
{
|
|||
|
foreach (NetworkObject n in nobs)
|
|||
|
RemoveFromMatchWithoutRebuild(n, manager);
|
|||
|
}
|
|||
|
|
|||
|
HashSet<NetworkObject> results;
|
|||
|
if (!_matchObjects.TryGetValueIL2CPP(match, out results))
|
|||
|
{
|
|||
|
results = new HashSet<NetworkObject>();
|
|||
|
_matchObjects.Add(match, results);
|
|||
|
}
|
|||
|
|
|||
|
bool r = false;
|
|||
|
for (int i = 0; i < nobs.Count; i++)
|
|||
|
{
|
|||
|
NetworkObject n = nobs[i];
|
|||
|
r |= results.Add(n);
|
|||
|
_objectMatch[n] = match;
|
|||
|
}
|
|||
|
|
|||
|
if (r)
|
|||
|
FinalizeChange(match, results, nobs, manager);
|
|||
|
}
|
|||
|
#endregion
|
|||
|
|
|||
|
#region Remove from match NetworkConnection.
|
|||
|
/// <summary>
|
|||
|
/// Removes a connection from any match without rebuilding observers.
|
|||
|
/// </summary>
|
|||
|
/// <param name="conn">Connection to remove from matches.</param>
|
|||
|
/// <param name="manager">NetworkManager connection belongs to. This is not currently used.</param>
|
|||
|
internal static bool RemoveFromMatchWithoutRebuild(NetworkConnection conn, NetworkManager manager)
|
|||
|
{
|
|||
|
bool removed = false;
|
|||
|
//If found to be in a match.
|
|||
|
if (_connectionMatch.TryGetValueIL2CPP(conn, out int match))
|
|||
|
{
|
|||
|
//If match is found.
|
|||
|
if (_matchConnections.TryGetValue(match, out HashSet<NetworkConnection> conns))
|
|||
|
{
|
|||
|
removed |= conns.Remove(conn);
|
|||
|
//If no more in hashset remove match.
|
|||
|
if (conns.Count == 0)
|
|||
|
_matchConnections.Remove(match);
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
//Remove from connectionMatch.
|
|||
|
_connectionMatch.Remove(conn);
|
|||
|
return removed;
|
|||
|
}
|
|||
|
/// <summary>
|
|||
|
/// Removes a connection from all matches.
|
|||
|
/// </summary>
|
|||
|
/// <param name="conn">NetworkConnection to remove.</param>
|
|||
|
/// <param name="manager">NetworkManager to rebuild observers on. If null InstanceFinder.NetworkManager will be used.</param>
|
|||
|
public static void RemoveFromMatch(NetworkConnection conn, NetworkManager manager)
|
|||
|
{
|
|||
|
bool removed = RemoveFromMatchWithoutRebuild(conn, manager);
|
|||
|
if (removed)
|
|||
|
GetServerObjects(manager).RebuildObservers();
|
|||
|
}
|
|||
|
/// <summary>
|
|||
|
/// Removes a connection from a match.
|
|||
|
/// </summary>
|
|||
|
/// <param name="match">Match to remove conn from.</param>
|
|||
|
/// <param name="conn">Connection to remove from match.</param>
|
|||
|
/// <param name="manager">NetworkManager to rebuild observers on. If null InstanceFinder.NetworkManager will be used.</param>
|
|||
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|||
|
public static void RemoveFromMatch(int match, NetworkConnection conn, NetworkManager manager)
|
|||
|
{
|
|||
|
if (_matchConnections.TryGetValueIL2CPP(match, out HashSet<NetworkConnection> results))
|
|||
|
{
|
|||
|
bool r = results.Remove(conn);
|
|||
|
_connectionMatch.Remove(conn);
|
|||
|
if (r)
|
|||
|
FinalizeChange(match, results, manager);
|
|||
|
}
|
|||
|
}
|
|||
|
/// <summary>
|
|||
|
/// Removes connections from a match.
|
|||
|
/// </summary>
|
|||
|
/// <param name="match">Match to remove conns from.</param>
|
|||
|
/// <param name="conns">Connections to remove from match.</param>
|
|||
|
/// <param name="manager">NetworkManager to rebuild observers on. If null InstanceFinder.NetworkManager will be used.</param>
|
|||
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|||
|
public static void RemoveFromMatch(int match, NetworkConnection[] conns, NetworkManager manager)
|
|||
|
{
|
|||
|
if (_matchConnections.TryGetValueIL2CPP(match, out HashSet<NetworkConnection> results))
|
|||
|
{
|
|||
|
bool r = false;
|
|||
|
for (int i = 0; i < conns.Length; i++)
|
|||
|
{
|
|||
|
NetworkConnection c = conns[i];
|
|||
|
r |= results.Remove(c);
|
|||
|
_connectionMatch.Remove(c);
|
|||
|
}
|
|||
|
|
|||
|
if (r)
|
|||
|
FinalizeChange(match, results, manager);
|
|||
|
}
|
|||
|
}
|
|||
|
/// <summary>
|
|||
|
/// Removes connections from a match.
|
|||
|
/// </summary>
|
|||
|
/// <param name="match">Match to remove conns from.</param>
|
|||
|
/// <param name="conns">Connections to remove from match.</param>
|
|||
|
/// <param name="manager">NetworkManager to rebuild observers on. If null InstanceFinder.NetworkManager will be used.</param>
|
|||
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|||
|
public static void RemoveFromMatch(int match, List<NetworkConnection> conns, NetworkManager manager)
|
|||
|
{
|
|||
|
if (_matchConnections.TryGetValueIL2CPP(match, out HashSet<NetworkConnection> results))
|
|||
|
{
|
|||
|
bool r = false;
|
|||
|
for (int i = 0; i < conns.Count; i++)
|
|||
|
{
|
|||
|
NetworkConnection c = conns[i];
|
|||
|
r |= results.Remove(c);
|
|||
|
_connectionMatch.Remove(c);
|
|||
|
}
|
|||
|
|
|||
|
if (r)
|
|||
|
FinalizeChange(match, results, manager);
|
|||
|
}
|
|||
|
}
|
|||
|
#endregion
|
|||
|
|
|||
|
#region Remove from match NetworkObject.
|
|||
|
/// <summary>
|
|||
|
/// Removes a network object from any match without rebuilding observers.
|
|||
|
/// </summary>
|
|||
|
/// <param name="nob">NetworkObject to remove.</param>
|
|||
|
/// <param name="manager">Manager which the network object belongs to. This value is not yet used.</param>
|
|||
|
internal static bool RemoveFromMatchWithoutRebuild(NetworkObject nob, NetworkManager manager = null)
|
|||
|
{
|
|||
|
bool removed = false;
|
|||
|
//If found to be in a match.
|
|||
|
if (_objectMatch.TryGetValueIL2CPP(nob, out int match))
|
|||
|
{
|
|||
|
//If match is found.
|
|||
|
if (_matchObjects.TryGetValue(match, out HashSet<NetworkObject> nobs))
|
|||
|
{
|
|||
|
removed |= nobs.Remove(nob);
|
|||
|
//If no more in hashset remove match.
|
|||
|
if (nobs.Count == 0)
|
|||
|
_matchObjects.Remove(match);
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
//Remove from connectionMatch.
|
|||
|
_objectMatch.Remove(nob);
|
|||
|
return removed;
|
|||
|
}
|
|||
|
/// <summary>
|
|||
|
/// Removes nob from all matches.
|
|||
|
/// </summary>
|
|||
|
/// <param name="nob">NetworkObject to remove.</param>
|
|||
|
/// <param name="manager">NetworkManager to rebuild observers on. If null InstanceFinder.NetworkManager will be used.</param>
|
|||
|
public static void RemoveFromMatch(NetworkObject nob, NetworkManager manager = null)
|
|||
|
{
|
|||
|
bool removed = RemoveFromMatchWithoutRebuild(nob, manager);
|
|||
|
if (removed)
|
|||
|
GetServerObjects(manager).RebuildObservers(nob);
|
|||
|
}
|
|||
|
/// <summary>
|
|||
|
/// Removes a network object from all matches.
|
|||
|
/// </summary>
|
|||
|
/// <param name="nobs">NetworkObjects to remove.</param>
|
|||
|
/// <param name="manager">NetworkManager to rebuild observers on. If null InstanceFinder.NetworkManager will be used.</param>
|
|||
|
public static void RemoveFromMatch(NetworkObject[] nobs, NetworkManager manager = null)
|
|||
|
{
|
|||
|
RemoveFromMatch(nobs.ToList(), manager);
|
|||
|
}
|
|||
|
/// <summary>
|
|||
|
/// Removes network objects from all matches.
|
|||
|
/// </summary>
|
|||
|
/// <param name="nobs">NetworkObjects to remove.</param>
|
|||
|
/// <param name="manager">NetworkManager to rebuild observers on. If null InstanceFinder.NetworkManager will be used.</param>
|
|||
|
public static void RemoveFromMatch(List<NetworkObject> nobs, NetworkManager manager = null)
|
|||
|
{
|
|||
|
bool removed = false;
|
|||
|
foreach (NetworkObject n in nobs)
|
|||
|
removed |= RemoveFromMatchWithoutRebuild(n, manager);
|
|||
|
|
|||
|
if (removed)
|
|||
|
GetServerObjects(manager).RebuildObservers(nobs);
|
|||
|
}
|
|||
|
/// <summary>
|
|||
|
/// Removes a network object from a match.
|
|||
|
/// </summary>
|
|||
|
/// <param name="match">Match to remove conn from.</param>
|
|||
|
/// <param name="nob">NetworkObject to remove from match.</param>
|
|||
|
/// <param name="manager">NetworkManager to rebuild observers on. If null InstanceFinder.NetworkManager will be used.</param>
|
|||
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|||
|
public static void RemoveFromMatch(int match, NetworkObject nob, NetworkManager manager = null)
|
|||
|
{
|
|||
|
if (_matchObjects.TryGetValueIL2CPP(match, out HashSet<NetworkObject> results))
|
|||
|
{
|
|||
|
bool r = results.Remove(nob);
|
|||
|
_objectMatch.Remove(nob);
|
|||
|
if (r)
|
|||
|
FinalizeChange(match, results, nob, manager);
|
|||
|
}
|
|||
|
}
|
|||
|
/// <summary>
|
|||
|
/// Removes network objects from a match.
|
|||
|
/// </summary>
|
|||
|
/// <param name="match">Match to remove conns from.</param>
|
|||
|
/// <param name="nobs">NetworkObjects to remove from match.</param>
|
|||
|
/// <param name="manager">NetworkManager to rebuild observers on. If null InstanceFinder.NetworkManager will be used.</param>
|
|||
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|||
|
public static void RemoveFromMatch(int match, NetworkObject[] nobs, NetworkManager manager = null)
|
|||
|
{
|
|||
|
if (_matchObjects.TryGetValueIL2CPP(match, out HashSet<NetworkObject> results))
|
|||
|
{
|
|||
|
bool r = false;
|
|||
|
for (int i = 0; i < nobs.Length; i++)
|
|||
|
{
|
|||
|
NetworkObject n = nobs[i];
|
|||
|
r |= results.Remove(n);
|
|||
|
_objectMatch.Remove(n);
|
|||
|
}
|
|||
|
|
|||
|
if (r)
|
|||
|
FinalizeChange(match, results, nobs, manager);
|
|||
|
}
|
|||
|
}
|
|||
|
/// <summary>
|
|||
|
/// Removes network objects from a match.
|
|||
|
/// </summary>
|
|||
|
/// <param name="match">Match to remove conns from.</param>
|
|||
|
/// <param name="nobs">NetworkObjects to remove from match.</param>
|
|||
|
/// <param name="manager">NetworkManager to rebuild observers on. If null InstanceFinder.NetworkManager will be used.</param>
|
|||
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|||
|
public static void RemoveFromMatch(int match, List<NetworkObject> nobs, NetworkManager manager = null)
|
|||
|
{
|
|||
|
if (_matchObjects.TryGetValueIL2CPP(match, out HashSet<NetworkObject> results))
|
|||
|
{
|
|||
|
bool r = false;
|
|||
|
for (int i = 0; i < nobs.Count; i++)
|
|||
|
{
|
|||
|
NetworkObject n = nobs[i];
|
|||
|
r |= results.Remove(n);
|
|||
|
_objectMatch.Remove(n);
|
|||
|
}
|
|||
|
|
|||
|
if (r)
|
|||
|
FinalizeChange(match, results, nobs, manager);
|
|||
|
}
|
|||
|
}
|
|||
|
#endregion
|
|||
|
|
|||
|
#region FinalizeChange NetworkConnection.
|
|||
|
/// <summary>
|
|||
|
/// Finalizes changes to observers.
|
|||
|
/// </summary>
|
|||
|
private static void FinalizeChange(int match, HashSet<NetworkConnection> remainingConnsInMatch, NetworkManager manager)
|
|||
|
{
|
|||
|
if (remainingConnsInMatch.Count == 0)
|
|||
|
_matchConnections.Remove(match);
|
|||
|
|
|||
|
/* Observers on all objects and all conditions have to be rebuilt.
|
|||
|
* This is because the connection changing matches could
|
|||
|
* require the connection to be visible for other players in the match,
|
|||
|
* as well make other connections in the same match visible.
|
|||
|
* But also make all the objects not associated with connections
|
|||
|
* of that match visible. In result to tick all of those boxes
|
|||
|
* all objects need to be rebuilt for all connections. */
|
|||
|
GetServerObjects(manager).RebuildObservers();
|
|||
|
}
|
|||
|
#endregion
|
|||
|
|
|||
|
#region FinalizeChange NetworkObject.
|
|||
|
/// <summary>
|
|||
|
/// Finalizes changes to observers.
|
|||
|
/// </summary>
|
|||
|
private static void FinalizeChange(int match, HashSet<NetworkObject> results, List<NetworkObject> nobs, NetworkManager manager)
|
|||
|
{
|
|||
|
ListCache<NetworkObject> cache = ListCaches.GetNetworkObjectCache();
|
|||
|
cache.AddValues(nobs);
|
|||
|
FinalizeChange(match, results, cache, manager);
|
|||
|
ListCaches.StoreCache(cache);
|
|||
|
}
|
|||
|
/// <summary>
|
|||
|
/// Finalizes changes to observers.
|
|||
|
/// </summary>
|
|||
|
private static void FinalizeChange(int match, HashSet<NetworkObject> results, NetworkObject[] nobs, NetworkManager manager)
|
|||
|
{
|
|||
|
ListCache<NetworkObject> cache = ListCaches.GetNetworkObjectCache();
|
|||
|
cache.AddValues(nobs);
|
|||
|
FinalizeChange(match, results, cache, manager);
|
|||
|
ListCaches.StoreCache(cache);
|
|||
|
}
|
|||
|
/// <summary>
|
|||
|
/// Finalizes changes to observers.
|
|||
|
/// </summary>
|
|||
|
private static void FinalizeChange(int match, HashSet<NetworkObject> results, NetworkObject nob, NetworkManager manager)
|
|||
|
{
|
|||
|
ListCache<NetworkObject> cache = ListCaches.GetNetworkObjectCache();
|
|||
|
cache.AddValue(nob);
|
|||
|
FinalizeChange(match, results, cache, manager);
|
|||
|
ListCaches.StoreCache(cache);
|
|||
|
}
|
|||
|
/// <summary>
|
|||
|
/// Finalizes changes to observers.
|
|||
|
/// </summary>
|
|||
|
private static void FinalizeChange(int match, HashSet<NetworkObject> results, ListCache<NetworkObject> nobs, NetworkManager manager)
|
|||
|
{
|
|||
|
if (results.Count == 0)
|
|||
|
_matchConnections.Remove(match);
|
|||
|
|
|||
|
GetServerObjects(manager).RebuildObservers(nobs);
|
|||
|
}
|
|||
|
#endregion
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// Returns if the object which this condition resides should be visible to connection.
|
|||
|
/// </summary>
|
|||
|
/// <param name="connection">Connection which the condition is being checked for.</param>
|
|||
|
/// <param name="currentlyAdded">True if the connection currently has visibility of this object.</param>
|
|||
|
/// <param name="notProcessed">True if the condition was not processed. This can be used to skip processing for performance. While output as true this condition result assumes the previous ConditionMet value.</param>
|
|||
|
public override bool ConditionMet(NetworkConnection connection, bool alreadyAdded, out bool notProcessed)
|
|||
|
{
|
|||
|
//If here then checks are being processed.
|
|||
|
notProcessed = false;
|
|||
|
NetworkConnection owner = base.NetworkObject.Owner;
|
|||
|
/* If object is owned then check if owner
|
|||
|
* and connection share a match. */
|
|||
|
if (owner.IsValid)
|
|||
|
{
|
|||
|
//Connection isn't in a match.
|
|||
|
if (!_connectionMatch.TryGetValueIL2CPP(connection, out int match))
|
|||
|
{
|
|||
|
//Return if this owner is also not in a match.
|
|||
|
return !_connectionMatch.TryGetValueIL2CPP(owner, out int _);
|
|||
|
}
|
|||
|
//Match isn't found.
|
|||
|
if (!_matchConnections.TryGetValueIL2CPP(match, out HashSet<NetworkConnection> conns))
|
|||
|
return false;
|
|||
|
//If owner is in same match return true.
|
|||
|
return conns.Contains(owner);
|
|||
|
}
|
|||
|
/* If no owner see if the object is in a match and if so
|
|||
|
* then compare that. */
|
|||
|
else
|
|||
|
{
|
|||
|
//Object isn't in a match.
|
|||
|
if (!_objectMatch.TryGetValueIL2CPP(base.NetworkObject, out int objectMatch))
|
|||
|
return true;
|
|||
|
/* See if connection is in the same match as the object.
|
|||
|
* If connection isn't in a match then it fails. */
|
|||
|
if (!_connectionMatch.TryGetValueIL2CPP(connection, out int connectionMatch))
|
|||
|
return false;
|
|||
|
return (connectionMatch == objectMatch);
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// Returns which ServerObjects to rebuild observers on.
|
|||
|
/// </summary>
|
|||
|
/// <param name="nm"></param>
|
|||
|
/// <returns></returns>
|
|||
|
private static ServerObjects GetServerObjects(NetworkManager manager)
|
|||
|
{
|
|||
|
return (manager == null) ? InstanceFinder.ServerManager.Objects : manager.ServerManager.Objects;
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
/* //todo this needs to be passing in the network manager to clear on,
|
|||
|
* otherwise only a single instance of NM is supported.
|
|||
|
* Users are already forced to specify which NM to add
|
|||
|
* matches for but the functionality separating different NMs in relation
|
|||
|
* to such isn't done yet. */
|
|||
|
/// <summary>
|
|||
|
/// Clears all match information without rebuilding.
|
|||
|
/// </summary>
|
|||
|
internal static void ClearMatchesWithoutRebuilding()
|
|||
|
{
|
|||
|
_connectionMatch.Clear();
|
|||
|
_matchConnections.Clear();
|
|||
|
_objectMatch.Clear();
|
|||
|
_matchObjects.Clear();
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// True if the condition requires regular updates.
|
|||
|
/// </summary>
|
|||
|
/// <returns></returns>
|
|||
|
public override bool Timed()
|
|||
|
{
|
|||
|
return false;
|
|||
|
}
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// Clones referenced ObserverCondition. This must be populated with your conditions settings.
|
|||
|
/// </summary>
|
|||
|
/// <returns></returns>
|
|||
|
public override ObserverCondition Clone()
|
|||
|
{
|
|||
|
MatchCondition copy = ScriptableObject.CreateInstance<MatchCondition>();
|
|||
|
copy.ConditionConstructor();
|
|||
|
return copy;
|
|||
|
}
|
|||
|
}
|
|||
|
}
|