예제 #1
0
 /// <summary>
 /// Validates if the performer is in range and capable of interaction -  all the typical requirements for all
 /// various interactions. Works properly even if player is hidden in a ClosetControl. Can also optionally allow soft crit.
 ///
 /// </summary>
 /// <param name="player">player performing the interaction</param>
 /// <param name="target">target object</param>
 /// <param name="side">side of the network this is being checked on</param>
 /// <param name="allowSoftCrit">whether to allow interaction while in soft crit</param>
 /// <param name="reachRange">range to allow</param>
 /// <param name="targetVector">target vector pointing from performer to the position they are trying to click,
 /// if specified will use this to determine if in range rather than target object position.</param>
 /// <param name="targetRegisterTile">target's register tile component. If you specify this it avoids garbage. Please provide this
 /// if you can do so without using GetComponent, especially if you are calling this frequently.
 /// This is an optimization so GetComponent call can be avoided to avoid
 /// creating garbage.</param>
 /// <returns></returns>
 public static bool CanApply(GameObject player, GameObject target, NetworkSide side, bool allowSoftCrit = false,
                             ReachRange reachRange = ReachRange.Standard, Vector2?targetVector = null, RegisterTile targetRegisterTile = null, bool isPlayerClick = false)
 {
     if (player == null)
     {
         return(false);
     }
     return(CanApply(player.GetComponent <PlayerScript>(), target, side, allowSoftCrit, reachRange, targetVector, targetRegisterTile, isPlayerClick));
 }
