From 14867a4b6d0e98f81af7ef373515b9066dcf563e Mon Sep 17 00:00:00 2001 From: NorbiPeti Date: Sat, 5 Sep 2020 23:19:54 +0200 Subject: [PATCH] Attempts at loading a custom dimension Including even patching the server --- .gitignore | 3 + pom.xml | 38 ++++ .../customdimensions/CustomDimensions.java | 179 ++++++++++++++++++ src/main/resources/plugin.yml | 5 + 4 files changed, 225 insertions(+) create mode 100644 .gitignore create mode 100644 pom.xml create mode 100644 src/main/java/buttondevteam/customdimensions/CustomDimensions.java create mode 100644 src/main/resources/plugin.yml diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..565e9b9 --- /dev/null +++ b/.gitignore @@ -0,0 +1,3 @@ +/target/ +/CustomDimensions.iml +/.idea/ diff --git a/pom.xml b/pom.xml new file mode 100644 index 0000000..c0b1bd3 --- /dev/null +++ b/pom.xml @@ -0,0 +1,38 @@ + + + 4.0.0 + + com.github.TBMCPlugins + CustomDimensions + 1.0-SNAPSHOT + + + + org.apache.maven.plugins + maven-compiler-plugin + + 10 + 10 + + + + + + + + spigot-repo + https://hub.spigotmc.org/nexus/content/repositories/snapshots/ + + + + + + org.spigotmc + spigot + 1.16.2-R0.1-SNAPSHOT + + + + \ No newline at end of file diff --git a/src/main/java/buttondevteam/customdimensions/CustomDimensions.java b/src/main/java/buttondevteam/customdimensions/CustomDimensions.java new file mode 100644 index 0000000..3151326 --- /dev/null +++ b/src/main/java/buttondevteam/customdimensions/CustomDimensions.java @@ -0,0 +1,179 @@ +package buttondevteam.customdimensions; + +import com.google.common.collect.ImmutableList; +import net.minecraft.server.v1_16_R2.*; +import org.bukkit.Bukkit; +import org.bukkit.command.CommandSender; +import org.bukkit.craftbukkit.v1_16_R2.CraftServer; +import org.bukkit.craftbukkit.v1_16_R2.CraftWorld; +import org.bukkit.craftbukkit.v1_16_R2.SpigotTimings; +import org.bukkit.event.EventHandler; +import org.bukkit.event.Listener; +import org.bukkit.event.world.WorldLoadEvent; +import org.bukkit.plugin.java.JavaPlugin; +import org.objenesis.Objenesis; +import org.objenesis.ObjenesisStd; +import org.spigotmc.SpigotWorldConfig; +import org.spigotmc.TickLimiter; + +import java.util.*; + +public class CustomDimensions extends JavaPlugin implements Listener { + /*@Command2.Subcommand + public void def(CommandSender sender, String name) { + *sender.sendMessage("Starting creation of " + name + "..."); + var world = load(); + if (world == null) + sender.sendMessage("Failed to load world."); + else + sender.sendMessage("World loaded! " + world.getName());* + }*/ + + @Override + public void onEnable() { + Bukkit.getPluginManager().registerEvents(this, this); + } + + @EventHandler + public void worldLoad(WorldLoadEvent event) { + System.out.println("World loaded: " + event.getWorld().getName()); + if (!event.getWorld().getName().equals(Bukkit.getWorlds().get(0).getName())) + return; + System.out.println("Main world"); + try { + load(); + } catch (Exception e) { + e.printStackTrace(); + } + } + + public void load() throws Exception { + System.out.println("Loading..."); + var console = ((CraftServer) Bukkit.getServer()).getServer(); + var field = console.getClass().getSuperclass().getDeclaredField("saveData"); + field.setAccessible(true); + var saveData = (SaveData) field.get(console); + IWorldDataServer iworlddataserver = saveData.H(); + GeneratorSettings generatorsettings = saveData.getGeneratorSettings(); + RegistryMaterials registrymaterials = generatorsettings.d(); + var worldloadlistener = console.worldLoadListenerFactory.create(11); + + var iterator = registrymaterials.d().iterator(); + + var mainWorld = Bukkit.getWorlds().get(0); + + while (iterator.hasNext()) { + Map.Entry, WorldDimension> entry = iterator.next(); + ResourceKey resourcekey = entry.getKey(); + + if (resourcekey != WorldDimension.OVERWORLD) { + ResourceKey resourcekey1 = ResourceKey.a(IRegistry.L, resourcekey.a()); + DimensionManager dimensionmanager1 = entry.getValue().b(); + ChunkGenerator chunkgenerator = entry.getValue().c(); + SecondaryWorldData secondaryworlddata = new SecondaryWorldData(saveData, iworlddataserver); + WorldServer worldserver1 = new WorldServer(console, console.executorService, console.convertable, + secondaryworlddata, resourcekey1, dimensionmanager1, worldloadlistener, chunkgenerator, + false, //isDebugWorld + BiomeManager.a(mainWorld.getSeed()), //Biome seed + ImmutableList.of(), false, org.bukkit.World.Environment.NORMAL, null, secondaryworlddata.getName()); + + ((CraftWorld) mainWorld).getHandle().getWorldBorder().a(new IWorldBorderListener.a(worldserver1.getWorldBorder())); + console.worldServer.put(resourcekey1, worldserver1); + } + } + System.out.println("Loading finished!"); + } + + /*private WorldServer createWorldServer(WorldDataMutable worldData, String name) throws Exception { + var obj = new ObjenesisStd(); + var ws = obj.newInstance(WorldServer.class); + ws.spigotConfig = new SpigotWorldConfig(name); + //ws.generator = gen; + var field = ws.getClass().getDeclaredField("world"); + field.setAccessible(true); + field.set(ws, new CraftWorld(ws, null, org.bukkit.World.Environment.NORMAL)); + ws.ticksPerAnimalSpawns = ws.getServer().getTicksPerAnimalSpawns(); + ws.ticksPerMonsterSpawns = ws.getServer().getTicksPerMonsterSpawns(); + ... + }*/ + + /*public World load(String name) { + File folder = new File(Bukkit.getWorldContainer(), name); + World world = Bukkit.getWorld(name); + if (world != null) { + return world; + } else if (folder.exists() && !folder.isDirectory()) { + throw new IllegalArgumentException("File exists with the name '" + name + "' and isn't a folder"); + } else { + ResourceKey actualDimension = ResourceKey.a(IRegistry.M, new MinecraftKey(name)); + + Convertable.ConversionSession worldSession; + try { + worldSession = Convertable.a(Bukkit.getWorldContainer().toPath()).c(name, actualDimension); + } catch (IOException var21) { + throw new RuntimeException(var21); + } + + var server = (CraftServer) Bukkit.getServer(); + var console = server.getServer(); + + MinecraftServer.convertWorld(worldSession); + RegistryReadOps registryreadops = RegistryReadOps.a(DynamicOpsNBT.a, console.dataPackResources.h(), console.f); + WorldDataServer worlddata = (WorldDataServer) worldSession.a(registryreadops, console.datapackconfiguration); + if (worlddata == null) { + System.out.println("No world data found in datapacks!"); + System.out.println("folder: "+worldSession.folder); + System.out.println("level name: "+worldSession.getLevelName()); + Bukkit.getWorlds() + //World folder: Minecraft only supports the three default types for the main world + //Therefore we can't load a separate world with a custom dimension + //How about just pretending we did + return null; + } + + worlddata.checkName(name); + worlddata.a(console.getServerModName(), console.getModded().isPresent()); + if (console.options.has("forceUpgrade")) { + Main.convertWorld(worldSession, DataConverterRegistry.a(), console.options.has("eraseCache"), + () -> true, worlddata.getGeneratorSettings().d().d().stream().map((entry) -> ResourceKey.a(IRegistry.K, + entry.getKey().a())).collect(ImmutableSet.toImmutableSet())); + } + + long j = BiomeManager.a(Bukkit.getWorlds().get(0).getSeed()); + List list = ImmutableList.of(new MobSpawnerPhantom(), new MobSpawnerPatrol(), new MobSpawnerCat(), new VillageSiege(), new MobSpawnerTrader(worlddata)); + RegistryMaterials registrymaterials = worlddata.getGeneratorSettings().d(); + WorldDimension worlddimension = registrymaterials.a(actualDimension); + DimensionManager dimensionmanager; + ChunkGenerator chunkgenerator; + if (worlddimension == null) { + //dimensionmanager = console.f.a().d(DimensionManager.OVERWORLD); + //chunkgenerator = GeneratorSettings.a(console.f.b(IRegistry.ay), console.f.b(IRegistry.ar), (new Random()).nextLong()); + System.out.println("World dimension is null!"); + return null; + } else { + dimensionmanager = worlddimension.b(); + chunkgenerator = worlddimension.c(); + } + + var environment = World.Environment.NORMAL; + + ResourceKey worldKey = ResourceKey.a(IRegistry.L, new MinecraftKey(name.toLowerCase(Locale.ENGLISH))); + WorldServer internal = new WorldServer(console, console.executorService, worldSession, worlddata, worldKey, + dimensionmanager, console.worldLoadListenerFactory.create(11), chunkgenerator, + worlddata.getGeneratorSettings().isDebugWorld(), j, environment == World.Environment.NORMAL ? list : ImmutableList.of(), + true, environment, null); + if (Bukkit.getWorld(name.toLowerCase(Locale.ENGLISH)) == null) { + System.out.println("Newly created world not found!"); + return null; + } else { + console.initWorld(internal, worlddata, worlddata, worlddata.getGeneratorSettings()); + internal.setSpawnFlags(true, true); + console.worldServer.put(internal.getDimensionKey(), internal); + server.getPluginManager().callEvent(new WorldInitEvent(internal.getWorld())); + console.loadSpawn(internal.getChunkProvider().playerChunkMap.worldLoadListener, internal); + server.getPluginManager().callEvent(new WorldLoadEvent(internal.getWorld())); + return internal.getWorld(); + } + } + }*/ +} diff --git a/src/main/resources/plugin.yml b/src/main/resources/plugin.yml new file mode 100644 index 0000000..03215c6 --- /dev/null +++ b/src/main/resources/plugin.yml @@ -0,0 +1,5 @@ +name: CustomDimensions +main: buttondevteam.customdimensions.CustomDimensions +version: '1.0' +load: STARTUP +api-version: '1.16'