Moved a couple of folders and wrote some code

This commit is contained in:
Madhav Kapa
2023-06-01 11:21:49 -07:00
parent 0eea70ab4e
commit e8684391ca
1380 changed files with 2766 additions and 13987 deletions

View File

@ -0,0 +1,143 @@
using FishNet.Connection;
using FishNet.Object;
using FishNet.Observing;
using FishNet.Utility.Extension;
using System.Collections.Generic;
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 specified distance to view the object.
/// </summary>
[CreateAssetMenu(menuName = "FishNet/Observers/Distance Condition", fileName = "New Distance Condition")]
public class DistanceCondition : ObserverCondition
{
#region Serialized.
/// <summary>
///
/// </summary>
[Tooltip("Maximum distance a client must be within this object to see it.")]
[SerializeField]
private float _maximumDistance = 100f;
/// <summary>
/// Maximum distance a client must be within this object to see it.
/// </summary>
public float MaximumDistance { get => _maximumDistance; set => _maximumDistance = value; }
/// <summary>
/// Additional percent of distance client must be until this object is hidden. For example, if distance was 100f and percent was 0.5f the client must be 150f units away before this object is hidden again. This can be useful for keeping objects from regularly appearing and disappearing.
/// </summary>
[Tooltip("Additional percent of distance client must be until this object is hidden. For example, if distance was 100f and percent was 0.5f the client must be 150f units away before this object is hidden again. This can be useful for keeping objects from regularly appearing and disappearing.")]
[Range(0f, 1f)]
[SerializeField]
private float _hideDistancePercent = 0.1f;
/// <summary>
///
/// </summary>
[Tooltip("How often this condition may change for a connection. This prevents objects from appearing and disappearing rapidly. A value of 0f will cause the object the update quickly as possible while any other value will be used as a delay.")]
[Range(0f, 60f)]
[SerializeField]
private float _updateFrequency;
/// <summary>
/// How often this condition may change for a connection. This prevents objects from appearing and disappearing rapidly. A value of 0f will cause the object the update quickly as possible while any other value will be used as a delay.
/// </summary>
public float UpdateFrequency { get => _updateFrequency; set => _updateFrequency = value; }
#endregion
#region Private.
/// <summary>
/// Tracks when connections may be updated for this object.
/// </summary>
private Dictionary<NetworkConnection, float> _timedUpdates = new Dictionary<NetworkConnection, float>();
#endregion
public void ConditionConstructor(float maximumDistance, float updateFrequency)
{
MaximumDistance = maximumDistance;
_updateFrequency = updateFrequency;
}
/// <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>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public override bool ConditionMet(NetworkConnection connection, bool currentlyAdded, out bool notProcessed)
{
if (_updateFrequency > 0f)
{
float nextAllowedUpdate;
float currentTime = Time.time;
if (!_timedUpdates.TryGetValueIL2CPP(connection, out nextAllowedUpdate))
{
_timedUpdates[connection] = (currentTime + _updateFrequency);
}
else
{
//Not enough time to process again.
if (currentTime < nextAllowedUpdate)
{
notProcessed = true;
//The return does not really matter since notProcessed is returned.
return false;
}
//Can process again.
else
{
_timedUpdates[connection] = (currentTime + _updateFrequency);
}
}
}
//If here then checks are being processed.
notProcessed = false;
float sqrMaximumDistance;
/* If already visible then use additional
* distance to determine when to hide. */
if (currentlyAdded)
{
float maxModified = (MaximumDistance * (1f + _hideDistancePercent));
sqrMaximumDistance = (maxModified * maxModified);
}
//Not visible, use normal distance.
else
{
sqrMaximumDistance = (MaximumDistance * MaximumDistance);
}
Vector3 thisPosition = NetworkObject.transform.position;
foreach (NetworkObject nob in connection.Objects)
{
//If within distance.
if (Vector3.SqrMagnitude(nob.transform.position - thisPosition) <= sqrMaximumDistance)
return true;
}
/* If here no client objects are within distance. */
return false;
}
/// <summary>
/// True if the condition requires regular updates.
/// </summary>
/// <returns></returns>
public override bool Timed()
{
return true;
}
/// <summary>
/// Clones referenced ObserverCondition. This must be populated with your conditions settings.
/// </summary>
/// <returns></returns>
public override ObserverCondition Clone()
{
DistanceCondition copy = ScriptableObject.CreateInstance<DistanceCondition>();
copy.ConditionConstructor(MaximumDistance, _updateFrequency);
return copy;
}
}
}

View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 7c3e28fa2e37d1d41b4f63c8a0cc2553
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,30 @@
using FishNet.Connection;
using FishNet.Observing;
using UnityEngine;
namespace FishNet.Component.Observing
{
[CreateAssetMenu(menuName = "FishNet/Observers/Host Only Condition", fileName = "New Host Only Condition")]
public class HostOnlyCondition : ObserverCondition
{
public override bool ConditionMet(NetworkConnection connection, bool currentlyAdded, out bool notProcessed)
{
notProcessed = false;
/* Only return true if connection is the local client.
* This check only runs on the server, so if local client
* is true then they must also be the server (clientHost). */
return (base.NetworkObject.ClientManager.Connection == connection);
}
public override bool Timed()
{
return false;
}
public override ObserverCondition Clone()
{
HostOnlyCondition copy = ScriptableObject.CreateInstance<HostOnlyCondition>();
return copy;
}
}
}