예제 #2
0
    /// <summary>
    /// Validates if the performer is in range and capable of interaction -  all the typical requirements for all
    /// various interactions. Works properly even if player is hidden in a ClosetControl. Can also optionally allow soft crit.
    ///
    /// </summary>
    /// <param name="playerScript">player script performing the interaction</param>
    /// <param name="target">target object.  Might be null if it's empty space</param>
    /// <param name="side">side of the network this is being checked on</param>
    /// <param name="allowSoftCrit">whether to allow interaction while in soft crit</param>
    /// <param name="reachRange">range to allow</param>
    /// <param name="targetVector">target vector pointing from performer to the position they are trying to click,
    /// if specified will use this to determine if in range rather than target object position.</param>
    /// <param name="targetRegisterTile">target's register tile component. If you specify this it avoids garbage. Please provide this
    /// if you can do so without using GetComponent, this is an optimization so GetComponent call can be avoided to avoid
    /// creating garbage.</param>
    /// <returns></returns>
    public static bool CanApply(
        PlayerScript playerScript,
        GameObject target,
        NetworkSide side,
        bool allowSoftCrit              = false,
        ReachRange reachRange           = ReachRange.Standard,
        Vector2?TargetPosition          = null,
        Vector2?targetVector            = null,
        RegisterTile targetRegisterTile = null
        )
    {
        if (playerScript == null)
        {
            return(false);
        }

        var playerObjBehavior = playerScript.pushPull;

        if (CanInteract(playerScript, side, allowSoftCrit) == false)
        {
            return(false);
        }

        //no matter what, if player is in closet, they can only reach the closet
        if (playerScript.IsHidden)
        {
            //Client does not seem to know what they are hidden in (playerObjBehavior.parentContianer is not set clientside),
            //so in this case they simply validate this and defer to the server to decide if it's valid
            //TODO: Correct this if there is a way for client to know their container.
            if (side == NetworkSide.Client)
            {
                return(true);
            }
            else
            {
                //server checks if player is trying to click the container they are in.
                var parentObj = playerObjBehavior.parentContainer != null
                                        ? playerObjBehavior.parentContainer.gameObject
                                        : null;
                return(parentObj == target);
            }
        }

        var result = false;

        // Check if target is in player's inventory.
        // This was added so NetTabs (NetTab.ValidatePeepers()) can be used on items in an inventory.
        if (target != null && target.TryGetComponent(out Pickupable pickupable) && pickupable.ItemSlot != null)
        {
            if (pickupable.ItemSlot.RootPlayer().OrNull()?.gameObject == playerScript.gameObject)
            {
                result = true;
            }
        }
예제 #3
0
 public static bool CanApply(ContextMenuApply toValidate, NetworkSide side, bool allowSoftCrit = false, ReachRange reachRange = ReachRange.Standard, bool isPlayerClick = false) =>
 CanApply(toValidate.Performer, toValidate.TargetObject, side, allowSoftCrit, reachRange, isPlayerClick: isPlayerClick);
예제 #4
0
 /// <summary>
 /// Validates if the performer is in range and not in crit for a TileApply interaction.
 /// Range check is based on the target vector of toValidate, not the distance to the object.
 /// </summary>
 /// <param name="toValidate">interaction to validate</param>
 /// <param name="side">side of the network this is being checked on</param>
 /// <param name="allowSoftCrit">whether to allow interaction while in soft crit</param>
 /// <param name="reachRange">range to allow</param>
 /// <returns></returns>
 public static bool CanApply(TileApply toValidate, NetworkSide side, bool allowSoftCrit = false, ReachRange reachRange = ReachRange.Standard, bool isPlayerClick = false) =>
 CanApply(toValidate.Performer, toValidate.TargetInteractableTiles.gameObject, side, allowSoftCrit, reachRange, toValidate.TargetVector, isPlayerClick: isPlayerClick);
예제 #5
0
    /// <summary>
    /// Validates if the performer is in range and capable of interaction -  all the typical requirements for all
    /// various interactions. Works properly even if player is hidden in a ClosetControl. Can also optionally allow soft crit.
    ///
    /// </summary>
    /// <param name="playerScript">player script performing the interaction</param>
    /// <param name="target">target object.  Might be null if it's empty space</param>
    /// <param name="side">side of the network this is being checked on</param>
    /// <param name="allowSoftCrit">whether to allow interaction while in soft crit</param>
    /// <param name="reachRange">range to allow</param>
    /// <param name="targetVector">target vector pointing from performer to the position they are trying to click,
    /// if specified will use this to determine if in range rather than target object position.</param>
    /// <param name="targetRegisterTile">target's register tile component. If you specify this it avoids garbage. Please provide this
    /// if you can do so without using GetComponent, this is an optimization so GetComponent call can be avoided to avoid
    /// creating garbage.</param>
    /// <returns></returns>
    public static bool CanApply(PlayerScript playerScript, GameObject target, NetworkSide side, bool allowSoftCrit = false,
                                ReachRange reachRange = ReachRange.Standard, Vector2?targetVector = null, RegisterTile targetRegisterTile = null, bool isPlayerClick = false)
    {
        if (playerScript == null)
        {
            return(false);
        }

        var playerObjBehavior = playerScript.pushPull;

        if (!CanInteract(playerScript, side, allowSoftCrit, isPlayerClick: isPlayerClick))
        {
            return(false);
        }

        //no matter what, if player is in closet, they can only reach the closet
        if (playerScript.IsHidden)
        {
            //Client does not seem to know what they are hidden in (playerObjBehavior.parentContianer is not set clientside),
            //so in this case they simply validate this and defer to the server to decide if it's valid
            //TODO: Correct this if there is a way for client to know their container.
            if (side == NetworkSide.Client)
            {
                return(true);
            }
            else
            {
                //server checks if player is trying to click the container they are in.
                var parentObj = playerObjBehavior.parentContainer != null
                                        ? playerObjBehavior.parentContainer.gameObject
                                        : null;
                return(parentObj == target);
            }
        }

        var result = false;

        if (reachRange == ReachRange.Unlimited)
        {
            result = true;
        }
        else if (reachRange == ReachRange.Standard)
        {
            result = IsInReachInternal(playerScript, target, side, targetVector, targetRegisterTile);
        }
        else if (reachRange == ReachRange.ExtendedServer)
        {
            //we don't check range client-side for this case.
            if (side == NetworkSide.Client)
            {
                result = true;
            }
            else
            {
                CustomNetTransform cnt = (target == null) ? null : target.GetComponent <CustomNetTransform>();

                if (cnt == null)
                {
                    result = IsInReachInternal(playerScript, target, side, targetVector, targetRegisterTile);
                }
                else
                {
                    result = ServerCanReachExtended(playerScript, cnt.ServerState);
                }
            }
        }

        if (!result && side == NetworkSide.Server && Logger.LogLevel >= LogLevel.Trace)
        {
            Vector3 worldPosition = Vector3.zero;
            bool    isFloating    = false;
            string  targetName    = string.Empty;

            // Client tried to do something out of range, report it
            // Note : it can be a security incident, but it might also be caused by bugs.
            // TODO: verify after a few rounds in multi-player, if this happens too often,
            // with this log information, try to find the cause and fix it (or fine tune it for less frequent logs).

            if (target != null)
            {
                targetName = target.name;

                if (target.TryGetComponent(out CustomNetTransform cnt))
                {
                    worldPosition = cnt.ServerState.WorldPosition;
                    isFloating    = cnt.IsFloatingServer;
                }
                else if (target.TryGetComponent(out PlayerSync playerSync))
                {
                    worldPosition = playerSync.ServerState.WorldPosition;
                    isFloating    = playerSync.IsWeightlessServer;
                }
            }

            Logger.LogTraceFormat($"Not in reach! Target: {targetName} server pos:{worldPosition} " +
                                  $"Player Name: {playerScript.playerName} Player pos:{playerScript.registerTile.WorldPositionServer} " +
                                  $"(floating={isFloating})", Category.Security);
        }

        return(result);
    }
예제 #6
0
 /// <summary>
 /// Validates if the performer is in range and not in crit for a MouseDrop interaction.
 /// </summary>
 /// <param name="toValidate">interaction to validate</param>
 /// <param name="side">side of the network this is being checked on</param>
 /// <param name="allowSoftCrit">whether to allow interaction while in soft crit</param>
 /// <param name="reachRange">range to allow</param>
 /// <returns></returns>
 public static bool CanApply(MouseDrop toValidate, NetworkSide side, bool allowSoftCrit = false, ReachRange reachRange = ReachRange.Standard) =>
 CanApply(toValidate.Performer, toValidate.TargetObject, side, allowSoftCrit, reachRange);
예제 #7
0
 /// <summary>
 /// Validates if the performer is in range and not in crit for a PositionalHandApply interaction.
 /// Range check is based on the target vector of toValidate, not the distance to the object.
 /// </summary>
 /// <param name="toValidate">interaction to validate</param>
 /// <param name="side">side of the network this is being checked on</param>
 /// <param name="allowSoftCrit">whether to allow interaction while in soft crit</param>
 /// <param name="reachRange">range to allow</param>
 /// <returns></returns>
 public static bool CanApply(PositionalHandApply toValidate, NetworkSide side, bool allowSoftCrit = false, ReachRange reachRange = ReachRange.Standard) =>
 CanApply(toValidate.Performer, toValidate.TargetObject, side, allowSoftCrit, reachRange, toValidate.TargetVector);
예제 #8
0
    /// <summary>
    /// Validates if the performer is in range and not in crit, which are typical requirements for all
    /// various interactions. Works properly even if player is hidden in a ClosetControl. Can also optionally allow soft crit.
    ///
    /// For PositionalHandApply, reach range is based on how far away they are clicking from themselves
    /// </summary>
    /// <param name="player">player performing the interaction</param>
    /// <param name="target">target object</param>
    /// <param name="side">side of the network this is being checked on</param>
    /// <param name="allowSoftCrit">whether to allow interaction while in soft crit</param>
    /// <param name="reachRange">range to allow</param>
    /// <param name="targetVector">target vector pointing from performer to the position they are trying to click,
    /// if specified will use this to determine if in range rather than target object position.</param>
    /// <returns></returns>
    public static bool CanApply(GameObject player, GameObject target, NetworkSide side, bool allowSoftCrit = false,
                                ReachRange reachRange = ReachRange.Standard, Vector2?targetVector = null)
    {
        var playerScript      = player.GetComponent <PlayerScript>();
        var playerObjBehavior = player.GetComponent <ObjectBehaviour>();

        if (!CanInteract(player, side, allowSoftCrit))
        {
            return(false);
        }

        //no matter what, if player is in closet, they can only reach the closet
        if (playerScript.IsHidden)
        {
            //Client does not seem to know what they are hidden in (playerObjBehavior.parentContianer is not set clientside),
            //so in this case they simply validate this and defer to the server to decide if it's valid
            //TODO: Correct this if there is a way for client to know their container.
            if (side == NetworkSide.Client)
            {
                return(true);
            }
            else
            {
                //server checks if player is trying to click the container they are in.
                var parentObj = playerObjBehavior.parentContainer != null
                                        ? playerObjBehavior.parentContainer.gameObject
                                        : null;
                return(parentObj == target);
            }
        }

        var result = false;

        if (reachRange == ReachRange.Unlimited)
        {
            result = true;
        }
        else if (reachRange == ReachRange.Standard)
        {
            var targetWorldPosition =
                targetVector != null ? player.transform.position + targetVector : target.transform.position;
            result = playerScript.IsInReach((Vector3)targetWorldPosition, side == NetworkSide.Server);
        }
        else if (reachRange == ReachRange.ExtendedServer)
        {
            //we don't check range client-side for this case.
            if (side == NetworkSide.Client)
            {
                result = true;
            }
            else
            {
                var cnt = target.GetComponent <CustomNetTransform>();
                if (cnt == null)
                {
                    var targetWorldPosition =
                        targetVector != null ? player.transform.position + targetVector : target.transform.position;
                    //fallback to standard range check if there is no CNT
                    result = playerScript.IsInReach((Vector3)targetWorldPosition, side == NetworkSide.Server);
                }
                else
                {
                    result = ServerCanReachExtended(playerScript, cnt.ServerState);
                }
            }
        }

        if (!result && side == NetworkSide.Server)
        {
            //client tried to do something out of range, report it
            var cnt = target.GetComponent <CustomNetTransform>();
            Logger.LogTraceFormat("Not in reach! server pos:{0} player pos:{1} (floating={2})", Category.Security,
                                  cnt.ServerState.WorldPosition, player.transform.position, cnt.IsFloatingServer);
        }

        return(result);
    }