SteamWar/FightSystem
Archiviert
13
1
Dieses Repository wurde am 2024-08-05 archiviert. Du kannst Dateien ansehen und es klonen, aber nicht pushen oder Issues/Pull-Requests öffnen.
FightSystem/src/de/steamwar/fightsystem/utils/TechHider.java

373 Zeilen
16 KiB
Java

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-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;
import javafx.util.Pair;
import net.minecraft.server.v1_12_R1.PacketPlayOutMapChunk;
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.craftbukkit.v1_12_R1.CraftChunk;
import org.bukkit.craftbukkit.v1_12_R1.entity.CraftPlayer;
2019-04-25 20:33:36 +02:00
import org.bukkit.entity.Player;
import java.util.ArrayList;
2019-09-12 20:46:21 +02:00
import java.util.Collections;
2019-04-25 20:33:36 +02:00
import java.util.List;
public class TechHider {
2019-06-22 17:11:10 +02:00
private TechHider(){}
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;
private static short obfuscateShift4;
private static final short BITMASK = 0x1FF;
2019-05-28 06:16:16 +02:00
private static Material obfuscateMaterial;
2019-04-25 20:33:36 +02:00
public static void init(){
2019-09-12 20:46:21 +02:00
if(disabled())
return;
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;
obfuscateShift4 = (short)(Config.ObfuscateWith << 4);
2019-05-28 06:16:16 +02:00
obfuscateMaterial = Material.getMaterial(Config.ObfuscateWith);
2019-09-05 18:26:13 +02:00
int threadMultiplier = 1;
if(Config.event())
threadMultiplier = 4;
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-07-01 21:02:32 +02:00
packet = packet.deepClone();
e.setPacket(packet);
StructureModifier<byte[]> byteArray = packet.getByteArrays();
StructureModifier<List> list = packet.getSpecificModifier(List.class);
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;
byte [] data = byteArray.read(0);
2019-09-25 18:21:20 +02:00
ByteBuf buffer = UnpooledByteBufAllocator.DEFAULT.directBuffer(data.length);
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;
i++;
2019-09-25 18:21:20 +02:00
buffer.writeByte(data[1]);
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;
/*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){
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)){
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;
}
}*/
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-25 18:21:20 +02:00
buffer.readBytes(data);
byteArray.write(0, data);
2019-04-25 20:33:36 +02:00
}
}
2019-09-05 18:26:13 +02:00
}).start(4 * threadMultiplier);
ProtocolLibrary.getProtocolManager().getAsynchronousManager().registerAsyncHandler(new PacketAdapter(FightSystem.getPlugin(), PacketType.Play.Server.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-05-28 06:16:16 +02:00
BlockPosition pos = packet.getBlockPositionModifier().read(0);
Player p = e.getPlayer();
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-07-01 21:02:32 +02:00
packet = packet.deepClone();
e.setPacket(packet);
StructureModifier<WrappedBlockData> blockStructure = packet.getBlockData();
2019-05-28 06:16:16 +02:00
WrappedBlockData block = blockStructure.read(0);
2019-04-25 20:33:36 +02:00
if(Config.HiddenBlocks.contains(block.getType().getId())){
2019-05-28 06:16:16 +02:00
block.setType(obfuscateMaterial);
2019-04-25 20:33:36 +02:00
blockStructure.write(0, block);
}
}
2019-09-05 18:26:13 +02:00
}).start(threadMultiplier);
ProtocolLibrary.getProtocolManager().getAsynchronousManager().registerAsyncHandler(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-07-01 21:02:32 +02:00
packet = packet.shallowClone();
e.setPacket(packet);
StructureModifier<MultiBlockChangeInfo[]> blockStructure = packet.getMultiBlockChangeInfoArrays();
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();
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-09-05 18:26:13 +02:00
}).start(threadMultiplier);
ProtocolLibrary.getProtocolManager().getAsynchronousManager().registerAsyncHandler(new PacketAdapter(FightSystem.getPlugin(), PacketType.Play.Server.BLOCK_ACTION) {
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-05-28 06:16:16 +02:00
Player p = e.getPlayer();
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
e.setCancelled(true);
}
}).start();
ProtocolLibrary.getProtocolManager().getAsynchronousManager().registerAsyncHandler(new PacketAdapter(FightSystem.getPlugin(), PacketType.Play.Client.USE_ITEM) {
2019-04-25 20:33:36 +02:00
@Override
public void onPacketReceiving(PacketEvent e) {
Player p = e.getPlayer();
2019-05-28 06:16:16 +02:00
if(p.getGameMode() == GameMode.SPECTATOR){
e.setCancelled(true);
}
}
2019-09-05 18:26:13 +02:00
}).start(threadMultiplier);
ProtocolLibrary.getProtocolManager().getAsynchronousManager().registerAsyncHandler(new PacketAdapter(FightSystem.getPlugin(), PacketType.Play.Client.USE_ENTITY) {
2019-05-28 06:16:16 +02:00
@Override
public void onPacketReceiving(PacketEvent e) {
Player p = e.getPlayer();
2019-04-25 20:33:36 +02:00
2019-05-28 06:16:16 +02:00
if(p.getGameMode() == GameMode.SPECTATOR){
e.setCancelled(true);
}
2019-04-25 20:33:36 +02:00
}
2019-09-05 18:26:13 +02:00
}).start(threadMultiplier);
2019-04-25 20:33:36 +02:00
}
2019-05-28 06:16:16 +02:00
private static boolean bypass(Player p, int chunkX, int chunkZ){
2019-09-05 18:26:13 +02:00
if(p == FightSystem.getEventLeiter())
return true;
2019-05-28 06:16:16 +02:00
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()){
2019-06-22 17:11:10 +02:00
return FightSystem.isEntern() ||
redMinX > chunkX ||
chunkX > redMaxX ||
redMinZ > chunkZ ||
chunkZ > redMaxZ;
2019-05-28 06:16:16 +02:00
}else{
2019-06-22 17:11:10 +02:00
return FightSystem.isEntern() ||
blueMinX > chunkX ||
chunkX > blueMaxX ||
blueMinZ > chunkZ ||
chunkZ > blueMaxZ;
2019-05-28 06:16:16 +02:00
}
}
public static List<Pair<Integer, Integer>> prepareChunkReload(Player p){
2019-09-12 20:46:21 +02:00
if(disabled())
return Collections.emptyList();
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;
}
public static void reloadChunks(Player p, List<Pair<Integer, Integer>> chunksToReload){
2019-09-12 20:46:21 +02:00
if(disabled())
return;
Bukkit.getScheduler().runTaskLater(FightSystem.getPlugin(), () -> {
for(Pair<Integer, Integer> chunk : chunksToReload){
if(bypass(p, chunk.getKey(), chunk.getValue()))
((CraftPlayer)p).getHandle().playerConnection.sendPacket(new PacketPlayOutMapChunk(((CraftChunk)p.getWorld().getChunkAt(chunk.getKey(), chunk.getValue())).getHandle(), 65535));
}
2019-06-22 17:11:10 +02:00
}, 40);
}
2019-09-12 20:46:21 +02:00
private static boolean disabled(){
return Config.event() && Config.OnlyPublicSchematics;
}
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);
}
}