Skip to content

Commit e70042a

Browse files
authored
Platform independent core (#453)
feat: made core module platform-independent feat: added new reflection library feat: added block tag support feat: added dynamic config lookup with support for patch versions feat: use vose's alias method for WeightedRandom feat: moved region file state management outside of nms feat: moved config/chunk package into core module test: add probabilistic unit tests for new WeightedRandom feat: added support for modded blocks fix: minor region file cache bug feat: add support for 1.21.9
1 parent c018c05 commit e70042a

File tree

199 files changed

+7841
-3474
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

199 files changed

+7841
-3474
lines changed

.github/workflows/buildtools.sh

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,4 +41,5 @@ checkVersion "1.21.1" "21"
4141
checkVersion "1.21.3" "21"
4242
checkVersion "1.21.4" "21"
4343
checkVersion "1.21.5" "21"
44-
checkVersion "1.21.6" "21"
44+
checkVersion "1.21.8" "21"
45+
checkVersion "1.21.9" "21"

orebfuscator-compatibility/orebfuscator-compatibility-api/src/main/java/net/imprex/orebfuscator/OrebfuscatorCompatibility.java

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,7 @@
99

1010
import dev.imprex.orebfuscator.config.api.Config;
1111
import dev.imprex.orebfuscator.logging.OfcLogger;
12-
import dev.imprex.orebfuscator.util.ChunkPosition;
13-
import dev.imprex.orebfuscator.util.MinecraftVersion;
12+
import dev.imprex.orebfuscator.util.ChunkCacheKey;
1413
import net.imprex.orebfuscator.compatibility.CompatibilityLayer;
1514
import net.imprex.orebfuscator.nms.ReadOnlyChunk;
1615
import net.imprex.orebfuscator.util.ServerVersion;
@@ -27,7 +26,7 @@ public static void initialize(Plugin plugin, Config config) {
2726
String className = "net.imprex.orebfuscator.compatibility.bukkit.BukkitCompatibilityLayer";
2827
if (ServerVersion.isFolia()) {
2928
className = "net.imprex.orebfuscator.compatibility.folia.FoliaCompatibilityLayer";
30-
} else if (ServerVersion.isPaper() && MinecraftVersion.minorVersion() >= 13) {
29+
} else if (ServerVersion.isPaper()) {
3130
className = "net.imprex.orebfuscator.compatibility.paper.PaperCompatibilityLayer";
3231
}
3332

@@ -65,8 +64,8 @@ public static void cancelTasks() {
6564
instance.getScheduler().cancelTasks();
6665
}
6766

68-
public static CompletableFuture<ReadOnlyChunk[]> getNeighboringChunks(World world, ChunkPosition position) {
69-
return instance.getNeighboringChunks(world, position);
67+
public static CompletableFuture<ReadOnlyChunk[]> getNeighboringChunks(World world, ChunkCacheKey key) {
68+
return instance.getNeighboringChunks(world, key);
7069
}
7170

7271
public static void close() {

orebfuscator-compatibility/orebfuscator-compatibility-api/src/main/java/net/imprex/orebfuscator/compatibility/CompatibilityLayer.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44

55
import org.bukkit.World;
66

7-
import dev.imprex.orebfuscator.util.ChunkPosition;
7+
import dev.imprex.orebfuscator.util.ChunkCacheKey;
88
import net.imprex.orebfuscator.nms.ReadOnlyChunk;
99

1010
public interface CompatibilityLayer {
@@ -13,5 +13,5 @@ public interface CompatibilityLayer {
1313

1414
CompatibilityScheduler getScheduler();
1515

16-
CompletableFuture<ReadOnlyChunk[]> getNeighboringChunks(World world, ChunkPosition position);
16+
CompletableFuture<ReadOnlyChunk[]> getNeighboringChunks(World world, ChunkCacheKey key);
1717
}

orebfuscator-compatibility/orebfuscator-compatibility-bukkit/src/main/java/net/imprex/orebfuscator/compatibility/bukkit/BukkitChunkLoader.java

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,8 @@
1010
import org.bukkit.plugin.Plugin;
1111

1212
import dev.imprex.orebfuscator.config.api.Config;
13+
import dev.imprex.orebfuscator.util.ChunkCacheKey;
1314
import dev.imprex.orebfuscator.util.ChunkDirection;
14-
import dev.imprex.orebfuscator.util.ChunkPosition;
1515
import net.imprex.orebfuscator.OrebfuscatorNms;
1616
import net.imprex.orebfuscator.nms.ReadOnlyChunk;
1717

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

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

4848
private final World world;
49-
private final ChunkPosition position;
49+
private final ChunkCacheKey key;
5050

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

53-
public Request(World world, ChunkPosition position) {
53+
public Request(World world, ChunkCacheKey key) {
5454
this.world = world;
55-
this.position = position;
55+
this.key = key;
5656
}
5757

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

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

6666
neighboringChunks[direction.ordinal()] = OrebfuscatorNms.getReadOnlyChunk(world, chunkX, chunkZ);
6767
}

orebfuscator-compatibility/orebfuscator-compatibility-bukkit/src/main/java/net/imprex/orebfuscator/compatibility/bukkit/BukkitCompatibilityLayer.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
import org.bukkit.plugin.Plugin;
77

88
import dev.imprex.orebfuscator.config.api.Config;
9-
import dev.imprex.orebfuscator.util.ChunkPosition;
9+
import dev.imprex.orebfuscator.util.ChunkCacheKey;
1010
import net.imprex.orebfuscator.compatibility.CompatibilityLayer;
1111
import net.imprex.orebfuscator.compatibility.CompatibilityScheduler;
1212
import net.imprex.orebfuscator.nms.ReadOnlyChunk;
@@ -34,7 +34,7 @@ public CompatibilityScheduler getScheduler() {
3434
}
3535

3636
@Override
37-
public CompletableFuture<ReadOnlyChunk[]> getNeighboringChunks(World world, ChunkPosition position) {
38-
return this.chunkLoader.submitRequest(world, position);
37+
public CompletableFuture<ReadOnlyChunk[]> getNeighboringChunks(World world, ChunkCacheKey key) {
38+
return this.chunkLoader.submitRequest(world, key);
3939
}
4040
}

orebfuscator-compatibility/orebfuscator-compatibility-paper/src/main/java/net/imprex/orebfuscator/compatibility/paper/AbstractPaperCompatibilityLayer.java

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,22 +4,22 @@
44

55
import org.bukkit.World;
66

7+
import dev.imprex.orebfuscator.util.ChunkCacheKey;
78
import dev.imprex.orebfuscator.util.ChunkDirection;
8-
import dev.imprex.orebfuscator.util.ChunkPosition;
99
import net.imprex.orebfuscator.OrebfuscatorNms;
1010
import net.imprex.orebfuscator.compatibility.CompatibilityLayer;
1111
import net.imprex.orebfuscator.nms.ReadOnlyChunk;
1212

1313
public abstract class AbstractPaperCompatibilityLayer implements CompatibilityLayer {
1414

1515
@Override
16-
public CompletableFuture<ReadOnlyChunk[]> getNeighboringChunks(World world, ChunkPosition position) {
16+
public CompletableFuture<ReadOnlyChunk[]> getNeighboringChunks(World world, ChunkCacheKey key) {
1717
CompletableFuture<?>[] futures = new CompletableFuture<?>[4];
1818
ReadOnlyChunk[] neighboringChunks = new ReadOnlyChunk[4];
1919

2020
for (ChunkDirection direction : ChunkDirection.values()) {
21-
int chunkX = position.x + direction.getOffsetX();
22-
int chunkZ = position.z + direction.getOffsetZ();
21+
int chunkX = key.x() + direction.getOffsetX();
22+
int chunkZ = key.z() + direction.getOffsetZ();
2323
int index = direction.ordinal();
2424

2525
futures[index] = world.getChunkAtAsync(chunkX, chunkZ).thenAccept(chunk -> {

orebfuscator-core/pom.xml

Lines changed: 48 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
1-
<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">
1+
<project xmlns="http://maven.apache.org/POM/4.0.0"
2+
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
3+
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
24
<modelVersion>4.0.0</modelVersion>
5+
36
<parent>
47
<groupId>net.imprex</groupId>
58
<artifactId>orebfuscator</artifactId>
@@ -25,17 +28,57 @@
2528
<scope>provided</scope>
2629
</dependency>
2730

31+
<!-- Third-Party -->
32+
<dependency>
33+
<groupId>com.google.guava</groupId>
34+
<artifactId>guava</artifactId>
35+
<version>${dependency.guava.version}</version>
36+
<scope>compile</scope>
37+
</dependency>
2838
<dependency>
29-
<groupId>org.spigotmc</groupId>
30-
<artifactId>spigot-api</artifactId>
31-
<version>${dependency.bukkit.version}</version>
39+
<groupId>com.google.code.gson</groupId>
40+
<artifactId>gson</artifactId>
41+
<version>${dependency.gson.version}</version>
3242
<scope>provided</scope>
3343
</dependency>
44+
<dependency>
45+
<groupId>org.yaml</groupId>
46+
<artifactId>snakeyaml</artifactId>
47+
<version>${dependency.snakeyaml.version}</version>
48+
<scope>compile</scope>
49+
</dependency>
3450
<dependency>
3551
<groupId>org.joml</groupId>
3652
<artifactId>joml</artifactId>
3753
<version>${dependency.joml.version}</version>
38-
<scope>compile</scope>
54+
<scope>provided</scope>
3955
</dependency>
56+
<!--<dependency>
57+
<groupId>org.lz4</groupId>
58+
<artifactId>lz4-java</artifactId>
59+
<version>${dependency.lz4.version}</version>
60+
<scope>compile</scope>
61+
</dependency>-->
4062
</dependencies>
63+
64+
<build>
65+
<plugins>
66+
<plugin>
67+
<groupId>org.apache.maven.plugins</groupId>
68+
<artifactId>maven-shade-plugin</artifactId>
69+
<configuration>
70+
<relocations>
71+
<relocation>
72+
<pattern>com.google.common</pattern>
73+
<shadedPattern>dev.imprex.shaded.com.google.common</shadedPattern>
74+
</relocation>
75+
<relocation>
76+
<pattern>org.yaml.snakeyaml</pattern>
77+
<shadedPattern>dev.imprex.shaded.org.yaml.snakeyaml</shadedPattern>
78+
</relocation>
79+
</relocations>
80+
</configuration>
81+
</plugin>
82+
</plugins>
83+
</build>
4184
</project>

orebfuscator-core/src/main/java/dev/imprex/orebfuscator/cache/AbstractRegionFileCache.java

Lines changed: 14 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,8 @@
99
import java.util.Objects;
1010
import java.util.concurrent.locks.ReadWriteLock;
1111
import java.util.concurrent.locks.ReentrantReadWriteLock;
12-
1312
import dev.imprex.orebfuscator.config.api.CacheConfig;
14-
import dev.imprex.orebfuscator.util.ChunkPosition;
13+
import dev.imprex.orebfuscator.util.ChunkCacheKey;
1514
import dev.imprex.orebfuscator.util.SimpleCache;
1615

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

3231
protected abstract void closeRegionFile(T t) throws IOException;
3332

34-
protected abstract DataInputStream createInputStream(T t, ChunkPosition key) throws IOException;
33+
protected abstract DataInputStream createInputStream(T t, ChunkCacheKey key) throws IOException;
3534

36-
protected abstract DataOutputStream createOutputStream(T t, ChunkPosition key) throws IOException;
35+
protected abstract DataOutputStream createOutputStream(T t, ChunkCacheKey key) throws IOException;
3736

38-
public final DataInputStream createInputStream(ChunkPosition key) throws IOException {
37+
public final DataInputStream createInputStream(ChunkCacheKey key) throws IOException {
3938
T t = this.get(this.cacheConfig.regionFile(key));
4039
return t != null ? this.createInputStream(t, key) : null;
4140
}
4241

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

7877
this.lock.writeLock().lock();
7978
try {
80-
this.regionFiles.putIfAbsent(path, t);
81-
return this.regionFiles.get(path);
79+
T previous = this.regionFiles.putIfAbsent(path, t);
80+
81+
if (previous != null) {
82+
// some other thread was faster, close fd
83+
closeRegionFile(t);
84+
return previous;
85+
}
86+
87+
return t;
8288
} finally {
8389
this.lock.writeLock().unlock();
8490
}

orebfuscator-plugin/src/main/java/dev/imprex/orebfuscator/chunk/Chunk.java renamed to orebfuscator-core/src/main/java/dev/imprex/orebfuscator/chunk/Chunk.java

Lines changed: 28 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1,51 +1,51 @@
11
package dev.imprex.orebfuscator.chunk;
22

33
import java.util.Arrays;
4-
4+
import dev.imprex.orebfuscator.interop.ChunkPacketAccessor;
5+
import dev.imprex.orebfuscator.interop.WorldAccessor;
56
import io.netty.buffer.ByteBuf;
67
import io.netty.buffer.PooledByteBufAllocator;
78
import io.netty.buffer.Unpooled;
8-
import net.imprex.orebfuscator.chunk.ChunkStruct;
9-
import net.imprex.orebfuscator.util.HeightAccessor;
109

1110
public class Chunk implements AutoCloseable {
1211

13-
public static Chunk fromChunkStruct(ChunkStruct chunkStruct) {
14-
return new Chunk(chunkStruct);
15-
}
12+
private final ChunkFactory factory;
1613

1714
private final int chunkX;
1815
private final int chunkZ;
1916

20-
private final HeightAccessor heightAccessor;
17+
private final WorldAccessor worldAccessor;
2118
private final ChunkSectionHolder[] sections;
2219

2320
private final ByteBuf inputBuffer;
2421
private final ByteBuf outputBuffer;
2522

26-
private Chunk(ChunkStruct chunkStruct) {
27-
this.chunkX = chunkStruct.chunkX;
28-
this.chunkZ = chunkStruct.chunkZ;
23+
Chunk(ChunkFactory factory, ChunkPacketAccessor packet) {
24+
this.factory = factory;
25+
26+
this.chunkX = packet.chunkX();
27+
this.chunkZ = packet.chunkZ();
2928

30-
this.heightAccessor = HeightAccessor.get(chunkStruct.world);
31-
this.sections = new ChunkSectionHolder[this.heightAccessor.getSectionCount()];
29+
this.worldAccessor = packet.world();
30+
this.sections = new ChunkSectionHolder[this.worldAccessor.getSectionCount()];
3231

33-
this.inputBuffer = Unpooled.wrappedBuffer(chunkStruct.data);
34-
this.outputBuffer = PooledByteBufAllocator.DEFAULT.heapBuffer(chunkStruct.data.length);
32+
byte[] data = packet.data();
33+
this.inputBuffer = Unpooled.wrappedBuffer(data);
34+
this.outputBuffer = PooledByteBufAllocator.DEFAULT.heapBuffer(data.length);
3535

3636
for (int sectionIndex = 0; sectionIndex < this.sections.length; sectionIndex++) {
37-
if (chunkStruct.sectionMask.get(sectionIndex)) {
37+
if (packet.isSectionPresent(sectionIndex)) {
3838
this.sections[sectionIndex] = new ChunkSectionHolder();
3939
}
4040
}
4141
}
4242

43-
public int getSectionCount() {
44-
return this.sections.length;
43+
public WorldAccessor world() {
44+
return worldAccessor;
4545
}
4646

47-
public HeightAccessor getHeightAccessor() {
48-
return heightAccessor;
47+
public int getSectionCount() {
48+
return this.sections.length;
4949
}
5050

5151
public ChunkSection getSection(int index) {
@@ -58,7 +58,7 @@ public ChunkSection getSection(int index) {
5858

5959
public int getBlockState(int x, int y, int z) {
6060
if (x >> 4 == this.chunkX && z >> 4 == this.chunkZ) {
61-
ChunkSectionHolder chunkSection = this.sections[this.heightAccessor.getSectionIndex(y)];
61+
ChunkSectionHolder chunkSection = this.sections[this.worldAccessor.getSectionIndex(y)];
6262
if (chunkSection != null) {
6363
return chunkSection.data[ChunkSection.positionToIndex(x & 0xF, y & 0xF, z & 0xF)];
6464
}
@@ -74,8 +74,11 @@ public byte[] finalizeOutput() {
7474
chunkSection.write();
7575
}
7676
}
77+
7778
this.outputBuffer.writeBytes(this.inputBuffer);
78-
return Arrays.copyOfRange(this.outputBuffer.array(), this.outputBuffer.arrayOffset(),
79+
80+
return Arrays.copyOfRange(
81+
this.outputBuffer.array(), this.outputBuffer.arrayOffset(),
7982
this.outputBuffer.arrayOffset() + this.outputBuffer.readableBytes());
8083
}
8184

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

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

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

112115
private class ChunkSectionHolder {
113116

114-
public ChunkSection chunkSection;
117+
public final ChunkSection chunkSection;
115118

116119
public final int[] data;
117120
public final int extraOffset;
118121

119122
private int extraBytes;
120123

121124
public ChunkSectionHolder() {
122-
this.chunkSection = new ChunkSection();
125+
this.chunkSection = new ChunkSection(factory);
123126

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

127-
if (ChunkCapabilities.hasBiomePalettedContainer()) {
130+
if (factory.versionFlags().hasBiomePalettedContainer()) {
128131
skipBiomePalettedContainer();
129132
this.extraBytes = inputBuffer.readerIndex() - this.extraOffset;
130133
}

0 commit comments

Comments
 (0)