mirror of
https://github.com/VolmitSoftware/Iris.git
synced 2026-06-24 21:51:24 +00:00
mid save
This commit is contained in:
+1
-1
@@ -43,7 +43,7 @@ registerCustomOutputTask('Coco', 'D://mcsm/plugins')
|
|||||||
registerCustomOutputTask('Strange', 'D://Servers/1.17 Test Server/plugins')
|
registerCustomOutputTask('Strange', 'D://Servers/1.17 Test Server/plugins')
|
||||||
registerCustomOutputTask('Vatuu', 'D://Minecraft/Servers/1.19.4/plugins')
|
registerCustomOutputTask('Vatuu', 'D://Minecraft/Servers/1.19.4/plugins')
|
||||||
registerCustomOutputTask('CrazyDev22', 'C://Users/Julian/Desktop/server/plugins')
|
registerCustomOutputTask('CrazyDev22', 'C://Users/Julian/Desktop/server/plugins')
|
||||||
registerCustomOutputTask('Pixel', 'C://Users/repix/Iris Dimension Engine/1.20.4 - Development/plugins')
|
registerCustomOutputTask('Pixel', 'D://Iris Dimension Engine/1.20.4 - Development/plugins')
|
||||||
// ========================== UNIX ==============================
|
// ========================== UNIX ==============================
|
||||||
registerCustomOutputTaskUnix('CyberpwnLT', '/Users/danielmills/development/server/plugins')
|
registerCustomOutputTaskUnix('CyberpwnLT', '/Users/danielmills/development/server/plugins')
|
||||||
registerCustomOutputTaskUnix('PsychoLT', '/Users/brianfopiano/Developer/RemoteGit/Server/plugins')
|
registerCustomOutputTaskUnix('PsychoLT', '/Users/brianfopiano/Developer/RemoteGit/Server/plugins')
|
||||||
|
|||||||
@@ -73,7 +73,6 @@ import static org.bukkit.Bukkit.getServer;
|
|||||||
public class CommandIris implements DecreeExecutor {
|
public class CommandIris implements DecreeExecutor {
|
||||||
private CommandStudio studio;
|
private CommandStudio studio;
|
||||||
private CommandPregen pregen;
|
private CommandPregen pregen;
|
||||||
private CommandLazyPregen lazyPregen;
|
|
||||||
private CommandSettings settings;
|
private CommandSettings settings;
|
||||||
private CommandObject object;
|
private CommandObject object;
|
||||||
private CommandJigsaw jigsaw;
|
private CommandJigsaw jigsaw;
|
||||||
|
|||||||
@@ -1,121 +0,0 @@
|
|||||||
/*
|
|
||||||
* Iris is a World Generator for Minecraft Bukkit Servers
|
|
||||||
* Copyright (c) 2022 Arcane Arts (Volmit Software)
|
|
||||||
*
|
|
||||||
* 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
|
|
||||||
* (at your option) 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 <https://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package com.volmit.iris.core.commands;
|
|
||||||
|
|
||||||
import com.volmit.iris.Iris;
|
|
||||||
import com.volmit.iris.core.IrisSettings;
|
|
||||||
import com.volmit.iris.core.gui.PregeneratorJob;
|
|
||||||
import com.volmit.iris.core.pregenerator.LazyPregenerator;
|
|
||||||
import com.volmit.iris.core.pregenerator.PregenTask;
|
|
||||||
import com.volmit.iris.core.tools.IrisToolbelt;
|
|
||||||
import com.volmit.iris.util.decree.DecreeExecutor;
|
|
||||||
import com.volmit.iris.util.decree.annotations.Decree;
|
|
||||||
import com.volmit.iris.util.decree.annotations.Param;
|
|
||||||
import com.volmit.iris.util.format.C;
|
|
||||||
import com.volmit.iris.util.math.Position2;
|
|
||||||
import org.bukkit.Bukkit;
|
|
||||||
import org.bukkit.World;
|
|
||||||
import org.bukkit.util.Vector;
|
|
||||||
|
|
||||||
import java.io.File;
|
|
||||||
import java.io.IOException;
|
|
||||||
|
|
||||||
@Decree(name = "lazypregen", aliases = "lazy", description = "Pregenerate your Iris worlds!")
|
|
||||||
public class CommandLazyPregen implements DecreeExecutor {
|
|
||||||
public String worldName;
|
|
||||||
@Decree(description = "Pregenerate a world")
|
|
||||||
public void start(
|
|
||||||
@Param(description = "The radius of the pregen in blocks", aliases = "size")
|
|
||||||
int radius,
|
|
||||||
@Param(description = "The world to pregen", contextual = true)
|
|
||||||
World world,
|
|
||||||
@Param(aliases = "middle", description = "The center location of the pregen. Use \"me\" for your current location", defaultValue = "0,0")
|
|
||||||
Vector center,
|
|
||||||
@Param(aliases = "maxcpm", description = "Limit the chunks per minute the pregen will generate", defaultValue = "999999999")
|
|
||||||
int cpm,
|
|
||||||
@Param(aliases = "silent", description = "Silent generation", defaultValue = "false")
|
|
||||||
boolean silent
|
|
||||||
) {
|
|
||||||
|
|
||||||
worldName = world.getName();
|
|
||||||
File worldDirectory = new File(Bukkit.getWorldContainer(), world.getName());
|
|
||||||
File lazyFile = new File(worldDirectory, "lazygen.json");
|
|
||||||
if (lazyFile.exists()) {
|
|
||||||
sender().sendMessage(C.BLUE + "Lazy pregen is already in progress");
|
|
||||||
Iris.info(C.YELLOW + "Lazy pregen is already in progress");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
|
||||||
if (sender().isPlayer() && access() == null) {
|
|
||||||
sender().sendMessage(C.RED + "The engine access for this world is null!");
|
|
||||||
sender().sendMessage(C.RED + "Please make sure the world is loaded & the engine is initialized. Generate a new chunk, for example.");
|
|
||||||
}
|
|
||||||
|
|
||||||
LazyPregenerator.LazyPregenJob pregenJob = LazyPregenerator.LazyPregenJob.builder()
|
|
||||||
.world(worldName)
|
|
||||||
.healingPosition(0)
|
|
||||||
.healing(false)
|
|
||||||
.chunksPerMinute(cpm)
|
|
||||||
.radiusBlocks(radius)
|
|
||||||
.position(0)
|
|
||||||
.silent(silent)
|
|
||||||
.build();
|
|
||||||
|
|
||||||
File lazyGenFile = new File(worldDirectory, "lazygen.json");
|
|
||||||
LazyPregenerator pregenerator = new LazyPregenerator(pregenJob, lazyGenFile);
|
|
||||||
pregenerator.start();
|
|
||||||
|
|
||||||
String msg = C.GREEN + "LazyPregen started in " + C.GOLD + worldName + C.GREEN + " of " + C.GOLD + (radius * 2) + C.GREEN + " by " + C.GOLD + (radius * 2) + C.GREEN + " blocks from " + C.GOLD + center.getX() + "," + center.getZ();
|
|
||||||
sender().sendMessage(msg);
|
|
||||||
Iris.info(msg);
|
|
||||||
} catch (Throwable e) {
|
|
||||||
sender().sendMessage(C.RED + "Epic fail. See console.");
|
|
||||||
Iris.reportError(e);
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Decree(description = "Stop the active pregeneration task", aliases = "x")
|
|
||||||
public void stop(
|
|
||||||
@Param(aliases = "world", description = "The world to pause")
|
|
||||||
World world
|
|
||||||
) throws IOException {
|
|
||||||
if (LazyPregenerator.getInstance() != null) {
|
|
||||||
LazyPregenerator.getInstance().shutdownInstance(world);
|
|
||||||
sender().sendMessage(C.LIGHT_PURPLE + "Closed lazygen instance for " + world.getName());
|
|
||||||
} else {
|
|
||||||
sender().sendMessage(C.YELLOW + "No active pregeneration tasks to stop");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Decree(description = "Pause / continue the active pregeneration task", aliases = {"t", "resume", "unpause"})
|
|
||||||
public void pause(
|
|
||||||
@Param(aliases = "world", description = "The world to pause")
|
|
||||||
World world
|
|
||||||
) {
|
|
||||||
if (LazyPregenerator.getInstance() != null) {
|
|
||||||
LazyPregenerator.getInstance().setPausedLazy(world);
|
|
||||||
sender().sendMessage(C.GREEN + "Paused/unpaused Lazy Pregen, now: " + (LazyPregenerator.getInstance().isPausedLazy(world) ? "Paused" : "Running") + ".");
|
|
||||||
} else {
|
|
||||||
sender().sendMessage(C.YELLOW + "No active Lazy Pregen tasks to pause/unpause.");
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -18,6 +18,7 @@
|
|||||||
|
|
||||||
package com.volmit.iris.core.nms;
|
package com.volmit.iris.core.nms;
|
||||||
|
|
||||||
|
import com.volmit.iris.Iris;
|
||||||
import com.volmit.iris.core.nms.container.BiomeColor;
|
import com.volmit.iris.core.nms.container.BiomeColor;
|
||||||
import com.volmit.iris.core.nms.datapack.DataVersion;
|
import com.volmit.iris.core.nms.datapack.DataVersion;
|
||||||
import com.volmit.iris.engine.framework.Engine;
|
import com.volmit.iris.engine.framework.Engine;
|
||||||
@@ -30,6 +31,7 @@ import com.volmit.iris.util.nbt.mca.palette.MCAPaletteAccess;
|
|||||||
import com.volmit.iris.util.nbt.tag.CompoundTag;
|
import com.volmit.iris.util.nbt.tag.CompoundTag;
|
||||||
import org.bukkit.*;
|
import org.bukkit.*;
|
||||||
import org.bukkit.block.Biome;
|
import org.bukkit.block.Biome;
|
||||||
|
import org.bukkit.block.data.BlockData;
|
||||||
import org.bukkit.entity.Dolphin;
|
import org.bukkit.entity.Dolphin;
|
||||||
import org.bukkit.entity.Entity;
|
import org.bukkit.entity.Entity;
|
||||||
import org.bukkit.entity.EntityType;
|
import org.bukkit.entity.EntityType;
|
||||||
@@ -125,4 +127,9 @@ public interface INMSBinding {
|
|||||||
}
|
}
|
||||||
|
|
||||||
KList<String> getStructureKeys();
|
KList<String> getStructureKeys();
|
||||||
|
|
||||||
|
default BlockData getBlockData(CompoundTag tag) {
|
||||||
|
Iris.error("Unsupported version!");
|
||||||
|
return null;
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -20,9 +20,12 @@ package com.volmit.iris.core.service;
|
|||||||
|
|
||||||
import com.google.gson.Gson;
|
import com.google.gson.Gson;
|
||||||
import com.volmit.iris.Iris;
|
import com.volmit.iris.Iris;
|
||||||
|
import com.volmit.iris.core.nms.INMS;
|
||||||
|
import com.volmit.iris.core.nms.v1X.NMSBinding1X;
|
||||||
import com.volmit.iris.engine.object.*;
|
import com.volmit.iris.engine.object.*;
|
||||||
import com.volmit.iris.util.collection.KList;
|
import com.volmit.iris.util.collection.KList;
|
||||||
import com.volmit.iris.util.collection.KMap;
|
import com.volmit.iris.util.collection.KMap;
|
||||||
|
import com.volmit.iris.util.format.C;
|
||||||
import com.volmit.iris.util.format.Form;
|
import com.volmit.iris.util.format.Form;
|
||||||
import com.volmit.iris.util.function.Consumer2;
|
import com.volmit.iris.util.function.Consumer2;
|
||||||
import com.volmit.iris.util.io.Converter;
|
import com.volmit.iris.util.io.Converter;
|
||||||
@@ -37,13 +40,16 @@ import com.volmit.iris.util.nbt.tag.ListTag;
|
|||||||
import com.volmit.iris.util.plugin.IrisService;
|
import com.volmit.iris.util.plugin.IrisService;
|
||||||
import com.volmit.iris.util.plugin.VolmitSender;
|
import com.volmit.iris.util.plugin.VolmitSender;
|
||||||
import com.volmit.iris.util.scheduling.J;
|
import com.volmit.iris.util.scheduling.J;
|
||||||
|
import org.apache.commons.io.FileUtils;
|
||||||
import org.bukkit.Material;
|
import org.bukkit.Material;
|
||||||
import org.bukkit.block.data.BlockData;
|
import org.bukkit.block.data.BlockData;
|
||||||
import org.bukkit.block.data.type.Jigsaw;
|
import org.bukkit.block.data.type.Jigsaw;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
import java.util.Objects;
|
||||||
import java.util.concurrent.atomic.AtomicInteger;
|
import java.util.concurrent.atomic.AtomicInteger;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
public class ConversionSVC implements IrisService {
|
public class ConversionSVC implements IrisService {
|
||||||
private KList<Converter> converters;
|
private KList<Converter> converters;
|
||||||
@@ -122,7 +128,7 @@ public class ConversionSVC implements IrisService {
|
|||||||
@SuppressWarnings("unchecked") ListTag<CompoundTag> paletteList = (ListTag<CompoundTag>) compound.getListTag("palette");
|
@SuppressWarnings("unchecked") ListTag<CompoundTag> paletteList = (ListTag<CompoundTag>) compound.getListTag("palette");
|
||||||
for (int i = 0; i < paletteList.size(); i++) {
|
for (int i = 0; i < paletteList.size(); i++) {
|
||||||
CompoundTag cp = paletteList.get(i);
|
CompoundTag cp = paletteList.get(i);
|
||||||
palette.add(NBTWorld.getBlockData(cp));
|
palette.add(INMS.get().getBlockData(cp));
|
||||||
}
|
}
|
||||||
IrisJigsawPiece piece = new IrisJigsawPiece();
|
IrisJigsawPiece piece = new IrisJigsawPiece();
|
||||||
IrisObject object = new IrisObject(w, h, d);
|
IrisObject object = new IrisObject(w, h, d);
|
||||||
@@ -135,20 +141,37 @@ public class ConversionSVC implements IrisService {
|
|||||||
int z = pos.get(2).asInt();
|
int z = pos.get(2).asInt();
|
||||||
BlockData bd = palette.get(cp.getInt("state")).clone();
|
BlockData bd = palette.get(cp.getInt("state")).clone();
|
||||||
|
|
||||||
|
piece.setObject(in.toURI().relativize(folder.toURI()).getPath() + file.getName().split("\\Q.\\E")[0]);
|
||||||
if (bd.getMaterial().equals(Material.JIGSAW) && cp.containsKey("nbt")) {
|
if (bd.getMaterial().equals(Material.JIGSAW) && cp.containsKey("nbt")) {
|
||||||
piece.setObject(in.toURI().relativize(folder.toURI()).getPath() + file.getName().split("\\Q.\\E")[0]);
|
//.setObject(in.toURI().relativize(folder.toURI()).getPath() + file.getName().split("\\Q.\\E")[0]);
|
||||||
IrisPosition spos = new IrisPosition(object.getSigned(x, y, z));
|
IrisPosition spos = new IrisPosition(object.getSigned(x, y, z));
|
||||||
CompoundTag nbt = cp.getCompoundTag("nbt");
|
CompoundTag nbt = cp.getCompoundTag("nbt");
|
||||||
CompoundTag finalState = new CompoundTag();
|
CompoundTag finalState = new CompoundTag();
|
||||||
finalState.putString("Name", nbt.getString("final_state"));
|
finalState.putString("Name", nbt.getString("final_state"));
|
||||||
BlockData jd = bd.clone();
|
BlockData jd = bd.clone();
|
||||||
bd = NBTWorld.getBlockData(finalState);
|
bd = INMS.get().getBlockData(finalState);
|
||||||
String joint = nbt.getString("joint");
|
String joint = nbt.getString("joint");
|
||||||
String pool = nbt.getString("pool");
|
String pool = nbt.getString("pool");
|
||||||
String poolId = toPoolName(pool);
|
String poolId = toPoolName(pool);
|
||||||
String name = nbt.getString("name");
|
String name = nbt.getString("name");
|
||||||
String target = nbt.getString("target");
|
String target = nbt.getString("target");
|
||||||
pools.computeIfAbsent(poolId, (k) -> new IrisJigsawPool());
|
pools.computeIfAbsent(poolId, (k) -> {
|
||||||
|
IrisJigsawPool irisPool = new IrisJigsawPool();
|
||||||
|
|
||||||
|
String basePath = in.toURI().relativize(folder.toURI()).getPath();
|
||||||
|
File baseFolder = new File(in.toURI().relativize(folder.toURI()).toString());
|
||||||
|
String[] paths = FileUtils.listFiles(folder, null, true)
|
||||||
|
.stream()
|
||||||
|
.map(path -> path.getPath().replaceAll("\\.nbt$", "")).toArray(String[]::new);
|
||||||
|
|
||||||
|
KList<String> poolList = new KList<>();
|
||||||
|
for (int ii = 0; ii < Objects.requireNonNull(paths).length; ii++) {
|
||||||
|
String lastSegment = paths[ii].substring(paths[ii].lastIndexOf("\\") + 1);
|
||||||
|
poolList.add(basePath + lastSegment);
|
||||||
|
}
|
||||||
|
irisPool.setPieces(poolList);
|
||||||
|
return irisPool;
|
||||||
|
});
|
||||||
IrisJigsawPieceConnector connector = new IrisJigsawPieceConnector();
|
IrisJigsawPieceConnector connector = new IrisJigsawPieceConnector();
|
||||||
connector.setName(name);
|
connector.setName(name);
|
||||||
connector.setTargetName(target);
|
connector.setTargetName(target);
|
||||||
@@ -169,10 +192,14 @@ public class ConversionSVC implements IrisService {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (piece.getObject().isBlank() || piece.getObject().isEmpty()) {
|
||||||
|
Iris.info(C.RED + "Failed Setting object with path: " + in.toURI().relativize(folder.toURI()).getPath() + file.getName().split("\\Q.\\E")[0]);
|
||||||
|
}
|
||||||
jpool.getPieces().addIfMissing(id);
|
jpool.getPieces().addIfMissing(id);
|
||||||
object.write(new File(destObjects, file.getName().split("\\Q.\\E")[0] + ".iob"));
|
object.write(new File(destObjects, file.getName().split("\\Q.\\E")[0] + ".iob"));
|
||||||
IO.writeAll(new File(destPieces, file.getName().split("\\Q.\\E")[0] + ".json"), new JSONObject(new Gson().toJson(piece)).toString(4));
|
IO.writeAll(new File(destPieces, file.getName().split("\\Q.\\E")[0] + ".json"), new JSONObject(new Gson().toJson(piece)).toString(4));
|
||||||
Iris.info("[Jigsaw]: (" + Form.pc((double) at.get() / (double) total.get(), 0) + ") Exported Piece: " + id);
|
Iris.info("[Jigsaw]: (" + Form.pc((double) at.get() / (double) total.get(), 0).replace("%", "%%") + ") Exported Piece: " + id);
|
||||||
|
|
||||||
}
|
}
|
||||||
} catch (Throwable e) {
|
} catch (Throwable e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
|
|||||||
@@ -10,14 +10,19 @@ import com.volmit.iris.util.math.RollingSequence;
|
|||||||
import com.volmit.iris.util.misc.E;
|
import com.volmit.iris.util.misc.E;
|
||||||
import com.volmit.iris.util.scheduling.ChronoLatch;
|
import com.volmit.iris.util.scheduling.ChronoLatch;
|
||||||
import com.volmit.iris.util.scheduling.J;
|
import com.volmit.iris.util.scheduling.J;
|
||||||
|
import org.bukkit.Bukkit;
|
||||||
|
import org.bukkit.NamespacedKey;
|
||||||
import org.bukkit.World;
|
import org.bukkit.World;
|
||||||
|
|
||||||
import java.io.File;
|
|
||||||
|
|
||||||
import org.bukkit.Chunk;
|
import org.bukkit.Chunk;
|
||||||
import org.bukkit.block.Biome;
|
import org.bukkit.block.Biome;
|
||||||
import org.bukkit.block.Block;
|
import org.bukkit.block.Block;
|
||||||
|
import org.bukkit.plugin.Plugin;
|
||||||
|
|
||||||
|
import java.io.BufferedWriter;
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.FileWriter;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.lang.reflect.Method;
|
||||||
import java.util.concurrent.atomic.AtomicInteger;
|
import java.util.concurrent.atomic.AtomicInteger;
|
||||||
import java.util.concurrent.atomic.AtomicLong;
|
import java.util.concurrent.atomic.AtomicLong;
|
||||||
|
|
||||||
@@ -41,6 +46,12 @@ public class IrisBiomeFixer {
|
|||||||
private AtomicInteger totalChunks = new AtomicInteger(0);
|
private AtomicInteger totalChunks = new AtomicInteger(0);
|
||||||
private ChronoLatch progressLatch = new ChronoLatch(5000); // Update every 5 seconds
|
private ChronoLatch progressLatch = new ChronoLatch(5000); // Update every 5 seconds
|
||||||
|
|
||||||
|
// File to store unregistered biome IDs
|
||||||
|
private File unregisteredBiomesFile;
|
||||||
|
|
||||||
|
// Reference to your plugin instance (Assuming you have one)
|
||||||
|
private Plugin plugin;
|
||||||
|
|
||||||
public IrisBiomeFixer(World world) {
|
public IrisBiomeFixer(World world) {
|
||||||
if (!IrisToolbelt.isIrisWorld(world)) {
|
if (!IrisToolbelt.isIrisWorld(world)) {
|
||||||
Iris.info("This is not an Iris world!");
|
Iris.info("This is not an Iris world!");
|
||||||
@@ -53,6 +64,10 @@ public class IrisBiomeFixer {
|
|||||||
this.world = world;
|
this.world = world;
|
||||||
this.latch = new ChronoLatch(3000);
|
this.latch = new ChronoLatch(3000);
|
||||||
this.engine = IrisToolbelt.access(world).getEngine();
|
this.engine = IrisToolbelt.access(world).getEngine();
|
||||||
|
this.plugin = Iris.instance;
|
||||||
|
|
||||||
|
// Initialize the file for storing unregistered biome IDs
|
||||||
|
this.unregisteredBiomesFile = new File(world.getWorldFolder(), "unregistered_biomes.txt");
|
||||||
}
|
}
|
||||||
|
|
||||||
public void fixBiomes() {
|
public void fixBiomes() {
|
||||||
@@ -75,7 +90,7 @@ public class IrisBiomeFixer {
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
totalChunks.addAndGet(1024); // Each region has 32x32 chunks = 1024
|
totalChunks.addAndGet(1024);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (File regionFile : regionFiles) {
|
for (File regionFile : regionFiles) {
|
||||||
@@ -112,27 +127,36 @@ public class IrisBiomeFixer {
|
|||||||
Block block = chunk.getBlock(x, y, z);
|
Block block = chunk.getBlock(x, y, z);
|
||||||
Biome bukkitBiome;
|
Biome bukkitBiome;
|
||||||
IrisBiome irisBiome = engine.getBiome(x, y, z);
|
IrisBiome irisBiome = engine.getBiome(x, y, z);
|
||||||
|
IrisBiomeCustom custom;
|
||||||
try {
|
try {
|
||||||
// Try to get the custom biome
|
custom = irisBiome.getCustomBiome(rng, x, y, z);
|
||||||
IrisBiomeCustom custom = irisBiome.getCustomBiome(rng, x, y, z);
|
} catch (Exception e) {
|
||||||
if (custom != null) {
|
custom = null;
|
||||||
bukkitBiome = Biome.valueOf(custom.getId().toUpperCase());
|
|
||||||
} else {
|
|
||||||
// Fallback to derivative biome if custom biome is null
|
|
||||||
bukkitBiome = irisBiome.getDerivative();
|
|
||||||
}
|
|
||||||
} catch (NullPointerException e) {
|
|
||||||
// So else will fail. But this works lol
|
|
||||||
bukkitBiome = irisBiome.getDerivative();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (bukkitBiome == null) {
|
if (custom != null) {
|
||||||
// This should be impossible
|
// Attempt to get the Biome enum constant
|
||||||
bukkitBiome = Biome.CUSTOM;
|
try {
|
||||||
Iris.warn("Biome NULL! using plains as fallback!");
|
bukkitBiome = Biome.valueOf(custom.getId().toUpperCase());
|
||||||
|
world.setBiome(block.getX(), block.getY(), block.getZ(), bukkitBiome);
|
||||||
|
} catch (IllegalArgumentException ex) {
|
||||||
|
// Custom biome not found in Biome enum
|
||||||
|
// Attempt to set custom biome via NMS
|
||||||
|
try {
|
||||||
|
setCustomBiome(block, custom.getId());
|
||||||
|
} catch (Exception e) {
|
||||||
|
// Log unregistered or failed to set custom biome
|
||||||
|
logUnregisteredBiome(custom.getId());
|
||||||
|
// Fallback to derivative biome
|
||||||
|
bukkitBiome = irisBiome.getDerivative();
|
||||||
|
world.setBiome(block.getX(), block.getY(), block.getZ(), bukkitBiome);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// Use derivative biome if custom biome is null
|
||||||
|
bukkitBiome = irisBiome.getDerivative();
|
||||||
|
world.setBiome(block.getX(), block.getY(), block.getZ(), bukkitBiome);
|
||||||
}
|
}
|
||||||
world.setBiome(block.getX(), block.getY(), block.getZ(), bukkitBiome);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -169,6 +193,64 @@ public class IrisBiomeFixer {
|
|||||||
Iris.info(String.format("Biome Fixing Completed: %d/%d chunks processed.", generated.get(), totalChunks.get()));
|
Iris.info(String.format("Biome Fixing Completed: %d/%d chunks processed.", generated.get(), totalChunks.get()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets a custom biome using NMS (Minecraft's internal classes).
|
||||||
|
*
|
||||||
|
* @param block The block whose biome is to be set.
|
||||||
|
* @param biomeId The NamespacedKey of the custom biome (e.g., "custom:my_biome").
|
||||||
|
* @throws Exception If reflection or NMS interaction fails.
|
||||||
|
*/
|
||||||
|
private void setCustomBiome(Block block, String biomeId) throws Exception {
|
||||||
|
// Parse the NamespacedKey
|
||||||
|
NamespacedKey key = NamespacedKey.fromString(biomeId);
|
||||||
|
if (key == null) {
|
||||||
|
throw new IllegalArgumentException("Invalid biome ID: " + biomeId);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Access NMS classes using reflection
|
||||||
|
// Adjust the version string as needed (e.g., "v1_20_R1")
|
||||||
|
String nmsVersion = Bukkit.getServer().getClass().getPackage().getName().split("\\.")[3];
|
||||||
|
Class<?> worldClass = Class.forName("org.bukkit.craftbukkit." + nmsVersion + ".CraftWorld");
|
||||||
|
Object nmsWorld = worldClass.cast(world).getClass().getMethod("getHandle").invoke(world);
|
||||||
|
|
||||||
|
Class<?> chunkClass = Class.forName("net.minecraft.world.level.chunk.Chunk");
|
||||||
|
Object nmsChunk = chunkClass.cast(nmsWorld.getClass().getMethod("getChunk", int.class, int.class, boolean.class)
|
||||||
|
.invoke(nmsWorld, block.getChunk().getX(), block.getChunk().getZ(), false));
|
||||||
|
|
||||||
|
// Get the biome registry
|
||||||
|
Class<?> registryKeyClass = Class.forName("net.minecraft.resources.ResourceKey");
|
||||||
|
Class<?> biomeClass = Class.forName("net.minecraft.world.level.biome.Biome");
|
||||||
|
Class<?> registryClass = Class.forName("net.minecraft.core.Registry");
|
||||||
|
Method biomeRegistryMethod = registryClass.getMethod("a", Class.class, Object.class);
|
||||||
|
Object biomeRegistry = biomeRegistryMethod.invoke(null, biomeClass, null); // Replace null with actual registry if needed
|
||||||
|
|
||||||
|
// Get the biome by key
|
||||||
|
Method getBiomeMethod = biomeClass.getMethod("a", registryKeyClass);
|
||||||
|
Object customBiome = getBiomeMethod.invoke(null, key.getNamespace() + ":" + key.getKey());
|
||||||
|
|
||||||
|
if (customBiome == null) {
|
||||||
|
throw new IllegalArgumentException("Custom biome not found: " + biomeId);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set the biome in the chunk
|
||||||
|
Method setBiomeMethod = chunkClass.getMethod("setBiome", int.class, int.class, biomeClass);
|
||||||
|
setBiomeMethod.invoke(nmsChunk, block.getX() & 15, block.getZ() & 15, customBiome);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Logs unregistered or failed to set custom biomes to a file.
|
||||||
|
*
|
||||||
|
* @param biomeId The ID of the biome that failed to register.
|
||||||
|
*/
|
||||||
|
private void logUnregisteredBiome(String biomeId) {
|
||||||
|
try (BufferedWriter writer = new BufferedWriter(new FileWriter(unregisteredBiomesFile, true))) {
|
||||||
|
writer.write(biomeId);
|
||||||
|
writer.newLine();
|
||||||
|
} catch (IOException e) {
|
||||||
|
Iris.error("Failed to log unregistered biome: " + biomeId, e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private long computeETA(int cps) {
|
private long computeETA(int cps) {
|
||||||
if (chunksPerSecond.size() < chunksPerSecond.getMax()) {
|
if (chunksPerSecond.size() < chunksPerSecond.getMax()) {
|
||||||
if (cps == 0) return Long.MAX_VALUE;
|
if (cps == 0) return Long.MAX_VALUE;
|
||||||
@@ -194,4 +276,3 @@ public class IrisBiomeFixer {
|
|||||||
return String.format("%02dh:%02dm:%02ds", hours, minutes, seconds);
|
return String.format("%02dh:%02dm:%02ds", hours, minutes, seconds);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -2,8 +2,11 @@ package com.volmit.iris.core.tools;
|
|||||||
|
|
||||||
import com.volmit.iris.Iris;
|
import com.volmit.iris.Iris;
|
||||||
import com.volmit.iris.engine.object.*;
|
import com.volmit.iris.engine.object.*;
|
||||||
|
import com.volmit.iris.util.collection.KList;
|
||||||
|
import com.volmit.iris.util.collection.KMap;
|
||||||
import com.volmit.iris.util.format.C;
|
import com.volmit.iris.util.format.C;
|
||||||
import com.volmit.iris.util.format.Form;
|
import com.volmit.iris.util.format.Form;
|
||||||
|
import com.volmit.iris.util.function.Consumer2;
|
||||||
import com.volmit.iris.util.misc.E;
|
import com.volmit.iris.util.misc.E;
|
||||||
import com.volmit.iris.util.nbt.io.NBTUtil;
|
import com.volmit.iris.util.nbt.io.NBTUtil;
|
||||||
import com.volmit.iris.util.nbt.io.NamedTag;
|
import com.volmit.iris.util.nbt.io.NamedTag;
|
||||||
@@ -141,28 +144,61 @@ public class IrisConverter {
|
|||||||
*
|
*
|
||||||
* @param sender
|
* @param sender
|
||||||
*/
|
*/
|
||||||
public static void convertJigsaw(VolmitSender sender) {
|
public static void convertJigsawStructure(File in, File out, VolmitSender sender) {
|
||||||
File folder = Iris.instance.getDataFolder("convert");
|
File dataFolder = Iris.instance.getDataFolder("convert");
|
||||||
|
try {
|
||||||
|
KMap<String, IrisJigsawPool> pools = new KMap<>();
|
||||||
|
KList<File> roots = new KList<>();
|
||||||
|
AtomicInteger total = new AtomicInteger(0);
|
||||||
|
AtomicInteger at = new AtomicInteger(0);
|
||||||
|
File destPools = new File(out.getAbsolutePath() + "/jigsaw-pools");
|
||||||
|
destPools.mkdirs();
|
||||||
|
findAllNBT(in, (folder, file) -> {
|
||||||
|
total.getAndIncrement();
|
||||||
|
if (roots.addIfMissing(folder)) {
|
||||||
|
String b = in.toURI().relativize(folder.toURI()).getPath();
|
||||||
|
if (b.startsWith("/")) {
|
||||||
|
b = b.substring(1);
|
||||||
|
}
|
||||||
|
|
||||||
FilenameFilter filter = (dir, name) -> name.endsWith(".nbt");
|
if (b.endsWith("/")) {
|
||||||
File[] fileList = folder.listFiles(filter);
|
b = b.substring(0, b.length() - 1);
|
||||||
if (fileList == null) {
|
}
|
||||||
sender.sendMessage("No schematic files to convert found in " + folder.getAbsolutePath());
|
|
||||||
|
pools.put(b, new IrisJigsawPool());
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
} catch (Exception e) {
|
||||||
|
Iris.error(C.RED + "Failed to convert: " + in.getPath());
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void findAllNBT(File path, Consumer2<File, File> inFile) {
|
||||||
|
if (path == null) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (File nbt : fileList) {
|
if (path.isFile() && path.getName().endsWith(".nbt")) {
|
||||||
try {
|
inFile.accept(path.getParentFile(), path);
|
||||||
NamedTag tag = NBTUtil.read(nbt);
|
return;
|
||||||
CompoundTag compound = (CompoundTag) tag.getTag();
|
}
|
||||||
} catch (Exception e) {
|
for (File i : path.listFiles()) {
|
||||||
Iris.error(C.RED + "Failed to convert: " + nbt.getName());
|
if (i.isDirectory()) {
|
||||||
e.printStackTrace();
|
findAllNBT(i, inFile);
|
||||||
}
|
} else if (i.isFile() && i.getName().endsWith(".nbt")) {
|
||||||
|
inFile.accept(path, i);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,29 +3,107 @@ package com.volmit.iris.engine.framework;
|
|||||||
import com.volmit.iris.engine.object.InventorySlotType;
|
import com.volmit.iris.engine.object.InventorySlotType;
|
||||||
import com.volmit.iris.engine.object.IrisLootTable;
|
import com.volmit.iris.engine.object.IrisLootTable;
|
||||||
import com.volmit.iris.util.collection.KList;
|
import com.volmit.iris.util.collection.KList;
|
||||||
|
import com.volmit.iris.util.math.RNG;
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
|
import org.bukkit.Bukkit;
|
||||||
|
import org.bukkit.Material;
|
||||||
|
import org.bukkit.NamespacedKey;
|
||||||
|
import org.bukkit.World;
|
||||||
import org.bukkit.block.Block;
|
import org.bukkit.block.Block;
|
||||||
import org.bukkit.event.Event;
|
import org.bukkit.event.Event;
|
||||||
import org.bukkit.event.HandlerList;
|
import org.bukkit.event.HandlerList;
|
||||||
|
import org.bukkit.event.world.LootGenerateEvent;
|
||||||
|
|
||||||
|
import org.bukkit.inventory.Inventory;
|
||||||
|
import org.bukkit.inventory.InventoryHolder;
|
||||||
|
import org.bukkit.inventory.ItemStack;
|
||||||
|
import org.bukkit.loot.LootContext;
|
||||||
|
import org.bukkit.loot.LootTable;
|
||||||
|
import org.bukkit.loot.LootTables;
|
||||||
|
|
||||||
|
import javax.annotation.Nullable;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Collection;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
@Getter
|
@Getter
|
||||||
public class IrisLootEvent extends Event {
|
public class IrisLootEvent extends Event {
|
||||||
private static final HandlerList handlers = new HandlerList();
|
private static final HandlerList handlers = new HandlerList();
|
||||||
|
|
||||||
private final Engine engine;
|
private final Engine engine;
|
||||||
private final Block block;
|
private final Block block;
|
||||||
private final InventorySlotType slot;
|
private final InventorySlotType slot;
|
||||||
private final KList<IrisLootTable> tables;
|
private final KList<IrisLootTable> tables;
|
||||||
|
private final Mode mode; // New field to represent the mode
|
||||||
|
|
||||||
|
// Define the different modes for the event
|
||||||
|
public enum Mode {
|
||||||
|
NORMAL,
|
||||||
|
BUKKIT_LOOT
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor for IrisLootEvent with mode selection.
|
||||||
|
*
|
||||||
|
* @param engine The engine instance.
|
||||||
|
* @param block The block associated with the event.
|
||||||
|
* @param slot The inventory slot type.
|
||||||
|
* @param tables The list of IrisLootTables. (mutable*)
|
||||||
|
*/
|
||||||
public IrisLootEvent(Engine engine, Block block, InventorySlotType slot, KList<IrisLootTable> tables) {
|
public IrisLootEvent(Engine engine, Block block, InventorySlotType slot, KList<IrisLootTable> tables) {
|
||||||
this.engine = engine;
|
this.engine = engine;
|
||||||
this.block = block;
|
this.block = block;
|
||||||
this.slot = slot;
|
this.slot = slot;
|
||||||
this.tables = tables;
|
this.tables = tables;
|
||||||
|
this.mode = Mode.BUKKIT_LOOT;
|
||||||
|
|
||||||
|
if (this.mode == Mode.BUKKIT_LOOT) {
|
||||||
|
triggerBukkitLootEvent();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Triggers the corresponding Bukkit loot event.
|
||||||
|
* This method integrates your custom IrisLootTables with Bukkit's LootGenerateEvent,
|
||||||
|
* allowing other plugins to modify or cancel the loot generation.
|
||||||
|
*/
|
||||||
|
private Inventory triggerBukkitLootEvent() {
|
||||||
|
if (block.getState() instanceof InventoryHolder) {
|
||||||
|
InventoryHolder holder = (InventoryHolder) block.getState();
|
||||||
|
Inventory inventory = holder.getInventory();
|
||||||
|
inventory.clear();
|
||||||
|
|
||||||
|
List<ItemStack> loot = new ArrayList<>();
|
||||||
|
RNG rng = new RNG();
|
||||||
|
int x = block.getX(), y = block.getY(), z = block.getZ();
|
||||||
|
|
||||||
|
for (IrisLootTable table : tables)
|
||||||
|
loot.addAll(table.getLoot(false, rng, slot, x, y, z));
|
||||||
|
|
||||||
|
LootContext context = new LootContext.Builder(block.getLocation()).build();
|
||||||
|
|
||||||
|
LootTable lootTable = Bukkit.getLootTable(LootTables.EMPTY.getKey()); // todo: Correct structure
|
||||||
|
|
||||||
|
LootGenerateEvent bukkitEvent = new LootGenerateEvent(engine.getWorld().realWorld(), null, holder, lootTable, context, loot, true); // todo: Use the iris loottable
|
||||||
|
Bukkit.getServer().getPluginManager().callEvent(bukkitEvent);
|
||||||
|
|
||||||
|
if (!bukkitEvent.isCancelled())
|
||||||
|
inventory.setContents(bukkitEvent.getLoot().toArray(new ItemStack[0]));
|
||||||
|
return inventory;
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public HandlerList getHandlers() {
|
public HandlerList getHandlers() {
|
||||||
return handlers;
|
return handlers;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Required method to get the HandlerList for this event.
|
||||||
|
*
|
||||||
|
* @return The HandlerList.
|
||||||
|
*/
|
||||||
public static HandlerList getHandlerList() {
|
public static HandlerList getHandlerList() {
|
||||||
return handlers;
|
return handlers;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -23,6 +23,7 @@ import org.bukkit.block.Block;
|
|||||||
import org.bukkit.block.BlockState;
|
import org.bukkit.block.BlockState;
|
||||||
import org.bukkit.block.TileState;
|
import org.bukkit.block.TileState;
|
||||||
import org.bukkit.block.data.BlockData;
|
import org.bukkit.block.data.BlockData;
|
||||||
|
import org.bukkit.inventory.Inventory;
|
||||||
import org.bukkit.inventory.InventoryHolder;
|
import org.bukkit.inventory.InventoryHolder;
|
||||||
|
|
||||||
@Getter
|
@Getter
|
||||||
@@ -64,6 +65,8 @@ public class WorldObjectPlacer implements IObjectPlacer {
|
|||||||
RNG rx = new RNG(Cache.key(x, z));
|
RNG rx = new RNG(Cache.key(x, z));
|
||||||
KList<IrisLootTable> tables = engine.getLootTables(rx, block);
|
KList<IrisLootTable> tables = engine.getLootTables(rx, block);
|
||||||
|
|
||||||
|
Inventory inventory = null;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
Bukkit.getPluginManager().callEvent(new IrisLootEvent(engine, block, slot, tables));
|
Bukkit.getPluginManager().callEvent(new IrisLootEvent(engine, block, slot, tables));
|
||||||
|
|
||||||
|
|||||||
@@ -16,6 +16,7 @@ import java.util.concurrent.atomic.AtomicInteger;
|
|||||||
|
|
||||||
import com.mojang.datafixers.util.Pair;
|
import com.mojang.datafixers.util.Pair;
|
||||||
import com.volmit.iris.core.nms.container.BiomeColor;
|
import com.volmit.iris.core.nms.container.BiomeColor;
|
||||||
|
import com.volmit.iris.util.data.B;
|
||||||
import com.volmit.iris.util.scheduling.J;
|
import com.volmit.iris.util.scheduling.J;
|
||||||
import net.minecraft.nbt.*;
|
import net.minecraft.nbt.*;
|
||||||
import net.minecraft.nbt.Tag;
|
import net.minecraft.nbt.Tag;
|
||||||
@@ -631,4 +632,32 @@ public class NMSBinding implements INMSBinding {
|
|||||||
public static Holder<net.minecraft.world.level.biome.Biome> biomeToBiomeBase(Registry<net.minecraft.world.level.biome.Biome> registry, Biome biome) {
|
public static Holder<net.minecraft.world.level.biome.Biome> biomeToBiomeBase(Registry<net.minecraft.world.level.biome.Biome> registry, Biome biome) {
|
||||||
return registry.getHolderOrThrow(ResourceKey.create(Registries.BIOME, CraftNamespacedKey.toMinecraft(biome.getKey())));
|
return registry.getHolderOrThrow(ResourceKey.create(Registries.BIOME, CraftNamespacedKey.toMinecraft(biome.getKey())));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public BlockData getBlockData(CompoundTag tag) {
|
||||||
|
if (tag == null) {
|
||||||
|
return B.getAir();
|
||||||
|
}
|
||||||
|
|
||||||
|
StringBuilder p = new StringBuilder(tag.getString("Name"));
|
||||||
|
|
||||||
|
if (tag.containsKey("Properties")) {
|
||||||
|
CompoundTag props = tag.getCompoundTag("Properties");
|
||||||
|
p.append('[');
|
||||||
|
|
||||||
|
for (String i : props.keySet()) {
|
||||||
|
p.append(i).append('=').append(props.getString(i)).append(',');
|
||||||
|
}
|
||||||
|
|
||||||
|
p.deleteCharAt(p.length() - 1).append(']');
|
||||||
|
}
|
||||||
|
|
||||||
|
BlockData b = B.get(String.valueOf(p));
|
||||||
|
|
||||||
|
if (b == null) {
|
||||||
|
return B.getAir();
|
||||||
|
}
|
||||||
|
|
||||||
|
return b;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user