forked from cgvr/DeltaVR
		
	
		
			
				
	
	
		
			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. */
 | 
						|
        }
 | 
						|
 | 
						|
    }
 | 
						|
 | 
						|
} |