diff --git a/pom.xml b/pom.xml
index 5551716..1c055f3 100644
--- a/pom.xml
+++ b/pom.xml
@@ -7,16 +7,4 @@
org.example
Server
1.0-SNAPSHOT
-
-
-
- org.apache.maven.plugins
- maven-compiler-plugin
-
-
- 8
-
-
-
-
\ No newline at end of file
diff --git a/src/main/java/net/minecraft/world/level/storage/AnvilConverter.java b/src/main/java/net/minecraft/world/level/storage/AnvilConverter.java
index eebb5f7..b71bea5 100644
--- a/src/main/java/net/minecraft/world/level/storage/AnvilConverter.java
+++ b/src/main/java/net/minecraft/world/level/storage/AnvilConverter.java
@@ -8,15 +8,31 @@
import java.io.File;
+import java.util.concurrent.TimeUnit;
public class AnvilConverter {
public static void main(String[] args) {
-
- if (args.length != 2) {
+ if (args.length < 2) {
printUsageAndExit();
}
+ // Handle optional third argument for number of threads
+ int numThreads = 1;
+ if (args.length == 3) {
+ try {
+ numThreads = Integer.parseInt(args[2]);
+ if (numThreads < 0) {
+ throw new NumberFormatException();
+ }
+ } catch (NumberFormatException e) {
+ System.err.println("Invalid number of threads: " + args[2]);
+ System.out.println("");
+ printUsageAndExit();
+ return;
+ }
+ }
+
File baseFolder;
try {
baseFolder = new File(args[0]);
@@ -40,7 +56,40 @@ public static void main(String[] args) {
return;
}
+ // Remove old .mca region files if they exist (they will be regenerated)
+ File regionFolder = new File(baseFolder, args[1] + "/region");
+ int regionCount = 0;
+ if (regionFolder.exists()) {
+ File[] regionFiles = regionFolder.listFiles();
+ if (regionFiles != null) {
+ for (File regionFile : regionFiles) {
+ if (regionFile.getName().endsWith(".mca")) {
+ regionFile.delete();
+ regionCount++;
+ }
+ }
+ }
+ }
+ if (regionCount > 0) {
+ System.out.println("Deleted " + regionCount + " old mca region files");
+ }
+
+ // Rename level.dat_mcr to level.dat
+ File levelDatMcr = new File(baseFolder, args[1] + "/level.dat_mcr");
+ File levelDat = new File(baseFolder, args[1] + "/level.dat");
+ if (levelDatMcr.exists()) {
+ if (levelDat.exists()) {
+ levelDat.delete();
+ }
+ levelDatMcr.renameTo(levelDat);
+ System.out.println("Renamed level.dat_mcr to level.dat");
+ }
+
System.out.println("Converting map!");
+
+ // Duration duration = new Duration();
+ long startTime = System.currentTimeMillis();
+
storage.convertLevel(args[1], new ProgressListener() {
private long timeStamp = System.currentTimeMillis();
@@ -59,7 +108,25 @@ public void progressStagePercentage(int i) {
public void progressStage(String string) {
}
- });
+ }, numThreads);
+
+ long endTime = System.currentTimeMillis();
+ long durationMillis = endTime - startTime;
+
+ // Calculate minutes, seconds, and milliseconds
+ long hours = TimeUnit.MILLISECONDS.toHours(durationMillis);
+ long minutes = TimeUnit.MILLISECONDS.toMinutes(durationMillis) -
+ TimeUnit.HOURS.toMinutes(hours);
+ long seconds = TimeUnit.MILLISECONDS.toSeconds(durationMillis) -
+ TimeUnit.MINUTES.toSeconds(minutes);
+ long millis = durationMillis - TimeUnit.MINUTES.toMillis(minutes) -
+ TimeUnit.SECONDS.toMillis(seconds);
+
+ // Format and print the duration time
+ String duration = String.format("%02d:%02d:%02d.%03d", hours, minutes, seconds, millis);
+ System.out.println("Conversion completed in: " + duration);
+
+
System.out.println("Done!");
System.out.println("To revert, replace level.dat with level.dat_mcr. Old mcr region files have not been modified.");
}
diff --git a/src/main/java/net/minecraft/world/level/storage/AnvilLevelStorageSource.java b/src/main/java/net/minecraft/world/level/storage/AnvilLevelStorageSource.java
index 3a42ca3..b01613b 100644
--- a/src/main/java/net/minecraft/world/level/storage/AnvilLevelStorageSource.java
+++ b/src/main/java/net/minecraft/world/level/storage/AnvilLevelStorageSource.java
@@ -6,14 +6,18 @@
* Don't do evil.
*/
-import java.io.*;
-import java.util.ArrayList;
-
+import com.mojang.nbt.CompoundTag;
+import com.mojang.nbt.NbtIo;
import net.minecraft.world.level.biome.BiomeSource;
-import net.minecraft.world.level.chunk.storage.*;
+import net.minecraft.world.level.chunk.storage.OldChunkStorage;
import net.minecraft.world.level.chunk.storage.OldChunkStorage.OldLevelChunk;
+import net.minecraft.world.level.chunk.storage.RegionFile;
-import com.mojang.nbt.*;
+import java.io.*;
+import java.util.ArrayList;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.concurrent.atomic.AtomicInteger;
public class AnvilLevelStorageSource {
@@ -79,7 +83,7 @@ private void saveDataTag(String levelId, CompoundTag dataTag) {
}
}
- public boolean convertLevel(String levelId, ProgressListener progress) {
+ public boolean convertLevel(String levelId, ProgressListener progress, int threadCount) {
progress.progressStagePercentage(0);
@@ -109,12 +113,23 @@ public boolean convertLevel(String levelId, ProgressListener progress) {
CompoundTag levelData = getDataTagFor(levelId);
+ //int threadCount = Runtime.getRuntime().availableProcessors();
+
+ // Print in what mode we are running
+ if (threadCount == 0) {
+ System.out.println("Running sequentially");
+ } else {
+ System.out.println("Running " + threadCount + " threads in parallel");
+ }
+
+ AtomicInteger currentCount = new AtomicInteger(0);
+
// convert normal world
- convertRegions(new File(baseFolder, "region"), normalRegions, null, 0, totalCount, progress);
+ convertRegions(new File(baseFolder, "region"), normalRegions, null, currentCount, totalCount, progress, threadCount);
// convert hell world
- convertRegions(new File(netherFolder, "region"), netherRegions, null, normalRegions.size(), totalCount, progress);
+ convertRegions(new File(netherFolder, "region"), netherRegions, null, currentCount, totalCount, progress, threadCount);
// convert end world
- convertRegions(new File(enderFolder, "region"), enderRegions, null, normalRegions.size() + netherRegions.size(), totalCount, progress);
+ convertRegions(new File(enderFolder, "region"), enderRegions, null, currentCount, totalCount, progress, threadCount);
makeMcrLevelDatBackup(levelId);
@@ -143,19 +158,40 @@ private void makeMcrLevelDatBackup(String levelId) {
}
}
- private void convertRegions(File baseFolder, ArrayList regionFiles, BiomeSource biomeSource, int currentCount, int totalCount, ProgressListener progress) {
+ private void convertRegions(File baseFolder, ArrayList regionFiles, BiomeSource biomeSource, AtomicInteger currentCount, int totalCount, ProgressListener progress, int numThreads) {
+ // Create an ExecutorService with a fixed thread pool
- for (File regionFile : regionFiles) {
- convertRegion(baseFolder, regionFile, biomeSource, currentCount, totalCount, progress);
+ if (numThreads <= 0) {
+ //Program is being run sequentially
+ for (File regionFile : regionFiles) {
+ convertRegion(baseFolder, regionFile, biomeSource, currentCount, totalCount, progress);
+ }
+ } else {
+ //Program is being run in parallel
+ ExecutorService executorService = Executors.newFixedThreadPool(numThreads);
+
+ // Submit tasks for each region file
+ for (File regionFile : regionFiles) {
+ executorService.submit(() -> {
+ convertRegion(baseFolder, regionFile, biomeSource, currentCount, totalCount, progress);
+ });
+ }
- currentCount++;
- int percent = (int) Math.round(100.0d * (double) currentCount / (double) totalCount);
- progress.progressStagePercentage(percent);
+ // Shut down the executor service and wait for all tasks to complete
+ executorService.shutdown();
+ try {
+ executorService.awaitTermination(Long.MAX_VALUE, java.util.concurrent.TimeUnit.NANOSECONDS);
+ } catch (InterruptedException e) {
+ e.printStackTrace();
+ }
}
+ // Update progress after all tasks are completed
+ int percent = (int) Math.round(100.0d * (double) totalCount / (double) totalCount);
+ progress.progressStagePercentage(percent);
}
- private void convertRegion(File baseFolder, File regionFile, BiomeSource biomeSource, int currentCount, int totalCount, ProgressListener progress) {
+ private void convertRegion(File baseFolder, File regionFile, BiomeSource biomeSource, AtomicInteger currentCounter, int totalCount, ProgressListener progress) {
try {
String name = regionFile.getName();
@@ -189,6 +225,10 @@ private void convertRegion(File baseFolder, File regionFile, BiomeSource biomeSo
}
}
}
+
+ // Update progress
+ int currentCount = currentCounter.get();
+
int basePercent = (int) Math.round(100.0d * (double) (currentCount * 1024) / (double) (totalCount * 1024));
int newPercent = (int) Math.round(100.0d * (double) ((x + 1) * 32 + currentCount * 1024) / (double) (totalCount * 1024));
if (newPercent > basePercent) {
@@ -196,6 +236,9 @@ private void convertRegion(File baseFolder, File regionFile, BiomeSource biomeSo
}
}
+ // Increment the counter
+ currentCounter.incrementAndGet();
+
regionSource.close();
regionDest.close();
} catch (IOException e) {