Skip to content

Commit

Permalink
more work
Browse files Browse the repository at this point in the history
  • Loading branch information
pop4959 committed Feb 1, 2024
1 parent 0e421d5 commit 2d2ece3
Show file tree
Hide file tree
Showing 5 changed files with 88 additions and 103 deletions.
5 changes: 1 addition & 4 deletions common/src/main/java/org/popcraft/chunky/GenerationTask.java
Original file line number Diff line number Diff line change
Expand Up @@ -116,12 +116,9 @@ private synchronized void update(final int chunkX, final int chunkZ, final boole

@Override
public void run() {
final long now = System.currentTimeMillis();
chunkIterator.postInitialization();
final long after = System.currentTimeMillis();
System.out.println(after - now);
final String poolThreadName = Thread.currentThread().getName();
Thread.currentThread().setName(String.format("Chunky-%s Thread", selection.world().getName()));
chunkIterator.process();
final Semaphore working = new Semaphore(MAX_WORKING_COUNT);
final boolean forceLoadExistingChunks = chunky.getConfig().isForceLoadExistingChunks();
startTime.set(System.currentTimeMillis());
Expand Down
22 changes: 2 additions & 20 deletions common/src/main/java/org/popcraft/chunky/command/TrimCommand.java
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,7 @@ public void execute(final Sender sender, final CommandArguments arguments) {
if (regionPath.isPresent()) {
try (final Stream<Path> files = Files.list(regionPath.get())) {
final List<Path> regions = files
.filter(file -> tryRegionCoordinate(file.getFileName().toString()).isPresent())
.filter(file -> ChunkCoordinate.fromRegionFile(file.getFileName().toString()).isPresent())
.toList();
final long totalRegions = regions.size();
for (final Path region: regions) {
Expand Down Expand Up @@ -135,7 +135,7 @@ public void execute(final Sender sender, final CommandArguments arguments) {
}

private int checkRegion(final World world, final String regionFileName, final Shape shape, final boolean inside, final boolean inhabitedTimeCheck, final int inhabitedTime) {
final Optional<ChunkCoordinate> regionCoordinate = tryRegionCoordinate(regionFileName);
final Optional<ChunkCoordinate> regionCoordinate = ChunkCoordinate.fromRegionFile(regionFileName);
if (regionCoordinate.isEmpty()) {
return 0;
}
Expand All @@ -148,24 +148,6 @@ private int checkRegion(final World world, final String regionFileName, final Sh
}
}

private Optional<ChunkCoordinate> tryRegionCoordinate(final String regionFileName) {
if (!regionFileName.startsWith("r.")) {
return Optional.empty();
}
final int extension = regionFileName.indexOf(".mca");
if (extension < 2) {
return Optional.empty();
}
final String regionCoordinates = regionFileName.substring(2, extension);
final int separator = regionCoordinates.indexOf('.');
final Optional<Integer> regionX = Input.tryInteger(regionCoordinates.substring(0, separator));
final Optional<Integer> regionZ = Input.tryInteger(regionCoordinates.substring(separator + 1));
if (regionX.isPresent() && regionZ.isPresent()) {
return Optional.of(new ChunkCoordinate(regionX.get(), regionZ.get()));
}
return Optional.empty();
}

private boolean shouldDeleteRegion(final Shape shape, final boolean inside, final int chunkX, final int chunkZ) {
for (int offsetX = 0; offsetX < 32; ++offsetX) {
for (int offsetZ = 0; offsetZ < 32; ++offsetZ) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,6 @@ public interface ChunkIterator extends Iterator<ChunkCoordinate> {

String name();

default void postInitialization() {
default void process() {
}
}
Original file line number Diff line number Diff line change
@@ -1,42 +1,61 @@
package org.popcraft.chunky.iterator;

import org.popcraft.chunky.Selection;
import org.popcraft.chunky.nbt.IntTag;
import org.popcraft.chunky.nbt.StringTag;
import org.popcraft.chunky.nbt.util.Chunk;
import org.popcraft.chunky.nbt.util.RegionFile;
import org.popcraft.chunky.util.ChunkCoordinate;
import org.popcraft.chunky.util.Hilbert;
import org.popcraft.chunky.util.Input;
import org.popcraft.chunky.util.Parameter;

import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.StandardOpenOption;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.NoSuchElementException;
import java.util.Optional;
import java.util.Queue;
import java.util.Set;
import java.util.concurrent.atomic.AtomicLong;
import java.util.stream.Stream;

public class WorldChunkIterator implements ChunkIterator {
private final Selection selection;
private final int minRegionX;
private final int minRegionZ;
private final int maxRegionX;
private final int maxRegionZ;
private final int minChunkX;
private final int minChunkZ;
private final int maxChunkX;
private final int maxChunkZ;
private final Queue<ChunkCoordinate> chunks;
private final AtomicLong total = new AtomicLong();
private final String fileName;
private final Path savePath;
private final Path regionPath;
private final String name;

public WorldChunkIterator(final Selection selection) {
final int centerRegionX = selection.centerRegionX();
final int centerRegionZ = selection.centerRegionZ();
final int radiusRegionsX = selection.radiusRegionsX();
final int radiusRegionsZ = selection.radiusRegionsZ();
this.minRegionX = centerRegionX - radiusRegionsX;
this.minRegionZ = centerRegionZ - radiusRegionsZ;
this.maxRegionX = centerRegionX + radiusRegionsX;
this.maxRegionZ = centerRegionZ + radiusRegionsZ;
final int centerChunkX = selection.centerChunkX();
final int centerChunkZ = selection.centerChunkZ();
final int radiusChunksX = selection.radiusChunksX();
final int radiusChunksZ = selection.radiusChunksZ();
this.minChunkX = centerChunkX - radiusChunksX;
this.minChunkZ = centerChunkZ - radiusChunksZ;
this.maxChunkX = centerChunkX + radiusChunksX;
this.maxChunkZ = centerChunkZ + radiusChunksZ;
this.chunks = new LinkedList<>();
final String worldName = selection.world().getName();
this.fileName = worldName.substring(worldName.indexOf(':') + 1);
this.name = Parameter.of(PatternType.CSV, fileName).toString();
this.selection = selection;
final String saveFile = worldName.substring(worldName.indexOf(':') + 1);
this.savePath = selection.chunky().getConfig().getDirectory().resolve(String.format("%s.csv", saveFile));
this.regionPath = selection.world().getRegionDirectory().orElse(null);
this.name = Parameter.of(PatternType.CSV, saveFile).toString();
}

@Override
Expand All @@ -63,78 +82,46 @@ public String name() {
}

@Override
public void postInitialization() {
final Path filePath = selection.chunky().getConfig().getDirectory().resolve(String.format("%s.csv", fileName));
final StringBuilder csvData = new StringBuilder();
final Optional<Path> regionPath = selection.world().getRegionDirectory();
try {
if (regionPath.isPresent()) {
try (final Stream<Path> files = Files.list(regionPath.get())) {
final List<Path> regions = files
.filter(file -> tryRegionCoordinate(file.getFileName().toString()).isPresent())
.toList();
final long totalRegions = regions.size();
System.out.println(totalRegions);
for (final Path region : regions) {
System.out.println(region.getFileName().toString());
final RegionFile regionFile = new RegionFile(region.toFile());
final Set<ChunkCoordinate> regionChunks = new HashSet<>();
for (final Chunk chunk : regionFile.getChunks()) {
final boolean generated = chunk.getData().getString("Status")
.map(StringTag::value)
.map(status -> "minecraft:full".equals(status) || "full".equals(status))
.orElse(false);
if (generated) {
final Optional<IntTag> xPos = chunk.getData().getInt("xPos");
final Optional<IntTag> zPos = chunk.getData().getInt("zPos");
if (xPos.isPresent() && zPos.isPresent()) {
final int x = xPos.get().value();
final int z = zPos.get().value();
regionChunks.add(new ChunkCoordinate(x, z));
}
}
}
if (!regionChunks.isEmpty()) {
final ChunkCoordinate regionCoordinates = tryRegionCoordinate(region.getFileName().toString()).orElse(null);
if (regionCoordinates == null) {
throw new IllegalStateException("Region coordinates could not be determined for region file");
}
final int regionX = regionCoordinates.x();
final int regionZ = regionCoordinates.z();
for (final ChunkCoordinate offset : Hilbert.chunkCoordinateOffsets()) {
final ChunkCoordinate chunkCoordinate = new ChunkCoordinate((regionX << 5) + offset.x(), (regionZ << 5) + offset.z());
if (regionChunks.contains(chunkCoordinate)) {
chunks.add(chunkCoordinate);
csvData.append(chunkCoordinate.x()).append(',').append(chunkCoordinate.z()).append('\n');
total.incrementAndGet();
}
}
}
public void process() {
if (regionPath == null) {
return;
}
final StringBuilder saveData = new StringBuilder();
try (final Stream<Path> files = Files.list(regionPath)) {
final List<Path> regions = files
.filter(file -> {
final ChunkCoordinate regionCoordinate = ChunkCoordinate.fromRegionFile(file.getFileName().toString())
.orElse(null);
return regionCoordinate != null && regionCoordinate.x() >= minRegionX && regionCoordinate.x() <= maxRegionX && regionCoordinate.z() >= minRegionZ && regionCoordinate.z() <= maxRegionZ;
})
.toList();
for (final Path region : regions) {
final ChunkCoordinate regionCoordinate = ChunkCoordinate.fromRegionFile(region.getFileName().toString())
.orElseThrow(IllegalStateException::new);
final int regionX = regionCoordinate.x();
final int regionZ = regionCoordinate.z();
final RegionFile regionFile = new RegionFile(region.toFile());
for (final ChunkCoordinate offset : Hilbert.chunkCoordinateOffsets()) {
final ChunkCoordinate chunkCoordinate = new ChunkCoordinate((regionX << 5) + offset.x(), (regionZ << 5) + offset.z());
if (chunkCoordinate.x() < minChunkX || chunkCoordinate.x() > maxChunkX || chunkCoordinate.z() < minChunkZ || chunkCoordinate.z() > maxChunkZ) {
continue;
}
regionFile.getChunk(chunkCoordinate.x(), chunkCoordinate.z()).ifPresent(chunk -> {
final boolean generated = chunk.getData().getString("Status")
.map(StringTag::value)
.map(status -> "minecraft:full".equals(status) || "full".equals(status))
.orElse(false);
if (generated) {
chunks.add(chunkCoordinate);
saveData.append(chunkCoordinate.x()).append(',').append(chunkCoordinate.z()).append('\n');
total.incrementAndGet();
}
});
}
}
Files.writeString(filePath, csvData, StandardOpenOption.CREATE, StandardOpenOption.TRUNCATE_EXISTING);
Files.writeString(savePath, saveData, StandardOpenOption.CREATE, StandardOpenOption.TRUNCATE_EXISTING);
} catch (IOException e) {
e.printStackTrace();
}
System.out.println(total.get());
}

private Optional<ChunkCoordinate> tryRegionCoordinate(final String regionFileName) {
if (!regionFileName.startsWith("r.")) {
return Optional.empty();
}
final int extension = regionFileName.indexOf(".mca");
if (extension < 2) {
return Optional.empty();
}
final String regionCoordinates = regionFileName.substring(2, extension);
final int separator = regionCoordinates.indexOf('.');
final Optional<Integer> regionX = Input.tryInteger(regionCoordinates.substring(0, separator));
final Optional<Integer> regionZ = Input.tryInteger(regionCoordinates.substring(separator + 1));
if (regionX.isPresent() && regionZ.isPresent()) {
return Optional.of(new ChunkCoordinate(regionX.get(), regionZ.get()));
}
return Optional.empty();
}
}
19 changes: 19 additions & 0 deletions common/src/main/java/org/popcraft/chunky/util/ChunkCoordinate.java
Original file line number Diff line number Diff line change
@@ -1,8 +1,27 @@
package org.popcraft.chunky.util;

import java.util.Objects;
import java.util.Optional;

public record ChunkCoordinate(int x, int z) implements Comparable<ChunkCoordinate> {
public static Optional<ChunkCoordinate> fromRegionFile(final String regionFileName) {
if (!regionFileName.startsWith("r.")) {
return Optional.empty();
}
final int extension = regionFileName.indexOf(".mca");
if (extension < 2) {
return Optional.empty();
}
final String regionCoordinates = regionFileName.substring(2, extension);
final int separator = regionCoordinates.indexOf('.');
final Optional<Integer> regionX = Input.tryInteger(regionCoordinates.substring(0, separator));
final Optional<Integer> regionZ = Input.tryInteger(regionCoordinates.substring(separator + 1));
if (regionX.isPresent() && regionZ.isPresent()) {
return Optional.of(new ChunkCoordinate(regionX.get(), regionZ.get()));
}
return Optional.empty();
}

@Override
public int compareTo(final ChunkCoordinate o) {
return this.x == o.x ? Integer.compare(this.z, o.z) : Integer.compare(this.x, o.x);
Expand Down

0 comments on commit 2d2ece3

Please sign in to comment.