How to guard against range hack

You can use a 4 line plugin that if the wood farmed to is 1 make a discount 1 of the inventory, and thus completely block the Farmer from the trees, I know it is not the right thing but it is a solution
 
You can use a 4 line plugin that if the wood farmed to is 1 make a discount 1 of the inventory, and thus completely block the Farmer from the trees, I know it is not the right thing but it is a solution
This is not a solution, but thanks. I now attach a hot-fix

C#:
public static void DoAction1(MeleeWeaponDataBlock mb, uLink.BitStream stream, ItemRepresentation rep, ref uLink.NetworkMessageInfo info)
        {
            GameObject gameObject;
            NetEntityID netEntityID;
            IMeleeWeaponItem meleeWeaponItem;
            ResourceTarget.ResourceTargetType resourceTargetType;
            int num;
            ResourceTarget component;
            TakeDamage local;
            NetCull.VerifyRPC(ref info, false);
            if (!stream.ReadBoolean())
            {
                netEntityID = NetEntityID.unassigned;
                gameObject = null;
            }
            else
            {
                netEntityID = stream.Read<NetEntityID>(new object[0]);
                if (netEntityID.isUnassigned)
                {
                    gameObject = null;
                }
                else
                {
                    gameObject = netEntityID.gameObject;
                    if (!gameObject)
                    {
                        netEntityID = NetEntityID.unassigned;
                    }
                }
            }
            stream.ReadVector3();
            bool flag = stream.ReadBoolean();
            if (!rep.Item<IMeleeWeaponItem>(out meleeWeaponItem))
            {
                return;
            }
            TakeDamage takeDamage = meleeWeaponItem.inventory.GetLocal<TakeDamage>();
            if (takeDamage && takeDamage.dead)
            {
                return;
            }
            if (!meleeWeaponItem.ValidatePrimaryMessageTime(info.timestamp))
            {
                return;
            }
            IDBase dBase = null;
            TakeDamage takeDamage1 = null;
            if (gameObject)
            {
                dBase = IDBase.Get(gameObject);
                if (!dBase)
                {
                    local = null;
                }
                else
                {
                    local = dBase.idMain.GetLocal<TakeDamage>();
                }
                takeDamage1 = local;
            }
            if (gameObject && Vector3.Distance(takeDamage.transform.position, gameObject.transform.position) >= 6f)
            {
                return;
            }
            Metabolism metabolism = meleeWeaponItem.inventory.GetComponent<Metabolism>();
            if (metabolism)
            {
                metabolism.SubtractCalories(UnityEngine.Random.Range(mb.caloriesPerSwing * 0.8f, mb.caloriesPerSwing * 1.2f));
            }
            rep.ActionStream(1, uLink.RPCMode.AllExceptOwner, stream);
            if (!(dBase == null) || !(gameObject == null))
            {
                component = ((dBase != null ? dBase.gameObject : gameObject)).GetComponent<ResourceTarget>();
            }
            else
            {
                component = null;
            }
            ResourceTarget resourceTarget = component;
            if (flag || resourceTarget && (takeDamage1 == null || takeDamage1.dead))
            {
                Character character = meleeWeaponItem.inventory.idMain as Character;
                resourceTargetType = (!flag ? resourceTarget.type : ResourceTarget.ResourceTargetType.StaticTree);
                float single = mb.efficiencies[(int)resourceTargetType];
                if (flag)
                {
                    mb.resourceGatherLevel += single;
                    if (mb.resourceGatherLevel >= 1f)
                    {
                        if (CheckWood(character.eyesRay, 3f))
                        {
                            int num1 = Mathf.FloorToInt(mb.resourceGatherLevel);
                            string str = "Wood";
                            ItemDataBlock byName = DatablockDictionary.GetByName(str);
                            if (!byName)
                            {
                                num = 0;
                            }
                            else
                            {
                                int num2 = meleeWeaponItem.inventory.AddItemAmount(byName, num1);
                                num = num1 - num2;
                            }
                            if (num > 0)
                            {
                                mb.resourceGatherLevel -= (float)num;
                                Notice.Inventory(info.sender, string.Concat(num.ToString(), " x ", str));
                            }
                        }
                        else
                        {
                            character.netUser.Kick(NetError.Facepunch_Connector_VAC_Banned, true);
                            return;
                        }
                    }
                }
                else if (resourceTarget)
                {
                    resourceTarget.DoGather(meleeWeaponItem.inventory, single);
                }
            }
            if (dBase)
            {
                float damage = mb.GetDamage();
                TakeDamage.Hurt(meleeWeaponItem.inventory, dBase, new DamageTypeList(0f, 0f, damage, 0f, 0f, 0f), new WeaponImpact(mb, meleeWeaponItem, rep));
            }
            if (gameObject)
            {
                meleeWeaponItem.TryConditionLoss(0.25f, 0.025f);
            }
        }

        static bool CheckWood(Ray ray, float fl)
        {
            RaycastHit[] tt = Physics.SphereCastAll(ray, fl, 3f);
            foreach(RaycastHit tt2 in tt)
            {
                if(tt2.collider.gameObject.tag == "Tree Collider")
                {
                    return true;
                }
            }
            return false;
        }
 
That is a lot of code,
I think this would work:
On_Gather
if (Vector3.Distance(player.location, entity.location) is greater than 5m)
Cancel gather event
 
You should be able to as it's a GameObject, Would be the same as getting a radtown, Rock, Barrel etc
I guess it'll be called Tree
Gatheritem as Get.GameObject<Tree>
 
here somthing to prevent autogather

C#:
  public static void checkAutoGather(PlayerHandler player)
        {
            Inventory inv = player.GetInventory();
            if (inv.activeItem == null) return;
            inv.FindItem(wooddata, out cachedInt);
            Debug.Log(cachedInt.ToString());
            if (Physics.Raycast(player.GetCharacter().eyesRay, out cachedRaycast))
            Debug.Log(cachedRaycast.collider.ToString());