diff --git a/README.md b/README.md index 9888e2c5b..f0b0d8a09 100644 --- a/README.md +++ b/README.md @@ -91,7 +91,7 @@ Given the extensive and intricate nature of plugin configurations, a modular tem The plugin enables model inheritance and texture overrides through configuration, while supporting [all item models](https://misode.github.io/assets/item/) from version 1.21.4 onward. It incorporates a version migration system that automatically downgrades 1.21.4+ item models to legacy formats with maximum backward compatibility. ### Breaking Changes You Have to Know & Possible Incompatibility with Other Plugins -- CraftEngine injects into PalettedContainer to ensure efficient storage and synchronization of plugin block data. This may cause conflicts with some other plugins that modify the palette. When analyzing server performance using Spark, palette operation overhead will be attributed to the CraftEngine plugin in the profiling results.. +- CraftEngine injects into PalettedContainer to ensure efficient storage and synchronization of plugin block data. This may cause conflicts with some other plugins that modify the palette. When analyzing server performance using Spark, palette operation overhead will be attributed to the CraftEngine plugin in the profiling results. - CraftEngine injects into FurnaceBlockEntity to modify its recipe fetching logic. - CraftEngine uses real server-side blocks, any plugin relying on Bukkit's Material class will fail to correctly identify custom block types. The proper approach is to use alternatives like BlockState#getBlock (mojmap) instead of the Material class. - CraftEngine implements 0-tick collision entities by extending certain Minecraft entities, ensuring hard collision works correctly on the server side (e.g., making a pig stand on a chair). However, some anti-cheat plugins do not check entity AABB (Axis-Aligned Bounding Box) properly when detecting player movement, which may lead to false flags. diff --git a/bukkit/build.gradle.kts b/bukkit/build.gradle.kts index aba60a7a3..92915efaf 100644 --- a/bukkit/build.gradle.kts +++ b/bukkit/build.gradle.kts @@ -13,7 +13,6 @@ repositories { dependencies { compileOnly(project(":core")) compileOnly(project(":shared")) - compileOnly(project(":bukkit:compatibility")) compileOnly(project(":bukkit:legacy")) // Anti Grief compileOnly("net.momirealms:antigrieflib:${rootProject.properties["anti_grief_version"]}") diff --git a/bukkit/compatibility/build.gradle.kts b/bukkit/compatibility/build.gradle.kts index 0165818bd..b0cd5fa25 100644 --- a/bukkit/compatibility/build.gradle.kts +++ b/bukkit/compatibility/build.gradle.kts @@ -9,11 +9,17 @@ repositories { maven("https://repo.momirealms.net/releases/") maven("https://mvn.lumine.io/repository/maven-public/") // model engine maven("https://nexus.phoenixdevt.fr/repository/maven-public/") // mmoitems + maven("https://repo.viaversion.com") // via + maven("https://repo.skriptlang.org/releases/") // skript } dependencies { compileOnly(project(":core")) + compileOnly(project(":bukkit")) + compileOnly(project(":bukkit:compatibility:legacy")) compileOnly("net.momirealms:sparrow-nbt:${rootProject.properties["sparrow_nbt_version"]}") + // NMS + compileOnly("net.momirealms:craft-engine-nms-helper:${rootProject.properties["nms_helper_version"]}") // Platform compileOnly("io.papermc.paper:paper-api:${rootProject.properties["paper_version"]}-R0.1-SNAPSHOT") // NeigeItems @@ -34,6 +40,10 @@ dependencies { compileOnly("io.lumine:MythicLib-dist:1.6.2-SNAPSHOT") // LuckPerms compileOnly("net.luckperms:api:5.4") + // viaversion + compileOnly("com.viaversion:viaversion-api:5.3.2") + // Skript + compileOnly("com.github.SkriptLang:Skript:2.11.0") } java { diff --git a/bukkit/compatibility/legacy/build.gradle.kts b/bukkit/compatibility/legacy/build.gradle.kts new file mode 100644 index 000000000..6178b659e --- /dev/null +++ b/bukkit/compatibility/legacy/build.gradle.kts @@ -0,0 +1,31 @@ +repositories { + mavenCentral() + maven("https://repo.papermc.io/repository/maven-public/") + maven("https://repo.rapture.pw/repository/maven-releases/") + maven("https://repo.momirealms.net/releases/") + maven("https://repo.infernalsuite.com/repository/maven-snapshots/") +} + +dependencies { + compileOnly(project(":core")) + // NBT + compileOnly("net.momirealms:sparrow-nbt:${rootProject.properties["sparrow_nbt_version"]}") + // Platform + compileOnly("io.papermc.paper:paper-api:${rootProject.properties["paper_version"]}-R0.1-SNAPSHOT") + compileOnly("com.infernalsuite.aswm:api:1.20.4-R0.1-SNAPSHOT") +} + +java { + sourceCompatibility = JavaVersion.VERSION_21 + targetCompatibility = JavaVersion.VERSION_21 + toolchain { + languageVersion = JavaLanguageVersion.of(21) + } + withSourcesJar() +} + +tasks.withType { + options.encoding = "UTF-8" + options.release.set(21) + dependsOn(tasks.clean) +} \ No newline at end of file diff --git a/bukkit/compatibility/legacy/src/main/java/net/momirealms/craftengine/bukkit/compatibility/legacy/slimeworld/LegacySlimeFormatStorageAdaptor.java b/bukkit/compatibility/legacy/src/main/java/net/momirealms/craftengine/bukkit/compatibility/legacy/slimeworld/LegacySlimeFormatStorageAdaptor.java new file mode 100644 index 000000000..872e50bf8 --- /dev/null +++ b/bukkit/compatibility/legacy/src/main/java/net/momirealms/craftengine/bukkit/compatibility/legacy/slimeworld/LegacySlimeFormatStorageAdaptor.java @@ -0,0 +1,74 @@ +package net.momirealms.craftengine.bukkit.compatibility.legacy.slimeworld; + +import com.infernalsuite.aswm.api.events.LoadSlimeWorldEvent; +import com.infernalsuite.aswm.api.world.SlimeWorld; +import net.momirealms.craftengine.core.world.World; +import net.momirealms.craftengine.core.world.WorldManager; +import net.momirealms.craftengine.core.world.chunk.storage.DefaultStorageAdaptor; +import net.momirealms.craftengine.core.world.chunk.storage.WorldDataStorage; +import org.bukkit.Bukkit; +import org.bukkit.event.EventHandler; +import org.bukkit.event.Listener; +import org.bukkit.plugin.Plugin; +import org.jetbrains.annotations.NotNull; + +import java.lang.reflect.Method; +import java.util.function.Function; + +public class LegacySlimeFormatStorageAdaptor extends DefaultStorageAdaptor implements Listener { + private final WorldManager worldManager; + private final Function SLIME_WORLD_GETTER; + + @EventHandler + public void onWorldLoad(LoadSlimeWorldEvent event) { + org.bukkit.World world = Bukkit.getWorld(event.getSlimeWorld().getName()); + this.worldManager.loadWorld(this.worldManager.createWorld(this.worldManager.wrap(world), new LegacySlimeWorldDataStorage(event.getSlimeWorld()))); + } + + public LegacySlimeFormatStorageAdaptor(WorldManager worldManager, int version) { + this.worldManager = worldManager; + try { + if (version == 1) { + Plugin plugin = Bukkit.getPluginManager().getPlugin("SlimeWorldManager"); + Class slimeClass = Class.forName("com.infernalsuite.aswm.api.SlimePlugin"); + Method method = slimeClass.getMethod("getWorld", String.class); + this.SLIME_WORLD_GETTER = (name) -> { + try { + return (SlimeWorld) method.invoke(plugin, name); + } catch (ReflectiveOperationException e) { + throw new RuntimeException(e); + } + }; + } else if (version == 2) { + Class apiClass = Class.forName("com.infernalsuite.aswm.api.AdvancedSlimePaperAPI"); + Object apiInstance = apiClass.getMethod("instance").invoke(null); + Method method = apiClass.getMethod("getLoadedWorld", String.class); + this.SLIME_WORLD_GETTER = (name) -> { + try { + return (SlimeWorld) method.invoke(apiInstance, name); + } catch (ReflectiveOperationException e) { + throw new RuntimeException(e); + } + }; + } else { + throw new IllegalArgumentException("Unsupported version: " + version); + } + } catch (ReflectiveOperationException e) { + throw new RuntimeException(e); + } + } + + public SlimeWorld getWorld(String name) { + return this.SLIME_WORLD_GETTER.apply(name); + } + + // 请注意,在加载事件的时候,无法通过AdvancedSlimePaperAPI.instance().getLoadedWorld来判断是否为slime世界 + @Override + public @NotNull WorldDataStorage adapt(@NotNull World world) { + SlimeWorld slimeWorld = getWorld(world.name()); + if (slimeWorld == null) { + return super.adapt(world); + } + return new LegacySlimeWorldDataStorage(slimeWorld); + } +} diff --git a/bukkit/compatibility/legacy/src/main/java/net/momirealms/craftengine/bukkit/compatibility/legacy/slimeworld/LegacySlimeWorldDataStorage.java b/bukkit/compatibility/legacy/src/main/java/net/momirealms/craftengine/bukkit/compatibility/legacy/slimeworld/LegacySlimeWorldDataStorage.java new file mode 100644 index 000000000..b4550330f --- /dev/null +++ b/bukkit/compatibility/legacy/src/main/java/net/momirealms/craftengine/bukkit/compatibility/legacy/slimeworld/LegacySlimeWorldDataStorage.java @@ -0,0 +1,80 @@ +package net.momirealms.craftengine.bukkit.compatibility.legacy.slimeworld; + +import com.flowpowered.nbt.ByteArrayTag; +import com.flowpowered.nbt.CompoundMap; +import com.infernalsuite.aswm.api.world.SlimeChunk; +import com.infernalsuite.aswm.api.world.SlimeWorld; +import net.momirealms.craftengine.core.world.CEWorld; +import net.momirealms.craftengine.core.world.ChunkPos; +import net.momirealms.craftengine.core.world.chunk.CEChunk; +import net.momirealms.craftengine.core.world.chunk.serialization.DefaultChunkSerializer; +import net.momirealms.craftengine.core.world.chunk.storage.WorldDataStorage; +import net.momirealms.sparrow.nbt.CompoundTag; +import net.momirealms.sparrow.nbt.NBT; +import org.jetbrains.annotations.NotNull; + +import java.lang.ref.WeakReference; +import java.util.Optional; + +public class LegacySlimeWorldDataStorage implements WorldDataStorage { + private final WeakReference slimeWorld; + + public LegacySlimeWorldDataStorage(SlimeWorld slimeWorld) { + this.slimeWorld = new WeakReference<>(slimeWorld); + } + + public SlimeWorld getWorld() { + return slimeWorld.get(); + } + + @Override + public @NotNull CEChunk readChunkAt(@NotNull CEWorld world, @NotNull ChunkPos pos) { + SlimeChunk slimeChunk = getWorld().getChunk(pos.x, pos.z); + if (slimeChunk == null) return new CEChunk(world, pos); + Optional tag = slimeChunk.getExtraData().getAsByteArrayTag("craftengine"); + if (tag.isEmpty()) return new CEChunk(world, pos); + try { + CompoundTag compoundTag = NBT.fromBytes(tag.get().getValue()); + if (compoundTag == null) return new CEChunk(world, pos); + return DefaultChunkSerializer.deserialize(world, pos, compoundTag); + } catch (Exception e) { + throw new RuntimeException("Failed to read chunk tag from slime world. " + pos, e); + } + } + + private CompoundMap createOrGetDataMap(SlimeWorld world) { + Optional optionalCompoundTag = world.getExtraData().getAsCompoundTag("craftengine"); + CompoundMap ccDataMap; + if (optionalCompoundTag.isEmpty()) { + ccDataMap = new CompoundMap(); + world.getExtraData().getValue().put(new com.flowpowered.nbt.CompoundTag("customcrops", ccDataMap)); + } else { + ccDataMap = optionalCompoundTag.get().getValue(); + } + return ccDataMap; + } + + @Override + public void writeChunkAt(@NotNull ChunkPos pos, @NotNull CEChunk chunk, boolean immediately) { + SlimeChunk slimeChunk = getWorld().getChunk(pos.x, pos.z); + if (slimeChunk == null) return; + CompoundTag nbt = DefaultChunkSerializer.serialize(chunk); + if (nbt == null) { + slimeChunk.getExtraData().getValue().remove("craftengine"); + } else { + try { + slimeChunk.getExtraData().getValue().put("craftengine", new ByteArrayTag("craftengine", NBT.toBytes(nbt))); + } catch (Exception e) { + throw new RuntimeException("Failed to write chunk tag to slime world. " + pos, e); + } + } + } + + @Override + public void flush() { + } + + @Override + public void close() { + } +} diff --git a/bukkit/compatibility/src/main/java/net/momirealms/craftengine/bukkit/compatibility/BukkitCompatibilityManager.java b/bukkit/compatibility/src/main/java/net/momirealms/craftengine/bukkit/compatibility/BukkitCompatibilityManager.java new file mode 100644 index 000000000..4de975ecd --- /dev/null +++ b/bukkit/compatibility/src/main/java/net/momirealms/craftengine/bukkit/compatibility/BukkitCompatibilityManager.java @@ -0,0 +1,199 @@ +package net.momirealms.craftengine.bukkit.compatibility; + +import net.momirealms.craftengine.bukkit.block.BukkitBlockManager; +import net.momirealms.craftengine.bukkit.compatibility.bettermodel.BetterModelModel; +import net.momirealms.craftengine.bukkit.compatibility.item.MMOItemsProvider; +import net.momirealms.craftengine.bukkit.compatibility.item.NeigeItemsProvider; +import net.momirealms.craftengine.bukkit.compatibility.legacy.slimeworld.LegacySlimeFormatStorageAdaptor; +import net.momirealms.craftengine.bukkit.compatibility.modelengine.ModelEngineModel; +import net.momirealms.craftengine.bukkit.compatibility.modelengine.ModelEngineUtils; +import net.momirealms.craftengine.bukkit.compatibility.papi.PlaceholderAPIUtils; +import net.momirealms.craftengine.bukkit.compatibility.permission.LuckPermsEventListeners; +import net.momirealms.craftengine.bukkit.compatibility.skript.SkriptHook; +import net.momirealms.craftengine.bukkit.compatibility.slimeworld.SlimeFormatStorageAdaptor; +import net.momirealms.craftengine.bukkit.compatibility.viaversion.ViaVersionUtils; +import net.momirealms.craftengine.bukkit.compatibility.worldedit.WorldEditBlockRegister; +import net.momirealms.craftengine.bukkit.font.BukkitFontManager; +import net.momirealms.craftengine.bukkit.item.BukkitItemManager; +import net.momirealms.craftengine.bukkit.plugin.BukkitCraftEngine; +import net.momirealms.craftengine.core.entity.furniture.AbstractExternalModel; +import net.momirealms.craftengine.core.entity.player.Player; +import net.momirealms.craftengine.core.plugin.CompatibilityManager; +import net.momirealms.craftengine.core.util.Key; +import net.momirealms.craftengine.core.util.VersionHelper; +import net.momirealms.craftengine.core.world.WorldManager; +import org.bukkit.Bukkit; +import org.bukkit.plugin.Plugin; + +import java.util.UUID; + +public class BukkitCompatibilityManager implements CompatibilityManager { + private final BukkitCraftEngine plugin; + private boolean hasPlaceholderAPI; + private boolean hasViaVersion; + + public BukkitCompatibilityManager(BukkitCraftEngine plugin) { + this.plugin = plugin; + } + + @Override + public void onLoad() { + } + + @Override + public void onEnable() { + this.initSlimeWorldHook(); + if (this.isPluginEnabled("PlaceholderAPI")) { + PlaceholderAPIUtils.registerExpansions(this.plugin); + this.hasPlaceholderAPI = true; + logHook("PlaceholderAPI"); + } + // skript + if (this.isPluginEnabled("Skript")) { + SkriptHook.register(); + logHook("Skript"); + Plugin skriptPlugin = getPlugin("Skript"); + // This can cause bugs, needs to find a better way +// for (BukkitTask task : Bukkit.getScheduler().getPendingTasks()) { +// if (task.getOwner() == skriptPlugin) { +// task.cancel(); +// if (VersionHelper.isFolia()) { +// Bukkit.getGlobalRegionScheduler().run(skriptPlugin, (t) -> { +// FastNMS.INSTANCE.getBukkitTaskRunnable(task).run(); +// }); +// } else { +// Bukkit.getScheduler().runTask(skriptPlugin, FastNMS.INSTANCE.getBukkitTaskRunnable(task)); +// } +// } +// } + } + } + + @Override + public void onDelayedEnable() { + this.initItemHooks(); + // WorldEdit + if (this.isPluginEnabled("FastAsyncWorldEdit")) { + this.initFastAsyncWorldEditHook(); + logHook("FastAsyncWorldEdit"); + } else if (this.isPluginEnabled("WorldEdit")) { + this.initWorldEditHook(); + logHook("WorldEdit"); + } + if (this.isPluginEnabled("LuckPerms")) { + this.initLuckPermsHook(); + logHook("LuckPerms"); + } + } + + private void logHook(String plugin) { + this.plugin.logger().info("[Compatibility] " + plugin + " hooked"); + } + + @Override + public AbstractExternalModel createModelEngineModel(String id) { + return new ModelEngineModel(id); + } + + @Override + public AbstractExternalModel createBetterModelModel(String id) { + return new BetterModelModel(id); + } + + @Override + public int interactionToBaseEntity(int id) { + return ModelEngineUtils.interactionToBaseEntity(id); + } + + private void initLuckPermsHook() { + new LuckPermsEventListeners(plugin.bootstrap(), (uuid) -> { + BukkitFontManager fontManager = (BukkitFontManager) plugin.fontManager(); + fontManager.refreshEmojiSuggestions(uuid); + }); + } + + private void initSlimeWorldHook() { + WorldManager worldManager = this.plugin.worldManager(); + if (VersionHelper.isOrAbove1_21_4()) { + try { + Class.forName("com.infernalsuite.asp.api.AdvancedSlimePaperAPI"); + SlimeFormatStorageAdaptor adaptor = new SlimeFormatStorageAdaptor(worldManager); + worldManager.setStorageAdaptor(adaptor); + Bukkit.getPluginManager().registerEvents(adaptor, plugin.bootstrap()); + logHook("AdvancedSlimePaper"); + } catch (ClassNotFoundException ignored) { + } + } else { + try { + Class.forName("com.infernalsuite.aswm.api.SlimePlugin"); + LegacySlimeFormatStorageAdaptor adaptor = new LegacySlimeFormatStorageAdaptor(worldManager, 1); + worldManager.setStorageAdaptor(adaptor); + Bukkit.getPluginManager().registerEvents(adaptor, plugin.bootstrap()); + logHook("AdvancedSlimePaper"); + } catch (ClassNotFoundException ignored) { + if (Bukkit.getPluginManager().isPluginEnabled("SlimeWorldPlugin")) { + LegacySlimeFormatStorageAdaptor adaptor = new LegacySlimeFormatStorageAdaptor(worldManager, 2); + worldManager.setStorageAdaptor(adaptor); + Bukkit.getPluginManager().registerEvents(adaptor, plugin.bootstrap()); + logHook("AdvancedSlimePaper"); + } + } + } + } + + private void initFastAsyncWorldEditHook() { + new WorldEditBlockRegister(BukkitBlockManager.instance(), true); + } + + private void initWorldEditHook() { + WorldEditBlockRegister weBlockRegister = new WorldEditBlockRegister(BukkitBlockManager.instance(), false); + try { + for (Key newBlockId : BukkitBlockManager.instance().blockRegisterOrder()) { + weBlockRegister.register(newBlockId); + } + } catch (Exception e) { + this.plugin.logger().warn("Failed to initialize world edit hook", e); + } + } + + private void initItemHooks() { + BukkitItemManager itemManager = BukkitItemManager.instance(); + if (this.isPluginEnabled("NeigeItems")) { + itemManager.registerExternalItemProvider(new NeigeItemsProvider()); + logHook("NeigeItems"); + } + if (this.isPluginEnabled("MMOItems")) { + itemManager.registerExternalItemProvider(new MMOItemsProvider()); + logHook("MMOItems"); + } + } + + private Plugin getPlugin(String name) { + return Bukkit.getPluginManager().getPlugin(name); + } + + @Override + public boolean hasPlaceholderAPI() { + return this.hasPlaceholderAPI; + } + + @Override + public boolean isPluginEnabled(String plugin) { + return Bukkit.getPluginManager().isPluginEnabled(plugin); + } + + @Override + public boolean hasPlugin(String plugin) { + return Bukkit.getPluginManager().getPlugin(plugin) != null; + } + + @Override + public String parse(Player player, String text) { + return PlaceholderAPIUtils.parse((org.bukkit.entity.Player) player.platformPlayer(), text); + } + + @Override + public int getPlayerProtocolVersion(UUID uuid) { + return ViaVersionUtils.getPlayerProtocolVersion(uuid); + } +} diff --git a/bukkit/compatibility/src/main/java/net/momirealms/craftengine/bukkit/compatibility/permission/LuckPermsEventListeners.java b/bukkit/compatibility/src/main/java/net/momirealms/craftengine/bukkit/compatibility/permission/LuckPermsEventListeners.java index ecfbb6983..aa47edb92 100644 --- a/bukkit/compatibility/src/main/java/net/momirealms/craftengine/bukkit/compatibility/permission/LuckPermsEventListeners.java +++ b/bukkit/compatibility/src/main/java/net/momirealms/craftengine/bukkit/compatibility/permission/LuckPermsEventListeners.java @@ -16,7 +16,6 @@ import java.util.List; import java.util.UUID; import java.util.concurrent.TimeUnit; import java.util.function.Consumer; -import java.util.logging.Level; public class LuckPermsEventListeners { private final JavaPlugin plugin; @@ -42,16 +41,16 @@ public class LuckPermsEventListeners { this.subscriptions.add(eventBus.subscribe(this.plugin, GroupDataRecalculateEvent.class, this::onGroupPermissionChange)); } - public void unregisterListeners() { - this.subscriptions.forEach(subscription -> { - try { - subscription.close(); - } catch (Exception e) { - this.plugin.getLogger().log(Level.WARNING, "Failed to close event subscription", e); - } - }); - this.subscriptions.clear(); - } +// public void unregisterListeners() { +// this.subscriptions.forEach(subscription -> { +// try { +// subscription.close(); +// } catch (Exception e) { +// this.plugin.getLogger().log(Level.WARNING, "Failed to close event subscription", e); +// } +// }); +// this.subscriptions.clear(); +// } private void onUserPermissionChange(UserDataRecalculateEvent event) { CraftEngine.instance().scheduler().async().execute(() -> { diff --git a/bukkit/compatibility/src/main/java/net/momirealms/craftengine/bukkit/compatibility/skript/SkriptHook.java b/bukkit/compatibility/src/main/java/net/momirealms/craftengine/bukkit/compatibility/skript/SkriptHook.java new file mode 100644 index 000000000..3e010e30c --- /dev/null +++ b/bukkit/compatibility/src/main/java/net/momirealms/craftengine/bukkit/compatibility/skript/SkriptHook.java @@ -0,0 +1,34 @@ +package net.momirealms.craftengine.bukkit.compatibility.skript; + +import net.momirealms.craftengine.bukkit.compatibility.skript.clazz.CraftEngineClasses; +import net.momirealms.craftengine.bukkit.compatibility.skript.condition.CondIsCustomBlock; +import net.momirealms.craftengine.bukkit.compatibility.skript.condition.CondIsCustomItem; +import net.momirealms.craftengine.bukkit.compatibility.skript.condition.CondIsFurniture; +import net.momirealms.craftengine.bukkit.compatibility.skript.effect.EffPlaceCustomBlock; +import net.momirealms.craftengine.bukkit.compatibility.skript.effect.EffPlaceFurniture; +import net.momirealms.craftengine.bukkit.compatibility.skript.effect.EffRemoveFurniture; +import net.momirealms.craftengine.bukkit.compatibility.skript.event.EvtCustomBlock; +import net.momirealms.craftengine.bukkit.compatibility.skript.event.EvtCustomClick; +import net.momirealms.craftengine.bukkit.compatibility.skript.event.EvtCustomFurniture; +import net.momirealms.craftengine.bukkit.compatibility.skript.expression.*; + +public class SkriptHook { + + public static void register() { + CraftEngineClasses.register(); + EvtCustomBlock.register(); + EvtCustomFurniture.register(); + EvtCustomClick.register(); + CondIsCustomBlock.register(); + CondIsFurniture.register(); + CondIsCustomItem.register(); + ExprBlockCustomBlockID.register(); + ExprItemCustomItemID.register(); + ExprBlockCustomBlockState.register(); + ExprCustomItem.register(); + ExprEntityFurnitureID.register(); + EffPlaceCustomBlock.register(); + EffPlaceFurniture.register(); + EffRemoveFurniture.register(); + } +} diff --git a/bukkit/compatibility/src/main/java/net/momirealms/craftengine/bukkit/compatibility/skript/clazz/CraftEngineClasses.java b/bukkit/compatibility/src/main/java/net/momirealms/craftengine/bukkit/compatibility/skript/clazz/CraftEngineClasses.java new file mode 100644 index 000000000..97579439a --- /dev/null +++ b/bukkit/compatibility/src/main/java/net/momirealms/craftengine/bukkit/compatibility/skript/clazz/CraftEngineClasses.java @@ -0,0 +1,127 @@ +package net.momirealms.craftengine.bukkit.compatibility.skript.clazz; + +import ch.njol.skript.classes.ClassInfo; +import ch.njol.skript.classes.Parser; +import ch.njol.skript.classes.Serializer; +import ch.njol.skript.lang.ParseContext; +import ch.njol.skript.registrations.Classes; +import ch.njol.yggdrasil.Fields; +import net.momirealms.craftengine.core.block.BlockStateParser; +import net.momirealms.craftengine.core.block.ImmutableBlockState; +import net.momirealms.craftengine.core.block.UnsafeBlockStateMatcher; +import org.jetbrains.annotations.Nullable; + +import java.io.StreamCorruptedException; + +public class CraftEngineClasses { + + public static void register() { + Classes.registerClass(new ClassInfo<>(ImmutableBlockState.class, "customblockstate") + .user("custom block state") + .name("Custom Block State") + .serializer(new Serializer<>() { + @Override + public Fields serialize(ImmutableBlockState o) { + Fields f = new Fields(); + f.putObject("customblockstate", o.toString()); + return f; + } + + @Override + public void deserialize(ImmutableBlockState o, Fields f) { + } + + @Override + public ImmutableBlockState deserialize(Fields f) throws StreamCorruptedException { + String data = f.getObject("customblockstate", String.class); + assert data != null; + try { + return BlockStateParser.deserialize(data); + } catch (IllegalArgumentException ex) { + throw new StreamCorruptedException("Invalid block data: " + data); + } + } + + @Override + public boolean mustSyncDeserialization() { + return true; + } + + @Override + protected boolean canBeInstantiated() { + return false; + } + }) + .parser(new Parser<>() { + @Override + public String toString(ImmutableBlockState o, int flags) { + return o.toString(); + } + + @Override + public String toVariableNameString(ImmutableBlockState o) { + return "customblockstate:" + o.toString(); + } + + @Override + public @Nullable ImmutableBlockState parse(String s, ParseContext context) { + return BlockStateParser.deserialize(s); + } + }) + ); + + Classes.registerClass(new ClassInfo<>(UnsafeBlockStateMatcher.class, "unsafeblockstatematcher") + .user("unsafe block state matcher") + .name("Unsafe Block State Matcher") + .serializer(new Serializer<>() { + @Override + public Fields serialize(UnsafeBlockStateMatcher o) { + Fields f = new Fields(); + f.putObject("unsafeblockstatematcher", o.toString()); + return f; + } + + @Override + public void deserialize(UnsafeBlockStateMatcher o, Fields f) { + } + + @Override + public UnsafeBlockStateMatcher deserialize(Fields f) throws StreamCorruptedException { + String data = f.getObject("unsafeblockstatematcher", String.class); + assert data != null; + try { + return UnsafeBlockStateMatcher.deserialize(data); + } catch (IllegalArgumentException ex) { + throw new StreamCorruptedException("Invalid block matcher: " + data); + } + } + + @Override + public boolean mustSyncDeserialization() { + return true; + } + + @Override + protected boolean canBeInstantiated() { + return false; + } + }) + .parser(new Parser<>() { + @Override + public String toString(UnsafeBlockStateMatcher o, int flags) { + return o.toString(); + } + + @Override + public String toVariableNameString(UnsafeBlockStateMatcher o) { + return "unsafeblockstatematcher:" + o.toString(); + } + + @Override + public @Nullable UnsafeBlockStateMatcher parse(String s, ParseContext context) { + return UnsafeBlockStateMatcher.deserialize(s); + } + }) + ); + } +} diff --git a/bukkit/compatibility/src/main/java/net/momirealms/craftengine/bukkit/compatibility/skript/condition/CondIsCustomBlock.java b/bukkit/compatibility/src/main/java/net/momirealms/craftengine/bukkit/compatibility/skript/condition/CondIsCustomBlock.java new file mode 100644 index 000000000..1f40970fa --- /dev/null +++ b/bukkit/compatibility/src/main/java/net/momirealms/craftengine/bukkit/compatibility/skript/condition/CondIsCustomBlock.java @@ -0,0 +1,41 @@ +package net.momirealms.craftengine.bukkit.compatibility.skript.condition; + +import ch.njol.skript.Skript; +import ch.njol.skript.conditions.base.PropertyCondition; +import ch.njol.skript.lang.Condition; +import ch.njol.skript.lang.Expression; +import ch.njol.skript.lang.SkriptParser; +import ch.njol.util.Kleenean; +import net.momirealms.craftengine.bukkit.api.CraftEngineBlocks; +import org.bukkit.block.Block; +import org.bukkit.event.Event; +import org.jetbrains.annotations.Nullable; + +public class CondIsCustomBlock extends Condition { + + public static void register() { + Skript.registerCondition(CondIsCustomBlock.class, + "%blocks% (is|are) custom block(s)", + "%blocks% (is|are)(n't| not) custom block(s)"); + } + + private Expression blocks; + + @Override + public boolean check(Event event) { + return blocks.check(event, CraftEngineBlocks::isCustomBlock, isNegated()); + } + + @Override + public String toString(@Nullable Event event, boolean debug) { + return PropertyCondition.toString(this, PropertyCondition.PropertyType.BE, event, debug, blocks, "custom block"); + } + + @SuppressWarnings("unchecked") + @Override + public boolean init(Expression[] expressions, int matchedPattern, Kleenean isDelayed, SkriptParser.ParseResult parseResult) { + blocks = (Expression) expressions[0]; + setNegated(matchedPattern > 1); + return true; + } +} diff --git a/bukkit/compatibility/src/main/java/net/momirealms/craftengine/bukkit/compatibility/skript/condition/CondIsCustomItem.java b/bukkit/compatibility/src/main/java/net/momirealms/craftengine/bukkit/compatibility/skript/condition/CondIsCustomItem.java new file mode 100644 index 000000000..b293e710f --- /dev/null +++ b/bukkit/compatibility/src/main/java/net/momirealms/craftengine/bukkit/compatibility/skript/condition/CondIsCustomItem.java @@ -0,0 +1,41 @@ +package net.momirealms.craftengine.bukkit.compatibility.skript.condition; + +import ch.njol.skript.Skript; +import ch.njol.skript.conditions.base.PropertyCondition; +import ch.njol.skript.lang.Condition; +import ch.njol.skript.lang.Expression; +import ch.njol.skript.lang.SkriptParser; +import ch.njol.util.Kleenean; +import net.momirealms.craftengine.bukkit.api.CraftEngineItems; +import org.bukkit.event.Event; +import org.bukkit.inventory.ItemStack; +import org.jetbrains.annotations.Nullable; + +public class CondIsCustomItem extends Condition { + + public static void register() { + Skript.registerCondition(CondIsCustomItem.class, + "%itemstacks% (is|are) custom item(s)", + "%itemstacks% (is|are)(n't| not) custom item(s)"); + } + + private Expression items; + + @Override + public boolean check(Event event) { + return items.check(event, CraftEngineItems::isCustomItem, isNegated()); + } + + @Override + public String toString(@Nullable Event event, boolean debug) { + return PropertyCondition.toString(this, PropertyCondition.PropertyType.BE, event, debug, items, "itemstack"); + } + + @SuppressWarnings("unchecked") + @Override + public boolean init(Expression[] expressions, int matchedPattern, Kleenean isDelayed, SkriptParser.ParseResult parseResult) { + items = (Expression) expressions[0]; + setNegated(matchedPattern > 1); + return true; + } +} diff --git a/bukkit/compatibility/src/main/java/net/momirealms/craftengine/bukkit/compatibility/skript/condition/CondIsFurniture.java b/bukkit/compatibility/src/main/java/net/momirealms/craftengine/bukkit/compatibility/skript/condition/CondIsFurniture.java new file mode 100644 index 000000000..00f3f7ad6 --- /dev/null +++ b/bukkit/compatibility/src/main/java/net/momirealms/craftengine/bukkit/compatibility/skript/condition/CondIsFurniture.java @@ -0,0 +1,41 @@ +package net.momirealms.craftengine.bukkit.compatibility.skript.condition; + +import ch.njol.skript.Skript; +import ch.njol.skript.conditions.base.PropertyCondition; +import ch.njol.skript.lang.Condition; +import ch.njol.skript.lang.Expression; +import ch.njol.skript.lang.SkriptParser; +import ch.njol.util.Kleenean; +import net.momirealms.craftengine.bukkit.api.CraftEngineFurniture; +import org.bukkit.entity.Entity; +import org.bukkit.event.Event; +import org.jetbrains.annotations.Nullable; + +public class CondIsFurniture extends Condition { + + public static void register() { + Skript.registerCondition(CondIsFurniture.class, + "%entities% (is|are) furniture", + "%entities% (is|are)(n't| not) furniture"); + } + + private Expression entities; + + @Override + public boolean check(Event event) { + return entities.check(event, CraftEngineFurniture::isFurniture, isNegated()); + } + + @Override + public String toString(@Nullable Event event, boolean debug) { + return PropertyCondition.toString(this, PropertyCondition.PropertyType.BE, event, debug, entities, "furniture"); + } + + @SuppressWarnings("unchecked") + @Override + public boolean init(Expression[] expressions, int matchedPattern, Kleenean isDelayed, SkriptParser.ParseResult parseResult) { + entities = (Expression) expressions[0]; + setNegated(matchedPattern > 1); + return true; + } +} diff --git a/bukkit/compatibility/src/main/java/net/momirealms/craftengine/bukkit/compatibility/skript/effect/EffPlaceCustomBlock.java b/bukkit/compatibility/src/main/java/net/momirealms/craftengine/bukkit/compatibility/skript/effect/EffPlaceCustomBlock.java new file mode 100644 index 000000000..70f6df975 --- /dev/null +++ b/bukkit/compatibility/src/main/java/net/momirealms/craftengine/bukkit/compatibility/skript/effect/EffPlaceCustomBlock.java @@ -0,0 +1,46 @@ +package net.momirealms.craftengine.bukkit.compatibility.skript.effect; + +import ch.njol.skript.Skript; +import ch.njol.skript.lang.Effect; +import ch.njol.skript.lang.Expression; +import ch.njol.skript.lang.SkriptParser; +import ch.njol.skript.util.Direction; +import ch.njol.util.Kleenean; +import net.momirealms.craftengine.bukkit.api.CraftEngineBlocks; +import net.momirealms.craftengine.core.block.ImmutableBlockState; +import org.bukkit.Location; +import org.bukkit.event.Event; +import org.jetbrains.annotations.Nullable; + +public class EffPlaceCustomBlock extends Effect { + + public static void register() { + Skript.registerEffect(EffPlaceCustomBlock.class, "place custom block %customblockstates% [%directions% %locations%]"); + } + + private Expression blocks; + private Expression locations; + + @Override + protected void execute(Event e) { + ImmutableBlockState[] os = blocks.getArray(e); + for (Location l : locations.getArray(e)) { + for (ImmutableBlockState o : os) { + CraftEngineBlocks.place(l, o, false); + } + } + } + + @Override + public String toString(@Nullable Event event, boolean debug) { + return "place custom block " + blocks.toString(event, debug) + " " + locations.toString(event, debug); + } + + @SuppressWarnings("unchecked") + @Override + public boolean init(Expression[] expressions, int matchedPattern, Kleenean isDelayed, SkriptParser.ParseResult parseResult) { + blocks = (Expression) expressions[0]; + locations = Direction.combine((Expression) expressions[1], (Expression) expressions[2]); + return true; + } +} diff --git a/bukkit/compatibility/src/main/java/net/momirealms/craftengine/bukkit/compatibility/skript/effect/EffPlaceFurniture.java b/bukkit/compatibility/src/main/java/net/momirealms/craftengine/bukkit/compatibility/skript/effect/EffPlaceFurniture.java new file mode 100644 index 000000000..5972298e8 --- /dev/null +++ b/bukkit/compatibility/src/main/java/net/momirealms/craftengine/bukkit/compatibility/skript/effect/EffPlaceFurniture.java @@ -0,0 +1,46 @@ +package net.momirealms.craftengine.bukkit.compatibility.skript.effect; + +import ch.njol.skript.Skript; +import ch.njol.skript.lang.Effect; +import ch.njol.skript.lang.Expression; +import ch.njol.skript.lang.SkriptParser; +import ch.njol.skript.util.Direction; +import ch.njol.util.Kleenean; +import net.momirealms.craftengine.bukkit.api.CraftEngineFurniture; +import net.momirealms.craftengine.core.util.Key; +import org.bukkit.Location; +import org.bukkit.event.Event; +import org.jetbrains.annotations.Nullable; + +public class EffPlaceFurniture extends Effect { + + public static void register() { + Skript.registerEffect(EffPlaceFurniture.class, "place furniture %strings% [%directions% %locations%]"); + } + + private Expression furniture; + private Expression locations; + + @Override + protected void execute(Event e) { + String[] os = furniture.getArray(e); + for (Location l : locations.getArray(e)) { + for (String o : os) { + CraftEngineFurniture.place(l, Key.of(o)); + } + } + } + + @Override + public String toString(@Nullable Event event, boolean debug) { + return "place furniture " + furniture.toString(event, debug) + " " + locations.toString(event, debug); + } + + @SuppressWarnings("unchecked") + @Override + public boolean init(Expression[] expressions, int matchedPattern, Kleenean isDelayed, SkriptParser.ParseResult parseResult) { + furniture = (Expression) expressions[0]; + locations = Direction.combine((Expression) expressions[1], (Expression) expressions[2]); + return true; + } +} diff --git a/bukkit/compatibility/src/main/java/net/momirealms/craftengine/bukkit/compatibility/skript/effect/EffRemoveFurniture.java b/bukkit/compatibility/src/main/java/net/momirealms/craftengine/bukkit/compatibility/skript/effect/EffRemoveFurniture.java new file mode 100644 index 000000000..750dd937c --- /dev/null +++ b/bukkit/compatibility/src/main/java/net/momirealms/craftengine/bukkit/compatibility/skript/effect/EffRemoveFurniture.java @@ -0,0 +1,45 @@ +package net.momirealms.craftengine.bukkit.compatibility.skript.effect; + +import ch.njol.skript.Skript; +import ch.njol.skript.lang.Effect; +import ch.njol.skript.lang.Expression; +import ch.njol.skript.lang.SkriptParser; +import ch.njol.util.Kleenean; +import net.momirealms.craftengine.bukkit.api.CraftEngineFurniture; +import net.momirealms.craftengine.bukkit.entity.furniture.LoadedFurniture; +import org.bukkit.entity.Entity; +import org.bukkit.event.Event; +import org.jetbrains.annotations.Nullable; + +public class EffRemoveFurniture extends Effect { + + public static void register() { + Skript.registerEffect(EffRemoveFurniture.class, "remove furniture %entities%"); + } + + private Expression entities; + + @Override + protected void execute(Event e) { + for (Entity entity : entities.getArray(e)) { + if (CraftEngineFurniture.isFurniture(entity)) { + LoadedFurniture loadedFurniture = CraftEngineFurniture.getLoadedFurnitureByBaseEntity(entity); + if (loadedFurniture != null) { + loadedFurniture.destroy(); + } + } + } + } + + @Override + public String toString(@Nullable Event event, boolean debug) { + return "remove furniture " + entities.toString(event, debug); + } + + @SuppressWarnings("unchecked") + @Override + public boolean init(Expression[] expressions, int matchedPattern, Kleenean isDelayed, SkriptParser.ParseResult parseResult) { + this.entities = (Expression) expressions[0]; + return true; + } +} diff --git a/bukkit/compatibility/src/main/java/net/momirealms/craftengine/bukkit/compatibility/skript/event/EvtCustomBlock.java b/bukkit/compatibility/src/main/java/net/momirealms/craftengine/bukkit/compatibility/skript/event/EvtCustomBlock.java new file mode 100644 index 000000000..e5510c23d --- /dev/null +++ b/bukkit/compatibility/src/main/java/net/momirealms/craftengine/bukkit/compatibility/skript/event/EvtCustomBlock.java @@ -0,0 +1,69 @@ +package net.momirealms.craftengine.bukkit.compatibility.skript.event; + +import ch.njol.skript.Skript; +import ch.njol.skript.lang.Literal; +import ch.njol.skript.lang.SkriptEvent; +import ch.njol.skript.lang.SkriptParser; +import net.momirealms.craftengine.bukkit.api.event.CustomBlockBreakEvent; +import net.momirealms.craftengine.bukkit.api.event.CustomBlockPlaceEvent; +import net.momirealms.craftengine.bukkit.util.BlockStateUtils; +import net.momirealms.craftengine.core.block.ImmutableBlockState; +import net.momirealms.craftengine.core.block.UnsafeBlockStateMatcher; +import net.momirealms.craftengine.core.entity.player.InteractionHand; +import org.bukkit.event.Event; +import org.jetbrains.annotations.Nullable; + +import java.util.Arrays; + +@SuppressWarnings({"unchecked"}) +public class EvtCustomBlock extends SkriptEvent { + + public static void register() { + Skript.registerEvent("Break Custom Block", EvtCustomBlock.class, CustomBlockBreakEvent.class, "(break[ing]|1¦min(e|ing)) [[of] %-unsafeblockstatematchers%]") + .description("Called when a custom block is broken by a player. If you use 'on mine', only events where the broken block dropped something will call the trigger."); + Skript.registerEvent("Place Custom Block", EvtCustomBlock.class, CustomBlockPlaceEvent.class, "(plac(e|ing)|build[ing]) [[of] %-unsafeblockstatematchers%]") + .description("Called when a player places a custom block."); + } + + @Nullable + private Literal blocks; + private UnsafeBlockStateMatcher[] blockArray; + private boolean mine = false; + + @Override + public boolean init(Literal[] args, int matchedPattern, SkriptParser.ParseResult parser) { + if (args[0] != null) { + blocks = ((Literal) args[0]); + blockArray = blocks.getAll(); + } + mine = parser.mark == 1; + return true; + } + + @Override + public boolean check(Event event) { + if (mine && event instanceof CustomBlockBreakEvent customBlockBreakEvent) { + if (!BlockStateUtils.isCorrectTool(customBlockBreakEvent.blockState(), customBlockBreakEvent.player().getItemInHand(InteractionHand.MAIN_HAND))) { + return false; + } + } + if (blocks == null) + return true; + + ImmutableBlockState state; + if (event instanceof CustomBlockBreakEvent customBlockBreakEvent) { + state = customBlockBreakEvent.blockState(); + } else if (event instanceof CustomBlockPlaceEvent customBlockPlaceEvent) { + state = customBlockPlaceEvent.blockState(); + } else { + return false; + } + + return Arrays.stream(blockArray).anyMatch(block -> block.matches(state)); + } + + @Override + public String toString(@Nullable Event event, boolean debug) { + return "break/place" + (blocks != null ? " of " + blocks.toString(event, debug) : ""); + } +} diff --git a/bukkit/compatibility/src/main/java/net/momirealms/craftengine/bukkit/compatibility/skript/event/EvtCustomClick.java b/bukkit/compatibility/src/main/java/net/momirealms/craftengine/bukkit/compatibility/skript/event/EvtCustomClick.java new file mode 100644 index 000000000..68bcdb48b --- /dev/null +++ b/bukkit/compatibility/src/main/java/net/momirealms/craftengine/bukkit/compatibility/skript/event/EvtCustomClick.java @@ -0,0 +1,110 @@ +package net.momirealms.craftengine.bukkit.compatibility.skript.event; + +import ch.njol.skript.Skript; +import ch.njol.skript.aliases.ItemType; +import ch.njol.skript.bukkitutil.ClickEventTracker; +import ch.njol.skript.lang.Literal; +import ch.njol.skript.lang.SkriptEvent; +import ch.njol.skript.lang.SkriptParser; +import net.momirealms.craftengine.bukkit.api.event.CustomBlockInteractEvent; +import net.momirealms.craftengine.bukkit.api.event.FurnitureInteractEvent; +import net.momirealms.craftengine.core.block.ImmutableBlockState; +import net.momirealms.craftengine.core.block.UnsafeBlockStateMatcher; +import net.momirealms.craftengine.core.entity.player.InteractionHand; +import org.bukkit.event.Event; +import org.bukkit.inventory.EquipmentSlot; +import org.jetbrains.annotations.Nullable; + +import java.util.function.Predicate; + +public class EvtCustomClick extends SkriptEvent { + + private final static int RIGHT = 1, LEFT = 2, ANY = RIGHT | LEFT; + public final static ClickEventTracker interactTracker = new ClickEventTracker(Skript.getInstance()); + + public static void register() { + Skript.registerEvent("Interact Custom Block Furniture", EvtCustomClick.class, new Class[]{CustomBlockInteractEvent.class, FurnitureInteractEvent.class}, + "[(" + RIGHT + ":right|" + LEFT + ":left)(| |-)][mouse(| |-)]click[ing] [on %-unsafeblockstatematchers/strings%] [(with|using|holding) %-itemtype%]", + "[(" + RIGHT + ":right|" + LEFT + ":left)(| |-)][mouse(| |-)]click[ing] (with|using|holding) %itemtype% on %unsafeblockstatematchers/strings%"); + } + + private @Nullable Literal type; + private @Nullable Literal tools; + private int click = ANY; + + @Override + public boolean check(Event event) { + ImmutableBlockState block; + String furnitureId; + if (event instanceof CustomBlockInteractEvent interactEvent) { + furnitureId = null; + CustomBlockInteractEvent.Action action = interactEvent.action(); + int click; + switch (action) { + case LEFT_CLICK -> click = LEFT; + case RIGHT_CLICK -> click = RIGHT; + default -> { + return false; + } + } + if ((this.click & click) == 0) + return false; + EquipmentSlot hand = interactEvent.hand() == InteractionHand.MAIN_HAND ? EquipmentSlot.HAND : EquipmentSlot.OFF_HAND; + if (!interactTracker.checkEvent(interactEvent.getPlayer(), interactEvent, hand)) { + return false; + } + block = interactEvent.blockState(); + } else if (event instanceof FurnitureInteractEvent interactEvent) { + furnitureId = interactEvent.furniture().id().toString(); + block = null; + if ((this.click & RIGHT) == 0) + return false; + } else { + return false; + } + + Predicate checker = itemType -> { + if (event instanceof CustomBlockInteractEvent event1) { + return itemType.isOfType(event1.item()); + } else if (event instanceof FurnitureInteractEvent event1) { + return itemType.isOfType(event1.player().getInventory().getItem(event1.hand() == InteractionHand.MAIN_HAND ? EquipmentSlot.HAND : EquipmentSlot.OFF_HAND)); + } else { + return false; + } + }; + + if (tools != null && !tools.check(event, checker)) + return false; + + if (type != null) { + return type.check(event, (Predicate) object -> { + if (object instanceof String id && furnitureId != null) { + return id.equals(furnitureId); + } else if (object instanceof UnsafeBlockStateMatcher matcher && block != null) { + return matcher.matches(block); + } + return false; + }); + } + return true; + } + + @SuppressWarnings("unchecked") + @Override + public boolean init(Literal[] args, int matchedPattern, SkriptParser.ParseResult parseResult) { + click = parseResult.mark == 0 ? ANY : parseResult.mark; + type = args[matchedPattern]; + tools = (Literal) args[1 - matchedPattern]; + return true; + } + + @Override + public String toString(@Nullable Event event, boolean debug) { + return switch (click) { + case LEFT -> "left"; + case RIGHT -> "right"; + default -> ""; + } + "click" + (type != null ? " on " + type.toString(event, debug) : "") + + (tools != null ? " holding " + tools.toString(event, debug) : ""); + } +} diff --git a/bukkit/compatibility/src/main/java/net/momirealms/craftengine/bukkit/compatibility/skript/event/EvtCustomFurniture.java b/bukkit/compatibility/src/main/java/net/momirealms/craftengine/bukkit/compatibility/skript/event/EvtCustomFurniture.java new file mode 100644 index 000000000..081b72f85 --- /dev/null +++ b/bukkit/compatibility/src/main/java/net/momirealms/craftengine/bukkit/compatibility/skript/event/EvtCustomFurniture.java @@ -0,0 +1,58 @@ +package net.momirealms.craftengine.bukkit.compatibility.skript.event; + +import ch.njol.skript.Skript; +import ch.njol.skript.lang.Literal; +import ch.njol.skript.lang.SkriptEvent; +import ch.njol.skript.lang.SkriptParser; +import net.momirealms.craftengine.bukkit.api.event.FurnitureBreakEvent; +import net.momirealms.craftengine.bukkit.api.event.FurniturePlaceEvent; +import org.bukkit.event.Event; +import org.jetbrains.annotations.Nullable; + +import java.util.Arrays; + +@SuppressWarnings({"unchecked"}) +public class EvtCustomFurniture extends SkriptEvent { + + public static void register() { + Skript.registerEvent("Break Furniture", EvtCustomFurniture.class, FurnitureBreakEvent.class, "(break[ing]) [[of] %-strings%]") + .description("Called when a furniture is broken by a player."); + Skript.registerEvent("Place Furniture", EvtCustomFurniture.class, FurniturePlaceEvent.class, "(plac(e|ing)|build[ing]) [[of] %-strings%]") + .description("Called when a player places a furniture."); + } + + @Nullable + private Literal ids; + private String[] idArray; + + @Override + public boolean init(Literal[] args, int matchedPattern, SkriptParser.ParseResult parser) { + if (args[0] != null) { + ids = ((Literal) args[0]); + idArray = ids.getAll(); + } + return true; + } + + @Override + public boolean check(Event event) { + if (ids == null) + return true; + + String id; + if (event instanceof FurnitureBreakEvent e) { + id = e.furniture().id().toString(); + } else if (event instanceof FurniturePlaceEvent e) { + id = e.furniture().id().toString(); + } else { + return false; + } + + return Arrays.asList(idArray).contains(id); + } + + @Override + public String toString(@Nullable Event event, boolean debug) { + return "break/place" + (ids != null ? " of " + ids.toString(event, debug) : ""); + } +} diff --git a/bukkit/compatibility/src/main/java/net/momirealms/craftengine/bukkit/compatibility/skript/expression/ExprBlockCustomBlockID.java b/bukkit/compatibility/src/main/java/net/momirealms/craftengine/bukkit/compatibility/skript/expression/ExprBlockCustomBlockID.java new file mode 100644 index 000000000..db116d731 --- /dev/null +++ b/bukkit/compatibility/src/main/java/net/momirealms/craftengine/bukkit/compatibility/skript/expression/ExprBlockCustomBlockID.java @@ -0,0 +1,41 @@ +package net.momirealms.craftengine.bukkit.compatibility.skript.expression; + +import ch.njol.skript.expressions.base.SimplePropertyExpression; +import net.momirealms.craftengine.bukkit.api.CraftEngineBlocks; +import net.momirealms.craftengine.core.block.CustomBlock; +import net.momirealms.craftengine.core.block.ImmutableBlockState; +import org.bukkit.block.Block; +import org.bukkit.block.data.BlockData; +import org.jetbrains.annotations.Nullable; + +import java.util.Optional; + +public class ExprBlockCustomBlockID extends SimplePropertyExpression { + + public static void register() { + register(ExprBlockCustomBlockID.class, String.class, "custom block id", "blocks/blockdata/customblockstates"); + } + + @Override + public @Nullable String convert(Object object) { + if (object instanceof ImmutableBlockState immutableBlockState) + return immutableBlockState.owner().value().id().toString(); + if (object instanceof CustomBlock customBlock) + return customBlock.id().toString(); + if (object instanceof Block block) + return Optional.ofNullable(CraftEngineBlocks.getCustomBlockState(block)).map(it -> it.owner().value().id().toString()).orElse(null); + if (object instanceof BlockData blockData) + return Optional.ofNullable(CraftEngineBlocks.getCustomBlockState(blockData)).map(it -> it.owner().value().id().toString()).orElse(null); + return null; + } + + @Override + protected String getPropertyName() { + return "custom block id"; + } + + @Override + public Class getReturnType() { + return String.class; + } +} diff --git a/bukkit/compatibility/src/main/java/net/momirealms/craftengine/bukkit/compatibility/skript/expression/ExprBlockCustomBlockState.java b/bukkit/compatibility/src/main/java/net/momirealms/craftengine/bukkit/compatibility/skript/expression/ExprBlockCustomBlockState.java new file mode 100644 index 000000000..04874c3c3 --- /dev/null +++ b/bukkit/compatibility/src/main/java/net/momirealms/craftengine/bukkit/compatibility/skript/expression/ExprBlockCustomBlockState.java @@ -0,0 +1,34 @@ +package net.momirealms.craftengine.bukkit.compatibility.skript.expression; + +import ch.njol.skript.expressions.base.SimplePropertyExpression; +import net.momirealms.craftengine.bukkit.api.CraftEngineBlocks; +import net.momirealms.craftengine.core.block.ImmutableBlockState; +import org.bukkit.block.Block; +import org.bukkit.block.data.BlockData; +import org.jetbrains.annotations.Nullable; + +public class ExprBlockCustomBlockState extends SimplePropertyExpression { + + public static void register() { + register(ExprBlockCustomBlockState.class, ImmutableBlockState.class, "custom block[ ]state", "blocks/blockdata"); + } + + @Override + public @Nullable ImmutableBlockState convert(Object object) { + if (object instanceof Block block) + return CraftEngineBlocks.getCustomBlockState(block); + if (object instanceof BlockData blockData) + return CraftEngineBlocks.getCustomBlockState(blockData); + return null; + } + + @Override + protected String getPropertyName() { + return "custom block state"; + } + + @Override + public Class getReturnType() { + return ImmutableBlockState.class; + } +} diff --git a/bukkit/compatibility/src/main/java/net/momirealms/craftengine/bukkit/compatibility/skript/expression/ExprCustomItem.java b/bukkit/compatibility/src/main/java/net/momirealms/craftengine/bukkit/compatibility/skript/expression/ExprCustomItem.java new file mode 100644 index 000000000..2c3557a47 --- /dev/null +++ b/bukkit/compatibility/src/main/java/net/momirealms/craftengine/bukkit/compatibility/skript/expression/ExprCustomItem.java @@ -0,0 +1,56 @@ +package net.momirealms.craftengine.bukkit.compatibility.skript.expression; + +import ch.njol.skript.Skript; +import ch.njol.skript.lang.Expression; +import ch.njol.skript.lang.ExpressionType; +import ch.njol.skript.lang.SkriptParser; +import ch.njol.skript.lang.util.SimpleExpression; +import ch.njol.util.Kleenean; +import net.momirealms.craftengine.bukkit.api.CraftEngineItems; +import net.momirealms.craftengine.core.item.ItemBuildContext; +import net.momirealms.craftengine.core.util.Key; +import org.bukkit.event.Event; +import org.bukkit.inventory.ItemStack; +import org.jetbrains.annotations.Nullable; + +import java.util.Objects; + +public class ExprCustomItem extends SimpleExpression { + + public static void register() { + Skript.registerExpression(ExprCustomItem.class, ItemStack.class, ExpressionType.SIMPLE, "[(the|a)] custom item [with id] %string%"); + } + + private Expression itemId; + + @Override + @SuppressWarnings("unchecked") + public boolean init(Expression[] exprs, int matchedPattern, Kleenean isDelayed, SkriptParser.ParseResult parseResult) { + itemId = (Expression) exprs[0]; + return true; + } + + @Override + @Nullable + protected ItemStack[] get(Event e) { + String itemId = this.itemId.getSingle(e); + if (itemId == null) + return null; + return new ItemStack[] {Objects.requireNonNull(CraftEngineItems.byId(Key.of(itemId))).buildItemStack(ItemBuildContext.EMPTY)}; + } + + @Override + public boolean isSingle() { + return true; + } + + @Override + public Class getReturnType() { + return ItemStack.class; + } + + @Override + public String toString(@Nullable Event e, boolean debug) { + return "the custom item with id " + itemId.toString(e, debug); + } +} diff --git a/bukkit/compatibility/src/main/java/net/momirealms/craftengine/bukkit/compatibility/skript/expression/ExprEntityFurnitureID.java b/bukkit/compatibility/src/main/java/net/momirealms/craftengine/bukkit/compatibility/skript/expression/ExprEntityFurnitureID.java new file mode 100644 index 000000000..f11a78ac1 --- /dev/null +++ b/bukkit/compatibility/src/main/java/net/momirealms/craftengine/bukkit/compatibility/skript/expression/ExprEntityFurnitureID.java @@ -0,0 +1,32 @@ +package net.momirealms.craftengine.bukkit.compatibility.skript.expression; + +import ch.njol.skript.expressions.base.SimplePropertyExpression; +import net.momirealms.craftengine.bukkit.api.CraftEngineFurniture; +import org.bukkit.entity.Entity; +import org.jetbrains.annotations.Nullable; + +import java.util.Objects; + +public class ExprEntityFurnitureID extends SimplePropertyExpression { + + public static void register() { + register(ExprEntityFurnitureID.class, String.class, "furniture id", "entities"); + } + + @Override + public @Nullable String convert(Object object) { + if (object instanceof Entity entity && CraftEngineFurniture.isFurniture(entity)) + return Objects.requireNonNull(CraftEngineFurniture.getLoadedFurnitureByBaseEntity(entity)).id().toString(); + return null; + } + + @Override + protected String getPropertyName() { + return "furniture id"; + } + + @Override + public Class getReturnType() { + return String.class; + } +} diff --git a/bukkit/compatibility/src/main/java/net/momirealms/craftengine/bukkit/compatibility/skript/expression/ExprItemCustomItemID.java b/bukkit/compatibility/src/main/java/net/momirealms/craftengine/bukkit/compatibility/skript/expression/ExprItemCustomItemID.java new file mode 100644 index 000000000..e9531c7b2 --- /dev/null +++ b/bukkit/compatibility/src/main/java/net/momirealms/craftengine/bukkit/compatibility/skript/expression/ExprItemCustomItemID.java @@ -0,0 +1,65 @@ +package net.momirealms.craftengine.bukkit.compatibility.skript.expression; + +import ch.njol.skript.aliases.ItemType; +import ch.njol.skript.classes.Changer; +import ch.njol.skript.expressions.base.SimplePropertyExpression; +import ch.njol.util.coll.CollectionUtils; +import net.momirealms.craftengine.bukkit.api.CraftEngineItems; +import net.momirealms.craftengine.bukkit.item.BukkitItemManager; +import net.momirealms.craftengine.core.item.Item; +import net.momirealms.craftengine.core.util.Key; +import org.bukkit.event.Event; +import org.bukkit.inventory.ItemStack; +import org.jetbrains.annotations.Nullable; + +import java.util.Optional; + +public class ExprItemCustomItemID extends SimplePropertyExpression { + + public static void register() { + register(ExprItemCustomItemID.class, String.class, "custom item id", "itemstacks/itemtypes"); + } + + @Override + public @Nullable String convert(Object object) { + if (object instanceof ItemStack itemStack) + return Optional.ofNullable(CraftEngineItems.byItemStack(itemStack)).map(it -> it.id().toString()).orElse(null); + if (object instanceof ItemType itemType) { + ItemStack itemStack = new ItemStack(itemType.getMaterial()); + itemStack.setItemMeta(itemType.getItemMeta()); + return Optional.ofNullable(CraftEngineItems.byItemStack(itemStack)).map(it -> it.id().toString()).orElse(null); + } + return null; + } + + @Override + protected String getPropertyName() { + return "custom item id"; + } + + @Override + public Class getReturnType() { + return String.class; + } + + @Override + public Class[] acceptChange(Changer.ChangeMode mode) { + return CollectionUtils.array(String.class); + } + + @Override + public void change(Event e, @Nullable Object[] delta, Changer.ChangeMode mode) { + Key id = Key.of((String) delta[0]); + for (Object item : getExpr().getArray(e)) { + if (item instanceof ItemStack itemStack) { + Item item1 = BukkitItemManager.instance().wrap(itemStack); + Item item2 = BukkitItemManager.instance().createWrappedItem(id, null); + item1.merge(item2); + item1.load(); + } else if (item instanceof ItemType itemType) { + Item item2 = BukkitItemManager.instance().createWrappedItem(id, null); + itemType.setItemMeta(item2.load().getItemMeta()); + } + } + } +} diff --git a/bukkit/compatibility/src/main/java/net/momirealms/craftengine/bukkit/compatibility/slimeworld/SlimeWorldDataStorage.java b/bukkit/compatibility/src/main/java/net/momirealms/craftengine/bukkit/compatibility/slimeworld/SlimeWorldDataStorage.java index 8e0a55696..ae6703087 100644 --- a/bukkit/compatibility/src/main/java/net/momirealms/craftengine/bukkit/compatibility/slimeworld/SlimeWorldDataStorage.java +++ b/bukkit/compatibility/src/main/java/net/momirealms/craftengine/bukkit/compatibility/slimeworld/SlimeWorldDataStorage.java @@ -2,13 +2,15 @@ package net.momirealms.craftengine.bukkit.compatibility.slimeworld; import com.infernalsuite.asp.api.world.SlimeChunk; import com.infernalsuite.asp.api.world.SlimeWorld; +import net.momirealms.craftengine.core.world.CEWorld; import net.momirealms.craftengine.core.world.ChunkPos; +import net.momirealms.craftengine.core.world.chunk.CEChunk; +import net.momirealms.craftengine.core.world.chunk.serialization.DefaultChunkSerializer; import net.momirealms.craftengine.core.world.chunk.storage.WorldDataStorage; import net.momirealms.sparrow.nbt.CompoundTag; import net.momirealms.sparrow.nbt.NBT; -import org.jetbrains.annotations.Nullable; +import org.jetbrains.annotations.NotNull; -import java.io.IOException; import java.lang.ref.WeakReference; import java.util.Map; @@ -25,15 +27,16 @@ public class SlimeWorldDataStorage implements WorldDataStorage { return slimeWorld.get(); } - @Nullable @Override - public CompoundTag readChunkTagAt(ChunkPos pos) { + public @NotNull CEChunk readChunkAt(@NotNull CEWorld world, @NotNull ChunkPos pos) { SlimeChunk slimeChunk = getWorld().getChunk(pos.x, pos.z); - if (slimeChunk == null) return null; + if (slimeChunk == null) return new CEChunk(world, pos); Object tag = slimeChunk.getExtraData().get("craftengine"); - if (tag == null) return null; + if (tag == null) return new CEChunk(world, pos); try { - return NBT.fromBytes(adaptor.byteArrayTagToBytes(tag)); + CompoundTag compoundTag = NBT.fromBytes(adaptor.byteArrayTagToBytes(tag)); + if (compoundTag == null) return new CEChunk(world, pos); + return DefaultChunkSerializer.deserialize(world, pos, compoundTag); } catch (Exception e) { throw new RuntimeException("Failed to read chunk tag from slime world. " + pos, e); } @@ -41,9 +44,10 @@ public class SlimeWorldDataStorage implements WorldDataStorage { @SuppressWarnings("unchecked") @Override - public void writeChunkTagAt(ChunkPos pos, @Nullable CompoundTag nbt) { + public void writeChunkAt(@NotNull ChunkPos pos, @NotNull CEChunk chunk, boolean immediately) { SlimeChunk slimeChunk = getWorld().getChunk(pos.x, pos.z); if (slimeChunk == null) return; + CompoundTag nbt = DefaultChunkSerializer.serialize(chunk); if (nbt == null) { slimeChunk.getExtraData().remove("craftengine"); } else { @@ -63,6 +67,6 @@ public class SlimeWorldDataStorage implements WorldDataStorage { } @Override - public void close() throws IOException { + public void close() { } } diff --git a/bukkit/compatibility/src/main/java/net/momirealms/craftengine/bukkit/compatibility/viaversion/ViaVersionUtils.java b/bukkit/compatibility/src/main/java/net/momirealms/craftengine/bukkit/compatibility/viaversion/ViaVersionUtils.java new file mode 100644 index 000000000..d34da59dc --- /dev/null +++ b/bukkit/compatibility/src/main/java/net/momirealms/craftengine/bukkit/compatibility/viaversion/ViaVersionUtils.java @@ -0,0 +1,14 @@ +package net.momirealms.craftengine.bukkit.compatibility.viaversion; + +import com.viaversion.viaversion.api.Via; + +import java.util.UUID; + +public final class ViaVersionUtils { + + private ViaVersionUtils() {} + + public static int getPlayerProtocolVersion(UUID uuid) { + return Via.getAPI().getPlayerProtocolVersion(uuid).getVersion(); + } +} diff --git a/bukkit/compatibility/src/main/java/net/momirealms/craftengine/bukkit/compatibility/worldedit/WorldEditBlockRegister.java b/bukkit/compatibility/src/main/java/net/momirealms/craftengine/bukkit/compatibility/worldedit/WorldEditBlockRegister.java index 94c28ebea..2066c2bc1 100644 --- a/bukkit/compatibility/src/main/java/net/momirealms/craftengine/bukkit/compatibility/worldedit/WorldEditBlockRegister.java +++ b/bukkit/compatibility/src/main/java/net/momirealms/craftengine/bukkit/compatibility/worldedit/WorldEditBlockRegister.java @@ -25,7 +25,7 @@ public class WorldEditBlockRegister { private final boolean isFAWE; public WorldEditBlockRegister(AbstractBlockManager manager, boolean isFAWE) { - field$BlockType$blockMaterial = ReflectionUtils.getDeclaredField(BlockType.class, "blockMaterial"); + this.field$BlockType$blockMaterial = ReflectionUtils.getDeclaredField(BlockType.class, "blockMaterial"); this.manager = manager; this.isFAWE = isFAWE; CEBlockParser blockParser = new CEBlockParser(WorldEdit.getInstance()); @@ -34,7 +34,7 @@ public class WorldEditBlockRegister { public void register(Key id) throws ReflectiveOperationException { BlockType blockType = new BlockType(id.toString(), blockState -> blockState); - field$BlockType$blockMaterial.set(blockType, LazyReference.from(() -> new BukkitBlockRegistry.BukkitBlockMaterial(null, Material.STONE))); + this.field$BlockType$blockMaterial.set(blockType, LazyReference.from(() -> new BukkitBlockRegistry.BukkitBlockMaterial(null, Material.STONE))); BlockType.REGISTRY.register(id.toString(), blockType); } diff --git a/bukkit/loader/build.gradle.kts b/bukkit/loader/build.gradle.kts index 092d166a5..ffb3920cf 100644 --- a/bukkit/loader/build.gradle.kts +++ b/bukkit/loader/build.gradle.kts @@ -19,6 +19,7 @@ dependencies { implementation(project(":bukkit")) implementation(project(":bukkit:legacy")) implementation(project(":bukkit:compatibility")) + implementation(project(":bukkit:compatibility:legacy")) implementation("net.kyori:adventure-platform-bukkit:${rootProject.properties["adventure_platform_version"]}") implementation("com.saicone.rtag:rtag-item:${rootProject.properties["rtag_version"]}") @@ -49,7 +50,7 @@ bukkit { apiVersion = "1.20" authors = listOf("XiaoMoMi") contributors = listOf("jhqwqmc", "iqtesterrr") - softDepend = listOf("PlaceholderAPI", "WorldEdit", "FastAsyncWorldEdit") + softDepend = listOf("PlaceholderAPI", "WorldEdit", "FastAsyncWorldEdit", "Skript") foliaSupported = true } diff --git a/bukkit/loader/src/main/resources/config.yml b/bukkit/loader/src/main/resources/config.yml index 63d41c3b3..eda56d932 100644 --- a/bukkit/loader/src/main/resources/config.yml +++ b/bukkit/loader/src/main/resources/config.yml @@ -343,6 +343,8 @@ light-system: force-update-light: false chunk-system: + # Unloaded chunks may be loaded soon. Delaying serialization can improve performance, especially for those double-dimension mob farms. + delay-serialization: 20 # seconds -1 = disable # 1 = NONE | Compression Speed | Decompress Speed | Compression Ratio | Memory Usage | # 2 = DEFLATE | Medium-Slow Medium Moderate Low | # 3 = GZIP | Medium-Slow Medium Moderate Low | diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/api/BukkitAdaptors.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/api/BukkitAdaptors.java new file mode 100644 index 000000000..d49ca44c8 --- /dev/null +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/api/BukkitAdaptors.java @@ -0,0 +1,32 @@ +package net.momirealms.craftengine.bukkit.api; + +import net.momirealms.craftengine.bukkit.entity.BukkitEntity; +import net.momirealms.craftengine.bukkit.plugin.BukkitCraftEngine; +import net.momirealms.craftengine.bukkit.plugin.user.BukkitServerPlayer; +import net.momirealms.craftengine.bukkit.world.BukkitWorld; +import net.momirealms.craftengine.bukkit.world.BukkitWorldBlock; +import org.bukkit.World; +import org.bukkit.block.Block; +import org.bukkit.entity.Entity; +import org.bukkit.entity.Player; + +public final class BukkitAdaptors { + + private BukkitAdaptors() {} + + public static BukkitServerPlayer adapt(final Player player) { + return BukkitCraftEngine.instance().adapt(player); + } + + public static BukkitWorld adapt(final World world) { + return new BukkitWorld(world); + } + + public static BukkitEntity adapt(final Entity entity) { + return new BukkitEntity(entity); + } + + public static BukkitWorldBlock adapt(final Block block) { + return new BukkitWorldBlock(block); + } +} diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/api/CraftEngineBlocks.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/api/CraftEngineBlocks.java index 0a840939a..7b8467ea5 100644 --- a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/api/CraftEngineBlocks.java +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/api/CraftEngineBlocks.java @@ -30,6 +30,8 @@ import org.jetbrains.annotations.Nullable; public final class CraftEngineBlocks { + private CraftEngineBlocks() {} + /** * Gets a custom block by ID * @@ -122,7 +124,7 @@ public final class CraftEngineBlocks { } /** - * Removes a block from the world if it's a custom one + * Removes a block from the world if it's custom * * @param block block to remove * @return success or not @@ -134,7 +136,7 @@ public final class CraftEngineBlocks { } /** - * Removes a block from the world if it's a custom one + * Removes a block from the world if it's custom * * @param block block to remove * @param applyPhysics whether to apply physics @@ -148,7 +150,7 @@ public final class CraftEngineBlocks { } /** - * Removes a block from the world if it's a custom one + * Removes a block from the world if it's custom * * @param block block to remove * @param player player who breaks the block @@ -191,7 +193,7 @@ public final class CraftEngineBlocks { } /** - * Checks if a block is a custom one + * Checks if a block is custom * * @param block block * @return is custom block or not @@ -234,7 +236,7 @@ public final class CraftEngineBlocks { * @return bukkit block data */ @NotNull - public static BlockData createBukkitBlockData(@NotNull ImmutableBlockState blockState) { + public static BlockData getBukkitBlockData(@NotNull ImmutableBlockState blockState) { return BlockStateUtils.fromBlockData(blockState.customBlockState().handle()); } } diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/api/CraftEngineFurniture.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/api/CraftEngineFurniture.java index fca21a6cc..4abf9bbab 100644 --- a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/api/CraftEngineFurniture.java +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/api/CraftEngineFurniture.java @@ -2,6 +2,8 @@ package net.momirealms.craftengine.bukkit.api; import net.momirealms.craftengine.bukkit.entity.furniture.BukkitFurnitureManager; import net.momirealms.craftengine.bukkit.entity.furniture.LoadedFurniture; +import net.momirealms.craftengine.bukkit.nms.CollisionEntity; +import net.momirealms.craftengine.bukkit.nms.FastNMS; import net.momirealms.craftengine.bukkit.plugin.BukkitCraftEngine; import net.momirealms.craftengine.bukkit.util.LocationUtils; import net.momirealms.craftengine.bukkit.world.BukkitWorld; @@ -25,7 +27,9 @@ import org.jetbrains.annotations.Nullable; import java.util.List; -public class CraftEngineFurniture { +public final class CraftEngineFurniture { + + private CraftEngineFurniture() {} /** * Gets custom furniture by ID @@ -120,6 +124,17 @@ public class CraftEngineFurniture { return furnitureId != null; } + /** + * Check if an entity is a collision entity + * + * @param entity entity to check + * @return is collision entity or not + */ + public static boolean isCollisionEntity(@NotNull Entity entity) { + Object nmsEntity = FastNMS.INSTANCE.method$CraftEntity$getHandle(entity); + return nmsEntity instanceof CollisionEntity; + } + /** * Check if an entity is a seat * diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/api/CraftEngineItems.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/api/CraftEngineItems.java index 1049ffafc..2203f6e5b 100644 --- a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/api/CraftEngineItems.java +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/api/CraftEngineItems.java @@ -8,7 +8,9 @@ import org.bukkit.inventory.ItemStack; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -public class CraftEngineItems { +public final class CraftEngineItems { + + private CraftEngineItems() {} /** * Gets a custom item by ID diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/api/event/CustomBlockBreakEvent.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/api/event/CustomBlockBreakEvent.java index 03c0cc3b3..4034c8dea 100644 --- a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/api/event/CustomBlockBreakEvent.java +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/api/event/CustomBlockBreakEvent.java @@ -1,10 +1,10 @@ package net.momirealms.craftengine.bukkit.api.event; +import net.momirealms.craftengine.bukkit.plugin.user.BukkitServerPlayer; import net.momirealms.craftengine.core.block.CustomBlock; import net.momirealms.craftengine.core.block.ImmutableBlockState; import org.bukkit.Location; import org.bukkit.block.Block; -import org.bukkit.entity.Player; import org.bukkit.event.Cancellable; import org.bukkit.event.HandlerList; import org.bukkit.event.player.PlayerEvent; @@ -18,17 +18,23 @@ public class CustomBlockBreakEvent extends PlayerEvent implements Cancellable { private final Location location; private final Block bukkitBlock; private boolean dropItems; + private final BukkitServerPlayer player; - public CustomBlockBreakEvent(@NotNull Player player, + public CustomBlockBreakEvent(@NotNull BukkitServerPlayer player, @NotNull Location location, @NotNull Block bukkitBlock, @NotNull ImmutableBlockState state) { - super(player); + super(player.platformPlayer()); this.customBlock = state.owner().value(); this.state = state; this.bukkitBlock = bukkitBlock; this.location = location; this.dropItems = true; + this.player = player; + } + + public BukkitServerPlayer player() { + return player; } public boolean dropItems() { @@ -44,11 +50,6 @@ public class CustomBlockBreakEvent extends PlayerEvent implements Cancellable { return bukkitBlock; } - @NotNull - public Player player() { - return getPlayer(); - } - @NotNull public CustomBlock customBlock() { return this.customBlock; diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/api/event/CustomBlockInteractEvent.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/api/event/CustomBlockInteractEvent.java index 71e55cb5d..f9c9eccf2 100644 --- a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/api/event/CustomBlockInteractEvent.java +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/api/event/CustomBlockInteractEvent.java @@ -10,6 +10,8 @@ import org.bukkit.entity.Player; import org.bukkit.event.Cancellable; import org.bukkit.event.HandlerList; import org.bukkit.event.player.PlayerEvent; +import org.bukkit.inventory.ItemStack; +import org.jetbrains.annotations.ApiStatus; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -24,6 +26,7 @@ public class CustomBlockInteractEvent extends PlayerEvent implements Cancellable private final InteractionHand hand; private final Action action; private final BlockFace clickedFace; + private final ItemStack item; public CustomBlockInteractEvent(@NotNull Player player, @NotNull Location location, @@ -32,7 +35,8 @@ public class CustomBlockInteractEvent extends PlayerEvent implements Cancellable @NotNull Block bukkitBlock, @NotNull BlockFace clickedFace, @NotNull InteractionHand hand, - @NotNull Action action) { + @NotNull Action action, + @Nullable ItemStack item) { super(player); this.customBlock = state.owner().value(); this.bukkitBlock = bukkitBlock; @@ -42,6 +46,7 @@ public class CustomBlockInteractEvent extends PlayerEvent implements Cancellable this.hand = hand; this.action = action; this.clickedFace = clickedFace; + this.item = item; } @NotNull @@ -89,6 +94,12 @@ public class CustomBlockInteractEvent extends PlayerEvent implements Cancellable return this.state; } + @ApiStatus.Experimental + @NotNull + public ItemStack item() { + return this.item; + } + @NotNull public static HandlerList getHandlerList() { return HANDLER_LIST; diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/BlockEventListener.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/BlockEventListener.java index f60b5d7f5..6b4dcd633 100644 --- a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/BlockEventListener.java +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/BlockEventListener.java @@ -7,7 +7,6 @@ import net.momirealms.craftengine.bukkit.plugin.BukkitCraftEngine; import net.momirealms.craftengine.bukkit.plugin.user.BukkitServerPlayer; import net.momirealms.craftengine.bukkit.util.*; import net.momirealms.craftengine.bukkit.world.BukkitWorld; -import net.momirealms.craftengine.core.block.BlockSettings; import net.momirealms.craftengine.core.block.ImmutableBlockState; import net.momirealms.craftengine.core.block.properties.Property; import net.momirealms.craftengine.core.entity.player.InteractionHand; @@ -52,7 +51,7 @@ public class BlockEventListener implements Listener { @EventHandler(ignoreCancelled = true) public void onPlayerAttack(EntityDamageByEntityEvent event) { - if (!VersionHelper.isVersionNewerThan1_20_5()) { + if (!VersionHelper.isOrAbove1_20_5()) { if (event.getDamager() instanceof Player player) { BukkitServerPlayer serverPlayer = plugin.adapt(player); serverPlayer.setClientSideCanBreakBlock(true); @@ -120,7 +119,7 @@ public class BlockEventListener implements Listener { } // trigger event - CustomBlockBreakEvent customBreakEvent = new CustomBlockBreakEvent(event.getPlayer(), location, block, state); + CustomBlockBreakEvent customBreakEvent = new CustomBlockBreakEvent(serverPlayer, location, block, state); boolean isCancelled = EventUtils.fireAndCheckCancel(customBreakEvent); if (isCancelled) { event.setCancelled(true); @@ -146,14 +145,10 @@ public class BlockEventListener implements Listener { Item itemInHand = serverPlayer.getItemInHand(InteractionHand.MAIN_HAND); // do not drop if it's not the correct tool - BlockSettings settings = state.settings(); - if (settings.requireCorrectTool()) { - if (itemInHand == null) return; - if (!settings.isCorrectTool(itemInHand.id()) && - (!settings.respectToolComponent() || !FastNMS.INSTANCE.method$ItemStack$isCorrectToolForDrops(itemInHand.getLiteralObject(), state.customBlockState().handle()))) { - return; - } + if (!BlockStateUtils.isCorrectTool(state, itemInHand)) { + return; } + // drop items ContextHolder.Builder builder = ContextHolder.builder(); builder.withParameter(LootParameters.WORLD, world); @@ -311,7 +306,7 @@ public class BlockEventListener implements Listener { @EventHandler(ignoreCancelled = true, priority = EventPriority.MONITOR) public void onEntityExplode(EntityExplodeEvent event) { - if (VersionHelper.isVersionNewerThan1_21()) { + if (VersionHelper.isOrAbove1_21()) { if (!ExplosionUtils.isDroppingItems(event)) return; } handleExplodeEvent(event.blockList(), new BukkitWorld(event.getEntity().getWorld()), event.getYield()); @@ -319,7 +314,7 @@ public class BlockEventListener implements Listener { @EventHandler(ignoreCancelled = true, priority = EventPriority.MONITOR) public void onBlockExplode(BlockExplodeEvent event) { - if (VersionHelper.isVersionNewerThan1_21()) { + if (VersionHelper.isOrAbove1_21()) { if (!ExplosionUtils.isDroppingItems(event)) return; } handleExplodeEvent(event.blockList(), new BukkitWorld(event.getBlock().getWorld()), event.getYield()); diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/BukkitBlockManager.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/BukkitBlockManager.java index 57d41aabe..807b57514 100644 --- a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/BukkitBlockManager.java +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/BukkitBlockManager.java @@ -7,7 +7,6 @@ import com.google.gson.JsonArray; import com.google.gson.JsonElement; import com.google.gson.JsonObject; import dev.dejvokep.boostedyaml.YamlDocument; -import net.momirealms.craftengine.bukkit.compatibility.worldedit.WorldEditBlockRegister; import net.momirealms.craftengine.bukkit.nms.FastNMS; import net.momirealms.craftengine.bukkit.plugin.BukkitCraftEngine; import net.momirealms.craftengine.bukkit.plugin.injector.BukkitInjector; @@ -108,7 +107,7 @@ public class BukkitBlockManager extends AbstractBlockManager { if (enableNoteBlocks) { this.recordVanillaNoteBlocks(); } - if (VersionHelper.isVersionNewerThan1_20_3()) { + if (VersionHelper.isOrAbove1_20_3()) { this.fallingBlockRemoveListener = new FallingBlockRemoveListener(); } else this.fallingBlockRemoveListener = null; this.stateId2ImmutableBlockStates = new ImmutableBlockState[customBlockCount]; @@ -117,6 +116,10 @@ public class BukkitBlockManager extends AbstractBlockManager { this.resetPacketConsumers(); } + public List blockRegisterOrder() { + return Collections.unmodifiableList(this.blockRegisterOrder); + } + public static BukkitBlockManager instance() { return instance; } @@ -127,12 +130,6 @@ public class BukkitBlockManager extends AbstractBlockManager { if (this.fallingBlockRemoveListener != null) { Bukkit.getPluginManager().registerEvents(this.fallingBlockRemoveListener, plugin.bootstrap()); } - // WorldEdit - if (this.plugin.isPluginEnabled("FastAsyncWorldEdit")) { - this.initFastAsyncWorldEditHook(); - } else if (this.plugin.isPluginEnabled("WorldEdit")) { - this.initWorldEditHook(); - } } @Override @@ -171,20 +168,6 @@ public class BukkitBlockManager extends AbstractBlockManager { this.tempVanillaBlockStateModels.clear(); } - public void initFastAsyncWorldEditHook() { - new WorldEditBlockRegister(this, true); - } - - public void initWorldEditHook() { - WorldEditBlockRegister weBlockRegister = new WorldEditBlockRegister(this, false); - try { - for (Key newBlockId : this.blockRegisterOrder) { - weBlockRegister.register(newBlockId); - } - } catch (Exception e) { - this.plugin.logger().warn("Failed to initialize world edit hook", e); - } - } @Nullable public Object getMinecraftBlockHolder(int stateId) { diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/BukkitCustomBlock.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/BukkitCustomBlock.java index 154a947b2..2bb530a75 100644 --- a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/BukkitCustomBlock.java +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/BukkitCustomBlock.java @@ -107,7 +107,7 @@ public class BukkitCustomBlock extends CustomBlock { Reflections.method$BlockStateBase$initCache.invoke(mcBlockState); // set block light if (settings.blockLight() != -1) { - if (VersionHelper.isVersionNewerThan1_21_2()) { + if (VersionHelper.isOrAbove1_21_2()) { Reflections.field$BlockStateBase$lightBlock.set(mcBlockState, settings.blockLight()); } else { Object cache = Reflections.field$BlockStateBase$cache.get(mcBlockState); diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/behavior/BushBlockBehavior.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/behavior/BushBlockBehavior.java index 9f626c36e..b19b7bdbf 100644 --- a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/behavior/BushBlockBehavior.java +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/behavior/BushBlockBehavior.java @@ -56,7 +56,7 @@ public class BushBlockBehavior extends BukkitBlockBehavior { Object level; Object blockPos; Object state = args[0]; - if (VersionHelper.isVersionNewerThan1_21_2()) { + if (VersionHelper.isOrAbove1_21_2()) { level = args[1]; blockPos = args[3]; } else { diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/behavior/ConcretePowderBlockBehavior.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/behavior/ConcretePowderBlockBehavior.java index 99ec57099..6f8cd8f8b 100644 --- a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/behavior/ConcretePowderBlockBehavior.java +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/behavior/ConcretePowderBlockBehavior.java @@ -99,7 +99,7 @@ public class ConcretePowderBlockBehavior extends FallingBlockBehavior { public Object updateShape(Object thisBlock, Object[] args, Callable superMethod) throws Exception { Object level; Object pos; - if (VersionHelper.isVersionNewerThan1_21_2()) { + if (VersionHelper.isOrAbove1_21_2()) { level = args[1]; pos = args[3]; } else { 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 8b2813ea9..07874400a 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 @@ -42,7 +42,7 @@ public class FallingBlockBehavior extends BukkitBlockBehavior { public Object updateShape(Object thisBlock, Object[] args, Callable superMethod) throws Exception { Object world; Object blockPos; - if (VersionHelper.isVersionNewerThan1_21_2()) { + if (VersionHelper.isOrAbove1_21_2()) { world = args[1]; blockPos = args[3]; } else { @@ -81,7 +81,7 @@ public class FallingBlockBehavior extends BukkitBlockBehavior { @Override public void onBrokenAfterFall(Object thisBlock, Object[] args) throws Exception { // Use EntityRemoveEvent for 1.20.3+ - if (VersionHelper.isVersionNewerThan1_20_3()) return; + if (VersionHelper.isOrAbove1_20_3()) return; Object level = args[0]; Object fallingBlockEntity = args[2]; boolean cancelDrop = (boolean) Reflections.field$FallingBlockEntity$cancelDrop.get(fallingBlockEntity); diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/behavior/LeavesBlockBehavior.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/behavior/LeavesBlockBehavior.java index 5c4ec7e41..9982700fa 100644 --- a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/behavior/LeavesBlockBehavior.java +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/behavior/LeavesBlockBehavior.java @@ -66,7 +66,7 @@ public class LeavesBlockBehavior extends WaterLoggedBlockBehavior { Object blockPos; Object neighborState; Object blockState = args[0]; - if (VersionHelper.isVersionNewerThan1_21_2()) { + if (VersionHelper.isOrAbove1_21_2()) { world = args[1]; neighborState = args[6]; blockPos = args[3]; diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/behavior/SugarCaneBlockBehavior.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/behavior/SugarCaneBlockBehavior.java index 051a0f296..4a504d371 100644 --- a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/behavior/SugarCaneBlockBehavior.java +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/behavior/SugarCaneBlockBehavior.java @@ -79,7 +79,7 @@ public class SugarCaneBlockBehavior extends BushBlockBehavior { public Object updateShape(Object thisBlock, Object[] args, Callable superMethod) throws Exception { Object world; Object blockPos; - if (VersionHelper.isVersionNewerThan1_21_2()) { + if (VersionHelper.isOrAbove1_21_2()) { world = args[1]; blockPos = args[3]; } else { @@ -120,7 +120,7 @@ public class SugarCaneBlockBehavior extends BushBlockBehavior { int age = currentState.get(ageProperty); if (age >= this.ageProperty.max || RandomUtils.generateRandomFloat(0, 1) < this.growSpeed) { Object abovePos = LocationUtils.above(blockPos); - if (VersionHelper.isVersionNewerThan1_21_5()) { + if (VersionHelper.isOrAbove1_21_5()) { Reflections.method$CraftEventFactory$handleBlockGrowEvent.invoke(null, level, abovePos, super.customBlock.defaultState().customBlockState().handle(), UpdateOption.UPDATE_ALL.flags()); } else { Reflections.method$CraftEventFactory$handleBlockGrowEvent.invoke(null, level, abovePos, super.customBlock.defaultState().customBlockState().handle()); diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/entity/data/DisplayEntityData.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/entity/data/DisplayEntityData.java index c206727cb..ec2f06cf3 100644 --- a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/entity/data/DisplayEntityData.java +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/entity/data/DisplayEntityData.java @@ -38,6 +38,6 @@ public class DisplayEntityData extends BaseEntityData { } public DisplayEntityData(int id, Object serializer, T defaultValue) { - super(!VersionHelper.isVersionNewerThan1_20_2() && id >= 11 ? id - 1 : id, serializer, defaultValue); + super(!VersionHelper.isOrAbove1_20_2() && id >= 11 ? id - 1 : id, 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 bb4c0c782..e747c74c0 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 @@ -60,15 +60,15 @@ public class EntityDataValue { Serializers$OPTIONAL_BLOCK_STATE = initSerializersByName("OPTIONAL_BLOCK_STATE"); Serializers$BOOLEAN = initSerializersByName("BOOLEAN"); Serializers$PARTICLE = initSerializersByName("PARTICLE"); - if (VersionHelper.isVersionNewerThan1_20_5()) Serializers$PARTICLES = initSerializersByName("PARTICLES"); + if (VersionHelper.isOrAbove1_20_5()) Serializers$PARTICLES = initSerializersByName("PARTICLES"); else Serializers$PARTICLES = null; Serializers$ROTATIONS = initSerializersByName("ROTATIONS"); Serializers$BLOCK_POS = initSerializersByName("BLOCK_POS"); Serializers$OPTIONAL_BLOCK_POS = initSerializersByName("OPTIONAL_BLOCK_POS"); Serializers$DIRECTION = initSerializersByName("DIRECTION"); - if (!VersionHelper.isVersionNewerThan1_21_5()) Serializers$OPTIONAL_UUID = initSerializersByName("OPTIONAL_UUID"); + if (!VersionHelper.isOrAbove1_21_5()) Serializers$OPTIONAL_UUID = initSerializersByName("OPTIONAL_UUID"); else Serializers$OPTIONAL_UUID = null; - if (VersionHelper.isVersionNewerThan1_21_5()) Serializers$OPTIONAL_LIVING_ENTITY_REFERENCE = initSerializersByName("OPTIONAL_LIVING_ENTITY_REFERENCE"); + 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"); @@ -76,11 +76,11 @@ public class EntityDataValue { Serializers$OPTIONAL_UNSIGNED_INT = initSerializersByName("OPTIONAL_UNSIGNED_INT"); Serializers$POSE = initSerializersByName("POSE"); Serializers$CAT_VARIANT = initSerializersByName("CAT_VARIANT"); - if (VersionHelper.isVersionNewerThan1_20_5()) Serializers$WOLF_VARIANT = initSerializersByName("WOLF_VARIANT"); + if (VersionHelper.isOrAbove1_20_5()) Serializers$WOLF_VARIANT = initSerializersByName("WOLF_VARIANT"); else Serializers$WOLF_VARIANT = null; Serializers$FROG_VARIANT = initSerializersByName("FROG_VARIANT"); Serializers$PAINTING_VARIANT = initSerializersByName("PAINTING_VARIANT"); - if (VersionHelper.isVersionNewerThan1_20_5()) Serializers$ARMADILLO_STATE = initSerializersByName("ARMADILLO_STATE"); + if (VersionHelper.isOrAbove1_20_5()) Serializers$ARMADILLO_STATE = initSerializersByName("ARMADILLO_STATE"); else Serializers$ARMADILLO_STATE = null; Serializers$SNIFFER_STATE = initSerializersByName("SNIFFER_STATE"); Serializers$VECTOR3 = initSerializersByName("VECTOR3"); diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/entity/data/InteractionEntityData.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/entity/data/InteractionEntityData.java index 9819e3550..250f58909 100644 --- a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/entity/data/InteractionEntityData.java +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/entity/data/InteractionEntityData.java @@ -13,6 +13,6 @@ public class InteractionEntityData extends BaseEntityData { } public InteractionEntityData(int id, Object serializer, T defaultValue) { - super(!VersionHelper.isVersionNewerThan1_20_2() && id >= 11 ? id - 1 : id, serializer, defaultValue); + super(!VersionHelper.isOrAbove1_20_2() && id >= 11 ? id - 1 : id, serializer, defaultValue); } } diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/entity/furniture/BukkitFurnitureManager.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/entity/furniture/BukkitFurnitureManager.java index 510b8346e..29ee90605 100644 --- a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/entity/furniture/BukkitFurnitureManager.java +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/entity/furniture/BukkitFurnitureManager.java @@ -1,7 +1,5 @@ package net.momirealms.craftengine.bukkit.entity.furniture; -import net.momirealms.craftengine.bukkit.compatibility.bettermodel.BetterModelModel; -import net.momirealms.craftengine.bukkit.compatibility.modelengine.ModelEngineModel; import net.momirealms.craftengine.bukkit.entity.furniture.hitbox.InteractionHitBox; import net.momirealms.craftengine.bukkit.nms.CollisionEntity; import net.momirealms.craftengine.bukkit.nms.FastNMS; @@ -60,7 +58,7 @@ public class BukkitFurnitureManager extends AbstractFurnitureManager { this.plugin = plugin; this.furnitureParser = new FurnitureParser(); this.furnitureEventListener = new FurnitureEventListener(this); - this.dismountListener = VersionHelper.isVersionNewerThan1_20_3() ? new DismountListener1_20_3(this) : new DismountListener1_20(this::handleDismount); + this.dismountListener = VersionHelper.isOrAbove1_20_3() ? new DismountListener1_20_3(this) : new DismountListener1_20(this::handleDismount); } @Override @@ -149,9 +147,9 @@ public class BukkitFurnitureManager extends AbstractFurnitureManager { // external model providers Optional externalModel; if (placementArguments.containsKey("model-engine")) { - externalModel = Optional.of(new ModelEngineModel(placementArguments.get("model-engine").toString())); + externalModel = Optional.of(plugin.compatibilityManager().createModelEngineModel(placementArguments.get("model-engine").toString())); } else if (placementArguments.containsKey("better-model")) { - externalModel = Optional.of(new BetterModelModel(placementArguments.get("better-model").toString())); + externalModel = Optional.of(plugin.compatibilityManager().createBetterModelModel(placementArguments.get("better-model").toString())); } else { externalModel = Optional.empty(); } @@ -294,7 +292,7 @@ public class BukkitFurnitureManager extends AbstractFurnitureManager { if (previous != null) return; Location location = display.getLocation(); - boolean above1_20_1 = VersionHelper.isVersionNewerThan1_20_2(); + boolean above1_20_1 = VersionHelper.isOrAbove1_20_2(); boolean preventChange = FastNMS.INSTANCE.isPreventingStatusUpdates(location.getWorld(), location.getBlockX() >> 4, location.getBlockZ() >> 4); if (above1_20_1) { if (!preventChange) { @@ -453,7 +451,11 @@ public class BukkitFurnitureManager extends AbstractFurnitureManager { } targetLocation.setYaw(player.getLocation().getYaw()); targetLocation.setPitch(player.getLocation().getPitch()); - player.teleport(targetLocation); + if (VersionHelper.isFolia()) { + player.teleportAsync(targetLocation); + } else { + player.teleport(targetLocation); + } } protected boolean isSeatCarrierType(Entity entity) { diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/entity/furniture/LoadedFurniture.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/entity/furniture/LoadedFurniture.java index 264fa2b6e..40505ab8d 100644 --- a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/entity/furniture/LoadedFurniture.java +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/entity/furniture/LoadedFurniture.java @@ -297,9 +297,9 @@ public class LoadedFurniture implements Furniture { public void spawnSeatEntityForPlayer(org.bukkit.entity.Player player, Seat seat) { Location location = this.calculateSeatLocation(seat); Entity seatEntity = seat.limitPlayerRotation() ? - EntityUtils.spawnEntity(player.getWorld(), VersionHelper.isVersionNewerThan1_20_2() ? location.subtract(0,0.9875,0) : location.subtract(0,0.990625,0), EntityType.ARMOR_STAND, entity -> { + EntityUtils.spawnEntity(player.getWorld(), VersionHelper.isOrAbove1_20_2() ? location.subtract(0,0.9875,0) : location.subtract(0,0.990625,0), EntityType.ARMOR_STAND, entity -> { ArmorStand armorStand = (ArmorStand) entity; - if (VersionHelper.isVersionNewerThan1_21_3()) { + if (VersionHelper.isOrAbove1_21_3()) { Objects.requireNonNull(armorStand.getAttribute(Attribute.MAX_HEALTH)).setBaseValue(0.01); } else { LegacyAttributeUtils.setMaxHealth(armorStand); @@ -316,7 +316,7 @@ public class LoadedFurniture implements Furniture { armorStand.getPersistentDataContainer().set(BukkitFurnitureManager.FURNITURE_SEAT_BASE_ENTITY_KEY, PersistentDataType.INTEGER, this.baseEntityId()); armorStand.getPersistentDataContainer().set(BukkitFurnitureManager.FURNITURE_SEAT_VECTOR_3F_KEY, PersistentDataType.STRING, seat.offset().x + ", " + seat.offset().y + ", " + seat.offset().z); }) : - EntityUtils.spawnEntity(player.getWorld(), VersionHelper.isVersionNewerThan1_20_2() ? location : location.subtract(0,0.25,0), EntityType.ITEM_DISPLAY, entity -> { + EntityUtils.spawnEntity(player.getWorld(), VersionHelper.isOrAbove1_20_2() ? location : location.subtract(0,0.25,0), EntityType.ITEM_DISPLAY, entity -> { ItemDisplay itemDisplay = (ItemDisplay) entity; itemDisplay.setPersistent(false); itemDisplay.getPersistentDataContainer().set(BukkitFurnitureManager.FURNITURE_SEAT_BASE_ENTITY_KEY, PersistentDataType.INTEGER, this.baseEntityId()); diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/entity/furniture/hitbox/CustomHitBox.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/entity/furniture/hitbox/CustomHitBox.java index 08126740d..9b00dc4fc 100644 --- a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/entity/furniture/hitbox/CustomHitBox.java +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/entity/furniture/hitbox/CustomHitBox.java @@ -57,7 +57,7 @@ public class CustomHitBox extends AbstractHitBox { FastNMS.INSTANCE.toNMSEntityType(this.entityType), 0, Reflections.instance$Vec3$Zero, 0 ), true); packets.accept(FastNMS.INSTANCE.constructor$ClientboundSetEntityDataPacket(entityId[0], List.copyOf(this.cachedValues)), true); - if (VersionHelper.isVersionNewerThan1_20_5() && this.scale != 1) { + if (VersionHelper.isOrAbove1_20_5() && this.scale != 1) { Object attributeInstance = Reflections.constructor$AttributeInstance.newInstance(Reflections.instance$Holder$Attribute$scale, (Consumer) (o) -> {}); Reflections.method$AttributeInstance$setBaseValue.invoke(attributeInstance, this.scale); packets.accept(Reflections.constructor$ClientboundUpdateAttributesPacket0.newInstance(entityId[0], Collections.singletonList(attributeInstance)), false); diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/entity/furniture/hitbox/ShulkerHitBox.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/entity/furniture/hitbox/ShulkerHitBox.java index 130a9bd36..0dd717463 100644 --- a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/entity/furniture/hitbox/ShulkerHitBox.java +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/entity/furniture/hitbox/ShulkerHitBox.java @@ -223,7 +223,7 @@ public class ShulkerHitBox extends AbstractHitBox { ), false); } // set shulker scale - if (VersionHelper.isVersionNewerThan1_20_5() && this.scale != 1) { + if (VersionHelper.isOrAbove1_20_5() && this.scale != 1) { Object attributeInstance = Reflections.constructor$AttributeInstance.newInstance(Reflections.instance$Holder$Attribute$scale, (Consumer) (o) -> {}); Reflections.method$AttributeInstance$setBaseValue.invoke(attributeInstance, this.scale); packets.accept(Reflections.constructor$ClientboundUpdateAttributesPacket0.newInstance(entityIds[1], Collections.singletonList(attributeInstance)), false); diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/font/BukkitFontManager.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/font/BukkitFontManager.java index 1e9a23fcf..c0b332ec6 100644 --- a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/font/BukkitFontManager.java +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/font/BukkitFontManager.java @@ -5,7 +5,6 @@ import com.google.gson.JsonObject; import io.papermc.paper.event.player.AsyncChatCommandDecorateEvent; import io.papermc.paper.event.player.AsyncChatDecorateEvent; import net.kyori.adventure.text.Component; -import net.momirealms.craftengine.bukkit.compatibility.permission.LuckPermsEventListeners; import net.momirealms.craftengine.bukkit.plugin.BukkitCraftEngine; import net.momirealms.craftengine.bukkit.util.ComponentUtils; import net.momirealms.craftengine.bukkit.util.LegacyInventoryUtils; @@ -35,7 +34,6 @@ import java.util.*; public class BukkitFontManager extends AbstractFontManager implements Listener { private final BukkitCraftEngine plugin; - private LuckPermsEventListeners luckPermsEventListeners; public BukkitFontManager(BukkitCraftEngine plugin) { super(plugin); @@ -44,9 +42,6 @@ public class BukkitFontManager extends AbstractFontManager implements Listener { @Override public void delayedInit() { - if (this.plugin.isPluginEnabled("LuckPerms")) { - luckPermsEventListeners = new LuckPermsEventListeners(plugin.bootstrap(), this::refreshEmojiSuggestions); - } Bukkit.getPluginManager().registerEvents(this, plugin.bootstrap()); } @@ -54,9 +49,6 @@ public class BukkitFontManager extends AbstractFontManager implements Listener { public void disable() { super.disable(); HandlerList.unregisterAll(this); - if (luckPermsEventListeners != null && this.plugin.isPluginEnabled("LuckPerms")) { - luckPermsEventListeners.unregisterListeners(); - } } @Override @@ -76,7 +68,8 @@ public class BukkitFontManager extends AbstractFontManager implements Listener { plugin.scheduler().async().execute(() -> this.addEmojiSuggestions(event.getPlayer(), getEmojiSuggestion(event.getPlayer()))); } - private void refreshEmojiSuggestions(UUID uuid) { + @Override + public void refreshEmojiSuggestions(UUID uuid) { Player player = Bukkit.getPlayer(uuid); if (player == null) return; removeEmojiSuggestions(player); @@ -138,14 +131,14 @@ public class BukkitFontManager extends AbstractFontManager implements Listener { if (result == null) return; Player player; try { - player = (Player) Reflections.method$InventoryView$getPlayer.invoke(VersionHelper.isVersionNewerThan1_21() ? event.getView() : LegacyInventoryUtils.getView(event)); + player = (Player) Reflections.method$InventoryView$getPlayer.invoke(VersionHelper.isOrAbove1_21() ? event.getView() : LegacyInventoryUtils.getView(event)); } catch (ReflectiveOperationException e) { this.plugin.logger().warn("Failed to get inventory viewer", e); return; } String renameText; - if (VersionHelper.isVersionNewerThan1_21_2()) { + if (VersionHelper.isOrAbove1_21_2()) { AnvilView anvilView = event.getView(); renameText = anvilView.getRenameText(); } else { diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/item/BukkitItemManager.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/item/BukkitItemManager.java index 10d34de44..01ccba6fe 100644 --- a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/item/BukkitItemManager.java +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/item/BukkitItemManager.java @@ -1,7 +1,5 @@ package net.momirealms.craftengine.bukkit.item; -import net.momirealms.craftengine.bukkit.compatibility.item.MMOItemsProvider; -import net.momirealms.craftengine.bukkit.compatibility.item.NeigeItemsProvider; import net.momirealms.craftengine.bukkit.item.behavior.AxeItemBehavior; import net.momirealms.craftengine.bukkit.item.behavior.BoneMealItemBehavior; import net.momirealms.craftengine.bukkit.item.behavior.BucketItemBehavior; @@ -131,16 +129,6 @@ public class BukkitItemManager extends AbstractItemManager { public void delayedInit() { Bukkit.getPluginManager().registerEvents(this.itemEventListener, this.plugin.bootstrap()); Bukkit.getPluginManager().registerEvents(this.debugStickListener, this.plugin.bootstrap()); - this.hookExternalPlugins(); - } - - private void hookExternalPlugins() { - if (this.plugin.isPluginEnabled("NeigeItems")) { - registerExternalItemProvider(new NeigeItemsProvider()); - } - if (this.plugin.isPluginEnabled("MMOItems")) { - registerExternalItemProvider(new MMOItemsProvider()); - } } public static BukkitItemManager instance() { @@ -289,7 +277,7 @@ public class BukkitItemManager extends AbstractItemManager { itemBuilder.dataModifier(new CustomModelDataModifier<>(customModelData)); } // Requires the item to have model before apply item-model - else if (!hasItemModelSection && section.containsKey("model") && VersionHelper.isVersionNewerThan1_21_2()) { + else if (!hasItemModelSection && section.containsKey("model") && VersionHelper.isOrAbove1_21_2()) { // check server version here because components require 1.21.2+ // customize or use the id itemModelKey = Key.from(section.getOrDefault("item-model", id.toString()).toString()); diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/item/ComponentItemWrapper.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/item/ComponentItemWrapper.java index 136dcd6d8..75f692f57 100644 --- a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/item/ComponentItemWrapper.java +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/item/ComponentItemWrapper.java @@ -22,6 +22,10 @@ public class ComponentItemWrapper implements ItemWrapper { this.item.setAmount(count); } + public void removeComponent(Object type) { + FastNMS.INSTANCE.removeComponent(this.getLiteralObject(), ensureDataComponentType(type)); + } + public void resetComponent(Object type) { FastNMS.INSTANCE.resetComponent(this.getLiteralObject(), ensureDataComponentType(type)); } diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/item/ComponentTypes.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/item/ComponentTypes.java index 30bb289e1..904cac448 100644 --- a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/item/ComponentTypes.java +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/item/ComponentTypes.java @@ -29,7 +29,7 @@ public class ComponentTypes { private ComponentTypes() {} private static Object getComponentType(Key key) { - if (!VersionHelper.isVersionNewerThan1_20_5()) return null; + if (!VersionHelper.isOrAbove1_20_5()) return null; return FastNMS.INSTANCE.getComponentType(key.namespace(), key.value()); } } diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/item/ItemEventListener.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/item/ItemEventListener.java index 27319d9ba..a23cf371a 100644 --- a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/item/ItemEventListener.java +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/item/ItemEventListener.java @@ -70,7 +70,8 @@ public class ItemEventListener implements Listener { block, event.getBlockFace(), event.getHand() == EquipmentSlot.HAND ? InteractionHand.MAIN_HAND : InteractionHand.OFF_HAND, - action.isRightClick() ? CustomBlockInteractEvent.Action.RIGHT_CLICK : CustomBlockInteractEvent.Action.LEFT_CLICK + action.isRightClick() ? CustomBlockInteractEvent.Action.RIGHT_CLICK : CustomBlockInteractEvent.Action.LEFT_CLICK, + event.getItem() ); if (EventUtils.fireAndCheckCancel(interactEvent)) { event.setCancelled(true); diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/item/behavior/AxeItemBehavior.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/item/behavior/AxeItemBehavior.java index 5b85ac0fc..47b466610 100644 --- a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/item/behavior/AxeItemBehavior.java +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/item/behavior/AxeItemBehavior.java @@ -96,7 +96,7 @@ public class AxeItemBehavior extends ItemBehavior { player.swingHand(context.getHand()); } // shrink item amount - if (VersionHelper.isVersionNewerThan1_20_5()) { + if (VersionHelper.isOrAbove1_20_5()) { Object itemStack = item.getLiteralObject(); Object serverPlayer = player.serverPlayer(); Object equipmentSlot = context.getHand() == InteractionHand.MAIN_HAND ? Reflections.instance$EquipmentSlot$MAINHAND : Reflections.instance$EquipmentSlot$OFFHAND; diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/item/factory/ComponentItemFactory1_20_5.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/item/factory/ComponentItemFactory1_20_5.java index 205ec55a3..08cc98ec3 100644 --- a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/item/factory/ComponentItemFactory1_20_5.java +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/item/factory/ComponentItemFactory1_20_5.java @@ -93,7 +93,7 @@ public class ComponentItemFactory1_20_5 extends BukkitItemFactory { MIXED_RECIPE_CONVERTORS.put(RecipeTypes.SMITHING_TRANSFORM, (BukkitRecipeConvertor>) (id, recipe) -> { try { Object nmsRecipe = createMinecraftSmithingTransformRecipe(recipe); - if (VersionHelper.isVersionNewerThan1_21_2()) { + if (VersionHelper.isOrAbove1_21_2()) { nmsRecipe = Reflections.constructor$RecipeHolder.newInstance( Reflections.method$CraftRecipe$toMinecraft.invoke(null, new NamespacedKey(id.namespace(), id.value())), nmsRecipe); - } else if (VersionHelper.isVersionNewerThan1_20_2()) { + } else if (VersionHelper.isOrAbove1_20_2()) { nmsRecipe = Reflections.constructor$RecipeHolder.newInstance(KeyUtils.toResourceLocation(id), nmsRecipe); } else { return () -> {}; @@ -255,7 +255,7 @@ public class BukkitRecipeManager extends AbstractRecipeManager { instance = this; this.plugin = plugin; this.recipeEventListener = new RecipeEventListener(plugin, this, plugin.itemManager()); - this.crafterEventListener = VersionHelper.isVersionNewerThan1_21() ? new CrafterEventListener(plugin, this, plugin.itemManager()) : null; + this.crafterEventListener = VersionHelper.isOrAbove1_21() ? new CrafterEventListener(plugin, this, plugin.itemManager()) : null; try { nmsRecipeManager = Reflections.method$MinecraftServer$getRecipeManager.invoke(Reflections.method$MinecraftServer$getServer.invoke(null)); } catch (ReflectiveOperationException e) { @@ -286,7 +286,7 @@ public class BukkitRecipeManager extends AbstractRecipeManager { @Override public void load() { if (!Config.enableRecipeSystem()) return; - if (VersionHelper.isVersionNewerThan1_21_2()) { + if (VersionHelper.isOrAbove1_21_2()) { try { this.stolenFeatureFlagSet = Reflections.field$RecipeManager$featureflagset.get(nmsRecipeManager); Reflections.field$RecipeManager$featureflagset.set(nmsRecipeManager, null); @@ -301,7 +301,7 @@ public class BukkitRecipeManager extends AbstractRecipeManager { if (!Config.enableRecipeSystem()) return; super.unload(); try { - if (VersionHelper.isVersionNewerThan1_21_2()) { + if (VersionHelper.isOrAbove1_21_2()) { Reflections.method$RecipeManager$finalizeRecipeLoading.invoke(nmsRecipeManager); } } catch (ReflectiveOperationException e) { @@ -349,7 +349,7 @@ public class BukkitRecipeManager extends AbstractRecipeManager { private void unregisterNMSRecipe(NamespacedKey key) { try { - if (VersionHelper.isVersionNewerThan1_21_2()) { + if (VersionHelper.isOrAbove1_21_2()) { Object recipeMap = Reflections.field$RecipeManager$recipes.get(nmsRecipeManager); Reflections.method$RecipeMap$removeRecipe.invoke(recipeMap, Reflections.method$CraftRecipe$toMinecraft.invoke(null, key)); } else { @@ -363,7 +363,7 @@ public class BukkitRecipeManager extends AbstractRecipeManager { @SuppressWarnings("unchecked") private void injectDataPackRecipes() { try { - Object fileToIdConverter = Reflections.method$FileToIdConverter$json.invoke(null, VersionHelper.isVersionNewerThan1_21() ? "recipe" : "recipes"); + Object fileToIdConverter = Reflections.method$FileToIdConverter$json.invoke(null, VersionHelper.isOrAbove1_21() ? "recipe" : "recipes"); Object minecraftServer = Reflections.method$MinecraftServer$getServer.invoke(null); Object packRepository = Reflections.method$MinecraftServer$getPackRepository.invoke(minecraftServer); List selected = (List) Reflections.field$PackRepository$selected.get(packRepository); @@ -446,13 +446,13 @@ public class BukkitRecipeManager extends AbstractRecipeManager { this.delayedTasksOnMainThread.clear(); // give flags back on 1.21.2+ - if (VersionHelper.isVersionNewerThan1_21_2() && this.stolenFeatureFlagSet != null) { + if (VersionHelper.isOrAbove1_21_2() && this.stolenFeatureFlagSet != null) { Reflections.field$RecipeManager$featureflagset.set(nmsRecipeManager(), this.stolenFeatureFlagSet); this.stolenFeatureFlagSet = null; } // refresh recipes - if (VersionHelper.isVersionNewerThan1_21_2()) { + if (VersionHelper.isOrAbove1_21_2()) { Reflections.method$RecipeManager$finalizeRecipeLoading.invoke(nmsRecipeManager()); } @@ -460,11 +460,11 @@ public class BukkitRecipeManager extends AbstractRecipeManager { Reflections.method$DedicatedPlayerList$reloadRecipes.invoke(Reflections.field$CraftServer$playerList.get(Bukkit.getServer())); // now we need to remove the fake `exact` - if (VersionHelper.isVersionNewerThan1_21_4()) { + if (VersionHelper.isOrAbove1_21_4()) { for (Object ingredient : injectedIngredients) { Reflections.field$Ingredient$itemStacks1_21_4.set(ingredient, null); } - } else if (VersionHelper.isVersionNewerThan1_21_2()) { + } else if (VersionHelper.isOrAbove1_21_2()) { for (Object ingredient : injectedIngredients) { Reflections.field$Ingredient$itemStacks1_21_2.set(ingredient, null); } @@ -711,11 +711,11 @@ public class BukkitRecipeManager extends AbstractRecipeManager { Object shapedRecipe = getNMSRecipe(id); recipeToMcRecipeHolder.put(recipe, shapedRecipe); - if (VersionHelper.isVersionNewerThan1_20_2()) { + if (VersionHelper.isOrAbove1_20_2()) { shapedRecipe = Reflections.field$RecipeHolder$recipe.get(shapedRecipe); } - if (VersionHelper.isVersionNewerThan1_21_2()) { + if (VersionHelper.isOrAbove1_21_2()) { Reflections.field$ShapedRecipe$placementInfo.set(shapedRecipe, null); } @@ -732,11 +732,11 @@ public class BukkitRecipeManager extends AbstractRecipeManager { Object shapelessRecipe = getNMSRecipe(id); recipeToMcRecipeHolder.put(recipe, shapelessRecipe); - if (VersionHelper.isVersionNewerThan1_20_2()) { + if (VersionHelper.isOrAbove1_20_2()) { shapelessRecipe = Reflections.field$RecipeHolder$recipe.get(shapelessRecipe); } - if (VersionHelper.isVersionNewerThan1_21_2()) { + if (VersionHelper.isOrAbove1_21_2()) { Reflections.field$ShapelessRecipe$placementInfo.set(shapelessRecipe, null); } @SuppressWarnings("unchecked") @@ -752,12 +752,12 @@ public class BukkitRecipeManager extends AbstractRecipeManager { Ingredient actualIngredient = recipe.ingredient(); Object smeltingRecipe = getNMSRecipe(id); recipeToMcRecipeHolder.put(recipe, smeltingRecipe); - if (VersionHelper.isVersionNewerThan1_20_2()) { + if (VersionHelper.isOrAbove1_20_2()) { smeltingRecipe = Reflections.field$RecipeHolder$recipe.get(smeltingRecipe); } Object ingredient; - if (VersionHelper.isVersionNewerThan1_21_2()) { + if (VersionHelper.isOrAbove1_21_2()) { ingredient = Reflections.field$SingleItemRecipe$input.get(smeltingRecipe); } else { ingredient = Reflections.field$AbstractCookingRecipe$input.get(smeltingRecipe); @@ -771,7 +771,7 @@ public class BukkitRecipeManager extends AbstractRecipeManager { // 获取nms配方,请注意1.20.1获取配方本身,而1.20.2+获取的是配方的holder // recipe on 1.20.1 and holder on 1.20.2+ private static Object getNMSRecipe(Key id) throws ReflectiveOperationException { - if (VersionHelper.isVersionNewerThan1_21_2()) { + if (VersionHelper.isOrAbove1_21_2()) { Object resourceKey = Reflections.method$CraftRecipe$toMinecraft.invoke(null, new NamespacedKey(id.namespace(), id.value())); @SuppressWarnings("unchecked") Optional optional = (Optional) Reflections.method$RecipeManager$byKey.invoke(nmsRecipeManager, resourceKey); @@ -800,9 +800,9 @@ public class BukkitRecipeManager extends AbstractRecipeManager { Object ingredient = fakeIngredients.get(i); Ingredient actualIngredient = actualIngredients.get(i); List items = getIngredientLooks(actualIngredient.items()); - if (VersionHelper.isVersionNewerThan1_21_4()) { + if (VersionHelper.isOrAbove1_21_4()) { Reflections.field$Ingredient$itemStacks1_21_4.set(ingredient, new HashSet<>(items)); - } else if (VersionHelper.isVersionNewerThan1_21_2()) { + } else if (VersionHelper.isOrAbove1_21_2()) { Reflections.field$Ingredient$itemStacks1_21_2.set(ingredient, items); } else { Object itemStackArray = Array.newInstance(Reflections.clazz$ItemStack, items.size()); @@ -845,21 +845,21 @@ public class BukkitRecipeManager extends AbstractRecipeManager { // create nms smithing recipe for different versions private static Object createMinecraftSmithingTransformRecipe(CustomSmithingTransformRecipe recipe) throws ReflectiveOperationException { - if (VersionHelper.isVersionNewerThan1_21_5()) { + if (VersionHelper.isOrAbove1_21_5()) { return Reflections.constructor$SmithingTransformRecipe.newInstance( toOptionalMinecraftIngredient(recipe.template()), toMinecraftIngredient(recipe.base()), toOptionalMinecraftIngredient(recipe.addition()), toTransmuteResult(recipe.result(ItemBuildContext.EMPTY)) ); - } else if (VersionHelper.isVersionNewerThan1_21_2()) { + } else if (VersionHelper.isOrAbove1_21_2()) { return Reflections.constructor$SmithingTransformRecipe.newInstance( toOptionalMinecraftIngredient(recipe.template()), toOptionalMinecraftIngredient(recipe.base()), toOptionalMinecraftIngredient(recipe.addition()), FastNMS.INSTANCE.method$CraftItemStack$asNMSCopy(recipe.result(ItemBuildContext.EMPTY)) ); - } else if (VersionHelper.isVersionNewerThan1_20_2()) { + } else if (VersionHelper.isOrAbove1_20_2()) { return Reflections.constructor$SmithingTransformRecipe.newInstance( toMinecraftIngredient(recipe.template()), toMinecraftIngredient(recipe.base()), diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/item/recipe/RecipeEventListener.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/item/recipe/RecipeEventListener.java index 937eefbdb..7bc3042f3 100644 --- a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/item/recipe/RecipeEventListener.java +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/item/recipe/RecipeEventListener.java @@ -279,7 +279,7 @@ public class RecipeEventListener implements Listener { @EventHandler(ignoreCancelled = true) public void onBlockIgnite(BlockIgniteEvent event) { if (!Config.enableRecipeSystem()) return; - if (VersionHelper.isVersionNewerThan1_21_2()) return; + if (VersionHelper.isOrAbove1_21_2()) return; Block block = event.getBlock(); Material material = block.getType(); if (material == Material.CAMPFIRE) { @@ -308,7 +308,7 @@ public class RecipeEventListener implements Listener { plugin.logger().warn("Failed to inject cooking block entity", e); } } - } else if (!VersionHelper.isVersionNewerThan1_21_2() && material == Material.CAMPFIRE) { + } else if (!VersionHelper.isOrAbove1_21_2() && material == Material.CAMPFIRE) { if (block.getState() instanceof Campfire campfire) { try { Object blockEntity = Reflections.field$CraftBlockEntityState$tileEntity.get(campfire); @@ -324,13 +324,13 @@ public class RecipeEventListener implements Listener { @EventHandler(ignoreCancelled = true) public void onPutItemOnCampfire(PlayerInteractEvent event) { if (!Config.enableRecipeSystem()) return; - if (!VersionHelper.isVersionNewerThan1_21_2()) return; + if (!VersionHelper.isOrAbove1_21_2()) return; if (event.getAction() != Action.RIGHT_CLICK_BLOCK) return; Block clicked = event.getClickedBlock(); if (clicked == null) return; Material type = clicked.getType(); if (type != Material.CAMPFIRE && type != Material.SOUL_CAMPFIRE) return; - if (!VersionHelper.isVersionNewerThan1_21_2()) { + if (!VersionHelper.isOrAbove1_21_2()) { if (clicked.getState() instanceof Campfire campfire) { try { Object blockEntity = Reflections.field$CraftBlockEntityState$tileEntity.get(campfire); @@ -375,7 +375,7 @@ public class RecipeEventListener implements Listener { @EventHandler(ignoreCancelled = true) public void onCampfireCook(CampfireStartEvent event) { if (!Config.enableRecipeSystem()) return; - if (!VersionHelper.isVersionNewerThan1_21_2()) return; + if (!VersionHelper.isOrAbove1_21_2()) return; CampfireRecipe recipe = event.getRecipe(); Key recipeId = new Key(recipe.getKey().namespace(), recipe.getKey().value()); @@ -406,7 +406,7 @@ public class RecipeEventListener implements Listener { @EventHandler(ignoreCancelled = true) public void onCampfireCook(BlockCookEvent event) { if (!Config.enableRecipeSystem()) return; - if (!VersionHelper.isVersionNewerThan1_21_2()) return; + if (!VersionHelper.isOrAbove1_21_2()) return; Material type = event.getBlock().getType(); if (type != Material.CAMPFIRE && type != Material.SOUL_CAMPFIRE) return; CampfireRecipe recipe = (CampfireRecipe) event.getRecipe(); @@ -563,7 +563,7 @@ public class RecipeEventListener implements Listener { String renameText; int maxRepairCost; //int previousCost; - if (VersionHelper.isVersionNewerThan1_21_2()) { + if (VersionHelper.isOrAbove1_21_2()) { AnvilView anvilView = event.getView(); renameText = anvilView.getRenameText(); maxRepairCost = anvilView.getMaximumRepairCost(); @@ -588,10 +588,10 @@ public class RecipeEventListener implements Listener { } catch (ReflectiveOperationException e) { plugin.logger().warn("Failed to get hover name", e); } - } else if (VersionHelper.isVersionNewerThan1_20_5() && wrappedFirst.hasComponent(ComponentTypes.CUSTOM_NAME)) { + } else if (VersionHelper.isOrAbove1_20_5() && wrappedFirst.hasComponent(ComponentTypes.CUSTOM_NAME)) { repairCost += 1; wrappedFirst.customName(null); - } else if (!VersionHelper.isVersionNewerThan1_20_5() && wrappedFirst.hasTag("display", "Name")) { + } else if (!VersionHelper.isOrAbove1_20_5() && wrappedFirst.hasTag("display", "Name")) { repairCost += 1; wrappedFirst.customName(null); } @@ -601,7 +601,7 @@ public class RecipeEventListener implements Listener { // To fix some client side visual issues try { Object anvilMenu; - if (VersionHelper.isVersionNewerThan1_21()) { + if (VersionHelper.isOrAbove1_21()) { anvilMenu = Reflections.field$CraftInventoryView$container.get(event.getView()); } else { anvilMenu = Reflections.field$CraftInventoryAnvil$menu.get(inventory); @@ -611,7 +611,7 @@ public class RecipeEventListener implements Listener { this.plugin.logger().warn("Failed to broadcast changes", e); } - if (VersionHelper.isVersionNewerThan1_21()) { + if (VersionHelper.isOrAbove1_21()) { AnvilView anvilView = event.getView(); anvilView.setRepairCost(finalCost); anvilView.setRepairItemCountCost(actualConsumedAmount); @@ -622,7 +622,7 @@ public class RecipeEventListener implements Listener { Player player; try { - player = (Player) Reflections.method$InventoryView$getPlayer.invoke(VersionHelper.isVersionNewerThan1_21() ? event.getView() : LegacyInventoryUtils.getView(event)); + player = (Player) Reflections.method$InventoryView$getPlayer.invoke(VersionHelper.isOrAbove1_21() ? event.getView() : LegacyInventoryUtils.getView(event)); } catch (ReflectiveOperationException e) { plugin.logger().warn("Failed to get inventory viewer", e); return; @@ -659,7 +659,7 @@ public class RecipeEventListener implements Listener { wrappedFirst.getCustomItem().ifPresent(item -> { if (!item.settings().renameable()) { String renameText; - if (VersionHelper.isVersionNewerThan1_21_2()) { + if (VersionHelper.isOrAbove1_21_2()) { AnvilView anvilView = event.getView(); renameText = anvilView.getRenameText(); } else { diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/loot/BukkitVanillaLootManager.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/loot/BukkitVanillaLootManager.java index 6a36cca25..ef2800849 100644 --- a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/loot/BukkitVanillaLootManager.java +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/loot/BukkitVanillaLootManager.java @@ -72,7 +72,7 @@ public class BukkitVanillaLootManager extends AbstractVanillaLootManager impleme ContextHolder.Builder builder = ContextHolder.builder(); builder.withParameter(LootParameters.WORLD, world); builder.withParameter(LootParameters.LOCATION, vec3d); - if (VersionHelper.isVersionNewerThan1_20_5()) { + if (VersionHelper.isOrAbove1_20_5()) { if (event.getDamageSource().getCausingEntity() instanceof Player player) { BukkitServerPlayer serverPlayer = this.plugin.adapt(player); builder.withParameter(LootParameters.PLAYER, serverPlayer); diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/pack/BukkitPackManager.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/pack/BukkitPackManager.java index 1f93103ca..918953dee 100644 --- a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/pack/BukkitPackManager.java +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/pack/BukkitPackManager.java @@ -21,7 +21,6 @@ import org.bukkit.event.EventPriority; import org.bukkit.event.HandlerList; import org.bukkit.event.Listener; import org.bukkit.event.player.PlayerJoinEvent; -import org.bukkit.event.player.PlayerResourcePackStatusEvent; import java.util.ArrayList; import java.util.List; @@ -49,27 +48,17 @@ public class BukkitPackManager extends AbstractPackManager implements Listener { @EventHandler(priority = EventPriority.LOW) public void onPlayerJoin(PlayerJoinEvent event) { - if (Config.sendPackOnJoin() && !VersionHelper.isVersionNewerThan1_20_2()) { + if (Config.sendPackOnJoin() && !VersionHelper.isOrAbove1_20_2()) { Player player = plugin.adapt(event.getPlayer()); this.sendResourcePack(player); } } - @EventHandler(priority = EventPriority.LOW) - public void onResourcePackStatus(PlayerResourcePackStatusEvent event) { - // for 1.20.1 servers, not recommended to use - if (Config.sendPackOnJoin() && Config.kickOnDeclined() && !VersionHelper.isVersionNewerThan1_20_2()) { - if (event.getStatus() == PlayerResourcePackStatusEvent.Status.DECLINED || event.getStatus() == PlayerResourcePackStatusEvent.Status.FAILED_DOWNLOAD) { - event.getPlayer().kick(); - } - } - } - @Override public void load() { if (ReloadCommand.RELOAD_PACK_FLAG || CraftEngine.instance().isInitializing()) { super.load(); - if (Config.sendPackOnJoin() && VersionHelper.isVersionNewerThan1_20_2() && !(resourcePackHost() instanceof NoneHost)) { + if (Config.sendPackOnJoin() && VersionHelper.isOrAbove1_20_2() && !(resourcePackHost() instanceof NoneHost)) { this.modifyServerSettings(); } } @@ -80,7 +69,7 @@ public class BukkitPackManager extends AbstractPackManager implements Listener { Object settings = Reflections.field$DedicatedServer$settings.get(Reflections.method$MinecraftServer$getServer.invoke(null)); Object properties = Reflections.field$DedicatedServerSettings$properties.get(settings); Object info; - if (VersionHelper.isVersionNewerThan1_20_3()) { + if (VersionHelper.isOrAbove1_20_3()) { info = Reflections.constructor$ServerResourcePackInfo.newInstance(new UUID(0, 0), FAKE_URL, "", Config.kickOnDeclined(), ComponentUtils.adventureToMinecraft(Config.resourcePackPrompt())); } else { info = Reflections.constructor$ServerResourcePackInfo.newInstance(FAKE_URL, "", Config.kickOnDeclined(), ComponentUtils.adventureToMinecraft(Config.resourcePackPrompt())); @@ -95,7 +84,7 @@ public class BukkitPackManager extends AbstractPackManager implements Listener { public void unload() { super.unload(); if (ReloadCommand.RELOAD_PACK_FLAG) { - if (VersionHelper.isVersionNewerThan1_20_2()) { + if (VersionHelper.isOrAbove1_20_2()) { this.resetServerSettings(); } } diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/BukkitCraftEngine.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/BukkitCraftEngine.java index 6c8d8ff1b..d6741da96 100644 --- a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/BukkitCraftEngine.java +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/BukkitCraftEngine.java @@ -5,7 +5,6 @@ import net.momirealms.craftengine.bukkit.advancement.BukkitAdvancementManager; import net.momirealms.craftengine.bukkit.api.event.CraftEngineReloadEvent; import net.momirealms.craftengine.bukkit.block.BukkitBlockManager; import net.momirealms.craftengine.bukkit.block.behavior.BukkitBlockBehaviors; -import net.momirealms.craftengine.bukkit.compatibility.papi.PlaceholderAPIUtils; import net.momirealms.craftengine.bukkit.entity.furniture.BukkitFurnitureManager; import net.momirealms.craftengine.bukkit.entity.furniture.hitbox.BukkitHitBoxTypes; import net.momirealms.craftengine.bukkit.font.BukkitFontManager; @@ -25,8 +24,8 @@ import net.momirealms.craftengine.bukkit.sound.BukkitSoundManager; import net.momirealms.craftengine.bukkit.util.EventUtils; import net.momirealms.craftengine.bukkit.util.Reflections; import net.momirealms.craftengine.bukkit.world.BukkitWorldManager; -import net.momirealms.craftengine.core.entity.player.Player; import net.momirealms.craftengine.core.item.ItemManager; +import net.momirealms.craftengine.core.plugin.CompatibilityManager; import net.momirealms.craftengine.core.plugin.CraftEngine; import net.momirealms.craftengine.core.plugin.classpath.ReflectionClassPathAppender; import net.momirealms.craftengine.core.plugin.command.sender.SenderFactory; @@ -51,10 +50,12 @@ import java.io.*; import java.lang.reflect.Field; import java.nio.file.Path; import java.util.List; +import java.util.Objects; import java.util.Optional; @SuppressWarnings("unchecked") public class BukkitCraftEngine extends CraftEngine { + private static final String COMPATIBILITY_CLASS = "net.momirealms.craftengine.bukkit.compatibility.BukkitCompatibilityManager"; private static BukkitCraftEngine instance; private final JavaPlugin bootstrap; private SchedulerTask tickTask; @@ -63,7 +64,6 @@ public class BukkitCraftEngine extends CraftEngine { private boolean requiresRestart = false; private boolean hasMod = false; private AntiGriefLib antiGrief; - private boolean hasPlaceholderAPI; public BukkitCraftEngine(JavaPlugin bootstrap) { super((p) -> { @@ -85,6 +85,12 @@ public class BukkitCraftEngine extends CraftEngine { } catch (Exception ignore) { } } + Class compatibilityClass = Objects.requireNonNull(ReflectionUtils.getClazz(COMPATIBILITY_CLASS), "Compatibility class not found"); + try { + super.compatibilityManager = (CompatibilityManager) Objects.requireNonNull(ReflectionUtils.getConstructor(compatibilityClass, 0)).newInstance(this); + } catch (ReflectiveOperationException e) { + logger().warn("Compatibility class could not be instantiated: " + compatibilityClass.getName()); + } } @Override @@ -96,6 +102,7 @@ public class BukkitCraftEngine extends CraftEngine { super.blockManager = new BukkitBlockManager(this); super.furnitureManager = new BukkitFurnitureManager(this); this.successfullyLoaded = true; + super.compatibilityManager().onLoad(); } @Override @@ -159,12 +166,7 @@ public class BukkitCraftEngine extends CraftEngine { super.fontManager = new BukkitFontManager(this); super.advancementManager = new BukkitAdvancementManager(this); super.onPluginEnable(); - // compatibility - // register expansion - if (this.isPluginEnabled("PlaceholderAPI")) { - PlaceholderAPIUtils.registerExpansions(this); - this.hasPlaceholderAPI = true; - } + super.compatibilityManager().onEnable(); } @Override @@ -204,6 +206,7 @@ public class BukkitCraftEngine extends CraftEngine { } }, 1, 1); } + super.compatibilityManager().onDelayedEnable(); } @Override @@ -270,21 +273,6 @@ public class BukkitCraftEngine extends CraftEngine { return instance; } - @Override - public boolean hasPlaceholderAPI() { - return this.hasPlaceholderAPI; - } - - @Override - public boolean isPluginEnabled(String plugin) { - return Bukkit.getPluginManager().isPluginEnabled(plugin); - } - - @Override - public String parse(Player player, String text) { - return PlaceholderAPIUtils.parse((org.bukkit.entity.Player) player.platformPlayer(), text); - } - @Override public BukkitNetworkManager networkManager() { return (BukkitNetworkManager) networkManager; diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/gui/BukkitGuiManager.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/gui/BukkitGuiManager.java index 8358b965b..2b6d78874 100644 --- a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/gui/BukkitGuiManager.java +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/gui/BukkitGuiManager.java @@ -43,7 +43,7 @@ public class BukkitGuiManager implements GuiManager, Listener { if (VersionHelper.isFolia()) { for (Player player : Bukkit.getOnlinePlayers()) { this.plugin.scheduler().sync().run(() -> { - org.bukkit.inventory.Inventory top = !VersionHelper.isVersionNewerThan1_21() ? LegacyInventoryUtils.getTopInventory(player) : player.getOpenInventory().getTopInventory(); + org.bukkit.inventory.Inventory top = !VersionHelper.isOrAbove1_21() ? LegacyInventoryUtils.getTopInventory(player) : player.getOpenInventory().getTopInventory(); if (top.getHolder() instanceof CraftEngineInventoryHolder holder) { holder.gui().onTimer(); } @@ -51,7 +51,7 @@ public class BukkitGuiManager implements GuiManager, Listener { } } else { for (Player player : Bukkit.getOnlinePlayers()) { - org.bukkit.inventory.Inventory top = !VersionHelper.isVersionNewerThan1_21() ? LegacyInventoryUtils.getTopInventory(player) : player.getOpenInventory().getTopInventory(); + org.bukkit.inventory.Inventory top = !VersionHelper.isOrAbove1_21() ? LegacyInventoryUtils.getTopInventory(player) : player.getOpenInventory().getTopInventory(); if (top.getHolder() instanceof CraftEngineInventoryHolder holder) { holder.gui().onTimer(); } diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/injector/BukkitInjector.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/injector/BukkitInjector.java index 2386ea39b..1b9b0bbf3 100644 --- a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/injector/BukkitInjector.java +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/injector/BukkitInjector.java @@ -318,11 +318,11 @@ public class BukkitInjector { .intercept(FieldAccessor.ofField("lastCustomRecipe")) .method(ElementMatchers.named("getRecipeFor").or(ElementMatchers.named("a"))) .intercept(MethodDelegation.to( - VersionHelper.isVersionNewerThan1_21_2() ? + VersionHelper.isOrAbove1_21_2() ? GetRecipeForMethodInterceptor1_21_2.INSTANCE : - (VersionHelper.isVersionNewerThan1_21() ? + (VersionHelper.isOrAbove1_21() ? GetRecipeForMethodInterceptor1_21.INSTANCE : - VersionHelper.isVersionNewerThan1_20_5() ? + VersionHelper.isOrAbove1_20_5() ? GetRecipeForMethodInterceptor1_20_5.INSTANCE : GetRecipeForMethodInterceptor1_20.INSTANCE) )) @@ -346,7 +346,7 @@ public class BukkitInjector { InjectedCacheCheck injectedChecker = (InjectedCacheCheck) Reflections.UNSAFE.allocateInstance(clazz$InjectedCacheChecker); injectedChecker.recipeType(recipeType); Reflections.field$AbstractFurnaceBlockEntity$quickCheck.set(entity, injectedChecker); - } else if (!VersionHelper.isVersionNewerThan1_21_2() && Reflections.clazz$CampfireBlockEntity.isInstance(entity)) { + } else if (!VersionHelper.isOrAbove1_21_2() && Reflections.clazz$CampfireBlockEntity.isInstance(entity)) { Object quickCheck = Reflections.field$CampfireBlockEntity$quickCheck.get(entity); if (clazz$InjectedCacheChecker.isInstance(quickCheck)) return; // already injected InjectedCacheCheck injectedChecker = (InjectedCacheCheck) Reflections.UNSAFE.allocateInstance(clazz$InjectedCacheChecker); @@ -368,6 +368,22 @@ public class BukkitInjector { } } +// public synchronized static void injectLevelChunkSection(Object targetSection, CESection ceSection, CEWorld ceWorld, SectionPos pos) { +// try { +// Object container = FastNMS.INSTANCE.field$LevelChunkSection$states(targetSection); +// if (!(container instanceof InjectedPalettedContainerHolder)) { +// InjectedPalettedContainerHolder injectedObject = FastNMS.INSTANCE.createInjectedPalettedContainerHolder(container); +// injectedObject.ceSection(ceSection); +// injectedObject.ceWorld(ceWorld); +// injectedObject.cePos(pos); +// Reflections.varHandle$PalettedContainer$data.setVolatile(injectedObject, Reflections.varHandle$PalettedContainer$data.get(container)); +// Reflections.field$LevelChunkSection$states.set(targetSection, injectedObject); +// } +// } catch (Exception e) { +// CraftEngine.instance().logger().severe("Failed to inject chunk section", e); +// } +// } + public static void injectLevelChunkSection(Object targetSection, CESection ceSection, CEWorld ceWorld, SectionPos pos) { try { Object container = FastNMS.INSTANCE.field$LevelChunkSection$states(targetSection); @@ -385,7 +401,7 @@ public class BukkitInjector { } } - public static void uninjectLevelChunkSection(Object section) { + public synchronized static void uninjectLevelChunkSection(Object section) { try { Object states = FastNMS.INSTANCE.field$LevelChunkSection$states(section); if (states instanceof InjectedPalettedContainerHolder holder) { @@ -750,7 +766,7 @@ public class BukkitInjector { Object direction; Object serverLevel; Object blockPos; - if (VersionHelper.isVersionNewerThan1_21_2()) { + if (VersionHelper.isOrAbove1_21_2()) { direction = args[4]; serverLevel = args[1]; blockPos = args[3]; 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 c5160f6db..7eb2bc5e4 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 @@ -1,5 +1,6 @@ package net.momirealms.craftengine.bukkit.plugin.network; +import com.google.gson.JsonObject; import io.netty.buffer.ByteBuf; import io.netty.channel.*; import io.netty.handler.codec.MessageToMessageDecoder; @@ -16,10 +17,7 @@ import net.momirealms.craftengine.core.plugin.CraftEngine; import net.momirealms.craftengine.core.plugin.network.ConnectionState; import net.momirealms.craftengine.core.plugin.network.NetWorkUser; import net.momirealms.craftengine.core.plugin.network.NetworkManager; -import net.momirealms.craftengine.core.util.FriendlyByteBuf; -import net.momirealms.craftengine.core.util.ListMonitor; -import net.momirealms.craftengine.core.util.TriConsumer; -import net.momirealms.craftengine.core.util.VersionHelper; +import net.momirealms.craftengine.core.util.*; import org.bukkit.Bukkit; import org.bukkit.entity.Player; import org.bukkit.event.EventHandler; @@ -72,10 +70,12 @@ public class BukkitNetworkManager implements NetworkManager, Listener, PluginMes private static final String PACKET_DECODER = "craftengine_decoder"; private static boolean hasModelEngine; + private static boolean hasViaVersion; public BukkitNetworkManager(BukkitCraftEngine plugin) { instance = this; hasModelEngine = Bukkit.getPluginManager().getPlugin("ModelEngine") != null; + hasViaVersion = Bukkit.getPluginManager().getPlugin("ViaVersion") != null; this.plugin = plugin; // set up packet id this.packetIds = setupPacketIds(); @@ -101,6 +101,8 @@ public class BukkitNetworkManager implements NetworkManager, Listener, PluginMes // set up mod channel this.plugin.bootstrap().getServer().getMessenger().registerIncomingPluginChannel(this.plugin.bootstrap(), MOD_CHANNEL, this); this.plugin.bootstrap().getServer().getMessenger().registerOutgoingPluginChannel(this.plugin.bootstrap(), MOD_CHANNEL); + // 配置via频道 + this.plugin.bootstrap().getServer().getMessenger().registerIncomingPluginChannel(this.plugin.bootstrap(), VIA_CHANNEL, this); // Inject server channel try { Object server = Reflections.method$MinecraftServer$getServer.invoke(null); @@ -119,7 +121,7 @@ public class BukkitNetworkManager implements NetworkManager, Listener, PluginMes } private PacketIds setupPacketIds() { - if (VersionHelper.isVersionNewerThan1_20_5()) { + if (VersionHelper.isOrAbove1_20_5()) { return new PacketIds1_20_5(); } else { return new PacketIds1_20(); @@ -127,7 +129,6 @@ public class BukkitNetworkManager implements NetworkManager, Listener, PluginMes } private void registerPacketHandlers() { - registerNMSPacketConsumer(PacketConsumers.LEVEL_CHUNK_WITH_LIGHT, Reflections.clazz$ClientboundLevelChunkWithLightPacket); registerNMSPacketConsumer(PacketConsumers.PLAYER_INFO_UPDATE, Reflections.clazz$ClientboundPlayerInfoUpdatePacket); registerNMSPacketConsumer(PacketConsumers.PLAYER_ACTION, Reflections.clazz$ServerboundPlayerActionPacket); registerNMSPacketConsumer(PacketConsumers.SWING_HAND, Reflections.clazz$ServerboundSwingPacket); @@ -147,20 +148,24 @@ public class BukkitNetworkManager implements NetworkManager, Listener, PluginMes registerNMSPacketConsumer(PacketConsumers.EDIT_BOOK, Reflections.clazz$ServerboundEditBookPacket); registerNMSPacketConsumer(PacketConsumers.CUSTOM_PAYLOAD, Reflections.clazz$ServerboundCustomPayloadPacket); registerNMSPacketConsumer(PacketConsumers.RESOURCE_PACK_PUSH, Reflections.clazz$ClientboundResourcePackPushPacket); + registerNMSPacketConsumer(PacketConsumers.HANDSHAKE_C2S, Reflections.clazz$ClientIntentionPacket); + registerNMSPacketConsumer(PacketConsumers.LOGIN_ACKNOWLEDGED, Reflections.clazz$ServerboundLoginAcknowledgedPacket); + registerNMSPacketConsumer(PacketConsumers.RESOURCE_PACK_RESPONSE, Reflections.clazz$ServerboundResourcePackPacket); + registerByteBufPacketConsumer(PacketConsumers.LEVEL_CHUNK_WITH_LIGHT, this.packetIds.clientboundLevelChunkWithLightPacket()); registerByteBufPacketConsumer(PacketConsumers.SECTION_BLOCK_UPDATE, this.packetIds.clientboundSectionBlocksUpdatePacket()); registerByteBufPacketConsumer(PacketConsumers.BLOCK_UPDATE, this.packetIds.clientboundBlockUpdatePacket()); - registerByteBufPacketConsumer(VersionHelper.isVersionNewerThan1_21_3() ? PacketConsumers.LEVEL_PARTICLE_1_21_3 : (VersionHelper.isVersionNewerThan1_20_5() ? PacketConsumers.LEVEL_PARTICLE_1_20_5 : PacketConsumers.LEVEL_PARTICLE_1_20), this.packetIds.clientboundLevelParticlesPacket()); + registerByteBufPacketConsumer(VersionHelper.isOrAbove1_21_3() ? PacketConsumers.LEVEL_PARTICLE_1_21_3 : (VersionHelper.isOrAbove1_20_5() ? PacketConsumers.LEVEL_PARTICLE_1_20_5 : PacketConsumers.LEVEL_PARTICLE_1_20), this.packetIds.clientboundLevelParticlesPacket()); registerByteBufPacketConsumer(PacketConsumers.LEVEL_EVENT, this.packetIds.clientboundLevelEventPacket()); - registerByteBufPacketConsumer(VersionHelper.isVersionNewerThan1_20_3() ? PacketConsumers.OPEN_SCREEN_1_20_3 : PacketConsumers.OPEN_SCREEN_1_20, this.packetIds.clientboundOpenScreenPacket()); - registerByteBufPacketConsumer(VersionHelper.isVersionNewerThan1_20_3() ? PacketConsumers.SET_TITLE_TEXT_1_20_3 : PacketConsumers.SET_TITLE_TEXT_1_20, this.packetIds.clientboundSetTitleTextPacket()); - registerByteBufPacketConsumer(VersionHelper.isVersionNewerThan1_20_3() ? PacketConsumers.SET_SUBTITLE_TEXT_1_20_3 : PacketConsumers.SET_SUBTITLE_TEXT_1_20, this.packetIds.clientboundSetSubtitleTextPacket()); - registerByteBufPacketConsumer(VersionHelper.isVersionNewerThan1_20_3() ? PacketConsumers.SET_ACTIONBAR_TEXT_1_20_3 : PacketConsumers.SET_ACTIONBAR_TEXT_1_20, this.packetIds.clientboundSetActionBarTextPacket()); - registerByteBufPacketConsumer(VersionHelper.isVersionNewerThan1_20_3() ? PacketConsumers.BOSS_EVENT_1_20_3 : PacketConsumers.BOSS_EVENT_1_20, this.packetIds.clientboundBossEventPacket()); - registerByteBufPacketConsumer(VersionHelper.isVersionNewerThan1_20_3() ? PacketConsumers.SYSTEM_CHAT_1_20_3 : PacketConsumers.SYSTEM_CHAT_1_20, this.packetIds.clientboundSystemChatPacket()); - registerByteBufPacketConsumer(VersionHelper.isVersionNewerThan1_20_3() ? PacketConsumers.TAB_LIST_1_20_3 : PacketConsumers.TAB_LIST_1_20, this.packetIds.clientboundTabListPacket()); - registerByteBufPacketConsumer(VersionHelper.isVersionNewerThan1_20_3() ? PacketConsumers.TEAM_1_20_3 : PacketConsumers.TEAM_1_20, this.packetIds.clientboundSetPlayerTeamPacket()); - registerByteBufPacketConsumer(VersionHelper.isVersionNewerThan1_20_3() ? PacketConsumers.SET_OBJECTIVE_1_20_3 : PacketConsumers.SET_OBJECTIVE_1_20, this.packetIds.clientboundSetObjectivePacket()); - registerByteBufPacketConsumer(PacketConsumers.SET_SCORE_1_20_3, VersionHelper.isVersionNewerThan1_20_3() ? this.packetIds.clientboundSetScorePacket() : -1); + registerByteBufPacketConsumer(VersionHelper.isOrAbove1_20_3() ? PacketConsumers.OPEN_SCREEN_1_20_3 : PacketConsumers.OPEN_SCREEN_1_20, this.packetIds.clientboundOpenScreenPacket()); + registerByteBufPacketConsumer(VersionHelper.isOrAbove1_20_3() ? PacketConsumers.SET_TITLE_TEXT_1_20_3 : PacketConsumers.SET_TITLE_TEXT_1_20, this.packetIds.clientboundSetTitleTextPacket()); + registerByteBufPacketConsumer(VersionHelper.isOrAbove1_20_3() ? PacketConsumers.SET_SUBTITLE_TEXT_1_20_3 : PacketConsumers.SET_SUBTITLE_TEXT_1_20, this.packetIds.clientboundSetSubtitleTextPacket()); + registerByteBufPacketConsumer(VersionHelper.isOrAbove1_20_3() ? PacketConsumers.SET_ACTIONBAR_TEXT_1_20_3 : PacketConsumers.SET_ACTIONBAR_TEXT_1_20, this.packetIds.clientboundSetActionBarTextPacket()); + registerByteBufPacketConsumer(VersionHelper.isOrAbove1_20_3() ? PacketConsumers.BOSS_EVENT_1_20_3 : PacketConsumers.BOSS_EVENT_1_20, this.packetIds.clientboundBossEventPacket()); + registerByteBufPacketConsumer(VersionHelper.isOrAbove1_20_3() ? PacketConsumers.SYSTEM_CHAT_1_20_3 : PacketConsumers.SYSTEM_CHAT_1_20, this.packetIds.clientboundSystemChatPacket()); + registerByteBufPacketConsumer(VersionHelper.isOrAbove1_20_3() ? PacketConsumers.TAB_LIST_1_20_3 : PacketConsumers.TAB_LIST_1_20, this.packetIds.clientboundTabListPacket()); + registerByteBufPacketConsumer(VersionHelper.isOrAbove1_20_3() ? PacketConsumers.TEAM_1_20_3 : PacketConsumers.TEAM_1_20, this.packetIds.clientboundSetPlayerTeamPacket()); + registerByteBufPacketConsumer(VersionHelper.isOrAbove1_20_3() ? PacketConsumers.SET_OBJECTIVE_1_20_3 : PacketConsumers.SET_OBJECTIVE_1_20, this.packetIds.clientboundSetObjectivePacket()); + registerByteBufPacketConsumer(PacketConsumers.SET_SCORE_1_20_3, VersionHelper.isOrAbove1_20_3() ? this.packetIds.clientboundSetScorePacket() : -1); registerByteBufPacketConsumer(PacketConsumers.REMOVE_ENTITY, this.packetIds.clientboundRemoveEntitiesPacket()); registerByteBufPacketConsumer(PacketConsumers.ADD_ENTITY_BYTEBUFFER, this.packetIds.clientboundAddEntityPacket()); registerByteBufPacketConsumer(PacketConsumers.SOUND, this.packetIds.clientboundSoundPacket()); @@ -202,9 +207,17 @@ public class BukkitNetworkManager implements NetworkManager, Listener, PluginMes return this.onlineUserArray; } - // 保留仅注册入频道用 @Override - public void onPluginMessageReceived(@NotNull String channel, @NotNull Player player, byte @NotNull [] message) {} + public void onPluginMessageReceived(@NotNull String channel, @NotNull Player player, byte @NotNull [] message) { + if (channel.equals(VIA_CHANNEL)) { + BukkitServerPlayer user = plugin.adapt(player); + if (user != null) { + JsonObject payload = GsonHelper.get().fromJson(new String(message), JsonObject.class); + int version = payload.get("version").getAsInt(); + user.setProtocolVersion(version); + } + } + } @Override public void init() { @@ -289,6 +302,10 @@ public class BukkitNetworkManager implements NetworkManager, Listener, PluginMes return hasModelEngine; } + public static boolean hasViaVersion() { + return hasViaVersion; + } + public void simulatePacket(@NotNull NetWorkUser player, Object packet) { Channel channel = player.nettyChannel(); if (channel.isOpen()) { diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/network/PacketConsumers.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/network/PacketConsumers.java index 719667520..13eab66b8 100644 --- a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/network/PacketConsumers.java +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/network/PacketConsumers.java @@ -9,7 +9,6 @@ import net.momirealms.craftengine.bukkit.api.CraftEngineFurniture; import net.momirealms.craftengine.bukkit.api.event.FurnitureBreakEvent; import net.momirealms.craftengine.bukkit.api.event.FurnitureInteractEvent; import net.momirealms.craftengine.bukkit.block.BukkitBlockManager; -import net.momirealms.craftengine.bukkit.compatibility.modelengine.ModelEngineUtils; import net.momirealms.craftengine.bukkit.entity.furniture.BukkitFurnitureManager; import net.momirealms.craftengine.bukkit.entity.furniture.LoadedFurniture; import net.momirealms.craftengine.bukkit.item.behavior.FurnitureItemBehavior; @@ -41,6 +40,7 @@ import net.momirealms.craftengine.core.world.EntityHitResult; import net.momirealms.craftengine.core.world.WorldEvents; import net.momirealms.craftengine.core.world.chunk.Palette; import net.momirealms.craftengine.core.world.chunk.PalettedContainer; +import net.momirealms.craftengine.core.world.chunk.packet.BlockEntityData; import net.momirealms.craftengine.core.world.chunk.packet.MCSection; import net.momirealms.craftengine.core.world.collision.AABB; import net.momirealms.sparrow.nbt.Tag; @@ -63,7 +63,6 @@ public class PacketConsumers { private static int[] mappingsMOD; private static IntIdentityList BLOCK_LIST; private static IntIdentityList BIOME_LIST; - private static final UUID EMPTY_UUID = new UUID(0, 0); public static void init(Map map, int registrySize) { mappings = new int[registrySize]; @@ -94,15 +93,53 @@ public class PacketConsumers { return mappingsMOD[stateId]; } - // TODO Use bytebuffer? - public static final TriConsumer LEVEL_CHUNK_WITH_LIGHT = (user, event, packet) -> { + public static final BiConsumer LEVEL_CHUNK_WITH_LIGHT = (user, event) -> { try { + BukkitServerPlayer player = (BukkitServerPlayer) user; + FriendlyByteBuf buf = event.getBuffer(); + int chunkX = buf.readInt(); + int chunkZ = buf.readInt(); + boolean named = !VersionHelper.isOrAbove1_20_2(); + // ClientboundLevelChunkPacketData + int heightmapsCount = 0; + Map heightmapsMap = null; + Tag heightmaps = null; + if (VersionHelper.isOrAbove1_21_5()) { + heightmapsMap = new HashMap<>(); + heightmapsCount = buf.readVarInt(); + for (int i = 0; i < heightmapsCount; i++) { + int key = buf.readVarInt(); + long[] value = buf.readLongArray(); + heightmapsMap.put(key, value); + } + } else { + heightmaps = buf.readNbt(named); + } + + int varInt = buf.readVarInt(); + byte[] buffer = new byte[varInt]; + buf.readBytes(buffer); + int blockEntitiesDataCount = buf.readVarInt(); + List blockEntitiesData = new ArrayList<>(); + for (int i = 0; i < blockEntitiesDataCount; i++) { + byte packedXZ = buf.readByte(); + short y = buf.readShort(); + int type = buf.readVarInt(); + Tag tag = buf.readNbt(named); + BlockEntityData blockEntityData = new BlockEntityData(packedXZ, y, type, tag); + blockEntitiesData.add(blockEntityData); + } + // ClientboundLightUpdatePacketData + BitSet skyYMask = buf.readBitSet(); + BitSet blockYMask = buf.readBitSet(); + BitSet emptySkyYMask = buf.readBitSet(); + BitSet emptyBlockYMask = buf.readBitSet(); + List skyUpdates = buf.readByteArrayList(2048); + List blockUpdates = buf.readByteArrayList(2048); + // 开始处理 if (user.clientModEnabled()) { - BukkitServerPlayer player = (BukkitServerPlayer) user; - Object chunkData = FastNMS.INSTANCE.field$ClientboundLevelChunkWithLightPacket$chunkData(packet); - byte[] buffer = (byte[]) Reflections.field$ClientboundLevelChunkPacketData$buffer.get(chunkData); - ByteBuf buf = Unpooled.copiedBuffer(buffer); - FriendlyByteBuf friendlyByteBuf = new FriendlyByteBuf(buf); + ByteBuf byteBuf = Unpooled.copiedBuffer(buffer); + FriendlyByteBuf friendlyByteBuf = new FriendlyByteBuf(byteBuf); FriendlyByteBuf newBuf = new FriendlyByteBuf(Unpooled.buffer()); for (int i = 0, count = player.clientSideSectionCount(); i < count; i++) { try { @@ -126,13 +163,10 @@ public class PacketConsumers { break; } } - Reflections.field$ClientboundLevelChunkPacketData$buffer.set(chunkData, newBuf.array()); + buffer = newBuf.array(); } else { - BukkitServerPlayer player = (BukkitServerPlayer) user; - Object chunkData = FastNMS.INSTANCE.field$ClientboundLevelChunkWithLightPacket$chunkData(packet); - byte[] buffer = (byte[]) Reflections.field$ClientboundLevelChunkPacketData$buffer.get(chunkData); - ByteBuf buf = Unpooled.copiedBuffer(buffer); - FriendlyByteBuf friendlyByteBuf = new FriendlyByteBuf(buf); + ByteBuf byteBuf = Unpooled.copiedBuffer(buffer); + FriendlyByteBuf friendlyByteBuf = new FriendlyByteBuf(byteBuf); FriendlyByteBuf newBuf = new FriendlyByteBuf(Unpooled.buffer()); for (int i = 0, count = player.clientSideSectionCount(); i < count; i++) { try { @@ -156,8 +190,38 @@ public class PacketConsumers { break; } } - Reflections.field$ClientboundLevelChunkPacketData$buffer.set(chunkData, newBuf.array()); + buffer = newBuf.array(); } + buf.clear(); + buf.writeVarInt(event.packetID()); + buf.writeInt(chunkX); + buf.writeInt(chunkZ); + if (VersionHelper.isOrAbove1_21_5()) { + buf.writeVarInt(heightmapsCount); + assert heightmapsMap != null; + for (Map.Entry entry : heightmapsMap.entrySet()) { + buf.writeVarInt(entry.getKey()); + buf.writeLongArray(entry.getValue()); + } + } else { + buf.writeNbt(heightmaps, named); + } + buf.writeVarInt(buffer.length); + buf.writeBytes(buffer); + buf.writeVarInt(blockEntitiesDataCount); + for (BlockEntityData blockEntityData : blockEntitiesData) { + buf.writeByte(blockEntityData.packedXZ()); + buf.writeShort(blockEntityData.y()); + buf.writeVarInt(blockEntityData.type()); + buf.writeNbt(blockEntityData.tag(), named); + } + buf.writeBitSet(skyYMask); + buf.writeBitSet(blockYMask); + buf.writeBitSet(emptySkyYMask); + buf.writeBitSet(emptyBlockYMask); + buf.writeByteArrayList(skyUpdates); + buf.writeByteArrayList(blockUpdates); + event.setChanged(true); } catch (Exception e) { CraftEngine.instance().logger().warn("Failed to handle ClientboundLevelChunkWithLightPacket", e); } @@ -1174,7 +1238,7 @@ public class PacketConsumers { BukkitServerPlayer player = (BukkitServerPlayer) user; String name = (String) Reflections.field$ServerboundHelloPacket$name.get(packet); player.setName(name); - if (VersionHelper.isVersionNewerThan1_20_2()) { + if (VersionHelper.isOrAbove1_20_2()) { UUID uuid = (UUID) Reflections.field$ServerboundHelloPacket$uuid.get(packet); player.setUUID(uuid); } else { @@ -1222,7 +1286,7 @@ public class PacketConsumers { BukkitServerPlayer player = (BukkitServerPlayer) user; player.clearView(); Object dimensionKey; - if (!VersionHelper.isVersionNewerThan1_20_2()) { + if (!VersionHelper.isOrAbove1_20_2()) { dimensionKey = Reflections.field$ClientboundRespawnPacket$dimension.get(packet); } else { Object commonInfo = Reflections.field$ClientboundRespawnPacket$commonPlayerSpawnInfo.get(packet); @@ -1247,7 +1311,10 @@ public class PacketConsumers { BukkitServerPlayer player = (BukkitServerPlayer) user; player.setConnectionState(ConnectionState.PLAY); Object dimensionKey; - if (!VersionHelper.isVersionNewerThan1_20_2()) { + if (!VersionHelper.isOrAbove1_20_2()) { + if (BukkitNetworkManager.hasViaVersion()) { + user.setProtocolVersion(CraftEngine.instance().compatibilityManager().getPlayerProtocolVersion(player.uuid())); + } dimensionKey = Reflections.field$ClientboundLoginPacket$dimension.get(packet); } else { Object commonInfo = Reflections.field$ClientboundLoginPacket$commonPlayerSpawnInfo.get(packet); @@ -1272,7 +1339,7 @@ public class PacketConsumers { // When the hotbar is full, the latest creative mode inventory can only be accessed when the player opens the inventory screen. Currently, it is not worth further handling this issue. public static final TriConsumer SET_CREATIVE_SLOT = (user, event, packet) -> { try { - if (VersionHelper.isVersionNewerThan1_21_4()) return; + if (VersionHelper.isOrAbove1_21_4()) return; if (!user.isOnline()) return; BukkitServerPlayer player = (BukkitServerPlayer) user; if (VersionHelper.isFolia()) { @@ -1295,7 +1362,7 @@ public class PacketConsumers { Player bukkitPlayer = player.platformPlayer(); if (bukkitPlayer == null) return; if (bukkitPlayer.getGameMode() != GameMode.CREATIVE) return; - int slot = VersionHelper.isVersionNewerThan1_20_5() ? Reflections.field$ServerboundSetCreativeModeSlotPacket$slotNum.getShort(packet) : Reflections.field$ServerboundSetCreativeModeSlotPacket$slotNum.getInt(packet); + int slot = VersionHelper.isOrAbove1_20_5() ? Reflections.field$ServerboundSetCreativeModeSlotPacket$slotNum.getShort(packet) : Reflections.field$ServerboundSetCreativeModeSlotPacket$slotNum.getInt(packet); if (slot < 36 || slot > 44) return; ItemStack item = FastNMS.INSTANCE.method$CraftItemStack$asCraftMirror(Reflections.field$ServerboundSetCreativeModeSlotPacket$itemStack.get(packet)); if (ItemUtils.isEmpty(item)) return; @@ -1585,7 +1652,7 @@ public class PacketConsumers { int entityId; if (BukkitNetworkManager.hasModelEngine()) { int fakeId = FastNMS.INSTANCE.field$ServerboundInteractPacket$entityId(packet); - entityId = ModelEngineUtils.interactionToBaseEntity(fakeId); + entityId = CraftEngine.instance().compatibilityManager().interactionToBaseEntity(fakeId); } else { entityId = FastNMS.INSTANCE.field$ServerboundInteractPacket$entityId(packet); } @@ -1867,7 +1934,7 @@ public class PacketConsumers { public static final TriConsumer CUSTOM_PAYLOAD = (user, event, packet) -> { try { - if (!VersionHelper.isVersionNewerThan1_20_5()) return; + if (!VersionHelper.isOrAbove1_20_5()) return; Object payload = Reflections.field$ServerboundCustomPayloadPacket$payload.get(packet); if (payload.getClass().equals(Reflections.clazz$DiscardedPayload)) { Object type = Reflections.method$CustomPacketPayload$type.invoke(payload); @@ -2149,7 +2216,7 @@ public class PacketConsumers { public static final TriConsumer RESOURCE_PACK_PUSH = (user, event, packet) -> { try { - if (!VersionHelper.isVersionNewerThan1_20_2()) return; + if (!VersionHelper.isOrAbove1_20_2()) return; // we should only handle fake urls String url = FastNMS.INSTANCE.field$ClientboundResourcePackPushPacket$url(packet); if (!url.equals(BukkitPackManager.FAKE_URL)) { @@ -2178,4 +2245,45 @@ public class PacketConsumers { CraftEngine.instance().logger().warn("Failed to handle ClientboundResourcePackPushPacket", e); } }; + + public static final TriConsumer HANDSHAKE_C2S = (user, event, packet) -> { + try { + if (BukkitNetworkManager.hasViaVersion()) return; + int protocolVersion = Reflections.field$ClientIntentionPacket$protocolVersion.getInt(packet); + user.setProtocolVersion(protocolVersion); + } catch (Exception e) { + CraftEngine.instance().logger().warn("Failed to handle ClientIntentionPacket", e); + } + }; + + public static final TriConsumer LOGIN_ACKNOWLEDGED = (user, event, packet) -> { + try { + if (BukkitNetworkManager.hasViaVersion()) { + user.setProtocolVersion(CraftEngine.instance().compatibilityManager().getPlayerProtocolVersion(user.uuid())); + } + } catch (Exception e) { + CraftEngine.instance().logger().warn("Failed to handle ServerboundLoginAcknowledgedPacket", e); + } + }; + + public static final TriConsumer RESOURCE_PACK_RESPONSE = (user, event, packet) -> { + try { + if (user.sentResourcePack() || !Config.sendPackOnJoin() || !Config.kickOnDeclined()) return; + Object action = Reflections.field$ServerboundResourcePackPacket$action.get(packet); + if (action == null) return; + if (action == Reflections.instance$ServerboundResourcePackPacket$Action$DECLINED + || action == Reflections.instance$ServerboundResourcePackPacket$Action$FAILED_DOWNLOAD) { + Object kickPacket = Reflections.constructor$ClientboundDisconnectPacket.newInstance( + ComponentUtils.adventureToMinecraft(Component.translatable("multiplayer.requiredTexturePrompt.disconnect"))); + user.nettyChannel().writeAndFlush(kickPacket); + user.nettyChannel().disconnect(); + return; + } + if (action == Reflections.instance$ServerboundResourcePackPacket$Action$SUCCESSFULLY_LOADED) { + user.setSentResourcePack(true); + } + } catch (Exception e) { + CraftEngine.instance().logger().warn("Failed to handle ServerboundResourcePackPacket", e); + } + }; } diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/network/id/PacketIdFinder.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/network/id/PacketIdFinder.java index 489ea5d01..fc5594bfe 100644 --- a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/network/id/PacketIdFinder.java +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/network/id/PacketIdFinder.java @@ -15,7 +15,7 @@ public class PacketIdFinder { static { try { - if (VersionHelper.isVersionNewerThan1_21()) { + if (VersionHelper.isOrAbove1_21()) { Object packetReport = Reflections.constructor$PacketReport.newInstance((Object) null); JsonElement jsonElement = (JsonElement) Reflections.method$PacketReport$serializePackets.invoke(packetReport); var play = jsonElement.getAsJsonObject().get("play"); @@ -26,7 +26,7 @@ public class PacketIdFinder { ids.put(entry2.getKey(), entry2.getValue().getAsJsonObject().get("protocol_id").getAsInt()); } } - } else if (VersionHelper.isVersionNewerThan1_20_5()) { + } else if (VersionHelper.isOrAbove1_20_5()) { gamePacketIdsByName.putAll(FastNMS.INSTANCE.method$getGamePacketIdsByName()); } else { gamePacketIdsByClazz.putAll(FastNMS.INSTANCE.method$getGamePacketIdsByClazz()); diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/user/BukkitServerPlayer.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/user/BukkitServerPlayer.java index bd873f8e8..13341b5b2 100644 --- a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/user/BukkitServerPlayer.java +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/user/BukkitServerPlayer.java @@ -18,6 +18,7 @@ import net.momirealms.craftengine.core.item.Item; import net.momirealms.craftengine.core.plugin.CraftEngine; import net.momirealms.craftengine.core.plugin.config.Config; import net.momirealms.craftengine.core.plugin.network.ConnectionState; +import net.momirealms.craftengine.core.plugin.network.ProtocolVersion; import net.momirealms.craftengine.core.util.Direction; import net.momirealms.craftengine.core.util.Key; import net.momirealms.craftengine.core.util.VersionHelper; @@ -39,6 +40,8 @@ import java.util.concurrent.ConcurrentHashMap; public class BukkitServerPlayer extends Player { private final BukkitCraftEngine plugin; + // handshake + private ProtocolVersion protocolVersion = ProtocolVersion.UNKNOWN; // connection state private final Channel channel; private String name; @@ -46,6 +49,7 @@ public class BukkitServerPlayer extends Player { private ConnectionState decoderState; private ConnectionState encoderState; private final Set resourcePackUUID = Collections.synchronizedSet(new HashSet<>()); + private boolean sentResourcePack = !Config.sendPackOnJoin(); // some references private Reference playerRef; private Reference serverPlayerRef; @@ -411,7 +415,7 @@ public class BukkitServerPlayer extends Player { } this.clientSideCanBreak = canBreak; if (canBreak) { - if (VersionHelper.isVersionNewerThan1_20_5()) { + if (VersionHelper.isOrAbove1_20_5()) { Object serverPlayer = serverPlayer(); Object attributeInstance = Reflections.method$ServerPlayer$getAttribute.invoke(serverPlayer, Reflections.instance$Holder$Attribute$block_break_speed); Object newPacket = Reflections.constructor$ClientboundUpdateAttributesPacket0.newInstance(entityID(), Lists.newArrayList(attributeInstance)); @@ -421,8 +425,8 @@ public class BukkitServerPlayer extends Player { resetEffect(Reflections.instance$MobEffecr$haste); } } else { - if (VersionHelper.isVersionNewerThan1_20_5()) { - Object attributeModifier = VersionHelper.isVersionNewerThan1_21() ? + if (VersionHelper.isOrAbove1_20_5()) { + Object attributeModifier = VersionHelper.isOrAbove1_21() ? Reflections.constructor$AttributeModifier.newInstance(KeyUtils.toResourceLocation("craftengine", "custom_hardness"), -9999d, Reflections.instance$AttributeModifier$Operation$ADD_VALUE) : Reflections.constructor$AttributeModifier.newInstance(UUID.randomUUID(), "craftengine:custom_hardness", -9999d, Reflections.instance$AttributeModifier$Operation$ADD_VALUE); Object attributeSnapshot = Reflections.constructor$ClientboundUpdateAttributesPacket$AttributeSnapshot.newInstance(Reflections.instance$Holder$Attribute$block_break_speed, 1d, Lists.newArrayList(attributeModifier)); @@ -516,7 +520,7 @@ public class BukkitServerPlayer extends Player { // creative mode + invalid item in hand if (canInstabuild() && (itemMaterial == Material.DEBUG_STICK || itemMaterial == Material.TRIDENT - || (VersionHelper.isVersionNewerThan1_20_5() && itemMaterial == MaterialUtils.MACE) + || (VersionHelper.isOrAbove1_20_5() && itemMaterial == MaterialUtils.MACE) || item.is(ItemTags.SWORDS))) { return; } @@ -753,11 +757,31 @@ public class BukkitServerPlayer extends Player { @Override public void addResourcePackUUID(UUID uuid) { - if (VersionHelper.isVersionNewerThan1_20_3()) { + if (VersionHelper.isOrAbove1_20_3()) { this.resourcePackUUID.add(uuid); } } + @Override + public ProtocolVersion protocolVersion() { + return this.protocolVersion; + } + + @Override + public void setProtocolVersion(int protocolVersion) { + this.protocolVersion = ProtocolVersion.getById(protocolVersion); + } + + @Override + public boolean sentResourcePack() { + return this.sentResourcePack; + } + + @Override + public void setSentResourcePack(boolean sentResourcePack) { + this.sentResourcePack = sentResourcePack; + } + @Override public void clearView() { this.entityTypeView.clear(); @@ -766,7 +790,7 @@ public class BukkitServerPlayer extends Player { @Override public void unloadCurrentResourcePack() { - if (!VersionHelper.isVersionNewerThan1_20_3()) { + if (!VersionHelper.isOrAbove1_20_3()) { return; } if (decoderState() == ConnectionState.PLAY && !this.resourcePackUUID.isEmpty()) { diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/sound/BukkitSoundManager.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/sound/BukkitSoundManager.java index 1f9203366..bfab4bb0f 100644 --- a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/sound/BukkitSoundManager.java +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/sound/BukkitSoundManager.java @@ -33,7 +33,7 @@ public class BukkitSoundManager extends AbstractSoundManager { Object soundId = KeyUtils.toResourceLocation(jukeboxSong.sound()); Object song = Reflections.method$Registry$get.invoke(Reflections.instance$InternalRegistries$JUKEBOX_SONG, resourceLocation); - Object soundEvent = VersionHelper.isVersionNewerThan1_21_2() ? + Object soundEvent = VersionHelper.isOrAbove1_21_2() ? Reflections.constructor$SoundEvent.newInstance(soundId, Optional.of(jukeboxSong.range())) : Reflections.constructor$SoundEvent.newInstance(soundId, jukeboxSong.range(), false); Object soundHolder = Reflections.method$Holder$direct.invoke(null, soundEvent); diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/util/BlockStateUtils.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/util/BlockStateUtils.java index bbce5ef50..515fdfc63 100644 --- a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/util/BlockStateUtils.java +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/util/BlockStateUtils.java @@ -2,10 +2,8 @@ package net.momirealms.craftengine.bukkit.util; import net.momirealms.craftengine.bukkit.block.BukkitBlockManager; import net.momirealms.craftengine.bukkit.nms.FastNMS; -import net.momirealms.craftengine.core.block.BlockStateParser; -import net.momirealms.craftengine.core.block.CustomBlock; -import net.momirealms.craftengine.core.block.ImmutableBlockState; -import net.momirealms.craftengine.core.block.PushReaction; +import net.momirealms.craftengine.core.block.*; +import net.momirealms.craftengine.core.item.Item; import net.momirealms.craftengine.core.util.Instrument; import net.momirealms.craftengine.core.util.Key; import net.momirealms.craftengine.core.util.MapColor; @@ -14,6 +12,9 @@ import org.bukkit.Bukkit; import org.bukkit.block.Block; import org.bukkit.block.data.BlockData; import org.bukkit.event.block.BlockPhysicsEvent; +import org.bukkit.inventory.ItemStack; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; import java.util.IdentityHashMap; import java.util.List; @@ -32,6 +33,18 @@ public class BlockStateUtils { hasInit = true; } + public static boolean isCorrectTool(@NotNull ImmutableBlockState state, @Nullable Item itemInHand) { + BlockSettings settings = state.settings(); + if (settings.requireCorrectTool()) { + if (itemInHand == null) return false; + if (!settings.isCorrectTool(itemInHand.id()) && + (!settings.respectToolComponent() || !FastNMS.INSTANCE.method$ItemStack$isCorrectToolForDrops(itemInHand.getLiteralObject(), state.customBlockState().handle()))) { + return false; + } + } + return true; + } + public static List getAllBlockStates(String blockState) { int index = blockState.indexOf('['); if (index == -1) { diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/util/BukkitReflectionUtils.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/util/BukkitReflectionUtils.java index 9bd26a702..bbaf192a2 100644 --- a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/util/BukkitReflectionUtils.java +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/util/BukkitReflectionUtils.java @@ -1,10 +1,13 @@ package net.momirealms.craftengine.bukkit.util; import net.momirealms.craftengine.core.util.ReflectionUtils; +import net.momirealms.craftengine.core.util.VersionHelper; import org.bukkit.Bukkit; import java.lang.reflect.Method; +import java.util.List; import java.util.Objects; +import java.util.function.Function; public final class BukkitReflectionUtils { private static final String PREFIX_MC = "net.minecraft."; @@ -66,4 +69,42 @@ public final class BukkitReflectionUtils { public static String assembleMCClass(String className) { return PREFIX_MC + className; } + + public static Class findReobfOrMojmapClass(String reobf, String mojmap) { + return findReobfOrMojmapClass(reobf, mojmap, BukkitReflectionUtils::assembleMCClass); + } + + public static Class findReobfOrMojmapClass(String reobf, String mojmap, Function classDecorator) { + if (VersionHelper.isMojmap()) return ReflectionUtils.getClazz(classDecorator.apply(mojmap)); + else return ReflectionUtils.getClazz(classDecorator.apply(reobf)); + } + + public static Class findReobfOrMojmapClass(List reobf, String mojmap) { + return findReobfOrMojmapClass(reobf, mojmap, BukkitReflectionUtils::assembleMCClass); + } + + public static Class findReobfOrMojmapClass(List reobf, String mojmap, Function classDecorator) { + if (VersionHelper.isMojmap()) return ReflectionUtils.getClazz(classDecorator.apply(mojmap)); + else return ReflectionUtils.getClazz(reobf.stream().map(classDecorator).toList().toArray(new String[0])); + } + + public static Class findReobfOrMojmapClass(String reobf, List mojmap) { + return findReobfOrMojmapClass(reobf, mojmap, BukkitReflectionUtils::assembleMCClass); + } + + public static Class findReobfOrMojmapClass(String reobf, List mojmap, Function classDecorator) { + if (VersionHelper.isMojmap()) return ReflectionUtils.getClazz(mojmap.stream().map(classDecorator).toList().toArray(new String[0])); + else return ReflectionUtils.getClazz(classDecorator.apply(reobf)); + } + + public static Class findReobfOrMojmapClass(List reobf, List mojmap) { + return findReobfOrMojmapClass(reobf, mojmap, BukkitReflectionUtils::assembleMCClass); + } + + public static Class findReobfOrMojmapClass(List reobf, List mojmap, Function classDecorator) { + String[] classes = VersionHelper.isMojmap() + ? mojmap.stream().map(classDecorator).toList().toArray(new String[0]) + : reobf.stream().map(classDecorator).toList().toArray(new String[0]); + return ReflectionUtils.getClazz(classes); + } } diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/util/EntityDataUtils.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/util/EntityDataUtils.java index 93b3b88c0..8c70d577f 100644 --- a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/util/EntityDataUtils.java +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/util/EntityDataUtils.java @@ -11,8 +11,8 @@ public class EntityDataUtils { private static final int USE_DEFAULT_BACKGROUND = 0x04; // 4 private static final int LEFT_ALIGNMENT = 0x08; // 8 private static final int RIGHT_ALIGNMENT = 0x10; // 16 - public static final int BLOCK_STATE_DATA_ID = VersionHelper.isVersionNewerThan1_20_2() ? 23 : 22; - public static final int TEXT_DATA_ID = VersionHelper.isVersionNewerThan1_20_2() ? 23 : 22; + public static final int BLOCK_STATE_DATA_ID = VersionHelper.isOrAbove1_20_2() ? 23 : 22; + public static final int TEXT_DATA_ID = VersionHelper.isOrAbove1_20_2() ? 23 : 22; public static final int CUSTOM_NAME_DATA_ID = 2; public static byte encodeTextDisplayMask(boolean hasShadow, boolean isSeeThrough, boolean useDefaultBackground, int alignment) { diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/util/EntityUtils.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/util/EntityUtils.java index 89f66906d..88e52d4b8 100644 --- a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/util/EntityUtils.java +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/util/EntityUtils.java @@ -27,7 +27,7 @@ public class EntityUtils { } public static Entity spawnEntity(World world, Location loc, EntityType type, Consumer function) { - if (VersionHelper.isVersionNewerThan1_20_2()) { + if (VersionHelper.isOrAbove1_20_2()) { return world.spawnEntity(loc, type, CreatureSpawnEvent.SpawnReason.CUSTOM, function); } else { return LegacyEntityUtils.spawnEntity(world, loc, type, function); diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/util/RecipeUtils.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/util/RecipeUtils.java index dfff3fd0a..4c59ea3b3 100644 --- a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/util/RecipeUtils.java +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/util/RecipeUtils.java @@ -15,9 +15,9 @@ public class RecipeUtils { public static List getIngredientsFromShapedRecipe(Object recipe) { List ingredients = new ArrayList<>(); try { - if (VersionHelper.isVersionNewerThan1_20_3()) { + if (VersionHelper.isOrAbove1_20_3()) { Object pattern = Reflections.field$1_20_3$ShapedRecipe$pattern.get(recipe); - if (VersionHelper.isVersionNewerThan1_21_2()) { + if (VersionHelper.isOrAbove1_21_2()) { List> optionals = (List>) Reflections.field$ShapedRecipePattern$ingredients1_21_2.get(pattern); for (Optional optional : optionals) { optional.ifPresent(ingredients::add); diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/util/Reflections.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/util/Reflections.java index cba4df44f..7d4d24a24 100644 --- a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/util/Reflections.java +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/util/Reflections.java @@ -69,9 +69,9 @@ public class Reflections { ); public static final Class clazz$Component = requireNonNull( - ReflectionUtils.getClazz( - BukkitReflectionUtils.assembleMCClass("network.chat.Component"), - BukkitReflectionUtils.assembleMCClass("network.chat.IChatBaseComponent") + BukkitReflectionUtils.findReobfOrMojmapClass( + "network.chat.IChatBaseComponent", + "network.chat.Component" ) ); @@ -147,23 +147,23 @@ public class Reflections { ); public static final Class clazz$LevelWriter = requireNonNull( - ReflectionUtils.getClazz( - BukkitReflectionUtils.assembleMCClass("world.level.LevelWriter"), - BukkitReflectionUtils.assembleMCClass("world.level.IWorldWriter") + BukkitReflectionUtils.findReobfOrMojmapClass( + "world.level.IWorldWriter", + "world.level.LevelWriter" ) ); public static final Class clazz$LevelReader = requireNonNull( - ReflectionUtils.getClazz( - BukkitReflectionUtils.assembleMCClass("world.level.LevelReader"), - BukkitReflectionUtils.assembleMCClass("world.level.IWorldReader") + BukkitReflectionUtils.findReobfOrMojmapClass( + "world.level.IWorldReader", + "world.level.LevelReader" ) ); public static final Class clazz$DimensionType = requireNonNull( - ReflectionUtils.getClazz( - BukkitReflectionUtils.assembleMCClass("world.level.dimension.DimensionType"), - BukkitReflectionUtils.assembleMCClass("world.level.dimension.DimensionManager") + BukkitReflectionUtils.findReobfOrMojmapClass( + "world.level.dimension.DimensionManager", + "world.level.dimension.DimensionType" ) ); @@ -201,16 +201,16 @@ public class Reflections { ); public static final Class clazz$ClientboundBossEventPacket = requireNonNull( - ReflectionUtils.getClazz( - BukkitReflectionUtils.assembleMCClass("network.protocol.game.ClientboundBossEventPacket"), - BukkitReflectionUtils.assembleMCClass("network.protocol.game.PacketPlayOutBoss") + BukkitReflectionUtils.findReobfOrMojmapClass( + "network.protocol.game.PacketPlayOutBoss", + "network.protocol.game.ClientboundBossEventPacket" ) ); public static final Class clazz$ClientboundBossEventPacket$Operation = requireNonNull( - ReflectionUtils.getClazz( - BukkitReflectionUtils.assembleMCClass("network.protocol.game.ClientboundBossEventPacket$Operation"), - BukkitReflectionUtils.assembleMCClass("network.protocol.game.PacketPlayOutBoss$Action") + BukkitReflectionUtils.findReobfOrMojmapClass( + "network.protocol.game.PacketPlayOutBoss$Action", + "network.protocol.game.ClientboundBossEventPacket$Operation" ) ); @@ -222,17 +222,17 @@ public class Reflections { ); public static final Class clazz$ClientboundBossEventPacket$AddOperation = requireNonNull( - ReflectionUtils.getClazz( - BukkitReflectionUtils.assembleMCClass("network.protocol.game.ClientboundBossEventPacket$AddOperation"), - BukkitReflectionUtils.assembleMCClass("network.protocol.game.PacketPlayOutBoss$a") + BukkitReflectionUtils.findReobfOrMojmapClass( + "network.protocol.game.PacketPlayOutBoss$a", + "network.protocol.game.ClientboundBossEventPacket$AddOperation" ) ); public static final Class clazz$BossEvent$BossBarColor = requireNonNull( - ReflectionUtils.getClazz( - BukkitReflectionUtils.assembleMCClass("world.BossEvent$BossBarColor"), - BukkitReflectionUtils.assembleMCClass("world.BossBattle$BarColor") + BukkitReflectionUtils.findReobfOrMojmapClass( + "world.BossBattle$BarColor", + "world.BossEvent$BossBarColor" ) ); @@ -245,9 +245,9 @@ public class Reflections { ); public static final Class clazz$BossEvent$BossBarOverlay = requireNonNull( - ReflectionUtils.getClazz( - BukkitReflectionUtils.assembleMCClass("world.BossEvent$BossBarOverlay"), - BukkitReflectionUtils.assembleMCClass("world.BossBattle$BarStyle") + BukkitReflectionUtils.findReobfOrMojmapClass( + "world.BossBattle$BarStyle", + "world.BossEvent$BossBarOverlay" ) ); @@ -309,9 +309,9 @@ public class Reflections { ); public static final Class clazz$ResourceLocation = requireNonNull( - ReflectionUtils.getClazz( - BukkitReflectionUtils.assembleMCClass("resources.ResourceLocation"), - BukkitReflectionUtils.assembleMCClass("resources.MinecraftKey") + BukkitReflectionUtils.findReobfOrMojmapClass( + "resources.MinecraftKey", + "resources.ResourceLocation" ) ); @@ -320,9 +320,9 @@ public class Reflections { } public static final Class clazz$ClientboundBossEventPacket$UpdateNameOperation = requireNonNull( - ReflectionUtils.getClazz( - BukkitReflectionUtils.assembleMCClass("network.protocol.game.ClientboundBossEventPacket$UpdateNameOperation"), - BukkitReflectionUtils.assembleMCClass("network.protocol.game.PacketPlayOutBoss$e") + BukkitReflectionUtils.findReobfOrMojmapClass( + "network.protocol.game.PacketPlayOutBoss$e", + "network.protocol.game.ClientboundBossEventPacket$UpdateNameOperation" ) ); @@ -334,14 +334,14 @@ public class Reflections { ); public static final Class clazz$SoundEvent = requireNonNull( - ReflectionUtils.getClazz( - BukkitReflectionUtils.assembleMCClass("sounds.SoundEvent"), - BukkitReflectionUtils.assembleMCClass("sounds.SoundEffect") + BukkitReflectionUtils.findReobfOrMojmapClass( + "sounds.SoundEffect", + "sounds.SoundEvent" ) ); public static final Constructor constructor$SoundEvent = requireNonNull( - VersionHelper.isVersionNewerThan1_21_2() ? + VersionHelper.isOrAbove1_21_2() ? ReflectionUtils.getConstructor( clazz$SoundEvent, clazz$ResourceLocation, Optional.class ) : @@ -377,7 +377,7 @@ public class Reflections { public static final Object instance$MinecraftRegistry; static { - if (VersionHelper.isVersionNewerThan1_20()) { + if (VersionHelper.isOrAbove1_20()) { try { Method method = requireNonNull(ReflectionUtils.getMethod(clazz$CraftRegistry, new String[]{"getMinecraftRegistry"})); instance$MinecraftRegistry = method.invoke(null); @@ -390,15 +390,15 @@ public class Reflections { } public static final Class clazz$Component$Serializer = requireNonNull( - ReflectionUtils.getClazz( - BukkitReflectionUtils.assembleMCClass("network.chat.Component$Serializer"), - BukkitReflectionUtils.assembleMCClass("network.chat.IChatBaseComponent$ChatSerializer") + BukkitReflectionUtils.findReobfOrMojmapClass( + "network.chat.IChatBaseComponent$ChatSerializer", + "network.chat.Component$Serializer" ) ); - public static final Class clazz$HolderLookup$Provider = ReflectionUtils.getClazz( - BukkitReflectionUtils.assembleMCClass("core.HolderLookup$Provider"), - BukkitReflectionUtils.assembleMCClass("core.HolderLookup$b") + public static final Class clazz$HolderLookup$Provider = BukkitReflectionUtils.findReobfOrMojmapClass( + "core.HolderLookup$b", + "core.HolderLookup$Provider" ); @Deprecated @@ -438,29 +438,33 @@ public class Reflections { ) ); - public static final Class clazz$ServerPlayer = requireNonNull(ReflectionUtils.getClazz( - BukkitReflectionUtils.assembleMCClass("server.level.ServerPlayer"), - BukkitReflectionUtils.assembleMCClass("server.level.EntityPlayer") - )); + public static final Class clazz$ServerPlayer = requireNonNull( + BukkitReflectionUtils.findReobfOrMojmapClass( + "server.level.EntityPlayer", + "server.level.ServerPlayer" + ) + ); - public static final Class clazz$ServerGamePacketListenerImpl = requireNonNull(ReflectionUtils.getClazz( - BukkitReflectionUtils.assembleMCClass("server.network.ServerGamePacketListenerImpl"), - BukkitReflectionUtils.assembleMCClass("server.network.PlayerConnection") - )); + public static final Class clazz$ServerGamePacketListenerImpl = requireNonNull( + BukkitReflectionUtils.findReobfOrMojmapClass( + "server.network.PlayerConnection", + "server.network.ServerGamePacketListenerImpl" + ) + ); public static final Class clazz$ServerCommonPacketListenerImpl = requireNonNull( clazz$ServerGamePacketListenerImpl.getSuperclass() ); public static final Class clazz$Connection = requireNonNull( - ReflectionUtils.getClazz( - BukkitReflectionUtils.assembleMCClass("network.Connection"), - BukkitReflectionUtils.assembleMCClass("network.NetworkManager") + BukkitReflectionUtils.findReobfOrMojmapClass( + "network.NetworkManager", + "network.Connection" ) ); public static final Field field$ServerCommonPacketListenerImpl$connection = requireNonNull( - VersionHelper.isVersionNewerThan1_20_2() ? + VersionHelper.isOrAbove1_20_2() ? ReflectionUtils.getDeclaredField( clazz$ServerCommonPacketListenerImpl, clazz$Connection, 0 ) : @@ -493,7 +497,7 @@ public class Reflections { ); public static final Method method$Connection$sendPacketImmediate = requireNonNull( - VersionHelper.isVersionNewerThan1_20_2() ? + VersionHelper.isOrAbove1_20_2() ? ReflectionUtils.getDeclaredMethod( clazz$Connection, void.class, new String[] {"sendPacket", "b"}, clazz$Packet, clazz$PacketSendListener, boolean.class ) : @@ -515,16 +519,16 @@ public class Reflections { ); public static final Class clazz$EntityType = requireNonNull( - ReflectionUtils.getClazz( - BukkitReflectionUtils.assembleMCClass("world.entity.EntityType"), - BukkitReflectionUtils.assembleMCClass("world.entity.EntityTypes") + BukkitReflectionUtils.findReobfOrMojmapClass( + "world.entity.EntityTypes", + "world.entity.EntityType" ) ); public static final Class clazz$EntityType$EntityFactory = requireNonNull( - ReflectionUtils.getClazz( - BukkitReflectionUtils.assembleMCClass("world.entity.EntityType$EntityFactory"), - BukkitReflectionUtils.assembleMCClass("world.entity.EntityTypes$b") + BukkitReflectionUtils.findReobfOrMojmapClass( + "world.entity.EntityTypes$b", + "world.entity.EntityType$EntityFactory" ) ); @@ -535,9 +539,9 @@ public class Reflections { ); public static final Class clazz$ClientboundAddEntityPacket = requireNonNull( - ReflectionUtils.getClazz( - BukkitReflectionUtils.assembleMCClass("network.protocol.game.PacketPlayOutSpawnEntity"), - BukkitReflectionUtils.assembleMCClass("network.protocol.game.ClientboundAddEntityPacket") + BukkitReflectionUtils.findReobfOrMojmapClass( + "network.protocol.game.PacketPlayOutSpawnEntity", + "network.protocol.game.ClientboundAddEntityPacket" ) ); @@ -561,15 +565,16 @@ public class Reflections { ) ); - public static final Class clazz$PacketPlayOutNamedEntitySpawn = - ReflectionUtils.getClazz( - BukkitReflectionUtils.assembleMCClass("network.protocol.game.PacketPlayOutNamedEntitySpawn") + public static final Class clazz$ClientboundAddPlayerPacket = + BukkitReflectionUtils.findReobfOrMojmapClass( + "network.protocol.game.PacketPlayOutNamedEntitySpawn", + "network.protocol.game.ClientboundAddPlayerPacket" ); public static final Class clazz$ClientboundRemoveEntitiesPacket = requireNonNull( - ReflectionUtils.getClazz( - BukkitReflectionUtils.assembleMCClass("network.protocol.game.ClientboundRemoveEntitiesPacket"), - BukkitReflectionUtils.assembleMCClass("network.protocol.game.PacketPlayOutEntityDestroy") + BukkitReflectionUtils.findReobfOrMojmapClass( + "network.protocol.game.PacketPlayOutEntityDestroy", + "network.protocol.game.ClientboundRemoveEntitiesPacket" ) ); @@ -586,15 +591,15 @@ public class Reflections { ) ); - public static final Field field$PacketPlayOutNamedEntitySpawn$entityId = clazz$PacketPlayOutNamedEntitySpawn != null ? + public static final Field field$ClientboundAddPlayerPacket$entityId = clazz$ClientboundAddPlayerPacket != null ? ReflectionUtils.getDeclaredField( - clazz$PacketPlayOutNamedEntitySpawn, int.class, 0 + clazz$ClientboundAddPlayerPacket, int.class, 0 ) : null; public static final Class clazz$Vec3 = requireNonNull( - ReflectionUtils.getClazz( - BukkitReflectionUtils.assembleMCClass("world.phys.Vec3"), - BukkitReflectionUtils.assembleMCClass("world.phys.Vec3D") + BukkitReflectionUtils.findReobfOrMojmapClass( + "world.phys.Vec3D", + "world.phys.Vec3" ) ); @@ -640,9 +645,9 @@ public class Reflections { ); public static final Class clazz$ClientboundSetPassengersPacket = requireNonNull( - ReflectionUtils.getClazz( - BukkitReflectionUtils.assembleMCClass("network.protocol.game.PacketPlayOutMount"), - BukkitReflectionUtils.assembleMCClass("network.protocol.game.ClientboundSetPassengersPacket") + BukkitReflectionUtils.findReobfOrMojmapClass( + "network.protocol.game.PacketPlayOutMount", + "network.protocol.game.ClientboundSetPassengersPacket" ) ); @@ -679,9 +684,9 @@ public class Reflections { } public static final Class clazz$ClientboundSetEntityDataPacket = requireNonNull( - ReflectionUtils.getClazz( - BukkitReflectionUtils.assembleMCClass("network.protocol.game.PacketPlayOutEntityMetadata"), - BukkitReflectionUtils.assembleMCClass("network.protocol.game.ClientboundSetEntityDataPacket") + BukkitReflectionUtils.findReobfOrMojmapClass( + "network.protocol.game.PacketPlayOutEntityMetadata", + "network.protocol.game.ClientboundSetEntityDataPacket" ) ); @@ -691,23 +696,23 @@ public class Reflections { // ); public static final Class clazz$EntityDataSerializers = requireNonNull( - ReflectionUtils.getClazz( - BukkitReflectionUtils.assembleMCClass("network.syncher.EntityDataSerializers"), - BukkitReflectionUtils.assembleMCClass("network.syncher.DataWatcherRegistry") + BukkitReflectionUtils.findReobfOrMojmapClass( + "network.syncher.DataWatcherRegistry", + "network.syncher.EntityDataSerializers" ) ); public static final Class clazz$EntityDataSerializer = requireNonNull( - ReflectionUtils.getClazz( - BukkitReflectionUtils.assembleMCClass("network.syncher.EntityDataSerializer"), - BukkitReflectionUtils.assembleMCClass("network.syncher.DataWatcherSerializer") + BukkitReflectionUtils.findReobfOrMojmapClass( + "network.syncher.DataWatcherSerializer", + "network.syncher.EntityDataSerializer" ) ); public static final Class clazz$EntityDataAccessor = requireNonNull( - ReflectionUtils.getClazz( - BukkitReflectionUtils.assembleMCClass("network.syncher.EntityDataAccessor"), - BukkitReflectionUtils.assembleMCClass("network.syncher.DataWatcherObject") + BukkitReflectionUtils.findReobfOrMojmapClass( + "network.syncher.DataWatcherObject", + "network.syncher.EntityDataAccessor" ) ); @@ -718,9 +723,9 @@ public class Reflections { // ); public static final Class clazz$SynchedEntityData = requireNonNull( - ReflectionUtils.getClazz( - BukkitReflectionUtils.assembleMCClass("network.syncher.SynchedEntityData"), - BukkitReflectionUtils.assembleMCClass("network.syncher.DataWatcher") + BukkitReflectionUtils.findReobfOrMojmapClass( + "network.syncher.DataWatcher", + "network.syncher.SynchedEntityData" ) ); @@ -731,9 +736,9 @@ public class Reflections { ); public static final Class clazz$SynchedEntityData$DataValue = requireNonNull( - ReflectionUtils.getClazz( - BukkitReflectionUtils.assembleMCClass("network.syncher.SynchedEntityData$DataValue"), - BukkitReflectionUtils.assembleMCClass("network.syncher.DataWatcher$b") + BukkitReflectionUtils.findReobfOrMojmapClass( + "network.syncher.DataWatcher$b", + "network.syncher.SynchedEntityData$DataValue" ) ); @@ -836,16 +841,16 @@ public class Reflections { // ); public static final Class clazz$ClientboundUpdateAttributesPacket = requireNonNull( - ReflectionUtils.getClazz( - BukkitReflectionUtils.assembleMCClass("network.protocol.game.ClientboundUpdateAttributesPacket"), - BukkitReflectionUtils.assembleMCClass("network.protocol.game.PacketPlayOutUpdateAttributes") + BukkitReflectionUtils.findReobfOrMojmapClass( + "network.protocol.game.PacketPlayOutUpdateAttributes", + "network.protocol.game.ClientboundUpdateAttributesPacket" ) ); public static final Class clazz$AttributeInstance = requireNonNull( - ReflectionUtils.getClazz( - BukkitReflectionUtils.assembleMCClass("world.entity.ai.attributes.AttributeInstance"), - BukkitReflectionUtils.assembleMCClass("world.entity.ai.attributes.AttributeModifiable") + BukkitReflectionUtils.findReobfOrMojmapClass( + "world.entity.ai.attributes.AttributeModifiable", + "world.entity.ai.attributes.AttributeInstance" ) ); @@ -885,10 +890,10 @@ public class Reflections { } public static final Constructor constructor$AttributeModifier = requireNonNull( - !VersionHelper.isVersionNewerThan1_20_5() ? + !VersionHelper.isOrAbove1_20_5() ? ReflectionUtils.getConstructor(clazz$AttributeModifier, String.class, double.class, clazz$AttributeModifier$Operation): ( - !VersionHelper.isVersionNewerThan1_21() ? + !VersionHelper.isOrAbove1_21() ? ReflectionUtils.getConstructor(clazz$AttributeModifier, UUID.class, String.class, double.class, clazz$AttributeModifier$Operation) : ( ReflectionUtils.getConstructor(clazz$AttributeModifier, clazz$ResourceLocation, double.class, clazz$AttributeModifier$Operation) @@ -921,9 +926,9 @@ public class Reflections { ); public static final Class clazz$ClientboundUpdateAttributesPacket$AttributeSnapshot = requireNonNull( - ReflectionUtils.getClazz( - BukkitReflectionUtils.assembleMCClass("network.protocol.game.ClientboundUpdateAttributesPacket$AttributeSnapshot"), - BukkitReflectionUtils.assembleMCClass("network.protocol.game.PacketPlayOutUpdateAttributes$AttributeSnapshot") + BukkitReflectionUtils.findReobfOrMojmapClass( + "network.protocol.game.PacketPlayOutUpdateAttributes$AttributeSnapshot", + "network.protocol.game.ClientboundUpdateAttributesPacket$AttributeSnapshot" ) ); @@ -940,9 +945,9 @@ public class Reflections { ); public static final Class clazz$Holder$Reference = requireNonNull( - ReflectionUtils.getClazz( - BukkitReflectionUtils.assembleMCClass("core.Holder$Reference"), - BukkitReflectionUtils.assembleMCClass("core.Holder$c") + BukkitReflectionUtils.findReobfOrMojmapClass( + "core.Holder$c", + "core.Holder$Reference" ) ); @@ -974,14 +979,14 @@ public class Reflections { ); public static final Class clazz$Attribute = requireNonNull( - ReflectionUtils.getClazz( - BukkitReflectionUtils.assembleMCClass("world.entity.ai.attributes.Attribute"), - BukkitReflectionUtils.assembleMCClass("world.entity.ai.attributes.AttributeBase") + BukkitReflectionUtils.findReobfOrMojmapClass( + "world.entity.ai.attributes.AttributeBase", + "world.entity.ai.attributes.Attribute" ) ); public static final Constructor constructor$ClientboundUpdateAttributesPacket$AttributeSnapshot = requireNonNull( - VersionHelper.isVersionNewerThan1_20_5() ? + VersionHelper.isOrAbove1_20_5() ? ReflectionUtils.getConstructor( clazz$ClientboundUpdateAttributesPacket$AttributeSnapshot, clazz$Holder, double.class, Collection.class ) : @@ -1003,16 +1008,16 @@ public class Reflections { ); public static final Class clazz$ClientboundGameEventPacket = requireNonNull( - ReflectionUtils.getClazz( - BukkitReflectionUtils.assembleMCClass("network.protocol.game.ClientboundGameEventPacket"), - BukkitReflectionUtils.assembleMCClass("network.protocol.game.PacketPlayOutGameStateChange") + BukkitReflectionUtils.findReobfOrMojmapClass( + "network.protocol.game.PacketPlayOutGameStateChange", + "network.protocol.game.ClientboundGameEventPacket" ) ); public static final Class clazz$ClientboundGameEventPacket$Type = requireNonNull( - ReflectionUtils.getClazz( - BukkitReflectionUtils.assembleMCClass("network.protocol.game.ClientboundGameEventPacket$Type"), - BukkitReflectionUtils.assembleMCClass("network.protocol.game.PacketPlayOutGameStateChange$a") + BukkitReflectionUtils.findReobfOrMojmapClass( + "network.protocol.game.PacketPlayOutGameStateChange$a", + "network.protocol.game.ClientboundGameEventPacket$Type" ) ); @@ -1035,9 +1040,9 @@ public class Reflections { ); public static final Class clazz$GameType = requireNonNull( - ReflectionUtils.getClazz( - BukkitReflectionUtils.assembleMCClass("world.level.GameType"), - BukkitReflectionUtils.assembleMCClass("world.level.EnumGamemode") + BukkitReflectionUtils.findReobfOrMojmapClass( + "world.level.EnumGamemode", + "world.level.GameType" ) ); @@ -1048,9 +1053,9 @@ public class Reflections { ); public static final Class clazz$Biome = requireNonNull( - ReflectionUtils.getClazz( - BukkitReflectionUtils.assembleMCClass("world.level.biome.Biome"), - BukkitReflectionUtils.assembleMCClass("world.level.biome.BiomeBase") + BukkitReflectionUtils.findReobfOrMojmapClass( + "world.level.biome.BiomeBase", + "world.level.biome.Biome" ) ); @@ -1061,9 +1066,9 @@ public class Reflections { ); public static final Class clazz$ServerLevel = requireNonNull( - ReflectionUtils.getClazz( - BukkitReflectionUtils.assembleMCClass("server.level.ServerLevel"), - BukkitReflectionUtils.assembleMCClass("server.level.WorldServer") + BukkitReflectionUtils.findReobfOrMojmapClass( + "server.level.WorldServer", + "server.level.ServerLevel" ) ); @@ -1128,16 +1133,16 @@ public class Reflections { ); public static final Class clazz$RegistryAccess$Frozen = requireNonNull( - ReflectionUtils.getClazz( - BukkitReflectionUtils.assembleMCClass("core.RegistryAccess$Frozen"), - BukkitReflectionUtils.assembleMCClass("core.IRegistryCustom$Dimension") + BukkitReflectionUtils.findReobfOrMojmapClass( + "core.IRegistryCustom$Dimension", + "core.RegistryAccess$Frozen" ) ); public static final Class clazz$RegistryAccess = requireNonNull( - ReflectionUtils.getClazz( - BukkitReflectionUtils.assembleMCClass("core.RegistryAccess"), - BukkitReflectionUtils.assembleMCClass("core.IRegistryCustom") + BukkitReflectionUtils.findReobfOrMojmapClass( + "core.IRegistryCustom", + "core.RegistryAccess" ) ); @@ -1148,9 +1153,9 @@ public class Reflections { ); public static final Class clazz$Registry = requireNonNull( - requireNonNull(ReflectionUtils.getClazz( - BukkitReflectionUtils.assembleMCClass("core.WritableRegistry"), - BukkitReflectionUtils.assembleMCClass("core.IRegistryWritable") + requireNonNull(BukkitReflectionUtils.findReobfOrMojmapClass( + "core.IRegistryWritable", + "core.WritableRegistry" )).getInterfaces()[0] ); @@ -1185,9 +1190,9 @@ public class Reflections { ); public static final Class clazz$DefaultedRegistry = requireNonNull( - ReflectionUtils.getClazz( - BukkitReflectionUtils.assembleMCClass("core.DefaultedRegistry"), - BukkitReflectionUtils.assembleMCClass("core.RegistryBlocks") + BukkitReflectionUtils.findReobfOrMojmapClass( + "core.RegistryBlocks", + "core.DefaultedRegistry" ) ); @@ -1249,9 +1254,9 @@ public class Reflections { } public static final Class clazz$ClientboundSetPlayerTeamPacket = requireNonNull( - ReflectionUtils.getClazz( - BukkitReflectionUtils.assembleMCClass("network.protocol.game.ClientboundSetPlayerTeamPacket"), - BukkitReflectionUtils.assembleMCClass("network.protocol.game.PacketPlayOutScoreboardTeam") + BukkitReflectionUtils.findReobfOrMojmapClass( + "network.protocol.game.PacketPlayOutScoreboardTeam", + "network.protocol.game.ClientboundSetPlayerTeamPacket" ) ); @@ -1274,31 +1279,31 @@ public class Reflections { ); public static final Class clazz$ClientboundSetPlayerTeamPacket$Parameters = requireNonNull( - ReflectionUtils.getClazz( - BukkitReflectionUtils.assembleMCClass("network.protocol.game.ClientboundSetPlayerTeamPacket$Parameters"), - BukkitReflectionUtils.assembleMCClass("network.protocol.game.PacketPlayOutScoreboardTeam$b") + BukkitReflectionUtils.findReobfOrMojmapClass( + "network.protocol.game.PacketPlayOutScoreboardTeam$b", + "network.protocol.game.ClientboundSetPlayerTeamPacket$Parameters" ) ); public static final Class clazz$Team$Visibility = requireNonNull( - ReflectionUtils.getClazz( - BukkitReflectionUtils.assembleMCClass("world.scores.Team$Visibility"), - BukkitReflectionUtils.assembleMCClass("world.scores.ScoreboardTeamBase$EnumTeamPush") + BukkitReflectionUtils.findReobfOrMojmapClass( + "world.scores.ScoreboardTeamBase$EnumTeamPush", + "world.scores.Team$Visibility" ) ); public static final Field field$ClientboundSetPlayerTeamPacket$Parameters$nametagVisibility = requireNonNull( ReflectionUtils.getInstanceDeclaredField( clazz$ClientboundSetPlayerTeamPacket$Parameters, - VersionHelper.isVersionNewerThan1_21_5() ? clazz$Team$Visibility : String.class, + VersionHelper.isOrAbove1_21_5() ? clazz$Team$Visibility : String.class, 0 ) ); public static final Class clazz$ServerConnectionListener = requireNonNull( - ReflectionUtils.getClazz( - BukkitReflectionUtils.assembleMCClass("server.network.ServerConnectionListener"), - BukkitReflectionUtils.assembleMCClass("server.network.ServerConnection") + BukkitReflectionUtils.findReobfOrMojmapClass( + "server.network.ServerConnection", + "server.network.ServerConnectionListener" ) ); @@ -1347,37 +1352,37 @@ public class Reflections { } public static final Class clazz$ClientboundBlockUpdatePacket = requireNonNull( - ReflectionUtils.getClazz( - BukkitReflectionUtils.assembleMCClass("network.protocol.game.ClientboundBlockUpdatePacket"), - BukkitReflectionUtils.assembleMCClass("network.protocol.game.PacketPlayOutBlockChange") + BukkitReflectionUtils.findReobfOrMojmapClass( + "network.protocol.game.PacketPlayOutBlockChange", + "network.protocol.game.ClientboundBlockUpdatePacket" ) ); public static final Class clazz$ClientboundSectionBlocksUpdatePacket = requireNonNull( - ReflectionUtils.getClazz( - BukkitReflectionUtils.assembleMCClass("network.protocol.game.ClientboundSectionBlocksUpdatePacket"), - BukkitReflectionUtils.assembleMCClass("network.protocol.game.PacketPlayOutMultiBlockChange") + BukkitReflectionUtils.findReobfOrMojmapClass( + "network.protocol.game.PacketPlayOutMultiBlockChange", + "network.protocol.game.ClientboundSectionBlocksUpdatePacket" ) ); public static final Class clazz$BlockPos = requireNonNull( - ReflectionUtils.getClazz( - BukkitReflectionUtils.assembleMCClass("core.BlockPos"), - BukkitReflectionUtils.assembleMCClass("core.BlockPosition") + BukkitReflectionUtils.findReobfOrMojmapClass( + "core.BlockPosition", + "core.BlockPos" ) ); public static final Class clazz$SectionPos = requireNonNull( - ReflectionUtils.getClazz( - BukkitReflectionUtils.assembleMCClass("core.SectionPos"), - BukkitReflectionUtils.assembleMCClass("core.SectionPosition") + BukkitReflectionUtils.findReobfOrMojmapClass( + "core.SectionPosition", + "core.SectionPos" ) ); public static final Class clazz$Vec3i = requireNonNull( - ReflectionUtils.getClazz( - BukkitReflectionUtils.assembleMCClass("core.Vec3i"), - BukkitReflectionUtils.assembleMCClass("core.BaseBlockPosition") + BukkitReflectionUtils.findReobfOrMojmapClass( + "core.BaseBlockPosition", + "core.Vec3i" ) ); @@ -1394,9 +1399,9 @@ public class Reflections { // ); public static final Class clazz$BlockState = requireNonNull( - ReflectionUtils.getClazz( - BukkitReflectionUtils.assembleMCClass("world.level.block.state.BlockState"), - BukkitReflectionUtils.assembleMCClass("world.level.block.state.IBlockData") + BukkitReflectionUtils.findReobfOrMojmapClass( + "world.level.block.state.IBlockData", + "world.level.block.state.BlockState" ) ); @@ -1437,9 +1442,9 @@ public class Reflections { ); public static final Class clazz$IdMapper = requireNonNull( - ReflectionUtils.getClazz( - BukkitReflectionUtils.assembleMCClass("core.IdMapper"), - BukkitReflectionUtils.assembleMCClass("core.RegistryBlockID") + BukkitReflectionUtils.findReobfOrMojmapClass( + "core.RegistryBlockID", + "core.IdMapper" ) ); @@ -1480,9 +1485,9 @@ public class Reflections { ); public static final Class clazz$LevelAccessor = requireNonNull( - ReflectionUtils.getClazz( - BukkitReflectionUtils.assembleMCClass("world.level.LevelAccessor"), - BukkitReflectionUtils.assembleMCClass("world.level.GeneratorAccess") + BukkitReflectionUtils.findReobfOrMojmapClass( + "world.level.GeneratorAccess", + "world.level.LevelAccessor" ) ); @@ -1497,9 +1502,9 @@ public class Reflections { } public static final Class clazz$Direction = requireNonNull( - ReflectionUtils.getClazz( - BukkitReflectionUtils.assembleMCClass("core.Direction"), - BukkitReflectionUtils.assembleMCClass("core.EnumDirection") + BukkitReflectionUtils.findReobfOrMojmapClass( + "core.EnumDirection", + "core.Direction" ) ); @@ -1634,9 +1639,9 @@ public class Reflections { ); public static final Class clazz$FriendlyByteBuf = requireNonNull( - ReflectionUtils.getClazz( - BukkitReflectionUtils.assembleMCClass("network.FriendlyByteBuf"), - BukkitReflectionUtils.assembleMCClass("network.PacketDataSerializer") + BukkitReflectionUtils.findReobfOrMojmapClass( + "network.PacketDataSerializer", + "network.FriendlyByteBuf" ) ); @@ -1669,30 +1674,30 @@ public class Reflections { ); public static final Class clazz$PalettedContainer = requireNonNull( - ReflectionUtils.getClazz( - BukkitReflectionUtils.assembleMCClass("world.level.chunk.PalettedContainer"), - BukkitReflectionUtils.assembleMCClass("world.level.chunk.DataPaletteBlock") + BukkitReflectionUtils.findReobfOrMojmapClass( + "world.level.chunk.DataPaletteBlock", + "world.level.chunk.PalettedContainer" ) ); public static final Class clazz$PalettedContainer$Data = requireNonNull( - ReflectionUtils.getClazz( - BukkitReflectionUtils.assembleMCClass("world.level.chunk.PalettedContainer$Data"), - BukkitReflectionUtils.assembleMCClass("world.level.chunk.DataPaletteBlock$c") + BukkitReflectionUtils.findReobfOrMojmapClass( + "world.level.chunk.DataPaletteBlock$c", + "world.level.chunk.PalettedContainer$Data" ) ); public static final Class clazz$BitStorage = requireNonNull( - ReflectionUtils.getClazz( - BukkitReflectionUtils.assembleMCClass("util.BitStorage"), - BukkitReflectionUtils.assembleMCClass("util.DataBits") + BukkitReflectionUtils.findReobfOrMojmapClass( + "util.DataBits", + "util.BitStorage" ) ); public static final Class clazz$Palette = requireNonNull( - ReflectionUtils.getClazz( - BukkitReflectionUtils.assembleMCClass("world.level.chunk.Palette"), - BukkitReflectionUtils.assembleMCClass("world.level.chunk.DataPalette") + BukkitReflectionUtils.findReobfOrMojmapClass( + "world.level.chunk.DataPalette", + "world.level.chunk.Palette" ) ); @@ -1761,9 +1766,9 @@ public class Reflections { ); public static final Class clazz$ClientboundPlayerInfoUpdatePacket$Action = requireNonNull( - ReflectionUtils.getClazz( - BukkitReflectionUtils.assembleMCClass("network.protocol.game.ClientboundPlayerInfoUpdatePacket$Action"), - BukkitReflectionUtils.assembleMCClass("network.protocol.game.ClientboundPlayerInfoUpdatePacket$a") + BukkitReflectionUtils.findReobfOrMojmapClass( + "network.protocol.game.ClientboundPlayerInfoUpdatePacket$a", + "network.protocol.game.ClientboundPlayerInfoUpdatePacket$Action" ) ); @@ -1829,30 +1834,30 @@ public class Reflections { ); public static final Class clazz$ChunkAccess = requireNonNull( - ReflectionUtils.getClazz( - BukkitReflectionUtils.assembleMCClass("world.level.chunk.ChunkAccess"), - BukkitReflectionUtils.assembleMCClass("world.level.chunk.IChunkAccess") + BukkitReflectionUtils.findReobfOrMojmapClass( + "world.level.chunk.IChunkAccess", + "world.level.chunk.ChunkAccess" ) ); public static final Class clazz$LevelChunk = requireNonNull( - ReflectionUtils.getClazz( - BukkitReflectionUtils.assembleMCClass("world.level.chunk.LevelChunk"), - BukkitReflectionUtils.assembleMCClass("world.level.chunk.Chunk") + BukkitReflectionUtils.findReobfOrMojmapClass( + "world.level.chunk.Chunk", + "world.level.chunk.LevelChunk" ) ); public static final Class clazz$LevelChunkSection = requireNonNull( - ReflectionUtils.getClazz( - BukkitReflectionUtils.assembleMCClass("world.level.chunk.LevelChunkSection"), - BukkitReflectionUtils.assembleMCClass("world.level.chunk.ChunkSection") + BukkitReflectionUtils.findReobfOrMojmapClass( + "world.level.chunk.ChunkSection", + "world.level.chunk.LevelChunkSection" ) ); public static final Class clazz$ServerChunkCache = requireNonNull( - ReflectionUtils.getClazz( - BukkitReflectionUtils.assembleMCClass("server.level.ServerChunkCache"), - BukkitReflectionUtils.assembleMCClass("server.level.ChunkProviderServer") + BukkitReflectionUtils.findReobfOrMojmapClass( + "server.level.ChunkProviderServer", + "server.level.ServerChunkCache" ) ); @@ -1882,23 +1887,23 @@ public class Reflections { ); public static final Class clazz$BlockEntity = requireNonNull( - ReflectionUtils.getClazz( - BukkitReflectionUtils.assembleMCClass("world.level.block.entity.BlockEntity"), - BukkitReflectionUtils.assembleMCClass("world.level.block.entity.TileEntity") + BukkitReflectionUtils.findReobfOrMojmapClass( + "world.level.block.entity.TileEntity", + "world.level.block.entity.BlockEntity" ) ); public static final Class clazz$AbstractFurnaceBlockEntity = requireNonNull( - ReflectionUtils.getClazz( - BukkitReflectionUtils.assembleMCClass("world.level.block.entity.AbstractFurnaceBlockEntity"), - BukkitReflectionUtils.assembleMCClass("world.level.block.entity.TileEntityFurnace") + BukkitReflectionUtils.findReobfOrMojmapClass( + "world.level.block.entity.TileEntityFurnace", + "world.level.block.entity.AbstractFurnaceBlockEntity" ) ); public static final Class clazz$CampfireBlockEntity = requireNonNull( - ReflectionUtils.getClazz( - BukkitReflectionUtils.assembleMCClass("world.level.block.entity.CampfireBlockEntity"), - BukkitReflectionUtils.assembleMCClass("world.level.block.entity.TileEntityCampfire") + BukkitReflectionUtils.findReobfOrMojmapClass( + "world.level.block.entity.TileEntityCampfire", + "world.level.block.entity.CampfireBlockEntity" ) ); @@ -1938,23 +1943,23 @@ public class Reflections { ); public static final Class clazz$StatePredicate = requireNonNull( - ReflectionUtils.getClazz( - BukkitReflectionUtils.assembleMCClass("world.level.block.state.BlockBehaviour$StatePredicate"), - BukkitReflectionUtils.assembleMCClass("world.level.block.state.BlockBase$f") + BukkitReflectionUtils.findReobfOrMojmapClass( + "world.level.block.state.BlockBase$f", + "world.level.block.state.BlockBehaviour$StatePredicate" ) ); public static final Class clazz$BlockBehaviour$Properties = requireNonNull( - ReflectionUtils.getClazz( - BukkitReflectionUtils.assembleMCClass("world.level.block.state.BlockBehaviour$Properties"), - BukkitReflectionUtils.assembleMCClass("world.level.block.state.BlockBase$Info") + BukkitReflectionUtils.findReobfOrMojmapClass( + "world.level.block.state.BlockBase$Info", + "world.level.block.state.BlockBehaviour$Properties" ) ); public static final Class clazz$BlockBehaviour = requireNonNull( - ReflectionUtils.getClazz( - BukkitReflectionUtils.assembleMCClass("world.level.block.state.BlockBehaviour"), - BukkitReflectionUtils.assembleMCClass("world.level.block.state.BlockBase") + BukkitReflectionUtils.findReobfOrMojmapClass( + "world.level.block.state.BlockBase", + "world.level.block.state.BlockBehaviour" ) ); @@ -1974,21 +1979,22 @@ public class Reflections { public static final Class clazz$MobEffect = requireNonNull( ReflectionUtils.getClazz( - BukkitReflectionUtils.assembleMCClass("world.effect.MobEffectList"), - BukkitReflectionUtils.assembleMCClass("world.effect.MobEffect") + BukkitReflectionUtils.assembleMCClass("world.effect.MobEffectList"), // 这里paper会自动获取到NM.world.effect.MobEffect + BukkitReflectionUtils.assembleMCClass("world.effect.MobEffect") // 如果插件是mojmap就会走这个 ) ); public static final Class clazz$MobEffectInstance = requireNonNull( - ReflectionUtils.getClazz( - BukkitReflectionUtils.assembleMCClass("world.effect.MobEffectInstance"), - BukkitReflectionUtils.assembleMCClass("world.effect.MobEffect") + BukkitReflectionUtils.findReobfOrMojmapClass( + "world.effect.MobEffect", + "world.effect.MobEffectInstance" ) ); public static final Class clazz$ParticleType = requireNonNull( - Optional.of(Objects.requireNonNull(ReflectionUtils.getClazz( - BukkitReflectionUtils.assembleMCClass("core.particles.ParticleType")))).map(it -> { + Optional.of(Objects.requireNonNull( + BukkitReflectionUtils.findReobfOrMojmapClass("core.particles.Particle", "core.particles.ParticleType") + )).map(it -> { if (it.getSuperclass() != Object.class) { return it.getSuperclass(); } @@ -1997,9 +2003,9 @@ public class Reflections { ); public static final Class clazz$SoundType = requireNonNull( - ReflectionUtils.getClazz( - BukkitReflectionUtils.assembleMCClass("world.level.block.SoundType"), - BukkitReflectionUtils.assembleMCClass("world.level.block.SoundEffectType") + BukkitReflectionUtils.findReobfOrMojmapClass( + "world.level.block.SoundEffectType", + "world.level.block.SoundType" ) ); @@ -2010,9 +2016,9 @@ public class Reflections { ); public static final Class clazz$ItemLike = requireNonNull( - ReflectionUtils.getClazz( - BukkitReflectionUtils.assembleMCClass("world.level.ItemLike"), - BukkitReflectionUtils.assembleMCClass("world.level.IMaterial") + BukkitReflectionUtils.findReobfOrMojmapClass( + "world.level.IMaterial", + "world.level.ItemLike" ) ); @@ -2023,30 +2029,30 @@ public class Reflections { ); public static final Class clazz$FluidState = requireNonNull( - ReflectionUtils.getClazz( - BukkitReflectionUtils.assembleMCClass("world.level.material.Fluid"), - BukkitReflectionUtils.assembleMCClass("world.level.material.FluidState") + BukkitReflectionUtils.findReobfOrMojmapClass( + "world.level.material.Fluid", + "world.level.material.FluidState" ) ); public static final Class clazz$Fluid = requireNonNull( ReflectionUtils.getClazz( - BukkitReflectionUtils.assembleMCClass("world.level.material.FluidType"), - BukkitReflectionUtils.assembleMCClass("world.level.material.Fluid") + BukkitReflectionUtils.assembleMCClass("world.level.material.FluidType"), // 这里paper会自动获取到NM.world.level.material.Fluid + BukkitReflectionUtils.assembleMCClass("world.level.material.Fluid") // 如果插件是mojmap就会走这个 ) ); public static final Class clazz$RecipeType = requireNonNull( - ReflectionUtils.getClazz( - BukkitReflectionUtils.assembleMCClass("world.item.crafting.RecipeType"), - BukkitReflectionUtils.assembleMCClass("world.item.crafting.Recipes") + BukkitReflectionUtils.findReobfOrMojmapClass( + "world.item.crafting.Recipes", + "world.item.crafting.RecipeType" ) ); public static final Class clazz$WorldGenLevel = requireNonNull( - ReflectionUtils.getClazz( - BukkitReflectionUtils.assembleMCClass("world.level.WorldGenLevel"), - BukkitReflectionUtils.assembleMCClass("world.level.GeneratorAccessSeed") + BukkitReflectionUtils.findReobfOrMojmapClass( + "world.level.GeneratorAccessSeed", + "world.level.WorldGenLevel" ) ); @@ -2058,15 +2064,15 @@ public class Reflections { // 1.20.1-1.20.2 public static final Class clazz$AbstractTreeGrower = - ReflectionUtils.getClazz( - BukkitReflectionUtils.assembleMCClass("world.level.block.grower.AbstractTreeGrower"), - BukkitReflectionUtils.assembleMCClass("world.level.block.grower.WorldGenTreeProvider") + BukkitReflectionUtils.findReobfOrMojmapClass( + "world.level.block.grower.WorldGenTreeProvider", + "world.level.block.grower.AbstractTreeGrower" ); public static final Class clazz$ConfiguredFeature = requireNonNull( - ReflectionUtils.getClazz( - BukkitReflectionUtils.assembleMCClass("world.level.levelgen.feature.ConfiguredFeature"), - BukkitReflectionUtils.assembleMCClass("world.level.levelgen.feature.WorldGenFeatureConfigured") + BukkitReflectionUtils.findReobfOrMojmapClass( + "world.level.levelgen.feature.WorldGenFeatureConfigured", + "world.level.levelgen.feature.ConfiguredFeature" ) ); @@ -2158,7 +2164,7 @@ public class Reflections { registries$Item = field.get(null); } else if (type == clazz$Fluid) { registries$Fluid = field.get(null); - } else if (VersionHelper.isVersionNewerThan1_21() && type == clazz$JukeboxSong) { + } else if (VersionHelper.isOrAbove1_21() && type == clazz$JukeboxSong) { registries$JukeboxSong = field.get(null); } } @@ -2226,9 +2232,9 @@ public class Reflections { ); public static final Class clazz$StateDefinition = requireNonNull( - ReflectionUtils.getClazz( - BukkitReflectionUtils.assembleMCClass("world.level.block.state.StateDefinition"), - BukkitReflectionUtils.assembleMCClass("world.level.block.state.BlockStateList") + BukkitReflectionUtils.findReobfOrMojmapClass( + "world.level.block.state.BlockStateList", + "world.level.block.state.StateDefinition" ) ); @@ -2245,9 +2251,9 @@ public class Reflections { ); public static final Class clazz$MappedRegistry = requireNonNull( - ReflectionUtils.getClazz( - BukkitReflectionUtils.assembleMCClass("core.MappedRegistry"), - BukkitReflectionUtils.assembleMCClass("core.RegistryMaterials") + BukkitReflectionUtils.findReobfOrMojmapClass( + "core.RegistryMaterials", + "core.MappedRegistry" ) ); @@ -2276,9 +2282,9 @@ public class Reflections { ); public static final Class clazz$MapColor = requireNonNull( - ReflectionUtils.getClazz( - BukkitReflectionUtils.assembleMCClass("world.level.material.MapColor"), - BukkitReflectionUtils.assembleMCClass("world.level.material.MaterialMapColor") + BukkitReflectionUtils.findReobfOrMojmapClass( + "world.level.material.MaterialMapColor", + "world.level.material.MapColor" ) ); @@ -2289,9 +2295,9 @@ public class Reflections { ); public static final Class clazz$PushReaction = requireNonNull( - ReflectionUtils.getClazz( - BukkitReflectionUtils.assembleMCClass("world.level.material.PushReaction"), - BukkitReflectionUtils.assembleMCClass("world.level.material.EnumPistonReaction") + BukkitReflectionUtils.findReobfOrMojmapClass( + "world.level.material.EnumPistonReaction", + "world.level.material.PushReaction" ) ); @@ -2302,9 +2308,9 @@ public class Reflections { ); public static final Class clazz$NoteBlockInstrument = requireNonNull( - ReflectionUtils.getClazz( - BukkitReflectionUtils.assembleMCClass("world.level.block.state.properties.NoteBlockInstrument"), - BukkitReflectionUtils.assembleMCClass("world.level.block.state.properties.BlockPropertyInstrument") + BukkitReflectionUtils.findReobfOrMojmapClass( + "world.level.block.state.properties.BlockPropertyInstrument", + "world.level.block.state.properties.NoteBlockInstrument" ) ); @@ -2315,16 +2321,16 @@ public class Reflections { ); public static final Class clazz$BlockStateBase = requireNonNull( - ReflectionUtils.getClazz( - BukkitReflectionUtils.assembleMCClass("world.level.block.state.BlockBehaviour$BlockStateBase"), - BukkitReflectionUtils.assembleMCClass("world.level.block.state.BlockBase$BlockData") + BukkitReflectionUtils.findReobfOrMojmapClass( + "world.level.block.state.BlockBase$BlockData", + "world.level.block.state.BlockBehaviour$BlockStateBase" ) ); public static final Class clazz$BlockStateBase$Cache = requireNonNull( - ReflectionUtils.getClazz( - BukkitReflectionUtils.assembleMCClass("world.level.block.state.BlockBehaviour$BlockStateBase$Cache"), - BukkitReflectionUtils.assembleMCClass("world.level.block.state.BlockBase$BlockData$Cache") + BukkitReflectionUtils.findReobfOrMojmapClass( + "world.level.block.state.BlockBase$BlockData$Cache", + "world.level.block.state.BlockBehaviour$BlockStateBase$Cache" ) ); @@ -2437,9 +2443,9 @@ public class Reflections { ); public static final Class clazz$AABB = requireNonNull( - ReflectionUtils.getClazz( - BukkitReflectionUtils.assembleMCClass("world.phys.AABB"), - BukkitReflectionUtils.assembleMCClass("world.phys.AxisAlignedBB") + BukkitReflectionUtils.findReobfOrMojmapClass( + "world.phys.AxisAlignedBB", + "world.phys.AABB" ) ); @@ -2493,16 +2499,16 @@ public class Reflections { ); public static final Class clazz$BlockGetter = requireNonNull( - ReflectionUtils.getClazz( - BukkitReflectionUtils.assembleMCClass("world.level.BlockGetter"), - BukkitReflectionUtils.assembleMCClass("world.level.IBlockAccess") + BukkitReflectionUtils.findReobfOrMojmapClass( + "world.level.IBlockAccess", + "world.level.BlockGetter" ) ); public static final Class clazz$StateHolder = requireNonNull( - ReflectionUtils.getClazz( - BukkitReflectionUtils.assembleMCClass("world.level.block.state.StateHolder"), - BukkitReflectionUtils.assembleMCClass("world.level.block.state.IBlockDataHolder") + BukkitReflectionUtils.findReobfOrMojmapClass( + "world.level.block.state.IBlockDataHolder", + "world.level.block.state.StateHolder" ) ); @@ -2513,9 +2519,9 @@ public class Reflections { ); public static final Class clazz$CollisionContext = requireNonNull( - ReflectionUtils.getClazz( - BukkitReflectionUtils.assembleMCClass("world.phys.shapes.CollisionContext"), - BukkitReflectionUtils.assembleMCClass("world.phys.shapes.VoxelShapeCollision") + BukkitReflectionUtils.findReobfOrMojmapClass( + "world.phys.shapes.VoxelShapeCollision", + "world.phys.shapes.CollisionContext" ) ); @@ -2555,10 +2561,11 @@ public class Reflections { ) ); - public static final Class clazz$MappedRegistry$TagSet = ReflectionUtils.getClazz( - BukkitReflectionUtils.assembleMCClass("core.MappedRegistry$TagSet") - //BukkitReflectionUtils.assembleMCClass("core.RegistryMaterials$TagSet") 1.21.2+ - ); + public static final Class clazz$MappedRegistry$TagSet = + BukkitReflectionUtils.findReobfOrMojmapClass( + "RegistryMaterials$a", + "core.MappedRegistry$TagSet" + ); public static final Field field$MappedRegistry$allTags = Optional.ofNullable(clazz$MappedRegistry$TagSet) .map(it -> ReflectionUtils.getDeclaredField(clazz$MappedRegistry, it, 0)) @@ -2579,29 +2586,29 @@ public class Reflections { ); public static final Class clazz$ClientboundLevelParticlesPacket = requireNonNull( - ReflectionUtils.getClazz( - BukkitReflectionUtils.assembleMCClass("network.protocol.game.ClientboundLevelParticlesPacket"), - BukkitReflectionUtils.assembleMCClass("network.protocol.game.PacketPlayOutWorldParticles") + BukkitReflectionUtils.findReobfOrMojmapClass( + "network.protocol.game.PacketPlayOutWorldParticles", + "network.protocol.game.ClientboundLevelParticlesPacket" ) ); public static final Constructor constructor$ClientboundLevelParticlesPacket = requireNonNull( - VersionHelper.isVersionNewerThan1_20_5() ? + VersionHelper.isOrAbove1_20_5() ? ReflectionUtils.getDeclaredConstructor(clazz$ClientboundLevelParticlesPacket, clazz$RegistryFriendlyByteBuf) : ReflectionUtils.getConstructor(clazz$ClientboundLevelParticlesPacket, clazz$FriendlyByteBuf) ); public static final Class clazz$ParticleOptions = requireNonNull( - ReflectionUtils.getClazz( - BukkitReflectionUtils.assembleMCClass("core.particles.ParticleOptions"), - BukkitReflectionUtils.assembleMCClass("core.particles.ParticleParam") + BukkitReflectionUtils.findReobfOrMojmapClass( + "core.particles.ParticleParam", + "core.particles.ParticleOptions" ) ); public static final Class clazz$BlockParticleOption = requireNonNull( - ReflectionUtils.getClazz( - BukkitReflectionUtils.assembleMCClass("core.particles.BlockParticleOption"), - BukkitReflectionUtils.assembleMCClass("core.particles.ParticleParamBlock") + BukkitReflectionUtils.findReobfOrMojmapClass( + "core.particles.ParticleParamBlock", + "core.particles.BlockParticleOption" ) ); @@ -2693,16 +2700,16 @@ public class Reflections { ); public static final Class clazz$ClientboundLightUpdatePacket = requireNonNull( - ReflectionUtils.getClazz( - BukkitReflectionUtils.assembleMCClass("network.protocol.game.ClientboundLightUpdatePacket"), - BukkitReflectionUtils.assembleMCClass("network.protocol.game.PacketPlayOutLightUpdate") + BukkitReflectionUtils.findReobfOrMojmapClass( + "network.protocol.game.PacketPlayOutLightUpdate", + "network.protocol.game.ClientboundLightUpdatePacket" ) ); public static final Class clazz$ChunkPos = requireNonNull( - ReflectionUtils.getClazz( - BukkitReflectionUtils.assembleMCClass("world.level.ChunkPos"), - BukkitReflectionUtils.assembleMCClass("world.level.ChunkCoordIntPair") + BukkitReflectionUtils.findReobfOrMojmapClass( + "world.level.ChunkCoordIntPair", + "world.level.ChunkPos" ) ); @@ -2727,23 +2734,23 @@ public class Reflections { ); public static final Class clazz$ChunkHolder = requireNonNull( - ReflectionUtils.getClazz( - BukkitReflectionUtils.assembleMCClass("server.level.ChunkHolder"), - BukkitReflectionUtils.assembleMCClass("server.level.PlayerChunk") + BukkitReflectionUtils.findReobfOrMojmapClass( + "server.level.PlayerChunk", + "server.level.ChunkHolder" ) ); public static final Class clazz$ChunkMap = requireNonNull( - ReflectionUtils.getClazz( - BukkitReflectionUtils.assembleMCClass("server.level.ChunkMap"), - BukkitReflectionUtils.assembleMCClass("server.level.PlayerChunkMap") + BukkitReflectionUtils.findReobfOrMojmapClass( + "server.level.PlayerChunkMap", + "server.level.ChunkMap" ) ); public static final Class clazz$ChunkHolder$PlayerProvider = requireNonNull( - ReflectionUtils.getClazz( - BukkitReflectionUtils.assembleMCClass("server.level.ChunkHolder$PlayerProvider"), - BukkitReflectionUtils.assembleMCClass("server.level.PlayerChunk$d") + BukkitReflectionUtils.findReobfOrMojmapClass( + "server.level.PlayerChunk$d", + "server.level.ChunkHolder$PlayerProvider" ) ); @@ -2798,9 +2805,9 @@ public class Reflections { ); public static final Class clazz$LightLayer = requireNonNull( - ReflectionUtils.getClazz( - BukkitReflectionUtils.assembleMCClass("world.level.LightLayer"), - BukkitReflectionUtils.assembleMCClass("world.level.EnumSkyBlock") + BukkitReflectionUtils.findReobfOrMojmapClass( + "world.level.EnumSkyBlock", + "world.level.LightLayer" ) ); @@ -2821,22 +2828,22 @@ public class Reflections { } public static final Method method$ChunkHolder$sectionLightChanged = requireNonNull( - VersionHelper.isVersionNewerThan1_21_2() ? + VersionHelper.isOrAbove1_21_2() ? ReflectionUtils.getMethod(clazz$ChunkHolder, boolean.class, clazz$LightLayer, int.class) : ReflectionUtils.getMethod(clazz$ChunkHolder, void.class, clazz$LightLayer, int.class) ); public static final Class clazz$ServerboundPlayerActionPacket = requireNonNull( - ReflectionUtils.getClazz( - BukkitReflectionUtils.assembleMCClass("network.protocol.game.ServerboundPlayerActionPacket"), - BukkitReflectionUtils.assembleMCClass("network.protocol.game.PacketPlayInBlockDig") + BukkitReflectionUtils.findReobfOrMojmapClass( + "network.protocol.game.PacketPlayInBlockDig", + "network.protocol.game.ServerboundPlayerActionPacket" ) ); public static final Class clazz$ServerboundPlayerActionPacket$Action = requireNonNull( - ReflectionUtils.getClazz( - BukkitReflectionUtils.assembleMCClass("network.protocol.game.ServerboundPlayerActionPacket$Action"), - BukkitReflectionUtils.assembleMCClass("network.protocol.game.PacketPlayInBlockDig$EnumPlayerDigType") + BukkitReflectionUtils.findReobfOrMojmapClass( + "network.protocol.game.PacketPlayInBlockDig$EnumPlayerDigType", + "network.protocol.game.ServerboundPlayerActionPacket$Action" ) ); @@ -2881,18 +2888,18 @@ public class Reflections { static { try { - if (VersionHelper.isVersionNewerThan1_20_5()) { - Object block_break_speed = FastNMS.INSTANCE.method$ResourceLocation$fromNamespaceAndPath("minecraft", VersionHelper.isVersionNewerThan1_21_2() ? "block_break_speed" : "player.block_break_speed"); + if (VersionHelper.isOrAbove1_20_5()) { + Object block_break_speed = FastNMS.INSTANCE.method$ResourceLocation$fromNamespaceAndPath("minecraft", VersionHelper.isOrAbove1_21_2() ? "block_break_speed" : "player.block_break_speed"); @SuppressWarnings("unchecked") Optional breakSpeedHolder = (Optional) method$Registry$getHolder0.invoke(instance$BuiltInRegistries$ATTRIBUTE, block_break_speed); instance$Holder$Attribute$block_break_speed = breakSpeedHolder.orElse(null); - Object block_interaction_range = FastNMS.INSTANCE.method$ResourceLocation$fromNamespaceAndPath("minecraft", VersionHelper.isVersionNewerThan1_21_2() ? "block_interaction_range" : "player.block_interaction_range"); + Object block_interaction_range = FastNMS.INSTANCE.method$ResourceLocation$fromNamespaceAndPath("minecraft", VersionHelper.isOrAbove1_21_2() ? "block_interaction_range" : "player.block_interaction_range"); @SuppressWarnings("unchecked") Optional blockInteractionRangeHolder = (Optional) method$Registry$getHolder0.invoke(instance$BuiltInRegistries$ATTRIBUTE, block_interaction_range); instance$Holder$Attribute$block_interaction_range = blockInteractionRangeHolder.orElse(null); - Object scale = FastNMS.INSTANCE.method$ResourceLocation$fromNamespaceAndPath("minecraft", VersionHelper.isVersionNewerThan1_21_2() ? "scale" : "generic.scale"); + Object scale = FastNMS.INSTANCE.method$ResourceLocation$fromNamespaceAndPath("minecraft", VersionHelper.isOrAbove1_21_2() ? "scale" : "generic.scale"); @SuppressWarnings("unchecked") Optional scaleHolder = (Optional) method$Registry$getHolder0.invoke(instance$BuiltInRegistries$ATTRIBUTE, scale); instance$Holder$Attribute$scale = scaleHolder.orElse(null); @@ -2907,15 +2914,15 @@ public class Reflections { } public static final Method method$ServerPlayer$getAttribute = requireNonNull( - VersionHelper.isVersionNewerThan1_20_5() ? + VersionHelper.isOrAbove1_20_5() ? ReflectionUtils.getMethod(clazz$ServerPlayer, clazz$AttributeInstance, clazz$Holder) : ReflectionUtils.getMethod(clazz$ServerPlayer, clazz$AttributeInstance, clazz$Attribute) ); public static final Class clazz$ServerPlayerGameMode = requireNonNull( - ReflectionUtils.getClazz( - BukkitReflectionUtils.assembleMCClass("server.level.ServerPlayerGameMode"), - BukkitReflectionUtils.assembleMCClass("server.level.PlayerInteractManager") + BukkitReflectionUtils.findReobfOrMojmapClass( + "server.level.PlayerInteractManager", + "server.level.ServerPlayerGameMode" ) ); @@ -2962,9 +2969,9 @@ public class Reflections { ); public static final Class clazz$Player = requireNonNull( - ReflectionUtils.getClazz( - BukkitReflectionUtils.assembleMCClass("world.entity.player.Player"), - BukkitReflectionUtils.assembleMCClass("world.entity.player.EntityHuman") + BukkitReflectionUtils.findReobfOrMojmapClass( + "world.entity.player.EntityHuman", + "world.entity.player.Player" ) ); @@ -2991,9 +2998,9 @@ public class Reflections { } public static final Class clazz$Level = requireNonNull( - ReflectionUtils.getClazz( - BukkitReflectionUtils.assembleMCClass("world.level.Level"), - BukkitReflectionUtils.assembleMCClass("world.level.World") + BukkitReflectionUtils.findReobfOrMojmapClass( + "world.level.World", + "world.level.Level" ) ); @@ -3010,9 +3017,9 @@ public class Reflections { // ); public static final Class clazz$ClientboundBlockDestructionPacket = requireNonNull( - ReflectionUtils.getClazz( - BukkitReflectionUtils.assembleMCClass("network.protocol.game.ClientboundBlockDestructionPacket"), - BukkitReflectionUtils.assembleMCClass("network.protocol.game.PacketPlayOutBlockBreakAnimation") + BukkitReflectionUtils.findReobfOrMojmapClass( + "network.protocol.game.PacketPlayOutBlockBreakAnimation", + "network.protocol.game.ClientboundBlockDestructionPacket" ) ); @@ -3023,16 +3030,16 @@ public class Reflections { // ); public static final Class clazz$ServerboundSwingPacket = requireNonNull( - ReflectionUtils.getClazz( - BukkitReflectionUtils.assembleMCClass("network.protocol.game.ServerboundSwingPacket"), - BukkitReflectionUtils.assembleMCClass("network.protocol.game.PacketPlayInArmAnimation") + BukkitReflectionUtils.findReobfOrMojmapClass( + "network.protocol.game.PacketPlayInArmAnimation", + "network.protocol.game.ServerboundSwingPacket" ) ); public static final Class clazz$InteractionHand = requireNonNull( - ReflectionUtils.getClazz( - BukkitReflectionUtils.assembleMCClass("world.InteractionHand"), - BukkitReflectionUtils.assembleMCClass("world.EnumHand") + BukkitReflectionUtils.findReobfOrMojmapClass( + "world.EnumHand", + "world.InteractionHand" ) ); @@ -3063,9 +3070,9 @@ public class Reflections { } public static final Class clazz$EquipmentSlot = requireNonNull( - ReflectionUtils.getClazz( - BukkitReflectionUtils.assembleMCClass("world.entity.EquipmentSlot"), - BukkitReflectionUtils.assembleMCClass("world.entity.EnumItemSlot") + BukkitReflectionUtils.findReobfOrMojmapClass( + "world.entity.EnumItemSlot", + "world.entity.EquipmentSlot" ) ); @@ -3099,9 +3106,9 @@ public class Reflections { } public static final Class clazz$ClientboundSetEquipmentPacket = requireNonNull( - ReflectionUtils.getClazz( - BukkitReflectionUtils.assembleMCClass("network.protocol.game.ClientboundSetEquipmentPacket"), - BukkitReflectionUtils.assembleMCClass("network.protocol.game.PacketPlayOutEntityEquipment") + BukkitReflectionUtils.findReobfOrMojmapClass( + "network.protocol.game.PacketPlayOutEntityEquipment", + "network.protocol.game.ClientboundSetEquipmentPacket" ) ); @@ -3112,9 +3119,9 @@ public class Reflections { ); public static final Class clazz$ClientboundEntityEventPacket = requireNonNull( - ReflectionUtils.getClazz( - BukkitReflectionUtils.assembleMCClass("network.protocol.game.ClientboundEntityEventPacket"), - BukkitReflectionUtils.assembleMCClass("network.protocol.game.PacketPlayOutEntityStatus") + BukkitReflectionUtils.findReobfOrMojmapClass( + "network.protocol.game.PacketPlayOutEntityStatus", + "network.protocol.game.ClientboundEntityEventPacket" ) ); @@ -3131,23 +3138,23 @@ public class Reflections { ); public static final Class clazz$ServerboundInteractPacket = requireNonNull( - ReflectionUtils.getClazz( - BukkitReflectionUtils.assembleMCClass("network.protocol.game.ServerboundInteractPacket"), - BukkitReflectionUtils.assembleMCClass("network.protocol.game.PacketPlayInUseEntity") + BukkitReflectionUtils.findReobfOrMojmapClass( + "network.protocol.game.PacketPlayInUseEntity", + "network.protocol.game.ServerboundInteractPacket" ) ); public static final Class clazz$ServerboundInteractPacket$Action = requireNonNull( - ReflectionUtils.getClazz( - BukkitReflectionUtils.assembleMCClass("network.protocol.game.ServerboundInteractPacket$Action"), - BukkitReflectionUtils.assembleMCClass("network.protocol.game.PacketPlayInUseEntity$EnumEntityUseAction") + BukkitReflectionUtils.findReobfOrMojmapClass( + "network.protocol.game.PacketPlayInUseEntity$EnumEntityUseAction", + "network.protocol.game.ServerboundInteractPacket$Action" ) ); public static final Class clazz$ServerboundInteractPacket$InteractionAction = requireNonNull( - ReflectionUtils.getClazz( - BukkitReflectionUtils.assembleMCClass("network.protocol.game.ServerboundInteractPacket$InteractionAction"), - BukkitReflectionUtils.assembleMCClass("network.protocol.game.PacketPlayInUseEntity$d") + BukkitReflectionUtils.findReobfOrMojmapClass( + "network.protocol.game.PacketPlayInUseEntity$d", + "network.protocol.game.ServerboundInteractPacket$InteractionAction" ) ); @@ -3158,9 +3165,9 @@ public class Reflections { ); public static final Class clazz$ServerboundInteractPacket$InteractionAtLocationAction = requireNonNull( - ReflectionUtils.getClazz( - BukkitReflectionUtils.assembleMCClass("network.protocol.game.ServerboundInteractPacket$InteractionAtLocationAction"), - BukkitReflectionUtils.assembleMCClass("network.protocol.game.PacketPlayInUseEntity$e") + BukkitReflectionUtils.findReobfOrMojmapClass( + "network.protocol.game.PacketPlayInUseEntity$e", + "network.protocol.game.ServerboundInteractPacket$InteractionAtLocationAction" ) ); @@ -3177,9 +3184,9 @@ public class Reflections { ); public static final Class clazz$ServerboundInteractPacket$ActionType = requireNonNull( - ReflectionUtils.getClazz( - BukkitReflectionUtils.assembleMCClass("network.protocol.game.ServerboundInteractPacket$ActionType"), - BukkitReflectionUtils.assembleMCClass("network.protocol.game.PacketPlayInUseEntity$b") + BukkitReflectionUtils.findReobfOrMojmapClass( + "network.protocol.game.PacketPlayInUseEntity$b", + "network.protocol.game.ServerboundInteractPacket$ActionType" ) ); @@ -3229,16 +3236,16 @@ public class Reflections { ); public static final Class clazz$ClientboundUpdateMobEffectPacket = requireNonNull( - ReflectionUtils.getClazz( - BukkitReflectionUtils.assembleMCClass("network.protocol.game.ClientboundUpdateMobEffectPacket"), - BukkitReflectionUtils.assembleMCClass("network.protocol.game.PacketPlayOutEntityEffect") + BukkitReflectionUtils.findReobfOrMojmapClass( + "network.protocol.game.PacketPlayOutEntityEffect", + "network.protocol.game.ClientboundUpdateMobEffectPacket" ) ); public static final Class clazz$ClientboundRemoveMobEffectPacket = requireNonNull( - ReflectionUtils.getClazz( - BukkitReflectionUtils.assembleMCClass("network.protocol.game.ClientboundRemoveMobEffectPacket"), - BukkitReflectionUtils.assembleMCClass("network.protocol.game.PacketPlayOutRemoveEntityEffect") + BukkitReflectionUtils.findReobfOrMojmapClass( + "network.protocol.game.PacketPlayOutRemoveEntityEffect", + "network.protocol.game.ClientboundRemoveMobEffectPacket" ) ); @@ -3271,7 +3278,7 @@ public class Reflections { ); public static final Constructor constructor$ClientboundUpdateMobEffectPacket = requireNonNull( - !VersionHelper.isVersionNewerThan1_20_5() ? + !VersionHelper.isOrAbove1_20_5() ? ReflectionUtils.getConstructor( clazz$ClientboundUpdateMobEffectPacket, int.class, clazz$MobEffectInstance ) : @@ -3287,7 +3294,7 @@ public class Reflections { ); public static final Field field$ClientboundUpdateMobEffectPacket$effect = requireNonNull( - !VersionHelper.isVersionNewerThan1_20_5() ? + !VersionHelper.isOrAbove1_20_5() ? ReflectionUtils.getInstanceDeclaredField( clazz$ClientboundUpdateMobEffectPacket, clazz$MobEffect, 0 ) : @@ -3297,7 +3304,7 @@ public class Reflections { ); public static final Field field$ClientboundUpdateMobEffectPacket$amplifier = requireNonNull( - !VersionHelper.isVersionNewerThan1_20_5() ? + !VersionHelper.isOrAbove1_20_5() ? ReflectionUtils.getInstanceDeclaredField( clazz$ClientboundUpdateMobEffectPacket, byte.class, 0 ) : @@ -3307,7 +3314,7 @@ public class Reflections { ); public static final Field field$ClientboundUpdateMobEffectPacket$duration = requireNonNull( - !VersionHelper.isVersionNewerThan1_20_5() ? + !VersionHelper.isOrAbove1_20_5() ? ReflectionUtils.getInstanceDeclaredField( clazz$ClientboundUpdateMobEffectPacket, int.class, 1 ) : @@ -3317,7 +3324,7 @@ public class Reflections { ); public static final Field field$ClientboundUpdateMobEffectPacket$flags = requireNonNull( - !VersionHelper.isVersionNewerThan1_20_5() ? + !VersionHelper.isOrAbove1_20_5() ? ReflectionUtils.getInstanceDeclaredField( clazz$ClientboundUpdateMobEffectPacket, byte.class, 1 ) : @@ -3327,7 +3334,7 @@ public class Reflections { ); public static final Method method$ServerPlayer$getEffect = requireNonNull( - !VersionHelper.isVersionNewerThan1_20_5() ? + !VersionHelper.isOrAbove1_20_5() ? ReflectionUtils.getMethod( clazz$ServerPlayer, clazz$MobEffectInstance, clazz$MobEffect ) : @@ -3364,14 +3371,14 @@ public class Reflections { .orElse(null); public static final Class clazz$ServerboundSetCreativeModeSlotPacket = requireNonNull( - ReflectionUtils.getClazz( - BukkitReflectionUtils.assembleMCClass("network.protocol.game.ServerboundSetCreativeModeSlotPacket"), - BukkitReflectionUtils.assembleMCClass("network.protocol.game.PacketPlayInSetCreativeSlot") + BukkitReflectionUtils.findReobfOrMojmapClass( + "network.protocol.game.PacketPlayInSetCreativeSlot", + "network.protocol.game.ServerboundSetCreativeModeSlotPacket" ) ); public static final Field field$ServerboundSetCreativeModeSlotPacket$slotNum = requireNonNull( - VersionHelper.isVersionNewerThan1_20_5() ? + VersionHelper.isOrAbove1_20_5() ? ReflectionUtils.getDeclaredField( clazz$ServerboundSetCreativeModeSlotPacket, short.class, 0 ) : @@ -3483,7 +3490,7 @@ public class Reflections { ); public static final Method method$BlockBehaviour$updateShape = requireNonNull( - VersionHelper.isVersionNewerThan1_21_2() ? + VersionHelper.isOrAbove1_21_2() ? ReflectionUtils.getDeclaredMethod( clazz$BlockBehaviour, clazz$BlockState, clazz$BlockState, clazz$LevelReader, clazz$ScheduledTickAccess, clazz$BlockPos, clazz$Direction, clazz$BlockPos, clazz$BlockState, clazz$RandomSource ) : @@ -3499,9 +3506,9 @@ public class Reflections { ); public static final Class clazz$FallingBlock = requireNonNull( - ReflectionUtils.getClazz( - BukkitReflectionUtils.assembleMCClass("world.level.block.FallingBlock"), - BukkitReflectionUtils.assembleMCClass("world.level.block.BlockFalling") + BukkitReflectionUtils.findReobfOrMojmapClass( + "world.level.block.BlockFalling", + "world.level.block.FallingBlock" ) ); @@ -3512,9 +3519,9 @@ public class Reflections { ); public static final Class clazz$FallingBlockEntity = requireNonNull( - ReflectionUtils.getClazz( - BukkitReflectionUtils.assembleMCClass("world.entity.item.FallingBlockEntity"), - BukkitReflectionUtils.assembleMCClass("world.entity.item.EntityFallingBlock") + BukkitReflectionUtils.findReobfOrMojmapClass( + "world.entity.item.EntityFallingBlock", + "world.entity.item.FallingBlockEntity" ) ); @@ -3614,9 +3621,9 @@ public class Reflections { ); public static final Class clazz$MutableBlockPos = requireNonNull( - ReflectionUtils.getClazz( - BukkitReflectionUtils.assembleMCClass("core.BlockPos$MutableBlockPos"), - BukkitReflectionUtils.assembleMCClass("core.BlockPosition$MutableBlockPosition") + BukkitReflectionUtils.findReobfOrMojmapClass( + "core.BlockPosition$MutableBlockPosition", + "core.BlockPos$MutableBlockPos" ) ); @@ -3639,23 +3646,23 @@ public class Reflections { ); public static final Class clazz$LeavesBlock = requireNonNull( - ReflectionUtils.getClazz( - BukkitReflectionUtils.assembleMCClass("world.level.block.LeavesBlock"), - BukkitReflectionUtils.assembleMCClass("world.level.block.BlockLeaves") + BukkitReflectionUtils.findReobfOrMojmapClass( + "world.level.block.BlockLeaves", + "world.level.block.LeavesBlock" ) ); public static final Class clazz$IntegerProperty = requireNonNull( - ReflectionUtils.getClazz( - BukkitReflectionUtils.assembleMCClass("world.level.block.state.properties.IntegerProperty"), - BukkitReflectionUtils.assembleMCClass("world.level.block.state.properties.BlockStateInteger") + BukkitReflectionUtils.findReobfOrMojmapClass( + "world.level.block.state.properties.BlockStateInteger", + "world.level.block.state.properties.IntegerProperty" ) ); public static final Class clazz$Property = requireNonNull( - ReflectionUtils.getClazz( - BukkitReflectionUtils.assembleMCClass("world.level.block.state.properties.Property"), - BukkitReflectionUtils.assembleMCClass("world.level.block.state.properties.IBlockState") + BukkitReflectionUtils.findReobfOrMojmapClass( + "world.level.block.state.properties.IBlockState", + "world.level.block.state.properties.Property" ) ); @@ -3703,16 +3710,16 @@ public class Reflections { ); public static final Class clazz$ClientboundRespawnPacket = requireNonNull( - ReflectionUtils.getClazz( - BukkitReflectionUtils.assembleMCClass("network.protocol.game.ClientboundRespawnPacket"), - BukkitReflectionUtils.assembleMCClass("network.protocol.game.PacketPlayOutRespawn") + BukkitReflectionUtils.findReobfOrMojmapClass( + "network.protocol.game.PacketPlayOutRespawn", + "network.protocol.game.ClientboundRespawnPacket" ) ); public static final Class clazz$ClientboundLoginPacket = requireNonNull( - ReflectionUtils.getClazz( - BukkitReflectionUtils.assembleMCClass("network.protocol.game.ClientboundLoginPacket"), - BukkitReflectionUtils.assembleMCClass("network.protocol.game.PacketPlayOutLogin") + BukkitReflectionUtils.findReobfOrMojmapClass( + "network.protocol.game.PacketPlayOutLogin", + "network.protocol.game.ClientboundLoginPacket" ) ); @@ -3742,7 +3749,7 @@ public class Reflections { // 1.20.2+ public static final Field field$CommonPlayerSpawnInfo$dimension = Optional.ofNullable(clazz$CommonPlayerSpawnInfo) .map(it -> { - if (VersionHelper.isVersionNewerThan1_20_5()) { + if (VersionHelper.isOrAbove1_20_5()) { return ReflectionUtils.getDeclaredField(it, clazz$ResourceKey, 0); } else { return ReflectionUtils.getDeclaredField(it, clazz$ResourceKey, 1); @@ -3791,7 +3798,7 @@ public class Reflections { instance$EntityType$SHULKER = Reflections.method$Registry$get.invoke(Reflections.instance$BuiltInRegistries$ENTITY_TYPE, shulker); Object armorStand = FastNMS.INSTANCE.method$ResourceLocation$fromNamespaceAndPath("minecraft", "armor_stand"); instance$EntityType$ARMOR_STAND = Reflections.method$Registry$get.invoke(Reflections.instance$BuiltInRegistries$ENTITY_TYPE, armorStand); - Object oakBoat = VersionHelper.isVersionNewerThan1_21_2() ? FastNMS.INSTANCE.method$ResourceLocation$fromNamespaceAndPath("minecraft", "oak_boat") : FastNMS.INSTANCE.method$ResourceLocation$fromNamespaceAndPath("minecraft", "boat"); + Object oakBoat = VersionHelper.isOrAbove1_21_2() ? FastNMS.INSTANCE.method$ResourceLocation$fromNamespaceAndPath("minecraft", "oak_boat") : FastNMS.INSTANCE.method$ResourceLocation$fromNamespaceAndPath("minecraft", "boat"); instance$EntityType$OAK_BOAT = Reflections.method$Registry$get.invoke(Reflections.instance$BuiltInRegistries$ENTITY_TYPE, oakBoat); } catch (ReflectiveOperationException e) { throw new RuntimeException(e); @@ -3883,9 +3890,9 @@ public class Reflections { ); public static final Class clazz$FireBlock = requireNonNull( - ReflectionUtils.getClazz( - BukkitReflectionUtils.assembleMCClass("world.level.block.FireBlock"), - BukkitReflectionUtils.assembleMCClass("world.level.block.BlockFire") + BukkitReflectionUtils.findReobfOrMojmapClass( + "world.level.block.BlockFire", + "world.level.block.FireBlock" ) ); @@ -3954,9 +3961,9 @@ public class Reflections { .orElse(null); public static final Class clazz$ClientboundMoveEntityPacket = requireNonNull( - ReflectionUtils.getClazz( - BukkitReflectionUtils.assembleMCClass("network.protocol.game.ClientboundMoveEntityPacket"), - BukkitReflectionUtils.assembleMCClass("network.protocol.game.PacketPlayOutEntity") + BukkitReflectionUtils.findReobfOrMojmapClass( + "network.protocol.game.PacketPlayOutEntity", + "network.protocol.game.ClientboundMoveEntityPacket" ) ); @@ -3967,16 +3974,16 @@ public class Reflections { ); public static final Class clazz$ClientboundMoveEntityPacket$Pos = requireNonNull( - ReflectionUtils.getClazz( - BukkitReflectionUtils.assembleMCClass("network.protocol.game.ClientboundMoveEntityPacket$Pos"), - BukkitReflectionUtils.assembleMCClass("network.protocol.game.PacketPlayOutEntity$PacketPlayOutRelEntityMove") + BukkitReflectionUtils.findReobfOrMojmapClass( + "network.protocol.game.PacketPlayOutEntity$PacketPlayOutRelEntityMove", + "network.protocol.game.ClientboundMoveEntityPacket$Pos" ) ); public static final Class clazz$ClientboundMoveEntityPacket$Rot = requireNonNull( - ReflectionUtils.getClazz( - BukkitReflectionUtils.assembleMCClass("network.protocol.game.ClientboundMoveEntityPacket$Rot"), - BukkitReflectionUtils.assembleMCClass("network.protocol.game.PacketPlayOutEntity$PacketPlayOutEntityLook") + BukkitReflectionUtils.findReobfOrMojmapClass( + "network.protocol.game.PacketPlayOutEntity$PacketPlayOutEntityLook", + "network.protocol.game.ClientboundMoveEntityPacket$Rot" ) ); @@ -3985,9 +3992,9 @@ public class Reflections { ); public static final Class clazz$ServerboundUseItemOnPacket = requireNonNull( - ReflectionUtils.getClazz( - BukkitReflectionUtils.assembleMCClass("network.protocol.game.ServerboundUseItemOnPacket"), - BukkitReflectionUtils.assembleMCClass("network.protocol.game.PacketPlayInUseItem") + BukkitReflectionUtils.findReobfOrMojmapClass( + "network.protocol.game.PacketPlayInUseItem", + "network.protocol.game.ServerboundUseItemOnPacket" ) ); @@ -4009,16 +4016,16 @@ public class Reflections { .orElse(null); public static final Class clazz$ClientboundSoundPacket = requireNonNull( - ReflectionUtils.getClazz( - BukkitReflectionUtils.assembleMCClass("network.protocol.game.ClientboundSoundPacket"), - BukkitReflectionUtils.assembleMCClass("network.protocol.game.PacketPlayOutNamedSoundEffect") + BukkitReflectionUtils.findReobfOrMojmapClass( + "network.protocol.game.PacketPlayOutNamedSoundEffect", + "network.protocol.game.ClientboundSoundPacket" ) ); public static final Class clazz$SoundSource = requireNonNull( - ReflectionUtils.getClazz( - BukkitReflectionUtils.assembleMCClass("sounds.SoundSource"), - BukkitReflectionUtils.assembleMCClass("sounds.SoundCategory") + BukkitReflectionUtils.findReobfOrMojmapClass( + "sounds.SoundCategory", + "sounds.SoundSource" ) ); @@ -4077,15 +4084,15 @@ public class Reflections { ); public static final Method method$CraftEventFactory$callBlockPlaceEvent = requireNonNull( - VersionHelper.isVersionNewerThan1_21_5() + VersionHelper.isOrAbove1_21_5() ? ReflectionUtils.getStaticMethod(clazz$CraftEventFactory, BlockPlaceEvent.class, clazz$ServerLevel, clazz$Player, clazz$InteractionHand, BlockState.class, clazz$BlockPos) : ReflectionUtils.getStaticMethod(clazz$CraftEventFactory, BlockPlaceEvent.class, clazz$ServerLevel, clazz$Player, clazz$InteractionHand, BlockState.class, int.class, int.class, int.class) ); public static final Class clazz$Abilities = requireNonNull( - ReflectionUtils.getClazz( - BukkitReflectionUtils.assembleMCClass("world.entity.player.Abilities"), - BukkitReflectionUtils.assembleMCClass("world.entity.player.PlayerAbilities") + BukkitReflectionUtils.findReobfOrMojmapClass( + "world.entity.player.PlayerAbilities", + "world.entity.player.Abilities" ) ); @@ -4161,9 +4168,9 @@ public class Reflections { } public static final Class clazz$FlowingFluid = requireNonNull( - ReflectionUtils.getClazz( - BukkitReflectionUtils.assembleMCClass("world.level.material.FlowingFluid"), - BukkitReflectionUtils.assembleMCClass("world.level.material.FluidTypeFlowing") + BukkitReflectionUtils.findReobfOrMojmapClass( + "world.level.material.FluidTypeFlowing", + "world.level.material.FlowingFluid" ) ); @@ -4205,8 +4212,8 @@ public class Reflections { public static final Class clazz$ResourceManager = requireNonNull( ReflectionUtils.getClazz( - BukkitReflectionUtils.assembleMCClass("server.packs.resources.IResourceManager"), - BukkitReflectionUtils.assembleMCClass("server.packs.resources.ResourceManager") + BukkitReflectionUtils.assembleMCClass("server.packs.resources.IResourceManager"), // 这里paper会自动获取到NM.server.packs.resources.ResourceManager + BukkitReflectionUtils.assembleMCClass("server.packs.resources.ResourceManager") // 如果插件是mojmap就会走这个 ) ); @@ -4217,9 +4224,9 @@ public class Reflections { ); public static final Class clazz$Resource = requireNonNull( - ReflectionUtils.getClazz( - BukkitReflectionUtils.assembleMCClass("server.packs.resources.IResource"), - BukkitReflectionUtils.assembleMCClass("server.packs.resources.Resource") + BukkitReflectionUtils.findReobfOrMojmapClass( + "server.packs.resources.IResource", + "server.packs.resources.Resource" ) ); @@ -4230,16 +4237,16 @@ public class Reflections { ); public static final Class clazz$MultiPackResourceManager = requireNonNull( - ReflectionUtils.getClazz( - BukkitReflectionUtils.assembleMCClass("server.packs.resources.MultiPackResourceManager"), - BukkitReflectionUtils.assembleMCClass("server.packs.resources.ResourceManager") + BukkitReflectionUtils.findReobfOrMojmapClass( + "server.packs.resources.ResourceManager", + "server.packs.resources.MultiPackResourceManager" ) ); public static final Class clazz$PackType = requireNonNull( - ReflectionUtils.getClazz( - BukkitReflectionUtils.assembleMCClass("server.packs.PackType"), - BukkitReflectionUtils.assembleMCClass("server.packs.EnumResourcePackType") + BukkitReflectionUtils.findReobfOrMojmapClass( + "server.packs.EnumResourcePackType", + "server.packs.PackType" ) ); @@ -4261,9 +4268,9 @@ public class Reflections { } public static final Class clazz$PackRepository = requireNonNull( - ReflectionUtils.getClazz( - BukkitReflectionUtils.assembleMCClass("server.packs.repository.ResourcePackRepository"), - BukkitReflectionUtils.assembleMCClass("server.packs.repository.PackRepository") + BukkitReflectionUtils.findReobfOrMojmapClass( + "server.packs.repository.ResourcePackRepository", + "server.packs.repository.PackRepository" ) ); @@ -4280,9 +4287,9 @@ public class Reflections { ); public static final Class clazz$Pack = requireNonNull( - ReflectionUtils.getClazz( - BukkitReflectionUtils.assembleMCClass("server.packs.repository.ResourcePackLoader"), - BukkitReflectionUtils.assembleMCClass("server.packs.repository.Pack") + BukkitReflectionUtils.findReobfOrMojmapClass( + "server.packs.repository.ResourcePackLoader", + "server.packs.repository.Pack" ) ); @@ -4305,9 +4312,9 @@ public class Reflections { ); public static final Class clazz$PackResources = requireNonNull( - ReflectionUtils.getClazz( - BukkitReflectionUtils.assembleMCClass("server.packs.PackResources"), - BukkitReflectionUtils.assembleMCClass("server.packs.IResourcePack") + BukkitReflectionUtils.findReobfOrMojmapClass( + "server.packs.IResourcePack", + "server.packs.PackResources" ) ); @@ -4336,16 +4343,16 @@ public class Reflections { ); public static final Class clazz$RecipeManager = requireNonNull( - ReflectionUtils.getClazz( - BukkitReflectionUtils.assembleMCClass("world.item.crafting.RecipeManager"), - BukkitReflectionUtils.assembleMCClass("world.item.crafting.CraftingManager") + BukkitReflectionUtils.findReobfOrMojmapClass( + "world.item.crafting.CraftingManager", + "world.item.crafting.RecipeManager" ) ); public static final Class clazz$RecipeManager$CachedCheck = requireNonNull( - ReflectionUtils.getClazz( - BukkitReflectionUtils.assembleMCClass("world.item.crafting.RecipeManager$CachedCheck"), - BukkitReflectionUtils.assembleMCClass("world.item.crafting.CraftingManager$a") + BukkitReflectionUtils.findReobfOrMojmapClass( + "world.item.crafting.CraftingManager$a", + "world.item.crafting.RecipeManager$CachedCheck" ) ); @@ -4449,9 +4456,9 @@ public class Reflections { ); public static final Class clazz$Inventory = requireNonNull( - ReflectionUtils.getClazz( - BukkitReflectionUtils.assembleMCClass("world.entity.player.Inventory"), - BukkitReflectionUtils.assembleMCClass("world.entity.player.PlayerInventory") + BukkitReflectionUtils.findReobfOrMojmapClass( + "world.entity.player.PlayerInventory", + "world.entity.player.Inventory" ) ); @@ -4480,9 +4487,9 @@ public class Reflections { ); public static final Class clazz$Ingredient = requireNonNull( - ReflectionUtils.getClazz( - BukkitReflectionUtils.assembleMCClass("world.item.crafting.Ingredient"), - BukkitReflectionUtils.assembleMCClass("world.item.crafting.RecipeItemStack") + BukkitReflectionUtils.findReobfOrMojmapClass( + "world.item.crafting.RecipeItemStack", + "world.item.crafting.Ingredient" ) ); @@ -4511,9 +4518,9 @@ public class Reflections { ); public static final Class clazz$ShapedRecipe = requireNonNull( - ReflectionUtils.getClazz( - BukkitReflectionUtils.assembleMCClass("world.item.crafting.ShapedRecipe"), - BukkitReflectionUtils.assembleMCClass("world.item.crafting.ShapedRecipes") + BukkitReflectionUtils.findReobfOrMojmapClass( + "world.item.crafting.ShapedRecipes", + "world.item.crafting.ShapedRecipe" ) ); @@ -4572,9 +4579,9 @@ public class Reflections { .orElse(null); public static final Class clazz$ShapelessRecipe = requireNonNull( - ReflectionUtils.getClazz( - BukkitReflectionUtils.assembleMCClass("world.item.crafting.ShapelessRecipe"), - BukkitReflectionUtils.assembleMCClass("world.item.crafting.ShapelessRecipes") + BukkitReflectionUtils.findReobfOrMojmapClass( + "world.item.crafting.ShapelessRecipes", + "world.item.crafting.ShapelessRecipe" ) ); @@ -4602,7 +4609,7 @@ public class Reflections { static { Method method$RecipeManager$byKey0 = null; - if (VersionHelper.isVersionNewerThan1_21_2()) { + if (VersionHelper.isOrAbove1_21_2()) { for (Method method : clazz$RecipeManager.getMethods()) { if (method.getParameterCount() == 1 && method.getParameterTypes()[0] == clazz$ResourceKey) { if (method.getReturnType() == Optional.class && method.getGenericReturnType() instanceof ParameterizedType type) { @@ -4613,7 +4620,7 @@ public class Reflections { } } } - } else if (VersionHelper.isVersionNewerThan1_20_2()) { + } else if (VersionHelper.isOrAbove1_20_2()) { for (Method method : clazz$RecipeManager.getMethods()) { if (method.getParameterCount() == 1 && method.getParameterTypes()[0] == clazz$ResourceLocation) { if (method.getReturnType() == Optional.class && method.getGenericReturnType() instanceof ParameterizedType type) { @@ -4661,23 +4668,23 @@ public class Reflections { ); public static final Class clazz$ResultContainer = requireNonNull( - ReflectionUtils.getClazz( - BukkitReflectionUtils.assembleMCClass("world.inventory.ResultContainer"), - BukkitReflectionUtils.assembleMCClass("world.inventory.InventoryCraftResult") + BukkitReflectionUtils.findReobfOrMojmapClass( + "world.inventory.InventoryCraftResult", + "world.inventory.ResultContainer" ) ); public static final Class clazz$Container = requireNonNull( - ReflectionUtils.getClazz( - BukkitReflectionUtils.assembleMCClass("world.Container"), - BukkitReflectionUtils.assembleMCClass("world.IInventory") + BukkitReflectionUtils.findReobfOrMojmapClass( + "world.IInventory", + "world.Container" ) ); public static final Class clazz$Recipe = requireNonNull( - ReflectionUtils.getClazz( - BukkitReflectionUtils.assembleMCClass("world.item.crafting.Recipe"), - BukkitReflectionUtils.assembleMCClass("world.item.crafting.IRecipe") + BukkitReflectionUtils.findReobfOrMojmapClass( + "world.item.crafting.IRecipe", + "world.item.crafting.Recipe" ) ); @@ -4697,9 +4704,9 @@ public class Reflections { ); public static final Class clazz$LivingEntity = requireNonNull( - ReflectionUtils.getClazz( - BukkitReflectionUtils.assembleMCClass("world.entity.LivingEntity"), - BukkitReflectionUtils.assembleMCClass("world.entity.EntityLiving") + BukkitReflectionUtils.findReobfOrMojmapClass( + "world.entity.EntityLiving", + "world.entity.LivingEntity" ) ); @@ -4723,9 +4730,9 @@ public class Reflections { // for 1.20.1-1.21.1 public static final Class clazz$AbstractCookingRecipe = requireNonNull( - ReflectionUtils.getClazz( - BukkitReflectionUtils.assembleMCClass("world.item.crafting.AbstractCookingRecipe"), - BukkitReflectionUtils.assembleMCClass("world.item.crafting.RecipeCooking") + BukkitReflectionUtils.findReobfOrMojmapClass( + "world.item.crafting.RecipeCooking", + "world.item.crafting.AbstractCookingRecipe" ) ); @@ -4737,8 +4744,9 @@ public class Reflections { // for 1.21.2+ public static final Class clazz$SingleItemRecipe = - ReflectionUtils.getClazz( - BukkitReflectionUtils.assembleMCClass("world.item.crafting.SingleItemRecipe") + BukkitReflectionUtils.findReobfOrMojmapClass( + "world.item.crafting.RecipeSingleItem", + "world.item.crafting.SingleItemRecipe" ); // for 1.21.2+ @@ -4880,9 +4888,9 @@ public class Reflections { ); public static final Class clazz$SimpleContainer = requireNonNull( - ReflectionUtils.getClazz( - BukkitReflectionUtils.assembleMCClass("world.SimpleContainer"), - BukkitReflectionUtils.assembleMCClass("world.InventorySubcontainer") + BukkitReflectionUtils.findReobfOrMojmapClass( + "world.InventorySubcontainer", + "world.SimpleContainer" ) ); @@ -4917,14 +4925,14 @@ public class Reflections { ); public static final Class clazz$BonemealableBlock = requireNonNull( - ReflectionUtils.getClazz( - BukkitReflectionUtils.assembleMCClass("world.level.block.BonemealableBlock"), - BukkitReflectionUtils.assembleMCClass("world.level.block.IBlockFragilePlantElement") + BukkitReflectionUtils.findReobfOrMojmapClass( + "world.level.block.IBlockFragilePlantElement", + "world.level.block.BonemealableBlock" ) ); public static final Method method$BonemealableBlock$isValidBonemealTarget = requireNonNull( - VersionHelper.isVersionNewerThan1_20_2() ? + VersionHelper.isOrAbove1_20_2() ? ReflectionUtils.getMethod( clazz$BonemealableBlock, boolean.class, clazz$LevelReader, clazz$BlockPos, clazz$BlockState ) : @@ -4946,9 +4954,9 @@ public class Reflections { ); public static final Class clazz$ClientboundLevelEventPacket = requireNonNull( - ReflectionUtils.getClazz( - BukkitReflectionUtils.assembleMCClass("network.protocol.game.ClientboundLevelEventPacket"), - BukkitReflectionUtils.assembleMCClass("network.protocol.game.PacketPlayOutWorldEvent") + BukkitReflectionUtils.findReobfOrMojmapClass( + "network.protocol.game.PacketPlayOutWorldEvent", + "network.protocol.game.ClientboundLevelEventPacket" ) ); @@ -4977,7 +4985,7 @@ public class Reflections { ); public static final Method method$ServerLevel$levelEvent = requireNonNull( - VersionHelper.isVersionNewerThan1_21_5() + VersionHelper.isOrAbove1_21_5() ? ReflectionUtils.getMethod(clazz$ServerLevel, void.class, clazz$Entity, int.class, clazz$BlockPos, int.class) : ReflectionUtils.getMethod(clazz$ServerLevel, void.class, clazz$Player, int.class, clazz$BlockPos, int.class) ); @@ -4997,16 +5005,16 @@ public class Reflections { ); public static final Class clazz$ClientboundOpenScreenPacket = requireNonNull( - ReflectionUtils.getClazz( - BukkitReflectionUtils.assembleMCClass("network.protocol.game.ClientboundOpenScreenPacket"), - BukkitReflectionUtils.assembleMCClass("network.protocol.game.PacketPlayOutOpenWindow") + BukkitReflectionUtils.findReobfOrMojmapClass( + "network.protocol.game.PacketPlayOutOpenWindow", + "network.protocol.game.ClientboundOpenScreenPacket" ) ); public static final Class clazz$MenuType = requireNonNull( - ReflectionUtils.getClazz( - BukkitReflectionUtils.assembleMCClass("world.inventory.MenuType"), - BukkitReflectionUtils.assembleMCClass("world.inventory.Containers") + BukkitReflectionUtils.findReobfOrMojmapClass( + "world.inventory.Containers", + "world.inventory.MenuType" ) ); @@ -5017,9 +5025,9 @@ public class Reflections { ); public static final Class clazz$AbstractContainerMenu = requireNonNull( - ReflectionUtils.getClazz( - BukkitReflectionUtils.assembleMCClass("world.inventory.AbstractContainerMenu"), - BukkitReflectionUtils.assembleMCClass("world.inventory.Container") + BukkitReflectionUtils.findReobfOrMojmapClass( + "world.inventory.Container", + "world.inventory.AbstractContainerMenu" ) ); @@ -5102,19 +5110,18 @@ public class Reflections { ); public static final Class clazz$ClientboundResourcePackPushPacket = requireNonNull( - ReflectionUtils.getClazz( - BukkitReflectionUtils.assembleMCClass("network.protocol.common.ClientboundResourcePackPushPacket"), - BukkitReflectionUtils.assembleMCClass("network.protocol.common.ClientboundResourcePackPacket"), - BukkitReflectionUtils.assembleMCClass("network.protocol.game.PacketPlayOutResourcePackSend") + BukkitReflectionUtils.findReobfOrMojmapClass( + List.of("network.protocol.game.PacketPlayOutResourcePackSend", "network.protocol.common.ClientboundResourcePackPacket", "network.protocol.common.ClientboundResourcePackPushPacket"), + List.of("network.protocol.common.ClientboundResourcePackPacket", "network.protocol.common.ClientboundResourcePackPushPacket") ) ); public static final Constructor constructor$ClientboundResourcePackPushPacket = requireNonNull( - VersionHelper.isVersionNewerThan1_20_5() ? + VersionHelper.isOrAbove1_20_5() ? ReflectionUtils.getConstructor( clazz$ClientboundResourcePackPushPacket, UUID.class, String.class, String.class, boolean.class, Optional.class ) : - VersionHelper.isVersionNewerThan1_20_3() ? + VersionHelper.isOrAbove1_20_3() ? ReflectionUtils.getConstructor( clazz$ClientboundResourcePackPushPacket, UUID.class, String.class, String.class, boolean.class, clazz$Component ) : @@ -5211,16 +5218,16 @@ public class Reflections { ); public static final Class clazz$CustomRecipe = requireNonNull( - ReflectionUtils.getClazz( - BukkitReflectionUtils.assembleMCClass("world.item.crafting.CustomRecipe"), - BukkitReflectionUtils.assembleMCClass("world.item.crafting.IRecipeComplex") + BukkitReflectionUtils.findReobfOrMojmapClass( + "world.item.crafting.IRecipeComplex", + "world.item.crafting.CustomRecipe" ) ); public static final Class clazz$RepairItemRecipe = requireNonNull( - ReflectionUtils.getClazz( - BukkitReflectionUtils.assembleMCClass("world.item.crafting.RepairItemRecipe"), - BukkitReflectionUtils.assembleMCClass("world.item.crafting.RecipeRepair") + BukkitReflectionUtils.findReobfOrMojmapClass( + "world.item.crafting.RecipeRepair", + "world.item.crafting.RepairItemRecipe" ) ); @@ -5237,9 +5244,9 @@ public class Reflections { ); public static final Class clazz$AnvilMenu = requireNonNull( - ReflectionUtils.getClazz( - BukkitReflectionUtils.assembleMCClass("world.inventory.AnvilMenu"), - BukkitReflectionUtils.assembleMCClass("world.inventory.ContainerAnvil") + BukkitReflectionUtils.findReobfOrMojmapClass( + "world.inventory.ContainerAnvil", + "world.inventory.AnvilMenu" ) ); @@ -5276,17 +5283,17 @@ public class Reflections { .orElse(null); public static final Constructor constructor$SmithingTransformRecipe = requireNonNull( - VersionHelper.isVersionNewerThan1_21_5() + VersionHelper.isOrAbove1_21_5() ? ReflectionUtils.getConstructor(clazz$SmithingTransformRecipe, Optional.class, clazz$Ingredient, Optional.class, clazz$TransmuteResult) - : VersionHelper.isVersionNewerThan1_21_2() + : VersionHelper.isOrAbove1_21_2() ? ReflectionUtils.getConstructor(clazz$SmithingTransformRecipe, Optional.class, Optional.class, Optional.class, clazz$ItemStack) - : VersionHelper.isVersionNewerThan1_20_2() + : VersionHelper.isOrAbove1_20_2() ? ReflectionUtils.getConstructor(clazz$SmithingTransformRecipe, clazz$Ingredient, clazz$Ingredient, clazz$Ingredient, clazz$ItemStack) : ReflectionUtils.getConstructor(clazz$SmithingTransformRecipe, clazz$ResourceLocation, clazz$Ingredient, clazz$Ingredient, clazz$Ingredient, clazz$ItemStack) ); public static final Method method$RecipeManager$addRecipe = requireNonNull( - VersionHelper.isVersionNewerThan1_20_2() ? + VersionHelper.isOrAbove1_20_2() ? ReflectionUtils.getMethod(clazz$RecipeManager, void.class, clazz$RecipeHolder) : ReflectionUtils.getMethod(clazz$RecipeManager, void.class, clazz$Recipe) ); @@ -5324,16 +5331,16 @@ public class Reflections { ); public static final Class clazz$BlockHitResult = requireNonNull( - ReflectionUtils.getClazz( - BukkitReflectionUtils.assembleMCClass("world.phys.BlockHitResult"), - BukkitReflectionUtils.assembleMCClass("world.phys.MovingObjectPositionBlock") + BukkitReflectionUtils.findReobfOrMojmapClass( + "world.phys.MovingObjectPositionBlock", + "world.phys.BlockHitResult" ) ); public static final Class clazz$ClipContext$Fluid = requireNonNull( - ReflectionUtils.getClazz( - BukkitReflectionUtils.assembleMCClass("world.level.ClipContext$Fluid"), - BukkitReflectionUtils.assembleMCClass("world.level.RayTrace$FluidCollisionOption") + BukkitReflectionUtils.findReobfOrMojmapClass( + "world.level.RayTrace$FluidCollisionOption", + "world.level.ClipContext$Fluid" ) ); @@ -5395,9 +5402,9 @@ public class Reflections { ); public static final Class clazz$HitResult = requireNonNull( - ReflectionUtils.getClazz( - BukkitReflectionUtils.assembleMCClass("world.phys.HitResult"), - BukkitReflectionUtils.assembleMCClass("world.phys.MovingObjectPosition") + BukkitReflectionUtils.findReobfOrMojmapClass( + "world.phys.MovingObjectPosition", + "world.phys.HitResult" ) ); @@ -5414,16 +5421,16 @@ public class Reflections { ); public static final Class clazz$LastSeenMessages$Update = requireNonNull( - ReflectionUtils.getClazz( - BukkitReflectionUtils.assembleMCClass("network.chat.LastSeenMessages$Update"), - BukkitReflectionUtils.assembleMCClass("network.chat.LastSeenMessages$b") + BukkitReflectionUtils.findReobfOrMojmapClass( + "network.chat.LastSeenMessages$b", + "network.chat.LastSeenMessages$Update" ) ); public static final Class clazz$ServerboundChatPacket = requireNonNull( - ReflectionUtils.getClazz( - BukkitReflectionUtils.assembleMCClass("network.protocol.game.ServerboundChatPacket"), - BukkitReflectionUtils.assembleMCClass("network.protocol.game.PacketPlayInChat") + BukkitReflectionUtils.findReobfOrMojmapClass( + "network.protocol.game.PacketPlayInChat", + "network.protocol.game.ServerboundChatPacket" ) ); @@ -5464,9 +5471,9 @@ public class Reflections { ); public static final Class clazz$ServerboundRenameItemPacket = requireNonNull( - ReflectionUtils.getClazz( - BukkitReflectionUtils.assembleMCClass("network.protocol.game.ServerboundRenameItemPacket"), - BukkitReflectionUtils.assembleMCClass("network.protocol.game.PacketPlayInItemName") + BukkitReflectionUtils.findReobfOrMojmapClass( + "network.protocol.game.PacketPlayInItemName", + "network.protocol.game.ServerboundRenameItemPacket" ) ); @@ -5477,9 +5484,9 @@ public class Reflections { ); public static final Class clazz$ServerboundSignUpdatePacket = requireNonNull( - ReflectionUtils.getClazz( - BukkitReflectionUtils.assembleMCClass("network.protocol.game.ServerboundSignUpdatePacket"), - BukkitReflectionUtils.assembleMCClass("network.protocol.game.PacketPlayInUpdateSign") + BukkitReflectionUtils.findReobfOrMojmapClass( + "network.protocol.game.PacketPlayInUpdateSign", + "network.protocol.game.ServerboundSignUpdatePacket" ) ); @@ -5550,9 +5557,9 @@ public class Reflections { ); public static final Class clazz$ServerboundEditBookPacket = requireNonNull( - ReflectionUtils.getClazz( - BukkitReflectionUtils.assembleMCClass("network.protocol.game.ServerboundEditBookPacket"), - BukkitReflectionUtils.assembleMCClass("network.protocol.game.PacketPlayInBEdit") + BukkitReflectionUtils.findReobfOrMojmapClass( + "network.protocol.game.PacketPlayInBEdit", + "network.protocol.game.ServerboundEditBookPacket" ) ); @@ -5581,16 +5588,16 @@ public class Reflections { ); public static final Class clazz$SimpleWaterloggedBlock = requireNonNull( - ReflectionUtils.getClazz( - BukkitReflectionUtils.assembleMCClass("world.level.block.SimpleWaterloggedBlock"), - BukkitReflectionUtils.assembleMCClass("world.level.block.IBlockWaterlogged") + BukkitReflectionUtils.findReobfOrMojmapClass( + "world.level.block.IBlockWaterlogged", + "world.level.block.SimpleWaterloggedBlock" ) ); public static final Method method$SimpleWaterloggedBlock$canPlaceLiquid = requireNonNull( - VersionHelper.isVersionNewerThan1_21_5() + VersionHelper.isOrAbove1_21_5() ? ReflectionUtils.getMethod(clazz$SimpleWaterloggedBlock, boolean.class, clazz$LivingEntity, clazz$BlockGetter, clazz$BlockPos, clazz$BlockState, clazz$Fluid) - : VersionHelper.isVersionNewerThan1_20_2() + : VersionHelper.isOrAbove1_20_2() ? ReflectionUtils.getMethod(clazz$SimpleWaterloggedBlock, boolean.class, clazz$Player, clazz$BlockGetter, clazz$BlockPos, clazz$BlockState, clazz$Fluid) : ReflectionUtils.getMethod(clazz$SimpleWaterloggedBlock, boolean.class, clazz$BlockGetter, clazz$BlockPos, clazz$BlockState, clazz$Fluid) ); @@ -5602,9 +5609,9 @@ public class Reflections { ); public static final Method method$SimpleWaterloggedBlock$pickupBlock = requireNonNull( - VersionHelper.isVersionNewerThan1_21_5() + VersionHelper.isOrAbove1_21_5() ? ReflectionUtils.getMethod(clazz$SimpleWaterloggedBlock, clazz$ItemStack, clazz$LivingEntity, clazz$LevelAccessor, clazz$BlockPos, clazz$BlockState) - : VersionHelper.isVersionNewerThan1_20_2() + : VersionHelper.isOrAbove1_20_2() ? ReflectionUtils.getMethod(clazz$SimpleWaterloggedBlock, clazz$ItemStack, clazz$Player, clazz$LevelAccessor, clazz$BlockPos, clazz$BlockState) : ReflectionUtils.getMethod(clazz$SimpleWaterloggedBlock, clazz$ItemStack, clazz$LevelAccessor, clazz$BlockPos, clazz$BlockState) ); @@ -5644,16 +5651,16 @@ public class Reflections { ); public static final Class clazz$HashMapPalette = requireNonNull( - ReflectionUtils.getClazz( - BukkitReflectionUtils.assembleMCClass("world.level.chunk.HashMapPalette"), - BukkitReflectionUtils.assembleMCClass("world.level.chunk.DataPaletteHash") + BukkitReflectionUtils.findReobfOrMojmapClass( + "world.level.chunk.DataPaletteHash", + "world.level.chunk.HashMapPalette" ) ); public static final Class clazz$CrudeIncrementalIntIdentityHashBiMap = requireNonNull( - ReflectionUtils.getClazz( - BukkitReflectionUtils.assembleMCClass("util.CrudeIncrementalIntIdentityHashBiMap"), - BukkitReflectionUtils.assembleMCClass("util.RegistryID") + BukkitReflectionUtils.findReobfOrMojmapClass( + "util.RegistryID", + "util.CrudeIncrementalIntIdentityHashBiMap" ) ); @@ -5670,9 +5677,9 @@ public class Reflections { ); public static final Class clazz$LinearPalette = requireNonNull( - ReflectionUtils.getClazz( - BukkitReflectionUtils.assembleMCClass("world.level.chunk.LinearPalette"), - BukkitReflectionUtils.assembleMCClass("world.level.chunk.DataPaletteLinear") + BukkitReflectionUtils.findReobfOrMojmapClass( + "world.level.chunk.DataPaletteLinear", + "world.level.chunk.LinearPalette" ) ); @@ -5713,9 +5720,9 @@ public class Reflections { ); public static final Class clazz$SupportType = requireNonNull( - ReflectionUtils.getClazz( - BukkitReflectionUtils.assembleMCClass("world.level.block.SupportType"), - BukkitReflectionUtils.assembleMCClass("world.level.block.EnumBlockSupport") + BukkitReflectionUtils.findReobfOrMojmapClass( + "world.level.block.EnumBlockSupport", + "world.level.block.SupportType" ) ); @@ -5759,9 +5766,9 @@ public class Reflections { ); public static final Class clazz$BlockInWorld = requireNonNull( - ReflectionUtils.getClazz( - BukkitReflectionUtils.assembleMCClass("world.level.block.state.pattern.BlockInWorld"), - BukkitReflectionUtils.assembleMCClass("world.level.block.state.pattern.ShapeDetectorBlock") + BukkitReflectionUtils.findReobfOrMojmapClass( + "world.level.block.state.pattern.ShapeDetectorBlock", + "world.level.block.state.pattern.BlockInWorld" ) ); @@ -5797,15 +5804,15 @@ public class Reflections { ); public static final Method method$BlockBehaviour$getDescriptionId = requireNonNull( - VersionHelper.isVersionNewerThan1_21_2() + VersionHelper.isOrAbove1_21_2() ? ReflectionUtils.getMethod(clazz$BlockBehaviour, String.class) : ReflectionUtils.getMethod(clazz$Block, String.class) ); public static final Class clazz$ServerboundCustomPayloadPacket = requireNonNull( - ReflectionUtils.getClazz( - BukkitReflectionUtils.assembleMCClass("network.protocol.common.ServerboundCustomPayloadPacket"), - BukkitReflectionUtils.assembleMCClass("network.protocol.game.PacketPlayInCustomPayload") + BukkitReflectionUtils.findReobfOrMojmapClass( + List.of("network.protocol.game.PacketPlayInCustomPayload", "network.protocol.common.ServerboundCustomPayloadPacket"), + List.of("network.protocol.game.ServerboundCustomPayloadPacket", "network.protocol.common.ServerboundCustomPayloadPacket") ) ); @@ -5817,8 +5824,9 @@ public class Reflections { // 1.20.5+ public static final Class clazz$CustomPacketPayload$Type = - ReflectionUtils.getClazz( - BukkitReflectionUtils.assembleMCClass("network.protocol.common.custom.CustomPacketPayload$Type") + BukkitReflectionUtils.findReobfOrMojmapClass( + "network.protocol.common.custom.CustomPacketPayload$b", + "network.protocol.common.custom.CustomPacketPayload$Type" ); // 1.20.2+ @@ -5856,9 +5864,9 @@ public class Reflections { ); public static final Class clazz$ClientboundDisconnectPacket = requireNonNull( - ReflectionUtils.getClazz( - BukkitReflectionUtils.assembleMCClass("network.protocol.common.ClientboundDisconnectPacket"), - BukkitReflectionUtils.assembleMCClass("network.protocol.game.PacketPlayOutKickDisconnect") + BukkitReflectionUtils.findReobfOrMojmapClass( + List.of("network.protocol.game.PacketPlayOutKickDisconnect", "network.protocol.common.ClientboundDisconnectPacket"), + List.of("network.protocol.game.ClientboundDisconnectPacket", "network.protocol.common.ClientboundDisconnectPacket") ) ); @@ -5869,7 +5877,7 @@ public class Reflections { ); public static final Method method$CraftEventFactory$handleBlockGrowEvent = requireNonNull( - VersionHelper.isVersionNewerThan1_21_5() ? + VersionHelper.isOrAbove1_21_5() ? ReflectionUtils.getStaticMethod( clazz$CraftEventFactory, boolean.class, clazz$Level, clazz$BlockPos, clazz$BlockState, int.class ) : @@ -5879,9 +5887,9 @@ public class Reflections { ); public static final Class clazz$BlockAndTintGetter = requireNonNull( - ReflectionUtils.getClazz( - BukkitReflectionUtils.assembleMCClass("world.level.BlockAndTintGetter"), - BukkitReflectionUtils.assembleMCClass("world.level.IBlockLightAccess") + BukkitReflectionUtils.findReobfOrMojmapClass( + "world.level.IBlockLightAccess", + "world.level.BlockAndTintGetter" ) ); @@ -5904,9 +5912,9 @@ public class Reflections { ); public static final Class clazz$Shulker = requireNonNull( - ReflectionUtils.getClazz( - BukkitReflectionUtils.assembleMCClass("world.entity.monster.Shulker"), - BukkitReflectionUtils.assembleMCClass("world.entity.monster.EntityShulker") + BukkitReflectionUtils.findReobfOrMojmapClass( + "world.entity.monster.EntityShulker", + "world.entity.monster.Shulker" ) ); @@ -5917,9 +5925,9 @@ public class Reflections { ); public static final Class clazz$Pose = requireNonNull( - ReflectionUtils.getClazz( - BukkitReflectionUtils.assembleMCClass("world.entity.Pose"), - BukkitReflectionUtils.assembleMCClass("world.entity.EntityPose") + BukkitReflectionUtils.findReobfOrMojmapClass( + "world.entity.EntityPose", + "world.entity.Pose" ) ); @@ -5967,7 +5975,7 @@ public class Reflections { instance$Pose$SNIFFING = instance$Poses[12]; instance$Pose$EMERGING = instance$Poses[13]; instance$Pose$DIGGING = instance$Poses[14]; - if (VersionHelper.isVersionNewerThan1_20_3()) { + if (VersionHelper.isOrAbove1_20_3()) { instance$Pose$SLIDING = instance$Poses[15]; instance$Pose$SHOOTING = instance$Poses[16]; instance$Pose$INHALING = instance$Poses[17]; @@ -5982,9 +5990,9 @@ public class Reflections { } public static final Class clazz$Attributes = requireNonNull( - ReflectionUtils.getClazz( - BukkitReflectionUtils.assembleMCClass("world.entity.ai.attributes.Attributes"), - BukkitReflectionUtils.assembleMCClass("world.entity.ai.attributes.GenericAttributes") + BukkitReflectionUtils.findReobfOrMojmapClass( + "world.entity.ai.attributes.GenericAttributes", + "world.entity.ai.attributes.Attributes" ) ); @@ -6019,13 +6027,13 @@ public class Reflections { // ); public static final Method method$Entity$canBeCollidedWith = requireNonNull( - VersionHelper.isVersionNewerThan1_20_5() + VersionHelper.isOrAbove1_20_5() ? ReflectionUtils.getMethod(clazz$Entity, boolean.class, new String[]{"canBeCollidedWith"}) - : VersionHelper.isVersionNewerThan1_20_3() + : VersionHelper.isOrAbove1_20_3() ? ReflectionUtils.getMethod(clazz$Entity, boolean.class, new String[]{"bz"}) - : VersionHelper.isVersionNewerThan1_20_2() + : VersionHelper.isOrAbove1_20_2() ? ReflectionUtils.getMethod(clazz$Entity, boolean.class, new String[]{"bx"}) - : VersionHelper.isVersionNewerThan1_20() + : VersionHelper.isOrAbove1_20() ? ReflectionUtils.getMethod(clazz$Entity, boolean.class, new String[]{"bu"}) : ReflectionUtils.getMethod(clazz$Entity, boolean.class, new String[]{"canBeCollidedWith", "bu", "bx", "bz"}) ); @@ -6039,28 +6047,28 @@ public class Reflections { @Deprecated public static final Method method$Entity$getId = requireNonNull( - VersionHelper.isVersionNewerThan1_20_5() + VersionHelper.isOrAbove1_20_5() ? ReflectionUtils.getMethod(clazz$Entity, int.class, new String[]{"getId"}) - : VersionHelper.isVersionNewerThan1_20_3() + : VersionHelper.isOrAbove1_20_3() ? ReflectionUtils.getMethod(clazz$Entity, int.class, new String[]{"aj"}) - : VersionHelper.isVersionNewerThan1_20_2() + : VersionHelper.isOrAbove1_20_2() ? ReflectionUtils.getMethod(clazz$Entity, int.class, new String[]{"ah"}) - : VersionHelper.isVersionNewerThan1_20() + : VersionHelper.isOrAbove1_20() ? ReflectionUtils.getMethod(clazz$Entity, int.class, new String[]{"af"}) : ReflectionUtils.getMethod(clazz$Entity, int.class, new String[]{"getId", "aj", "ah", "af"}) ); public static final Class clazz$ClientboundMoveEntityPacket$PosRot = requireNonNull( - ReflectionUtils.getClazz( - BukkitReflectionUtils.assembleMCClass("network.protocol.game.ClientboundMoveEntityPacket$PosRot"), - BukkitReflectionUtils.assembleMCClass("network.protocol.game.PacketPlayOutEntity$PacketPlayOutRelEntityMoveLook") + BukkitReflectionUtils.findReobfOrMojmapClass( + "network.protocol.game.PacketPlayOutEntity$PacketPlayOutRelEntityMoveLook", + "network.protocol.game.ClientboundMoveEntityPacket$PosRot" ) ); public static final Class clazz$ClientboundRotateHeadPacket = requireNonNull( - ReflectionUtils.getClazz( - BukkitReflectionUtils.assembleMCClass("network.protocol.game.ClientboundRotateHeadPacket"), - BukkitReflectionUtils.assembleMCClass("network.protocol.game.PacketPlayOutEntityHeadRotation") + BukkitReflectionUtils.findReobfOrMojmapClass( + "network.protocol.game.PacketPlayOutEntityHeadRotation", + "network.protocol.game.ClientboundRotateHeadPacket" ) ); @@ -6071,9 +6079,9 @@ public class Reflections { ); public static final Class clazz$ClientboundSetEntityMotionPacket = requireNonNull( - ReflectionUtils.getClazz( - BukkitReflectionUtils.assembleMCClass("network.protocol.game.ClientboundSetEntityMotionPacket"), - BukkitReflectionUtils.assembleMCClass("network.protocol.game.PacketPlayOutEntityVelocity") + BukkitReflectionUtils.findReobfOrMojmapClass( + "network.protocol.game.PacketPlayOutEntityVelocity", + "network.protocol.game.ClientboundSetEntityMotionPacket" ) ); @@ -6084,9 +6092,9 @@ public class Reflections { ); public static final Class clazz$Rotation = requireNonNull( - ReflectionUtils.getClazz( - BukkitReflectionUtils.assembleMCClass("world.level.block.Rotation"), - BukkitReflectionUtils.assembleMCClass("world.level.block.EnumBlockRotation") + BukkitReflectionUtils.findReobfOrMojmapClass( + "world.level.block.EnumBlockRotation", + "world.level.block.Rotation" ) ); @@ -6120,9 +6128,9 @@ public class Reflections { ); public static final Class clazz$Mirror = requireNonNull( - ReflectionUtils.getClazz( - BukkitReflectionUtils.assembleMCClass("world.level.block.Mirror"), - BukkitReflectionUtils.assembleMCClass("world.level.block.EnumBlockMirror") + BukkitReflectionUtils.findReobfOrMojmapClass( + "world.level.block.EnumBlockMirror", + "world.level.block.Mirror" ) ); @@ -6204,7 +6212,7 @@ public class Reflections { public static final Method method$Level$moonrise$getEntityLookup = requireNonNull( ReflectionUtils.getMethod( - VersionHelper.isVersionNewerThan1_21() ? clazz$Level : clazz$ServerLevel, + VersionHelper.isOrAbove1_21() ? clazz$Level : clazz$ServerLevel, clazz$EntityLookup ) ); @@ -6329,7 +6337,7 @@ public class Reflections { // 1.21.2+ static { try { - if (VersionHelper.isVersionNewerThan1_21_2()) { + if (VersionHelper.isOrAbove1_21_2()) { Object[] values = (Object[]) method$ParticleStatus$values.invoke(null); instance$ParticleStatus$ALL = values[0]; instance$ParticleStatus$DECREASED = values[1]; @@ -6380,16 +6388,16 @@ public class Reflections { ); public static final Class clazz$ClientboundTabListPacket = requireNonNull( - ReflectionUtils.getClazz( - BukkitReflectionUtils.assembleMCClass("network.protocol.game.ClientboundTabListPacket"), - BukkitReflectionUtils.assembleMCClass("network.protocol.game.PacketPlayOutPlayerListHeaderFooter") + BukkitReflectionUtils.findReobfOrMojmapClass( + "network.protocol.game.PacketPlayOutPlayerListHeaderFooter", + "network.protocol.game.ClientboundTabListPacket" ) ); public static final Class clazz$ClientboundSetObjectivePacket = requireNonNull( - ReflectionUtils.getClazz( - BukkitReflectionUtils.assembleMCClass("network.protocol.game.ClientboundSetObjectivePacket"), - BukkitReflectionUtils.assembleMCClass("network.protocol.game.PacketPlayOutScoreboardObjective") + BukkitReflectionUtils.findReobfOrMojmapClass( + "network.protocol.game.PacketPlayOutScoreboardObjective", + "network.protocol.game.ClientboundSetObjectivePacket" ) ); @@ -6430,9 +6438,9 @@ public class Reflections { } public static final Class clazz$ClientboundSetScorePacket = requireNonNull( - ReflectionUtils.getClazz( - BukkitReflectionUtils.assembleMCClass("network.protocol.game.ClientboundSetScorePacket"), - BukkitReflectionUtils.assembleMCClass("network.protocol.game.PacketPlayOutScoreboardScore") + BukkitReflectionUtils.findReobfOrMojmapClass( + "network.protocol.game.PacketPlayOutScoreboardScore", + "network.protocol.game.ClientboundSetScorePacket" ) ); @@ -6442,9 +6450,9 @@ public class Reflections { ); public static final Class clazz$ServerboundHelloPacket = requireNonNull( - ReflectionUtils.getClazz( - BukkitReflectionUtils.assembleMCClass("network.protocol.login.ServerboundHelloPacket"), - BukkitReflectionUtils.assembleMCClass("network.protocol.login.PacketLoginInStart") + BukkitReflectionUtils.findReobfOrMojmapClass( + "network.protocol.login.PacketLoginInStart", + "network.protocol.login.ServerboundHelloPacket" ) ); @@ -6455,7 +6463,7 @@ public class Reflections { ); public static final Field field$ServerboundHelloPacket$uuid = requireNonNull( - VersionHelper.isVersionNewerThan1_20_2() ? + VersionHelper.isOrAbove1_20_2() ? ReflectionUtils.getDeclaredField( clazz$ServerboundHelloPacket, UUID.class, 0 ) : @@ -6472,24 +6480,22 @@ public class Reflections { public static final Field field$ClientboundResourcePackPushPacket$prompt = requireNonNull( ReflectionUtils.getDeclaredField( clazz$ClientboundResourcePackPushPacket, - VersionHelper.isVersionNewerThan1_20_5() ? Optional.class : clazz$Component, + VersionHelper.isOrAbove1_20_5() ? Optional.class : clazz$Component, 0 ) ); public static final Class clazz$ServerboundResourcePackPacket = requireNonNull( - ReflectionUtils.getClazz( - BukkitReflectionUtils.assembleMCClass("network.protocol.common.ServerboundResourcePackPacket"), - BukkitReflectionUtils.assembleMCClass("network.protocol.game.PacketPlayInResourcePackStatus") + BukkitReflectionUtils.findReobfOrMojmapClass( + List.of("network.protocol.game.PacketPlayInResourcePackStatus", "network.protocol.common.ServerboundResourcePackPacket"), + List.of("network.protocol.game.ServerboundResourcePackPacket", "network.protocol.common.ServerboundResourcePackPacket") ) ); public static final Class clazz$ServerboundResourcePackPacket$Action = requireNonNull( - ReflectionUtils.getClazz( - BukkitReflectionUtils.assembleMCClass("network.protocol.common.ServerboundResourcePackPacket$Action"), - BukkitReflectionUtils.assembleMCClass("network.protocol.common.ServerboundResourcePackPacket$a"), - BukkitReflectionUtils.assembleMCClass("network.protocol.game.ServerboundResourcePackPacket$Action"), - BukkitReflectionUtils.assembleMCClass("network.protocol.game.PacketPlayInResourcePackStatus$EnumResourcePackStatus") + BukkitReflectionUtils.findReobfOrMojmapClass( + List.of("network.protocol.game.PacketPlayInResourcePackStatus$EnumResourcePackStatus", "network.protocol.common.ServerboundResourcePackPacket$a"), + List.of("network.protocol.game.ServerboundResourcePackPacket$Action", "network.protocol.common.ServerboundResourcePackPacket$Action") ) ); @@ -6499,12 +6505,33 @@ public class Reflections { ) ); + public static final Object instance$ServerboundResourcePackPacket$Action$SUCCESSFULLY_LOADED; + public static final Object instance$ServerboundResourcePackPacket$Action$DECLINED; + public static final Object instance$ServerboundResourcePackPacket$Action$FAILED_DOWNLOAD; public static final Object instance$ServerboundResourcePackPacket$Action$ACCEPTED; + public static final Object instance$ServerboundResourcePackPacket$Action$DOWNLOADED; + public static final Object instance$ServerboundResourcePackPacket$Action$INVALID_URL; + public static final Object instance$ServerboundResourcePackPacket$Action$FAILED_RELOAD; + public static final Object instance$ServerboundResourcePackPacket$Action$DISCARDED; static { try { Object[] values = (Object[]) method$ServerboundResourcePackPacket$Action$values.invoke(null); + instance$ServerboundResourcePackPacket$Action$SUCCESSFULLY_LOADED = values[0]; + instance$ServerboundResourcePackPacket$Action$DECLINED = values[1]; + instance$ServerboundResourcePackPacket$Action$FAILED_DOWNLOAD = values[2]; instance$ServerboundResourcePackPacket$Action$ACCEPTED = values[3]; + if (VersionHelper.isOrAbove1_20_3()) { + instance$ServerboundResourcePackPacket$Action$DOWNLOADED = values[4]; + instance$ServerboundResourcePackPacket$Action$INVALID_URL = values[5]; + instance$ServerboundResourcePackPacket$Action$FAILED_RELOAD = values[6]; + instance$ServerboundResourcePackPacket$Action$DISCARDED = values[7]; + } else { + instance$ServerboundResourcePackPacket$Action$DOWNLOADED = null; + instance$ServerboundResourcePackPacket$Action$INVALID_URL = null; + instance$ServerboundResourcePackPacket$Action$FAILED_RELOAD = null; + instance$ServerboundResourcePackPacket$Action$DISCARDED = null; + } } catch (Exception e) { throw new RuntimeException(e); } @@ -6521,4 +6548,29 @@ public class Reflections { "core.component.DataComponentType" ) ); + + public static final Class clazz$ClientIntentionPacket = requireNonNull( + BukkitReflectionUtils.findReobfOrMojmapClass( + "network.protocol.handshake.PacketHandshakingInSetProtocol", + "network.protocol.handshake.ClientIntentionPacket" + ) + ); + + public static final Field field$ClientIntentionPacket$protocolVersion = requireNonNull( + ReflectionUtils.getDeclaredField( + clazz$ClientIntentionPacket, int.class, VersionHelper.isOrAbove1_20_2() ? 0 : 1 + ) + ); + + // 1.20.2+ + public static final Class clazz$ServerboundLoginAcknowledgedPacket = + ReflectionUtils.getClazz( + BukkitReflectionUtils.assembleMCClass("network.protocol.login.ServerboundLoginAcknowledgedPacket") + ); + + public static final Field field$ServerboundResourcePackPacket$action = requireNonNull( + ReflectionUtils.getDeclaredField( + clazz$ServerboundResourcePackPacket, clazz$ServerboundResourcePackPacket$Action, 0 + ) + ); } diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/world/BukkitWorld.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/world/BukkitWorld.java index 5e6aa6235..b63a851ac 100644 --- a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/world/BukkitWorld.java +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/world/BukkitWorld.java @@ -74,7 +74,7 @@ public class BukkitWorld implements World { public void dropItemNaturally(Vec3d location, Item item) { ItemStack itemStack = (ItemStack) item.load(); if (ItemUtils.isEmpty(itemStack)) return; - if (VersionHelper.isVersionNewerThan1_21_2()) { + if (VersionHelper.isOrAbove1_21_2()) { platformWorld().dropItemNaturally(new Location(null, location.x(), location.y(), location.z()), (ItemStack) item.getItem()); } else { platformWorld().dropItemNaturally(new Location(null, location.x() - 0.5, location.y() - 0.5, location.z() - 0.5), (ItemStack) item.getItem()); diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/world/BukkitWorldManager.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/world/BukkitWorldManager.java index b402a8fad..070737eee 100644 --- a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/world/BukkitWorldManager.java +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/world/BukkitWorldManager.java @@ -1,6 +1,5 @@ package net.momirealms.craftengine.bukkit.world; -import net.momirealms.craftengine.bukkit.compatibility.slimeworld.SlimeFormatStorageAdaptor; import net.momirealms.craftengine.bukkit.nms.FastNMS; import net.momirealms.craftengine.bukkit.plugin.BukkitCraftEngine; import net.momirealms.craftengine.bukkit.plugin.injector.BukkitInjector; @@ -10,18 +9,15 @@ import net.momirealms.craftengine.core.block.ImmutableBlockState; import net.momirealms.craftengine.core.plugin.CraftEngine; import net.momirealms.craftengine.core.plugin.config.Config; import net.momirealms.craftengine.core.plugin.scheduler.SchedulerTask; -import net.momirealms.craftengine.core.util.VersionHelper; import net.momirealms.craftengine.core.world.CEWorld; import net.momirealms.craftengine.core.world.ChunkPos; import net.momirealms.craftengine.core.world.SectionPos; import net.momirealms.craftengine.core.world.WorldManager; import net.momirealms.craftengine.core.world.chunk.CEChunk; import net.momirealms.craftengine.core.world.chunk.CESection; -import net.momirealms.craftengine.core.world.chunk.serialization.ChunkSerializer; import net.momirealms.craftengine.core.world.chunk.storage.DefaultStorageAdaptor; import net.momirealms.craftengine.core.world.chunk.storage.StorageAdaptor; import net.momirealms.craftengine.core.world.chunk.storage.WorldDataStorage; -import net.momirealms.sparrow.nbt.CompoundTag; import org.bukkit.Bukkit; import org.bukkit.Chunk; import org.bukkit.World; @@ -29,10 +25,7 @@ import org.bukkit.event.EventHandler; import org.bukkit.event.EventPriority; import org.bukkit.event.HandlerList; import org.bukkit.event.Listener; -import org.bukkit.event.world.ChunkLoadEvent; -import org.bukkit.event.world.ChunkUnloadEvent; -import org.bukkit.event.world.WorldLoadEvent; -import org.bukkit.event.world.WorldUnloadEvent; +import org.bukkit.event.world.*; import org.jetbrains.annotations.NotNull; import java.io.IOException; @@ -57,16 +50,6 @@ public class BukkitWorldManager implements WorldManager, Listener { instance = this; this.plugin = plugin; this.worlds = new HashMap<>(); - if (VersionHelper.isVersionNewerThan1_21_4()) { - try { - Class.forName("com.infernalsuite.asp.api.AdvancedSlimePaperAPI"); - SlimeFormatStorageAdaptor adaptor = new SlimeFormatStorageAdaptor(this); - this.storageAdaptor = adaptor; - Bukkit.getPluginManager().registerEvents(adaptor, plugin.bootstrap()); - return; - } catch (ClassNotFoundException ignored) { - } - } this.storageAdaptor = new DefaultStorageAdaptor(); } @@ -148,6 +131,11 @@ public class BukkitWorldManager implements WorldManager, Listener { for (Chunk chunk : world.getLoadedChunks()) { handleChunkUnload(ceWorld, chunk); } + try { + ceWorld.worldDataStorage().close(); + } catch (IOException e) { + this.plugin.logger().warn("Error unloading world: " + world.getName(), e); + } } this.worlds.clear(); } @@ -198,6 +186,13 @@ public class BukkitWorldManager implements WorldManager, Listener { unloadWorld(new BukkitWorld(event.getWorld())); } + @EventHandler(ignoreCancelled = true, priority = EventPriority.HIGHEST) + public void onWorldSave(WorldSaveEvent event) { + for (CEWorld world : this.worldArray) { + world.save(); + } + } + @Override public void unloadWorld(net.momirealms.craftengine.core.world.World world) { CEWorld ceWorld; @@ -270,10 +265,9 @@ public class BukkitWorldManager implements WorldManager, Listener { CEChunk ceChunk = world.getChunkAtIfLoaded(chunk.getX(), chunk.getZ()); if (ceChunk != null) { try { - world.worldDataStorage().writeChunkTagAt(pos, ChunkSerializer.serialize(ceChunk)); + world.worldDataStorage().writeChunkAt(pos, ceChunk, false); } catch (IOException e) { - plugin.logger().warn("Failed to write chunk tag at " + chunk.getX() + " " + chunk.getZ(), e); - return; + this.plugin.logger().warn("Failed to write chunk tag at " + chunk.getX() + " " + chunk.getZ(), e); } finally { if (Config.restoreVanillaBlocks()) { CESection[] ceSections = ceChunk.sections(); @@ -308,12 +302,7 @@ public class BukkitWorldManager implements WorldManager, Listener { if (ceWorld.isChunkLoaded(pos.longKey)) return; CEChunk ceChunk; try { - CompoundTag chunkNbt = ceWorld.worldDataStorage().readChunkTagAt(pos); - if (chunkNbt != null) { - ceChunk = ChunkSerializer.deserialize(ceWorld, pos, chunkNbt); - } else { - ceChunk = new CEChunk(ceWorld, pos); - } + ceChunk = ceWorld.worldDataStorage().readChunkAt(ceWorld, pos); try { CESection[] ceSections = ceChunk.sections(); Object worldServer = FastNMS.INSTANCE.field$CraftChunk$worldServer(chunk); diff --git a/core/src/main/java/net/momirealms/craftengine/core/block/BlockNbtParser.java b/core/src/main/java/net/momirealms/craftengine/core/block/BlockNbtParser.java index aada90b73..5e8c4956f 100644 --- a/core/src/main/java/net/momirealms/craftengine/core/block/BlockNbtParser.java +++ b/core/src/main/java/net/momirealms/craftengine/core/block/BlockNbtParser.java @@ -12,7 +12,7 @@ public class BlockNbtParser { @Nullable public static CompoundTag deserialize(@NotNull CustomBlock block, @NotNull String data) { - StringReader reader = new StringReader(data); + StringReader reader = StringReader.simple(data); CompoundTag properties = new CompoundTag(); while (reader.canRead()) { String propertyName = reader.readUnquotedString(); diff --git a/core/src/main/java/net/momirealms/craftengine/core/block/BlockStateHolder.java b/core/src/main/java/net/momirealms/craftengine/core/block/BlockStateHolder.java index feb5535cb..7d9c265b3 100644 --- a/core/src/main/java/net/momirealms/craftengine/core/block/BlockStateHolder.java +++ b/core/src/main/java/net/momirealms/craftengine/core/block/BlockStateHolder.java @@ -48,16 +48,11 @@ public class BlockStateHolder { return propertyMap.entrySet().stream() .map(entry -> { Property property = entry.getKey(); - return property.name() + "=" + formatValue(property, entry.getValue()); + return property.name() + "=" + Property.formatValue(property, entry.getValue()); }) .collect(Collectors.joining(",")); } - @SuppressWarnings("unchecked") - private static > String formatValue(Property property, Comparable value) { - return property.valueName((T) value); - } - public Collection> getProperties() { return Collections.unmodifiableSet(propertyMap.keySet()); } diff --git a/core/src/main/java/net/momirealms/craftengine/core/block/BlockStateMatcher.java b/core/src/main/java/net/momirealms/craftengine/core/block/BlockStateMatcher.java new file mode 100644 index 000000000..3886220dc --- /dev/null +++ b/core/src/main/java/net/momirealms/craftengine/core/block/BlockStateMatcher.java @@ -0,0 +1,108 @@ +package net.momirealms.craftengine.core.block; + +import net.momirealms.craftengine.core.block.properties.Property; +import net.momirealms.craftengine.core.registry.BuiltInRegistries; +import net.momirealms.craftengine.core.registry.Holder; +import net.momirealms.craftengine.core.util.Key; +import net.momirealms.craftengine.core.util.Pair; +import net.momirealms.craftengine.core.util.StringReader; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.util.ArrayList; +import java.util.List; +import java.util.Optional; +import java.util.stream.Collectors; + +public class BlockStateMatcher { + private final List, Comparable>> properties; + private final Key id; + + public BlockStateMatcher(Key id, List, Comparable>> properties) { + this.properties = properties; + this.id = id; + } + + public boolean matches(ImmutableBlockState state) { + if (!state.owner().value().id.equals(this.id)) { + return false; + } + for (Pair, Comparable> pair : this.properties) { + if (!state.get(pair.left()).equals(pair.right())) { + return false; + } + } + return true; + } + + @Override + public String toString() { + if (properties.isEmpty()) { + return id.toString(); + } + return id + "[" + getPropertiesAsString() + "]"; + } + + public String getPropertiesAsString() { + return properties.stream() + .map(entry -> { + Property property = entry.left(); + return property.name() + "=" + Property.formatValue(property, entry.right()); + }) + .collect(Collectors.joining(",")); + } + + @SuppressWarnings("DuplicatedCode") + @Nullable + public static BlockStateMatcher deserialize(@NotNull String data) { + StringReader reader = StringReader.simple(data); + String blockIdString = reader.readUnquotedString(); + if (reader.canRead() && reader.peek() == ':') { + reader.skip(); + blockIdString = blockIdString + ":" + reader.readUnquotedString(); + } + Optional> optional = BuiltInRegistries.BLOCK.get(Key.from(blockIdString)); + if (optional.isEmpty()) { + return null; + } + Holder holder = optional.get(); + List, Comparable>> properties = new ArrayList<>(); + if (reader.canRead() && reader.peek() == '[') { + reader.skip(); + while (reader.canRead()) { + reader.skipWhitespace(); + if (reader.peek() == ']') break; + String propertyName = reader.readUnquotedString(); + reader.skipWhitespace(); + if (!reader.canRead() || reader.peek() != '=') { + return null; + } + reader.skip(); + reader.skipWhitespace(); + String propertyValue = reader.readUnquotedString(); + Property property = holder.value().getProperty(propertyName); + if (property != null) { + Optional optionalValue = property.optional(propertyValue); + if (optionalValue.isEmpty()) { + return null; + } else { + properties.add(Pair.of(property, (Comparable) optionalValue.get())); + } + } else { + return null; + } + reader.skipWhitespace(); + if (reader.canRead() && reader.peek() == ',') { + reader.skip(); + } + } + reader.skipWhitespace(); + if (reader.canRead() && reader.peek() == ']') { + reader.skip(); + } else { + return null; + } + } + return new BlockStateMatcher(holder.value().id(), properties); + } +} diff --git a/core/src/main/java/net/momirealms/craftengine/core/block/BlockStateParser.java b/core/src/main/java/net/momirealms/craftengine/core/block/BlockStateParser.java index f8cc31c6e..8d8ec6949 100644 --- a/core/src/main/java/net/momirealms/craftengine/core/block/BlockStateParser.java +++ b/core/src/main/java/net/momirealms/craftengine/core/block/BlockStateParser.java @@ -31,7 +31,7 @@ public class BlockStateParser { private Property property; public BlockStateParser(String data, int cursor) { - this.reader = new StringReader(data.toLowerCase()); + this.reader = StringReader.simple(data.toLowerCase()); this.reader.setCursor(cursor); this.cursor = cursor; this.replaceCursor = cursor; @@ -188,7 +188,7 @@ public class BlockStateParser { @Nullable public static ImmutableBlockState deserialize(@NotNull String data) { - StringReader reader = new StringReader(data); + StringReader reader = StringReader.simple(data); String blockIdString = reader.readUnquotedString(); if (reader.canRead() && reader.peek() == ':') { reader.skip(); diff --git a/core/src/main/java/net/momirealms/craftengine/core/block/UnsafeBlockStateMatcher.java b/core/src/main/java/net/momirealms/craftengine/core/block/UnsafeBlockStateMatcher.java new file mode 100644 index 000000000..00b9d4b49 --- /dev/null +++ b/core/src/main/java/net/momirealms/craftengine/core/block/UnsafeBlockStateMatcher.java @@ -0,0 +1,98 @@ +package net.momirealms.craftengine.core.block; + +import net.momirealms.craftengine.core.block.properties.Property; +import net.momirealms.craftengine.core.registry.BuiltInRegistries; +import net.momirealms.craftengine.core.registry.Holder; +import net.momirealms.craftengine.core.util.Key; +import net.momirealms.craftengine.core.util.Pair; +import net.momirealms.craftengine.core.util.StringReader; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.util.ArrayList; +import java.util.List; +import java.util.Optional; +import java.util.stream.Collectors; + +public class UnsafeBlockStateMatcher { + private final List> matchers; + private final Key id; + + public UnsafeBlockStateMatcher(Key id, List> matchers) { + this.id = id; + this.matchers = matchers; + } + + public boolean matches(ImmutableBlockState state) { + if (!state.owner().value().id.equals(this.id)) { + return false; + } + CustomBlock customBlock = state.owner().value(); + for (Pair matcher : matchers) { + Property property = customBlock.getProperty(matcher.left()); + if (property == null) { + return false; + } + Comparable value = state.get(property); + String valueStr = Property.formatValue(property, value); + if (!matcher.right().equals(valueStr)) { + return false; + } + } + return true; + } + + @Override + public String toString() { + if (matchers.isEmpty()) { + return id.toString(); + } + return id + "[" + matchers.stream() + .map(entry -> entry.left() + "=" + entry.right()) + .collect(Collectors.joining(",")) + "]"; + } + + @SuppressWarnings("DuplicatedCode") + @Nullable + public static UnsafeBlockStateMatcher deserialize(@NotNull String data) { + StringReader reader = StringReader.simple(data); + String blockIdString = reader.readUnquotedString(); + if (reader.canRead() && reader.peek() == ':') { + reader.skip(); + blockIdString = blockIdString + ":" + reader.readUnquotedString(); + } + Optional> optional = BuiltInRegistries.BLOCK.get(Key.from(blockIdString)); + if (optional.isEmpty()) { + return null; + } + Holder holder = optional.get(); + List> properties = new ArrayList<>(); + if (reader.canRead() && reader.peek() == '[') { + reader.skip(); + while (reader.canRead()) { + reader.skipWhitespace(); + if (reader.peek() == ']') break; + String propertyName = reader.readUnquotedString(); + reader.skipWhitespace(); + if (!reader.canRead() || reader.peek() != '=') { + return null; + } + reader.skip(); + reader.skipWhitespace(); + String propertyValue = reader.readUnquotedString(); + properties.add(new Pair<>(propertyName, propertyValue)); + reader.skipWhitespace(); + if (reader.canRead() && reader.peek() == ',') { + reader.skip(); + } + } + reader.skipWhitespace(); + if (reader.canRead() && reader.peek() == ']') { + reader.skip(); + } else { + return null; + } + } + return new UnsafeBlockStateMatcher(holder.value().id(), properties); + } +} diff --git a/core/src/main/java/net/momirealms/craftengine/core/block/properties/Property.java b/core/src/main/java/net/momirealms/craftengine/core/block/properties/Property.java index 83b45f7fb..a61d33e00 100644 --- a/core/src/main/java/net/momirealms/craftengine/core/block/properties/Property.java +++ b/core/src/main/java/net/momirealms/craftengine/core/block/properties/Property.java @@ -162,4 +162,9 @@ public abstract class Property> { .map(it -> it.apply(property)) .orElse(((context, state) -> ImmutableBlockState.with(state, property, property.defaultValue()))); } + + @SuppressWarnings("unchecked") + public static > String formatValue(Property property, Comparable value) { + return property.valueName((T) value); + } } diff --git a/core/src/main/java/net/momirealms/craftengine/core/font/AbstractFontManager.java b/core/src/main/java/net/momirealms/craftengine/core/font/AbstractFontManager.java index 072010f25..60bcb92b4 100644 --- a/core/src/main/java/net/momirealms/craftengine/core/font/AbstractFontManager.java +++ b/core/src/main/java/net/momirealms/craftengine/core/font/AbstractFontManager.java @@ -384,7 +384,12 @@ public abstract class AbstractFontManager implements FontManager { Key imageId = new Key(split[0], split[1]); Optional bitmapImage = bitmapImageByImageId(imageId); if (bitmapImage.isPresent()) { - image = bitmapImage.get().miniMessage(Integer.parseInt(split[2]), Integer.parseInt(split[3])); + try { + image = bitmapImage.get().miniMessage(Integer.parseInt(split[2]), Integer.parseInt(split[3])); + } catch (ArrayIndexOutOfBoundsException e) { + TranslationManager.instance().log("warning.config.emoji.invalid_image", path.toString(), id.toString(), rawImage); + return; + } } else { TranslationManager.instance().log("warning.config.emoji.invalid_image", path.toString(), id.toString(), rawImage); return; @@ -462,15 +467,20 @@ public abstract class AbstractFontManager implements FontManager { } }).toList(); } else { - String character = (String) section.get("char"); - if (character == null) { + Object c = section.get("char"); + if (c == null) { TranslationManager.instance().log("warning.config.image.lack_char", path.toString(), id.toString()); return; } - if (character.length() == 1) { - chars = List.of(character.toCharArray()); + if (c instanceof Integer integer) { + chars = List.of(new char[]{(char) integer.intValue()}); } else { - chars = List.of(CharacterUtils.decodeUnicodeToChars(character)); + String character = c.toString(); + if (character.length() == 1) { + chars = List.of(character.toCharArray()); + } else { + chars = List.of(CharacterUtils.decodeUnicodeToChars(character)); + } } } @@ -492,6 +502,10 @@ public abstract class AbstractFontManager implements FontManager { return; } } + if (codepoints.length == 0) { + TranslationManager.instance().log("warning.config.image.lack_char", path.toString(), id.toString()); + return; + } codepointGrid[i] = codepoints; if (size == -1) size = codepoints.length; if (size != codepoints.length) { diff --git a/core/src/main/java/net/momirealms/craftengine/core/font/FontManager.java b/core/src/main/java/net/momirealms/craftengine/core/font/FontManager.java index 59869b59b..95d2251d4 100644 --- a/core/src/main/java/net/momirealms/craftengine/core/font/FontManager.java +++ b/core/src/main/java/net/momirealms/craftengine/core/font/FontManager.java @@ -15,6 +15,7 @@ import org.jetbrains.annotations.Nullable; import java.util.Collection; import java.util.Map; import java.util.Optional; +import java.util.UUID; public interface FontManager extends Manageable { Key DEFAULT_FONT = Key.of("minecraft:default"); @@ -103,4 +104,6 @@ public interface FontManager extends Manageable { } Map matchTags(String json); + + void refreshEmojiSuggestions(UUID uuid); } diff --git a/core/src/main/java/net/momirealms/craftengine/core/item/AbstractItemManager.java b/core/src/main/java/net/momirealms/craftengine/core/item/AbstractItemManager.java index 74c19e195..4548fadab 100644 --- a/core/src/main/java/net/momirealms/craftengine/core/item/AbstractItemManager.java +++ b/core/src/main/java/net/momirealms/craftengine/core/item/AbstractItemManager.java @@ -229,25 +229,29 @@ public abstract class AbstractItemManager extends AbstractModelGenerator impl String pattern = data.get("pattern").toString().toLowerCase(Locale.ENGLISH); return new TrimModifier<>(material, pattern); }, "trim"); - if (VersionHelper.isVersionNewerThan1_20_5()) { + if (VersionHelper.isOrAbove1_20_5()) { registerDataFunction((obj) -> { Map data = MiscUtils.castToMap(obj, false); return new ComponentModifier<>(data); }, "components", "component"); + registerDataFunction((obj) -> { + List data = MiscUtils.getAsStringList(obj); + return new RemoveComponentModifier<>(data); + }, "remove-components", "remove-component"); } - if (VersionHelper.isVersionNewerThan1_21()) { + if (VersionHelper.isOrAbove1_21()) { registerDataFunction((obj) -> { String song = obj.toString(); return new JukeboxSongModifier<>(new JukeboxPlayable(song, true)); }, "jukebox-playable"); } - if (VersionHelper.isVersionNewerThan1_21_2()) { + if (VersionHelper.isOrAbove1_21_2()) { registerDataFunction((obj) -> { String id = obj.toString(); return new TooltipStyleModifier<>(Key.of(id)); }, "tooltip-style"); } - if (VersionHelper.isVersionNewerThan1_21_2()) { + if (VersionHelper.isOrAbove1_21_2()) { registerDataFunction((obj) -> { Map data = MiscUtils.castToMap(obj, false); return new EquippableModifier<>(EquipmentData.fromMap(data)); diff --git a/core/src/main/java/net/momirealms/craftengine/core/item/EquipmentData.java b/core/src/main/java/net/momirealms/craftengine/core/item/EquipmentData.java index 25c10703f..2a33f07df 100644 --- a/core/src/main/java/net/momirealms/craftengine/core/item/EquipmentData.java +++ b/core/src/main/java/net/momirealms/craftengine/core/item/EquipmentData.java @@ -104,7 +104,7 @@ public class EquipmentData { map.put("dispensable", this.dispensable); map.put("swappable", this.swappable); map.put("damage_on_hurt", this.damageOnHurt); - if (VersionHelper.isVersionNewerThan1_21_5()) { + if (VersionHelper.isOrAbove1_21_5()) { map.put("equip_on_interact", this.equipOnInteract); } if (this.cameraOverlay != null) { diff --git a/core/src/main/java/net/momirealms/craftengine/core/item/ItemSettings.java b/core/src/main/java/net/momirealms/craftengine/core/item/ItemSettings.java index 3e5897b11..2e02df698 100644 --- a/core/src/main/java/net/momirealms/craftengine/core/item/ItemSettings.java +++ b/core/src/main/java/net/momirealms/craftengine/core/item/ItemSettings.java @@ -25,7 +25,7 @@ public class ItemSettings { public List> modifiers() { ArrayList> modifiers = new ArrayList<>(); - if (VersionHelper.isVersionNewerThan1_21_2() && this.equipment != null && this.equipment.modernData() != null) modifiers.add(new EquippableModifier<>(this.equipment.modernData())); + if (VersionHelper.isOrAbove1_21_2() && this.equipment != null && this.equipment.modernData() != null) modifiers.add(new EquippableModifier<>(this.equipment.modernData())); // TODO 1.20 leather armor return modifiers; } @@ -172,7 +172,7 @@ public class ItemSettings { registerFactory("equippable", (value -> { Map args = MiscUtils.castToMap(value, false); EquipmentData data; - if (VersionHelper.isVersionNewerThan1_21_2() && args.containsKey("slot")) data = EquipmentData.fromMap(args); + if (VersionHelper.isOrAbove1_21_2() && args.containsKey("slot")) data = EquipmentData.fromMap(args); else data = null; EquipmentGeneration equipment = new EquipmentGeneration( EquipmentGeneration.Layer.fromConfig(args.get("humanoid")), diff --git a/core/src/main/java/net/momirealms/craftengine/core/item/modifier/RemoveComponentModifier.java b/core/src/main/java/net/momirealms/craftengine/core/item/modifier/RemoveComponentModifier.java new file mode 100644 index 000000000..b44deeca0 --- /dev/null +++ b/core/src/main/java/net/momirealms/craftengine/core/item/modifier/RemoveComponentModifier.java @@ -0,0 +1,36 @@ +package net.momirealms.craftengine.core.item.modifier; + +import net.momirealms.craftengine.core.item.Item; +import net.momirealms.craftengine.core.item.ItemBuildContext; + +import java.util.Collections; +import java.util.List; + +public class RemoveComponentModifier implements ItemDataModifier { + private final List arguments; + + public RemoveComponentModifier(List arguments) { + this.arguments = arguments; + } + + public List arguments() { + return Collections.unmodifiableList(this.arguments); + } + + @Override + public String name() { + return "remove-components"; + } + + @Override + public void apply(Item item, ItemBuildContext context) { + for (String argument : arguments) { + item.removeComponent(argument); + } + } + + @Override + public void remove(Item item) { + // I can't guess + } +} diff --git a/core/src/main/java/net/momirealms/craftengine/core/item/recipe/AbstractRecipeManager.java b/core/src/main/java/net/momirealms/craftengine/core/item/recipe/AbstractRecipeManager.java index 069a4c03f..6f55615cf 100644 --- a/core/src/main/java/net/momirealms/craftengine/core/item/recipe/AbstractRecipeManager.java +++ b/core/src/main/java/net/momirealms/craftengine/core/item/recipe/AbstractRecipeManager.java @@ -40,9 +40,9 @@ public abstract class AbstractRecipeManager implements RecipeManager { } private VanillaRecipeReader initVanillaRecipeReader() { - if (VersionHelper.isVersionNewerThan1_21_2()) { + if (VersionHelper.isOrAbove1_21_2()) { return new VanillaRecipeReader1_21_2(); - } else if (VersionHelper.isVersionNewerThan1_20_5()) { + } else if (VersionHelper.isOrAbove1_20_5()) { return new VanillaRecipeReader1_20_5(); } else { return new VanillaRecipeReader1_20(); diff --git a/core/src/main/java/net/momirealms/craftengine/core/item/recipe/CustomSmithingTransformRecipe.java b/core/src/main/java/net/momirealms/craftengine/core/item/recipe/CustomSmithingTransformRecipe.java index 309a5e41f..51dabc68d 100644 --- a/core/src/main/java/net/momirealms/craftengine/core/item/recipe/CustomSmithingTransformRecipe.java +++ b/core/src/main/java/net/momirealms/craftengine/core/item/recipe/CustomSmithingTransformRecipe.java @@ -161,7 +161,7 @@ public class CustomSmithingTransformRecipe implements Recipe { public static final Key KEEP_TAGS = Key.of("craftengine:keep_tags"); static { - if (VersionHelper.isVersionNewerThan1_20_5()) { + if (VersionHelper.isOrAbove1_20_5()) { register(KEEP_COMPONENTS, KeepComponents.FACTORY); } else { register(KEEP_TAGS, KeepTags.FACTORY); diff --git a/core/src/main/java/net/momirealms/craftengine/core/loot/LootPool.java b/core/src/main/java/net/momirealms/craftengine/core/loot/LootPool.java index 04a196a1a..981093c85 100644 --- a/core/src/main/java/net/momirealms/craftengine/core/loot/LootPool.java +++ b/core/src/main/java/net/momirealms/craftengine/core/loot/LootPool.java @@ -10,7 +10,7 @@ import net.momirealms.craftengine.core.loot.function.LootFunction; import net.momirealms.craftengine.core.loot.function.LootFunctions; import net.momirealms.craftengine.core.loot.number.NumberProvider; import net.momirealms.craftengine.core.util.MCUtils; -import org.apache.commons.lang3.mutable.MutableInt; +import net.momirealms.craftengine.core.util.MutableInt; import java.util.List; import java.util.Random; @@ -64,7 +64,7 @@ public class LootPool { private void addRandomItem(Consumer> lootConsumer, LootContext context) { Random randomSource = context.randomSource(); List> list = Lists.newArrayList(); - MutableInt mutableInt = new MutableInt(); + MutableInt mutableInt = new MutableInt(0); for (LootEntryContainer lootPoolEntryContainer : this.entryContainers) { lootPoolEntryContainer.expand(context, (choice) -> { int i = choice.getWeight(context.luck()); diff --git a/core/src/main/java/net/momirealms/craftengine/core/plugin/CompatibilityManager.java b/core/src/main/java/net/momirealms/craftengine/core/plugin/CompatibilityManager.java new file mode 100644 index 000000000..b6f1d0794 --- /dev/null +++ b/core/src/main/java/net/momirealms/craftengine/core/plugin/CompatibilityManager.java @@ -0,0 +1,31 @@ +package net.momirealms.craftengine.core.plugin; + +import net.momirealms.craftengine.core.entity.furniture.AbstractExternalModel; +import net.momirealms.craftengine.core.entity.player.Player; + +import java.util.UUID; + +public interface CompatibilityManager { + + void onLoad(); + + void onEnable(); + + void onDelayedEnable(); + + AbstractExternalModel createModelEngineModel(String id); + + AbstractExternalModel createBetterModelModel(String id); + + int interactionToBaseEntity(int id); + + boolean hasPlaceholderAPI(); + + boolean isPluginEnabled(String plugin); + + boolean hasPlugin(String plugin); + + String parse(Player player, String text); + + int getPlayerProtocolVersion(UUID uuid); +} diff --git a/core/src/main/java/net/momirealms/craftengine/core/plugin/CraftEngine.java b/core/src/main/java/net/momirealms/craftengine/core/plugin/CraftEngine.java index 0a2fe02bc..a0c9669e2 100644 --- a/core/src/main/java/net/momirealms/craftengine/core/plugin/CraftEngine.java +++ b/core/src/main/java/net/momirealms/craftengine/core/plugin/CraftEngine.java @@ -29,7 +29,6 @@ import net.momirealms.craftengine.core.plugin.logger.filter.LogFilter; import net.momirealms.craftengine.core.plugin.network.NetworkManager; import net.momirealms.craftengine.core.plugin.scheduler.SchedulerAdapter; import net.momirealms.craftengine.core.sound.SoundManager; -import net.momirealms.craftengine.core.util.VersionHelper; import net.momirealms.craftengine.core.world.WorldManager; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.core.Logger; @@ -68,6 +67,7 @@ public abstract class CraftEngine implements Plugin { protected SoundManager soundManager; protected VanillaLootManager vanillaLootManager; protected AdvancementManager advancementManager; + protected CompatibilityManager compatibilityManager; private final Consumer reloadEventDispatcher; private boolean isReloading; @@ -82,7 +82,6 @@ public abstract class CraftEngine implements Plugin { protected CraftEngine(Consumer reloadEventDispatcher) { instance = this; this.reloadEventDispatcher = reloadEventDispatcher; - VersionHelper.init(serverVersion()); } public static CraftEngine instance() { @@ -371,8 +370,6 @@ public abstract class CraftEngine implements Plugin { return isInitializing; } - public abstract boolean hasPlaceholderAPI(); - @Override public DependencyManager dependencyManager() { return dependencyManager; @@ -460,4 +457,9 @@ public abstract class CraftEngine implements Plugin { public VanillaLootManager vanillaLootManager() { return vanillaLootManager; } + + @Override + public CompatibilityManager compatibilityManager() { + return compatibilityManager; + } } diff --git a/core/src/main/java/net/momirealms/craftengine/core/plugin/Plugin.java b/core/src/main/java/net/momirealms/craftengine/core/plugin/Plugin.java index aa0fb2508..d7d693264 100644 --- a/core/src/main/java/net/momirealms/craftengine/core/plugin/Plugin.java +++ b/core/src/main/java/net/momirealms/craftengine/core/plugin/Plugin.java @@ -3,7 +3,6 @@ package net.momirealms.craftengine.core.plugin; import net.momirealms.craftengine.core.advancement.AdvancementManager; import net.momirealms.craftengine.core.block.BlockManager; import net.momirealms.craftengine.core.entity.furniture.FurnitureManager; -import net.momirealms.craftengine.core.entity.player.Player; import net.momirealms.craftengine.core.font.FontManager; import net.momirealms.craftengine.core.item.ItemManager; import net.momirealms.craftengine.core.item.recipe.RecipeManager; @@ -90,7 +89,5 @@ public interface Plugin { void debug(Supplier message); - boolean isPluginEnabled(String plugin); - - String parse(Player player, String text); + CompatibilityManager compatibilityManager(); } diff --git a/core/src/main/java/net/momirealms/craftengine/core/plugin/config/Config.java b/core/src/main/java/net/momirealms/craftengine/core/plugin/config/Config.java index fffc622f2..a1020c555 100644 --- a/core/src/main/java/net/momirealms/craftengine/core/plugin/config/Config.java +++ b/core/src/main/java/net/momirealms/craftengine/core/plugin/config/Config.java @@ -98,6 +98,7 @@ public class Config { protected boolean chunk_system$restore_vanilla_blocks_on_chunk_unload; protected boolean chunk_system$restore_custom_blocks_on_chunk_load; protected boolean chunk_system$sync_custom_blocks_on_chunk_load; + protected int chunk_system$delay_serialization; protected boolean furniture$handle_invalid_furniture_on_chunk_load$enable; protected Map furniture$handle_invalid_furniture_on_chunk_load$mapping; @@ -265,6 +266,7 @@ public class Config { chunk_system$restore_vanilla_blocks_on_chunk_unload = config.getBoolean("chunk-system.restore-vanilla-blocks-on-chunk-unload", true); chunk_system$restore_custom_blocks_on_chunk_load = config.getBoolean("chunk-system.restore-custom-blocks-on-chunk-load", true); chunk_system$sync_custom_blocks_on_chunk_load = config.getBoolean("chunk-system.sync-custom-blocks-on-chunk-load", false); + chunk_system$delay_serialization = config.getInt("chunk-system.delay-serialization", 20); // furniture furniture$handle_invalid_furniture_on_chunk_load$enable = config.getBoolean("furniture.handle-invalid-furniture-on-chunk-load.enable", false); @@ -683,6 +685,10 @@ public class Config { return instance.furniture$collision_entity_type; } + public static int delaySerialization() { + return instance.chunk_system$delay_serialization; + } + public YamlDocument loadOrCreateYamlData(String fileName) { File file = new File(this.plugin.dataFolderFile(), fileName); if (!file.exists()) { diff --git a/core/src/main/java/net/momirealms/craftengine/core/plugin/gui/category/ItemBrowserManagerImpl.java b/core/src/main/java/net/momirealms/craftengine/core/plugin/gui/category/ItemBrowserManagerImpl.java index c457cac1c..b8d61c3d7 100644 --- a/core/src/main/java/net/momirealms/craftengine/core/plugin/gui/category/ItemBrowserManagerImpl.java +++ b/core/src/main/java/net/momirealms/craftengine/core/plugin/gui/category/ItemBrowserManagerImpl.java @@ -406,7 +406,7 @@ public class ItemBrowserManagerImpl implements ItemBrowserManager { if (inRecipes == recipes) return; player.playSound(Constants.SOUND_CLICK_BUTTON); if (!inRecipes.isEmpty()) { - openRecipePage(c.clicker(), e.gui(), inRecipes, 0, 0, canOpenNoRecipePage); + openRecipePage(c.clicker(), e.gui(), inRecipes, 0, depth + 1, canOpenNoRecipePage); } else if (canOpenNoRecipePage) { openNoRecipePage(player, result, e.gui(), 0); } @@ -415,7 +415,7 @@ public class ItemBrowserManagerImpl implements ItemBrowserManager { if (inRecipes == recipes) return; player.playSound(Constants.SOUND_CLICK_BUTTON); if (!inRecipes.isEmpty()) { - openRecipePage(c.clicker(), e.gui(), inRecipes, 0, 0, canOpenNoRecipePage); + openRecipePage(c.clicker(), e.gui(), inRecipes, 0, depth + 1, canOpenNoRecipePage); } } })) @@ -489,7 +489,7 @@ public class ItemBrowserManagerImpl implements ItemBrowserManager { if (inRecipes == recipes) return; player.playSound(Constants.SOUND_CLICK_BUTTON); if (!inRecipes.isEmpty()) { - openRecipePage(c.clicker(), e.gui(), inRecipes, 0, 0, canOpenNoRecipePage); + openRecipePage(c.clicker(), e.gui(), inRecipes, 0, depth + 1, canOpenNoRecipePage); } else if (canOpenNoRecipePage) { openNoRecipePage(player, e.item().id(), e.gui(), 0); } @@ -498,7 +498,7 @@ public class ItemBrowserManagerImpl implements ItemBrowserManager { if (inRecipes == recipes) return; player.playSound(Constants.SOUND_CLICK_BUTTON); if (!inRecipes.isEmpty()) { - openRecipePage(c.clicker(), e.gui(), inRecipes, 0, 0, canOpenNoRecipePage); + openRecipePage(c.clicker(), e.gui(), inRecipes, 0, depth + 1, canOpenNoRecipePage); } } })); @@ -522,7 +522,7 @@ public class ItemBrowserManagerImpl implements ItemBrowserManager { if (inRecipes == recipes) return; player.playSound(Constants.SOUND_CLICK_BUTTON); if (!inRecipes.isEmpty()) { - openRecipePage(c.clicker(), e.gui(), inRecipes, 0, 0, canOpenNoRecipePage); + openRecipePage(c.clicker(), e.gui(), inRecipes, 0, depth + 1, canOpenNoRecipePage); } else if (canOpenNoRecipePage) { openNoRecipePage(player, e.item().id(), e.gui(), 0); } @@ -531,7 +531,7 @@ public class ItemBrowserManagerImpl implements ItemBrowserManager { if (inRecipes == recipes) return; player.playSound(Constants.SOUND_CLICK_BUTTON); if (!inRecipes.isEmpty()) { - openRecipePage(c.clicker(), e.gui(), inRecipes, 0, 0, canOpenNoRecipePage); + openRecipePage(c.clicker(), e.gui(), inRecipes, 0, depth + 1, canOpenNoRecipePage); } } })); @@ -555,7 +555,7 @@ public class ItemBrowserManagerImpl implements ItemBrowserManager { if (inRecipes == recipes) return; player.playSound(Constants.SOUND_CLICK_BUTTON); if (!inRecipes.isEmpty()) { - openRecipePage(c.clicker(), e.gui(), inRecipes, 0, 0, canOpenNoRecipePage); + openRecipePage(c.clicker(), e.gui(), inRecipes, 0, depth + 1, canOpenNoRecipePage); } else if (canOpenNoRecipePage) { openNoRecipePage(player, e.item().id(), e.gui(), 0); } @@ -564,7 +564,7 @@ public class ItemBrowserManagerImpl implements ItemBrowserManager { if (inRecipes == recipes) return; player.playSound(Constants.SOUND_CLICK_BUTTON); if (!inRecipes.isEmpty()) { - openRecipePage(c.clicker(), e.gui(), inRecipes, 0, 0, canOpenNoRecipePage); + openRecipePage(c.clicker(), e.gui(), inRecipes, 0, depth + 1, canOpenNoRecipePage); } } })); @@ -613,7 +613,7 @@ public class ItemBrowserManagerImpl implements ItemBrowserManager { if (inRecipes == recipes) return; player.playSound(Constants.SOUND_CLICK_BUTTON); if (!inRecipes.isEmpty()) { - openRecipePage(c.clicker(), e.gui(), inRecipes, 0, 0, canOpenNoRecipePage); + openRecipePage(c.clicker(), e.gui(), inRecipes, 0, depth + 1, canOpenNoRecipePage); } else if (canOpenNoRecipePage) { openNoRecipePage(player, result, e.gui(), 0); } @@ -622,7 +622,7 @@ public class ItemBrowserManagerImpl implements ItemBrowserManager { if (inRecipes == recipes) return; player.playSound(Constants.SOUND_CLICK_BUTTON); if (!inRecipes.isEmpty()) { - openRecipePage(c.clicker(), e.gui(), inRecipes, 0, 0, canOpenNoRecipePage); + openRecipePage(c.clicker(), e.gui(), inRecipes, 0, depth + 1, canOpenNoRecipePage); } } })) @@ -649,7 +649,7 @@ public class ItemBrowserManagerImpl implements ItemBrowserManager { if (inRecipes == recipes) return; player.playSound(Constants.SOUND_CLICK_BUTTON); if (!inRecipes.isEmpty()) { - openRecipePage(c.clicker(), e.gui(), inRecipes, 0, 0, canOpenNoRecipePage); + openRecipePage(c.clicker(), e.gui(), inRecipes, 0, depth + 1, canOpenNoRecipePage); } else if (canOpenNoRecipePage) { openNoRecipePage(player, e.item().id(), e.gui(), 0); } @@ -658,7 +658,7 @@ public class ItemBrowserManagerImpl implements ItemBrowserManager { if (inRecipes == recipes) return; player.playSound(Constants.SOUND_CLICK_BUTTON); if (!inRecipes.isEmpty()) { - openRecipePage(c.clicker(), e.gui(), inRecipes, 0, 0, canOpenNoRecipePage); + openRecipePage(c.clicker(), e.gui(), inRecipes, 0, depth + 1, canOpenNoRecipePage); } } })) @@ -746,7 +746,7 @@ public class ItemBrowserManagerImpl implements ItemBrowserManager { if (inRecipes == recipes) return; player.playSound(Constants.SOUND_CLICK_BUTTON); if (!inRecipes.isEmpty()) { - openRecipePage(c.clicker(), e.gui(), inRecipes, 0, 0, canOpenNoRecipePage); + openRecipePage(c.clicker(), e.gui(), inRecipes, 0, depth + 1, canOpenNoRecipePage); } else if (canOpenNoRecipePage) { openNoRecipePage(player, result, e.gui(), 0); } @@ -755,7 +755,7 @@ public class ItemBrowserManagerImpl implements ItemBrowserManager { if (inRecipes == recipes) return; player.playSound(Constants.SOUND_CLICK_BUTTON); if (!inRecipes.isEmpty()) { - openRecipePage(c.clicker(), e.gui(), inRecipes, 0, 0, canOpenNoRecipePage); + openRecipePage(c.clicker(), e.gui(), inRecipes, 0, depth + 1, canOpenNoRecipePage); } } })) @@ -788,7 +788,7 @@ public class ItemBrowserManagerImpl implements ItemBrowserManager { if (inRecipes == recipes) return; player.playSound(Constants.SOUND_CLICK_BUTTON); if (!inRecipes.isEmpty()) { - openRecipePage(c.clicker(), e.gui(), inRecipes, 0, 0, canOpenNoRecipePage); + openRecipePage(c.clicker(), e.gui(), inRecipes, 0, depth + 1, canOpenNoRecipePage); } else if (canOpenNoRecipePage) { openNoRecipePage(player, e.item().id(), e.gui(), 0); } @@ -797,7 +797,7 @@ public class ItemBrowserManagerImpl implements ItemBrowserManager { if (inRecipes == recipes) return; player.playSound(Constants.SOUND_CLICK_BUTTON); if (!inRecipes.isEmpty()) { - openRecipePage(c.clicker(), e.gui(), inRecipes, 0, 0, canOpenNoRecipePage); + openRecipePage(c.clicker(), e.gui(), inRecipes, 0, depth + 1, canOpenNoRecipePage); } } })) @@ -891,7 +891,7 @@ public class ItemBrowserManagerImpl implements ItemBrowserManager { if (inRecipes == recipes) return; player.playSound(Constants.SOUND_CLICK_BUTTON); if (!inRecipes.isEmpty()) { - openRecipePage(c.clicker(), e.gui(), inRecipes, 0, 0, canOpenNoRecipePage); + openRecipePage(c.clicker(), e.gui(), inRecipes, 0, depth + 1, canOpenNoRecipePage); } else if (canOpenNoRecipePage) { openNoRecipePage(player, result, e.gui(), 0); } @@ -900,7 +900,7 @@ public class ItemBrowserManagerImpl implements ItemBrowserManager { if (inRecipes == recipes) return; player.playSound(Constants.SOUND_CLICK_BUTTON); if (!inRecipes.isEmpty()) { - openRecipePage(c.clicker(), e.gui(), inRecipes, 0, 0, canOpenNoRecipePage); + openRecipePage(c.clicker(), e.gui(), inRecipes, 0, depth + 1, canOpenNoRecipePage); } } })) @@ -983,7 +983,7 @@ public class ItemBrowserManagerImpl implements ItemBrowserManager { if (inRecipes == recipes) return; player.playSound(Constants.SOUND_CLICK_BUTTON); if (!inRecipes.isEmpty()) { - openRecipePage(c.clicker(), e.gui(), inRecipes, 0, 0, canOpenNoRecipePage); + openRecipePage(c.clicker(), e.gui(), inRecipes, 0, depth + 1, canOpenNoRecipePage); } else if (canOpenNoRecipePage) { openNoRecipePage(player, e.item().id(), e.gui(), 0); } @@ -992,7 +992,7 @@ public class ItemBrowserManagerImpl implements ItemBrowserManager { if (inRecipes == recipes) return; player.playSound(Constants.SOUND_CLICK_BUTTON); if (!inRecipes.isEmpty()) { - openRecipePage(c.clicker(), e.gui(), inRecipes, 0, 0, canOpenNoRecipePage); + openRecipePage(c.clicker(), e.gui(), inRecipes, 0, depth + 1, canOpenNoRecipePage); } } })); @@ -1026,7 +1026,7 @@ public class ItemBrowserManagerImpl implements ItemBrowserManager { if (inRecipes == recipes) return; player.playSound(Constants.SOUND_CLICK_BUTTON); if (!inRecipes.isEmpty()) { - openRecipePage(c.clicker(), e.gui(), inRecipes, 0, 0, canOpenNoRecipePage); + openRecipePage(c.clicker(), e.gui(), inRecipes, 0, depth + 1, canOpenNoRecipePage); } else if (canOpenNoRecipePage) { openNoRecipePage(player, e.item().id(), e.gui(), 0); } @@ -1035,7 +1035,7 @@ public class ItemBrowserManagerImpl implements ItemBrowserManager { if (inRecipes == recipes) return; player.playSound(Constants.SOUND_CLICK_BUTTON); if (!inRecipes.isEmpty()) { - openRecipePage(c.clicker(), e.gui(), inRecipes, 0, 0, canOpenNoRecipePage); + openRecipePage(c.clicker(), e.gui(), inRecipes, 0, depth + 1, canOpenNoRecipePage); } } })); diff --git a/core/src/main/java/net/momirealms/craftengine/core/plugin/network/NetWorkUser.java b/core/src/main/java/net/momirealms/craftengine/core/plugin/network/NetWorkUser.java index f2a8b8d2d..a88dd7c6a 100644 --- a/core/src/main/java/net/momirealms/craftengine/core/plugin/network/NetWorkUser.java +++ b/core/src/main/java/net/momirealms/craftengine/core/plugin/network/NetWorkUser.java @@ -51,4 +51,12 @@ public interface NetWorkUser { void setClientModState(boolean enable); void addResourcePackUUID(UUID uuid); + + ProtocolVersion protocolVersion(); + + void setProtocolVersion(int protocolVersion); + + boolean sentResourcePack(); + + void setSentResourcePack(boolean sentResourcePack); } diff --git a/core/src/main/java/net/momirealms/craftengine/core/plugin/network/NetworkManager.java b/core/src/main/java/net/momirealms/craftengine/core/plugin/network/NetworkManager.java index b6bbae960..facef471a 100644 --- a/core/src/main/java/net/momirealms/craftengine/core/plugin/network/NetworkManager.java +++ b/core/src/main/java/net/momirealms/craftengine/core/plugin/network/NetworkManager.java @@ -9,6 +9,7 @@ import java.util.List; public interface NetworkManager extends Manageable { String MOD_CHANNEL = "craftengine:payload"; + String VIA_CHANNEL = "vv:proxy_details"; void setUser(Channel channel, NetWorkUser user); diff --git a/core/src/main/java/net/momirealms/craftengine/core/plugin/network/ProtocolVersion.java b/core/src/main/java/net/momirealms/craftengine/core/plugin/network/ProtocolVersion.java new file mode 100644 index 000000000..c692c6da6 --- /dev/null +++ b/core/src/main/java/net/momirealms/craftengine/core/plugin/network/ProtocolVersion.java @@ -0,0 +1,52 @@ +package net.momirealms.craftengine.core.plugin.network; + +public enum ProtocolVersion { + UNKNOWN(-1, "Unknown"), + V1_20(763, "1.20"), + V1_20_1(763, "1.20.1"), + V1_20_2(764, "1.20.2"), + V1_20_3(765, "1.20.3"), + V1_20_4(765, "1.20.4"), + V1_20_5(766, "1.20.5"), + V1_20_6(766, "1.20.6"), + V1_21(767, "1.21"), + V1_21_1(767, "1.21.1"), + V1_21_2(768, "1.21.2"), + V1_21_3(768, "1.21.3"), + V1_21_4(769, "1.21.4"), + V1_21_5(770, "1.21.5"); + + private final int id; + private final String name; + + ProtocolVersion(int id, String name) { + this.id = id; + this.name = name; + } + + public int getId() { + return id; + } + + public String getName() { + return name; + } + + public static ProtocolVersion getByName(String name) { + for (ProtocolVersion version : values()) { + if (version.getName().equals(name)) { + return version; + } + } + return UNKNOWN; + } + + public static ProtocolVersion getById(int id) { + for (ProtocolVersion version : values()) { + if (version.getId() == id) { + return version; + } + } + return UNKNOWN; + } +} diff --git a/core/src/main/java/net/momirealms/craftengine/core/plugin/script/AbstractTokenStringReader.java b/core/src/main/java/net/momirealms/craftengine/core/plugin/script/AbstractTokenStringReader.java deleted file mode 100644 index 1f991efd7..000000000 --- a/core/src/main/java/net/momirealms/craftengine/core/plugin/script/AbstractTokenStringReader.java +++ /dev/null @@ -1,63 +0,0 @@ -package net.momirealms.craftengine.core.plugin.script; - -public abstract class AbstractTokenStringReader implements TokenStringReader { - protected final char[] chars; - protected int index; - - public AbstractTokenStringReader(char[] chars) { - this.chars = chars; - } - - @Override - public boolean hasNext() { - return this.index < this.chars.length; - } - - @Override - public int index() { - return this.index; - } - - @Override - public String nextToken() { - if (!hasNext()) { - throw new IndexOutOfBoundsException(); - } - int start = this.index; - int end = this.chars.length - 1; - while (this.index < this.chars.length && !Character.isWhitespace(this.chars[this.index])) { - end++; - } - String token = new String(this.chars, start, end - start); - this.index = end; - return token; - } - - @Override - public char peek() { - return this.chars[this.index]; - } - - @Override - public char peek(int n) { - return this.chars[this.index + n]; - } - - @Override - public void skip(int n) { - if (n < 0) { - throw new IllegalArgumentException("n < 0"); - } - if (index() + n >= this.chars.length) { - throw new IndexOutOfBoundsException("index(" + index() + ") + (" + n + ") > chars.length(" + this.chars.length + ")"); - } - this.index += n; - } - - @Override - public void skipWhitespace() { - while (this.index < this.chars.length && !Character.isWhitespace(this.chars[this.index])) { - this.index++; - } - } -} diff --git a/core/src/main/java/net/momirealms/craftengine/core/plugin/script/Action.java b/core/src/main/java/net/momirealms/craftengine/core/plugin/script/Action.java deleted file mode 100644 index 20573dd90..000000000 --- a/core/src/main/java/net/momirealms/craftengine/core/plugin/script/Action.java +++ /dev/null @@ -1,4 +0,0 @@ -package net.momirealms.craftengine.core.plugin.script; - -public interface Action { -} diff --git a/core/src/main/java/net/momirealms/craftengine/core/plugin/script/Block.java b/core/src/main/java/net/momirealms/craftengine/core/plugin/script/Block.java deleted file mode 100644 index 789c91123..000000000 --- a/core/src/main/java/net/momirealms/craftengine/core/plugin/script/Block.java +++ /dev/null @@ -1,72 +0,0 @@ -package net.momirealms.craftengine.core.plugin.script; - -import net.momirealms.craftengine.core.util.Key; - -public interface Block { - - int size(); - - Action[] actions(); - - Key id(); - - Action byIndex(int index); - - int indexOf(Action action); - - boolean contains(Action action); - - static Block create(Key id, Action... actions) { - return new BlockImpl(id, actions); - } - - class BlockImpl implements Block { - private final Key id; - private final Action[] actions; - - public BlockImpl(Key id, Action[] actions) { - this.actions = actions; - this.id = id; - } - - @Override - public int size() { - return actions.length; - } - - @Override - public Action[] actions() { - return this.actions; - } - - @Override - public Key id() { - return this.id; - } - - @Override - public boolean contains(Action action) { - for (Action value : this.actions) { - if (value.equals(action)) { - return true; - } - } - return false; - } - - @Override - public Action byIndex(int index) { - return this.actions[index]; - } - - @Override - public int indexOf(final Action action) { - for (int i = 0; i < this.actions.length; i++) { - if (this.actions[i].equals(action)) { - return i; - } - } - return -1; - } - } -} diff --git a/core/src/main/java/net/momirealms/craftengine/core/plugin/script/Task.java b/core/src/main/java/net/momirealms/craftengine/core/plugin/script/Task.java deleted file mode 100644 index 3924f2178..000000000 --- a/core/src/main/java/net/momirealms/craftengine/core/plugin/script/Task.java +++ /dev/null @@ -1,61 +0,0 @@ -package net.momirealms.craftengine.core.plugin.script; - -import net.momirealms.craftengine.core.util.Key; -import org.jetbrains.annotations.Nullable; - -import java.util.Collections; -import java.util.LinkedHashMap; -import java.util.Map; - -public interface Task { - - Map blocks(); - - Key id(); - - @Nullable - Block byId(Key id); - - @Nullable - Block byAction(Action action); - - static Task create(Key key, Map blocks) { - return new TaskImpl(key, blocks); - } - - class TaskImpl implements Task { - private final Key id; - private final Map blocks = new LinkedHashMap<>(); - - public TaskImpl(Key id, Map blocks) { - this.blocks.putAll(blocks); - this.id = id; - } - - @Nullable - @Override - public Block byId(Key id) { - return this.blocks.get(id); - } - - @Override - public Map blocks() { - return Collections.unmodifiableMap(this.blocks); - } - - @Override - public Key id() { - return this.id; - } - - @Override - public @Nullable Block byAction(Action action) { - for (Block block : blocks.values()) { - if (block.contains(action)) { - return block; - } - } - return null; - } - } -} diff --git a/core/src/main/java/net/momirealms/craftengine/core/plugin/script/TaskActionParser.java b/core/src/main/java/net/momirealms/craftengine/core/plugin/script/TaskActionParser.java deleted file mode 100644 index 3bf720e3a..000000000 --- a/core/src/main/java/net/momirealms/craftengine/core/plugin/script/TaskActionParser.java +++ /dev/null @@ -1,6 +0,0 @@ -package net.momirealms.craftengine.core.plugin.script; - -public interface TaskActionParser { - - Action parse(TokenStringReader reader); -} diff --git a/core/src/main/java/net/momirealms/craftengine/core/plugin/script/TaskActionParsers.java b/core/src/main/java/net/momirealms/craftengine/core/plugin/script/TaskActionParsers.java deleted file mode 100644 index d72978f04..000000000 --- a/core/src/main/java/net/momirealms/craftengine/core/plugin/script/TaskActionParsers.java +++ /dev/null @@ -1,4 +0,0 @@ -package net.momirealms.craftengine.core.plugin.script; - -public class TaskActionParsers { -} diff --git a/core/src/main/java/net/momirealms/craftengine/core/plugin/script/TaskContext.java b/core/src/main/java/net/momirealms/craftengine/core/plugin/script/TaskContext.java deleted file mode 100644 index 824568dec..000000000 --- a/core/src/main/java/net/momirealms/craftengine/core/plugin/script/TaskContext.java +++ /dev/null @@ -1,8 +0,0 @@ -package net.momirealms.craftengine.core.plugin.script; - -public interface TaskContext { - - Task task(); - - -} diff --git a/core/src/main/java/net/momirealms/craftengine/core/plugin/script/TokenStringReader.java b/core/src/main/java/net/momirealms/craftengine/core/plugin/script/TokenStringReader.java deleted file mode 100644 index e300dbc8a..000000000 --- a/core/src/main/java/net/momirealms/craftengine/core/plugin/script/TokenStringReader.java +++ /dev/null @@ -1,18 +0,0 @@ -package net.momirealms.craftengine.core.plugin.script; - -public interface TokenStringReader { - - char peek(); - - char peek(int n); - - void skip(int n); - - int index(); - - boolean hasNext(); - - String nextToken(); - - void skipWhitespace(); -} diff --git a/core/src/main/java/net/momirealms/craftengine/core/plugin/script/argument/ArgumentParser.java b/core/src/main/java/net/momirealms/craftengine/core/plugin/script/argument/ArgumentParser.java deleted file mode 100644 index 3965ec2a3..000000000 --- a/core/src/main/java/net/momirealms/craftengine/core/plugin/script/argument/ArgumentParser.java +++ /dev/null @@ -1,8 +0,0 @@ -package net.momirealms.craftengine.core.plugin.script.argument; - -import net.momirealms.craftengine.core.plugin.script.TokenStringReader; - -public interface ArgumentParser { - - T parse(TokenStringReader reader); -} diff --git a/core/src/main/java/net/momirealms/craftengine/core/plugin/script/argument/ArgumentParsers.java b/core/src/main/java/net/momirealms/craftengine/core/plugin/script/argument/ArgumentParsers.java deleted file mode 100644 index 63ceaeb10..000000000 --- a/core/src/main/java/net/momirealms/craftengine/core/plugin/script/argument/ArgumentParsers.java +++ /dev/null @@ -1,19 +0,0 @@ -package net.momirealms.craftengine.core.plugin.script.argument; - -public class ArgumentParsers { - public static final ArgumentParser INT_PARSER = new IntArgumentParser(); - public static final ArgumentParser LONG_PARSER = new LongArgumentParser(); - public static final ArgumentParser DOUBLE_PARSER = new DoubleArgumentParser(); - - public static ArgumentParser intParser() { - return INT_PARSER; - } - - public static ArgumentParser longParser() { - return LONG_PARSER; - } - - public static ArgumentParser doubleParser() { - return DOUBLE_PARSER; - } -} diff --git a/core/src/main/java/net/momirealms/craftengine/core/plugin/script/argument/DoubleArgumentParser.java b/core/src/main/java/net/momirealms/craftengine/core/plugin/script/argument/DoubleArgumentParser.java deleted file mode 100644 index 718e8cb8f..000000000 --- a/core/src/main/java/net/momirealms/craftengine/core/plugin/script/argument/DoubleArgumentParser.java +++ /dev/null @@ -1,12 +0,0 @@ -package net.momirealms.craftengine.core.plugin.script.argument; - -import net.momirealms.craftengine.core.plugin.script.TokenStringReader; - -public class DoubleArgumentParser implements ArgumentParser { - - @Override - public Double parse(TokenStringReader reader) { - String token = reader.nextToken(); - return Double.parseDouble(token); - } -} diff --git a/core/src/main/java/net/momirealms/craftengine/core/plugin/script/argument/IntArgumentParser.java b/core/src/main/java/net/momirealms/craftengine/core/plugin/script/argument/IntArgumentParser.java deleted file mode 100644 index fd2a5c635..000000000 --- a/core/src/main/java/net/momirealms/craftengine/core/plugin/script/argument/IntArgumentParser.java +++ /dev/null @@ -1,12 +0,0 @@ -package net.momirealms.craftengine.core.plugin.script.argument; - -import net.momirealms.craftengine.core.plugin.script.TokenStringReader; - -public class IntArgumentParser implements ArgumentParser { - - @Override - public Integer parse(TokenStringReader reader) { - String token = reader.nextToken(); - return Integer.parseInt(token); - } -} diff --git a/core/src/main/java/net/momirealms/craftengine/core/plugin/script/argument/LongArgumentParser.java b/core/src/main/java/net/momirealms/craftengine/core/plugin/script/argument/LongArgumentParser.java deleted file mode 100644 index b8c5b2355..000000000 --- a/core/src/main/java/net/momirealms/craftengine/core/plugin/script/argument/LongArgumentParser.java +++ /dev/null @@ -1,12 +0,0 @@ -package net.momirealms.craftengine.core.plugin.script.argument; - -import net.momirealms.craftengine.core.plugin.script.TokenStringReader; - -public class LongArgumentParser implements ArgumentParser { - - @Override - public Long parse(TokenStringReader reader) { - String token = reader.nextToken(); - return Long.parseLong(token); - } -} diff --git a/core/src/main/java/net/momirealms/craftengine/core/plugin/text/minimessage/PlaceholderTag.java b/core/src/main/java/net/momirealms/craftengine/core/plugin/text/minimessage/PlaceholderTag.java index 62eae2e39..59b331975 100644 --- a/core/src/main/java/net/momirealms/craftengine/core/plugin/text/minimessage/PlaceholderTag.java +++ b/core/src/main/java/net/momirealms/craftengine/core/plugin/text/minimessage/PlaceholderTag.java @@ -20,11 +20,11 @@ public class PlaceholderTag implements TagResolver { @Override public @Nullable Tag resolve(@NotNull String name, @NotNull ArgumentQueue arguments, @NotNull Context ctx) throws ParsingException { - if (!this.has(name) || !CraftEngine.instance().hasPlaceholderAPI()) { + if (!this.has(name) || !CraftEngine.instance().compatibilityManager().hasPlaceholderAPI()) { return null; } String placeholder = arguments.popOr("No argument placeholder provided").toString(); - String parsed = CraftEngine.instance().parse(player, "%" + placeholder + "%"); + String parsed = CraftEngine.instance().compatibilityManager().parse(player, "%" + placeholder + "%"); return Tag.inserting(AdventureHelper.miniMessage().deserialize(parsed)); } diff --git a/core/src/main/java/net/momirealms/craftengine/core/registry/BuiltInRegistries.java b/core/src/main/java/net/momirealms/craftengine/core/registry/BuiltInRegistries.java index e52b5ba0f..59d7b9711 100644 --- a/core/src/main/java/net/momirealms/craftengine/core/registry/BuiltInRegistries.java +++ b/core/src/main/java/net/momirealms/craftengine/core/registry/BuiltInRegistries.java @@ -22,7 +22,6 @@ import net.momirealms.craftengine.core.pack.model.select.SelectPropertyFactory; import net.momirealms.craftengine.core.pack.model.special.SpecialModelFactory; import net.momirealms.craftengine.core.pack.model.tint.TintFactory; import net.momirealms.craftengine.core.plugin.config.template.TemplateArgumentFactory; -import net.momirealms.craftengine.core.plugin.script.TaskActionParser; import net.momirealms.craftengine.core.util.Key; import net.momirealms.craftengine.core.util.ResourceKey; @@ -50,7 +49,6 @@ public class BuiltInRegistries { public static final Registry SMITHING_RESULT_PROCESSOR_FACTORY = createRegistry(Registries.SMITHING_RESULT_PROCESSOR_FACTORY); public static final Registry HITBOX_FACTORY = createRegistry(Registries.HITBOX_FACTORY); public static final Registry RESOURCE_PACK_HOST_FACTORY = createRegistry(Registries.RESOURCE_PACK_HOST_FACTORY); - public static final Registry TASK_ACTION_PARSER = createRegistry(Registries.TASK_ACTION_PARSER); private static Registry createRegistry(ResourceKey> key) { return new MappedRegistry<>(key); diff --git a/core/src/main/java/net/momirealms/craftengine/core/registry/Registries.java b/core/src/main/java/net/momirealms/craftengine/core/registry/Registries.java index febb757b8..07e1e4ef8 100644 --- a/core/src/main/java/net/momirealms/craftengine/core/registry/Registries.java +++ b/core/src/main/java/net/momirealms/craftengine/core/registry/Registries.java @@ -22,7 +22,6 @@ import net.momirealms.craftengine.core.pack.model.select.SelectPropertyFactory; import net.momirealms.craftengine.core.pack.model.special.SpecialModelFactory; import net.momirealms.craftengine.core.pack.model.tint.TintFactory; import net.momirealms.craftengine.core.plugin.config.template.TemplateArgumentFactory; -import net.momirealms.craftengine.core.plugin.script.TaskActionParser; import net.momirealms.craftengine.core.util.Key; import net.momirealms.craftengine.core.util.ResourceKey; @@ -51,5 +50,4 @@ public class Registries { public static final ResourceKey> SMITHING_RESULT_PROCESSOR_FACTORY = new ResourceKey<>(ROOT_REGISTRY, Key.withDefaultNamespace("smithing_result_processor_factory")); public static final ResourceKey> HITBOX_FACTORY = new ResourceKey<>(ROOT_REGISTRY, Key.withDefaultNamespace("hitbox_factory")); public static final ResourceKey> RESOURCE_PACK_HOST_FACTORY = new ResourceKey<>(ROOT_REGISTRY, Key.withDefaultNamespace("resource_pack_host_factory")); - public static final ResourceKey> TASK_ACTION_PARSER = new ResourceKey<>(ROOT_REGISTRY, Key.withDefaultNamespace("task_action_parser")); } diff --git a/core/src/main/java/net/momirealms/craftengine/core/sound/AbstractSoundManager.java b/core/src/main/java/net/momirealms/craftengine/core/sound/AbstractSoundManager.java index 939968c01..38ce5197e 100644 --- a/core/src/main/java/net/momirealms/craftengine/core/sound/AbstractSoundManager.java +++ b/core/src/main/java/net/momirealms/craftengine/core/sound/AbstractSoundManager.java @@ -47,7 +47,7 @@ public abstract class AbstractSoundManager implements SoundManager { @Override public void runDelayedSyncTasks() { - if (!VersionHelper.isVersionNewerThan1_21()) return; + if (!VersionHelper.isOrAbove1_21()) return; this.registerSongs(this.songs); } diff --git a/core/src/main/java/net/momirealms/craftengine/core/util/AdventureHelper.java b/core/src/main/java/net/momirealms/craftengine/core/util/AdventureHelper.java index 7d32c3fb6..1cfa6f2d4 100644 --- a/core/src/main/java/net/momirealms/craftengine/core/util/AdventureHelper.java +++ b/core/src/main/java/net/momirealms/craftengine/core/util/AdventureHelper.java @@ -30,7 +30,7 @@ public class AdventureHelper { this.miniMessageStrict = MiniMessage.builder().strict(true).build(); this.miniMessageCustom = MiniMessage.builder().tags(TagResolver.empty()).build(); GsonComponentSerializer.Builder builder = GsonComponentSerializer.builder(); - if (!VersionHelper.isVersionNewerThan1_20_5()) { + if (!VersionHelper.isOrAbove1_20_5()) { builder.legacyHoverEventSerializer(NBTLegacyHoverEventSerializer.get()); builder.editOptions((b) -> b.value(JSONOptions.EMIT_HOVER_SHOW_ENTITY_ID_AS_INT_ARRAY, false)); } diff --git a/core/src/main/java/net/momirealms/craftengine/core/util/DefaultStringReader.java b/core/src/main/java/net/momirealms/craftengine/core/util/DefaultStringReader.java new file mode 100644 index 000000000..f2c98db0c --- /dev/null +++ b/core/src/main/java/net/momirealms/craftengine/core/util/DefaultStringReader.java @@ -0,0 +1,314 @@ +package net.momirealms.craftengine.core.util; + +public class DefaultStringReader implements StringReader { + private static final char SYNTAX_ESCAPE = '\\'; + private static final char SYNTAX_DOUBLE_QUOTE = '"'; + private static final char SYNTAX_SINGLE_QUOTE = '\''; + private final String string; + private int cursor; + private int marker; + + public DefaultStringReader(DefaultStringReader other) { + this.string = other.string; + this.cursor = other.cursor; + this.marker = other.marker; + } + + public DefaultStringReader(String string) { + this.string = string; + } + + @Override + public int getMarker() { + return this.marker; + } + + @Override + public void setMarker(int marker) { + this.marker = marker; + } + + @Override + public void restore() { + this.cursor = this.marker; + } + + @Override + public String getString() { + return this.string; + } + + @Override + public void setCursor(int cursor) { + this.cursor = cursor; + } + + @Override + public int getRemainingLength() { + return this.string.length() - this.cursor; + } + + @Override + public int getTotalLength() { + return this.string.length(); + } + + @Override + public int getCursor() { + return this.cursor; + } + + @Override + public String getRead() { + return this.string.substring(0, this.cursor); + } + + @Override + public String getRemaining() { + return this.string.substring(this.cursor); + } + + @Override + public boolean canRead(int length) { + return this.cursor + length <= this.string.length(); + } + + @Override + public boolean canRead() { + return this.canRead(1); + } + + @Override + public char peek() { + return this.string.charAt(this.cursor); + } + + @Override + public char peek(int offset) { + return this.string.charAt(this.cursor + offset); + } + + @Override + public char read() { + if (!canRead()) { + throw new RuntimeException("No more characters to read."); + } + return this.string.charAt(this.cursor++); + } + + @Override + public void skip() { + if (!canRead()) { + throw new RuntimeException("No more characters to skip."); + } + ++this.cursor; + } + + @Override + public void skip(int count) { + if (!canRead()) { + throw new RuntimeException("No more characters to skip."); + } + this.cursor += count; + } + + public static boolean isAllowedNumber(char c) { + return c >= '0' && c <= '9' || c == '.' || c == '-'; + } + + public static boolean isQuotedStringStart(char c) { + return c == SYNTAX_DOUBLE_QUOTE || c == SYNTAX_SINGLE_QUOTE; + } + + @Override + public void skipWhitespace() { + while (this.canRead() && Character.isWhitespace(this.peek())) { + this.skip(); + } + } + + @Override + public void skipWhitespaceAndComment() { + while (this.canRead()) { + if (Character.isWhitespace(this.peek())) { + this.skip(); + } else if (this.peek() == '/' && this.canRead(1)) { + if (this.peek(1) == '/') { + this.skip(2); + while (this.canRead() && this.peek() != '\n' && this.peek() != '\r') { + this.skip(); + } + } else if (this.peek(1) == '*') { + this.skip(2); + while (this.canRead()) { + if (this.peek() == '*' && this.canRead(1) && this.peek(1) == '/') { + this.skip(2); + break; + } + this.skip(); + } + } else { + break; + } + } else { + break; + } + } + } + + @Override + public int readInt() { + int start = this.cursor; + while (this.canRead() && isAllowedNumber(this.peek())) { + this.skip(); + } + String number = this.string.substring(start, this.cursor); + if (number.isEmpty()) { + throw new RuntimeException("Expected integer, but found empty string."); + } + try { + return Integer.parseInt(number); + } catch (NumberFormatException e) { + this.cursor = start; + throw new RuntimeException("Failed to parse integer: " + number); + } + } + + @Override + public long readLong() { + int start = this.cursor; + while (this.canRead() && isAllowedNumber(this.peek())) { + this.skip(); + } + String number = this.string.substring(start, this.cursor); + if (number.isEmpty()) { + throw new RuntimeException("Expected long, but found empty string."); + } + try { + return Long.parseLong(number); + } catch (NumberFormatException e) { + this.cursor = start; + throw new RuntimeException("Failed to parse long: " + number); + } + } + + @Override + public double readDouble() { + int start = this.cursor; + while (this.canRead() && isAllowedNumber(this.peek())) { + this.skip(); + } + String number = this.string.substring(start, this.cursor); + if (number.isEmpty()) { + throw new RuntimeException("Expected double, but found empty string."); + } + try { + return Double.parseDouble(number); + } catch (NumberFormatException e) { + this.cursor = start; + throw new RuntimeException("Failed to parse double: " + number); + } + } + + @Override + public float readFloat() { + int start = this.cursor; + while (this.canRead() && isAllowedNumber(this.peek())) { + this.skip(); + } + String number = this.string.substring(start, this.cursor); + if (number.isEmpty()) { + throw new RuntimeException("Expected float, but found empty string."); + } + try { + return Float.parseFloat(number); + } catch (NumberFormatException e) { + this.cursor = start; + throw new RuntimeException("Failed to parse float: " + number); + } + } + + public static boolean isAllowedInUnquotedString(char c) { + return c >= '0' && c <= '9' || c >= 'A' && c <= 'Z' || c >= 'a' && c <= 'z' || c == '_' || c == '-' || c == '.' || c == '+'; + } + + @Override + public String readUnquotedString() { + int start = this.cursor; + while (this.canRead() && isAllowedInUnquotedString(this.peek())) { + this.skip(); + } + return this.string.substring(start, this.cursor); + } + + @Override + public String readQuotedString() { + if (!this.canRead()) { + return ""; + } else { + char next = this.peek(); + if (!isQuotedStringStart(next)) { + throw new RuntimeException("Expected quoted string, but found: " + next); + } else { + this.skip(); + return this.readStringUntil(next); + } + } + } + + public String readStringUntil(char terminator) { + StringBuilder result = new StringBuilder(); + boolean escaped = false; + + while (this.canRead()) { + char c = this.read(); + if (escaped) { + if (c != terminator && c != SYNTAX_ESCAPE) { + this.setCursor(this.getCursor() - 1); + throw new RuntimeException("Invalid escape sequence."); + } + result.append(c); + escaped = false; + } else if (c == SYNTAX_ESCAPE) { + escaped = true; + } else { + if (c == terminator) { + return result.toString(); + } + result.append(c); + } + } + throw new RuntimeException("Unexpected end of input while reading string."); + } + + @Override + public String readString() { + if (!this.canRead()) { + return ""; + } else { + char next = this.peek(); + if (isQuotedStringStart(next)) { + this.skip(); + return this.readStringUntil(next); + } else { + return this.readUnquotedString(); + } + } + } + + @Override + public boolean readBoolean() { + int start = this.cursor; + String value = this.readString(); + if (value.isEmpty()) { + throw new RuntimeException("Expected boolean, but found empty string."); + } else if (value.equals("true")) { + return true; + } else if (value.equals("false")) { + return false; + } else { + this.cursor = start; + throw new RuntimeException("Failed to parse boolean: " + value); + } + } +} 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 81ceb9719..5219bb4b4 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 @@ -101,6 +101,29 @@ public class FriendlyByteBuf extends ByteBuf { idList.forEach(this::writeVarInt); } + public List readByteArrayList() { + int listSize = this.readVarInt(); + List bytes = new ArrayList<>(); + for (int i = 0; i < listSize; ++i) { + bytes.add(this.readByteArray()); + } + return bytes; + } + + public List readByteArrayList(int maxSize) { + int listSize = this.readVarInt(); + List bytes = new ArrayList<>(); + for (int i = 0; i < listSize; ++i) { + bytes.add(this.readByteArray(maxSize)); + } + return bytes; + } + + public void writeByteArrayList(List bytes) { + this.writeVarInt(bytes.size()); + bytes.forEach(this::writeByteArray); + } + public > M readMap(IntFunction mapFactory, FriendlyByteBuf.Reader keyReader, FriendlyByteBuf.Reader valueReader) { int mapSize = this.readVarInt(); M map = mapFactory.apply(mapSize); diff --git a/core/src/main/java/net/momirealms/craftengine/core/util/Key.java b/core/src/main/java/net/momirealms/craftengine/core/util/Key.java index bd0a211bc..f536fa5ba 100644 --- a/core/src/main/java/net/momirealms/craftengine/core/util/Key.java +++ b/core/src/main/java/net/momirealms/craftengine/core/util/Key.java @@ -43,7 +43,8 @@ public record Key(String namespace, String value) { return false; } if (!(obj instanceof Key key)) return false; - return this.namespace.equals(key.namespace()) && this.value.equals(key.value()); + // 先比value命中率高 + return this.value.equals(key.value()) && this.namespace.equals(key.namespace()); } @Override diff --git a/core/src/main/java/net/momirealms/craftengine/core/util/MutableInt.java b/core/src/main/java/net/momirealms/craftengine/core/util/MutableInt.java new file mode 100644 index 000000000..425f374fa --- /dev/null +++ b/core/src/main/java/net/momirealms/craftengine/core/util/MutableInt.java @@ -0,0 +1,21 @@ +package net.momirealms.craftengine.core.util; + +public class MutableInt { + private int value; + + public MutableInt(int value) { + this.value = value; + } + + public int intValue() { + return value; + } + + public void set(int value) { + this.value = value; + } + + public void add(final int value) { + this.value += value; + } +} diff --git a/core/src/main/java/net/momirealms/craftengine/core/util/ProtocolVersionUtils.java b/core/src/main/java/net/momirealms/craftengine/core/util/ProtocolVersionUtils.java new file mode 100644 index 000000000..8372e1117 --- /dev/null +++ b/core/src/main/java/net/momirealms/craftengine/core/util/ProtocolVersionUtils.java @@ -0,0 +1,10 @@ +package net.momirealms.craftengine.core.util; + +import net.momirealms.craftengine.core.plugin.network.ProtocolVersion; + +public class ProtocolVersionUtils { + + public static boolean isVersionNewerThan(ProtocolVersion version, ProtocolVersion targetVersion) { + return version.getId() >= targetVersion.getId(); + } +} diff --git a/core/src/main/java/net/momirealms/craftengine/core/util/StringReader.java b/core/src/main/java/net/momirealms/craftengine/core/util/StringReader.java index 4fd76995f..2202bed2c 100644 --- a/core/src/main/java/net/momirealms/craftengine/core/util/StringReader.java +++ b/core/src/main/java/net/momirealms/craftengine/core/util/StringReader.java @@ -1,238 +1,62 @@ package net.momirealms.craftengine.core.util; -public class StringReader { - private static final char SYNTAX_ESCAPE = '\\'; - private static final char SYNTAX_DOUBLE_QUOTE = '"'; - private static final char SYNTAX_SINGLE_QUOTE = '\''; - private final String string; - private int cursor; +public interface StringReader { - public StringReader(StringReader other) { - this.string = other.string; - this.cursor = other.cursor; + static StringReader simple(String input) { + return new DefaultStringReader(input); } - public StringReader(String string) { - this.string = string; - } + int getMarker(); - public String getString() { - return this.string; - } + void setMarker(int marker); - public void setCursor(int cursor) { - this.cursor = cursor; - } + void restore(); - public int getRemainingLength() { - return this.string.length() - this.cursor; - } + String getString(); - public int getTotalLength() { - return this.string.length(); - } + void setCursor(int cursor); - public int getCursor() { - return this.cursor; - } + int getRemainingLength(); - public String getRead() { - return this.string.substring(0, this.cursor); - } + int getTotalLength(); - public String getRemaining() { - return this.string.substring(this.cursor); - } + int getCursor(); - public boolean canRead(int length) { - return this.cursor + length <= this.string.length(); - } + String getRead(); - public boolean canRead() { - return this.canRead(1); - } + String getRemaining(); - public char peek() { - return this.string.charAt(this.cursor); - } + boolean canRead(int length); - public char peek(int offset) { - return this.string.charAt(this.cursor + offset); - } + boolean canRead(); - public char read() { - if (!canRead()) { - throw new RuntimeException("No more characters to read."); - } - return this.string.charAt(this.cursor++); - } + char peek(); - public void skip() { - if (!canRead()) { - throw new RuntimeException("No more characters to skip."); - } - ++this.cursor; - } + char peek(int offset); - public static boolean isAllowedNumber(char c) { - return c >= '0' && c <= '9' || c == '.' || c == '-'; - } + char read(); - public static boolean isQuotedStringStart(char c) { - return c == SYNTAX_DOUBLE_QUOTE || c == SYNTAX_SINGLE_QUOTE; - } + void skip(); - public void skipWhitespace() { - while (this.canRead() && Character.isWhitespace(this.peek())) { - this.skip(); - } - } + void skip(int count); - public int readInt() { - int start = this.cursor; - while (this.canRead() && isAllowedNumber(this.peek())) { - this.skip(); - } - String number = this.string.substring(start, this.cursor); - if (number.isEmpty()) { - throw new RuntimeException("Expected integer, but found empty string."); - } - try { - return Integer.parseInt(number); - } catch (NumberFormatException var4) { - this.cursor = start; - throw new RuntimeException("Failed to parse integer: " + number); - } - } + void skipWhitespace(); - public long readLong() { - int start = this.cursor; - while (this.canRead() && isAllowedNumber(this.peek())) { - this.skip(); - } - String number = this.string.substring(start, this.cursor); - if (number.isEmpty()) { - throw new RuntimeException("Expected long, but found empty string."); - } - try { - return Long.parseLong(number); - } catch (NumberFormatException var4) { - this.cursor = start; - throw new RuntimeException("Failed to parse long: " + number); - } - } + void skipWhitespaceAndComment(); - public double readDouble() { - int start = this.cursor; - while (this.canRead() && isAllowedNumber(this.peek())) { - this.skip(); - } - String number = this.string.substring(start, this.cursor); - if (number.isEmpty()) { - throw new RuntimeException("Expected double, but found empty string."); - } - try { - return Double.parseDouble(number); - } catch (NumberFormatException var4) { - this.cursor = start; - throw new RuntimeException("Failed to parse double: " + number); - } - } + int readInt(); - public float readFloat() { - int start = this.cursor; - while (this.canRead() && isAllowedNumber(this.peek())) { - this.skip(); - } - String number = this.string.substring(start, this.cursor); - if (number.isEmpty()) { - throw new RuntimeException("Expected float, but found empty string."); - } - try { - return Float.parseFloat(number); - } catch (NumberFormatException var4) { - this.cursor = start; - throw new RuntimeException("Failed to parse float: " + number); - } - } + long readLong(); - public static boolean isAllowedInUnquotedString(char c) { - return c >= '0' && c <= '9' || c >= 'A' && c <= 'Z' || c >= 'a' && c <= 'z' || c == '_' || c == '-' || c == '.' || c == '+'; - } + double readDouble(); - public String readUnquotedString() { - int start = this.cursor; - while (this.canRead() && isAllowedInUnquotedString(this.peek())) { - this.skip(); - } - return this.string.substring(start, this.cursor); - } + float readFloat(); - public String readQuotedString() { - if (!this.canRead()) { - return ""; - } else { - char next = this.peek(); - if (!isQuotedStringStart(next)) { - throw new RuntimeException("Expected quoted string, but found: " + next); - } else { - this.skip(); - return this.readStringUntil(next); - } - } - } + String readUnquotedString(); - public String readStringUntil(char terminator) { - StringBuilder result = new StringBuilder(); - boolean escaped = false; + String readQuotedString(); - while (this.canRead()) { - char c = this.read(); - if (escaped) { - if (c != terminator && c != SYNTAX_ESCAPE) { - this.setCursor(this.getCursor() - 1); - throw new RuntimeException("Invalid escape sequence."); - } - result.append(c); - escaped = false; - } else if (c == SYNTAX_ESCAPE) { - escaped = true; - } else { - if (c == terminator) { - return result.toString(); - } - result.append(c); - } - } - throw new RuntimeException("Unexpected end of input while reading string."); - } + String readString(); - public String readString() { - if (!this.canRead()) { - return ""; - } else { - char next = this.peek(); - if (isQuotedStringStart(next)) { - this.skip(); - return this.readStringUntil(next); - } else { - return this.readUnquotedString(); - } - } - } - - public boolean readBoolean() { - int start = this.cursor; - String value = this.readString(); - if (value.isEmpty()) { - throw new RuntimeException("Expected boolean, but found empty string."); - } else if (value.equals("true")) { - return true; - } else if (value.equals("false")) { - return false; - } else { - this.cursor = start; - throw new RuntimeException("Failed to parse boolean: " + value); - } - } + boolean readBoolean(); } diff --git a/core/src/main/java/net/momirealms/craftengine/core/util/UUIDUtils.java b/core/src/main/java/net/momirealms/craftengine/core/util/UUIDUtils.java new file mode 100644 index 000000000..9d29dc019 --- /dev/null +++ b/core/src/main/java/net/momirealms/craftengine/core/util/UUIDUtils.java @@ -0,0 +1,9 @@ +package net.momirealms.craftengine.core.util; + +import java.util.UUID; + +public final class UUIDUtils { + public static final UUID EMPTY = new UUID(0, 0); + + private UUIDUtils() {} +} 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 926c6ca90..d9b5fb78f 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 @@ -1,46 +1,95 @@ package net.momirealms.craftengine.core.util; -public class VersionHelper { - private static float version; - private static boolean mojmap; - private static boolean folia; - private static boolean paper; +import java.lang.reflect.Field; - public static void init(String serverVersion) { - String[] split = serverVersion.split("\\."); - version = Float.parseFloat(split[1] + "." + (split.length == 3 ? split[2] : "0")); - checkMojMap(); - checkFolia(); - checkPaper(); +import static java.util.Objects.requireNonNull; + +public class VersionHelper { + private static final Class clazz$DetectedVersion = requireNonNull( + ReflectionUtils.getClazz("net.minecraft.DetectedVersion", "net.minecraft.MinecraftVersion")); + private static final Class clazz$WorldVersion = requireNonNull( + ReflectionUtils.getClazz("net.minecraft.WorldVersion")); + public static final Field field$DetectedVersion$BUILT_IN = requireNonNull( + ReflectionUtils.getDeclaredField(clazz$DetectedVersion, clazz$WorldVersion, 0)); + public static final Field field$DetectedVersion$name = requireNonNull( + ReflectionUtils.getDeclaredField(clazz$DetectedVersion, String.class, 1)); + + private static final float version; + private static final boolean mojmap; + private static final boolean folia; + private static final boolean paper; + + private static final boolean v1_20; + private static final boolean v1_20_1; + private static final boolean v1_20_2; + private static final boolean v1_20_3; + private static final boolean v1_20_4; + private static final boolean v1_20_5; + private static final boolean v1_20_6; + private static final boolean v1_21; + private static final boolean v1_21_1; + private static final boolean v1_21_2; + private static final boolean v1_21_3; + private static final boolean v1_21_4; + private static final boolean v1_21_5; + + static { + try { + Object detectedVersion = field$DetectedVersion$BUILT_IN.get(null); + String name = (String) field$DetectedVersion$name.get(detectedVersion); + String[] split = name.split("\\."); + version = Float.parseFloat(split[1] + "." + (split.length == 3 ? split[2] : "0")); + mojmap = checkMojMap(); + folia = checkFolia(); + paper = checkPaper(); + v1_20 = version >= 20f; + v1_20_1 = version >= 20.1f; + v1_20_2 = version >= 20.2f; + v1_20_3 = version >= 20.3f; + v1_20_4 = version >= 20.4f; + v1_20_5 = version >= 20.5f; + v1_20_6 = version >= 20.6f; + v1_21 = version >= 21f; + v1_21_1 = version >= 21.1f; + v1_21_2 = version >= 21.2f; + v1_21_3 = version >= 21.3f; + v1_21_4 = version >= 21.4f; + v1_21_5 = version >= 21.5f; + } catch (ReflectiveOperationException e) { + throw new RuntimeException(e); + } } public static float version() { return version; } - private static void checkMojMap() { + private static boolean checkMojMap() { // Check if the server is Mojmap try { - Class.forName("net.minecraft.network.protocol.game.ClientboundBossEventPacket"); - mojmap = true; + Class.forName("net.neoforged.art.internal.RenamerImpl"); + return true; } catch (ClassNotFoundException ignored) { } + return false; } - private static void checkFolia() { + private static boolean checkFolia() { try { Class.forName("io.papermc.paper.threadedregions.RegionizedServer"); - folia = true; + return true; } catch (ClassNotFoundException ignored) { } + return false; } - private static void checkPaper() { + private static boolean checkPaper() { try { Class.forName("io.papermc.paper.adventure.PaperAdventure"); - paper = true; + return true; } catch (ClassNotFoundException ignored) { } + return false; } public static boolean isFolia() { @@ -55,43 +104,55 @@ public class VersionHelper { return mojmap; } - public static boolean isVersionNewerThan1_20() { - return version >= 20f; + public static boolean isOrAbove1_20() { + return v1_20; } - public static boolean isVersionNewerThan1_20_2() { - return version >= 20.19f; + public static boolean isOrAbove1_20_1() { + return v1_20_1; } - public static boolean isVersionNewerThan1_20_3() { - return version >= 20.29f; + public static boolean isOrAbove1_20_2() { + return v1_20_2; } - public static boolean isVersionNewerThan1_20_4() { - return version >= 20.39f; + public static boolean isOrAbove1_20_3() { + return v1_20_3; } - public static boolean isVersionNewerThan1_20_5() { - return version >= 20.49f; + public static boolean isOrAbove1_20_4() { + return v1_20_4; } - public static boolean isVersionNewerThan1_21() { - return version >= 21f; + public static boolean isOrAbove1_20_5() { + return v1_20_5; } - public static boolean isVersionNewerThan1_21_2() { - return version >= 21.19f; + public static boolean isOrAbove1_20_6() { + return v1_20_6; } - public static boolean isVersionNewerThan1_21_3() { - return version >= 21.29f; + public static boolean isOrAbove1_21() { + return v1_21; } - public static boolean isVersionNewerThan1_21_4() { - return version >= 21.39f; + public static boolean isOrAbove1_21_1() { + return v1_21_1; } - public static boolean isVersionNewerThan1_21_5() { - return version >= 21.49f; + public static boolean isOrAbove1_21_2() { + return v1_21_2; + } + + public static boolean isOrAbove1_21_3() { + return v1_21_3; + } + + public static boolean isOrAbove1_21_4() { + return v1_21_4; + } + + public static boolean isOrAbove1_21_5() { + return v1_21_5; } } \ No newline at end of file diff --git a/core/src/main/java/net/momirealms/craftengine/core/util/context/ContextHolder.java b/core/src/main/java/net/momirealms/craftengine/core/util/context/ContextHolder.java index 1a259899d..7939014e9 100644 --- a/core/src/main/java/net/momirealms/craftengine/core/util/context/ContextHolder.java +++ b/core/src/main/java/net/momirealms/craftengine/core/util/context/ContextHolder.java @@ -1,7 +1,5 @@ package net.momirealms.craftengine.core.util.context; -import org.jetbrains.annotations.Contract; - import javax.annotation.Nullable; import java.util.HashMap; import java.util.Map; @@ -38,7 +36,6 @@ public class ContextHolder { @SuppressWarnings("unchecked") @Nullable - @Contract("_,!null->!null; _,_->_") public T getOrDefault(ContextKey parameter, @Nullable T defaultValue) { return (T) this.params.getOrDefault(parameter, defaultValue); } diff --git a/core/src/main/java/net/momirealms/craftengine/core/world/CEWorld.java b/core/src/main/java/net/momirealms/craftengine/core/world/CEWorld.java index 59a4978f3..6817fd512 100644 --- a/core/src/main/java/net/momirealms/craftengine/core/world/CEWorld.java +++ b/core/src/main/java/net/momirealms/craftengine/core/world/CEWorld.java @@ -2,11 +2,13 @@ package net.momirealms.craftengine.core.world; import it.unimi.dsi.fastutil.longs.Long2ObjectOpenHashMap; import net.momirealms.craftengine.core.block.ImmutableBlockState; +import net.momirealms.craftengine.core.plugin.CraftEngine; import net.momirealms.craftengine.core.world.chunk.CEChunk; import net.momirealms.craftengine.core.world.chunk.storage.StorageAdaptor; import net.momirealms.craftengine.core.world.chunk.storage.WorldDataStorage; import org.jetbrains.annotations.Nullable; +import java.io.IOException; import java.util.Collections; import java.util.HashSet; import java.util.Map; @@ -41,6 +43,19 @@ public abstract class CEWorld { this.lastChunkPos = ChunkPos.INVALID_CHUNK_POS; } + public void save() { + this.loadedChunkMapLock.readLock().lock(); + try { + for (Map.Entry entry : this.loadedChunkMap.entrySet()) { + worldDataStorage.writeChunkAt(new ChunkPos(entry.getKey()), entry.getValue(), true); + } + } catch (IOException e) { + CraftEngine.instance().logger().warn("Failed to save world chunks", e); + } finally { + this.loadedChunkMapLock.readLock().unlock(); + } + } + public World world() { return world; } @@ -77,16 +92,20 @@ public abstract class CEWorld { } @Nullable - public CEChunk getLoadedChunkImmediately(int x, int z) { - long longKey = ChunkPos.asLong(x, z); + public CEChunk getChunkAtIfLoaded(long chunkPos) { this.loadedChunkMapLock.readLock().lock(); try { - return this.loadedChunkMap.get(longKey); + return getChunkAtIfLoadedMainThread(chunkPos); } finally { this.loadedChunkMapLock.readLock().unlock(); } } + @Nullable + public CEChunk getChunkAtIfLoaded(int x, int z) { + return getChunkAtIfLoaded(ChunkPos.asLong(x, z)); + } + @Nullable public CEChunk getChunkAtIfLoadedMainThread(long chunkPos) { if (chunkPos == this.lastChunkPos) { @@ -105,12 +124,6 @@ public abstract class CEWorld { return getChunkAtIfLoadedMainThread(ChunkPos.asLong(x, z)); } - @Nullable - public CEChunk getChunkAtIfLoaded(int x, int z) { - long chunkPos = ChunkPos.asLong(x, z); - return this.getChunkAtIfLoadedMainThread(chunkPos); - } - public WorldHeight worldHeight() { return worldHeightAccessor; } diff --git a/core/src/main/java/net/momirealms/craftengine/core/world/chunk/CEChunk.java b/core/src/main/java/net/momirealms/craftengine/core/world/chunk/CEChunk.java index f1b573d61..41667fae2 100644 --- a/core/src/main/java/net/momirealms/craftengine/core/world/chunk/CEChunk.java +++ b/core/src/main/java/net/momirealms/craftengine/core/world/chunk/CEChunk.java @@ -44,6 +44,16 @@ public class CEChunk { this.fillEmptySection(); } + public boolean isEmpty() { + if (!this.entities.isEmpty()) return false; + for (CESection section : this.sections) { + if (section != null && !section.statesContainer().isEmpty()) { + return false; + } + } + return true; + } + private void fillEmptySection() { for (int i = 0; i < sections.length; ++i) { if (sections[i] == null) { diff --git a/core/src/main/java/net/momirealms/craftengine/core/world/chunk/CESection.java b/core/src/main/java/net/momirealms/craftengine/core/world/chunk/CESection.java index 676968ed2..92eb3dd3e 100644 --- a/core/src/main/java/net/momirealms/craftengine/core/world/chunk/CESection.java +++ b/core/src/main/java/net/momirealms/craftengine/core/world/chunk/CESection.java @@ -17,15 +17,15 @@ public class CESection { } public void setBlockState(BlockPos pos, ImmutableBlockState state) { - setBlockState(pos.x() & 15, pos.y() & 15, pos.z() & 15, state); + this.setBlockState(pos.x() & 15, pos.y() & 15, pos.z() & 15, state); } public void setBlockState(int x, int y, int z, ImmutableBlockState state) { - statesContainer.set((y << 4 | z) << 4 | x, state); + this.statesContainer.set((y << 4 | z) << 4 | x, state); } public void setBlockState(int index, ImmutableBlockState state) { - statesContainer.set(index, state); + this.statesContainer.set(index, state); } public ImmutableBlockState getBlockState(BlockPos pos) { diff --git a/core/src/main/java/net/momirealms/craftengine/core/world/chunk/PalettedContainer.java b/core/src/main/java/net/momirealms/craftengine/core/world/chunk/PalettedContainer.java index 06cee4328..3a6fb0e5f 100644 --- a/core/src/main/java/net/momirealms/craftengine/core/world/chunk/PalettedContainer.java +++ b/core/src/main/java/net/momirealms/craftengine/core/world/chunk/PalettedContainer.java @@ -23,9 +23,9 @@ import java.util.function.Predicate; import java.util.stream.LongStream; public class PalettedContainer implements PaletteResizeListener, ReadableContainer { - private static final BiConsumer RAW_DATA_WRITER = VersionHelper.isVersionNewerThan1_21_5() ? + private static final BiConsumer RAW_DATA_WRITER = VersionHelper.isOrAbove1_21_5() ? (FriendlyByteBuf::writeFixedSizeLongArray) : (FriendlyByteBuf::writeLongArray); - private static final BiConsumer RAW_DATA_READER = VersionHelper.isVersionNewerThan1_21_5() ? + private static final BiConsumer RAW_DATA_READER = VersionHelper.isOrAbove1_21_5() ? (FriendlyByteBuf::readFixedSizeLongArray) : (FriendlyByteBuf::readLongArray); private final PaletteResizeListener dummyListener = (newSize, added) -> 0; private final IndexedIterable idList; diff --git a/core/src/main/java/net/momirealms/craftengine/core/world/chunk/packet/BlockEntityData.java b/core/src/main/java/net/momirealms/craftengine/core/world/chunk/packet/BlockEntityData.java new file mode 100644 index 000000000..3b57e24b6 --- /dev/null +++ b/core/src/main/java/net/momirealms/craftengine/core/world/chunk/packet/BlockEntityData.java @@ -0,0 +1,5 @@ +package net.momirealms.craftengine.core.world.chunk.packet; + +import net.momirealms.sparrow.nbt.Tag; + +public record BlockEntityData(int packedXZ, short y, int type, Tag tag) {} diff --git a/core/src/main/java/net/momirealms/craftengine/core/world/chunk/serialization/ChunkSerializer.java b/core/src/main/java/net/momirealms/craftengine/core/world/chunk/serialization/DefaultChunkSerializer.java similarity index 90% rename from core/src/main/java/net/momirealms/craftengine/core/world/chunk/serialization/ChunkSerializer.java rename to core/src/main/java/net/momirealms/craftengine/core/world/chunk/serialization/DefaultChunkSerializer.java index 878c2ccaf..62dacbd48 100644 --- a/core/src/main/java/net/momirealms/craftengine/core/world/chunk/serialization/ChunkSerializer.java +++ b/core/src/main/java/net/momirealms/craftengine/core/world/chunk/serialization/DefaultChunkSerializer.java @@ -11,7 +11,7 @@ import org.jetbrains.annotations.Nullable; import java.util.List; -public class ChunkSerializer { +public class DefaultChunkSerializer { @Nullable public static CompoundTag serialize(@NotNull CEChunk chunk) { @@ -19,7 +19,7 @@ public class ChunkSerializer { CESection[] ceSections = chunk.sections(); for (CESection ceSection : ceSections) { if (ceSection != null) { - CompoundTag sectionNbt = SectionSerializer.serialize(ceSection); + CompoundTag sectionNbt = DefaultSectionSerializer.serialize(ceSection); if (sectionNbt != null) { sections.add(sectionNbt); } @@ -38,7 +38,7 @@ public class ChunkSerializer { CESection[] sectionArray = new CESection[world.worldHeight().getSectionsCount()]; for (int i = 0, size = sections.size(); i < size; ++i) { CompoundTag sectionTag = sections.getCompound(i); - CESection ceSection = SectionSerializer.deserialize(sectionTag); + CESection ceSection = DefaultSectionSerializer.deserialize(sectionTag); if (ceSection != null) { int sectionIndex = world.worldHeight().getSectionIndexFromSectionY(ceSection.sectionY()); if (sectionIndex >= 0 && sectionIndex < sectionArray.length) { diff --git a/core/src/main/java/net/momirealms/craftengine/core/world/chunk/serialization/SectionSerializer.java b/core/src/main/java/net/momirealms/craftengine/core/world/chunk/serialization/DefaultSectionSerializer.java similarity index 98% rename from core/src/main/java/net/momirealms/craftengine/core/world/chunk/serialization/SectionSerializer.java rename to core/src/main/java/net/momirealms/craftengine/core/world/chunk/serialization/DefaultSectionSerializer.java index dd93b67e5..2505618b3 100644 --- a/core/src/main/java/net/momirealms/craftengine/core/world/chunk/serialization/SectionSerializer.java +++ b/core/src/main/java/net/momirealms/craftengine/core/world/chunk/serialization/DefaultSectionSerializer.java @@ -24,7 +24,7 @@ import java.util.List; import java.util.Optional; import java.util.stream.LongStream; -public class SectionSerializer { +public class DefaultSectionSerializer { @Nullable public static CompoundTag serialize(@NotNull CESection section) { diff --git a/core/src/main/java/net/momirealms/craftengine/core/world/chunk/storage/DefaultRegionFileStorage.java b/core/src/main/java/net/momirealms/craftengine/core/world/chunk/storage/DefaultRegionFileStorage.java index 3881127f2..132bc699f 100644 --- a/core/src/main/java/net/momirealms/craftengine/core/world/chunk/storage/DefaultRegionFileStorage.java +++ b/core/src/main/java/net/momirealms/craftengine/core/world/chunk/storage/DefaultRegionFileStorage.java @@ -5,9 +5,13 @@ import it.unimi.dsi.fastutil.longs.LongLinkedOpenHashSet; import net.momirealms.craftengine.core.plugin.config.Config; import net.momirealms.craftengine.core.util.ExceptionCollector; import net.momirealms.craftengine.core.util.FileUtils; +import net.momirealms.craftengine.core.world.CEWorld; import net.momirealms.craftengine.core.world.ChunkPos; +import net.momirealms.craftengine.core.world.chunk.CEChunk; +import net.momirealms.craftengine.core.world.chunk.serialization.DefaultChunkSerializer; import net.momirealms.sparrow.nbt.CompoundTag; import net.momirealms.sparrow.nbt.NBT; +import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import java.io.DataInputStream; @@ -117,15 +121,14 @@ public class DefaultRegionFileStorage implements WorldDataStorage { } @Override - @Nullable - public CompoundTag readChunkTagAt(ChunkPos pos) throws IOException { + public @NotNull CEChunk readChunkAt(@NotNull CEWorld world, @NotNull ChunkPos pos) throws IOException { RegionFile regionFile = this.getRegionFile(pos, false, true); try { DataInputStream dataInputStream = regionFile.getChunkDataInputStream(pos); CompoundTag tag; try { if (dataInputStream == null) { - return null; + return new CEChunk(world, pos); } tag = NBT.readCompound(dataInputStream, false); } catch (Throwable t1) { @@ -137,14 +140,19 @@ public class DefaultRegionFileStorage implements WorldDataStorage { throw t1; } dataInputStream.close(); - return tag; + return DefaultChunkSerializer.deserialize(world, pos, tag); } finally { regionFile.fileLock.unlock(); } } @Override - public void writeChunkTagAt(ChunkPos pos, @Nullable CompoundTag nbt) throws IOException { + public void writeChunkAt(@NotNull ChunkPos pos, @NotNull CEChunk chunk, boolean immediately) throws IOException { + CompoundTag nbt = DefaultChunkSerializer.serialize(chunk); + writeChunkTagAt(pos, nbt); + } + + public void writeChunkTagAt(@NotNull ChunkPos pos, @Nullable CompoundTag nbt) throws IOException { RegionFile regionFile = this.getRegionFile(pos, nbt == null, true); try { if (nbt == null) { diff --git a/core/src/main/java/net/momirealms/craftengine/core/world/chunk/storage/DefaultStorageAdaptor.java b/core/src/main/java/net/momirealms/craftengine/core/world/chunk/storage/DefaultStorageAdaptor.java index 9de5d571c..401ed6880 100644 --- a/core/src/main/java/net/momirealms/craftengine/core/world/chunk/storage/DefaultStorageAdaptor.java +++ b/core/src/main/java/net/momirealms/craftengine/core/world/chunk/storage/DefaultStorageAdaptor.java @@ -1,5 +1,6 @@ package net.momirealms.craftengine.core.world.chunk.storage; +import net.momirealms.craftengine.core.plugin.config.Config; import net.momirealms.craftengine.core.world.CEWorld; import net.momirealms.craftengine.core.world.World; import org.jetbrains.annotations.NotNull; @@ -8,6 +9,10 @@ public class DefaultStorageAdaptor implements StorageAdaptor { @Override public @NotNull WorldDataStorage adapt(@NotNull World world) { - return new DefaultRegionFileStorage(world.directory().resolve(CEWorld.REGION_DIRECTORY)); + if (Config.delaySerialization() > 0) { + return new DelayedDefaultRegionFileStorage(world.directory().resolve(CEWorld.REGION_DIRECTORY), Config.delaySerialization()); + } else { + return new DefaultRegionFileStorage(world.directory().resolve(CEWorld.REGION_DIRECTORY)); + } } } diff --git a/core/src/main/java/net/momirealms/craftengine/core/world/chunk/storage/DelayedDefaultRegionFileStorage.java b/core/src/main/java/net/momirealms/craftengine/core/world/chunk/storage/DelayedDefaultRegionFileStorage.java new file mode 100644 index 000000000..04dceb3a0 --- /dev/null +++ b/core/src/main/java/net/momirealms/craftengine/core/world/chunk/storage/DelayedDefaultRegionFileStorage.java @@ -0,0 +1,76 @@ +package net.momirealms.craftengine.core.world.chunk.storage; + +import com.github.benmanes.caffeine.cache.Cache; +import com.github.benmanes.caffeine.cache.Caffeine; +import com.github.benmanes.caffeine.cache.RemovalCause; +import net.momirealms.craftengine.core.plugin.CraftEngine; +import net.momirealms.craftengine.core.world.CEWorld; +import net.momirealms.craftengine.core.world.ChunkPos; +import net.momirealms.craftengine.core.world.chunk.CEChunk; +import org.jetbrains.annotations.NotNull; + +import java.io.IOException; +import java.nio.file.Path; +import java.util.concurrent.TimeUnit; + +public class DelayedDefaultRegionFileStorage extends DefaultRegionFileStorage { + private final Cache chunkCache; + + public DelayedDefaultRegionFileStorage(Path directory, int time) { + super(directory); + this.chunkCache = Caffeine.newBuilder() + .expireAfterWrite(time, TimeUnit.SECONDS) + .removalListener((ChunkPos key, CEChunk value, RemovalCause cause) -> { + if (key == null || value == null) { + return; + } + if (cause == RemovalCause.EXPIRED || cause == RemovalCause.SIZE) { + try { + super.writeChunkAt(key, value, true); + } catch (IOException e) { + CraftEngine.instance().logger().warn("Failed to write chunk at " + key, e); + } + } + }) + .build(); + } + + @Override + public @NotNull CEChunk readChunkAt(@NotNull CEWorld world, @NotNull ChunkPos pos) throws IOException { + CEChunk chunk = this.chunkCache.asMap().remove(pos); + if (chunk != null) { + return chunk; + } + return super.readChunkAt(world, pos); + } + + @Override + public void writeChunkAt(@NotNull ChunkPos pos, @NotNull CEChunk chunk, boolean immediately) throws IOException { + if (immediately) { + super.writeChunkAt(pos, chunk, true); + return; + } + if (chunk.isEmpty()) { + super.writeChunkTagAt(pos, null); + return; + } + this.chunkCache.put(pos, chunk); + } + + @Override + public synchronized void close() throws IOException { + this.saveCache(); + super.close(); + } + + private void saveCache() { + try { + for (var chunk : this.chunkCache.asMap().entrySet()) { + super.writeChunkAt(chunk.getKey(), chunk.getValue(), true); + } + } catch (IOException e) { + CraftEngine.instance().logger().warn("Failed to save chunks", e); + } + this.chunkCache.invalidateAll(); + } +} \ No newline at end of file diff --git a/core/src/main/java/net/momirealms/craftengine/core/world/chunk/storage/WorldDataStorage.java b/core/src/main/java/net/momirealms/craftengine/core/world/chunk/storage/WorldDataStorage.java index a9e76effd..b3b4dd47d 100644 --- a/core/src/main/java/net/momirealms/craftengine/core/world/chunk/storage/WorldDataStorage.java +++ b/core/src/main/java/net/momirealms/craftengine/core/world/chunk/storage/WorldDataStorage.java @@ -1,17 +1,18 @@ package net.momirealms.craftengine.core.world.chunk.storage; +import net.momirealms.craftengine.core.world.CEWorld; import net.momirealms.craftengine.core.world.ChunkPos; -import net.momirealms.sparrow.nbt.CompoundTag; -import org.jetbrains.annotations.Nullable; +import net.momirealms.craftengine.core.world.chunk.CEChunk; +import org.jetbrains.annotations.NotNull; import java.io.IOException; public interface WorldDataStorage { - @Nullable - CompoundTag readChunkTagAt(ChunkPos pos) throws IOException; + @NotNull + CEChunk readChunkAt(@NotNull CEWorld world, @NotNull ChunkPos pos) throws IOException; - void writeChunkTagAt(ChunkPos pos, @Nullable CompoundTag nbt) throws IOException; + void writeChunkAt(@NotNull ChunkPos pos, @NotNull CEChunk chunk, boolean immediately) throws IOException; void flush() throws IOException; diff --git a/gradle.properties b/gradle.properties index 0a73fcf03..a38fd2bdd 100644 --- a/gradle.properties +++ b/gradle.properties @@ -2,12 +2,11 @@ org.gradle.jvmargs=-Xmx1G # Project settings # Rule: [major update].[feature update].[bug fix] -project_version=0.0.50 +project_version=0.0.51 config_version=30 lang_version=7 project_group=net.momirealms latest_supported_version=1.21.5 -latest_minecraft_version=1.21.5 # Supported languages supported_languages=en,zh_cn,zh_tw,es @@ -45,13 +44,13 @@ sparrow_util_version=0.39 fastutil_version=8.5.15 netty_version=4.1.119.Final joml_version=1.10.8 -datafixerupper_version=1.0.20 +datafixerupper_version=6.0.8 mojang_brigadier_version=1.0.18 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.61.7 +nms_helper_version=0.62 reactive_streams_version=1.0.4 amazon_awssdk_version=2.31.23 amazon_awssdk_eventstream_version=1.0.1 @@ -61,9 +60,10 @@ mixin_version=0.15.2+mixin.0.8.7 ignite_version=1.1.0 tiny_remapper_version=0.10.4 # Fabric Dependencies -fabric_version=0.119.2+1.21.4 -yarn_mappings=1.21.4+build.8 -loader_version=0.16.10 +latest_minecraft_version=1.21.5 +fabric_version=0.121.0+1.21.5 +yarn_mappings=1.21.5+build.1 +loader_version=0.16.13 modmenu_version=13.0.3 cloth_version=17.0.144 diff --git a/settings.gradle.kts b/settings.gradle.kts index d75ce83fd..19bcd7ced 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -4,6 +4,7 @@ include(":core") include(":bukkit") include(":bukkit:legacy") include(":bukkit:compatibility") +include(":bukkit:compatibility:legacy") include(":bukkit:loader") include(":server-mod:v1_20_1") include(":server-mod:v1_20_5") @@ -18,4 +19,4 @@ pluginManagement { maven("https://repo.papermc.io/repository/maven-public/") maven("https://maven.fabricmc.net/") } -} +} \ No newline at end of file