mirror of
https://github.com/Xiao-MoMi/craft-engine.git
synced 2025-12-27 10:59:07 +00:00
refactor(bukkit): 实现配置并且优化性能
This commit is contained in:
@@ -48,7 +48,6 @@ public class TestCommand extends BukkitCommandFeature<CommandSender> {
|
||||
return CompletableFuture.completedFuture(plugin().itemManager().cachedSuggestions());
|
||||
}
|
||||
}))
|
||||
.required("interpolationDuration", IntegerParser.integerParser())
|
||||
.required("displayType", ByteParser.byteParser((byte) 0, (byte) 8))
|
||||
.required("translation", StringParser.stringParser())
|
||||
.required("rotationLeft", StringParser.stringParser())
|
||||
@@ -57,12 +56,6 @@ public class TestCommand extends BukkitCommandFeature<CommandSender> {
|
||||
NamespacedKey namespacedKey = context.get("id");
|
||||
ItemStack item = new ItemStack(Material.TRIDENT);
|
||||
item.editMeta((meta) -> {
|
||||
PersistentDataContainer container = meta.getPersistentDataContainer();
|
||||
container.set(CustomTridentUtils.customTridentKey, PersistentDataType.STRING, namespacedKey.asString());
|
||||
container.set(CustomTridentUtils.interpolationDurationaKey, PersistentDataType.INTEGER, context.get("interpolationDuration"));
|
||||
container.set(CustomTridentUtils.displayTypeKey, PersistentDataType.BYTE, context.get("displayType"));
|
||||
container.set(CustomTridentUtils.translationKey, PersistentDataType.STRING, context.get("translation"));
|
||||
container.set(CustomTridentUtils.rotationLeftKey, PersistentDataType.STRING, context.get("rotationLeft"));
|
||||
Item<ItemStack> ceItem = BukkitItemManager.instance().createWrappedItem(Key.of(namespacedKey.asString()), null);
|
||||
Optional<Integer> customModelData = ceItem.customModelData();
|
||||
customModelData.ifPresent(meta::setCustomModelData);
|
||||
|
||||
@@ -1621,7 +1621,7 @@ public class PacketConsumers {
|
||||
try {
|
||||
int entityId = FastNMS.INSTANCE.method$ClientboundEntityPositionSyncPacket$id(packet);
|
||||
if (user.tridentView().containsKey(entityId)) {
|
||||
CustomTridentUtils.modifyCustomTridentPositionSync(event, packet, entityId);
|
||||
event.replacePacket(CustomTridentUtils.buildCustomTridentPositionSync(packet, entityId));
|
||||
return;
|
||||
}
|
||||
if (BukkitFurnitureManager.instance().isFurnitureRealEntity(entityId)) {
|
||||
@@ -2345,7 +2345,7 @@ public class PacketConsumers {
|
||||
try {
|
||||
int entityId = BukkitInjector.internalFieldAccessor().field$ClientboundMoveEntityPacket$entityId(packet);
|
||||
if (user.tridentView().containsKey(entityId)) {
|
||||
CustomTridentUtils.modifyCustomTridentMove(packet);
|
||||
event.replacePacket(CustomTridentUtils.buildCustomTridentMove(packet, entityId));
|
||||
}
|
||||
} catch (Exception e) {
|
||||
CraftEngine.instance().logger().warn("Failed to handle ClientboundMoveEntityPacket$PosRot", e);
|
||||
|
||||
@@ -4,6 +4,8 @@ import net.momirealms.craftengine.bukkit.entity.data.ItemDisplayEntityData;
|
||||
import net.momirealms.craftengine.bukkit.item.BukkitItemManager;
|
||||
import net.momirealms.craftengine.bukkit.nms.FastNMS;
|
||||
import net.momirealms.craftengine.bukkit.plugin.network.NMSPacketEvent;
|
||||
import net.momirealms.craftengine.core.entity.CustomTrident;
|
||||
import net.momirealms.craftengine.core.item.CustomItem;
|
||||
import net.momirealms.craftengine.core.item.Enchantment;
|
||||
import net.momirealms.craftengine.core.item.Item;
|
||||
import net.momirealms.craftengine.core.plugin.CraftEngine;
|
||||
@@ -12,74 +14,51 @@ import net.momirealms.craftengine.core.plugin.scheduler.SchedulerTask;
|
||||
import net.momirealms.craftengine.core.util.Key;
|
||||
import net.momirealms.craftengine.core.util.MCUtils;
|
||||
import net.momirealms.craftengine.core.util.VersionHelper;
|
||||
import org.bukkit.NamespacedKey;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.entity.Entity;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.entity.Trident;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.bukkit.persistence.PersistentDataContainer;
|
||||
import org.bukkit.persistence.PersistentDataType;
|
||||
import org.joml.Quaternionf;
|
||||
import org.joml.Vector3f;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import java.util.Optional;
|
||||
import java.util.UUID;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
public class CustomTridentUtils {
|
||||
public static final NamespacedKey customTridentKey = Objects.requireNonNull(NamespacedKey.fromString("craftengine:custom_trident"));
|
||||
public static final NamespacedKey interpolationDurationaKey = Objects.requireNonNull(NamespacedKey.fromString("craftengine:interpolation_duration"));
|
||||
public static final NamespacedKey displayTypeKey = Objects.requireNonNull(NamespacedKey.fromString("craftengine:display_type"));
|
||||
public static final NamespacedKey translationKey = Objects.requireNonNull(NamespacedKey.fromString("craftengine:translation"));
|
||||
public static final NamespacedKey rotationLeftKey = Objects.requireNonNull(NamespacedKey.fromString("craftengine:rotation_left"));
|
||||
|
||||
public static void handleCustomTrident(NetWorkUser user, NMSPacketEvent event, Object packet) throws IllegalAccessException {
|
||||
public static void handleCustomTrident(NetWorkUser user, NMSPacketEvent event, Object packet) {
|
||||
int entityId = FastNMS.INSTANCE.field$ClientboundAddEntityPacket$entityId(packet);
|
||||
Trident trident = getTridentById(user, entityId);
|
||||
if (trident == null) return;
|
||||
World world = trident.getWorld();
|
||||
Object serverEntity;
|
||||
Object nmsEntity = FastNMS.INSTANCE.method$CraftEntity$getHandle(trident);
|
||||
Object tracker = Reflections.field$Entity$trackedEntity.get(nmsEntity);
|
||||
if (tracker != null) {
|
||||
serverEntity = Reflections.field$ChunkMap$TrackedEntity$serverEntity.get(tracker);
|
||||
} else {
|
||||
serverEntity = null;
|
||||
}
|
||||
Object trackedEntity = FastNMS.INSTANCE.field$Entity$trackedEntity(nmsEntity);
|
||||
Object serverEntity = FastNMS.INSTANCE.filed$ChunkMap$TrackedEntity$serverEntity(trackedEntity);
|
||||
if (notCustomTrident(trident)) return;
|
||||
modifyCustomTridentPacket(packet);
|
||||
Object newPacket = modifyCustomTridentPacket(packet, entityId);
|
||||
List<Object> itemDisplayValues = buildEntityDataValues(trident);
|
||||
user.tridentView().put(entityId, itemDisplayValues);
|
||||
user.sendPacket(packet, true);
|
||||
user.sendPacket(newPacket, true);
|
||||
user.sendPacket(FastNMS.INSTANCE.constructor$ClientboundSetEntityDataPacket(entityId, itemDisplayValues), true);
|
||||
event.setCancelled(true);
|
||||
if (serverEntity != null) {
|
||||
// 这里直接暴力更新
|
||||
SchedulerTask task = CraftEngine.instance().scheduler().asyncRepeating(() -> {
|
||||
try {
|
||||
Reflections.method$ServerEntity$sendChanges.invoke(serverEntity);
|
||||
if (!isInGround(nmsEntity)) {
|
||||
world.spawnParticle(ParticleUtils.getParticle("BUBBLE"), trident.getLocation(), 1, 0, 0, 0, 0);
|
||||
}
|
||||
} catch (IllegalAccessException | InvocationTargetException e) {
|
||||
CraftEngine.instance().logger().warn("Failed to send entity data packet", e);
|
||||
FastNMS.INSTANCE.method$ServerEntity$sendChanges(serverEntity);
|
||||
if (canSpawnParticle(nmsEntity)) {
|
||||
world.spawnParticle(ParticleUtils.getParticle("BUBBLE"), trident.getLocation(), 1, 0, 0, 0, 0);
|
||||
}
|
||||
}, 0, 5, TimeUnit.MILLISECONDS);
|
||||
user.tridentTaskView().put(entityId, task);
|
||||
}
|
||||
}
|
||||
|
||||
private static boolean isInGround(Object nmsEntity) throws IllegalAccessException, InvocationTargetException {
|
||||
if (!Reflections.field$Entity$wasTouchingWater.getBoolean(nmsEntity)) return true;
|
||||
if (VersionHelper.isOrAbove1_21_2()) {
|
||||
return (boolean) Reflections.method$AbstractArrow$isInGround.invoke(nmsEntity);
|
||||
} else {
|
||||
return Reflections.field$AbstractArrow$inGround.getBoolean(nmsEntity);
|
||||
}
|
||||
private static boolean canSpawnParticle(Object nmsEntity) {
|
||||
if (!FastNMS.INSTANCE.field$AbstractArrow$wasTouchingWater(nmsEntity)) return false;
|
||||
return !FastNMS.INSTANCE.method$AbstractArrow$isInGround(nmsEntity);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@@ -92,62 +71,75 @@ public class CustomTridentUtils {
|
||||
|
||||
public static boolean notCustomTrident(Trident trident) {
|
||||
if (trident == null) return true;
|
||||
PersistentDataContainer container = trident.getItemStack().getItemMeta().getPersistentDataContainer();
|
||||
String customTrident = container.get(customTridentKey, PersistentDataType.STRING);
|
||||
return customTrident == null;
|
||||
Optional<CustomItem<ItemStack>> customItem = BukkitItemManager.instance().wrap(trident.getItemStack()).getCustomItem();
|
||||
return customItem.map(itemStackCustomItem -> itemStackCustomItem.settings().customTrident() == null).orElse(true);
|
||||
}
|
||||
|
||||
public static void modifyCustomTridentPacket(Object packet) throws IllegalAccessException {
|
||||
float yRot = MCUtils.unpackDegrees(Reflections.field$ClientboundAddEntityPacket$yRot.getByte(packet));
|
||||
float xRot = MCUtils.unpackDegrees(Reflections.field$ClientboundAddEntityPacket$xRot.getByte(packet));
|
||||
Reflections.field$ClientboundAddEntityPacket$type.set(packet, Reflections.instance$EntityType$ITEM_DISPLAY);
|
||||
Reflections.field$ClientboundAddEntityPacket$yRot.setByte(packet, MCUtils.packDegrees(-yRot));
|
||||
Reflections.field$ClientboundAddEntityPacket$xRot.setByte(packet, MCUtils.packDegrees(Math.clamp(-xRot, -90.0F, 90.0F)));
|
||||
public static Object modifyCustomTridentPacket(Object packet, int entityId) {
|
||||
UUID uuid = FastNMS.INSTANCE.field$ClientboundAddEntityPacket$uuid(packet);
|
||||
double x = FastNMS.INSTANCE.field$ClientboundAddEntityPacket$x(packet);
|
||||
double y = FastNMS.INSTANCE.field$ClientboundAddEntityPacket$y(packet);
|
||||
double z = FastNMS.INSTANCE.field$ClientboundAddEntityPacket$z(packet);
|
||||
float yRot = FastNMS.INSTANCE.field$ClientboundAddEntityPacket$yRot(packet);
|
||||
float xRot = FastNMS.INSTANCE.field$ClientboundAddEntityPacket$xRot(packet);
|
||||
Object type = Reflections.instance$EntityType$ITEM_DISPLAY;
|
||||
int data = FastNMS.INSTANCE.field$ClientboundAddEntityPacket$data(packet);
|
||||
double xa = FastNMS.INSTANCE.field$ClientboundAddEntityPacket$xa(packet);
|
||||
double ya = FastNMS.INSTANCE.field$ClientboundAddEntityPacket$ya(packet);
|
||||
double za = FastNMS.INSTANCE.field$ClientboundAddEntityPacket$za(packet);
|
||||
double yHeadRot = FastNMS.INSTANCE.field$ClientboundAddEntityPacket$yHeadRot(packet);
|
||||
return FastNMS.INSTANCE.constructor$ClientboundAddEntityPacket(
|
||||
entityId, uuid, x, y, z,
|
||||
MCUtils.clamp(-xRot, -90.0F, 90.0F), -yRot,
|
||||
type, data, FastNMS.INSTANCE.constructor$Vec3(xa, ya, za), yHeadRot
|
||||
);
|
||||
}
|
||||
|
||||
public static List<Object> buildEntityDataValues(Trident trident) {
|
||||
List<Object> itemDisplayValues = new ArrayList<>();
|
||||
ItemStack itemStack = trident.getItemStack();
|
||||
PersistentDataContainer container = itemStack.getItemMeta().getPersistentDataContainer();
|
||||
String customTrident = container.getOrDefault(customTridentKey, PersistentDataType.STRING, "craftengine:empty");
|
||||
Item<ItemStack> item = BukkitItemManager.instance().createWrappedItem(Key.of(customTrident), null);
|
||||
Optional<CustomItem<ItemStack>> customItem = BukkitItemManager.instance().wrap(itemStack).getCustomItem();
|
||||
if (customItem.isEmpty()) return itemDisplayValues;
|
||||
CustomTrident customTrident = customItem.get().settings().customTrident();
|
||||
Item<ItemStack> item = BukkitItemManager.instance().createWrappedItem(customTrident.customTridentItemId(), null);
|
||||
itemStack.getEnchantments().forEach((enchantment, level) -> item.addEnchantment(new Enchantment(Key.of(enchantment.getKey().toString()), level)));
|
||||
Integer interpolationDurationa = container.getOrDefault(interpolationDurationaKey, PersistentDataType.INTEGER, 2);
|
||||
Byte displayType = container.getOrDefault(displayTypeKey, PersistentDataType.BYTE, (byte) 0);
|
||||
String translation = container.getOrDefault(translationKey, PersistentDataType.STRING, "0+0+0");
|
||||
String[] translations = translation.split("\\+");
|
||||
String rotationLeft = container.getOrDefault(rotationLeftKey, PersistentDataType.STRING, "0+0+0+0");
|
||||
String[] rotationLefts = rotationLeft.split("\\+");
|
||||
ItemDisplayEntityData.InterpolationDelay.addEntityDataIfNotDefaultValue(-1, itemDisplayValues);
|
||||
ItemDisplayEntityData.Translation.addEntityDataIfNotDefaultValue(new Vector3f(Float.parseFloat(translations[0]), Float.parseFloat(translations[1]), Float.parseFloat(translations[2])), itemDisplayValues);
|
||||
ItemDisplayEntityData.RotationLeft.addEntityDataIfNotDefaultValue(new Quaternionf(Float.parseFloat(rotationLefts[0]), Float.parseFloat(rotationLefts[1]), Float.parseFloat(rotationLefts[2]), Float.parseFloat(rotationLefts[3])), itemDisplayValues);
|
||||
ItemDisplayEntityData.Translation.addEntityDataIfNotDefaultValue(customTrident.translation(), itemDisplayValues);
|
||||
ItemDisplayEntityData.RotationLeft.addEntityDataIfNotDefaultValue(customTrident.rotationLefts(), itemDisplayValues);
|
||||
if (VersionHelper.isOrAbove1_20_2()) {
|
||||
ItemDisplayEntityData.TransformationInterpolationDuration.addEntityDataIfNotDefaultValue(interpolationDurationa, itemDisplayValues);
|
||||
ItemDisplayEntityData.PositionRotationInterpolationDuration.addEntityDataIfNotDefaultValue(interpolationDurationa, itemDisplayValues);
|
||||
ItemDisplayEntityData.TransformationInterpolationDuration.addEntityDataIfNotDefaultValue(2, itemDisplayValues);
|
||||
ItemDisplayEntityData.PositionRotationInterpolationDuration.addEntityDataIfNotDefaultValue(2, itemDisplayValues);
|
||||
} else {
|
||||
ItemDisplayEntityData.InterpolationDuration.addEntityDataIfNotDefaultValue(interpolationDurationa, itemDisplayValues);
|
||||
ItemDisplayEntityData.InterpolationDuration.addEntityDataIfNotDefaultValue(2, itemDisplayValues);
|
||||
}
|
||||
ItemDisplayEntityData.DisplayedItem.addEntityDataIfNotDefaultValue(item.getLiteralObject(), itemDisplayValues);
|
||||
ItemDisplayEntityData.DisplayType.addEntityDataIfNotDefaultValue(displayType, itemDisplayValues);
|
||||
ItemDisplayEntityData.DisplayType.addEntityDataIfNotDefaultValue(customTrident.displayType(), itemDisplayValues);
|
||||
return itemDisplayValues;
|
||||
}
|
||||
|
||||
public static void modifyCustomTridentPositionSync(NMSPacketEvent event, Object packet, int entityId) throws IllegalAccessException, InvocationTargetException, InstantiationException {
|
||||
Object positionMoveRotation = Reflections.field$ClientboundEntityPositionSyncPacket$values.get(packet);
|
||||
boolean onGround = Reflections.field$ClientboundEntityPositionSyncPacket$onGround.getBoolean(packet);
|
||||
Object position = Reflections.field$PositionMoveRotation$position.get(positionMoveRotation);
|
||||
Object deltaMovement = Reflections.field$PositionMoveRotation$deltaMovement.get(positionMoveRotation);
|
||||
float yRot = Reflections.field$PositionMoveRotation$yRot.getFloat(positionMoveRotation);
|
||||
float xRot = Reflections.field$PositionMoveRotation$xRot.getFloat(positionMoveRotation);
|
||||
Object newPositionMoveRotation = Reflections.constructor$PositionMoveRotation.newInstance(position, deltaMovement, -yRot, Math.clamp(-xRot, -90.0F, 90.0F));
|
||||
event.replacePacket(Reflections.constructor$ClientboundEntityPositionSyncPacket.newInstance(entityId, newPositionMoveRotation, onGround));
|
||||
public static Object buildCustomTridentPositionSync(Object packet, int entityId) {
|
||||
Object positionMoveRotation = FastNMS.INSTANCE.field$ClientboundEntityPositionSyncPacket$values(packet);
|
||||
boolean onGround = FastNMS.INSTANCE.field$ClientboundEntityPositionSyncPacket$onGround(packet);
|
||||
Object position = FastNMS.INSTANCE.field$PositionMoveRotation$position(positionMoveRotation);
|
||||
Object deltaMovement = FastNMS.INSTANCE.field$PositionMoveRotation$deltaMovement(positionMoveRotation);
|
||||
float yRot = FastNMS.INSTANCE.field$PositionMoveRotation$yRot(positionMoveRotation);
|
||||
float xRot = FastNMS.INSTANCE.field$PositionMoveRotation$xRot(positionMoveRotation);
|
||||
Object newPositionMoveRotation = FastNMS.INSTANCE.constructor$PositionMoveRotation(position, deltaMovement, -yRot, Math.clamp(-xRot, -90.0F, 90.0F));
|
||||
return FastNMS.INSTANCE.constructor$ClientboundEntityPositionSyncPacket(entityId, newPositionMoveRotation, onGround);
|
||||
}
|
||||
|
||||
public static void modifyCustomTridentMove(Object packet) throws IllegalAccessException {
|
||||
float xRot = MCUtils.unpackDegrees(Reflections.field$ClientboundMoveEntityPacket$xRot.getByte(packet));
|
||||
float yRot = MCUtils.unpackDegrees(Reflections.field$ClientboundMoveEntityPacket$yRot.getByte(packet));
|
||||
Reflections.field$ClientboundMoveEntityPacket$xRot.setByte(packet, MCUtils.packDegrees(Math.clamp(-xRot, -90.0F, 90.0F)));
|
||||
Reflections.field$ClientboundMoveEntityPacket$yRot.setByte(packet, MCUtils.packDegrees(-yRot));
|
||||
public static Object buildCustomTridentMove(Object packet, int entityId) {
|
||||
short xa = FastNMS.INSTANCE.field$ClientboundMoveEntityPacket$xa(packet);
|
||||
short ya = FastNMS.INSTANCE.field$ClientboundMoveEntityPacket$ya(packet);
|
||||
short za = FastNMS.INSTANCE.field$ClientboundMoveEntityPacket$za(packet);
|
||||
float xRot = MCUtils.unpackDegrees(FastNMS.INSTANCE.field$ClientboundMoveEntityPacket$xRot(packet));
|
||||
float yRot = MCUtils.unpackDegrees(FastNMS.INSTANCE.field$ClientboundMoveEntityPacket$yRot(packet));
|
||||
boolean onGround = FastNMS.INSTANCE.field$ClientboundMoveEntityPacket$onGround(packet);
|
||||
return FastNMS.INSTANCE.constructor$ClientboundMoveEntityPacket$PosRot(
|
||||
entityId, xa, ya, za,
|
||||
MCUtils.packDegrees(-yRot), MCUtils.packDegrees(MCUtils.clamp(-xRot, -90.0F, 90.0F)),
|
||||
onGround
|
||||
);
|
||||
}
|
||||
|
||||
public static List<Object> buildCustomTridentSetEntityDataPacket(NetWorkUser user, List<Object> packedItems, int entityId) {
|
||||
|
||||
@@ -6632,130 +6632,4 @@ public class Reflections {
|
||||
)
|
||||
);
|
||||
|
||||
public static final Field field$ClientboundSetEntityDataPacket$id = requireNonNull(
|
||||
ReflectionUtils.getDeclaredField(
|
||||
clazz$ClientboundSetEntityDataPacket, int.class, 0
|
||||
)
|
||||
);
|
||||
|
||||
public static final Class<?> clazz$PositionMoveRotation =
|
||||
ReflectionUtils.getClazz(
|
||||
BukkitReflectionUtils.assembleMCClass("world.entity.PositionMoveRotation")
|
||||
);
|
||||
|
||||
public static final Constructor<?> constructor$PositionMoveRotation = Optional.ofNullable(clazz$PositionMoveRotation)
|
||||
.map(ReflectionUtils::getTheOnlyConstructor)
|
||||
.orElse(null);
|
||||
|
||||
public static final Field field$ClientboundEntityPositionSyncPacket$values = Optional.ofNullable(clazz$ClientboundEntityPositionSyncPacket)
|
||||
.map(it -> ReflectionUtils.getInstanceDeclaredField(it, clazz$PositionMoveRotation, 0))
|
||||
.orElse(null);
|
||||
|
||||
public static final Field field$ClientboundEntityPositionSyncPacket$onGround = Optional.ofNullable(clazz$ClientboundEntityPositionSyncPacket)
|
||||
.map(it -> ReflectionUtils.getInstanceDeclaredField(it, boolean.class, 0))
|
||||
.orElse(null);
|
||||
|
||||
public static final Field field$PositionMoveRotation$position = Optional.ofNullable(clazz$PositionMoveRotation)
|
||||
.map(it -> ReflectionUtils.getInstanceDeclaredField(it, clazz$Vec3, 0))
|
||||
.orElse(null);
|
||||
|
||||
public static final Field field$PositionMoveRotation$deltaMovement = Optional.ofNullable(clazz$PositionMoveRotation)
|
||||
.map(it -> ReflectionUtils.getInstanceDeclaredField(it, clazz$Vec3, 1))
|
||||
.orElse(null);
|
||||
|
||||
public static final Field field$PositionMoveRotation$yRot = Optional.ofNullable(clazz$PositionMoveRotation)
|
||||
.map(it -> ReflectionUtils.getInstanceDeclaredField(it, float.class, 0))
|
||||
.orElse(null);
|
||||
|
||||
public static final Field field$PositionMoveRotation$xRot = Optional.ofNullable(clazz$PositionMoveRotation)
|
||||
.map(it -> ReflectionUtils.getInstanceDeclaredField(it, float.class, 1))
|
||||
.orElse(null);
|
||||
|
||||
public static final Constructor<?> constructor$ClientboundEntityPositionSyncPacket = Optional.ofNullable(clazz$ClientboundEntityPositionSyncPacket)
|
||||
.map(ReflectionUtils::getTheOnlyConstructor)
|
||||
.orElse(null);
|
||||
|
||||
public static final Field field$ClientboundAddEntityPacket$xRot = requireNonNull(
|
||||
ReflectionUtils.getDeclaredField(
|
||||
clazz$ClientboundAddEntityPacket, byte.class, 0
|
||||
)
|
||||
);
|
||||
|
||||
public static final Field field$ClientboundAddEntityPacket$yRot = requireNonNull(
|
||||
ReflectionUtils.getDeclaredField(
|
||||
clazz$ClientboundAddEntityPacket, byte.class, 1
|
||||
)
|
||||
);
|
||||
|
||||
public static final Field field$ClientboundMoveEntityPacket$xRot = requireNonNull(
|
||||
ReflectionUtils.getDeclaredField(
|
||||
clazz$ClientboundMoveEntityPacket, byte.class, 1
|
||||
)
|
||||
);
|
||||
|
||||
public static final Field field$ClientboundMoveEntityPacket$yRot = requireNonNull(
|
||||
ReflectionUtils.getDeclaredField(
|
||||
clazz$ClientboundMoveEntityPacket, byte.class, 0
|
||||
)
|
||||
);
|
||||
|
||||
public static final Class<?> clazz$ServerEntity = requireNonNull(
|
||||
BukkitReflectionUtils.findReobfOrMojmapClass(
|
||||
"server.level.EntityTrackerEntry",
|
||||
"server.level.ServerEntity"
|
||||
)
|
||||
);
|
||||
|
||||
public static final Method method$ServerEntity$sendChanges = requireNonNull(
|
||||
ReflectionUtils.getMethod(
|
||||
clazz$ServerEntity, void.class, new String[]{ "sendChanges", "a" }
|
||||
)
|
||||
);
|
||||
|
||||
public static final Class<?> clazz$ChunkMap$TrackedEntity = requireNonNull(
|
||||
BukkitReflectionUtils.findReobfOrMojmapClass(
|
||||
"server.level.PlayerChunkMap$EntityTracker",
|
||||
"server.level.ChunkMap$TrackedEntity"
|
||||
)
|
||||
);
|
||||
|
||||
public static final Field field$Entity$trackedEntity = requireNonNull(
|
||||
ReflectionUtils.getDeclaredField(
|
||||
clazz$Entity, clazz$ChunkMap$TrackedEntity, 0
|
||||
)
|
||||
);
|
||||
|
||||
public static final Field field$ChunkMap$TrackedEntity$serverEntity = requireNonNull(
|
||||
ReflectionUtils.getDeclaredField(
|
||||
clazz$ChunkMap$TrackedEntity, clazz$ServerEntity, 0
|
||||
)
|
||||
);
|
||||
|
||||
public static final Field field$Entity$wasTouchingWater = requireNonNull(
|
||||
ReflectionUtils.getDeclaredField(
|
||||
clazz$Entity, VersionHelper.isOrAbove1_21_2()
|
||||
? new String[]{ "wasTouchingWater", "ag" } : VersionHelper.isOrAbove1_20_5()
|
||||
? new String[]{ "wasTouchingWater", "aj" } : VersionHelper.isOrAbove1_20_2()
|
||||
? new String[]{ "wasTouchingWater", "ai" } : new String[]{ "wasTouchingWater", "ah" }
|
||||
)
|
||||
);
|
||||
|
||||
public static final Class<?> clazz$AbstractArrow = requireNonNull(
|
||||
BukkitReflectionUtils.findReobfOrMojmapClass(
|
||||
"world.entity.projectile.EntityArrow",
|
||||
"world.entity.projectile.AbstractArrow"
|
||||
)
|
||||
);
|
||||
|
||||
// 1.20~1.21.1
|
||||
public static final Field field$AbstractArrow$inGround =
|
||||
ReflectionUtils.getDeclaredField(
|
||||
clazz$AbstractArrow, boolean.class, 0
|
||||
);
|
||||
|
||||
// 1.21.2+
|
||||
public static final Method method$AbstractArrow$isInGround =
|
||||
ReflectionUtils.getMethod(
|
||||
clazz$AbstractArrow, boolean.class, VersionHelper.isOrAbove1_21_5() ? new String[]{ "isInGround", "e" } : new String[]{ "isInGround", "l" }
|
||||
);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,8 @@
|
||||
package net.momirealms.craftengine.core.entity;
|
||||
|
||||
import net.momirealms.craftengine.core.util.Key;
|
||||
import org.joml.Quaternionf;
|
||||
import org.joml.Vector3f;
|
||||
|
||||
public record CustomTrident(Key customTridentItemId, Byte displayType, Vector3f translation, Quaternionf rotationLefts) {
|
||||
}
|
||||
@@ -1,5 +1,6 @@
|
||||
package net.momirealms.craftengine.core.item;
|
||||
|
||||
import net.momirealms.craftengine.core.entity.CustomTrident;
|
||||
import net.momirealms.craftengine.core.item.modifier.EquippableModifier;
|
||||
import net.momirealms.craftengine.core.item.modifier.ItemDataModifier;
|
||||
import net.momirealms.craftengine.core.pack.misc.EquipmentGeneration;
|
||||
@@ -9,6 +10,8 @@ import net.momirealms.craftengine.core.util.MiscUtils;
|
||||
import net.momirealms.craftengine.core.util.ResourceConfigUtils;
|
||||
import net.momirealms.craftengine.core.util.VersionHelper;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.joml.Quaternionf;
|
||||
import org.joml.Vector3f;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.stream.Collectors;
|
||||
@@ -22,6 +25,7 @@ public class ItemSettings {
|
||||
List<AnvilRepairItem> anvilRepairItems = List.of();
|
||||
boolean renameable = true;
|
||||
boolean canPlaceRelatedVanillaBlock = false;
|
||||
CustomTrident customTrident;
|
||||
|
||||
private ItemSettings() {}
|
||||
|
||||
@@ -50,6 +54,7 @@ public class ItemSettings {
|
||||
newSettings.anvilRepairItems = settings.anvilRepairItems;
|
||||
newSettings.renameable = settings.renameable;
|
||||
newSettings.canPlaceRelatedVanillaBlock = settings.canPlaceRelatedVanillaBlock;
|
||||
newSettings.customTrident = settings.customTrident;
|
||||
return newSettings;
|
||||
}
|
||||
|
||||
@@ -65,6 +70,10 @@ public class ItemSettings {
|
||||
return settings;
|
||||
}
|
||||
|
||||
public CustomTrident customTrident() {
|
||||
return customTrident;
|
||||
}
|
||||
|
||||
public boolean canPlaceRelatedVanillaBlock() {
|
||||
return canPlaceRelatedVanillaBlock;
|
||||
}
|
||||
@@ -109,6 +118,11 @@ public class ItemSettings {
|
||||
return this;
|
||||
}
|
||||
|
||||
public ItemSettings customTrident(CustomTrident customTrident) {
|
||||
this.customTrident = customTrident;
|
||||
return this;
|
||||
}
|
||||
|
||||
public ItemSettings canPlaceRelatedVanillaBlock(boolean canPlaceRelatedVanillaBlock) {
|
||||
this.canPlaceRelatedVanillaBlock = canPlaceRelatedVanillaBlock;
|
||||
return this;
|
||||
@@ -193,6 +207,14 @@ public class ItemSettings {
|
||||
boolean bool = (boolean) value;
|
||||
return settings -> settings.canPlaceRelatedVanillaBlock(bool);
|
||||
}));
|
||||
registerFactory("custom-trident", (value -> {
|
||||
Map<String, Object> args = MiscUtils.castToMap(value, false);
|
||||
Key customTridentItemId = Key.of(args.get("custom-trident-item").toString());
|
||||
Byte displayType = Byte.valueOf(args.get("display-type").toString());
|
||||
Vector3f translation = MiscUtils.getAsVector3f(args.get("translation"), "translation");
|
||||
Quaternionf rotationLefts = MiscUtils.getAsQuaternionf(args.get("rotation-left"), "rotation-left");
|
||||
return settings -> settings.customTrident(new CustomTrident(customTridentItemId, displayType, translation, rotationLefts));
|
||||
}));
|
||||
}
|
||||
|
||||
private static void registerFactory(String id, ItemSettings.Modifier.Factory factory) {
|
||||
|
||||
@@ -197,4 +197,16 @@ public class MCUtils {
|
||||
public static float unpackDegrees(byte degrees) {
|
||||
return (float)(degrees * 360) / 256.0F;
|
||||
}
|
||||
|
||||
public static int clamp(int value, int min, int max) {
|
||||
return Math.min(Math.max(value, min), max);
|
||||
}
|
||||
|
||||
public static float clamp(float value, float min, float max) {
|
||||
return value < min ? min : Math.min(value, max);
|
||||
}
|
||||
|
||||
public static double clamp(double value, double min, double max) {
|
||||
return value < min ? min : Math.min(value, max);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -50,7 +50,7 @@ byte_buddy_version=1.17.5
|
||||
ahocorasick_version=0.6.3
|
||||
snake_yaml_version=2.4
|
||||
anti_grief_version=0.15
|
||||
nms_helper_version=0.65.15
|
||||
nms_helper_version=0.65.17
|
||||
evalex_version=3.5.0
|
||||
reactive_streams_version=1.0.4
|
||||
amazon_awssdk_version=2.31.23
|
||||
|
||||
Reference in New Issue
Block a user