Entity Attribute Reach Modification

Reach_Attribute_Modifier Дистанция (Reach) HIGH +8 очков

🎮 Влияние на механику Minecraft

До версии Minecraft 1.20.5 дистанция атаки и взаимодействия игрока задавалась жестко зашитыми константами в коде клиента и сервера (3.0 блока для выживания, 4.5 для креатива). Начиная с версии 1.20.5 Mojang перенесла эти параметры в систему атрибутов сущностей: player.entity_interaction_range (PLAYER_ENTITY_INTERACTION_RANGE) и player.block_interaction_range (PLAYER_BLOCK_INTERACTION_RANGE).

Reach_Attribute_Modifier фиксирует создание модификаторов атрибутов EntityAttributeModifier, нацеленных на реестр дистанции взаимодействия. В сценарии чит-модификации код создает экземпляр модификатора с положительным смещением и регистрирует его в контейнере атрибутов локального игрока. Это расширяет радиус атаки и взаимодействия на уровне стандартных игровых механик без необходимости прямого патчинга методов рейкастинга или байткода ClientPlayerInteractionManager.

На серверах с ванильной валидацией или серверными античитами клиентские модификаторы атрибутов, не подтвержденные сервером, приводят к отклонению пакетов взаимодействия и отмене ударов.

🔍 Анализируемые функции и API

EntityAttributes.PLAYER_ENTITY_INTERACTION_RANGE / field_51576

Ванильный реестр атрибутов Minecraft 1.20.5+, определяющий дальность взаимодействия и атаки по сущностям (class_5132.field_51576).

EntityAttributeModifier.<init> / class_1322.<init>

Конструктор модификатора атрибута сущности, создающий надбавку к базовой дистанции (class_1322.<init>).

💻 Реализация в моде (Исходный код)

package com.example.reach;

import net.minecraft.entity.attribute.EntityAttributeModifier;
import net.minecraft.entity.attribute.EntityAttributes;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.util.Identifier;

public class AttributeReachUtil {
    private static final Identifier REACH_MODIFIER_ID = Identifier.of("reach_boost", "attack_range");

    public static void applyExtendedReach(PlayerEntity player, double extraBlocks) {
        var attributeInstance = player.getAttributeInstance(EntityAttributes.PLAYER_ENTITY_INTERACTION_RANGE);
        if (attributeInstance != null) {
            EntityAttributeModifier modifier = new EntityAttributeModifier(
                REACH_MODIFIER_ID,
                extraBlocks,
                EntityAttributeModifier.Operation.ADD_VALUE
            );
            attributeInstance.removeModifier(REACH_MODIFIER_ID);
            attributeInstance.addTemporaryModifier(modifier);
        }
    }
}

🛡️ Сигнатура байткода и статический детект

Детектор анализирует пул констант класса и проверяет одновременное присутствие двух условий на уровне класса:

  • Ссылку на поле атрибута дистанции взаимодействия с сущностями или блоками: Intermediary class_5132.field_51574 (PLAYER_BLOCK_INTERACTION_RANGE), class_5132.field_51576 (PLAYER_ENTITY_INTERACTION_RANGE), имена ENTITY_INTERACTION_RANGE, BLOCK_INTERACTION_RANGE, константу Forge ForgeMod.REACH_DISTANCE или библиотечные атрибуты ReachEntityAttributes.REACH / ATTACK_RANGE.
  • Вызов конструктора модификатора атрибутов: EntityAttributeModifier.<init> (Intermediary class_1322.<init>) или Forge AttributeModifier.<init>.

Правило работает на уровне класса (scope: class). Поскольку детектор ожидает создание экземпляра EntityAttributeModifier в одном классе с обращением к атрибуту дистанции, изменение параметров исключительно через рефлексию или сетевые пакеты без явного вызова конструктора не будет обнаружено данной сигнатурой.