Fix custom world height in xray patch

This commit is contained in:
Nassim Jahnke 2021-06-16 15:14:19 +02:00
parent 41c8d7f600
commit 3539c592ed
4 changed files with 61 additions and 57 deletions

View file

@ -25,7 +25,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ +
+ public boolean antiXray; + public boolean antiXray;
+ public EngineMode engineMode; + public EngineMode engineMode;
+ public int maxChunkSectionIndex; + public int maxBlockHeight;
+ public int updateRadius; + public int updateRadius;
+ public boolean lavaObscures; + public boolean lavaObscures;
+ public boolean usePermission; + public boolean usePermission;
@ -35,8 +35,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ antiXray = getBoolean("anti-xray.enabled", false); + antiXray = getBoolean("anti-xray.enabled", false);
+ engineMode = EngineMode.getById(getInt("anti-xray.engine-mode", EngineMode.HIDE.getId())); + engineMode = EngineMode.getById(getInt("anti-xray.engine-mode", EngineMode.HIDE.getId()));
+ engineMode = engineMode == null ? EngineMode.HIDE : engineMode; + engineMode = engineMode == null ? EngineMode.HIDE : engineMode;
+ maxChunkSectionIndex = getInt("anti-xray.max-chunk-section-index", 3); + maxBlockHeight = getInt("anti-xray.max-block-height", 64);
+ maxChunkSectionIndex = maxChunkSectionIndex > 15 ? 15 : maxChunkSectionIndex;
+ updateRadius = getInt("anti-xray.update-radius", 2); + updateRadius = getInt("anti-xray.update-radius", 2);
+ lavaObscures = getBoolean("anti-xray.lava-obscures", false); + lavaObscures = getBoolean("anti-xray.lava-obscures", false);
+ usePermission = getBoolean("anti-xray.use-permission", false); + usePermission = getBoolean("anti-xray.use-permission", false);
@ -53,7 +52,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ set("anti-xray.hidden-blocks", hiddenBlocks); + set("anti-xray.hidden-blocks", hiddenBlocks);
+ set("anti-xray.replacement-blocks", replacementBlocks); + set("anti-xray.replacement-blocks", replacementBlocks);
+ } + }
+ log("Anti-Xray: " + (antiXray ? "enabled" : "disabled") + " / Engine Mode: " + engineMode.getDescription() + " / Up to " + ((maxChunkSectionIndex + 1) * 16) + " blocks / Update Radius: " + updateRadius); + log("Anti-Xray: " + (antiXray ? "enabled" : "disabled") + " / Engine Mode: " + engineMode.getDescription() + " / Up to " + ((maxBlockHeight >> 4) << 4) + " blocks / Update Radius: " + updateRadius);
+ if (antiXray && usePermission) { + if (antiXray && usePermission) {
+ Bukkit.getLogger().warning("You have enabled permission-based Anti-Xray checking - depending on your permission plugin, this may cause performance issues"); + Bukkit.getLogger().warning("You have enabled permission-based Anti-Xray checking - depending on your permission plugin, this may cause performance issues");
+ } + }
@ -95,12 +94,12 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ return false; + return false;
+ } + }
+ +
+ public ChunkPacketInfo<BlockState> getChunkPacketInfo(ClientboundLevelChunkPacket packetPlayOutMapChunk, LevelChunk chunk) { + public ChunkPacketInfo<BlockState> getChunkPacketInfo(ClientboundLevelChunkPacket chunkPacket, LevelChunk chunk) {
+ return null; + return null;
+ } + }
+ +
+ public void modifyBlocks(ClientboundLevelChunkPacket packetPlayOutMapChunk, ChunkPacketInfo<BlockState> chunkPacketInfo) { + public void modifyBlocks(ClientboundLevelChunkPacket chunkPacket, ChunkPacketInfo<BlockState> chunkPacketInfo) {
+ packetPlayOutMapChunk.setReady(true); + chunkPacket.setReady(true);
+ } + }
+ +
+ public void onBlockChange(Level world, BlockPos blockPosition, BlockState newBlockData, BlockState oldBlockData, int flag) { + public void onBlockChange(Level world, BlockPos blockPosition, BlockState newBlockData, BlockState oldBlockData, int flag) {
@ -155,6 +154,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ +
+ private final Executor executor; + private final Executor executor;
+ private final EngineMode engineMode; + private final EngineMode engineMode;
+ private final int worldSectionHeight;
+ private final int maxChunkSectionIndex; + private final int maxChunkSectionIndex;
+ private final int updateRadius; + private final int updateRadius;
+ private final boolean usePermission; + private final boolean usePermission;
@ -175,7 +175,10 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ public ChunkPacketBlockControllerAntiXray(Level world, Executor executor) { + public ChunkPacketBlockControllerAntiXray(Level world, Executor executor) {
+ PaperWorldConfig paperWorldConfig = world.paperConfig; + PaperWorldConfig paperWorldConfig = world.paperConfig;
+ engineMode = paperWorldConfig.engineMode; + engineMode = paperWorldConfig.engineMode;
+ maxChunkSectionIndex = paperWorldConfig.maxChunkSectionIndex; +
+ int minSection = world.getMinSection();
+ worldSectionHeight = world.getSectionsCount();
+ maxChunkSectionIndex = (paperWorldConfig.maxBlockHeight >> 4) - minSection;
+ updateRadius = paperWorldConfig.updateRadius; + updateRadius = paperWorldConfig.updateRadius;
+ usePermission = paperWorldConfig.usePermission; + usePermission = paperWorldConfig.usePermission;
+ +
@ -208,11 +211,10 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ } + }
+ +
+ // The doc of the LinkedHashSet(Collection<? extends E> c) constructor doesn't specify that the insertion order is the predictable iteration order of the specified Collection, although it is in the implementation + // The doc of the LinkedHashSet(Collection<? extends E> c) constructor doesn't specify that the insertion order is the predictable iteration order of the specified Collection, although it is in the implementation
+ Set<BlockState> predefinedBlockDataSet = new LinkedHashSet<BlockState>(); + Set<BlockState> predefinedBlockDataSet = new LinkedHashSet<>(predefinedBlockDataList);
+ // Therefore addAll(Collection<? extends E> c) is used, which guarantees this order in the doc + // Therefore addAll(Collection<? extends E> c) is used, which guarantees this order in the doc
+ predefinedBlockDataSet.addAll(predefinedBlockDataList); + predefinedBlockData = predefinedBlockDataSet.isEmpty() ? new BlockState[] {Blocks.DIAMOND_ORE.defaultBlockState()} : predefinedBlockDataSet.toArray(new BlockState[0]);
+ predefinedBlockData = predefinedBlockDataSet.size() == 0 ? new BlockState[] {Blocks.DIAMOND_ORE.defaultBlockState()} : predefinedBlockDataSet.toArray(new BlockState[0]); + predefinedBlockDataFull = predefinedBlockDataSet.isEmpty() ? new BlockState[] {Blocks.DIAMOND_ORE.defaultBlockState()} : predefinedBlockDataList.toArray(new BlockState[0]);
+ predefinedBlockDataFull = predefinedBlockDataSet.size() == 0 ? new BlockState[] {Blocks.DIAMOND_ORE.defaultBlockState()} : predefinedBlockDataList.toArray(new BlockState[0]);
+ predefinedBlockDataStone = null; + predefinedBlockDataStone = null;
+ predefinedBlockDataNetherrack = null; + predefinedBlockDataNetherrack = null;
+ predefinedBlockDataEndStone = null; + predefinedBlockDataEndStone = null;
@ -266,19 +268,14 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ public BlockState[] getPredefinedBlockData(Level world, ChunkAccess chunk, LevelChunkSection chunkSection, boolean initializeBlocks) { + public BlockState[] getPredefinedBlockData(Level world, ChunkAccess chunk, LevelChunkSection chunkSection, boolean initializeBlocks) {
+ // Return the block data which should be added to the data palettes so that they can be used for the obfuscation + // Return the block data which should be added to the data palettes so that they can be used for the obfuscation
+ if (chunkSection.bottomBlockY() >> 4 <= maxChunkSectionIndex) { + if (chunkSection.bottomBlockY() >> 4 <= maxChunkSectionIndex) {
+ switch (engineMode) { + if (engineMode == EngineMode.HIDE) {
+ case HIDE: + return switch (world.getWorld().getEnvironment()) {
+ switch (world.getWorld().getEnvironment()) { + case NETHER -> predefinedBlockDataNetherrack;
+ case NETHER: + case THE_END -> predefinedBlockDataEndStone;
+ return predefinedBlockDataNetherrack; + default -> predefinedBlockDataStone;
+ case THE_END: + };
+ return predefinedBlockDataEndStone;
+ default:
+ return predefinedBlockDataStone;
+ }
+ default:
+ return predefinedBlockData;
+ } + }
+ return predefinedBlockData;
+ } + }
+ +
+ return null; + return null;
@ -290,24 +287,23 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ } + }
+ +
+ @Override + @Override
+ public ChunkPacketInfoAntiXray getChunkPacketInfo(ClientboundLevelChunkPacket packetPlayOutMapChunk, LevelChunk chunk) { + public ChunkPacketInfoAntiXray getChunkPacketInfo(ClientboundLevelChunkPacket chunkPacket, LevelChunk chunk) {
+ // Return a new instance to collect data and objects in the right state while creating the chunk packet for thread safe access later + // Return a new instance to collect data and objects in the right state while creating the chunk packet for thread safe access later
+ // Note: As of 1.14 this has to be moved later due to the chunk system. + // Note: As of 1.14 this has to be moved later due to the chunk system.
+ ChunkPacketInfoAntiXray chunkPacketInfoAntiXray = new ChunkPacketInfoAntiXray(packetPlayOutMapChunk, chunk, this); + return new ChunkPacketInfoAntiXray(chunkPacket, chunk, this);
+ return chunkPacketInfoAntiXray;
+ } + }
+ +
+ @Override + @Override
+ public void modifyBlocks(ClientboundLevelChunkPacket packetPlayOutMapChunk, ChunkPacketInfo<BlockState> chunkPacketInfo) { + public void modifyBlocks(ClientboundLevelChunkPacket chunkPacket, ChunkPacketInfo<BlockState> chunkPacketInfo) {
+ if (chunkPacketInfo == null) { + if (chunkPacketInfo == null) {
+ packetPlayOutMapChunk.setReady(true); + chunkPacket.setReady(true);
+ return; + return;
+ } + }
+ +
+ if (!Bukkit.isPrimaryThread()) { + if (!Bukkit.isPrimaryThread()) {
+ // plugins? + // plugins?
+ MinecraftServer.getServer().scheduleOnMain(() -> { + MinecraftServer.getServer().scheduleOnMain(() -> {
+ this.modifyBlocks(packetPlayOutMapChunk, chunkPacketInfo); + this.modifyBlocks(chunkPacket, chunkPacketInfo);
+ }); + });
+ return; + return;
+ } + }
@ -315,7 +311,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ LevelChunk chunk = chunkPacketInfo.getChunk(); + LevelChunk chunk = chunkPacketInfo.getChunk();
+ int x = chunk.getPos().x; + int x = chunk.getPos().x;
+ int z = chunk.getPos().z; + int z = chunk.getPos().z;
+ ServerLevel world = (ServerLevel)chunk.level; + ServerLevel world = chunk.level;
+ ((ChunkPacketInfoAntiXray) chunkPacketInfo).setNearbyChunks( + ((ChunkPacketInfoAntiXray) chunkPacketInfo).setNearbyChunks(
+ (LevelChunk) world.getChunkIfLoadedImmediately(x - 1, z), + (LevelChunk) world.getChunkIfLoadedImmediately(x - 1, z),
+ (LevelChunk) world.getChunkIfLoadedImmediately(x + 1, z), + (LevelChunk) world.getChunkIfLoadedImmediately(x + 1, z),
@ -337,11 +333,11 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ +
+ public void obfuscate(ChunkPacketInfoAntiXray chunkPacketInfoAntiXray) { + public void obfuscate(ChunkPacketInfoAntiXray chunkPacketInfoAntiXray) {
+ int[] predefinedBlockDataBits = this.predefinedBlockDataBits.get(); + int[] predefinedBlockDataBits = this.predefinedBlockDataBits.get();
+ boolean[] solid = this.solid.get(); + boolean[] solid = ChunkPacketBlockControllerAntiXray.solid.get();
+ boolean[] obfuscate = this.obfuscate.get(); + boolean[] obfuscate = ChunkPacketBlockControllerAntiXray.obfuscate.get();
+ boolean[][] current = this.current.get(); + boolean[][] current = ChunkPacketBlockControllerAntiXray.current.get();
+ boolean[][] next = this.next.get(); + boolean[][] next = ChunkPacketBlockControllerAntiXray.next.get();
+ boolean[][] nextNext = this.nextNext.get(); + boolean[][] nextNext = ChunkPacketBlockControllerAntiXray.nextNext.get();
+ // dataBitsReader, dataBitsWriter and nearbyChunkSections could also be reused (with ThreadLocal if necessary) but it's not worth it + // dataBitsReader, dataBitsWriter and nearbyChunkSections could also be reused (with ThreadLocal if necessary) but it's not worth it
+ DataBitsReader dataBitsReader = new DataBitsReader(); + DataBitsReader dataBitsReader = new DataBitsReader();
+ DataBitsWriter dataBitsWriter = new DataBitsWriter(); + DataBitsWriter dataBitsWriter = new DataBitsWriter();
@ -431,7 +427,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ // If so, obfuscate the upper layer of the current chunk section by reading blocks of the first layer from the chunk section above if it exists + // If so, obfuscate the upper layer of the current chunk section by reading blocks of the first layer from the chunk section above if it exists
+ LevelChunkSection aboveChunkSection; + LevelChunkSection aboveChunkSection;
+ +
+ if (chunkSectionIndex != 15 && (aboveChunkSection = chunkPacketInfoAntiXray.getChunk().getSections()[chunkSectionIndex + 1]) != LevelChunk.EMPTY_CHUNK_SECTION) { + if (chunkSectionIndex != worldSectionHeight && (aboveChunkSection = chunkPacketInfoAntiXray.getChunk().getSections()[chunkSectionIndex + 1]) != LevelChunk.EMPTY_CHUNK_SECTION) {
+ boolean[][] temp = current; + boolean[][] temp = current;
+ current = next; + current = next;
+ next = nextNext; + next = nextNext;
@ -467,7 +463,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ } + }
+ } + }
+ +
+ chunkPacketInfoAntiXray.getPacketPlayOutMapChunk().setReady(true); + chunkPacketInfoAntiXray.getChunkPacket().setReady(true);
+ } + }
+ +
+ private void obfuscateLayer(int y, DataBitsReader dataBitsReader, DataBitsWriter dataBitsWriter, boolean[] solid, boolean[] obfuscate, int[] predefinedBlockDataBits, boolean[][] current, boolean[][] next, boolean[][] nextNext, LevelChunkSection[] nearbyChunkSections, IntSupplier random) { + private void obfuscateLayer(int y, DataBitsReader dataBitsReader, DataBitsWriter dataBitsWriter, boolean[] solid, boolean[] obfuscate, int[] predefinedBlockDataBits, boolean[][] current, boolean[][] next, boolean[][] nextNext, LevelChunkSection[] nearbyChunkSections, IntSupplier random) {
@ -780,21 +776,27 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ +
+public class ChunkPacketInfo<T> { +public class ChunkPacketInfo<T> {
+ +
+ private final ClientboundLevelChunkPacket packetPlayOutMapChunk; + private final ClientboundLevelChunkPacket chunkPacket;
+ private final LevelChunk chunk; + private final LevelChunk chunk;
+ private byte[] data; + private byte[] data;
+ private final int[] bitsPerObject = new int[16]; + private final int[] bitsPerObject;
+ private final Object[] dataPalettes = new Object[16]; + private final Object[] dataPalettes;
+ private final int[] dataBitsIndexes = new int[16]; + private final int[] dataBitsIndexes;
+ private final Object[][] predefinedObjects = new Object[16][]; + private final Object[][] predefinedObjects;
+ +
+ public ChunkPacketInfo(ClientboundLevelChunkPacket packetPlayOutMapChunk, LevelChunk chunk) { + public ChunkPacketInfo(ClientboundLevelChunkPacket chunkPacket, LevelChunk chunk) {
+ this.packetPlayOutMapChunk = packetPlayOutMapChunk; + this.chunkPacket = chunkPacket;
+ this.chunk = chunk; + this.chunk = chunk;
+
+ int sections = chunk.getSectionsCount();
+ this.bitsPerObject = new int[sections];
+ this.dataPalettes = new Object[sections];
+ this.dataBitsIndexes = new int[sections];
+ this.predefinedObjects = new Object[sections][];
+ } + }
+ +
+ public ClientboundLevelChunkPacket getPacketPlayOutMapChunk() { + public ClientboundLevelChunkPacket getChunkPacket() {
+ return packetPlayOutMapChunk; + return chunkPacket;
+ } + }
+ +
+ public LevelChunk getChunk() { + public LevelChunk getChunk() {
@ -1298,7 +1300,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ // Paper end + // Paper end
buf.writeShort(this.nonEmptyBlockCount); buf.writeShort(this.nonEmptyBlockCount);
- this.states.write(buf); - this.states.write(buf);
+ this.states.write(buf, chunkPacketInfo, this.bottomBlockY >> 4); // Paper - Anti-Xray - Add chunk packet info + this.states.write(buf, chunkPacketInfo, this.bottomBlockY); // Paper - Anti-Xray - Add chunk packet info
} }
public int getSerializedSize() { public int getSerializedSize() {
@ -1384,7 +1386,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ @Deprecated public void write(FriendlyByteBuf buf) { + @Deprecated public void write(FriendlyByteBuf buf) {
+ write(buf, null, 0); + write(buf, null, 0);
+ } + }
+ public void write(FriendlyByteBuf buf, com.destroystokyo.paper.antixray.ChunkPacketInfo<T> chunkPacketInfo, int chunkSectionIndex) { + public void write(FriendlyByteBuf buf, com.destroystokyo.paper.antixray.ChunkPacketInfo<T> chunkPacketInfo, int bottomBlockY) {
+ // Paper end + // Paper end
try { try {
this.acquire(); this.acquire();
@ -1392,10 +1394,12 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
this.palette.write(buf); this.palette.write(buf);
+ // Paper start - Anti-Xray - Add chunk packet info + // Paper start - Anti-Xray - Add chunk packet info
+ if (chunkPacketInfo != null) { + if (chunkPacketInfo != null) {
+ chunkPacketInfo.setBitsPerObject(chunkSectionIndex, this.bits); + // Bottom block to 0 based chunk section index
+ chunkPacketInfo.setDataPalette(chunkSectionIndex, this.palette); + int section = (bottomBlockY >> 4) - chunkPacketInfo.getChunk().getMinSection();
+ chunkPacketInfo.setDataBitsIndex(chunkSectionIndex, buf.writerIndex() + FriendlyByteBuf.getVarIntSize(this.storage.getDataBits().length)); + chunkPacketInfo.setBitsPerObject(section, this.bits);
+ chunkPacketInfo.setPredefinedObjects(chunkSectionIndex, this.predefinedObjects); + chunkPacketInfo.setDataPalette(section, this.palette);
+ chunkPacketInfo.setDataBitsIndex(section, buf.writerIndex() + FriendlyByteBuf.getVarIntSize(this.storage.getDataBits().length));
+ chunkPacketInfo.setPredefinedObjects(section, this.predefinedObjects);
+ } + }
+ // Paper end + // Paper end
buf.writeLongArray(this.storage.getRaw()); buf.writeLongArray(this.storage.getRaw());

View file

@ -62,7 +62,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ +
public boolean antiXray; public boolean antiXray;
public EngineMode engineMode; public EngineMode engineMode;
public int maxChunkSectionIndex; public int maxBlockHeight;
diff --git a/src/main/java/net/minecraft/world/entity/item/ItemEntity.java b/src/main/java/net/minecraft/world/entity/item/ItemEntity.java diff --git a/src/main/java/net/minecraft/world/entity/item/ItemEntity.java b/src/main/java/net/minecraft/world/entity/item/ItemEntity.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/net/minecraft/world/entity/item/ItemEntity.java --- a/src/main/java/net/minecraft/world/entity/item/ItemEntity.java

View file

@ -37,7 +37,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ +
public boolean antiXray; public boolean antiXray;
public EngineMode engineMode; public EngineMode engineMode;
public int maxChunkSectionIndex; public int maxBlockHeight;
diff --git a/src/main/java/net/minecraft/server/MCUtil.java b/src/main/java/net/minecraft/server/MCUtil.java diff --git a/src/main/java/net/minecraft/server/MCUtil.java b/src/main/java/net/minecraft/server/MCUtil.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/net/minecraft/server/MCUtil.java --- a/src/main/java/net/minecraft/server/MCUtil.java

View file

@ -67,8 +67,8 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
@Deprecated public void write(FriendlyByteBuf buf) { @Deprecated public void write(FriendlyByteBuf buf) {
write(buf, null, 0); write(buf, null, 0);
} }
- public void write(FriendlyByteBuf buf, com.destroystokyo.paper.antixray.ChunkPacketInfo<T> chunkPacketInfo, int chunkSectionIndex) { - public void write(FriendlyByteBuf buf, com.destroystokyo.paper.antixray.ChunkPacketInfo<T> chunkPacketInfo, int bottomBlockY) {
+ public synchronized void write(FriendlyByteBuf buf, com.destroystokyo.paper.antixray.ChunkPacketInfo<T> chunkPacketInfo, int chunkSectionIndex) { // Paper - synchronize + public synchronized void write(FriendlyByteBuf buf, com.destroystokyo.paper.antixray.ChunkPacketInfo<T> chunkPacketInfo, int bottomBlockY) { // Paper - synchronize
// Paper end // Paper end
try { try {
this.acquire(); this.acquire();