View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: aa62c0af0c0a4da46b03309dcd3858c3
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,585 @@
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;
}
}
}

View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 5afdd6c2de1c76f4faa6840cc29fda8a
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,47 @@
using FishNet.Connection;
using FishNet.Observing;
using UnityEngine;
namespace FishNet.Component.Observing
{
/// <summary>
/// This condition makes an object only visible to the owner.
/// </summary>
[CreateAssetMenu(menuName = "FishNet/Observers/Owner Only Condition", fileName = "New Owner Only Condition")]
public class OwnerOnlyCondition : ObserverCondition
{
/// <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 currentlyAdded, out bool notProcessed)
{
notProcessed = false;
/* Returning false immediately indicates no connection will
* meet this condition. */
return false;
}
/// <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()
{
OwnerOnlyCondition copy = ScriptableObject.CreateInstance<OwnerOnlyCondition>();
return copy;
}
}
}

View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 1ca3d8a36a10fd344806a2df999f3eda
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,88 @@
using FishNet.Connection;
using FishNet.Observing;
using UnityEngine;
using UnityEngine.SceneManagement;
namespace FishNet.Component.Observing
{
/// <summary>
/// When this observer condition is placed on an object, a client must be within the same scene to view the object.
/// </summary>
[CreateAssetMenu(menuName = "FishNet/Observers/Scene Condition", fileName = "New Scene Condition")]
public class SceneCondition : ObserverCondition
{
#region Serialized.
///// <summary>
///// True to synchronize which scene the object was spawned in to clients. When true this object will be moved to the clients equivelant of the scene it was spawned in on the server. This setting does not continously move this object to the same scene.
///// </summary>
//[Tooltip("True to synchronize which scene the object was spawned in to clients. When true this object will be moved to the clients equivelant of the scene it was spawned in on the server. This setting does not continously move this object to the same scene.")]
//[SerializeField]
//private bool _synchronizeScene;
#endregion
public void ConditionConstructor()
{
//_synchronizeScene = synchronizeScene;
}
/// <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 currentlyAdded, out bool notProcessed)
{
notProcessed = false;
/* If this objects connection is valid then check if
* connection and this objects owner shares any scenes.
* Don't check if the object resides in the same scene
* because thats not reliable as server might be moving
* objects. */
if (base.NetworkObject.Owner.IsValid)
{
foreach (Scene s in base.NetworkObject.Owner.Scenes)
{
//Scenes match.
if (connection.Scenes.Contains(s))
return true;
}
//Fall through, no scenes shared.
return false;
}
/* If there is no owner as a fallback see if
* the connection is in the same scene as this object. */
else
{
/* When there is no owner only then is the gameobject
* scene checked. That's the only way to know at this point. */
return connection.Scenes.Contains(base.NetworkObject.gameObject.scene);
}
}
/// <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()
{
SceneCondition copy = ScriptableObject.CreateInstance<SceneCondition>();
//copy.ConditionConstructor(_synchronizeScene);
copy.ConditionConstructor();
return copy;
}
}
}

View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: fab85d1c51ee2c344b7dd914dc262ec4
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 3d6d71fdcee27584d8d47bef4455a5f9
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,18 @@
%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
--- !u!114 &11400000
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 0}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 7c3e28fa2e37d1d41b4f63c8a0cc2553, type: 3}
m_Name: DistanceCondition
m_EditorClassIdentifier:
NetworkObject: {fileID: 0}
_maximumDistance: 10
_hideDistancePercent: 0.1
_updateFrequency: 0

View File

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 5f33eb0e5b83b5546822cfe42a305657
NativeFormatImporter:
externalObjects: {}
mainObjectFileID: 11400000
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,15 @@
%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
--- !u!114 &11400000
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 0}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: aa62c0af0c0a4da46b03309dcd3858c3, type: 3}
m_Name: HostOnlyCondition
m_EditorClassIdentifier:
NetworkObject: {fileID: 0}

View File

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 9ff842b44ec59314d9efcecbcdbaac04
NativeFormatImporter:
externalObjects: {}
mainObjectFileID: 11400000
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,15 @@
%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
--- !u!114 &11400000
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 0}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 5afdd6c2de1c76f4faa6840cc29fda8a, type: 3}
m_Name: MatchCondition
m_EditorClassIdentifier:
NetworkObject: {fileID: 0}

View File

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: efcd7f0dfd341ed4e8671079e91e0544
NativeFormatImporter:
externalObjects: {}
mainObjectFileID: 11400000
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,15 @@
%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
--- !u!114 &11400000
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 0}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 1ca3d8a36a10fd344806a2df999f3eda, type: 3}
m_Name: OwnerOnlyCondition
m_EditorClassIdentifier:
NetworkObject: {fileID: 0}

View File

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: bcf92670d91dbb74dad77c56b9b8712e
NativeFormatImporter:
externalObjects: {}
mainObjectFileID: 11400000
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,17 @@
%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
--- !u!114 &11400000
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 0}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: fab85d1c51ee2c344b7dd914dc262ec4, type: 3}
m_Name: SceneCondition
m_EditorClassIdentifier:
NetworkObject: {fileID: 0}
_synchronizeScene: 1
_timed: 0

View File

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 2033f54fd2794464bae08fa5a55c8996
NativeFormatImporter:
externalObjects: {}
mainObjectFileID: 11400000
userData:
assetBundleName:
assetBundleVariant: