mirror of
https://github.com/Xiao-MoMi/craft-engine.git
synced 2025-12-29 03:49:15 +00:00
feat(entity): 实现潜影贝碰撞箱
This commit is contained in:
@@ -0,0 +1,21 @@
|
||||
package net.momirealms.craftengine.bukkit.entity;
|
||||
|
||||
import net.momirealms.craftengine.bukkit.util.Reflections;
|
||||
|
||||
import java.util.Optional;
|
||||
|
||||
public class BaseEntityData<T> extends SimpleEntityData<T> {
|
||||
|
||||
public static final BaseEntityData<Byte> SharedFlags = new BaseEntityData<>(0, EntityDataValue.Serializers$BYTE, (byte) 0);
|
||||
public static final BaseEntityData<Integer> AirSupply = new BaseEntityData<>(1, EntityDataValue.Serializers$INT, 300);
|
||||
public static final BaseEntityData<Optional<Object>> CustomName = new BaseEntityData<>(2, EntityDataValue.Serializers$OPTIONAL_COMPONENT, Optional.empty());
|
||||
public static final BaseEntityData<Boolean> CustomNameVisible = new BaseEntityData<>(3, EntityDataValue.Serializers$BOOLEAN, false);
|
||||
public static final BaseEntityData<Boolean> Silent = new BaseEntityData<>(4, EntityDataValue.Serializers$BOOLEAN, false);
|
||||
public static final BaseEntityData<Boolean> NoGravity = new BaseEntityData<>(5, EntityDataValue.Serializers$BOOLEAN, false);
|
||||
public static final BaseEntityData<Object> Pose = new BaseEntityData<>(6, EntityDataValue.Serializers$POSE, Reflections.instance$Pose$STANDING);
|
||||
public static final BaseEntityData<Integer> TicksFrozen = new BaseEntityData<>(7, EntityDataValue.Serializers$INT, 0);
|
||||
|
||||
public BaseEntityData(int id, Object serializer, T defaultValue) {
|
||||
super(id, serializer, defaultValue);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
package net.momirealms.craftengine.bukkit.entity;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public interface EntityData<T> {
|
||||
|
||||
Object serializer();
|
||||
int id();
|
||||
T defaultValue();
|
||||
|
||||
default Object createEntityDataIfNotDefaultValue(T value) {
|
||||
if (defaultValue().equals(value)) return null;
|
||||
return EntityDataValue.create(id(), serializer(), value);
|
||||
}
|
||||
|
||||
default void addEntityDataIfNotDefaultValue(T value, List<Object> list) {
|
||||
if (!defaultValue().equals(value)) {
|
||||
list.add(EntityDataValue.create(id(), serializer(), value));
|
||||
}
|
||||
}
|
||||
|
||||
default void addEntityData(T value, List<Object> list) {
|
||||
list.add(EntityDataValue.create(id(), serializer(), value));
|
||||
}
|
||||
|
||||
static <T> EntityData<T> of(int id, Object serializer, T defaultValue) {
|
||||
return new SimpleEntityData<>(id, serializer, defaultValue);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
package net.momirealms.craftengine.bukkit.entity;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
|
||||
public class LivingEntityData<T> extends BaseEntityData<T> {
|
||||
|
||||
public static final LivingEntityData<Byte> LivingEntityFlags = new LivingEntityData<>(8, EntityDataValue.Serializers$BYTE, (byte) 0);
|
||||
public static final LivingEntityData<Float> Health = new LivingEntityData<>(9, EntityDataValue.Serializers$FLOAT, 1.0f);
|
||||
public static final LivingEntityData<List<Object>> EffectParticles = new LivingEntityData<>(10, EntityDataValue.Serializers$PARTICLES, List.of());
|
||||
public static final LivingEntityData<Boolean> EffectAmbience = new LivingEntityData<>(11, EntityDataValue.Serializers$BOOLEAN, false);
|
||||
public static final LivingEntityData<Integer> ArrowCount = new LivingEntityData<>(12, EntityDataValue.Serializers$INT, 0);
|
||||
public static final LivingEntityData<Integer> StingerCount = new LivingEntityData<>(13, EntityDataValue.Serializers$INT, 0);
|
||||
public static final LivingEntityData<Optional<Object>> SleepingPos = new LivingEntityData<>(14, EntityDataValue.Serializers$OPTIONAL_BLOCK_POS, Optional.empty());
|
||||
|
||||
public LivingEntityData(int id, Object serializer, T defaultValue) {
|
||||
super(id, serializer, defaultValue);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
package net.momirealms.craftengine.bukkit.entity;
|
||||
|
||||
public class MobData<T> extends LivingEntityData<T> {
|
||||
|
||||
public static final MobData<Byte> MobFlags = new MobData<>(15, EntityDataValue.Serializers$BYTE, (byte) 0);
|
||||
|
||||
public MobData(int id, Object serializer, T defaultValue) {
|
||||
super(id, serializer, defaultValue);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
package net.momirealms.craftengine.bukkit.entity;
|
||||
|
||||
import net.momirealms.craftengine.bukkit.util.Reflections;
|
||||
|
||||
public class ShulkerData<T> extends MobData<T> {
|
||||
|
||||
public static final ShulkerData<Object> AttachFace = new ShulkerData<>(16, EntityDataValue.Serializers$DIRECTION, Reflections.instance$Direction$DOWN);
|
||||
public static final ShulkerData<Byte> Peek = new ShulkerData<>(17, EntityDataValue.Serializers$BYTE, (byte) 0);
|
||||
public static final ShulkerData<Byte> Color = new ShulkerData<>(18, EntityDataValue.Serializers$BYTE, (byte) 16);
|
||||
|
||||
public ShulkerData(int id, Object serializer, T defaultValue) {
|
||||
super(id, serializer, defaultValue);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
package net.momirealms.craftengine.bukkit.entity;
|
||||
|
||||
public class SimpleEntityData<T> implements EntityData<T> {
|
||||
|
||||
private final int id;
|
||||
private final Object serializer;
|
||||
private final T defaultValue;
|
||||
|
||||
public SimpleEntityData(int id, Object serializer, T defaultValue) {
|
||||
this.id = id;
|
||||
this.serializer = serializer;
|
||||
this.defaultValue = defaultValue;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int id() {
|
||||
return id;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object serializer() {
|
||||
return serializer;
|
||||
}
|
||||
|
||||
@Override
|
||||
public T defaultValue() {
|
||||
return defaultValue;
|
||||
}
|
||||
}
|
||||
@@ -9,6 +9,6 @@ public class BukkitHitBoxTypes extends HitBoxTypes {
|
||||
static {
|
||||
register(INTERACTION, InteractionHitBox.FACTORY);
|
||||
register(SHULKER, ShulkerHitBox.FACTORY);
|
||||
register(BOAT, BoatHitBox.FACTORY);
|
||||
register(BOAT, HappyGhastHitBox.FACTORY);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9,11 +9,13 @@ import java.util.Map;
|
||||
import java.util.function.Consumer;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
public class BoatHitBox extends AbstractHitBox {
|
||||
public class HappyGhastHitBox extends AbstractHitBox {
|
||||
public static final Factory FACTORY = new Factory();
|
||||
private final double scale;
|
||||
|
||||
public BoatHitBox(Seat[] seats, Vector3f position) {
|
||||
public HappyGhastHitBox(Seat[] seats, Vector3f position, double scale) {
|
||||
super(seats, position);
|
||||
this.scale = scale;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -21,9 +23,13 @@ public class BoatHitBox extends AbstractHitBox {
|
||||
return HitBoxTypes.BOAT;
|
||||
}
|
||||
|
||||
public double scale() {
|
||||
return scale;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addSpawnPackets(int[] entityId, double x, double y, double z, float yaw, Consumer<Object> packets) {
|
||||
// 生成无重力船
|
||||
// todo 乐魂
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -35,9 +41,11 @@ public class BoatHitBox extends AbstractHitBox {
|
||||
|
||||
@Override
|
||||
public HitBox create(Map<String, Object> arguments) {
|
||||
return new BoatHitBox(
|
||||
double scale = MiscUtils.getAsDouble(arguments.getOrDefault("scale", "1"));
|
||||
return new HappyGhastHitBox(
|
||||
HitBoxFactory.getSeats(arguments),
|
||||
MiscUtils.getVector3f(arguments.getOrDefault("position", "0"))
|
||||
MiscUtils.getVector3f(arguments.getOrDefault("position", "0")),
|
||||
scale
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -1,14 +1,19 @@
|
||||
package net.momirealms.craftengine.bukkit.entity.furniture;
|
||||
|
||||
import com.google.common.collect.Lists;
|
||||
import io.netty.buffer.ByteBuf;
|
||||
import io.netty.buffer.Unpooled;
|
||||
import net.momirealms.craftengine.bukkit.entity.BaseEntityData;
|
||||
import net.momirealms.craftengine.bukkit.entity.MobData;
|
||||
import net.momirealms.craftengine.bukkit.entity.ShulkerData;
|
||||
import net.momirealms.craftengine.bukkit.util.DirectionUtils;
|
||||
import net.momirealms.craftengine.bukkit.util.MobEffectUtils;
|
||||
import net.momirealms.craftengine.bukkit.util.Reflections;
|
||||
import net.momirealms.craftengine.core.entity.furniture.*;
|
||||
import net.momirealms.craftengine.core.util.Direction;
|
||||
import net.momirealms.craftengine.core.util.Key;
|
||||
import net.momirealms.craftengine.core.util.MiscUtils;
|
||||
import net.momirealms.craftengine.core.util.*;
|
||||
import org.joml.Vector3f;
|
||||
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
import java.util.*;
|
||||
import java.util.function.Consumer;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
@@ -19,6 +24,7 @@ public class ShulkerHitBox extends AbstractHitBox {
|
||||
private final byte peek;
|
||||
// todo或许还能做个方向,但是会麻烦点,和 yaw 有关
|
||||
private final Direction direction;
|
||||
private List<Object> cachedValues;
|
||||
|
||||
public ShulkerHitBox(Seat[] seats, Vector3f position, double scale, byte peek, Direction direction) {
|
||||
super(seats, position);
|
||||
@@ -46,10 +52,43 @@ public class ShulkerHitBox extends AbstractHitBox {
|
||||
|
||||
@Override
|
||||
public void addSpawnPackets(int[] entityIds, double x, double y, double z, float yaw, Consumer<Object> packets) {
|
||||
// 1.生成假的展示实体
|
||||
// 2.生成假的潜影贝
|
||||
// 3.潜影贝骑展示实体
|
||||
// 4.潜影贝数据设置(隐身,尺寸,peek,方向)
|
||||
Vector3f offset = QuaternionUtils.toQuaternionf(0f, Math.toRadians(180f - yaw), 0f).conjugate().transform(new Vector3f(position()));
|
||||
try {
|
||||
packets.accept(Reflections.constructor$ClientboundAddEntityPacket.newInstance(
|
||||
entityIds[0], UUID.randomUUID(), x + offset.x, y + offset.y, z - offset.z, 0, yaw,
|
||||
Reflections.instance$EntityType$SHULKER, 0, Reflections.instance$Vec3$Zero, 0
|
||||
));
|
||||
packets.accept(Reflections.constructor$ClientboundSetEntityDataPacket.newInstance(entityIds[0], getCachedValues()));
|
||||
packets.accept(Reflections.constructor$ClientboundAddEntityPacket.newInstance(
|
||||
entityIds[1], UUID.randomUUID(), x + offset.x, y + offset.y, z - offset.z, 0, yaw,
|
||||
Reflections.instance$EntityType$ITEM_DISPLAY, 0, Reflections.instance$Vec3$Zero, 0
|
||||
));
|
||||
ByteBuf byteBuf = Unpooled.buffer();
|
||||
Object friendlyByteBuf = Reflections.constructor$FriendlyByteBuf.newInstance(byteBuf);
|
||||
Reflections.method$FriendlyByteBuf$writeVarInt.invoke(friendlyByteBuf, entityIds[1]);
|
||||
Reflections.method$FriendlyByteBuf$writeVarIntArray.invoke(friendlyByteBuf, (Object) new int[] {entityIds[0]});
|
||||
packets.accept(Reflections.constructor$ClientboundSetPassengersPacket.newInstance(friendlyByteBuf));
|
||||
if (VersionHelper.isVersionNewerThan1_20_5()) {
|
||||
Object attributeInstance = Reflections.constructor$AttributeInstance.newInstance(Reflections.instance$Attributes$SCALE, (Consumer<?>) (o) -> {});
|
||||
Reflections.method$AttributeInstance$setBaseValue.invoke(attributeInstance, scale);
|
||||
packets.accept(Reflections.constructor$ClientboundUpdateAttributesPacket0.newInstance(entityIds[0], Collections.singletonList(attributeInstance)));
|
||||
}
|
||||
} catch (ReflectiveOperationException e) {
|
||||
throw new RuntimeException("Failed to construct shulker hitbox spawn packet", e);
|
||||
}
|
||||
}
|
||||
|
||||
private synchronized List<Object> getCachedValues() {
|
||||
if (this.cachedValues == null) {
|
||||
this.cachedValues = new ArrayList<>();
|
||||
ShulkerData.Peek.addEntityDataIfNotDefaultValue(peek, this.cachedValues);
|
||||
ShulkerData.AttachFace.addEntityDataIfNotDefaultValue(DirectionUtils.toNMSDirection(direction), this.cachedValues);
|
||||
ShulkerData.NoGravity.addEntityDataIfNotDefaultValue(true, this.cachedValues);
|
||||
ShulkerData.Silent.addEntityDataIfNotDefaultValue(true, this.cachedValues);
|
||||
ShulkerData.MobFlags.addEntityDataIfNotDefaultValue((byte) 0x01, this.cachedValues); // 无ai
|
||||
ShulkerData.SharedFlags.addEntityDataIfNotDefaultValue((byte) 0x20, this.cachedValues); // 不可见
|
||||
}
|
||||
return this.cachedValues;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -29,4 +29,15 @@ public class DirectionUtils {
|
||||
case EAST -> BlockFace.EAST;
|
||||
};
|
||||
}
|
||||
|
||||
public static Object toNMSDirection(Direction direction) {
|
||||
return switch (direction) {
|
||||
case UP -> Reflections.instance$Direction$UP;
|
||||
case DOWN -> Reflections.instance$Direction$DOWN;
|
||||
case NORTH -> Reflections.instance$Direction$NORTH;
|
||||
case SOUTH -> Reflections.instance$Direction$SOUTH;
|
||||
case WEST -> Reflections.instance$Direction$WEST;
|
||||
case EAST -> Reflections.instance$Direction$EAST;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3141,6 +3141,7 @@ public class Reflections {
|
||||
|
||||
public static final Object instance$MobEffecr$mining_fatigue;
|
||||
public static final Object instance$MobEffecr$haste;
|
||||
public static final Object instance$MobEffecr$invisibility;
|
||||
|
||||
// for 1.20.1-1.20.4
|
||||
static {
|
||||
@@ -3149,6 +3150,8 @@ public class Reflections {
|
||||
instance$MobEffecr$mining_fatigue = method$Registry$get.invoke(instance$BuiltInRegistries$MOB_EFFECT, mining_fatigue);
|
||||
Object haste = method$ResourceLocation$fromNamespaceAndPath.invoke(null, "minecraft", "haste");
|
||||
instance$MobEffecr$haste = method$Registry$get.invoke(instance$BuiltInRegistries$MOB_EFFECT, haste);
|
||||
Object invisibility = method$ResourceLocation$fromNamespaceAndPath.invoke(null, "minecraft", "invisibility");
|
||||
instance$MobEffecr$invisibility = method$Registry$get.invoke(instance$BuiltInRegistries$MOB_EFFECT, invisibility);
|
||||
} catch (ReflectiveOperationException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
@@ -3665,6 +3668,7 @@ public class Reflections {
|
||||
public static final Object instance$EntityType$ITEM_DISPLAY;
|
||||
public static final Object instance$EntityType$FALLING_BLOCK;
|
||||
public static final Object instance$EntityType$INTERACTION;
|
||||
public static final Object instance$EntityType$SHULKER;
|
||||
|
||||
static {
|
||||
try {
|
||||
@@ -3676,6 +3680,8 @@ public class Reflections {
|
||||
instance$EntityType$FALLING_BLOCK = Reflections.method$Registry$get.invoke(Reflections.instance$BuiltInRegistries$ENTITY_TYPE, fallingBlock);
|
||||
Object interaction = method$ResourceLocation$fromNamespaceAndPath.invoke(null, "minecraft", "interaction");
|
||||
instance$EntityType$INTERACTION = Reflections.method$Registry$get.invoke(Reflections.instance$BuiltInRegistries$ENTITY_TYPE, interaction);
|
||||
Object shulker = method$ResourceLocation$fromNamespaceAndPath.invoke(null, "minecraft", "shulker");
|
||||
instance$EntityType$SHULKER = Reflections.method$Registry$get.invoke(Reflections.instance$BuiltInRegistries$ENTITY_TYPE, shulker);
|
||||
} catch (ReflectiveOperationException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
@@ -5782,4 +5788,135 @@ public class Reflections {
|
||||
clazz$CraftShulker, clazz$Shulker, 0
|
||||
)
|
||||
);
|
||||
|
||||
public static final Class<?> clazz$Pose = requireNonNull(
|
||||
ReflectionUtils.getClazz(
|
||||
BukkitReflectionUtils.assembleMCClass("world.entity.Pose"),
|
||||
BukkitReflectionUtils.assembleMCClass("world.entity.EntityPose")
|
||||
)
|
||||
);
|
||||
|
||||
public static final Method method$Pose$values = requireNonNull(
|
||||
ReflectionUtils.getStaticMethod(
|
||||
clazz$Pose, clazz$Pose.arrayType()
|
||||
)
|
||||
);
|
||||
|
||||
public static final Object instance$Pose$STANDING;
|
||||
public static final Object instance$Pose$FALL_FLYING;
|
||||
public static final Object instance$Pose$SLEEPING;
|
||||
public static final Object instance$Pose$SWIMMING;
|
||||
public static final Object instance$Pose$SPIN_ATTACK;
|
||||
public static final Object instance$Pose$CROUCHING;
|
||||
public static final Object instance$Pose$LONG_JUMPING;
|
||||
public static final Object instance$Pose$DYING;
|
||||
public static final Object instance$Pose$CROAKING;
|
||||
public static final Object instance$Pose$USING_TONGUE;
|
||||
public static final Object instance$Pose$SITTING;
|
||||
public static final Object instance$Pose$ROARING;
|
||||
public static final Object instance$Pose$SNIFFING;
|
||||
public static final Object instance$Pose$EMERGING;
|
||||
public static final Object instance$Pose$DIGGING;
|
||||
public static final Object instance$Pose$SLIDING;
|
||||
public static final Object instance$Pose$SHOOTING;
|
||||
public static final Object instance$Pose$INHALING;
|
||||
public static final Object[] instance$Poses;
|
||||
|
||||
static {
|
||||
try {
|
||||
instance$Poses = (Object[]) method$Pose$values.invoke(null);
|
||||
instance$Pose$STANDING = instance$Poses[0];
|
||||
instance$Pose$FALL_FLYING = instance$Poses[1];
|
||||
instance$Pose$SLEEPING = instance$Poses[2];
|
||||
instance$Pose$SWIMMING = instance$Poses[3];
|
||||
instance$Pose$SPIN_ATTACK = instance$Poses[4];
|
||||
instance$Pose$CROUCHING = instance$Poses[5];
|
||||
instance$Pose$LONG_JUMPING = instance$Poses[6];
|
||||
instance$Pose$DYING = instance$Poses[7];
|
||||
instance$Pose$CROAKING = instance$Poses[8];
|
||||
instance$Pose$USING_TONGUE = instance$Poses[9];
|
||||
instance$Pose$SITTING = instance$Poses[10];
|
||||
instance$Pose$ROARING = instance$Poses[11];
|
||||
instance$Pose$SNIFFING = instance$Poses[12];
|
||||
instance$Pose$EMERGING = instance$Poses[13];
|
||||
instance$Pose$DIGGING = instance$Poses[14];
|
||||
if (VersionHelper.isVersionNewerThan1_20_3()) {
|
||||
instance$Pose$SLIDING = instance$Poses[15];
|
||||
instance$Pose$SHOOTING = instance$Poses[16];
|
||||
instance$Pose$INHALING = instance$Poses[17];
|
||||
} else {
|
||||
instance$Pose$SLIDING = null;
|
||||
instance$Pose$SHOOTING = null;
|
||||
instance$Pose$INHALING = null;
|
||||
}
|
||||
} catch (ReflectiveOperationException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
public static final Method method$AttributeInstance$getModifier = requireNonNull(
|
||||
ReflectionUtils.getMethod(
|
||||
clazz$AttributeInstance, clazz$AttributeModifier, clazz$ResourceLocation
|
||||
)
|
||||
);
|
||||
|
||||
public static final Class<?> clazz$Attributes = requireNonNull(
|
||||
ReflectionUtils.getClazz(
|
||||
BukkitReflectionUtils.assembleMCClass("world.entity.ai.attributes.Attributes"),
|
||||
BukkitReflectionUtils.assembleMCClass("world.entity.ai.attributes.GenericAttributes")
|
||||
)
|
||||
);
|
||||
|
||||
// 1.20.5+
|
||||
public static final Field field$Attributes$SCALE =
|
||||
ReflectionUtils.getDeclaredField(
|
||||
clazz$Attributes, "SCALE"
|
||||
);
|
||||
|
||||
// 1.20.5+
|
||||
public static final Object instance$Attributes$SCALE = Optional.ofNullable(field$Attributes$SCALE)
|
||||
.map(it -> {
|
||||
try {
|
||||
return it.get(null);
|
||||
} catch (IllegalAccessException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
})
|
||||
.orElse(null);
|
||||
|
||||
public static final Constructor<?> constructor$AttributeInstance = requireNonNull(
|
||||
ReflectionUtils.getConstructor(
|
||||
clazz$AttributeInstance, clazz$Holder, Consumer.class
|
||||
)
|
||||
);
|
||||
|
||||
public static final Method method$AttributeInstance$setBaseValue = requireNonNull(
|
||||
ReflectionUtils.getMethod(
|
||||
clazz$AttributeInstance, void.class, double.class
|
||||
)
|
||||
);
|
||||
|
||||
public static final Constructor<?> constructor$MobEffectInstance = requireNonNull(
|
||||
ReflectionUtils.getConstructor(
|
||||
clazz$MobEffectInstance, clazz$Holder, int.class, int.class, boolean.class, boolean.class, boolean.class
|
||||
)
|
||||
);
|
||||
|
||||
public static final Constructor<?> constructor$ClientboundSetPassengersPacket = requireNonNull(
|
||||
ReflectionUtils.getDeclaredConstructor(
|
||||
clazz$ClientboundSetPassengersPacket, clazz$FriendlyByteBuf
|
||||
)
|
||||
);
|
||||
|
||||
public static final Method method$FriendlyByteBuf$writeVarInt = requireNonNull(
|
||||
ReflectionUtils.getMethod(
|
||||
clazz$FriendlyByteBuf, clazz$FriendlyByteBuf, new String[]{"writeVarInt", "d", "c"}, int.class
|
||||
)
|
||||
);
|
||||
|
||||
public static final Method method$FriendlyByteBuf$writeVarIntArray = requireNonNull(
|
||||
ReflectionUtils.getMethod(
|
||||
clazz$FriendlyByteBuf, clazz$FriendlyByteBuf, int[].class
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user