Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion .github/workflows/buildtools.sh
Original file line number Diff line number Diff line change
Expand Up @@ -41,4 +41,5 @@ checkVersion "1.21.1" "21"
checkVersion "1.21.3" "21"
checkVersion "1.21.4" "21"
checkVersion "1.21.5" "21"
checkVersion "1.21.6" "21"
checkVersion "1.21.8" "21"
checkVersion "1.21.9" "21"
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,7 @@

import dev.imprex.orebfuscator.config.api.Config;
import dev.imprex.orebfuscator.logging.OfcLogger;
import dev.imprex.orebfuscator.util.ChunkPosition;
import dev.imprex.orebfuscator.util.MinecraftVersion;
import dev.imprex.orebfuscator.util.ChunkCacheKey;
import net.imprex.orebfuscator.compatibility.CompatibilityLayer;
import net.imprex.orebfuscator.nms.ReadOnlyChunk;
import net.imprex.orebfuscator.util.ServerVersion;
Expand All @@ -27,7 +26,7 @@ public static void initialize(Plugin plugin, Config config) {
String className = "net.imprex.orebfuscator.compatibility.bukkit.BukkitCompatibilityLayer";
if (ServerVersion.isFolia()) {
className = "net.imprex.orebfuscator.compatibility.folia.FoliaCompatibilityLayer";
} else if (ServerVersion.isPaper() && MinecraftVersion.minorVersion() >= 13) {
} else if (ServerVersion.isPaper()) {
className = "net.imprex.orebfuscator.compatibility.paper.PaperCompatibilityLayer";
}

Expand Down Expand Up @@ -65,8 +64,8 @@ public static void cancelTasks() {
instance.getScheduler().cancelTasks();
}

public static CompletableFuture<ReadOnlyChunk[]> getNeighboringChunks(World world, ChunkPosition position) {
return instance.getNeighboringChunks(world, position);
public static CompletableFuture<ReadOnlyChunk[]> getNeighboringChunks(World world, ChunkCacheKey key) {
return instance.getNeighboringChunks(world, key);
}

public static void close() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

import org.bukkit.World;

import dev.imprex.orebfuscator.util.ChunkPosition;
import dev.imprex.orebfuscator.util.ChunkCacheKey;
import net.imprex.orebfuscator.nms.ReadOnlyChunk;

public interface CompatibilityLayer {
Expand All @@ -13,5 +13,5 @@ public interface CompatibilityLayer {

CompatibilityScheduler getScheduler();

CompletableFuture<ReadOnlyChunk[]> getNeighboringChunks(World world, ChunkPosition position);
CompletableFuture<ReadOnlyChunk[]> getNeighboringChunks(World world, ChunkCacheKey key);
}
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,8 @@
import org.bukkit.plugin.Plugin;

import dev.imprex.orebfuscator.config.api.Config;
import dev.imprex.orebfuscator.util.ChunkCacheKey;
import dev.imprex.orebfuscator.util.ChunkDirection;
import dev.imprex.orebfuscator.util.ChunkPosition;
import net.imprex.orebfuscator.OrebfuscatorNms;
import net.imprex.orebfuscator.nms.ReadOnlyChunk;

Expand All @@ -27,8 +27,8 @@ public BukkitChunkLoader(Plugin plugin, Config config) {
Bukkit.getScheduler().runTaskTimer(plugin, this, 0, 1);
}

public CompletableFuture<ReadOnlyChunk[]> submitRequest(World world, ChunkPosition chunkPosition) {
Request request = new Request(world, chunkPosition);
public CompletableFuture<ReadOnlyChunk[]> submitRequest(World world, ChunkCacheKey key) {
Request request = new Request(world, key);
this.requests.offer(request);
return request.future;
}
Expand All @@ -46,22 +46,22 @@ public void run() {
private class Request implements Runnable {

private final World world;
private final ChunkPosition position;
private final ChunkCacheKey key;

private final CompletableFuture<ReadOnlyChunk[]> future = new CompletableFuture<>();

public Request(World world, ChunkPosition position) {
public Request(World world, ChunkCacheKey key) {
this.world = world;
this.position = position;
this.key = key;
}

@Override
public void run() {
final ReadOnlyChunk[] neighboringChunks = new ReadOnlyChunk[4];

for (ChunkDirection direction : ChunkDirection.values()) {
int chunkX = position.x + direction.getOffsetX();
int chunkZ = position.z + direction.getOffsetZ();
int chunkX = key.x() + direction.getOffsetX();
int chunkZ = key.z() + direction.getOffsetZ();

neighboringChunks[direction.ordinal()] = OrebfuscatorNms.getReadOnlyChunk(world, chunkX, chunkZ);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
import org.bukkit.plugin.Plugin;

import dev.imprex.orebfuscator.config.api.Config;
import dev.imprex.orebfuscator.util.ChunkPosition;
import dev.imprex.orebfuscator.util.ChunkCacheKey;
import net.imprex.orebfuscator.compatibility.CompatibilityLayer;
import net.imprex.orebfuscator.compatibility.CompatibilityScheduler;
import net.imprex.orebfuscator.nms.ReadOnlyChunk;
Expand Down Expand Up @@ -34,7 +34,7 @@ public CompatibilityScheduler getScheduler() {
}

@Override
public CompletableFuture<ReadOnlyChunk[]> getNeighboringChunks(World world, ChunkPosition position) {
return this.chunkLoader.submitRequest(world, position);
public CompletableFuture<ReadOnlyChunk[]> getNeighboringChunks(World world, ChunkCacheKey key) {
return this.chunkLoader.submitRequest(world, key);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,22 +4,22 @@

import org.bukkit.World;

import dev.imprex.orebfuscator.util.ChunkCacheKey;
import dev.imprex.orebfuscator.util.ChunkDirection;
import dev.imprex.orebfuscator.util.ChunkPosition;
import net.imprex.orebfuscator.OrebfuscatorNms;
import net.imprex.orebfuscator.compatibility.CompatibilityLayer;
import net.imprex.orebfuscator.nms.ReadOnlyChunk;

public abstract class AbstractPaperCompatibilityLayer implements CompatibilityLayer {

@Override
public CompletableFuture<ReadOnlyChunk[]> getNeighboringChunks(World world, ChunkPosition position) {
public CompletableFuture<ReadOnlyChunk[]> getNeighboringChunks(World world, ChunkCacheKey key) {
CompletableFuture<?>[] futures = new CompletableFuture<?>[4];
ReadOnlyChunk[] neighboringChunks = new ReadOnlyChunk[4];

for (ChunkDirection direction : ChunkDirection.values()) {
int chunkX = position.x + direction.getOffsetX();
int chunkZ = position.z + direction.getOffsetZ();
int chunkX = key.x() + direction.getOffsetX();
int chunkZ = key.z() + direction.getOffsetZ();
int index = direction.ordinal();

futures[index] = world.getChunkAtAsync(chunkX, chunkZ).thenAccept(chunk -> {
Expand Down
53 changes: 48 additions & 5 deletions orebfuscator-core/pom.xml
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>

<parent>
<groupId>net.imprex</groupId>
<artifactId>orebfuscator</artifactId>
Expand All @@ -25,17 +28,57 @@
<scope>provided</scope>
</dependency>

<!-- Third-Party -->
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>${dependency.guava.version}</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.spigotmc</groupId>
<artifactId>spigot-api</artifactId>
<version>${dependency.bukkit.version}</version>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
<version>${dependency.gson.version}</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.yaml</groupId>
<artifactId>snakeyaml</artifactId>
<version>${dependency.snakeyaml.version}</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.joml</groupId>
<artifactId>joml</artifactId>
<version>${dependency.joml.version}</version>
<scope>compile</scope>
<scope>provided</scope>
</dependency>
<!--<dependency>
<groupId>org.lz4</groupId>
<artifactId>lz4-java</artifactId>
<version>${dependency.lz4.version}</version>
<scope>compile</scope>
</dependency>-->
</dependencies>

<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<configuration>
<relocations>
<relocation>
<pattern>com.google.common</pattern>
<shadedPattern>dev.imprex.shaded.com.google.common</shadedPattern>
</relocation>
<relocation>
<pattern>org.yaml.snakeyaml</pattern>
<shadedPattern>dev.imprex.shaded.org.yaml.snakeyaml</shadedPattern>
</relocation>
</relocations>
</configuration>
</plugin>
</plugins>
</build>
</project>
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,8 @@
import java.util.Objects;
import java.util.concurrent.locks.ReadWriteLock;
import java.util.concurrent.locks.ReentrantReadWriteLock;

import dev.imprex.orebfuscator.config.api.CacheConfig;
import dev.imprex.orebfuscator.util.ChunkPosition;
import dev.imprex.orebfuscator.util.ChunkCacheKey;
import dev.imprex.orebfuscator.util.SimpleCache;

public abstract class AbstractRegionFileCache<T> {
Expand All @@ -31,16 +30,16 @@ public AbstractRegionFileCache(CacheConfig cacheConfig) {

protected abstract void closeRegionFile(T t) throws IOException;

protected abstract DataInputStream createInputStream(T t, ChunkPosition key) throws IOException;
protected abstract DataInputStream createInputStream(T t, ChunkCacheKey key) throws IOException;

protected abstract DataOutputStream createOutputStream(T t, ChunkPosition key) throws IOException;
protected abstract DataOutputStream createOutputStream(T t, ChunkCacheKey key) throws IOException;

public final DataInputStream createInputStream(ChunkPosition key) throws IOException {
public final DataInputStream createInputStream(ChunkCacheKey key) throws IOException {
T t = this.get(this.cacheConfig.regionFile(key));
return t != null ? this.createInputStream(t, key) : null;
}

public final DataOutputStream createOutputStream(ChunkPosition key) throws IOException {
public final DataOutputStream createOutputStream(ChunkCacheKey key) throws IOException {
T t = this.get(this.cacheConfig.regionFile(key));
return t != null ? this.createOutputStream(t, key) : null;
}
Expand Down Expand Up @@ -77,8 +76,15 @@ protected final T get(Path path) throws IOException {

this.lock.writeLock().lock();
try {
this.regionFiles.putIfAbsent(path, t);
return this.regionFiles.get(path);
T previous = this.regionFiles.putIfAbsent(path, t);

if (previous != null) {
// some other thread was faster, close fd
closeRegionFile(t);
return previous;
}

return t;
} finally {
this.lock.writeLock().unlock();
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,51 +1,51 @@
package dev.imprex.orebfuscator.chunk;

import java.util.Arrays;

import dev.imprex.orebfuscator.interop.ChunkPacketAccessor;
import dev.imprex.orebfuscator.interop.WorldAccessor;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.PooledByteBufAllocator;
import io.netty.buffer.Unpooled;
import net.imprex.orebfuscator.chunk.ChunkStruct;
import net.imprex.orebfuscator.util.HeightAccessor;

public class Chunk implements AutoCloseable {

public static Chunk fromChunkStruct(ChunkStruct chunkStruct) {
return new Chunk(chunkStruct);
}
private final ChunkFactory factory;

private final int chunkX;
private final int chunkZ;

private final HeightAccessor heightAccessor;
private final WorldAccessor worldAccessor;
private final ChunkSectionHolder[] sections;

private final ByteBuf inputBuffer;
private final ByteBuf outputBuffer;

private Chunk(ChunkStruct chunkStruct) {
this.chunkX = chunkStruct.chunkX;
this.chunkZ = chunkStruct.chunkZ;
Chunk(ChunkFactory factory, ChunkPacketAccessor packet) {
this.factory = factory;

this.chunkX = packet.chunkX();
this.chunkZ = packet.chunkZ();

this.heightAccessor = HeightAccessor.get(chunkStruct.world);
this.sections = new ChunkSectionHolder[this.heightAccessor.getSectionCount()];
this.worldAccessor = packet.world();
this.sections = new ChunkSectionHolder[this.worldAccessor.getSectionCount()];

this.inputBuffer = Unpooled.wrappedBuffer(chunkStruct.data);
this.outputBuffer = PooledByteBufAllocator.DEFAULT.heapBuffer(chunkStruct.data.length);
byte[] data = packet.data();
this.inputBuffer = Unpooled.wrappedBuffer(data);
this.outputBuffer = PooledByteBufAllocator.DEFAULT.heapBuffer(data.length);

for (int sectionIndex = 0; sectionIndex < this.sections.length; sectionIndex++) {
if (chunkStruct.sectionMask.get(sectionIndex)) {
if (packet.isSectionPresent(sectionIndex)) {
this.sections[sectionIndex] = new ChunkSectionHolder();
}
}
}

public int getSectionCount() {
return this.sections.length;
public WorldAccessor world() {
return worldAccessor;
}

public HeightAccessor getHeightAccessor() {
return heightAccessor;
public int getSectionCount() {
return this.sections.length;
}

public ChunkSection getSection(int index) {
Expand All @@ -58,7 +58,7 @@ public ChunkSection getSection(int index) {

public int getBlockState(int x, int y, int z) {
if (x >> 4 == this.chunkX && z >> 4 == this.chunkZ) {
ChunkSectionHolder chunkSection = this.sections[this.heightAccessor.getSectionIndex(y)];
ChunkSectionHolder chunkSection = this.sections[this.worldAccessor.getSectionIndex(y)];
if (chunkSection != null) {
return chunkSection.data[ChunkSection.positionToIndex(x & 0xF, y & 0xF, z & 0xF)];
}
Expand All @@ -74,8 +74,11 @@ public byte[] finalizeOutput() {
chunkSection.write();
}
}

this.outputBuffer.writeBytes(this.inputBuffer);
return Arrays.copyOfRange(this.outputBuffer.array(), this.outputBuffer.arrayOffset(),

return Arrays.copyOfRange(
this.outputBuffer.array(), this.outputBuffer.arrayOffset(),
this.outputBuffer.arrayOffset() + this.outputBuffer.readableBytes());
}

Expand All @@ -98,7 +101,7 @@ private void skipBiomePalettedContainer() {

int expectedDataLength = SimpleVarBitBuffer.calculateArraySize(bitsPerValue, 64);

if (ChunkCapabilities.hasLongArrayLengthField()) {
if (factory.versionFlags().hasLongArrayLengthField()) {
int dataLength = ByteBufUtil.readVarInt(this.inputBuffer);
if (expectedDataLength != dataLength) {
throw new IndexOutOfBoundsException(
Expand All @@ -111,20 +114,20 @@ private void skipBiomePalettedContainer() {

private class ChunkSectionHolder {

public ChunkSection chunkSection;
public final ChunkSection chunkSection;

public final int[] data;
public final int extraOffset;

private int extraBytes;

public ChunkSectionHolder() {
this.chunkSection = new ChunkSection();
this.chunkSection = new ChunkSection(factory);

this.data = this.chunkSection.read(inputBuffer);
this.extraOffset = inputBuffer.readerIndex();

if (ChunkCapabilities.hasBiomePalettedContainer()) {
if (factory.versionFlags().hasBiomePalettedContainer()) {
skipBiomePalettedContainer();
this.extraBytes = inputBuffer.readerIndex() - this.extraOffset;
}
Expand Down
Loading