Skip to content

Commit 41c45aa

Browse files
authored
Add support for 1.21.5 (#414)
* feat: add support for 1.21.5 * ci: allow manual trigger of build action
1 parent 79674c6 commit 41c45aa

12 files changed

Lines changed: 362 additions & 9 deletions

File tree

.github/workflows/build.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
name: Build
22

33
on:
4+
- workflow_dispatch
45
- push
56
- pull_request
67

.github/workflows/buildtools.sh

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,3 +40,4 @@ checkVersion "1.20.6" "21"
4040
checkVersion "1.21.1" "21"
4141
checkVersion "1.21.3" "21"
4242
checkVersion "1.21.4" "21"
43+
checkVersion "1.21.5" "21"

orebfuscator-common/src/main/java/net/imprex/orebfuscator/util/MinecraftVersion.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ private static final class NmsMapping {
1515
private static final List<NmsMapping> MAPPINGS = new ArrayList<>();
1616

1717
static {
18+
MAPPINGS.add(new NmsMapping("1.21.5", "v1_21_R4"));
1819
MAPPINGS.add(new NmsMapping("1.21.4", "v1_21_R3"));
1920
MAPPINGS.add(new NmsMapping("1.21.2", "v1_21_R2"));
2021
MAPPINGS.add(new NmsMapping("1.21", "v1_21_R1"));
Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
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">
2+
<modelVersion>4.0.0</modelVersion>
3+
4+
<parent>
5+
<groupId>net.imprex</groupId>
6+
<artifactId>orebfuscator-nms</artifactId>
7+
<version>${revision}</version>
8+
</parent>
9+
10+
<artifactId>orebfuscator-nms-v1_21_R4</artifactId>
11+
<packaging>jar</packaging>
12+
13+
<dependencies>
14+
<dependency>
15+
<groupId>net.imprex</groupId>
16+
<artifactId>orebfuscator-nms-api</artifactId>
17+
<version>${revision}</version>
18+
<scope>provided</scope>
19+
</dependency>
20+
<dependency>
21+
<groupId>org.spigotmc</groupId>
22+
<artifactId>spigot</artifactId>
23+
<version>1.21.5-R0.1-SNAPSHOT</version>
24+
<classifier>remapped-mojang</classifier>
25+
<scope>provided</scope>
26+
</dependency>
27+
</dependencies>
28+
29+
30+
<build>
31+
<plugins>
32+
<plugin>
33+
<groupId>org.apache.maven.plugins</groupId>
34+
<artifactId>maven-shade-plugin</artifactId>
35+
<configuration>
36+
<shadedArtifactAttached>true</shadedArtifactAttached>
37+
<shadedClassifierName>mojang-mapped</shadedClassifierName>
38+
<relocations>
39+
<relocation>
40+
<pattern>net.imprex.orebfuscator.nms.v1_21_R4</pattern>
41+
<shadedPattern>net.imprex.orebfuscator.nms.v1_21_R4_mojang</shadedPattern>
42+
</relocation>
43+
</relocations>
44+
</configuration>
45+
</plugin>
46+
<plugin>
47+
<groupId>net.md-5</groupId>
48+
<artifactId>specialsource-maven-plugin</artifactId>
49+
<version>${plugin.specialsource.version}</version>
50+
<executions>
51+
<execution>
52+
<phase>package</phase>
53+
<goals>
54+
<goal>remap</goal>
55+
</goals>
56+
<id>remap-obf</id>
57+
<configuration>
58+
<srgIn>org.spigotmc:minecraft-server:1.21.5-R0.1-SNAPSHOT:txt:maps-mojang</srgIn>
59+
<reverse>true</reverse>
60+
<remappedDependencies>org.spigotmc:spigot:1.21.5-R0.1-SNAPSHOT:jar:remapped-mojang</remappedDependencies>
61+
<remappedArtifactAttached>true</remappedArtifactAttached>
62+
<remappedClassifierName>remapped-obf</remappedClassifierName>
63+
</configuration>
64+
</execution>
65+
<execution>
66+
<phase>package</phase>
67+
<goals>
68+
<goal>remap</goal>
69+
</goals>
70+
<id>remap-spigot</id>
71+
<configuration>
72+
<inputFile>${project.build.directory}/${project.artifactId}-${project.version}-remapped-obf.jar</inputFile>
73+
<srgIn>org.spigotmc:minecraft-server:1.21.5-R0.1-SNAPSHOT:csrg:maps-spigot</srgIn>
74+
<remappedDependencies>org.spigotmc:spigot:1.21.5-R0.1-SNAPSHOT:jar:remapped-obf</remappedDependencies>
75+
</configuration>
76+
</execution>
77+
</executions>
78+
</plugin>
79+
</plugins>
80+
</build>
81+
82+
</project>
Lines changed: 176 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,176 @@
1+
package net.imprex.orebfuscator.nms.v1_21_R4;
2+
3+
import java.util.ArrayList;
4+
import java.util.HashMap;
5+
import java.util.List;
6+
import java.util.Map;
7+
import java.util.Objects;
8+
9+
import org.bukkit.Material;
10+
import org.bukkit.World;
11+
import org.bukkit.craftbukkit.v1_21_R4.CraftWorld;
12+
import org.bukkit.craftbukkit.v1_21_R4.block.data.CraftBlockData;
13+
import org.bukkit.craftbukkit.v1_21_R4.entity.CraftPlayer;
14+
import org.bukkit.entity.Player;
15+
16+
import com.google.common.collect.ImmutableList;
17+
18+
import it.unimi.dsi.fastutil.shorts.Short2ObjectLinkedOpenHashMap;
19+
import it.unimi.dsi.fastutil.shorts.Short2ObjectMap;
20+
import net.imprex.orebfuscator.config.Config;
21+
import net.imprex.orebfuscator.nms.AbstractNmsManager;
22+
import net.imprex.orebfuscator.nms.ReadOnlyChunk;
23+
import net.imprex.orebfuscator.util.BlockProperties;
24+
import net.imprex.orebfuscator.util.BlockStateProperties;
25+
import net.imprex.orebfuscator.util.NamespacedKey;
26+
import net.minecraft.core.BlockPos;
27+
import net.minecraft.core.SectionPos;
28+
import net.minecraft.core.registries.BuiltInRegistries;
29+
import net.minecraft.network.protocol.Packet;
30+
import net.minecraft.network.protocol.game.ClientGamePacketListener;
31+
import net.minecraft.network.protocol.game.ClientboundBlockUpdatePacket;
32+
import net.minecraft.network.protocol.game.ClientboundSectionBlocksUpdatePacket;
33+
import net.minecraft.resources.ResourceKey;
34+
import net.minecraft.server.level.ServerChunkCache;
35+
import net.minecraft.server.level.ServerLevel;
36+
import net.minecraft.server.level.ServerPlayer;
37+
import net.minecraft.world.level.block.Block;
38+
import net.minecraft.world.level.block.Blocks;
39+
import net.minecraft.world.level.block.entity.BlockEntity;
40+
import net.minecraft.world.level.block.state.BlockState;
41+
import net.minecraft.world.level.chunk.LevelChunk;
42+
import net.minecraft.world.level.chunk.LevelChunkSection;
43+
44+
public class NmsManager extends AbstractNmsManager {
45+
46+
private static final int BLOCK_ID_AIR = Block.getId(Blocks.AIR.defaultBlockState());
47+
48+
static int getBlockState(LevelChunk chunk, int x, int y, int z) {
49+
LevelChunkSection[] sections = chunk.getSections();
50+
51+
int sectionIndex = chunk.getSectionIndex(y);
52+
if (sectionIndex >= 0 && sectionIndex < sections.length) {
53+
LevelChunkSection section = sections[sectionIndex];
54+
if (section != null && !section.hasOnlyAir()) {
55+
return Block.getId(section.getBlockState(x & 0xF, y & 0xF, z & 0xF));
56+
}
57+
}
58+
59+
return BLOCK_ID_AIR;
60+
}
61+
62+
private static ServerLevel level(World world) {
63+
return ((CraftWorld) world).getHandle();
64+
}
65+
66+
private static ServerPlayer player(Player player) {
67+
return ((CraftPlayer) player).getHandle();
68+
}
69+
70+
public NmsManager(Config config) {
71+
super(Block.BLOCK_STATE_REGISTRY.size(), new RegionFileCache(config.cache()));
72+
73+
for (Map.Entry<ResourceKey<Block>, Block> entry : BuiltInRegistries.BLOCK.entrySet()) {
74+
NamespacedKey namespacedKey = NamespacedKey.fromString(entry.getKey().location().toString());
75+
Block block = entry.getValue();
76+
77+
ImmutableList<BlockState> possibleBlockStates = block.getStateDefinition().getPossibleStates();
78+
BlockProperties.Builder builder = BlockProperties.builder(namespacedKey);
79+
80+
for (BlockState blockState : possibleBlockStates) {
81+
Material material = CraftBlockData.fromData(blockState).getMaterial();
82+
83+
BlockStateProperties properties = BlockStateProperties.builder(Block.getId(blockState))
84+
.withIsAir(blockState.isAir())
85+
// check if material is occluding and use blockData check for rare edge cases like barrier, spawner, slime_block, ...
86+
.withIsOccluding(material.isOccluding() && blockState.canOcclude())
87+
.withIsBlockEntity(blockState.hasBlockEntity())
88+
.withIsDefaultState(Objects.equals(block.defaultBlockState(), blockState))
89+
.build();
90+
91+
builder.withBlockState(properties);
92+
}
93+
94+
this.registerBlockProperties(builder.build());
95+
}
96+
}
97+
98+
@Override
99+
public ReadOnlyChunk getReadOnlyChunk(World world, int chunkX, int chunkZ) {
100+
ServerChunkCache serverChunkCache = level(world).getChunkSource();
101+
LevelChunk chunk = serverChunkCache.getChunk(chunkX, chunkZ, true);
102+
return new ReadOnlyChunkWrapper(chunk);
103+
}
104+
105+
@Override
106+
public int getBlockState(World world, int x, int y, int z) {
107+
ServerChunkCache serverChunkCache = level(world).getChunkSource();
108+
if (!serverChunkCache.isChunkLoaded(x >> 4, z >> 4)) {
109+
return BLOCK_ID_AIR;
110+
}
111+
112+
LevelChunk chunk = serverChunkCache.getChunk(x >> 4, z >> 4, true);
113+
if (chunk == null) {
114+
return BLOCK_ID_AIR;
115+
}
116+
117+
return getBlockState(chunk, x, y, z);
118+
}
119+
120+
@Override
121+
public void sendBlockUpdates(World world, Iterable<net.imprex.orebfuscator.util.BlockPos> iterable) {
122+
ServerChunkCache serverChunkCache = level(world).getChunkSource();
123+
BlockPos.MutableBlockPos position = new BlockPos.MutableBlockPos();
124+
125+
for (net.imprex.orebfuscator.util.BlockPos pos : iterable) {
126+
position.set(pos.x, pos.y, pos.z);
127+
serverChunkCache.blockChanged(position);
128+
}
129+
}
130+
131+
@Override
132+
public void sendBlockUpdates(Player player, Iterable<net.imprex.orebfuscator.util.BlockPos> iterable) {
133+
ServerPlayer serverPlayer = player(player);
134+
ServerLevel level = serverPlayer.serverLevel();
135+
ServerChunkCache serverChunkCache = level.getChunkSource();
136+
137+
BlockPos.MutableBlockPos position = new BlockPos.MutableBlockPos();
138+
Map<SectionPos, Short2ObjectMap<BlockState>> sectionPackets = new HashMap<>();
139+
List<Packet<ClientGamePacketListener>> blockEntityPackets = new ArrayList<>();
140+
141+
for (net.imprex.orebfuscator.util.BlockPos pos : iterable) {
142+
if (!serverChunkCache.isChunkLoaded(pos.x >> 4, pos.z >> 4)) {
143+
continue;
144+
}
145+
146+
position.set(pos.x, pos.y, pos.z);
147+
BlockState blockState = level.getBlockState(position);
148+
149+
sectionPackets.computeIfAbsent(SectionPos.of(position), key -> new Short2ObjectLinkedOpenHashMap<>())
150+
.put(SectionPos.sectionRelativePos(position), blockState);
151+
152+
if (blockState.hasBlockEntity()) {
153+
BlockEntity blockEntity = level.getBlockEntity(position);
154+
if (blockEntity != null) {
155+
blockEntityPackets.add(blockEntity.getUpdatePacket());
156+
}
157+
}
158+
}
159+
160+
for (Map.Entry<SectionPos, Short2ObjectMap<BlockState>> entry : sectionPackets.entrySet()) {
161+
Short2ObjectMap<BlockState> blockStates = entry.getValue();
162+
if (blockStates.size() == 1) {
163+
Short2ObjectMap.Entry<BlockState> blockEntry = blockStates.short2ObjectEntrySet().iterator().next();
164+
BlockPos blockPosition = entry.getKey().relativeToBlockPos(blockEntry.getShortKey());
165+
serverPlayer.connection.send(new ClientboundBlockUpdatePacket(blockPosition, blockEntry.getValue()));
166+
} else {
167+
serverPlayer.connection.send(new ClientboundSectionBlocksUpdatePacket(entry.getKey(),
168+
blockStates.keySet(), blockStates.values().toArray(BlockState[]::new)));
169+
}
170+
}
171+
172+
for (Packet<ClientGamePacketListener> packet : blockEntityPackets) {
173+
serverPlayer.connection.send(packet);
174+
}
175+
}
176+
}
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
package net.imprex.orebfuscator.nms.v1_21_R4;
2+
3+
import net.imprex.orebfuscator.nms.ReadOnlyChunk;
4+
import net.minecraft.world.level.chunk.LevelChunk;
5+
6+
public class ReadOnlyChunkWrapper implements ReadOnlyChunk {
7+
8+
private final LevelChunk chunk;
9+
10+
ReadOnlyChunkWrapper(LevelChunk chunk) {
11+
this.chunk = chunk;
12+
}
13+
14+
@Override
15+
public int getBlockState(int x, int y, int z) {
16+
return NmsManager.getBlockState(chunk, x, y, z);//ClientboundSetPlayerTeamPacket
17+
}
18+
}
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
package net.imprex.orebfuscator.nms.v1_21_R4;
2+
3+
import java.io.DataInputStream;
4+
import java.io.DataOutputStream;
5+
import java.io.IOException;
6+
import java.nio.file.Path;
7+
8+
import org.bukkit.Bukkit;
9+
import org.bukkit.craftbukkit.v1_21_R4.CraftServer;
10+
11+
import net.imprex.orebfuscator.config.CacheConfig;
12+
import net.imprex.orebfuscator.nms.AbstractRegionFileCache;
13+
import net.imprex.orebfuscator.util.ChunkPosition;
14+
import net.minecraft.world.level.ChunkPos;
15+
import net.minecraft.world.level.chunk.storage.RegionFile;
16+
import net.minecraft.world.level.chunk.storage.RegionFileVersion;
17+
18+
public class RegionFileCache extends AbstractRegionFileCache<RegionFile> {
19+
20+
RegionFileCache(CacheConfig cacheConfig) {
21+
super(cacheConfig);
22+
}
23+
24+
@Override
25+
protected RegionFile createRegionFile(Path path) throws IOException {
26+
boolean isSyncChunkWrites = ((CraftServer) Bukkit.getServer()).getServer().forceSynchronousWrites();
27+
return new RegionFile(null, path, path.getParent(), RegionFileVersion.VERSION_NONE, isSyncChunkWrites);
28+
}
29+
30+
@Override
31+
protected void closeRegionFile(RegionFile t) throws IOException {
32+
t.close();
33+
}
34+
35+
@Override
36+
protected DataInputStream createInputStream(RegionFile t, ChunkPosition key) throws IOException {
37+
return t.getChunkDataInputStream(new ChunkPos(key.x, key.z));
38+
}
39+
40+
@Override
41+
protected DataOutputStream createOutputStream(RegionFile t, ChunkPosition key) throws IOException {
42+
return t.getChunkDataOutputStream(new ChunkPos(key.x, key.z));
43+
}
44+
}

orebfuscator-nms/pom.xml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,5 +30,6 @@
3030
<module>orebfuscator-nms-v1_21_R1</module>
3131
<module>orebfuscator-nms-v1_21_R2</module>
3232
<module>orebfuscator-nms-v1_21_R3</module>
33+
<module>orebfuscator-nms-v1_21_R4</module>
3334
</modules>
3435
</project>

orebfuscator-plugin/pom.xml

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -307,5 +307,18 @@
307307
<version>${revision}</version>
308308
<scope>compile</scope>
309309
</dependency>
310+
<dependency>
311+
<groupId>net.imprex</groupId>
312+
<artifactId>orebfuscator-nms-v1_21_R4</artifactId>
313+
<version>${revision}</version>
314+
<classifier>mojang-mapped</classifier>
315+
<scope>compile</scope>
316+
</dependency>
317+
<dependency>
318+
<groupId>net.imprex</groupId>
319+
<artifactId>orebfuscator-nms-v1_21_R4</artifactId>
320+
<version>${revision}</version>
321+
<scope>compile</scope>
322+
</dependency>
310323
</dependencies>
311324
</project>

orebfuscator-plugin/src/main/java/net/imprex/orebfuscator/chunk/Chunk.java

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -95,13 +95,16 @@ private void skipBiomePalettedContainer() {
9595
}
9696
}
9797

98-
int dataLength = ByteBufUtil.readVarInt(this.inputBuffer);
99-
if (SimpleVarBitBuffer.calculateArraySize(bitsPerValue, 64) != dataLength) {
100-
throw new IndexOutOfBoundsException("data.length != VarBitBuffer::size " + dataLength + " " +
101-
SimpleVarBitBuffer.calculateArraySize(bitsPerValue, 64));
98+
int expectedDataLength = SimpleVarBitBuffer.calculateArraySize(bitsPerValue, 64);
99+
100+
if (ChunkCapabilities.hasLongArrayLengthField()) {
101+
int dataLength = ByteBufUtil.readVarInt(this.inputBuffer);
102+
if (expectedDataLength != dataLength) {
103+
throw new IndexOutOfBoundsException("data.length != VarBitBuffer::size " + dataLength + " " + expectedDataLength);
104+
}
102105
}
103106

104-
this.inputBuffer.skipBytes(Long.BYTES * dataLength);
107+
this.inputBuffer.skipBytes(Long.BYTES * expectedDataLength);
105108
}
106109

107110
private class ChunkSectionHolder {

0 commit comments

Comments
 (0)