From 55265c093417cc5c215a2e8d99256a65c5bbd111 Mon Sep 17 00:00:00 2001 From: XiaoMoMi Date: Sun, 30 Mar 2025 05:10:08 +0800 Subject: [PATCH] code clean up --- .../api/action/builtin/ActionFakeItem.java | 1 - build.gradle.kts | 32 +-- compatibility-asp-r2/build.gradle.kts | 25 ++ .../adaptor/asp_r1/SlimeWorldAdaptorR1.java | 254 ++++++++++++++++++ .../itemsadder_r2/ItemsAdderListener.java | 3 +- .../itemsadder_r2/ItemsAdderProvider.java | 2 +- plugin/build.gradle.kts | 1 + .../bukkit/world/BukkitWorldManager.java | 30 ++- settings.gradle.kts | 1 + 9 files changed, 307 insertions(+), 42 deletions(-) create mode 100644 compatibility-asp-r2/build.gradle.kts create mode 100644 compatibility-asp-r2/src/main/java/net/momirealms/customcrops/bukkit/integration/adaptor/asp_r1/SlimeWorldAdaptorR1.java diff --git a/api/src/main/java/net/momirealms/customcrops/api/action/builtin/ActionFakeItem.java b/api/src/main/java/net/momirealms/customcrops/api/action/builtin/ActionFakeItem.java index edf9233..88bbc4b 100644 --- a/api/src/main/java/net/momirealms/customcrops/api/action/builtin/ActionFakeItem.java +++ b/api/src/main/java/net/momirealms/customcrops/api/action/builtin/ActionFakeItem.java @@ -24,7 +24,6 @@ import net.momirealms.customcrops.api.context.ContextKeys; import net.momirealms.customcrops.api.core.ConfigManager; import net.momirealms.customcrops.api.misc.value.MathValue; import net.momirealms.customcrops.api.util.LocationUtils; -import net.momirealms.customcrops.api.util.PluginUtils; import net.momirealms.customcrops.common.helper.VersionHelper; import net.momirealms.sparrow.heart.SparrowHeart; import net.momirealms.sparrow.heart.feature.entity.FakeEntity; diff --git a/build.gradle.kts b/build.gradle.kts index cd1bbb8..920ad44 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -3,7 +3,7 @@ import java.io.ByteArrayOutputStream plugins { id("java") - id("com.gradleup.shadow") version "9.0.0-beta6" + id("com.gradleup.shadow") version "9.0.0-beta11" } val git : String = versionBanner() @@ -31,28 +31,10 @@ subprojects { } } -fun versionBanner(): String { - val os = ByteArrayOutputStream() - try { - project.exec { - commandLine = "git rev-parse --short=8 HEAD".split(" ") - standardOutput = os - } - } catch (e: ExecException) { - return "Unknown" - } - return String(os.toByteArray()).trim() -} +fun versionBanner() = project.providers.exec { + commandLine("git", "rev-parse", "--short=8", "HEAD") +}.standardOutput.asText.map { it.trim() }.getOrElse("Unknown") -fun builder(): String { - val os = ByteArrayOutputStream() - try { - project.exec { - commandLine = "git config user.name".split(" ") - standardOutput = os - } - } catch (e: ExecException) { - return "Unknown" - } - return String(os.toByteArray()).trim() -} \ No newline at end of file +fun builder() = project.providers.exec { + commandLine("git", "config", "user.name") +}.standardOutput.asText.map { it.trim() }.getOrElse("Unknown") \ No newline at end of file diff --git a/compatibility-asp-r2/build.gradle.kts b/compatibility-asp-r2/build.gradle.kts new file mode 100644 index 0000000..ea63323 --- /dev/null +++ b/compatibility-asp-r2/build.gradle.kts @@ -0,0 +1,25 @@ +repositories { + mavenCentral() + maven("https://repo.rapture.pw/repository/maven-releases/") // slime world + maven("https://repo.infernalsuite.com/repository/maven-snapshots/") + maven("https://repo.papermc.io/repository/maven-public/") +} + +dependencies { + compileOnly(project(":api")) + compileOnly("com.infernalsuite.asp:api:4.0.0-SNAPSHOT") +} + +java { + sourceCompatibility = JavaVersion.VERSION_21 + targetCompatibility = JavaVersion.VERSION_21 + toolchain { + languageVersion = JavaLanguageVersion.of(21) + } +} + +tasks.withType { + options.encoding = "UTF-8" + options.release.set(21) + dependsOn(tasks.clean) +} \ No newline at end of file diff --git a/compatibility-asp-r2/src/main/java/net/momirealms/customcrops/bukkit/integration/adaptor/asp_r1/SlimeWorldAdaptorR1.java b/compatibility-asp-r2/src/main/java/net/momirealms/customcrops/bukkit/integration/adaptor/asp_r1/SlimeWorldAdaptorR1.java new file mode 100644 index 0000000..21f622d --- /dev/null +++ b/compatibility-asp-r2/src/main/java/net/momirealms/customcrops/bukkit/integration/adaptor/asp_r1/SlimeWorldAdaptorR1.java @@ -0,0 +1,254 @@ +/* + * Copyright (C) <2024> + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package net.momirealms.customcrops.bukkit.integration.adaptor.asp_r1; + +import com.infernalsuite.aswm.api.events.LoadSlimeWorldEvent; +import com.infernalsuite.aswm.api.world.SlimeWorld; +import net.momirealms.customcrops.api.BukkitCustomCropsPlugin; +import net.momirealms.customcrops.api.core.InternalRegistries; +import net.momirealms.customcrops.api.core.block.CustomCropsBlock; +import net.momirealms.customcrops.api.core.world.*; +import net.momirealms.customcrops.api.core.world.adaptor.AbstractWorldAdaptor; +import net.momirealms.customcrops.api.util.StringUtils; +import net.momirealms.customcrops.api.util.TagUtils; +import net.momirealms.customcrops.common.helper.GsonHelper; +import net.momirealms.customcrops.common.util.Key; +import org.bukkit.Bukkit; +import org.bukkit.World; +import org.bukkit.event.EventHandler; +import org.bukkit.event.Listener; +import org.bukkit.plugin.Plugin; +import org.jetbrains.annotations.Nullable; + +import java.lang.reflect.Method; +import java.util.HashSet; +import java.util.Map; +import java.util.Optional; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.PriorityBlockingQueue; +import java.util.function.Function; + +public class SlimeWorldAdaptorR1 extends AbstractWorldAdaptor implements Listener { + + private final Function getSlimeWorldFunction; + + public SlimeWorldAdaptorR1(int version) { + 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.getSlimeWorldFunction = (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.getSlimeWorldFunction = (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); + } + } + + @EventHandler + public void onWorldLoad(LoadSlimeWorldEvent event) { + World world = Bukkit.getWorld(event.getSlimeWorld().getName()); + if (!BukkitCustomCropsPlugin.getInstance().getWorldManager().isMechanicEnabled(world)) return; + BukkitCustomCropsPlugin.getInstance().getWorldManager().loadWorld(adapt(event.getSlimeWorld())); + } + + @Override + public CustomCropsWorld adapt(Object world) { + return CustomCropsWorld.create((SlimeWorld) world, this); + } + + @Override + public SlimeWorld getWorld(String worldName) { + return getSlimeWorldFunction.apply(worldName); + } + + private CompoundMap createOrGetDataMap(SlimeWorld world) { + Optional optionalCompoundTag = world.getExtraData().getAsCompoundTag("customcrops"); + CompoundMap ccDataMap; + if (optionalCompoundTag.isEmpty()) { + ccDataMap = new CompoundMap(); + world.getExtraData().getValue().put(new CompoundTag("customcrops", ccDataMap)); + } else { + ccDataMap = optionalCompoundTag.get().getValue(); + } + return ccDataMap; + } + + @Override + public WorldExtraData loadExtraData(SlimeWorld world) { + CompoundMap ccDataMap = createOrGetDataMap(world); + String json = Optional.ofNullable(ccDataMap.get("world-info")).map(tag -> tag.getAsStringTag().get().getValue()).orElse(null); + return (json == null || json.equals("null")) ? WorldExtraData.empty() : GsonHelper.get().fromJson(json, WorldExtraData.class); + } + + @Override + public void saveExtraData(CustomCropsWorld world) { + CompoundMap ccDataMap = createOrGetDataMap(world.world()); + ccDataMap.put(new StringTag("world-info", GsonHelper.get().toJson(world.extraData()))); + } + + @Nullable + @Override + public CustomCropsRegion loadRegion(CustomCropsWorld world, RegionPos pos, boolean createIfNotExists) { + return null; + } + + @Nullable + @Override + public CustomCropsChunk loadChunk(CustomCropsWorld world, ChunkPos pos, boolean createIfNotExists) { + long time1 = System.currentTimeMillis(); + CompoundMap ccDataMap = createOrGetDataMap(world.world()); + Tag chunkTag = ccDataMap.get(pos.asString()); + if (chunkTag == null) { + return createIfNotExists ? world.createChunk(pos) : null; + } + Optional chunkCompoundTag = chunkTag.getAsCompoundTag(); + if (chunkCompoundTag.isEmpty()) { + return createIfNotExists ? world.createChunk(pos) : null; + } + CustomCropsChunk chunk = tagToChunk(world, chunkCompoundTag.get()); + long time2 = System.currentTimeMillis(); + BukkitCustomCropsPlugin.getInstance().debug(() -> "Took " + (time2-time1) + "ms to load chunk " + pos); + return chunk; + } + + @Override + public void saveRegion(CustomCropsWorld world, CustomCropsRegion region) {} + + @Override + public void saveChunk(CustomCropsWorld world, CustomCropsChunk chunk) { + CompoundMap ccDataMap = createOrGetDataMap(world.world()); + SerializableChunk serializableChunk = toSerializableChunk(chunk); + Runnable runnable = () -> { + if (serializableChunk.canPrune()) { + ccDataMap.remove(chunk.chunkPos().asString()); + } else { + ccDataMap.put(chunkToTag(serializableChunk)); + } + }; + if (Bukkit.isPrimaryThread()) { + runnable.run(); + } else { + BukkitCustomCropsPlugin.getInstance().getScheduler().sync().run(runnable, null); + } + } + + @Override + public String getName(SlimeWorld world) { + return world.getName(); + } + + @Override + public int priority() { + return SLIME_WORLD_PRIORITY; + } + + private CompoundTag chunkToTag(SerializableChunk serializableChunk) { + CompoundMap map = new CompoundMap(); + map.put(new IntTag("x", serializableChunk.x())); + map.put(new IntTag("z", serializableChunk.z())); + map.put(new IntTag("version", CHUNK_VERSION)); + map.put(new IntTag("loadedSeconds", serializableChunk.loadedSeconds())); + map.put(new LongTag("lastLoadedTime", serializableChunk.lastLoadedTime())); + map.put(new IntArrayTag("queued", serializableChunk.queuedTasks())); + map.put(new IntArrayTag("ticked", serializableChunk.ticked())); + CompoundMap sectionMap = new CompoundMap(); + for (SerializableSection section : serializableChunk.sections()) { + sectionMap.put(new ListTag<>(String.valueOf(section.sectionID()), TagType.TAG_COMPOUND, section.blocks())); + } + map.put(new CompoundTag("sections", sectionMap)); + return new CompoundTag(serializableChunk.x() + "," + serializableChunk.z(), map); + } + + @SuppressWarnings("all") + private CustomCropsChunk tagToChunk(CustomCropsWorld world, CompoundTag tag) { + CompoundMap map = tag.getValue(); + IntTag version = (IntTag) map.getOrDefault("version", new IntTag("version", 1)); + int versionNumber = version.getValue(); + Function keyFunction = versionNumber < 2 ? + (s) -> { + return Key.key("customcrops", StringUtils.toLowerCase(s)); + } : s -> { + return Key.key(s); + }; + int x = (int) map.get("x").getValue(); + int z = (int) map.get("z").getValue(); + + ChunkPos coordinate = new ChunkPos(x, z); + int loadedSeconds = (int) map.get("loadedSeconds").getValue(); + long lastLoadedTime = (long) map.get("lastLoadedTime").getValue(); + int[] queued = (int[]) map.get("queued").getValue(); + int[] ticked = (int[]) map.get("ticked").getValue(); + + PriorityBlockingQueue queue = new PriorityBlockingQueue<>(Math.max(11, queued.length / 2)); + for (int i = 0, size = queued.length / 2; i < size; i++) { + BlockPos pos = new BlockPos(queued[2*i+1]); + queue.add(new DelayedTickTask(queued[2*i], pos)); + } + + HashSet tickedSet = new HashSet<>(Math.max(11, ticked.length)); + for (int tick : ticked) { + tickedSet.add(new BlockPos(tick)); + } + + ConcurrentHashMap sectionMap = new ConcurrentHashMap<>(); + CompoundMap sectionCompoundMap = (CompoundMap) map.get("sections").getValue(); + for (Map.Entry> entry : sectionCompoundMap.entrySet()) { + if (entry.getValue() instanceof ListTag listTag) { + int id = Integer.parseInt(entry.getKey()); + ConcurrentHashMap blockMap = new ConcurrentHashMap<>(); + ListTag blocks = (ListTag) listTag; + for (CompoundTag blockTag : blocks.getValue()) { + CompoundMap block = blockTag.getValue(); + CompoundMap data = (CompoundMap) block.get("data").getValue(); + Key key = keyFunction.apply((String) block.get("type").getValue()); + CustomCropsBlock customBlock = InternalRegistries.BLOCK.get(key); + if (customBlock == null) { + BukkitCustomCropsPlugin.getInstance().getInstance().getPluginLogger().warn("[" + world.worldName() + "] Unrecognized custom block " + key + " has been removed from chunk " + ChunkPos.of(x, z)); + continue; + } + for (int pos : (int[]) block.get("pos").getValue()) { + BlockPos blockPos = new BlockPos(pos); + blockMap.put(blockPos, CustomCropsBlockState.create(customBlock, TagUtils.deepClone(data))); + } + } + sectionMap.put(id, CustomCropsSection.restore(id, blockMap)); + } + } + return world.restoreChunk(coordinate, loadedSeconds, lastLoadedTime, sectionMap, queue, tickedSet); + } +} diff --git a/compatibility-itemsadder-r2/src/main/java/net/momirealms/customcrops/bukkit/integration/custom/itemsadder_r2/ItemsAdderListener.java b/compatibility-itemsadder-r2/src/main/java/net/momirealms/customcrops/bukkit/integration/custom/itemsadder_r2/ItemsAdderListener.java index 15b20b9..54a11ff 100644 --- a/compatibility-itemsadder-r2/src/main/java/net/momirealms/customcrops/bukkit/integration/custom/itemsadder_r2/ItemsAdderListener.java +++ b/compatibility-itemsadder-r2/src/main/java/net/momirealms/customcrops/bukkit/integration/custom/itemsadder_r2/ItemsAdderListener.java @@ -15,12 +15,11 @@ * along with this program. If not, see . */ -package net.momirealms.customcrops.bukkit.integration.custom.itemsadder_r1; +package net.momirealms.customcrops.bukkit.integration.custom.itemsadder_r2; import dev.lone.itemsadder.api.Events.*; import net.momirealms.customcrops.api.core.AbstractCustomEventListener; import net.momirealms.customcrops.api.core.AbstractItemManager; -import net.momirealms.customcrops.api.util.DummyCancellable; import org.bukkit.Material; import org.bukkit.entity.Player; import org.bukkit.event.EventHandler; diff --git a/compatibility-itemsadder-r2/src/main/java/net/momirealms/customcrops/bukkit/integration/custom/itemsadder_r2/ItemsAdderProvider.java b/compatibility-itemsadder-r2/src/main/java/net/momirealms/customcrops/bukkit/integration/custom/itemsadder_r2/ItemsAdderProvider.java index 89682dd..5f33f47 100644 --- a/compatibility-itemsadder-r2/src/main/java/net/momirealms/customcrops/bukkit/integration/custom/itemsadder_r2/ItemsAdderProvider.java +++ b/compatibility-itemsadder-r2/src/main/java/net/momirealms/customcrops/bukkit/integration/custom/itemsadder_r2/ItemsAdderProvider.java @@ -15,7 +15,7 @@ * along with this program. If not, see . */ -package net.momirealms.customcrops.bukkit.integration.custom.itemsadder_r1; +package net.momirealms.customcrops.bukkit.integration.custom.itemsadder_r2; import dev.lone.itemsadder.api.CustomBlock; import dev.lone.itemsadder.api.CustomFurniture; diff --git a/plugin/build.gradle.kts b/plugin/build.gradle.kts index 6c81fac..6581a80 100644 --- a/plugin/build.gradle.kts +++ b/plugin/build.gradle.kts @@ -17,6 +17,7 @@ dependencies { } implementation(project(":compatibility")) implementation(project(":compatibility-asp-r1")) +// implementation(project(":compatibility-asp-r2")) implementation("net.kyori:adventure-api:${rootProject.properties["adventure_bundle_version"]}") implementation("net.kyori:adventure-text-minimessage:${rootProject.properties["adventure_bundle_version"]}") diff --git a/plugin/src/main/java/net/momirealms/customcrops/bukkit/world/BukkitWorldManager.java b/plugin/src/main/java/net/momirealms/customcrops/bukkit/world/BukkitWorldManager.java index 7790241..7ab124a 100644 --- a/plugin/src/main/java/net/momirealms/customcrops/bukkit/world/BukkitWorldManager.java +++ b/plugin/src/main/java/net/momirealms/customcrops/bukkit/world/BukkitWorldManager.java @@ -28,6 +28,7 @@ import net.momirealms.customcrops.api.integration.SeasonProvider; import net.momirealms.customcrops.bukkit.config.BukkitConfigManager; import net.momirealms.customcrops.bukkit.integration.adaptor.BukkitWorldAdaptor; import net.momirealms.customcrops.bukkit.integration.adaptor.asp_r1.SlimeWorldAdaptorR1; +import net.momirealms.customcrops.common.helper.VersionHelper; import org.bukkit.Bukkit; import org.bukkit.Chunk; import org.bukkit.World; @@ -53,19 +54,22 @@ public class BukkitWorldManager implements WorldManager, Listener { public BukkitWorldManager(BukkitCustomCropsPlugin plugin) { this.plugin = plugin; - try { - Class.forName("com.infernalsuite.aswm.api.SlimePlugin"); - SlimeWorldAdaptorR1 adaptor = new SlimeWorldAdaptorR1(1); - adaptors.add(adaptor); - Bukkit.getPluginManager().registerEvents(adaptor, plugin.getBootstrap()); - plugin.getPluginLogger().info("SlimeWorldManager hooked!"); - } catch (ClassNotFoundException ignored) { - } - if (Bukkit.getPluginManager().isPluginEnabled("SlimeWorldPlugin")) { - SlimeWorldAdaptorR1 adaptor = new SlimeWorldAdaptorR1(2); - adaptors.add(adaptor); - Bukkit.getPluginManager().registerEvents(adaptor, plugin.getBootstrap()); - plugin.getPluginLogger().info("AdvancedSlimePaper hooked!"); + // asp uses adventure nbt since 1.21.4 + if (!VersionHelper.isVersionNewerThan1_21_4()) { + try { + Class.forName("com.infernalsuite.aswm.api.SlimePlugin"); + SlimeWorldAdaptorR1 adaptor = new SlimeWorldAdaptorR1(1); + adaptors.add(adaptor); + Bukkit.getPluginManager().registerEvents(adaptor, plugin.getBootstrap()); + plugin.getPluginLogger().info("SlimeWorldManager hooked!"); + } catch (ClassNotFoundException ignored) { + } + if (Bukkit.getPluginManager().isPluginEnabled("SlimeWorldPlugin")) { + SlimeWorldAdaptorR1 adaptor = new SlimeWorldAdaptorR1(2); + adaptors.add(adaptor); + Bukkit.getPluginManager().registerEvents(adaptor, plugin.getBootstrap()); + plugin.getPluginLogger().info("AdvancedSlimePaper hooked!"); + } } this.adaptors.add(new BukkitWorldAdaptor()); this.seasonProvider = new SeasonProvider() { diff --git a/settings.gradle.kts b/settings.gradle.kts index cdd0ee9..fcbbcd5 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -3,6 +3,7 @@ include(":api") include(":plugin") include(":compatibility") include(":compatibility-asp-r1") +//include(":compatibility-asp-r2") include(":compatibility-oraxen-r1") include(":compatibility-oraxen-r2") include(":compatibility-nexo-r1")