diff --git a/bukkit/legacy/src/main/java/net/momirealms/craftengine/bukkit/util/LegacyAuthLibUtils.java b/bukkit/legacy/src/main/java/net/momirealms/craftengine/bukkit/util/LegacyAuthLibUtils.java new file mode 100644 index 000000000..63a00b16e --- /dev/null +++ b/bukkit/legacy/src/main/java/net/momirealms/craftengine/bukkit/util/LegacyAuthLibUtils.java @@ -0,0 +1,16 @@ +package net.momirealms.craftengine.bukkit.util; + +import com.mojang.authlib.GameProfile; + +import java.util.UUID; + +public class LegacyAuthLibUtils { + + public static String getName(GameProfile profile) { + return profile.getName(); + } + + public static UUID getId(GameProfile profile) { + return profile.getId(); + } +} diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/behavior/FallingBlockBehavior.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/behavior/FallingBlockBehavior.java index e41956aec..48a99aa1f 100644 --- a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/behavior/FallingBlockBehavior.java +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/behavior/FallingBlockBehavior.java @@ -1,6 +1,7 @@ package net.momirealms.craftengine.bukkit.block.behavior; import net.momirealms.craftengine.bukkit.block.BukkitBlockManager; +import net.momirealms.craftengine.bukkit.entity.data.BaseEntityData; import net.momirealms.craftengine.bukkit.nms.FastNMS; import net.momirealms.craftengine.bukkit.plugin.reflection.minecraft.CoreReflections; import net.momirealms.craftengine.bukkit.util.BlockStateUtils; @@ -75,8 +76,7 @@ public class FallingBlockBehavior extends BukkitBlockBehavior { Object level = args[0]; Object fallingBlockEntity = args[2]; Object entityData = CoreReflections.field$Entity$entityData.get(fallingBlockEntity); - boolean isSilent = (boolean) CoreReflections.method$SynchedEntityData$get.invoke(entityData, CoreReflections.instance$Entity$DATA_SILENT); - if (!isSilent) { + if (!BaseEntityData.Silent.get(entityData)) { Object blockState = CoreReflections.field$FallingBlockEntity$blockState.get(fallingBlockEntity); Optional optionalCustomState = BlockStateUtils.getOptionalCustomBlockState(blockState); if (optionalCustomState.isEmpty()) return; @@ -93,12 +93,11 @@ public class FallingBlockBehavior extends BukkitBlockBehavior { Object level = args[0]; Object pos = args[1]; Object entityData = CoreReflections.field$Entity$entityData.get(fallingBlock); - boolean isSilent = (boolean) CoreReflections.method$SynchedEntityData$get.invoke(entityData, CoreReflections.instance$Entity$DATA_SILENT); Object blockState = args[2]; int stateId = BlockStateUtils.blockStateToId(blockState); ImmutableBlockState immutableBlockState = BukkitBlockManager.instance().getImmutableBlockState(stateId); if (immutableBlockState == null || immutableBlockState.isEmpty()) return; - if (!isSilent) { + if (!BaseEntityData.Silent.get(entityData)) { net.momirealms.craftengine.core.world.World world = new BukkitWorld(FastNMS.INSTANCE.method$Level$getCraftWorld(level)); world.playBlockSound(Vec3d.atCenterOf(LocationUtils.fromBlockPos(pos)), immutableBlockState.settings().sounds().landSound()); } diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/entity/data/EntityData.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/entity/data/EntityData.java index da99028c4..0574a93f9 100644 --- a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/entity/data/EntityData.java +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/entity/data/EntityData.java @@ -1,5 +1,7 @@ package net.momirealms.craftengine.bukkit.entity.data; +import net.momirealms.craftengine.bukkit.nms.FastNMS; + import java.util.List; public interface EntityData { @@ -27,6 +29,11 @@ public interface EntityData { list.add(EntityDataValue.create(id(), serializer(), entityDataAccessor(), value)); } + @SuppressWarnings("unchecked") + default T get(Object entityData) { + return (T) FastNMS.INSTANCE.method$SynchedEntityData$get(entityData, entityDataAccessor()); + } + static EntityData of(Class clazz, Object serializer, T defaultValue) { return new SimpleEntityData<>(clazz, serializer, defaultValue); } diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/entity/data/EntityDataValue.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/entity/data/EntityDataValue.java index fee5d034f..30d191d09 100644 --- a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/entity/data/EntityDataValue.java +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/entity/data/EntityDataValue.java @@ -71,7 +71,8 @@ public class EntityDataValue { if (VersionHelper.isOrAbove1_21_5()) Serializers$OPTIONAL_LIVING_ENTITY_REFERENCE = initSerializersByName("OPTIONAL_LIVING_ENTITY_REFERENCE"); else Serializers$OPTIONAL_LIVING_ENTITY_REFERENCE = null; Serializers$OPTIONAL_GLOBAL_POS = initSerializersByName("OPTIONAL_GLOBAL_POS"); - Serializers$COMPOUND_TAG = initSerializersByName("COMPOUND_TAG"); + if (!VersionHelper.isOrAbove1_21_9()) Serializers$COMPOUND_TAG = initSerializersByName("COMPOUND_TAG"); + else Serializers$COMPOUND_TAG = null; Serializers$VILLAGER_DATA = initSerializersByName("VILLAGER_DATA"); Serializers$OPTIONAL_UNSIGNED_INT = initSerializersByName("OPTIONAL_UNSIGNED_INT"); Serializers$POSE = initSerializersByName("POSE"); diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/item/factory/BukkitItemFactory.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/item/factory/BukkitItemFactory.java index c8f760d99..f836d910b 100644 --- a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/item/factory/BukkitItemFactory.java +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/item/factory/BukkitItemFactory.java @@ -49,7 +49,7 @@ public abstract class BukkitItemFactory> extend case "1.21.4" -> { return new ComponentItemFactory1_21_4(plugin); } - case "1.21.5", "1.21.6", "1.21.7", "1.21.8" -> { + case "1.21.5", "1.21.6", "1.21.7", "1.21.8", "1.21.9" -> { return new ComponentItemFactory1_21_5(plugin); } default -> throw new IllegalStateException("Unsupported server version: " + plugin.serverVersion()); diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/command/BukkitCommandManager.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/command/BukkitCommandManager.java index 9d80faf29..024b38db9 100644 --- a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/command/BukkitCommandManager.java +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/command/BukkitCommandManager.java @@ -60,7 +60,7 @@ public class BukkitCommandManager extends AbstractCommandManager )); final LegacyPaperCommandManager manager = (LegacyPaperCommandManager) getCommandManager(); manager.settings().set(ManagerSetting.ALLOW_UNSAFE_REGISTRATION, true); - if (manager.hasCapability(CloudBukkitCapabilities.NATIVE_BRIGADIER)) { + if (manager.hasCapability(CloudBukkitCapabilities.NATIVE_BRIGADIER) && manager.hasCapability(CloudBukkitCapabilities.BRIGADIER)) { manager.registerBrigadier(); manager.brigadierManager().setNativeNumberSuggestions(true); } else if (manager.hasCapability(CloudBukkitCapabilities.ASYNCHRONOUS_COMPLETION)) { diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/network/BukkitNetworkManager.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/network/BukkitNetworkManager.java index 4671b7ed5..7ced7ec1b 100644 --- a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/network/BukkitNetworkManager.java +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/network/BukkitNetworkManager.java @@ -1815,8 +1815,13 @@ public class BukkitNetworkManager implements NetworkManager, Listener, PluginMes @Override public void onPacketSend(NetWorkUser user, NMSPacketEvent event, Object packet) { GameProfile gameProfile = FastNMS.INSTANCE.field$ClientboundLoginFinishedPacket$gameProfile(packet); - user.setVerifiedName(gameProfile.getName()); - user.setVerifiedUUID(gameProfile.getId()); + if (VersionHelper.isOrAbove1_21_9()) { + user.setVerifiedName(gameProfile.name()); + user.setVerifiedUUID(gameProfile.id()); + } else { + user.setVerifiedName(LegacyAuthLibUtils.getName(gameProfile)); + user.setVerifiedUUID(LegacyAuthLibUtils.getId(gameProfile)); + } } } @@ -3533,6 +3538,7 @@ public class BukkitNetworkManager implements NetworkManager, Listener, PluginMes double x = buf.readDouble(); double y = buf.readDouble(); double z = buf.readDouble(); + Vec3d movement = VersionHelper.isOrAbove1_21_9() ? buf.readLpVec3() : null; byte xRot = buf.readByte(); byte yRot = buf.readByte(); byte yHeadRot = buf.readByte(); @@ -3540,9 +3546,9 @@ public class BukkitNetworkManager implements NetworkManager, Listener, PluginMes // Falling blocks int remapped = remapBlockState(data, user.clientModEnabled()); if (remapped != data) { - int xa = buf.readShort(); - int ya = buf.readShort(); - int za = buf.readShort(); + int xa = VersionHelper.isOrAbove1_21_9() ? -1 : buf.readShort(); + int ya = VersionHelper.isOrAbove1_21_9() ? -1 : buf.readShort(); + int za = VersionHelper.isOrAbove1_21_9() ? -1 : buf.readShort(); event.setChanged(true); buf.clear(); buf.writeVarInt(event.packetID()); @@ -3552,13 +3558,14 @@ public class BukkitNetworkManager implements NetworkManager, Listener, PluginMes buf.writeDouble(x); buf.writeDouble(y); buf.writeDouble(z); + if (VersionHelper.isOrAbove1_21_9()) buf.writeLpVec3(movement); buf.writeByte(xRot); buf.writeByte(yRot); buf.writeByte(yHeadRot); buf.writeVarInt(remapped); - buf.writeShort(xa); - buf.writeShort(ya); - buf.writeShort(za); + if (!VersionHelper.isOrAbove1_21_9()) buf.writeShort(xa); + if (!VersionHelper.isOrAbove1_21_9()) buf.writeShort(ya); + if (!VersionHelper.isOrAbove1_21_9()) buf.writeShort(za); } }; this.handlers[MEntityTypes.ITEM_DISPLAY$registryId] = (user, event) -> { diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/network/handler/ProjectilePacketHandler.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/network/handler/ProjectilePacketHandler.java index 6e697af25..1524c7a39 100644 --- a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/network/handler/ProjectilePacketHandler.java +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/network/handler/ProjectilePacketHandler.java @@ -18,6 +18,7 @@ import net.momirealms.craftengine.core.plugin.network.NetWorkUser; import net.momirealms.craftengine.core.util.FriendlyByteBuf; import net.momirealms.craftengine.core.util.MCUtils; import net.momirealms.craftengine.core.util.VersionHelper; +import net.momirealms.craftengine.core.world.Vec3d; import org.bukkit.inventory.ItemStack; import java.util.ArrayList; @@ -70,13 +71,14 @@ public class ProjectilePacketHandler implements EntityPacketHandler { double x = buf.readDouble(); double y = buf.readDouble(); double z = buf.readDouble(); + Vec3d movement = VersionHelper.isOrAbove1_21_9() ? buf.readLpVec3() : null; byte xRot = buf.readByte(); byte yRot = buf.readByte(); byte yHeadRot = buf.readByte(); int data = buf.readVarInt(); - int xa = buf.readShort(); - int ya = buf.readShort(); - int za = buf.readShort(); + int xa = VersionHelper.isOrAbove1_21_9() ? -1 : buf.readShort(); + int ya = VersionHelper.isOrAbove1_21_9() ? -1 : buf.readShort(); + int za = VersionHelper.isOrAbove1_21_9() ? -1 : buf.readShort(); event.setChanged(true); buf.clear(); buf.writeVarInt(event.packetID()); @@ -86,13 +88,14 @@ public class ProjectilePacketHandler implements EntityPacketHandler { buf.writeDouble(x); buf.writeDouble(y); buf.writeDouble(z); + if (VersionHelper.isOrAbove1_21_9()) buf.writeLpVec3(movement); buf.writeByte(MCUtils.packDegrees(MCUtils.clamp(-MCUtils.unpackDegrees(xRot), -90.0F, 90.0F))); buf.writeByte(MCUtils.packDegrees(-MCUtils.unpackDegrees(yRot))); buf.writeByte(yHeadRot); buf.writeVarInt(data); - buf.writeShort(xa); - buf.writeShort(ya); - buf.writeShort(za); + if (!VersionHelper.isOrAbove1_21_9()) buf.writeShort(xa); + if (!VersionHelper.isOrAbove1_21_9()) buf.writeShort(ya); + if (!VersionHelper.isOrAbove1_21_9()) buf.writeShort(za); } private Object convertCustomProjectilePositionSyncPacket(Object packet) { diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/reflection/minecraft/CoreReflections.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/reflection/minecraft/CoreReflections.java index 571f99f4a..65a0549f6 100644 --- a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/reflection/minecraft/CoreReflections.java +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/reflection/minecraft/CoreReflections.java @@ -667,9 +667,9 @@ public final class CoreReflections { ) ); - public static final Method method$SynchedEntityData$get = requireNonNull( - ReflectionUtils.getMethod(clazz$SynchedEntityData, Object.class, clazz$EntityDataAccessor) - ); + // public static final Method method$SynchedEntityData$get = requireNonNull( + // ReflectionUtils.getDeclaredMethod(clazz$SynchedEntityData, Object.class, new String[]{"get", VersionHelper.isOrAbove1_20_5() ? "a" : "b"}, clazz$EntityDataAccessor) + // ); public static final Class clazz$SynchedEntityData$DataValue = requireNonNull( BukkitReflectionUtils.findReobfOrMojmapClass( @@ -974,9 +974,9 @@ public final class CoreReflections { ReflectionUtils.getDeclaredField(clazz$PalettedContainer$Data, clazz$Palette, 0) ); - public static final Method method$Palette$write = requireNonNull( - ReflectionUtils.getMethod(clazz$Palette, void.class, clazz$FriendlyByteBuf) - ); + // public static final Method method$Palette$write = requireNonNull( + // ReflectionUtils.getMethod(clazz$Palette, void.class, clazz$FriendlyByteBuf) + // ); public static final Class clazz$ChunkAccess = requireNonNull( BukkitReflectionUtils.findReobfOrMojmapClass( @@ -1576,7 +1576,9 @@ public final class CoreReflections { ); public static final Method method$BlockBehaviour$getAnalogOutputSignal = requireNonNull( - ReflectionUtils.getDeclaredMethod(clazz$BlockBehaviour, int.class, new String[]{"getAnalogOutputSignal", "a"}, clazz$BlockState, clazz$Level, clazz$BlockPos) + VersionHelper.isOrAbove1_21_9() + ? ReflectionUtils.getDeclaredMethod(clazz$BlockBehaviour, int.class, new String[]{"getAnalogOutputSignal", "a"}, clazz$BlockState, clazz$Level, clazz$BlockPos, clazz$Direction) + : ReflectionUtils.getDeclaredMethod(clazz$BlockBehaviour, int.class, new String[]{"getAnalogOutputSignal", "a"}, clazz$BlockState, clazz$Level, clazz$BlockPos) ); public static final Method method$Entity$level = requireNonNull( @@ -3609,23 +3611,23 @@ public final class CoreReflections { clazz$Registry, clazz$HolderLookup$RegistryLookup, new String[]{"asLookup", "p"} ); - public static final Field field$ServerEntity$broadcast = requireNonNull( - ReflectionUtils.getDeclaredField( - clazz$ServerEntity, Consumer.class, 0 - ) - ); + // public static final Field field$ServerEntity$broadcast = requireNonNull( + // ReflectionUtils.getDeclaredField( + // clazz$ServerEntity, Consumer.class, 0 + // ) + // ); - public static final MethodHandle methodHandle$ServerEntity$broadcastSetter; + // public static final MethodHandle methodHandle$ServerEntity$broadcastSetter; public static final MethodHandle methodHandle$ServerEntity$updateIntervalSetter; public static final MethodHandle methodHandle$ServerPlayer$connectionGetter; public static final MethodHandle methodHandle$ServerPlayer$getAttributeMethod; static { try { - methodHandle$ServerEntity$broadcastSetter = requireNonNull( - ReflectionUtils.unreflectSetter(field$ServerEntity$broadcast) - .asType(MethodType.methodType(void.class, Object.class, Consumer.class)) - ); + // methodHandle$ServerEntity$broadcastSetter = requireNonNull( + // ReflectionUtils.unreflectSetter(field$ServerEntity$broadcast) + // .asType(MethodType.methodType(void.class, Object.class, Consumer.class)) + // ); methodHandle$ServerEntity$updateIntervalSetter = requireNonNull( ReflectionUtils.unreflectSetter(field$ServerEntity$updateInterval) .asType(MethodType.methodType(void.class, Object.class, int.class)) diff --git a/common-files/src/main/resources/resources/default/resourcepack/pack.mcmeta b/common-files/src/main/resources/resources/default/resourcepack/pack.mcmeta index 0ae3705e1..4d5e8390e 100644 --- a/common-files/src/main/resources/resources/default/resourcepack/pack.mcmeta +++ b/common-files/src/main/resources/resources/default/resourcepack/pack.mcmeta @@ -1,10 +1,12 @@ { - "pack":{ + "pack": { "pack_format": 15, - "description":"CraftEngine", + "description": "CraftEngine", "supported_formats": { "min_inclusive": 15, "max_inclusive": 1000 - } + }, + "min_format": 15, + "max_format": 1000 } } \ No newline at end of file diff --git a/core/src/main/java/net/momirealms/craftengine/core/block/BlockBehavior.java b/core/src/main/java/net/momirealms/craftengine/core/block/BlockBehavior.java index e969cab8c..d81554d1a 100644 --- a/core/src/main/java/net/momirealms/craftengine/core/block/BlockBehavior.java +++ b/core/src/main/java/net/momirealms/craftengine/core/block/BlockBehavior.java @@ -100,7 +100,8 @@ public abstract class BlockBehavior { return false; } - // BlockState state, Level level, BlockPos pos + // 1.20.1~1.21.8 BlockState state, Level level, BlockPos pos + // 1.21.9+ BlockState state, Level level, BlockPos pos public int getAnalogOutputSignal(Object thisBlock, Object[] args) throws Exception { return 0; } diff --git a/core/src/main/java/net/momirealms/craftengine/core/pack/conflict/resolution/ResolutionMergePackMcMeta.java b/core/src/main/java/net/momirealms/craftengine/core/pack/conflict/resolution/ResolutionMergePackMcMeta.java index 186a1c3eb..be609eeb1 100644 --- a/core/src/main/java/net/momirealms/craftengine/core/pack/conflict/resolution/ResolutionMergePackMcMeta.java +++ b/core/src/main/java/net/momirealms/craftengine/core/pack/conflict/resolution/ResolutionMergePackMcMeta.java @@ -19,63 +19,148 @@ public class ResolutionMergePackMcMeta implements Resolution { this.description = description; } - private static class MinMax { - int min; - int max; - - MinMax(int min, int max) { - this.min = min; - this.max = max; - } + record MinMax(int min, int max) { } + @SuppressWarnings("DuplicatedCode") public static void mergeMcMeta(Path file1, Path file2, JsonElement customDescription) throws IOException { - JsonElement elem1 = GsonHelper.readJsonFile(file1); - JsonElement elem2 = GsonHelper.readJsonFile(file2); + JsonObject mcmeta1 = GsonHelper.readJsonFile(file1).getAsJsonObject(); + JsonObject mcmeta2 = GsonHelper.readJsonFile(file2).getAsJsonObject(); - JsonObject merged = mergeValues(elem1.getAsJsonObject(), elem2.getAsJsonObject()) - .getAsJsonObject(); + JsonObject merged = mergeValues(mcmeta1, mcmeta2).getAsJsonObject(); - if (merged.has("pack")) { - JsonObject pack = merged.getAsJsonObject("pack"); + if (mcmeta1.has("pack") && mcmeta2.has("pack")) { + JsonObject mergedPack = merged.getAsJsonObject("pack"); + JsonObject mcmeta1Pack = mcmeta1.getAsJsonObject("pack"); + JsonObject mcmeta2Pack = mcmeta2.getAsJsonObject("pack"); - int pf1 = elem1.getAsJsonObject().getAsJsonObject("pack") - .getAsJsonPrimitive("pack_format").getAsInt(); - int pf2 = elem2.getAsJsonObject().getAsJsonObject("pack") - .getAsJsonPrimitive("pack_format").getAsInt(); - pack.addProperty("pack_format", Math.max(pf1, pf2)); + int minPackFormat = Integer.MAX_VALUE; + int maxPackFormat = Integer.MIN_VALUE; + JsonArray mergedMinFormat = null; + JsonArray mergedMaxFormat = null; - JsonElement sf1 = elem1.getAsJsonObject().getAsJsonObject("pack") - .get("supported_formats"); - JsonElement sf2 = elem2.getAsJsonObject().getAsJsonObject("pack") - .get("supported_formats"); + if (mcmeta1Pack.has("pack_format") && mcmeta2Pack.has("pack_format")) { + int packFormat1 = mcmeta1Pack.getAsJsonPrimitive("pack_format").getAsInt(); + int packFormat2 = mcmeta2Pack.getAsJsonPrimitive("pack_format").getAsInt(); + int mergedPackFormat = maxPackFormat = Math.max(packFormat1, packFormat2); + minPackFormat = Math.min(packFormat1, packFormat2); + mergedPack.addProperty("pack_format", mergedPackFormat); + } else if (mcmeta1Pack.has("pack_format")) { + minPackFormat = maxPackFormat = mcmeta1Pack.getAsJsonPrimitive("pack_format").getAsInt(); + } else if (mcmeta2Pack.has("pack_format")) { + minPackFormat = maxPackFormat = mcmeta2Pack.getAsJsonPrimitive("pack_format").getAsInt(); + } - if (sf1 != null || sf2 != null) { - MinMax mergedMinMax = getMergedMinMax(sf1, sf2, pf1, pf2); + if (mcmeta1Pack.has("min_format") || mcmeta2Pack.has("min_format")) { + int[] minFormat1 = new int[]{Integer.MAX_VALUE, 0}; + int[] minFormat2 = new int[]{Integer.MAX_VALUE, 0}; - JsonElement mergedSf = createSupportedFormatsElement( - sf1 != null ? sf1 : sf2, + if (mcmeta1Pack.has("min_format")) { + JsonElement minFormat = mcmeta1Pack.get("min_format"); + if (minFormat.isJsonPrimitive()) { + minFormat1[0] = minFormat.getAsInt(); + } + if (minFormat.isJsonArray()) { + JsonArray minFormatArray = minFormat.getAsJsonArray(); + minFormat1[0] = minFormatArray.get(0).getAsInt(); + if (minFormatArray.size() > 1) { + minFormat1[1] = minFormatArray.get(1).getAsInt(); + } + } + } + + if (mcmeta2Pack.has("min_format")) { + JsonElement minFormat = mcmeta2Pack.get("min_format"); + if (minFormat.isJsonPrimitive()) { + minFormat2[0] = minFormat.getAsInt(); + } + if (mcmeta2Pack.isJsonArray()) { + JsonArray minFormatArray = minFormat.getAsJsonArray(); + minFormat2[0] = minFormatArray.get(0).getAsInt(); + if (minFormatArray.size() > 1) { + minFormat2[1] = minFormatArray.get(1).getAsInt(); + } + } + } + minPackFormat = Math.min(minPackFormat, Math.min(minFormat1[0], minFormat2[0])); + mergedMinFormat = new JsonArray(2); + mergedMinFormat.add(minPackFormat); + mergedMinFormat.add(Math.min(minFormat1[1], minFormat2[1])); + mergedPack.add("min_format", mergedMinFormat); + } + + if (mcmeta1Pack.has("max_format") || mcmeta2Pack.has("max_format")) { + int[] maxFormat1 = new int[]{Integer.MIN_VALUE, 0}; + int[] maxFormat2 = new int[]{Integer.MIN_VALUE, 0}; + + if (mcmeta1Pack.has("max_format")) { + JsonElement maxFormat = mcmeta1Pack.get("max_format"); + if (maxFormat.isJsonPrimitive()) { + maxFormat1[0] = maxFormat.getAsInt(); + } + if (maxFormat.isJsonArray()) { + JsonArray maxFormatArray = maxFormat.getAsJsonArray(); + maxFormat1[0] = maxFormatArray.get(0).getAsInt(); + if (maxFormatArray.size() > 1) { + maxFormat1[1] = maxFormatArray.get(1).getAsInt(); + } + } + } + + if (mcmeta2Pack.has("max_format")) { + JsonElement maxFormat = mcmeta2Pack.get("max_format"); + if (maxFormat.isJsonPrimitive()) { + maxFormat2[0] = maxFormat.getAsInt(); + } + if (maxFormat.isJsonArray()) { + JsonArray maxFormatArray = maxFormat.getAsJsonArray(); + maxFormat2[0] = maxFormatArray.get(0).getAsInt(); + if (maxFormatArray.size() > 1) { + maxFormat2[1] = maxFormatArray.get(1).getAsInt(); + } + } + } + + maxPackFormat = Math.max(maxPackFormat, Math.max(maxFormat1[0], maxFormat2[0])); + mergedMaxFormat = new JsonArray(2); + mergedMaxFormat.add(maxPackFormat); + mergedMaxFormat.add(Math.max(maxFormat1[1], maxFormat2[1])); + mergedPack.add("max_format", mergedMaxFormat); + } + + JsonElement supportedFormats1 = mcmeta1Pack.get("supported_formats"); + JsonElement supportedFormats2 = mcmeta2Pack.get("supported_formats"); + + if (supportedFormats1 != null || supportedFormats2 != null) { + MinMax mergedMinMax = getMergedMinMax(supportedFormats1, supportedFormats2, minPackFormat, maxPackFormat); + JsonElement mergedSupportedFormats = createSupportedFormatsElement( + supportedFormats1 != null ? supportedFormats1 : supportedFormats2, mergedMinMax.min, mergedMinMax.max ); - - pack.add("supported_formats", mergedSf); + if (mergedMinFormat != null && !mergedMinFormat.isEmpty()) { + mergedMinFormat.set(0, new JsonPrimitive(Math.min(mergedMinMax.min, mergedMinFormat.get(0).getAsInt()))); + } + if (mergedMaxFormat != null && !mergedMaxFormat.isEmpty()) { + mergedMaxFormat.set(0, new JsonPrimitive(Math.max(mergedMinMax.max, mergedMaxFormat.get(0).getAsInt()))); + } + mergedPack.add("supported_formats", mergedSupportedFormats); } if (customDescription != null) { - pack.add("description", customDescription); + mergedPack.add("description", customDescription); } else { - JsonPrimitive desc1 = elem1.getAsJsonObject().getAsJsonObject("pack") + JsonPrimitive description1 = mcmeta1.getAsJsonObject().getAsJsonObject("pack") .getAsJsonPrimitive("description"); - JsonPrimitive desc2 = elem2.getAsJsonObject().getAsJsonObject("pack") + JsonPrimitive description2 = mcmeta2.getAsJsonObject().getAsJsonObject("pack") .getAsJsonPrimitive("description"); - String mergedDesc = (desc1 != null ? desc1.getAsString() : "") - + (desc1 != null && desc2 != null ? "\n" : "") - + (desc2 != null ? desc2.getAsString() : ""); + String mergedDesc = (description1 != null ? description1.getAsString() : "") + + (description1 != null && description2 != null ? "\n" : "") + + (description2 != null ? description2.getAsString() : ""); if (!mergedDesc.isEmpty()) { - pack.addProperty("description", mergedDesc); + mergedPack.addProperty("description", mergedDesc); } } } @@ -83,16 +168,14 @@ public class ResolutionMergePackMcMeta implements Resolution { GsonHelper.writeJsonFile(merged, file1); } - private static MinMax getMergedMinMax(JsonElement sf1, JsonElement sf2, int pf1, int pf2) { + private static MinMax getMergedMinMax(JsonElement sf1, JsonElement sf2, int minPackFormat, int maxPackFormat) { MinMax mm1 = parseSupportedFormats(sf1); MinMax mm2 = parseSupportedFormats(sf2); int finalMin = Math.min(mm1.min, mm2.min); int finalMax = Math.max(mm1.max, mm2.max); - int pfMin = Math.min(pf1, pf2); - int pfMax = Math.max(pf1, pf2); - finalMin = Math.min(pfMin, finalMin); - finalMax = Math.max(pfMax, finalMax); + finalMin = Math.min(minPackFormat, finalMin); + finalMax = Math.max(maxPackFormat, finalMax); return new MinMax(finalMin, finalMax); } @@ -110,7 +193,7 @@ public class ResolutionMergePackMcMeta implements Resolution { if (supported.isJsonArray()) { JsonArray arr = supported.getAsJsonArray(); int min = arr.get(0).getAsInt(); - int max = arr.get(arr.size()-1).getAsInt(); + int max = arr.get(arr.size() - 1).getAsInt(); return new MinMax(min, max); } diff --git a/core/src/main/java/net/momirealms/craftengine/core/util/FriendlyByteBuf.java b/core/src/main/java/net/momirealms/craftengine/core/util/FriendlyByteBuf.java index 68e30c8a2..62c582ee7 100644 --- a/core/src/main/java/net/momirealms/craftengine/core/util/FriendlyByteBuf.java +++ b/core/src/main/java/net/momirealms/craftengine/core/util/FriendlyByteBuf.java @@ -14,6 +14,7 @@ import it.unimi.dsi.fastutil.ints.IntList; import net.kyori.adventure.text.Component; import net.momirealms.craftengine.core.registry.Registry; import net.momirealms.craftengine.core.world.BlockPos; +import net.momirealms.craftengine.core.world.Vec3d; import net.momirealms.sparrow.nbt.NBT; import net.momirealms.sparrow.nbt.Tag; import org.jetbrains.annotations.NotNull; @@ -76,7 +77,7 @@ public class FriendlyByteBuf extends ByteBuf { public > C readCollection(IntFunction collectionFactory, Reader reader) { int i = this.readVarInt(); C collection = collectionFactory.apply(i); - for(int j = 0; j < i; ++j) { + for (int j = 0; j < i; ++j) { collection.add(reader.apply(this)); } return collection; @@ -93,7 +94,7 @@ public class FriendlyByteBuf extends ByteBuf { public T[] readArray(Reader reader, Class type) { int i = this.readVarInt(); T[] array = (T[]) Array.newInstance(type, i); - for(int j = 0; j < i; ++j) { + for (int j = 0; j < i; ++j) { array[j] = reader.apply(this); } return array; @@ -101,7 +102,7 @@ public class FriendlyByteBuf extends ByteBuf { public void writeArray(T[] array, Writer writer) { this.writeVarInt(array.length); - for(T t : array) { + for (T t : array) { writer.accept(this, t); } } @@ -351,7 +352,7 @@ public class FriendlyByteBuf extends ByteBuf { } public long[] readFixedSizeLongArray(long[] output) { - for(int i = 0; i < output.length; ++i) { + for (int i = 0; i < output.length; ++i) { output[i] = this.readLong(); } return output; @@ -473,12 +474,12 @@ public class FriendlyByteBuf extends ByteBuf { public void writeHolderSet(Either, Key> holderSet) { holderSet.ifLeft( - ints -> { - writeVarInt(ints.size() + 1); - for (Integer anInt : ints) { - writeVarInt(anInt); + ints -> { + writeVarInt(ints.size() + 1); + for (Integer anInt : ints) { + writeVarInt(anInt); + } } - } ).ifRight(key -> { writeVarInt(0); writeKey(key); @@ -599,13 +600,57 @@ public class FriendlyByteBuf extends ByteBuf { @SuppressWarnings("unchecked") public > T readEnumConstant(Class enumClass) { - return (T)((Enum[])enumClass.getEnumConstants())[this.readVarInt()]; + return (T) ((Enum[]) enumClass.getEnumConstants())[this.readVarInt()]; } public FriendlyByteBuf writeEnumConstant(Enum instance) { return this.writeVarInt(instance.ordinal()); } + public Vec3d readLpVec3() { + int unsignedByte = this.readUnsignedByte(); + if (unsignedByte == 0) { + return Vec3d.ZERO; + } else { + int unsignedByte1 = this.readUnsignedByte(); + long unsignedInt = this.readUnsignedInt(); + long l = unsignedInt << 16 | (long) (unsignedByte1 << 8) | (long) unsignedByte; + long l1 = unsignedByte & 3; + if ((unsignedByte & 4) == 4) { + l1 |= ((long) this.readVarInt() & 4294967295L) << 2; + } + return new Vec3d( + (Math.min((double) ((l >> 3) & 32767L), (double) 32766.0F) * (double) 2.0F / (double) 32766.0F - (double) 1.0F) * (double) l1, + (Math.min((double) ((l >> 18) & 32767L), (double) 32766.0F) * (double) 2.0F / (double) 32766.0F - (double) 1.0F) * (double) l1, + (Math.min((double) ((l >> 33) & 32767L), (double) 32766.0F) * (double) 2.0F / (double) 32766.0F - (double) 1.0F) * (double) l1 + ); + } + } + + public void writeLpVec3(Vec3d vec3) { + double d = Double.isNaN(vec3.x) ? (double) 0.0F : Math.clamp(vec3.x, -1.7179869183E10, 1.7179869183E10); + double d1 = Double.isNaN(vec3.y) ? (double) 0.0F : Math.clamp(vec3.y, -1.7179869183E10, 1.7179869183E10); + double d2 = Double.isNaN(vec3.z) ? (double) 0.0F : Math.clamp(vec3.z, -1.7179869183E10, 1.7179869183E10); + double max = MCUtils.absMax(d, MCUtils.absMax(d1, d2)); + if (max < 3.051944088384301E-5) { + this.writeByte(0); + } else { + long l = MCUtils.ceilLong(max); + boolean flag = (l & 3L) != l; + long l1 = flag ? l & 3L | 4L : l; + long l2 = (Math.round(((d / (double) l) * (double) 0.5F + (double) 0.5F) * (double) 32766.0F)) << 3; + long l3 = (Math.round(((d1 / (double) l) * (double) 0.5F + (double) 0.5F) * (double) 32766.0F)) << 18; + long l4 = (Math.round(((d2 / (double) l) * (double) 0.5F + (double) 0.5F) * (double) 32766.0F)) << 33; + long l5 = l1 | l2 | l3 | l4; + this.writeByte((byte) ((int) l5)); + this.writeByte((byte) ((int) (l5 >> 8))); + this.writeInt((int) (l5 >> 16)); + if (flag) { + this.writeVarInt((int) (l >> 2)); + } + } + } + @FunctionalInterface public interface Writer extends BiConsumer { diff --git a/core/src/main/java/net/momirealms/craftengine/core/util/MCUtils.java b/core/src/main/java/net/momirealms/craftengine/core/util/MCUtils.java index 38cf3acdd..c78fc05d1 100644 --- a/core/src/main/java/net/momirealms/craftengine/core/util/MCUtils.java +++ b/core/src/main/java/net/momirealms/craftengine/core/util/MCUtils.java @@ -282,4 +282,13 @@ public class MCUtils { public static double clamp(double value, double min, double max) { return value < min ? min : Math.min(value, max); } + + public static double absMax(double x, double y) { + return Math.max(Math.abs(x), Math.abs(y)); + } + + public static long ceilLong(double value) { + long l = (long)value; + return value > (double)l ? l + 1L : l; + } } diff --git a/core/src/main/java/net/momirealms/craftengine/core/util/MinecraftVersion.java b/core/src/main/java/net/momirealms/craftengine/core/util/MinecraftVersion.java index 2e20c0a66..80fc10b38 100644 --- a/core/src/main/java/net/momirealms/craftengine/core/util/MinecraftVersion.java +++ b/core/src/main/java/net/momirealms/craftengine/core/util/MinecraftVersion.java @@ -22,6 +22,7 @@ public final class MinecraftVersion implements Comparable { PACK_FORMATS.put(1_21_06, 63); PACK_FORMATS.put(1_21_07, 64); PACK_FORMATS.put(1_21_08, 64); + PACK_FORMATS.put(1_21_09, 69); PACK_FORMATS.put(1_99_99, 1000); } diff --git a/core/src/main/java/net/momirealms/craftengine/core/util/MinecraftVersions.java b/core/src/main/java/net/momirealms/craftengine/core/util/MinecraftVersions.java index 2f28c73ad..b9c6980cc 100644 --- a/core/src/main/java/net/momirealms/craftengine/core/util/MinecraftVersions.java +++ b/core/src/main/java/net/momirealms/craftengine/core/util/MinecraftVersions.java @@ -19,5 +19,6 @@ public final class MinecraftVersions { public static final MinecraftVersion V1_21_6 = new MinecraftVersion("1.21.6"); public static final MinecraftVersion V1_21_7 = new MinecraftVersion("1.21.7"); public static final MinecraftVersion V1_21_8 = new MinecraftVersion("1.21.8"); + public static final MinecraftVersion V1_21_9 = new MinecraftVersion("1.21.9"); public static final MinecraftVersion FUTURE = new MinecraftVersion("1.99.99"); } diff --git a/core/src/main/java/net/momirealms/craftengine/core/util/VersionHelper.java b/core/src/main/java/net/momirealms/craftengine/core/util/VersionHelper.java index 6b36f6bc3..2112ecd15 100644 --- a/core/src/main/java/net/momirealms/craftengine/core/util/VersionHelper.java +++ b/core/src/main/java/net/momirealms/craftengine/core/util/VersionHelper.java @@ -33,6 +33,7 @@ public class VersionHelper { private static final boolean v1_21_6; private static final boolean v1_21_7; private static final boolean v1_21_8; + private static final boolean v1_21_9; static { try (InputStream inputStream = Class.forName("net.minecraft.obfuscate.DontObfuscate").getResourceAsStream("/version.json")) { @@ -68,6 +69,7 @@ public class VersionHelper { v1_21_6 = version >= 12106; v1_21_7 = version >= 12107; v1_21_8 = version >= 12108; + v1_21_9 = version >= 12109; majorVersion = major; minorVersion = minor; @@ -239,4 +241,8 @@ public class VersionHelper { public static boolean isOrAbove1_21_8() { return v1_21_8; } + + public static boolean isOrAbove1_21_9() { + return v1_21_9; + } } \ No newline at end of file diff --git a/core/src/main/java/net/momirealms/craftengine/core/world/Vec3d.java b/core/src/main/java/net/momirealms/craftengine/core/world/Vec3d.java index aeb8b3df5..83ac823ba 100644 --- a/core/src/main/java/net/momirealms/craftengine/core/world/Vec3d.java +++ b/core/src/main/java/net/momirealms/craftengine/core/world/Vec3d.java @@ -3,6 +3,7 @@ package net.momirealms.craftengine.core.world; import net.momirealms.craftengine.core.util.MCUtils; public class Vec3d implements Position { + public static final Vec3d ZERO = new Vec3d(0, 0, 0); public final double x; public final double y; public final double z; diff --git a/gradle.properties b/gradle.properties index 1b25eea7b..6d228cad0 100644 --- a/gradle.properties +++ b/gradle.properties @@ -50,13 +50,13 @@ byte_buddy_version=1.17.5 ahocorasick_version=0.6.3 snake_yaml_version=2.5 anti_grief_version=0.20 -nms_helper_version=1.0.92 +nms_helper_version=1.0.93 evalex_version=3.5.0 reactive_streams_version=1.0.4 amazon_awssdk_version=2.33.1 amazon_awssdk_eventstream_version=1.0.1 jimfs_version=1.3.0 -authlib_version=6.0.58 +authlib_version=7.0.60 concurrent_util_version=0.0.3 # Proxy settings