Fix for PaperSpigot and issue #188
parent
972286af6c
commit
b5fd5c57e7
|
@ -4,7 +4,7 @@
|
|||
|
||||
<groupId>com.lishid</groupId>
|
||||
<artifactId>orebfuscator</artifactId>
|
||||
<version>4.4.1-SNAPSHOT</version>
|
||||
<version>4.4.2-SNAPSHOT</version>
|
||||
<packaging>jar</packaging>
|
||||
|
||||
<name>Orebfuscator4</name>
|
||||
|
|
|
@ -7,17 +7,26 @@ package com.lishid.orebfuscator.chunkmap;
|
|||
|
||||
import java.io.IOException;
|
||||
import java.util.Arrays;
|
||||
import java.util.Stack;
|
||||
|
||||
import com.lishid.orebfuscator.NmsInstance;
|
||||
|
||||
public class ChunkMapManager {
|
||||
private static final ThreadLocal<ChunkMapBuffer> _buffer = new ThreadLocal<ChunkMapBuffer>() {
|
||||
@Override
|
||||
protected ChunkMapBuffer initialValue() {
|
||||
return new ChunkMapBuffer();
|
||||
}
|
||||
};
|
||||
|
||||
public class ChunkMapManager implements AutoCloseable {
|
||||
private static final Object _lock = new Object();
|
||||
private static final Stack<ChunkMapBuffer> _bufferStack = new Stack<>();
|
||||
|
||||
private static ChunkMapBuffer popBuffer() {
|
||||
synchronized(_lock) {
|
||||
return _bufferStack.isEmpty() ? new ChunkMapBuffer() : _bufferStack.pop();
|
||||
}
|
||||
}
|
||||
|
||||
private static void pushBuffer(ChunkMapBuffer buffer) {
|
||||
synchronized(_lock) {
|
||||
_bufferStack.push(buffer);
|
||||
}
|
||||
}
|
||||
|
||||
private ChunkMapBuffer buffer;
|
||||
private ChunkData chunkData;
|
||||
private ChunkReader reader;
|
||||
|
@ -42,43 +51,51 @@ public class ChunkMapManager {
|
|||
return this.chunkData;
|
||||
}
|
||||
|
||||
public ChunkMapManager(ChunkData chunkData) {
|
||||
this.buffer = _buffer.get();
|
||||
this.chunkData = chunkData;
|
||||
}
|
||||
|
||||
public void init() throws IOException {
|
||||
this.reader = new ChunkReader(this.chunkData.data);
|
||||
this.sectionCount = 0;
|
||||
this.sectionIndex = -1;
|
||||
this.minX = this.chunkData.chunkX << 4;
|
||||
this.maxX = this.minX + 15;
|
||||
this.minZ = this.chunkData.chunkZ << 4;
|
||||
this.maxZ = this.minZ + 15;
|
||||
|
||||
this.buffer.lightArrayLength = 2048;
|
||||
private ChunkMapManager() {
|
||||
|
||||
}
|
||||
|
||||
public static ChunkMapManager create(ChunkData chunkData) throws IOException {
|
||||
ChunkMapManager manager = new ChunkMapManager();
|
||||
manager.chunkData = chunkData;
|
||||
manager.buffer = popBuffer();
|
||||
manager.reader = new ChunkReader(chunkData.data);
|
||||
manager.sectionCount = 0;
|
||||
manager.sectionIndex = -1;
|
||||
manager.minX = chunkData.chunkX << 4;
|
||||
manager.maxX = manager.minX + 15;
|
||||
manager.minZ = chunkData.chunkZ << 4;
|
||||
manager.maxZ = manager.minZ + 15;
|
||||
|
||||
manager.buffer.lightArrayLength = 2048;
|
||||
|
||||
if(this.chunkData.isOverworld) {
|
||||
this.buffer.lightArrayLength <<= 1;
|
||||
if(chunkData.isOverworld) {
|
||||
manager.buffer.lightArrayLength <<= 1;
|
||||
}
|
||||
|
||||
manager.buffer.writer.init();
|
||||
|
||||
this.buffer.writer.init();
|
||||
|
||||
int mask = this.chunkData.primaryBitMask;
|
||||
int mask = chunkData.primaryBitMask;
|
||||
|
||||
while(mask != 0) {
|
||||
if((mask & 0x1) != 0) {
|
||||
this.sectionCount++;
|
||||
manager.sectionCount++;
|
||||
}
|
||||
|
||||
mask >>>= 1;
|
||||
}
|
||||
|
||||
this.buffer.clearLayers();
|
||||
|
||||
moveToNextLayer();
|
||||
manager.buffer.clearLayers();
|
||||
|
||||
manager.moveToNextLayer();
|
||||
|
||||
return manager;
|
||||
}
|
||||
|
||||
|
||||
public void close() throws Exception {
|
||||
pushBuffer(this.buffer);
|
||||
}
|
||||
|
||||
public boolean inputHasNonAirBlock() {
|
||||
return this.buffer.paletteLength > 1 || NmsInstance.current.isAir(this.buffer.palette[0]);
|
||||
}
|
||||
|
|
|
@ -59,7 +59,7 @@ public class ChunkReader {
|
|||
|
||||
private void readLong() throws IOException {
|
||||
if(this.byteIndex + 7 >= this.data.length) {
|
||||
throw new IOException("No data to read.");
|
||||
throw new IOException("No data to read. byteIndex = " + this.byteIndex);
|
||||
}
|
||||
|
||||
this.buffer = ((this.data[this.byteIndex] & 0xffL) << 56)
|
||||
|
@ -83,7 +83,7 @@ public class ChunkReader {
|
|||
value |= (b & 0x7F) << (size++ * 7);
|
||||
|
||||
if(size > 5) {
|
||||
throw new IOException("Invalid VarInt.");
|
||||
throw new IOException("Invalid VarInt. byteIndex = " + this.byteIndex + ", value = " + value + ", size = " + size);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -92,7 +92,7 @@ public class ChunkReader {
|
|||
|
||||
public int readByte() throws IOException {
|
||||
if(this.byteIndex >= this.data.length) {
|
||||
throw new IOException("No data to read.");
|
||||
throw new IOException("No data to read. byteIndex = " + this.byteIndex);
|
||||
}
|
||||
|
||||
return this.data[this.byteIndex++] & 0xff;
|
||||
|
|
|
@ -18,6 +18,7 @@ package com.lishid.orebfuscator.hook;
|
|||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.logging.Level;
|
||||
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.entity.Player;
|
||||
|
@ -50,6 +51,8 @@ public class ProtocolLibHook {
|
|||
this.manager.addPacketListener(new PacketAdapter(plugin, PacketType.Play.Server.MAP_CHUNK) {
|
||||
@Override
|
||||
public void onPacketSending(PacketEvent event) {
|
||||
ChunkData chunkData = null;
|
||||
|
||||
try {
|
||||
Player player = event.getPlayer();
|
||||
|
||||
|
@ -72,7 +75,7 @@ public class ProtocolLibHook {
|
|||
|
||||
List nmsTags = list.read(0);
|
||||
|
||||
ChunkData chunkData = new ChunkData();
|
||||
chunkData = new ChunkData();
|
||||
chunkData.chunkX = ints.read(0);
|
||||
chunkData.chunkZ = ints.read(1);
|
||||
chunkData.groundUpContinuous = bools.read(0);
|
||||
|
@ -83,7 +86,7 @@ public class ProtocolLibHook {
|
|||
|
||||
Calculations.Result result = Calculations.obfuscateOrUseCache(chunkData, player, worldConfig);
|
||||
|
||||
if(result.output != null) {
|
||||
if(result != null && result.output != null) {
|
||||
byteArray.write(0, result.output);
|
||||
|
||||
if(nmsTags != null) {
|
||||
|
@ -92,6 +95,10 @@ public class ProtocolLibHook {
|
|||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
if(chunkData != null) {
|
||||
Orebfuscator.logger.log(Level.SEVERE, "ChunkX = " + chunkData.chunkX + ", chunkZ = " + chunkData.chunkZ);
|
||||
}
|
||||
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
@ -147,7 +154,7 @@ public class ProtocolLibHook {
|
|||
}
|
||||
}
|
||||
|
||||
/*
|
||||
/*
|
||||
private static boolean _isSaved;
|
||||
private void saveTestData(ChunkData chunkData) {
|
||||
if(_isSaved) return;
|
||||
|
@ -156,7 +163,7 @@ public class ProtocolLibHook {
|
|||
|
||||
FileOutputStream fos;
|
||||
try {
|
||||
fos = new FileOutputStream("D:\\Temp\\chunk.dat");
|
||||
fos = new FileOutputStream("D:\\Temp\\chunk_X" + chunkData.chunkX + "_Z" + chunkData.chunkZ + ".dat");
|
||||
fos.write(chunkData.chunkX & 0xff);
|
||||
fos.write((chunkData.chunkX >> 8) & 0xff);
|
||||
fos.write(chunkData.chunkZ & 0xff);
|
||||
|
|
|
@ -48,7 +48,7 @@ public class Calculations {
|
|||
|
||||
private static Random random = new Random();
|
||||
|
||||
public static Result obfuscateOrUseCache(ChunkData chunkData, Player player, WorldConfig worldConfig) throws IOException {
|
||||
public static Result obfuscateOrUseCache(ChunkData chunkData, Player player, WorldConfig worldConfig) throws Exception {
|
||||
if(chunkData.primaryBitMask == 0) return null;
|
||||
|
||||
byte[] output;
|
||||
|
@ -67,7 +67,7 @@ public class Calculations {
|
|||
removedEntities = new ArrayList<>();
|
||||
|
||||
output = obfuscate(worldConfig, chunkData, player, proximityBlocks, removedEntities);
|
||||
|
||||
|
||||
if (cache != null) {
|
||||
// If cache is still allowed
|
||||
if(chunkData.useCache) {
|
||||
|
@ -137,7 +137,7 @@ public class Calculations {
|
|||
Player player,
|
||||
ArrayList<BlockCoord> proximityBlocks,
|
||||
ArrayList<BlockCoord> removedEntities
|
||||
) throws IOException
|
||||
) throws Exception
|
||||
{
|
||||
ProximityHiderConfig proximityHider = worldConfig.getProximityHiderConfig();
|
||||
int initialRadius = Orebfuscator.config.getInitialRadius();
|
||||
|
@ -149,7 +149,6 @@ public class Calculations {
|
|||
|
||||
int engineMode = Orebfuscator.config.getEngineMode();
|
||||
int maxChance = worldConfig.getAirGeneratorMaxChance();
|
||||
int incrementMax = maxChance;
|
||||
|
||||
int randomBlocksLength = worldConfig.getRandomBlocks().length;
|
||||
boolean randomAlternate = false;
|
||||
|
@ -157,132 +156,133 @@ public class Calculations {
|
|||
int startX = chunkData.chunkX << 4;
|
||||
int startZ = chunkData.chunkZ << 4;
|
||||
|
||||
ChunkMapManager manager = new ChunkMapManager(chunkData);
|
||||
manager.init();
|
||||
byte[] output;
|
||||
|
||||
for(int i = 0; i < manager.getSectionCount(); i++) {
|
||||
worldConfig.shuffleRandomBlocks();
|
||||
try (ChunkMapManager manager = ChunkMapManager.create(chunkData)) {
|
||||
for (int i = 0; i < manager.getSectionCount(); i++) {
|
||||
worldConfig.shuffleRandomBlocks();
|
||||
|
||||
for(int offsetY = 0; offsetY < 16; offsetY++) {
|
||||
for(int offsetZ = 0; offsetZ < 16; offsetZ++) {
|
||||
incrementMax = (maxChance + random(maxChance)) / 2;
|
||||
|
||||
for(int offsetX = 0; offsetX < 16; offsetX++) {
|
||||
int blockData = manager.readNextBlock();
|
||||
int x = startX | offsetX;
|
||||
int y = manager.getY();
|
||||
int z = startZ | offsetZ;
|
||||
for (int offsetY = 0; offsetY < 16; offsetY++) {
|
||||
for (int offsetZ = 0; offsetZ < 16; offsetZ++) {
|
||||
int incrementMax = (maxChance + random(maxChance)) / 2;
|
||||
|
||||
// Initialize data
|
||||
int obfuscateBits = worldConfig.getObfuscatedBits(blockData);
|
||||
boolean obfuscateFlag = (obfuscateBits & Globals.MASK_OBFUSCATE) != 0;
|
||||
boolean proximityHiderFlag = (obfuscateBits & Globals.MASK_PROXIMITYHIDER) != 0;
|
||||
boolean darknessBlockFlag = (obfuscateBits & Globals.MASK_DARKNESSBLOCK) != 0;
|
||||
boolean tileEntityFlag = (obfuscateBits & Globals.MASK_TILEENTITY) != 0;
|
||||
for (int offsetX = 0; offsetX < 16; offsetX++) {
|
||||
int blockData = manager.readNextBlock();
|
||||
int x = startX | offsetX;
|
||||
int y = manager.getY();
|
||||
int z = startZ | offsetZ;
|
||||
|
||||
boolean obfuscate = false;
|
||||
boolean specialObfuscate = false;
|
||||
// Initialize data
|
||||
int obfuscateBits = worldConfig.getObfuscatedBits(blockData);
|
||||
boolean obfuscateFlag = (obfuscateBits & Globals.MASK_OBFUSCATE) != 0;
|
||||
boolean proximityHiderFlag = (obfuscateBits & Globals.MASK_PROXIMITYHIDER) != 0;
|
||||
boolean darknessBlockFlag = (obfuscateBits & Globals.MASK_DARKNESSBLOCK) != 0;
|
||||
boolean tileEntityFlag = (obfuscateBits & Globals.MASK_TILEENTITY) != 0;
|
||||
|
||||
// Check if the block should be obfuscated for the default engine modes
|
||||
if (obfuscateFlag) {
|
||||
if (initialRadius == 0) {
|
||||
// Do not interfere with PH
|
||||
if (proximityHiderFlag && proximityHider.isEnabled() && proximityHider.isProximityObfuscated(y, blockData)) {
|
||||
if (!areAjacentBlocksTransparent(manager, player.getWorld(), false, x, y, z, 1)) {
|
||||
boolean obfuscate = false;
|
||||
boolean specialObfuscate = false;
|
||||
|
||||
// Check if the block should be obfuscated for the default engine modes
|
||||
if (obfuscateFlag) {
|
||||
if (initialRadius == 0) {
|
||||
// Do not interfere with PH
|
||||
if (proximityHiderFlag && proximityHider.isEnabled() && proximityHider.isProximityObfuscated(y, blockData)) {
|
||||
if (!areAjacentBlocksTransparent(manager, player.getWorld(), false, x, y, z, 1)) {
|
||||
obfuscate = true;
|
||||
}
|
||||
} else {
|
||||
// Obfuscate all blocks
|
||||
obfuscate = true;
|
||||
}
|
||||
} else {
|
||||
// Obfuscate all blocks
|
||||
obfuscate = true;
|
||||
}
|
||||
} else {
|
||||
// Check if any nearby blocks are transparent
|
||||
if (!areAjacentBlocksTransparent(manager, player.getWorld(), false, x, y, z, initialRadius)) {
|
||||
obfuscate = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Check if the block should be obfuscated because of proximity check
|
||||
if (!obfuscate && proximityHiderFlag && proximityHider.isEnabled() && proximityHider.isProximityObfuscated(y, blockData)) {
|
||||
BlockCoord block = new BlockCoord(x, y, z);
|
||||
if (block != null) {
|
||||
proximityBlocks.add(block);
|
||||
}
|
||||
|
||||
obfuscate = true;
|
||||
if (proximityHider.isUseSpecialBlock()) {
|
||||
specialObfuscate = true;
|
||||
}
|
||||
}
|
||||
|
||||
// Check if the block is obfuscated
|
||||
if (obfuscate && (!worldConfig.isBypassObfuscationForSignsWithText() || canObfuscate(chunkData, x, y, z, blockData))) {
|
||||
if (specialObfuscate) {
|
||||
// Proximity hider
|
||||
blockData = proximityHider.getSpecialBlockID();
|
||||
} else {
|
||||
if (engineMode == 1) {
|
||||
// Engine mode 1, replace with stone
|
||||
blockData = worldConfig.getMode1BlockId();
|
||||
} else if (engineMode == 2) {
|
||||
// Ending mode 2, replace with random block
|
||||
if (randomBlocksLength > 1) {
|
||||
randomIncrement = CalculationsUtil.increment(randomIncrement, randomBlocksLength);
|
||||
}
|
||||
|
||||
blockData = worldConfig.getRandomBlock(randomIncrement, randomAlternate);
|
||||
randomAlternate = !randomAlternate;
|
||||
}
|
||||
// Anti texturepack and freecam
|
||||
if (worldConfig.isAntiTexturePackAndFreecam()) {
|
||||
// Add random air blocks
|
||||
randomIncrement2 = random(incrementMax);
|
||||
|
||||
if (randomIncrement2 == 0) {
|
||||
randomCave = 1 + random(3);
|
||||
}
|
||||
|
||||
if (randomCave > 0) {
|
||||
blockData = NmsInstance.current.getCaveAirBlockId();
|
||||
randomCave--;
|
||||
// Check if any nearby blocks are transparent
|
||||
if (!areAjacentBlocksTransparent(manager, player.getWorld(), false, x, y, z, initialRadius)) {
|
||||
obfuscate = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Check if the block should be obfuscated because of the darkness
|
||||
if (!obfuscate && darknessBlockFlag && worldConfig.isDarknessHideBlocks()) {
|
||||
if (!areAjacentBlocksBright(player.getWorld(), x, y, z, 1)) {
|
||||
// Hide block, setting it to air
|
||||
blockData = NmsInstance.current.getCaveAirBlockId();
|
||||
// Check if the block should be obfuscated because of proximity check
|
||||
if (!obfuscate && proximityHiderFlag && proximityHider.isEnabled() && proximityHider.isProximityObfuscated(y, blockData)) {
|
||||
BlockCoord block = new BlockCoord(x, y, z);
|
||||
if (block != null) {
|
||||
proximityBlocks.add(block);
|
||||
}
|
||||
|
||||
obfuscate = true;
|
||||
if (proximityHider.isUseSpecialBlock()) {
|
||||
specialObfuscate = true;
|
||||
}
|
||||
}
|
||||
|
||||
// Check if the block is obfuscated
|
||||
if (obfuscate && (!worldConfig.isBypassObfuscationForSignsWithText() || canObfuscate(chunkData, x, y, z, blockData))) {
|
||||
if (specialObfuscate) {
|
||||
// Proximity hider
|
||||
blockData = proximityHider.getSpecialBlockID();
|
||||
} else {
|
||||
if (engineMode == 1) {
|
||||
// Engine mode 1, replace with stone
|
||||
blockData = worldConfig.getMode1BlockId();
|
||||
} else if (engineMode == 2) {
|
||||
// Ending mode 2, replace with random block
|
||||
if (randomBlocksLength > 1) {
|
||||
randomIncrement = CalculationsUtil.increment(randomIncrement, randomBlocksLength);
|
||||
}
|
||||
|
||||
blockData = worldConfig.getRandomBlock(randomIncrement, randomAlternate);
|
||||
randomAlternate = !randomAlternate;
|
||||
}
|
||||
// Anti texturepack and freecam
|
||||
if (worldConfig.isAntiTexturePackAndFreecam()) {
|
||||
// Add random air blocks
|
||||
randomIncrement2 = random(incrementMax);
|
||||
|
||||
if (randomIncrement2 == 0) {
|
||||
randomCave = 1 + random(3);
|
||||
}
|
||||
|
||||
if (randomCave > 0) {
|
||||
blockData = NmsInstance.current.getCaveAirBlockId();
|
||||
randomCave--;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Check if the block should be obfuscated because of the darkness
|
||||
if (!obfuscate && darknessBlockFlag && worldConfig.isDarknessHideBlocks()) {
|
||||
if (!areAjacentBlocksBright(player.getWorld(), x, y, z, 1)) {
|
||||
// Hide block, setting it to air
|
||||
blockData = NmsInstance.current.getCaveAirBlockId();
|
||||
obfuscate = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (obfuscate && tileEntityFlag) {
|
||||
removedEntities.add(new BlockCoord(x, y, z));
|
||||
}
|
||||
|
||||
if (offsetY == 0 && offsetZ == 0 && offsetX == 0) {
|
||||
manager.finalizeOutput();
|
||||
manager.initOutputPalette();
|
||||
addBlocksToPalette(manager, worldConfig);
|
||||
manager.initOutputSection();
|
||||
}
|
||||
|
||||
manager.writeOutputBlock(blockData);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (obfuscate && tileEntityFlag) {
|
||||
removedEntities.add(new BlockCoord(x, y, z));
|
||||
}
|
||||
manager.finalizeOutput();
|
||||
|
||||
if(offsetY == 0 && offsetZ == 0 && offsetX == 0) {
|
||||
manager.finalizeOutput();
|
||||
manager.initOutputPalette();
|
||||
addBlocksToPalette(manager, worldConfig);
|
||||
manager.initOutputSection();
|
||||
}
|
||||
|
||||
manager.writeOutputBlock(blockData);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
manager.finalizeOutput();
|
||||
|
||||
byte[] output = manager.createOutput();
|
||||
output = manager.createOutput();
|
||||
}
|
||||
|
||||
ProximityHider.addProximityBlocks(player, chunkData.chunkX, chunkData.chunkZ, proximityBlocks);
|
||||
|
||||
|
||||
//Orebfuscator.log("Create new chunk data for x = " + chunkData.chunkX + ", z = " + chunkData.chunkZ);/*debug*/
|
||||
|
||||
return output;
|
||||
|
|
Loading…
Reference in New Issue