121 lines
		
	
	
		
			4.1 KiB
		
	
	
	
		
			C#
		
	
	
	
	
	
			
		
		
	
	
			121 lines
		
	
	
		
			4.1 KiB
		
	
	
	
		
			C#
		
	
	
	
	
	
| using FishNet.Connection;
 | |
| using FishNet.Managing;
 | |
| using FishNet.Managing.Logging;
 | |
| using FishNet.Managing.Server;
 | |
| using FishNet.Object;
 | |
| using FishNet.Object.Synchronizing;
 | |
| using UnityEngine;
 | |
| 
 | |
| namespace FishNet.Component.Ownership
 | |
| {
 | |
|     /// <summary>
 | |
|     /// Adding this component allows any client to take ownership of the object and begin modifying it immediately.
 | |
|     /// </summary>
 | |
|     public class PredictedOwner : NetworkBehaviour
 | |
|     {
 | |
|         #region Public.
 | |
|         /// <summary>
 | |
|         /// True if the local client used TakeOwnership and is awaiting an ownership change.
 | |
|         /// </summary>
 | |
|         public bool TakingOwnership { get; private set; }
 | |
|         /// <summary>
 | |
|         /// Owner on client prior to taking ownership. This can be used to reverse a failed ownership attempt.
 | |
|         /// </summary>
 | |
|         public NetworkConnection PreviousOwner { get; private set; } = NetworkManager.EmptyConnection;
 | |
|         #endregion
 | |
| 
 | |
|         #region Serialized.
 | |
|         /// <summary>
 | |
|         /// True if to enable this component.
 | |
|         /// </summary>
 | |
|         [Tooltip("True if to enable this component.")]
 | |
|         [SyncVar(SendRate = 0f)]
 | |
|         [SerializeField]
 | |
|         private bool _allowTakeOwnership = true;
 | |
|         /// <summary>
 | |
|         /// Sets the next value for AllowTakeOwnership and synchronizes it.
 | |
|         /// Only the server may use this method.
 | |
|         /// </summary>
 | |
|         /// <param name="value">Next value to use.</param>
 | |
|         [Server]
 | |
|         public void SetAllowTakeOwnership(bool value) => _allowTakeOwnership = value;
 | |
|         #endregion
 | |
| 
 | |
|         /// <summary>
 | |
|         /// Called on the client after gaining or losing ownership.
 | |
|         /// </summary>
 | |
|         /// <param name="prevOwner">Previous owner of this object.</param>
 | |
|         public override void OnOwnershipClient(NetworkConnection prevOwner)
 | |
|         {
 | |
|             base.OnOwnershipClient(prevOwner);
 | |
|             /* Unset taken ownership either way.
 | |
|             * If the new owner it won't be used,
 | |
|             * if no longer owner then another client
 | |
|             * took it. */
 | |
|             TakingOwnership = false;
 | |
|             PreviousOwner = base.Owner;
 | |
|         }
 | |
| 
 | |
|         /// <summary>
 | |
|         /// Takes ownership of this object to the local client and allows immediate control.
 | |
|         /// </summary>
 | |
|         [Client]
 | |
|         public virtual void TakeOwnership()
 | |
|         {
 | |
|             if (!_allowTakeOwnership)
 | |
|                 return;
 | |
|             //Already owner.
 | |
|             if (base.IsOwner)
 | |
|                 return;
 | |
| 
 | |
|             NetworkConnection c = base.ClientManager.Connection;
 | |
|             TakingOwnership = true;
 | |
|             //If not server go through the server.
 | |
|             if (!base.IsServer)
 | |
|             {
 | |
|                 base.NetworkObject.SetLocalOwnership(c);
 | |
|                 ServerTakeOwnership();
 | |
|             }
 | |
|             //Otherwise take directly without rpcs.
 | |
|             else
 | |
|             {
 | |
|                 OnTakeOwnership(c);
 | |
|             }
 | |
|         }
 | |
| 
 | |
| 
 | |
|         /// <summary>
 | |
|         /// Takes ownership of this object.
 | |
|         /// </summary>
 | |
|         [ServerRpc(RequireOwnership = false)]
 | |
|         private void ServerTakeOwnership(NetworkConnection caller = null)
 | |
|         {
 | |
|             OnTakeOwnership(caller);
 | |
|         }
 | |
| 
 | |
|         /// <summary>
 | |
|         /// Called on the server when a client tries to take ownership of this object.
 | |
|         /// </summary>
 | |
|         /// <param name="caller">Connection trying to take ownership.</param>
 | |
|         [Server]
 | |
|         protected virtual void OnTakeOwnership(NetworkConnection caller)
 | |
|         {
 | |
|             //Client somehow disconnected between here and there.
 | |
|             if (!caller.IsActive)
 | |
|                 return;
 | |
|             //Feature is not enabled.
 | |
|             if (!_allowTakeOwnership)
 | |
|                 return;
 | |
|             //Already owner.
 | |
|             if (caller == base.Owner)
 | |
|                 return;
 | |
| 
 | |
|             base.GiveOwnership(caller);
 | |
|             /* No need to send a response back because an ownershipchange will handle changes.
 | |
|              * Although if you were to override with this your own behavior
 | |
|              * you could send responses for approved/denied. */
 | |
|         }
 | |
| 
 | |
|     }
 | |
| 
 | |
| } |