2019-09-05 18:26:13 +02:00
|
|
|
package de.steamwar.fightsystem.utils;
|
2019-04-25 20:33:36 +02:00
|
|
|
|
|
|
|
import com.comphenix.protocol.PacketType;
|
|
|
|
import com.comphenix.protocol.ProtocolLibrary;
|
|
|
|
import com.comphenix.protocol.events.PacketAdapter;
|
|
|
|
import com.comphenix.protocol.events.PacketContainer;
|
|
|
|
import com.comphenix.protocol.events.PacketEvent;
|
|
|
|
import com.comphenix.protocol.reflect.StructureModifier;
|
2019-05-28 06:16:16 +02:00
|
|
|
import com.comphenix.protocol.wrappers.BlockPosition;
|
|
|
|
import com.comphenix.protocol.wrappers.ChunkCoordIntPair;
|
2019-04-25 20:33:36 +02:00
|
|
|
import com.comphenix.protocol.wrappers.MultiBlockChangeInfo;
|
|
|
|
import com.comphenix.protocol.wrappers.WrappedBlockData;
|
|
|
|
import com.comphenix.protocol.wrappers.nbt.NbtCompound;
|
|
|
|
import com.comphenix.protocol.wrappers.nbt.NbtFactory;
|
|
|
|
import com.google.common.primitives.Bytes;
|
2019-11-10 22:34:22 +01:00
|
|
|
import de.steamwar.core.Core;
|
2019-09-05 18:26:13 +02:00
|
|
|
import de.steamwar.fightsystem.FightSystem;
|
|
|
|
import de.steamwar.fightsystem.fight.Fight;
|
|
|
|
import de.steamwar.fightsystem.fight.FightTeam;
|
2019-09-25 18:21:20 +02:00
|
|
|
import io.netty.buffer.ByteBuf;
|
|
|
|
import io.netty.buffer.UnpooledByteBufAllocator;
|
2019-06-08 12:57:58 +02:00
|
|
|
import javafx.util.Pair;
|
2019-06-05 22:14:27 +02:00
|
|
|
import org.bukkit.Bukkit;
|
2019-05-28 06:16:16 +02:00
|
|
|
import org.bukkit.GameMode;
|
2019-04-25 20:33:36 +02:00
|
|
|
import org.bukkit.Material;
|
|
|
|
import org.bukkit.entity.Player;
|
|
|
|
|
2019-11-03 17:26:51 +01:00
|
|
|
import java.util.*;
|
2019-04-25 20:33:36 +02:00
|
|
|
|
|
|
|
public class TechHider {
|
2019-06-22 17:11:10 +02:00
|
|
|
private TechHider(){}
|
|
|
|
|
2019-11-03 17:26:51 +01:00
|
|
|
private static Map<PacketContainer, PacketContainer> packetCache = new HashMap<>();
|
|
|
|
|
2019-05-28 06:16:16 +02:00
|
|
|
private static int arenaMinX;
|
|
|
|
private static int arenaMaxX;
|
|
|
|
private static int arenaMinZ;
|
|
|
|
private static int arenaMaxZ;
|
|
|
|
private static int blueMinX;
|
|
|
|
private static int blueMaxX;
|
|
|
|
private static int blueMinZ;
|
|
|
|
private static int blueMaxZ;
|
|
|
|
private static int redMinX;
|
|
|
|
private static int redMaxX;
|
|
|
|
private static int redMinZ;
|
|
|
|
private static int redMaxZ;
|
2019-06-05 22:14:27 +02:00
|
|
|
private static short obfuscateShift4;
|
2019-11-10 17:29:59 +01:00
|
|
|
//private static final short BITMASK = 0x1FF;
|
2019-05-28 06:16:16 +02:00
|
|
|
private static Material obfuscateMaterial;
|
2019-10-07 08:23:24 +02:00
|
|
|
private static boolean running = false;
|
|
|
|
private static int threadMultiplier = 1;
|
2019-05-28 06:16:16 +02:00
|
|
|
|
2019-04-25 20:33:36 +02:00
|
|
|
public static void init(){
|
2019-09-12 20:46:21 +02:00
|
|
|
if(disabled())
|
|
|
|
return;
|
|
|
|
|
2019-07-01 18:04:46 +02:00
|
|
|
arenaMinX = posToChunk(Config.ArenaMinX);
|
|
|
|
arenaMinZ = posToChunk(Config.ArenaMinZ);
|
|
|
|
blueMinX = posToChunk(Config.TeamBlueCornerX);
|
|
|
|
blueMinZ = posToChunk(Config.TeamBlueCornerZ);
|
|
|
|
redMinX = posToChunk(Config.TeamRedCornerX);
|
|
|
|
redMinZ = posToChunk(Config.TeamRedCornerZ);
|
|
|
|
|
|
|
|
arenaMaxX = posToChunk(Config.ArenaMaxX) + 1;
|
|
|
|
arenaMaxZ = posToChunk(Config.ArenaMaxZ) + 1;
|
|
|
|
blueMaxX = posToChunk(Config.TeamBlueCornerX + Config.SchemsizeX) + 1;
|
|
|
|
blueMaxZ = posToChunk(Config.TeamBlueCornerZ + Config.SchemsizeZ) + 1;
|
|
|
|
redMaxX = posToChunk(Config.TeamRedCornerX + Config.SchemsizeX) + 1;
|
|
|
|
redMaxZ = posToChunk(Config.TeamRedCornerZ + Config.SchemsizeZ) + 1;
|
|
|
|
|
2019-06-05 22:14:27 +02:00
|
|
|
obfuscateShift4 = (short)(Config.ObfuscateWith << 4);
|
2019-11-10 17:29:59 +01:00
|
|
|
//noinspection deprecation
|
2019-05-28 06:16:16 +02:00
|
|
|
obfuscateMaterial = Material.getMaterial(Config.ObfuscateWith);
|
|
|
|
|
2019-09-05 18:26:13 +02:00
|
|
|
if(Config.event())
|
|
|
|
threadMultiplier = 4;
|
|
|
|
|
2019-11-10 22:34:22 +01:00
|
|
|
if(Core.getVersion() > 8){
|
|
|
|
ProtocolLibrary.getProtocolManager().addPacketListener(new PacketAdapter(FightSystem.getPlugin(), PacketType.Play.Client.USE_ITEM) {
|
|
|
|
@Override
|
|
|
|
public void onPacketReceiving(PacketEvent e) {
|
|
|
|
Player p = e.getPlayer();
|
2019-10-07 08:23:24 +02:00
|
|
|
|
2019-11-10 22:34:22 +01:00
|
|
|
if(p.getGameMode() == GameMode.SPECTATOR){
|
|
|
|
e.setCancelled(true);
|
|
|
|
}
|
2019-10-07 08:23:24 +02:00
|
|
|
}
|
2019-11-10 22:34:22 +01:00
|
|
|
});
|
|
|
|
}
|
2019-11-08 09:32:43 +01:00
|
|
|
ProtocolLibrary.getProtocolManager().addPacketListener(new PacketAdapter(FightSystem.getPlugin(), PacketType.Play.Client.USE_ENTITY) {
|
2019-10-07 08:23:24 +02:00
|
|
|
@Override
|
|
|
|
public void onPacketReceiving(PacketEvent e) {
|
|
|
|
Player p = e.getPlayer();
|
|
|
|
|
|
|
|
if(p.getGameMode() == GameMode.SPECTATOR){
|
|
|
|
e.setCancelled(true);
|
|
|
|
}
|
|
|
|
}
|
2019-11-08 09:32:43 +01:00
|
|
|
});
|
2019-10-07 08:23:24 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
public static void start(){
|
|
|
|
if(running)
|
|
|
|
return;
|
|
|
|
running = true;
|
|
|
|
|
|
|
|
if(disabled())
|
|
|
|
return;
|
|
|
|
|
2019-11-03 17:26:51 +01:00
|
|
|
Bukkit.getScheduler().runTaskTimer(FightSystem.getPlugin(), packetCache::clear, 1, 1);
|
|
|
|
|
2019-11-10 17:29:59 +01:00
|
|
|
chunkHider();
|
|
|
|
multiBlockHider();
|
|
|
|
blockHider();
|
|
|
|
blockActionHider();
|
|
|
|
}
|
|
|
|
|
|
|
|
private static boolean bypass(Player p, int chunkX, int chunkZ){
|
|
|
|
if(p == FightSystem.getEventLeiter())
|
|
|
|
return true;
|
|
|
|
|
|
|
|
FightTeam ft = Fight.getPlayerTeam(p);
|
|
|
|
if(ft == null){
|
|
|
|
//Außerhalb der Arena
|
|
|
|
return arenaMinX > chunkX ||
|
|
|
|
chunkX > arenaMaxX ||
|
|
|
|
arenaMinZ > chunkZ ||
|
|
|
|
chunkZ > arenaMaxZ;
|
|
|
|
}else if(ft.isBlue()){
|
|
|
|
return FightSystem.isEntern() ||
|
|
|
|
redMinX > chunkX ||
|
|
|
|
chunkX > redMaxX ||
|
|
|
|
redMinZ > chunkZ ||
|
|
|
|
chunkZ > redMaxZ;
|
|
|
|
}else{
|
|
|
|
return FightSystem.isEntern() ||
|
|
|
|
blueMinX > chunkX ||
|
|
|
|
chunkX > blueMaxX ||
|
|
|
|
blueMinZ > chunkZ ||
|
|
|
|
chunkZ > blueMaxZ;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
private static void chunkHider(){
|
|
|
|
ProtocolLibrary.getProtocolManager().getAsynchronousManager().registerAsyncHandler(new PacketAdapter(FightSystem.getPlugin(), PacketType.Play.Server.MAP_CHUNK) {
|
2019-04-25 20:33:36 +02:00
|
|
|
@Override
|
|
|
|
public void onPacketSending(PacketEvent e) {
|
2019-07-01 21:02:32 +02:00
|
|
|
PacketContainer packet = e.getPacket();
|
2019-04-25 20:33:36 +02:00
|
|
|
StructureModifier<Integer> ints = packet.getIntegers();
|
|
|
|
|
|
|
|
int chunkX = ints.read(0);
|
|
|
|
int chunkZ = ints.read(1);
|
2019-05-28 06:16:16 +02:00
|
|
|
Player p = e.getPlayer();
|
|
|
|
if(bypass(p, chunkX, chunkZ))
|
|
|
|
return;
|
|
|
|
|
2019-11-03 17:26:51 +01:00
|
|
|
PacketContainer cached = packetCache.get(packet);
|
|
|
|
if(cached != null){
|
|
|
|
e.setPacket(cached);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
cached = packet.deepClone();
|
|
|
|
packetCache.put(packet, cached);
|
|
|
|
e.setPacket(cached);
|
|
|
|
StructureModifier<List> list = cached.getSpecificModifier(List.class);
|
2019-07-01 21:02:32 +02:00
|
|
|
List nmsTags = list.read(0);
|
2019-04-25 20:33:36 +02:00
|
|
|
boolean changed = false;
|
|
|
|
for(int i = nmsTags.size() - 1; i >= 0; i--){
|
|
|
|
NbtCompound nbt = NbtFactory.fromNMSCompound(nmsTags.get(i));
|
2019-05-28 06:16:16 +02:00
|
|
|
if(Config.HiddenBlockEntities.contains(nbt.getString("id"))){
|
2019-04-25 20:33:36 +02:00
|
|
|
nmsTags.remove(i);
|
|
|
|
changed = true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if(changed){
|
|
|
|
list.write(0, nmsTags);
|
|
|
|
}
|
|
|
|
|
|
|
|
changed = false;
|
2019-11-03 17:26:51 +01:00
|
|
|
StructureModifier<byte[]> byteArray = cached.getByteArrays();
|
2019-04-25 20:33:36 +02:00
|
|
|
byte [] data = byteArray.read(0);
|
2019-09-29 19:35:32 +02:00
|
|
|
ByteBuf buffer = UnpooledByteBufAllocator.DEFAULT.directBuffer(data.length + 100);
|
2019-04-25 20:33:36 +02:00
|
|
|
int i = 0;
|
|
|
|
|
2019-09-25 18:21:20 +02:00
|
|
|
while(i < data.length){
|
|
|
|
byte bitsPerBlock = data[i++];
|
|
|
|
buffer.writeByte(bitsPerBlock);
|
2019-04-25 20:33:36 +02:00
|
|
|
if(bitsPerBlock < 4)
|
|
|
|
bitsPerBlock = 4;
|
|
|
|
else if(bitsPerBlock > 8){
|
|
|
|
bitsPerBlock = 13;
|
2019-09-29 19:35:32 +02:00
|
|
|
buffer.writeByte(data[++i]);
|
2019-04-25 20:33:36 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
if(bitsPerBlock != 13){
|
2019-09-25 18:21:20 +02:00
|
|
|
int paletteLength = readVarInt(data, i);
|
|
|
|
int paletteLengthLength = readVarIntLength(data, i);
|
|
|
|
buffer.writeBytes(data, i, paletteLengthLength);
|
|
|
|
i += paletteLengthLength;
|
2019-04-25 20:33:36 +02:00
|
|
|
for(int actPaletteId = 0; actPaletteId < paletteLength; actPaletteId++){
|
2019-09-25 18:21:20 +02:00
|
|
|
int actPalette = readVarInt(data, i);
|
|
|
|
int actPaletteLength = readVarIntLength(data, i);
|
2019-04-25 20:33:36 +02:00
|
|
|
|
|
|
|
int blockId = actPalette >> 4;
|
|
|
|
if(Config.HiddenBlocks.contains(blockId)){
|
2019-05-28 06:16:16 +02:00
|
|
|
byte[] a = writeVarInt(obfuscateShift4);
|
2019-09-25 18:21:20 +02:00
|
|
|
buffer.writeBytes(a);
|
2019-04-25 20:33:36 +02:00
|
|
|
changed = true;
|
|
|
|
}else{
|
2019-09-25 18:21:20 +02:00
|
|
|
buffer.writeBytes(data, i, actPaletteLength);
|
2019-04-25 20:33:36 +02:00
|
|
|
}
|
2019-09-25 18:21:20 +02:00
|
|
|
i += actPaletteLength;
|
2019-04-25 20:33:36 +02:00
|
|
|
}
|
2019-09-25 18:21:20 +02:00
|
|
|
int dataArrayLength = readVarInt(data, i);
|
|
|
|
int dataArrayLengthLength = readVarIntLength(data, i);
|
|
|
|
buffer.writeBytes(data, i, dataArrayLength * 8 + dataArrayLengthLength);
|
|
|
|
i += dataArrayLengthLength;
|
2019-04-25 20:33:36 +02:00
|
|
|
i += dataArrayLength * 8;
|
|
|
|
}else{
|
2019-09-25 18:21:20 +02:00
|
|
|
int dataArrayLength = readVarInt(data, i);
|
|
|
|
int dataArrayLengthLength = readVarIntLength(data, i);
|
|
|
|
buffer.writeBytes(data, i, dataArrayLength*8 + dataArrayLengthLength);
|
|
|
|
i += dataArrayLengthLength;
|
2019-06-08 12:57:58 +02:00
|
|
|
/*int arrayEnd = dataArrayLength * 8 + i;
|
2019-04-25 20:33:36 +02:00
|
|
|
int bitsOver = 8; //9 bits (id) + 4 bits (metadata)
|
|
|
|
while(i < arrayEnd){
|
2019-06-08 12:57:58 +02:00
|
|
|
int blockId = (newData.get(i++) & (BITMASK >> 9 - bitsOver)) << 9-bitsOver;
|
2019-04-25 20:33:36 +02:00
|
|
|
blockId += newData.get(i) >> bitsOver-1;
|
|
|
|
if(Config.HiddenBlocks.contains(blockId)){
|
2019-06-08 12:57:58 +02:00
|
|
|
final short debug = 44;
|
|
|
|
newData.set(i-1, (byte)(newData.get(i-1) & -(BITMASK >> 9-bitsOver) | debug >> 9-bitsOver));
|
|
|
|
newData.set(i, (byte)(newData.get(i) & -(BITMASK << bitsOver-1) | debug << bitsOver-1));
|
|
|
|
System.out.println(blockId + " replaced at " + chunkX + " " + chunkZ + " i:" + i + " " + String.format("%8s", Integer.toBinaryString(newData.get(i-1) & 0xFF)).replace(' ', '0') + String.format("%8s", Integer.toBinaryString(newData.get(i) & 0xFF)).replace(' ', '0') + " " + bitsOver);
|
|
|
|
changed = true;
|
2019-04-25 20:33:36 +02:00
|
|
|
}
|
|
|
|
bitsOver -= 5; // 13-8
|
|
|
|
if(bitsOver < 1){
|
|
|
|
i++;
|
|
|
|
bitsOver += 8;
|
|
|
|
}
|
2019-06-08 12:57:58 +02:00
|
|
|
}*/
|
|
|
|
i += dataArrayLength * 8;
|
2019-04-25 20:33:36 +02:00
|
|
|
}
|
|
|
|
|
2019-09-25 18:21:20 +02:00
|
|
|
buffer.writeBytes(data, i, 4096);
|
2019-04-25 20:33:36 +02:00
|
|
|
i += 4096; //Skylight (Not in Nether/End!!!) 2048 + Blocklight 2048
|
|
|
|
}
|
|
|
|
|
|
|
|
if(changed){
|
2019-09-29 19:35:32 +02:00
|
|
|
data = new byte[buffer.readableBytes()];
|
2019-09-25 18:21:20 +02:00
|
|
|
buffer.readBytes(data);
|
|
|
|
byteArray.write(0, data);
|
2019-04-25 20:33:36 +02:00
|
|
|
}
|
|
|
|
}
|
2019-11-10 17:29:59 +01:00
|
|
|
}).start(threadMultiplier * 4);
|
|
|
|
}
|
2019-11-03 17:26:51 +01:00
|
|
|
|
2019-11-10 17:29:59 +01:00
|
|
|
private static void multiBlockHider(){
|
2019-11-08 09:32:43 +01:00
|
|
|
ProtocolLibrary.getProtocolManager().addPacketListener(new PacketAdapter(FightSystem.getPlugin(), PacketType.Play.Server.MULTI_BLOCK_CHANGE) {
|
2019-04-25 20:33:36 +02:00
|
|
|
@Override
|
|
|
|
public void onPacketSending(PacketEvent e) {
|
2019-07-01 21:02:32 +02:00
|
|
|
PacketContainer packet = e.getPacket();
|
2019-04-25 20:33:36 +02:00
|
|
|
|
2019-05-28 06:16:16 +02:00
|
|
|
Player p = e.getPlayer();
|
2019-06-14 19:11:09 +02:00
|
|
|
ChunkCoordIntPair pos = packet.getChunkCoordIntPairs().read(0);
|
2019-05-28 06:16:16 +02:00
|
|
|
if(bypass(p, pos.getChunkX(), pos.getChunkZ()))
|
|
|
|
return;
|
|
|
|
|
2019-11-03 17:26:51 +01:00
|
|
|
PacketContainer cached = packetCache.get(packet);
|
|
|
|
if(cached != null){
|
|
|
|
e.setPacket(cached);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
cached = packet.shallowClone();
|
|
|
|
packetCache.put(packet, cached);
|
|
|
|
e.setPacket(cached);
|
|
|
|
StructureModifier<MultiBlockChangeInfo[]> blockStructure = cached.getMultiBlockChangeInfoArrays();
|
2019-07-01 21:02:32 +02:00
|
|
|
MultiBlockChangeInfo[] changes = blockStructure.read(0).clone();
|
2019-05-28 06:16:16 +02:00
|
|
|
boolean changed = false;
|
2019-04-25 20:33:36 +02:00
|
|
|
for(MultiBlockChangeInfo mbci : changes){
|
|
|
|
WrappedBlockData block = mbci.getData();
|
2019-11-10 17:29:59 +01:00
|
|
|
//noinspection deprecation
|
2019-04-25 20:33:36 +02:00
|
|
|
if(Config.HiddenBlocks.contains(block.getType().getId())){
|
|
|
|
changed = true;
|
2019-05-28 06:16:16 +02:00
|
|
|
block.setType(obfuscateMaterial);
|
2019-04-25 20:33:36 +02:00
|
|
|
mbci.setData(block);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if(changed){
|
|
|
|
blockStructure.write(0, changes);
|
|
|
|
}
|
|
|
|
}
|
2019-11-08 09:32:43 +01:00
|
|
|
});
|
2019-11-10 17:29:59 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
private static void blockHider(){
|
|
|
|
ProtocolLibrary.getProtocolManager().addPacketListener(new PacketAdapter(FightSystem.getPlugin(), PacketType.Play.Server.BLOCK_CHANGE) {
|
2019-04-25 20:33:36 +02:00
|
|
|
@Override
|
|
|
|
public void onPacketSending(PacketEvent e) {
|
|
|
|
PacketContainer packet = e.getPacket();
|
2019-05-28 06:16:16 +02:00
|
|
|
BlockPosition pos = packet.getBlockPositionModifier().read(0);
|
2019-07-01 18:04:46 +02:00
|
|
|
|
2019-05-28 06:16:16 +02:00
|
|
|
Player p = e.getPlayer();
|
2019-07-01 18:04:46 +02:00
|
|
|
if(bypass(p, posToChunk(pos.getX()), posToChunk(pos.getZ())))
|
2019-05-28 06:16:16 +02:00
|
|
|
return;
|
2019-04-25 20:33:36 +02:00
|
|
|
|
2019-11-10 17:29:59 +01:00
|
|
|
PacketContainer cached = packetCache.get(packet);
|
|
|
|
if(cached != null){
|
|
|
|
e.setPacket(cached);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
cached = packet.deepClone();
|
|
|
|
packetCache.put(packet, cached);
|
|
|
|
e.setPacket(cached);
|
|
|
|
StructureModifier<WrappedBlockData> blockStructure = cached.getBlockData();
|
|
|
|
WrappedBlockData block = blockStructure.read(0);
|
|
|
|
//noinspection deprecation
|
|
|
|
if(Config.HiddenBlocks.contains(block.getType().getId())){
|
|
|
|
block.setType(obfuscateMaterial);
|
|
|
|
blockStructure.write(0, block);
|
|
|
|
}
|
2019-04-25 20:33:36 +02:00
|
|
|
}
|
2019-11-08 09:32:43 +01:00
|
|
|
});
|
2019-04-25 20:33:36 +02:00
|
|
|
}
|
|
|
|
|
2019-11-10 17:29:59 +01:00
|
|
|
private static void blockActionHider(){
|
|
|
|
ProtocolLibrary.getProtocolManager().addPacketListener(new PacketAdapter(FightSystem.getPlugin(), PacketType.Play.Server.BLOCK_ACTION) {
|
|
|
|
@Override
|
|
|
|
public void onPacketSending(PacketEvent e) {
|
|
|
|
PacketContainer packet = e.getPacket();
|
|
|
|
BlockPosition pos = packet.getBlockPositionModifier().read(0);
|
2019-09-05 18:26:13 +02:00
|
|
|
|
2019-11-10 17:29:59 +01:00
|
|
|
Player p = e.getPlayer();
|
|
|
|
if(bypass(p, posToChunk(pos.getX()), posToChunk(pos.getZ())))
|
|
|
|
return;
|
|
|
|
|
|
|
|
e.setCancelled(true);
|
|
|
|
}
|
|
|
|
});
|
2019-05-28 06:16:16 +02:00
|
|
|
}
|
|
|
|
|
2019-06-08 12:57:58 +02:00
|
|
|
public static List<Pair<Integer, Integer>> prepareChunkReload(Player p){
|
2019-09-12 20:46:21 +02:00
|
|
|
if(disabled())
|
|
|
|
return Collections.emptyList();
|
2019-06-08 12:57:58 +02:00
|
|
|
List<Pair<Integer, Integer>> chunksToReload = new ArrayList<>();
|
|
|
|
for(int x = arenaMinX; x <= arenaMaxX; x++)
|
|
|
|
for(int z = arenaMinZ; z <= arenaMaxZ; z++)
|
|
|
|
if(!bypass(p, x, z))
|
|
|
|
chunksToReload.add(new Pair<>(x, z));
|
|
|
|
return chunksToReload;
|
|
|
|
}
|
2019-06-05 22:14:27 +02:00
|
|
|
|
2019-06-08 12:57:58 +02:00
|
|
|
public static void reloadChunks(Player p, List<Pair<Integer, Integer>> chunksToReload){
|
2019-09-12 20:46:21 +02:00
|
|
|
if(disabled())
|
|
|
|
return;
|
2019-06-08 12:57:58 +02:00
|
|
|
Bukkit.getScheduler().runTaskLater(FightSystem.getPlugin(), () -> {
|
2019-07-01 18:04:46 +02:00
|
|
|
for(Pair<Integer, Integer> chunk : chunksToReload){
|
|
|
|
if(bypass(p, chunk.getKey(), chunk.getValue()))
|
2019-11-10 22:34:22 +01:00
|
|
|
reloadChunk(p, chunk);
|
2019-07-01 18:04:46 +02:00
|
|
|
}
|
2019-06-22 17:11:10 +02:00
|
|
|
}, 40);
|
2019-06-05 22:14:27 +02:00
|
|
|
}
|
|
|
|
|
2019-11-10 22:34:22 +01:00
|
|
|
private static void reloadChunk(Player p, Pair<Integer, Integer> chunk){
|
|
|
|
switch(Core.getVersion()){
|
|
|
|
case 8:
|
|
|
|
TechHider_v8.reloadChunk(p, chunk);
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
TechHider_v12.reloadChunk(p, chunk);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-09-12 20:46:21 +02:00
|
|
|
private static boolean disabled(){
|
|
|
|
return Config.event() && Config.OnlyPublicSchematics;
|
|
|
|
}
|
|
|
|
|
2019-07-01 18:04:46 +02:00
|
|
|
private static int posToChunk(int c){
|
|
|
|
int chunk = c / 16;
|
|
|
|
if(c<0)
|
|
|
|
chunk--;
|
|
|
|
return chunk;
|
|
|
|
}
|
|
|
|
|
2019-05-28 06:16:16 +02:00
|
|
|
private static int readVarInt(byte[] array, int startPos) {
|
2019-04-25 20:33:36 +02:00
|
|
|
int numRead = 0;
|
|
|
|
int result = 0;
|
|
|
|
byte read;
|
|
|
|
do {
|
|
|
|
read = array[startPos + numRead];
|
|
|
|
int value = (read & 0b01111111);
|
|
|
|
result |= (value << (7 * numRead));
|
|
|
|
|
|
|
|
numRead++;
|
|
|
|
if (numRead > 5) {
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
} while ((read & 0b10000000) != 0);
|
|
|
|
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
2019-05-28 06:16:16 +02:00
|
|
|
private static int readVarIntLength(byte[] array, int startPos) {
|
2019-04-25 20:33:36 +02:00
|
|
|
int numRead = 0;
|
|
|
|
byte read;
|
|
|
|
do {
|
|
|
|
read = array[startPos + numRead];
|
|
|
|
numRead++;
|
|
|
|
if (numRead > 5) {
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
} while ((read & 0b10000000) != 0);
|
|
|
|
|
|
|
|
return numRead;
|
|
|
|
}
|
|
|
|
|
2019-05-28 06:16:16 +02:00
|
|
|
private static byte[] writeVarInt(int value) {
|
2019-09-25 18:21:20 +02:00
|
|
|
List<Byte> buffer = new ArrayList<>(5);
|
2019-04-25 20:33:36 +02:00
|
|
|
do {
|
|
|
|
byte temp = (byte)(value & 0b01111111);
|
|
|
|
// Note: >>> means that the sign bit is shifted with the rest of the number rather than being left alone
|
|
|
|
value >>>= 7;
|
|
|
|
if (value != 0) {
|
|
|
|
temp |= 0b10000000;
|
|
|
|
}
|
|
|
|
buffer.add(temp);
|
|
|
|
} while (value != 0);
|
|
|
|
return Bytes.toArray(buffer);
|
|
|
|
}
|
|
|
|
}
|