9
0
mirror of https://github.com/Xiao-MoMi/craft-engine.git synced 2026-01-04 15:41:38 +00:00

添加旧版本slimeworld支持

This commit is contained in:
XiaoMoMi
2025-04-25 03:25:47 +08:00
parent 338639c015
commit bee4ed2767
13 changed files with 317 additions and 23 deletions

View File

@@ -0,0 +1,30 @@
repositories {
mavenCentral()
maven("https://repo.papermc.io/repository/maven-public/")
maven("https://repo.rapture.pw/repository/maven-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<JavaCompile> {
options.encoding = "UTF-8"
options.release.set(21)
dependsOn(tasks.clean)
}

View File

@@ -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<String, SlimeWorld> 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);
}
}

View File

@@ -0,0 +1,81 @@
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.io.IOException;
import java.lang.ref.WeakReference;
import java.util.Optional;
public class LegacySlimeWorldDataStorage implements WorldDataStorage {
private final WeakReference<com.infernalsuite.aswm.api.world.SlimeWorld> 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<ByteArrayTag> 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<com.flowpowered.nbt.CompoundTag> 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() {
}
}

View File

@@ -68,6 +68,6 @@ public class SlimeWorldDataStorage implements WorldDataStorage {
}
@Override
public void close() throws IOException {
public void close() {
}
}