mirror of
https://github.com/VolmitSoftware/Iris.git
synced 2026-06-18 14:50:57 +00:00
sync multiple mca fixes
This commit is contained in:
@@ -1,134 +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.pregenerator.DeepSearchPregenerator;
|
|
||||||
import com.volmit.iris.core.pregenerator.PregenTask;
|
|
||||||
import com.volmit.iris.core.pregenerator.TurboPregenerator;
|
|
||||||
import com.volmit.iris.core.tools.IrisToolbelt;
|
|
||||||
import com.volmit.iris.util.data.Dimension;
|
|
||||||
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 = "DeepSearch", aliases = "search", description = "Pregenerate your Iris worlds!")
|
|
||||||
public class CommandDeepSearch implements DecreeExecutor {
|
|
||||||
public String worldName;
|
|
||||||
@Decree(description = "DeepSearch 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
|
|
||||||
) {
|
|
||||||
|
|
||||||
worldName = world.getName();
|
|
||||||
File worldDirectory = new File(Bukkit.getWorldContainer(), world.getName());
|
|
||||||
File TurboFile = new File(worldDirectory, "DeepSearch.json");
|
|
||||||
if (TurboFile.exists()) {
|
|
||||||
if (DeepSearchPregenerator.getInstance() != null) {
|
|
||||||
sender().sendMessage(C.BLUE + "DeepSearch is already in progress");
|
|
||||||
Iris.info(C.YELLOW + "DeepSearch is already in progress");
|
|
||||||
return;
|
|
||||||
} else {
|
|
||||||
try {
|
|
||||||
TurboFile.delete();
|
|
||||||
} catch (Exception e){
|
|
||||||
Iris.error("Failed to delete the old instance file of DeepSearch!");
|
|
||||||
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.");
|
|
||||||
}
|
|
||||||
|
|
||||||
DeepSearchPregenerator.DeepSearchJob DeepSearchJob = DeepSearchPregenerator.DeepSearchJob.builder()
|
|
||||||
.world(world)
|
|
||||||
.radiusBlocks(radius)
|
|
||||||
.position(0)
|
|
||||||
.build();
|
|
||||||
|
|
||||||
File SearchGenFile = new File(worldDirectory, "DeepSearch.json");
|
|
||||||
DeepSearchPregenerator pregenerator = new DeepSearchPregenerator(DeepSearchJob, SearchGenFile);
|
|
||||||
pregenerator.start();
|
|
||||||
|
|
||||||
String msg = C.GREEN + "DeepSearch 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 DeepSearch task", aliases = "x")
|
|
||||||
public void stop(@Param(aliases = "world", description = "The world to pause") World world) throws IOException {
|
|
||||||
DeepSearchPregenerator DeepSearchInstance = DeepSearchPregenerator.getInstance();
|
|
||||||
File worldDirectory = new File(Bukkit.getWorldContainer(), world.getName());
|
|
||||||
File turboFile = new File(worldDirectory, "DeepSearch.json");
|
|
||||||
|
|
||||||
if (DeepSearchInstance != null) {
|
|
||||||
DeepSearchInstance.shutdownInstance(world);
|
|
||||||
sender().sendMessage(C.LIGHT_PURPLE + "Closed Turbogen instance for " + world.getName());
|
|
||||||
} else if (turboFile.exists() && turboFile.delete()) {
|
|
||||||
sender().sendMessage(C.LIGHT_PURPLE + "Closed Turbogen instance for " + world.getName());
|
|
||||||
} else if (turboFile.exists()) {
|
|
||||||
Iris.error("Failed to delete the old instance file of Turbo Pregen!");
|
|
||||||
} 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 (TurboPregenerator.getInstance() != null) {
|
|
||||||
TurboPregenerator.setPausedTurbo(world);
|
|
||||||
sender().sendMessage(C.GREEN + "Paused/unpaused Turbo Pregen, now: " + (TurboPregenerator.isPausedTurbo(world) ? "Paused" : "Running") + ".");
|
|
||||||
} else {
|
|
||||||
File worldDirectory = new File(Bukkit.getWorldContainer(), world.getName());
|
|
||||||
File TurboFile = new File(worldDirectory, "DeepSearch.json");
|
|
||||||
if (TurboFile.exists()){
|
|
||||||
TurboPregenerator.loadTurboGenerator(world.getName());
|
|
||||||
sender().sendMessage(C.YELLOW + "Started DeepSearch back up!");
|
|
||||||
} else {
|
|
||||||
sender().sendMessage(C.YELLOW + "No active DeepSearch tasks to pause/unpause.");
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -26,6 +26,7 @@ import com.volmit.iris.core.pregenerator.ChunkUpdater;
|
|||||||
import com.volmit.iris.core.service.IrisEngineSVC;
|
import com.volmit.iris.core.service.IrisEngineSVC;
|
||||||
import com.volmit.iris.core.tools.IrisPackBenchmarking;
|
import com.volmit.iris.core.tools.IrisPackBenchmarking;
|
||||||
import com.volmit.iris.core.tools.IrisToolbelt;
|
import com.volmit.iris.core.tools.IrisToolbelt;
|
||||||
|
import com.volmit.iris.core.tools.IrisWorldDump;
|
||||||
import com.volmit.iris.engine.framework.Engine;
|
import com.volmit.iris.engine.framework.Engine;
|
||||||
import com.volmit.iris.engine.mantle.components.MantleObjectComponent;
|
import com.volmit.iris.engine.mantle.components.MantleObjectComponent;
|
||||||
import com.volmit.iris.engine.object.IrisBiome;
|
import com.volmit.iris.engine.object.IrisBiome;
|
||||||
@@ -169,11 +170,12 @@ public class CommandDeveloper implements DecreeExecutor {
|
|||||||
|
|
||||||
@Decree(description = "test")
|
@Decree(description = "test")
|
||||||
public void mca (
|
public void mca (
|
||||||
@Param(description = "String") String world) {
|
@Param(description = "String") World world) {
|
||||||
try {
|
try {
|
||||||
File[] McaFiles = new File(world, "region").listFiles((dir, name) -> name.endsWith(".mca"));
|
File[] McaFiles = new File(world.getName(), "region").listFiles((dir, name) -> name.endsWith(".mca"));
|
||||||
for (File mca : McaFiles) {
|
for (File mca : McaFiles) {
|
||||||
MCAFile MCARegion = MCAUtil.read(mca);
|
IrisWorldDump dump = new IrisWorldDump(world, sender());
|
||||||
|
dump.dump();
|
||||||
}
|
}
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
|
|||||||
@@ -85,7 +85,6 @@ import java.util.function.Supplier;
|
|||||||
public class CommandStudio implements DecreeExecutor {
|
public class CommandStudio implements DecreeExecutor {
|
||||||
private CommandFind find;
|
private CommandFind find;
|
||||||
private CommandEdit edit;
|
private CommandEdit edit;
|
||||||
//private CommandDeepSearch deepSearch;
|
|
||||||
|
|
||||||
public static String hrf(Duration duration) {
|
public static String hrf(Duration duration) {
|
||||||
return duration.toString().substring(2).replaceAll("(\\d[HMS])(?!$)", "$1 ").toLowerCase();
|
return duration.toString().substring(2).replaceAll("(\\d[HMS])(?!$)", "$1 ").toLowerCase();
|
||||||
|
|||||||
@@ -1,275 +0,0 @@
|
|||||||
package com.volmit.iris.core.pregenerator;
|
|
||||||
|
|
||||||
import com.google.gson.Gson;
|
|
||||||
import com.volmit.iris.Iris;
|
|
||||||
import com.volmit.iris.core.tools.IrisToolbelt;
|
|
||||||
import com.volmit.iris.engine.framework.Engine;
|
|
||||||
import com.volmit.iris.engine.object.IrisBiome;
|
|
||||||
import com.volmit.iris.util.collection.KList;
|
|
||||||
import com.volmit.iris.util.format.C;
|
|
||||||
import com.volmit.iris.util.format.Form;
|
|
||||||
import com.volmit.iris.util.io.IO;
|
|
||||||
import com.volmit.iris.util.math.M;
|
|
||||||
import com.volmit.iris.util.math.Position2;
|
|
||||||
import com.volmit.iris.util.math.RollingSequence;
|
|
||||||
import com.volmit.iris.util.math.Spiraler;
|
|
||||||
import com.volmit.iris.util.scheduling.ChronoLatch;
|
|
||||||
import com.volmit.iris.util.scheduling.J;
|
|
||||||
import lombok.Builder;
|
|
||||||
import lombok.Data;
|
|
||||||
import lombok.Getter;
|
|
||||||
import org.bukkit.Bukkit;
|
|
||||||
import org.bukkit.World;
|
|
||||||
import org.bukkit.event.EventHandler;
|
|
||||||
import org.bukkit.event.Listener;
|
|
||||||
import org.bukkit.event.world.WorldUnloadEvent;
|
|
||||||
import org.bukkit.scheduler.BukkitRunnable;
|
|
||||||
|
|
||||||
import java.io.File;
|
|
||||||
import java.io.FileWriter;
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.LinkedHashMap;
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.concurrent.ExecutorService;
|
|
||||||
import java.util.concurrent.Executors;
|
|
||||||
import java.util.concurrent.atomic.AtomicInteger;
|
|
||||||
import java.util.concurrent.atomic.AtomicLong;
|
|
||||||
import java.util.concurrent.locks.ReentrantLock;
|
|
||||||
|
|
||||||
public class DeepSearchPregenerator extends Thread implements Listener {
|
|
||||||
@Getter
|
|
||||||
private static DeepSearchPregenerator instance;
|
|
||||||
private final DeepSearchJob job;
|
|
||||||
private final File destination;
|
|
||||||
private final int maxPosition;
|
|
||||||
private World world;
|
|
||||||
private final ChronoLatch latch;
|
|
||||||
private static AtomicInteger foundChunks;
|
|
||||||
private final AtomicInteger foundLast;
|
|
||||||
private final AtomicInteger foundTotalChunks;
|
|
||||||
private final AtomicLong startTime;
|
|
||||||
private final RollingSequence chunksPerSecond;
|
|
||||||
private final RollingSequence chunksPerMinute;
|
|
||||||
private final AtomicInteger chunkCachePos;
|
|
||||||
private final AtomicInteger chunkCacheSize;
|
|
||||||
private int pos;
|
|
||||||
private final AtomicInteger foundCacheLast;
|
|
||||||
private final AtomicInteger foundCache;
|
|
||||||
private LinkedHashMap<Integer, Position2> chunkCache;
|
|
||||||
private KList<Position2> chunkQueue;
|
|
||||||
private final ReentrantLock cacheLock;
|
|
||||||
|
|
||||||
private static final Map<String, DeepSearchJob> jobs = new HashMap<>();
|
|
||||||
|
|
||||||
public DeepSearchPregenerator(DeepSearchJob job, File destination) {
|
|
||||||
this.job = job;
|
|
||||||
this.chunkCacheSize = new AtomicInteger(); // todo
|
|
||||||
this.chunkCachePos = new AtomicInteger(1000);
|
|
||||||
this.foundCacheLast = new AtomicInteger();
|
|
||||||
this.foundCache = new AtomicInteger();
|
|
||||||
this.cacheLock = new ReentrantLock();
|
|
||||||
this.destination = destination;
|
|
||||||
this.chunkCache = new LinkedHashMap<>();
|
|
||||||
this.maxPosition = new Spiraler(job.getRadiusBlocks() * 2, job.getRadiusBlocks() * 2, (x, z) -> {
|
|
||||||
}).count();
|
|
||||||
this.world = Bukkit.getWorld(job.getWorld().getUID());
|
|
||||||
this.chunkQueue = new KList<>();
|
|
||||||
this.latch = new ChronoLatch(3000);
|
|
||||||
this.startTime = new AtomicLong(M.ms());
|
|
||||||
this.chunksPerSecond = new RollingSequence(10);
|
|
||||||
this.chunksPerMinute = new RollingSequence(10);
|
|
||||||
foundChunks = new AtomicInteger(0);
|
|
||||||
this.foundLast = new AtomicInteger(0);
|
|
||||||
this.foundTotalChunks = new AtomicInteger((int) Math.ceil(Math.pow((2.0 * job.getRadiusBlocks()) / 16, 2)));
|
|
||||||
|
|
||||||
this.pos = 0;
|
|
||||||
jobs.put(job.getWorld().getName(), job);
|
|
||||||
DeepSearchPregenerator.instance = this;
|
|
||||||
}
|
|
||||||
|
|
||||||
@EventHandler
|
|
||||||
public void on(WorldUnloadEvent e) {
|
|
||||||
if (e.getWorld().equals(world)) {
|
|
||||||
interrupt();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void run() {
|
|
||||||
while (!interrupted()) {
|
|
||||||
tick();
|
|
||||||
}
|
|
||||||
try {
|
|
||||||
saveNow();
|
|
||||||
} catch (IOException e) {
|
|
||||||
throw new RuntimeException(e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void tick() {
|
|
||||||
DeepSearchJob job = jobs.get(world.getName());
|
|
||||||
// chunkCache(); //todo finish this
|
|
||||||
if (latch.flip() && !job.paused) {
|
|
||||||
if (cacheLock.isLocked()) {
|
|
||||||
Iris.info("DeepFinder: Caching: " + chunkCachePos.get() + " Of " + chunkCacheSize.get());
|
|
||||||
} else {
|
|
||||||
long eta = computeETA();
|
|
||||||
save();
|
|
||||||
int secondGenerated = foundChunks.get() - foundLast.get();
|
|
||||||
foundLast.set(foundChunks.get());
|
|
||||||
secondGenerated = secondGenerated / 3;
|
|
||||||
chunksPerSecond.put(secondGenerated);
|
|
||||||
chunksPerMinute.put(secondGenerated * 60);
|
|
||||||
Iris.info("DeepFinder: " + C.IRIS + world.getName() + C.RESET + " Searching: " + Form.f(foundChunks.get()) + " of " + Form.f(foundTotalChunks.get()) + " " + Form.f((int) chunksPerSecond.getAverage()) + "/s ETA: " + Form.duration((double) eta, 2));
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
if (foundChunks.get() >= foundTotalChunks.get()) {
|
|
||||||
Iris.info("Completed DeepSearch!");
|
|
||||||
interrupt();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private long computeETA() {
|
|
||||||
return (long) ((foundTotalChunks.get() - foundChunks.get()) / chunksPerSecond.getAverage()) * 1000;
|
|
||||||
// todo broken
|
|
||||||
}
|
|
||||||
|
|
||||||
private final ExecutorService executorService = Executors.newSingleThreadExecutor();
|
|
||||||
|
|
||||||
private void queueSystem(Position2 chunk) {
|
|
||||||
if (chunkQueue.isEmpty()) {
|
|
||||||
for (int limit = 512; limit != 0; limit--) {
|
|
||||||
pos = job.getPosition() + 1;
|
|
||||||
chunkQueue.add(getChunk(pos));
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
//MCAUtil.read();
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
private void findInChunk(World world, int x, int z) throws IOException {
|
|
||||||
int xx = x * 16;
|
|
||||||
int zz = z * 16;
|
|
||||||
Engine engine = IrisToolbelt.access(world).getEngine();
|
|
||||||
for (int i = 0; i < 16; i++) {
|
|
||||||
for (int j = 0; j < 16; j++) {
|
|
||||||
int height = engine.getHeight(xx + i, zz + j);
|
|
||||||
if (height > 300) {
|
|
||||||
File found = new File("plugins" + "iris" + "found.txt");
|
|
||||||
FileWriter writer = new FileWriter(found);
|
|
||||||
if (!found.exists()) {
|
|
||||||
found.createNewFile();
|
|
||||||
}
|
|
||||||
IrisBiome biome = engine.getBiome(xx, engine.getHeight(), zz);
|
|
||||||
Iris.info("Found at! " + xx + ", " + zz + "Biome ID: " + biome.getName() + ", ");
|
|
||||||
writer.write("Biome at: X: " + xx + " Z: " + zz + "Biome ID: " + biome.getName() + ", ");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public Position2 getChunk(int position) {
|
|
||||||
int p = -1;
|
|
||||||
AtomicInteger xx = new AtomicInteger();
|
|
||||||
AtomicInteger zz = new AtomicInteger();
|
|
||||||
Spiraler s = new Spiraler(job.getRadiusBlocks() * 2, job.getRadiusBlocks() * 2, (x, z) -> {
|
|
||||||
xx.set(x);
|
|
||||||
zz.set(z);
|
|
||||||
});
|
|
||||||
|
|
||||||
while (s.hasNext() && p++ < position) {
|
|
||||||
s.next();
|
|
||||||
}
|
|
||||||
|
|
||||||
return new Position2(xx.get(), zz.get());
|
|
||||||
}
|
|
||||||
|
|
||||||
public void save() {
|
|
||||||
J.a(() -> {
|
|
||||||
try {
|
|
||||||
saveNow();
|
|
||||||
} catch (Throwable e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void setPausedDeep(World world) {
|
|
||||||
DeepSearchJob job = jobs.get(world.getName());
|
|
||||||
if (isPausedDeep(world)){
|
|
||||||
job.paused = false;
|
|
||||||
} else {
|
|
||||||
job.paused = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( job.paused) {
|
|
||||||
Iris.info(C.BLUE + "DeepSearch: " + C.IRIS + world.getName() + C.BLUE + " Paused");
|
|
||||||
} else {
|
|
||||||
Iris.info(C.BLUE + "DeepSearch: " + C.IRIS + world.getName() + C.BLUE + " Resumed");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static boolean isPausedDeep(World world) {
|
|
||||||
DeepSearchJob job = jobs.get(world.getName());
|
|
||||||
return job != null && job.isPaused();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void shutdownInstance(World world) throws IOException {
|
|
||||||
Iris.info("DeepSearch: " + C.IRIS + world.getName() + C.BLUE + " Shutting down..");
|
|
||||||
DeepSearchJob job = jobs.get(world.getName());
|
|
||||||
File worldDirectory = new File(Bukkit.getWorldContainer(), world.getName());
|
|
||||||
File deepFile = new File(worldDirectory, "DeepSearch.json");
|
|
||||||
|
|
||||||
if (job == null) {
|
|
||||||
Iris.error("No DeepSearch job found for world: " + world.getName());
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
|
||||||
if (!job.isPaused()) {
|
|
||||||
job.setPaused(true);
|
|
||||||
}
|
|
||||||
save();
|
|
||||||
jobs.remove(world.getName());
|
|
||||||
new BukkitRunnable() {
|
|
||||||
@Override
|
|
||||||
public void run() {
|
|
||||||
while (deepFile.exists()){
|
|
||||||
deepFile.delete();
|
|
||||||
J.sleep(1000);
|
|
||||||
}
|
|
||||||
Iris.info("DeepSearch: " + C.IRIS + world.getName() + C.BLUE + " File deleted and instance closed.");
|
|
||||||
}
|
|
||||||
}.runTaskLater(Iris.instance, 20L);
|
|
||||||
} catch (Exception e) {
|
|
||||||
Iris.error("Failed to shutdown DeepSearch for " + world.getName());
|
|
||||||
e.printStackTrace();
|
|
||||||
} finally {
|
|
||||||
saveNow();
|
|
||||||
interrupt();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public void saveNow() throws IOException {
|
|
||||||
IO.writeAll(this.destination, new Gson().toJson(job));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Data
|
|
||||||
@Builder
|
|
||||||
public static class DeepSearchJob {
|
|
||||||
private World world;
|
|
||||||
@Builder.Default
|
|
||||||
private int radiusBlocks = 5000;
|
|
||||||
@Builder.Default
|
|
||||||
private int position = 0;
|
|
||||||
@Builder.Default
|
|
||||||
boolean paused = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@@ -0,0 +1,114 @@
|
|||||||
|
package com.volmit.iris.core.tools;
|
||||||
|
|
||||||
|
import com.volmit.iris.Iris;
|
||||||
|
import com.volmit.iris.engine.framework.Engine;
|
||||||
|
import com.volmit.iris.util.collection.KList;
|
||||||
|
import com.volmit.iris.util.format.C;
|
||||||
|
import com.volmit.iris.util.format.Form;
|
||||||
|
import com.volmit.iris.util.nbt.mca.Chunk;
|
||||||
|
import com.volmit.iris.util.nbt.mca.MCAFile;
|
||||||
|
import com.volmit.iris.util.nbt.mca.MCAUtil;
|
||||||
|
import com.volmit.iris.util.nbt.tag.CompoundTag;
|
||||||
|
import com.volmit.iris.util.plugin.VolmitSender;
|
||||||
|
import org.bukkit.World;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.concurrent.atomic.AtomicInteger;
|
||||||
|
import java.util.concurrent.atomic.AtomicReferenceArray;
|
||||||
|
|
||||||
|
public class IrisWorldDump {
|
||||||
|
private KList<MCAFile> mcaList;
|
||||||
|
private World world;
|
||||||
|
private File MCADirectory;
|
||||||
|
private AtomicInteger processed;
|
||||||
|
private AtomicInteger totalToProcess;
|
||||||
|
private Engine engine = null;
|
||||||
|
private Boolean IrisWorld;
|
||||||
|
private VolmitSender sender;
|
||||||
|
|
||||||
|
public IrisWorldDump(World world, VolmitSender sender) {
|
||||||
|
this.world = world;
|
||||||
|
this.sender = sender;
|
||||||
|
this.MCADirectory = new File(world.getWorldFolder(), "region");
|
||||||
|
if (Runtime.getRuntime().maxMemory() < 1.5 * estimateMemoryUsage()) {
|
||||||
|
sender.sendMessage(C.YELLOW + "Not enough memory!");
|
||||||
|
sender.sendMessage(C.YELLOW + "- Process amount: " + Form.memSize(Runtime.getRuntime().maxMemory()));
|
||||||
|
sender.sendMessage(C.YELLOW + "- Required amount: " + Form.memSize(estimateMemoryUsage()));
|
||||||
|
//return;
|
||||||
|
}
|
||||||
|
sender.sendMessage("Initializing IrisWorldDump...");
|
||||||
|
|
||||||
|
this.mcaList = new KList<>(getMcaFiles());
|
||||||
|
this.processed = new AtomicInteger(0);
|
||||||
|
this.totalToProcess = new AtomicInteger(0);
|
||||||
|
|
||||||
|
try {
|
||||||
|
this.engine = IrisToolbelt.access(world).getEngine();
|
||||||
|
this.IrisWorld = true;
|
||||||
|
} catch (Exception e) {
|
||||||
|
this.IrisWorld = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void dump() {
|
||||||
|
for (MCAFile mca : mcaList) {
|
||||||
|
AtomicReferenceArray<Chunk> chunks = new AtomicReferenceArray<>(1024);
|
||||||
|
for (int i = 0; i < chunks.length(); i++) {
|
||||||
|
chunks.set(i, mca.getChunks().get(i));
|
||||||
|
}
|
||||||
|
for (int i = 0; i < chunks.length(); i++) {
|
||||||
|
Chunk chunk = chunks.get(i);
|
||||||
|
if (chunk != null) {
|
||||||
|
int CHUNK_HEIGHT = (world.getMaxHeight() - world.getMinHeight());
|
||||||
|
for (int x = 0; x < 16; x++) {
|
||||||
|
for (int z = 0; z < 16; z++) {
|
||||||
|
for (int y = 0; y < CHUNK_HEIGHT; y++) {
|
||||||
|
CompoundTag tag = chunk.getBlockStateAt(x,y,z);
|
||||||
|
int i1 = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private long estimateMemoryUsage() {
|
||||||
|
long size = 0;
|
||||||
|
for (File mca : MCADirectory.listFiles()) {
|
||||||
|
size =+ mca.length();
|
||||||
|
}
|
||||||
|
return size;
|
||||||
|
}
|
||||||
|
|
||||||
|
private List<MCAFile> getMcaFiles() {
|
||||||
|
List<MCAFile> mcaFiles = new ArrayList<>();
|
||||||
|
int l = 0;
|
||||||
|
int f = 0;
|
||||||
|
for (File mca : MCADirectory.listFiles()) {
|
||||||
|
if (mca.getName().endsWith(".mca")) {
|
||||||
|
try {
|
||||||
|
mcaFiles.add(MCAUtil.read(mca));
|
||||||
|
l++;
|
||||||
|
} catch (Exception e) {
|
||||||
|
f++;
|
||||||
|
Iris.error("Failed to read mca file: " + mca.getName(), e);
|
||||||
|
e.printStackTrace(); // todo: debug line
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
sender.sendMessage("Loaded: " + l + " MCA Regions");
|
||||||
|
if (f > 0) {
|
||||||
|
sender.sendMessage(C.RED +"Failed " + C.GRAY + "to load: " + f + " MCA Regions");
|
||||||
|
}
|
||||||
|
return mcaFiles;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -150,8 +150,8 @@ public class Chunk {
|
|||||||
if ((loadFlags & STRUCTURES) != 0) {
|
if ((loadFlags & STRUCTURES) != 0) {
|
||||||
structures = level.getCompoundTag("Structures");
|
structures = level.getCompoundTag("Structures");
|
||||||
}
|
}
|
||||||
if ((loadFlags & (BLOCK_LIGHTS | BLOCK_STATES | SKY_LIGHT)) != 0 && level.containsKey("Sections")) {
|
if ((loadFlags & (BLOCK_LIGHTS | BLOCK_STATES | SKY_LIGHT)) != 0 && level.containsKey("sections")) {
|
||||||
for (CompoundTag section : level.getListTag("Sections").asCompoundTagList()) {
|
for (CompoundTag section : level.getListTag("sections").asCompoundTagList()) {
|
||||||
int sectionIndex = section.getByte("Y");
|
int sectionIndex = section.getByte("Y");
|
||||||
if (sectionIndex > 15 || sectionIndex < 0) {
|
if (sectionIndex > 15 || sectionIndex < 0) {
|
||||||
continue;
|
continue;
|
||||||
|
|||||||
@@ -37,7 +37,8 @@ public class Section {
|
|||||||
|
|
||||||
public Section(CompoundTag sectionRoot, int dataVersion, long loadFlags) {
|
public Section(CompoundTag sectionRoot, int dataVersion, long loadFlags) {
|
||||||
data = sectionRoot;
|
data = sectionRoot;
|
||||||
ListTag<?> rawPalette = sectionRoot.getListTag("Palette");
|
//ListTag<?> rawPalette = sectionRoot.getListTag("palette");
|
||||||
|
ListTag<?> rawPalette = sectionRoot.getCompoundTag("biomes").getListTag("palette");
|
||||||
if (rawPalette == null) {
|
if (rawPalette == null) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|||||||
+2
-1
@@ -42,6 +42,7 @@ public class MCAWrappedPalettedContainer<T> implements MCAPaletteAccess {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void readFromSection(CompoundTag tag) {
|
public void readFromSection(CompoundTag tag) {
|
||||||
container.read(tag.getListTag("Palette"), tag.getLongArrayTag("BlockStates").getValue());
|
//container.read(tag.getListTag("palette"), tag.getLongArrayTag("block_states").getValue());
|
||||||
|
container.read(tag.getCompoundTag("block_states").getListTag("palette"), tag.getCompoundTag("block_states").getLongArrayTag("data").getValue());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user