New Fight UI #288
@ -19,12 +19,15 @@
|
|||||||
|
|
||||||
package de.steamwar.fightsystem.utils;
|
package de.steamwar.fightsystem.utils;
|
||||||
|
|
||||||
|
import com.comphenix.tinyprotocol.Reflection;
|
||||||
|
import de.steamwar.fightsystem.record.REntity;
|
||||||
import org.bukkit.DyeColor;
|
import org.bukkit.DyeColor;
|
||||||
import org.bukkit.Material;
|
import org.bukkit.Material;
|
||||||
import org.bukkit.World;
|
import org.bukkit.World;
|
||||||
import org.bukkit.block.Block;
|
import org.bukkit.block.Block;
|
||||||
import org.bukkit.block.data.BlockData;
|
import org.bukkit.block.data.BlockData;
|
||||||
import org.bukkit.block.data.Waterlogged;
|
import org.bukkit.block.data.Waterlogged;
|
||||||
|
import org.bukkit.entity.EntityType;
|
||||||
import org.bukkit.event.block.BlockPhysicsEvent;
|
import org.bukkit.event.block.BlockPhysicsEvent;
|
||||||
import org.bukkit.inventory.ItemStack;
|
import org.bukkit.inventory.ItemStack;
|
||||||
import org.bukkit.inventory.meta.BlockDataMeta;
|
import org.bukkit.inventory.meta.BlockDataMeta;
|
||||||
@ -108,4 +111,29 @@ public class FlatteningWrapper14 implements FlatteningWrapper.IFlatteningWrapper
|
|||||||
public boolean checkPistonMoving(Block block) {
|
public boolean checkPistonMoving(Block block) {
|
||||||
return block.getType() == Material.MOVING_PISTON;
|
return block.getType() == Material.MOVING_PISTON;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setNamedSpawnPacketDataWatcher(Object packet) {
|
||||||
|
// field not present
|
||||||
|
}
|
||||||
|
|
||||||
|
private static final Class<?> entityTypes = Reflection.getClass("{nms}.EntityTypes");
|
||||||
|
private static final Reflection.FieldAccessor<?> spawnType = Reflection.getField(REntity.spawnPacket, entityTypes, 0);
|
||||||
|
private static final Object tnt = Reflection.getField(entityTypes, "TNT", entityTypes).get(null);
|
||||||
|
private static final Object arrow = Reflection.getField(entityTypes, "ARROW", entityTypes).get(null);
|
||||||
|
private static final Object fireball = Reflection.getField(entityTypes, "FIREBALL", entityTypes).get(null);
|
||||||
|
@Override
|
||||||
|
public void setSpawnPacketType(Object packet, EntityType type) {
|
||||||
|
switch(type) {
|
||||||
|
case PRIMED_TNT:
|
||||||
|
spawnType.set(packet, tnt);
|
||||||
|
break;
|
||||||
|
case ARROW:
|
||||||
|
spawnType.set(packet, arrow);
|
||||||
|
break;
|
||||||
|
case FIREBALL:
|
||||||
|
spawnType.set(packet, fireball);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -19,76 +19,27 @@
|
|||||||
|
|
||||||
package de.steamwar.fightsystem.utils;
|
package de.steamwar.fightsystem.utils;
|
||||||
|
|
||||||
import com.comphenix.protocol.PacketType;
|
|
||||||
import com.comphenix.protocol.events.PacketAdapter;
|
|
||||||
import com.comphenix.protocol.events.PacketContainer;
|
|
||||||
import com.comphenix.protocol.events.PacketEvent;
|
|
||||||
import com.comphenix.protocol.reflect.StructureModifier;
|
|
||||||
import com.comphenix.protocol.wrappers.nbt.NbtBase;
|
|
||||||
import com.comphenix.protocol.wrappers.nbt.NbtCompound;
|
|
||||||
import de.steamwar.fightsystem.Config;
|
|
||||||
import de.steamwar.fightsystem.FightSystem;
|
|
||||||
import io.netty.buffer.ByteBuf;
|
import io.netty.buffer.ByteBuf;
|
||||||
import io.netty.buffer.UnpooledByteBufAllocator;
|
import io.netty.buffer.UnpooledByteBufAllocator;
|
||||||
import org.bukkit.entity.Player;
|
|
||||||
|
|
||||||
import java.nio.ByteBuffer;
|
import java.nio.ByteBuffer;
|
||||||
import java.nio.LongBuffer;
|
import java.nio.LongBuffer;
|
||||||
import java.util.List;
|
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
import java.util.function.BiFunction;
|
||||||
|
|
||||||
import static de.steamwar.fightsystem.utils.TechHider.bypass;
|
public class TechHider14 implements BiFunction<byte[], Integer, byte[]> {
|
||||||
|
|
||||||
public class TechHider14 extends PacketAdapter {
|
|
||||||
|
|
||||||
private final Set<Integer> hiddenBlockIds = BlockIdWrapper.impl.getHiddenBlockIds();
|
private final Set<Integer> hiddenBlockIds = BlockIdWrapper.impl.getHiddenBlockIds();
|
||||||
private final int obfuscateWith = BlockIdWrapper.impl.getObfuscateWith();
|
private final int obfuscateWith = BlockIdWrapper.impl.getObfuscateWith();
|
||||||
|
|
||||||
public TechHider14(){
|
|
||||||
super(FightSystem.getPlugin(), PacketType.Play.Server.MAP_CHUNK);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onPacketSending(PacketEvent e) {
|
public byte[] apply(byte[] data, Integer primaryBitMask) {
|
||||||
PacketContainer packet = e.getPacket();
|
|
||||||
StructureModifier<Integer> ints = packet.getIntegers();
|
|
||||||
|
|
||||||
int chunkX = ints.read(0);
|
|
||||||
int chunkZ = ints.read(1);
|
|
||||||
Player p = e.getPlayer();
|
|
||||||
if(bypass(p, chunkX, chunkZ))
|
|
||||||
return;
|
|
||||||
|
|
||||||
packet = packet.shallowClone();
|
|
||||||
e.setPacket(packet);
|
|
||||||
StructureModifier<List<NbtBase<?>>> list = packet.getListNbtModifier();
|
|
||||||
List<NbtBase<?>> nmsTags = list.read(0);
|
|
||||||
boolean changed = false;
|
|
||||||
for(int i = nmsTags.size() - 1; i >= 0; i--){
|
|
||||||
NbtBase<?> nbtBase = nmsTags.get(i);
|
|
||||||
assert nbtBase instanceof NbtCompound;
|
|
||||||
NbtCompound nbt = (NbtCompound) nbtBase;
|
|
||||||
if(Config.HiddenBlockEntities.contains(nbt.getString("id"))){
|
|
||||||
nmsTags.remove(i);
|
|
||||||
changed = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if(changed){
|
|
||||||
list.write(0, nmsTags);
|
|
||||||
}
|
|
||||||
|
|
||||||
changed = false;
|
|
||||||
StructureModifier<byte[]> byteArray = packet.getByteArrays();
|
|
||||||
int primaryBitMask = ints.read(2);
|
|
||||||
byte[] data = byteArray.read(0);
|
|
||||||
ByteBuf buffer = UnpooledByteBufAllocator.DEFAULT.directBuffer(data.length + 100);
|
ByteBuf buffer = UnpooledByteBufAllocator.DEFAULT.directBuffer(data.length + 100);
|
||||||
int i = 0;
|
int i = 0;
|
||||||
|
|
||||||
//int chunkY = 0;
|
|
||||||
while(primaryBitMask != 0){
|
while(primaryBitMask != 0){
|
||||||
while((primaryBitMask & 1) == 0){
|
while((primaryBitMask & 1) == 0){
|
||||||
primaryBitMask >>= 1;
|
primaryBitMask >>= 1;
|
||||||
//chunkY++;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
buffer.writeBytes(data, i, 2); // Block count
|
buffer.writeBytes(data, i, 2); // Block count
|
||||||
@ -107,7 +58,6 @@ public class TechHider14 extends PacketAdapter {
|
|||||||
|
|
||||||
if(hiddenBlockIds.contains(blockId)){
|
if(hiddenBlockIds.contains(blockId)){
|
||||||
buffer.writeBytes(TechHider.writeVarInt(obfuscateWith));
|
buffer.writeBytes(TechHider.writeVarInt(obfuscateWith));
|
||||||
changed = true;
|
|
||||||
}else{
|
}else{
|
||||||
buffer.writeBytes(data, i, actPaletteLength);
|
buffer.writeBytes(data, i, actPaletteLength);
|
||||||
}
|
}
|
||||||
@ -132,7 +82,6 @@ public class TechHider14 extends PacketAdapter {
|
|||||||
|
|
||||||
for(int pos = 0; pos < 4096; pos++){
|
for(int pos = 0; pos < 4096; pos++){
|
||||||
if(hiddenBlockIds.contains(values.get(pos))){
|
if(hiddenBlockIds.contains(values.get(pos))){
|
||||||
changed = true;
|
|
||||||
values.set(pos, obfuscateWith);
|
values.set(pos, obfuscateWith);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -144,15 +93,12 @@ public class TechHider14 extends PacketAdapter {
|
|||||||
}
|
}
|
||||||
|
|
||||||
primaryBitMask >>= 1;
|
primaryBitMask >>= 1;
|
||||||
//chunkY++;
|
|
||||||
}
|
}
|
||||||
buffer.writeBytes(data, i, data.length - i); // MC appends a 0 byte at the end if there is a full chunk, idk why
|
buffer.writeBytes(data, i, data.length - i); // MC appends a 0 byte at the end if there is a full chunk, idk why
|
||||||
|
|
||||||
if(changed){
|
data = new byte[buffer.readableBytes()];
|
||||||
data = new byte[buffer.readableBytes()];
|
buffer.readBytes(data);
|
||||||
buffer.readBytes(data);
|
return data;
|
||||||
byteArray.write(0, data);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static final class VariableValueArray {
|
private static final class VariableValueArray {
|
||||||
|
@ -54,6 +54,6 @@ public class BlockIdWrapper8 implements BlockIdWrapper.IBlockIdWrapper {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Object getPose(boolean sneaking) {
|
public Object getPose(boolean sneaking) {
|
||||||
return null;
|
return Byte.valueOf((byte)(sneaking ? 2 : 0));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -19,12 +19,14 @@
|
|||||||
|
|
||||||
package de.steamwar.fightsystem.utils;
|
package de.steamwar.fightsystem.utils;
|
||||||
|
|
||||||
import com.comphenix.protocol.wrappers.EnumWrappers;
|
import com.comphenix.tinyprotocol.Reflection;
|
||||||
import de.steamwar.fightsystem.listener.Recording;
|
import de.steamwar.fightsystem.listener.Recording;
|
||||||
import de.steamwar.fightsystem.record.GlobalRecorder;
|
import de.steamwar.fightsystem.record.GlobalRecorder;
|
||||||
|
import de.steamwar.fightsystem.record.REntity;
|
||||||
import net.md_5.bungee.api.chat.BaseComponent;
|
import net.md_5.bungee.api.chat.BaseComponent;
|
||||||
import net.minecraft.server.v1_8_R3.ChatComponentText;
|
import net.minecraft.server.v1_8_R3.ChatComponentText;
|
||||||
import net.minecraft.server.v1_8_R3.PacketPlayOutChat;
|
import net.minecraft.server.v1_8_R3.PacketPlayOutChat;
|
||||||
|
import net.royawesome.jlibnoise.MathHelper;
|
||||||
import org.bukkit.Effect;
|
import org.bukkit.Effect;
|
||||||
import org.bukkit.Location;
|
import org.bukkit.Location;
|
||||||
import org.bukkit.Material;
|
import org.bukkit.Material;
|
||||||
@ -34,9 +36,19 @@ import org.bukkit.entity.Player;
|
|||||||
import org.bukkit.event.Listener;
|
import org.bukkit.event.Listener;
|
||||||
import org.bukkit.scoreboard.Team;
|
import org.bukkit.scoreboard.Team;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
public class BountifulWrapper8 implements BountifulWrapper.IBountifulWrapper {
|
public class BountifulWrapper8 implements BountifulWrapper.IBountifulWrapper {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean bowInHand(EnumWrappers.Hand hand, Player p) {
|
public boolean mainHand(Object packet) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean bowInHand(boolean mainHand, Player p) {
|
||||||
return p.getInventory().getItemInHand().getType() == Material.BOW;
|
return p.getInventory().getItemInHand().getType() == Material.BOW;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -86,4 +98,63 @@ public class BountifulWrapper8 implements BountifulWrapper.IBountifulWrapper {
|
|||||||
public void spawnParticle(World world, String particleName, double x, double y, double z) {
|
public void spawnParticle(World world, String particleName, double x, double y, double z) {
|
||||||
world.playEffect(new Location(world, x, y, z), Effect.valueOf(particleName), 1);
|
world.playEffect(new Location(world, x, y, z), Effect.valueOf(particleName), 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Object getDataWatcherObject(int index, Class<?> type) {
|
||||||
|
return index;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static final Class<?> watchableObject = Reflection.getClass("{nms}.DataWatcher$WatchableObject");
|
||||||
|
private static final Reflection.ConstructorInvoker watchableObjectConstructor = Reflection.getConstructor(watchableObject, int.class, int.class, Object.class);
|
||||||
|
private static final Map<Class<?>, Integer> watchableDatatypes = new HashMap<>();
|
||||||
|
static {
|
||||||
|
watchableDatatypes.put(byte.class, 0);
|
||||||
|
watchableDatatypes.put(short.class, 1);
|
||||||
|
watchableDatatypes.put(int.class, 2);
|
||||||
|
watchableDatatypes.put(float.class, 3);
|
||||||
|
watchableDatatypes.put(String.class, 4);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Object getDataWatcherItem(Object dwo, Object value) {
|
||||||
|
return watchableObjectConstructor.invoke(watchableDatatypes.get(value.getClass()), dwo, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static final Reflection.FieldAccessor<Integer> teleportX = Reflection.getField(REntity.teleportPacket, int.class, 1);
|
||||||
|
private static final Reflection.FieldAccessor<Integer> teleportY = Reflection.getField(REntity.teleportPacket, int.class, 2);
|
||||||
|
private static final Reflection.FieldAccessor<Integer> teleportZ = Reflection.getField(REntity.teleportPacket, int.class, 3);
|
||||||
|
@Override
|
||||||
|
public void setTeleportPacketPosition(Object packet, double x, double y, double z) {
|
||||||
|
teleportX.set(packet, MathHelper.floor(x * 32));
|
||||||
|
teleportY.set(packet, MathHelper.floor(y * 32));
|
||||||
|
teleportZ.set(packet, MathHelper.floor(z * 32));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setSpawnPacketUUID(Object packet, UUID uuid) {
|
||||||
|
// field not present
|
||||||
|
}
|
||||||
|
|
||||||
|
private static final Reflection.FieldAccessor<Integer> equipmentSlot = Reflection.getField(REntity.equipmentPacket, int.class, 1);
|
||||||
|
@Override
|
||||||
|
public void setEquipmentPacketSlot(Object packet, String slot) {
|
||||||
|
switch(slot){
|
||||||
|
case "HEAD":
|
||||||
|
equipmentSlot.set(packet, 4);
|
||||||
|
break;
|
||||||
|
case "CHEST":
|
||||||
|
equipmentSlot.set(packet, 3);
|
||||||
|
break;
|
||||||
|
case "LEGS":
|
||||||
|
equipmentSlot.set(packet, 2);
|
||||||
|
break;
|
||||||
|
case "FEET":
|
||||||
|
equipmentSlot.set(packet, 1);
|
||||||
|
break;
|
||||||
|
case "MAINHAND":
|
||||||
|
case "OFFHAND":
|
||||||
|
default:
|
||||||
|
equipmentSlot.set(packet, 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -19,10 +19,14 @@
|
|||||||
|
|
||||||
package de.steamwar.fightsystem.utils;
|
package de.steamwar.fightsystem.utils;
|
||||||
|
|
||||||
|
import com.comphenix.tinyprotocol.Reflection;
|
||||||
|
import de.steamwar.core.Core;
|
||||||
|
import de.steamwar.fightsystem.record.REntity;
|
||||||
import org.bukkit.DyeColor;
|
import org.bukkit.DyeColor;
|
||||||
import org.bukkit.Material;
|
import org.bukkit.Material;
|
||||||
import org.bukkit.World;
|
import org.bukkit.World;
|
||||||
import org.bukkit.block.Block;
|
import org.bukkit.block.Block;
|
||||||
|
import org.bukkit.entity.EntityType;
|
||||||
import org.bukkit.event.block.BlockPhysicsEvent;
|
import org.bukkit.event.block.BlockPhysicsEvent;
|
||||||
import org.bukkit.inventory.ItemStack;
|
import org.bukkit.inventory.ItemStack;
|
||||||
import org.bukkit.inventory.meta.ItemMeta;
|
import org.bukkit.inventory.meta.ItemMeta;
|
||||||
@ -86,4 +90,29 @@ public class FlatteningWrapper8 implements FlatteningWrapper.IFlatteningWrapper
|
|||||||
public boolean checkPistonMoving(Block block) {
|
public boolean checkPistonMoving(Block block) {
|
||||||
return block.getType() == Material.PISTON_MOVING_PIECE;
|
return block.getType() == Material.PISTON_MOVING_PIECE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static final Class<?> dataWatcher = Reflection.getClass("{nms}.DataWatcher");
|
||||||
|
private static final Reflection.FieldAccessor<?> namedSpawnDataWatcher = Reflection.getField(REntity.namedSpawnPacket, dataWatcher, 0);
|
||||||
|
private static final Class<?> entity = Reflection.getClass("{nms}.Entity");
|
||||||
|
private static final Reflection.ConstructorInvoker dataWatcherConstructor = Reflection.getConstructor(dataWatcher, entity);
|
||||||
|
@Override
|
||||||
|
public void setNamedSpawnPacketDataWatcher(Object packet) {
|
||||||
|
namedSpawnDataWatcher.set(packet, dataWatcherConstructor.invoke((Object) null));
|
||||||
|
}
|
||||||
|
|
||||||
|
private static final Reflection.FieldAccessor<Integer> spawnType = Reflection.getField(REntity.spawnPacket, int.class, Core.getVersion() > 8 ? 6 : 9);
|
||||||
|
@Override
|
||||||
|
public void setSpawnPacketType(Object packet, EntityType type) {
|
||||||
|
switch(type) {
|
||||||
|
case PRIMED_TNT:
|
||||||
|
spawnType.set(packet, 50);
|
||||||
|
break;
|
||||||
|
case ARROW:
|
||||||
|
spawnType.set(packet, 60);
|
||||||
|
break;
|
||||||
|
case FIREBALL:
|
||||||
|
spawnType.set(packet, 63);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -19,19 +19,13 @@
|
|||||||
|
|
||||||
package de.steamwar.fightsystem.utils;
|
package de.steamwar.fightsystem.utils;
|
||||||
|
|
||||||
import com.comphenix.protocol.PacketType;
|
import java.util.function.BiFunction;
|
||||||
import com.comphenix.protocol.events.PacketAdapter;
|
|
||||||
import com.comphenix.protocol.events.PacketEvent;
|
|
||||||
import de.steamwar.fightsystem.FightSystem;
|
|
||||||
|
|
||||||
public class TechHider8 extends PacketAdapter {
|
public class TechHider8 implements BiFunction<byte[], Integer, byte[]> {
|
||||||
|
|
||||||
public TechHider8() {
|
|
||||||
super(FightSystem.getPlugin(), PacketType.Play.Server.MAP_CHUNK);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onPacketSending(PacketEvent e) {
|
public byte[] apply(byte[] data, Integer primaryBitMask) {
|
||||||
// no implementation availible
|
// No implementation availible
|
||||||
|
return data;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -19,9 +19,10 @@
|
|||||||
|
|
||||||
package de.steamwar.fightsystem.utils;
|
package de.steamwar.fightsystem.utils;
|
||||||
|
|
||||||
import com.comphenix.protocol.wrappers.EnumWrappers;
|
import com.comphenix.tinyprotocol.Reflection;
|
||||||
import de.steamwar.fightsystem.listener.Recording;
|
import de.steamwar.fightsystem.listener.Recording;
|
||||||
import de.steamwar.fightsystem.record.GlobalRecorder;
|
import de.steamwar.fightsystem.record.GlobalRecorder;
|
||||||
|
import de.steamwar.fightsystem.record.REntity;
|
||||||
import net.md_5.bungee.api.ChatMessageType;
|
import net.md_5.bungee.api.ChatMessageType;
|
||||||
import net.md_5.bungee.api.chat.BaseComponent;
|
import net.md_5.bungee.api.chat.BaseComponent;
|
||||||
import org.bukkit.Material;
|
import org.bukkit.Material;
|
||||||
@ -37,11 +38,24 @@ import org.bukkit.event.player.PlayerPickupArrowEvent;
|
|||||||
import org.bukkit.event.player.PlayerSwapHandItemsEvent;
|
import org.bukkit.event.player.PlayerSwapHandItemsEvent;
|
||||||
import org.bukkit.scoreboard.Team;
|
import org.bukkit.scoreboard.Team;
|
||||||
|
|
||||||
|
import java.lang.reflect.Field;
|
||||||
|
import java.lang.reflect.ParameterizedType;
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
public class BountifulWrapper9 implements BountifulWrapper.IBountifulWrapper {
|
public class BountifulWrapper9 implements BountifulWrapper.IBountifulWrapper {
|
||||||
|
|
||||||
|
private static final Class<?> enumHand = Reflection.getClass("{nms}.EnumHand");
|
||||||
|
private static final Object mainHand = enumHand.getEnumConstants()[0];
|
||||||
|
private static final Reflection.FieldAccessor<?> blockPlaceHand = Reflection.getField(Recording.blockPlacePacket, enumHand, 0);
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean bowInHand(EnumWrappers.Hand hand, Player p) {
|
public boolean mainHand(Object packet) {
|
||||||
return (hand == EnumWrappers.Hand.MAIN_HAND && p.getInventory().getItemInMainHand().getType() == Material.BOW) ||
|
return blockPlaceHand.get(packet) == mainHand;
|
||||||
(hand == EnumWrappers.Hand.OFF_HAND && p.getInventory().getItemInOffHand().getType() == Material.BOW);
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean bowInHand(boolean mainHand, Player p) {
|
||||||
|
return (mainHand ? p.getInventory().getItemInMainHand() : p.getInventory().getItemInOffHand()).getType() == Material.BOW;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -110,4 +124,73 @@ public class BountifulWrapper9 implements BountifulWrapper.IBountifulWrapper {
|
|||||||
public void spawnParticle(World world, String particleName, double x, double y, double z) {
|
public void spawnParticle(World world, String particleName, double x, double y, double z) {
|
||||||
world.spawnParticle(Particle.valueOf(particleName), x, y, z, 1);
|
world.spawnParticle(Particle.valueOf(particleName), x, y, z, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private static final Class<?> dataWatcherObject = Reflection.getClass("{nms}.DataWatcherObject");
|
||||||
|
private static final Class<?> dataWatcherRegistry = Reflection.getClass("{nms}.DataWatcherRegistry");
|
||||||
|
private static final Class<?> dataWatcherSerializer = Reflection.getClass("{nms}.DataWatcherSerializer");
|
||||||
|
private static final Reflection.ConstructorInvoker dataWatcherObjectConstructor = Reflection.getConstructor(dataWatcherObject, int.class, dataWatcherSerializer);
|
||||||
|
@Override
|
||||||
|
public Object getDataWatcherObject(int index, Class<?> type) {
|
||||||
|
for(Field field : dataWatcherRegistry.getFields()) {
|
||||||
|
if(dataWatcherSerializer.isAssignableFrom(field.getType()) && type.equals(((ParameterizedType) field.getGenericType()).getActualTypeArguments()[0])) {
|
||||||
|
try {
|
||||||
|
return dataWatcherObjectConstructor.invoke(index, field.get(null));
|
||||||
|
} catch (IllegalAccessException e) {
|
||||||
|
throw new SecurityException("Could not get field", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
throw new SecurityException("Could not find Serializer for " + type.getName());
|
||||||
|
}
|
||||||
|
|
||||||
|
private static final Class<?> item = Reflection.getClass("{nms}.DataWatcher$Item");
|
||||||
|
private static final Reflection.ConstructorInvoker itemConstructor = Reflection.getConstructor(item, dataWatcherObject, Object.class);
|
||||||
|
@Override
|
||||||
|
public Object getDataWatcherItem(Object dwo, Object value) {
|
||||||
|
return itemConstructor.invoke(dwo, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static final Reflection.FieldAccessor<Double> teleportX = Reflection.getField(REntity.teleportPacket, double.class, 0);
|
||||||
|
private static final Reflection.FieldAccessor<Double> teleportY = Reflection.getField(REntity.teleportPacket, double.class, 1);
|
||||||
|
private static final Reflection.FieldAccessor<Double> teleportZ = Reflection.getField(REntity.teleportPacket, double.class, 2);
|
||||||
|
@Override
|
||||||
|
public void setTeleportPacketPosition(Object packet, double x, double y, double z) {
|
||||||
|
teleportX.set(packet, x);
|
||||||
|
teleportY.set(packet, y);
|
||||||
|
teleportZ.set(packet, z);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static final Reflection.FieldAccessor<UUID> spawnUUID = Reflection.getField(REntity.spawnPacket, UUID.class, 0);
|
||||||
|
@Override
|
||||||
|
public void setSpawnPacketUUID(Object packet, UUID uuid) {
|
||||||
|
spawnUUID.set(packet, uuid);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static final Class<?> enumItemSlot = Reflection.getClass("{nms}.EnumItemSlot");
|
||||||
|
private static final Reflection.FieldAccessor<?> equipmentSlot = Reflection.getField(REntity.equipmentPacket, enumItemSlot, 0);
|
||||||
|
private static final Object[] itemSlots = enumItemSlot.getEnumConstants();
|
||||||
|
@Override
|
||||||
|
public void setEquipmentPacketSlot(Object packet, String slot) {
|
||||||
|
switch(slot){
|
||||||
|
case "HEAD":
|
||||||
|
equipmentSlot.set(packet, itemSlots[5]);
|
||||||
|
break;
|
||||||
|
case "CHEST":
|
||||||
|
equipmentSlot.set(packet, itemSlots[4]);
|
||||||
|
break;
|
||||||
|
case "LEGS":
|
||||||
|
equipmentSlot.set(packet, itemSlots[3]);
|
||||||
|
break;
|
||||||
|
case "FEET":
|
||||||
|
equipmentSlot.set(packet, itemSlots[2]);
|
||||||
|
break;
|
||||||
|
case "OFFHAND":
|
||||||
|
equipmentSlot.set(packet, itemSlots[1]);
|
||||||
|
break;
|
||||||
|
case "MAINHAND":
|
||||||
|
default:
|
||||||
|
equipmentSlot.set(packet, itemSlots[0]);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/*
|
/*
|
||||||
This file is a part of the SteamWar software.
|
This file is a part of the SteamWar software.
|
||||||
|
|
||||||
Copyright (C) 2020 SteamWar.de-Serverteam
|
Copyright (C) 2021 SteamWar.de-Serverteam
|
||||||
|
|
||||||
This program is free software: you can redistribute it and/or modify
|
This program is free software: you can redistribute it and/or modify
|
||||||
it under the terms of the GNU Affero General Public License as published by
|
it under the terms of the GNU Affero General Public License as published by
|
||||||
@ -15,68 +15,25 @@
|
|||||||
|
|
||||||
You should have received a copy of the GNU Affero General Public License
|
You should have received a copy of the GNU Affero General Public License
|
||||||
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package de.steamwar.fightsystem.utils;
|
package de.steamwar.fightsystem.utils;
|
||||||
|
|
||||||
import com.comphenix.protocol.PacketType;
|
|
||||||
import com.comphenix.protocol.events.PacketAdapter;
|
|
||||||
import com.comphenix.protocol.events.PacketContainer;
|
|
||||||
import com.comphenix.protocol.events.PacketEvent;
|
|
||||||
import com.comphenix.protocol.reflect.StructureModifier;
|
|
||||||
import com.comphenix.protocol.wrappers.nbt.NbtBase;
|
|
||||||
import com.comphenix.protocol.wrappers.nbt.NbtCompound;
|
|
||||||
import de.steamwar.fightsystem.Config;
|
|
||||||
import de.steamwar.fightsystem.FightSystem;
|
|
||||||
import io.netty.buffer.ByteBuf;
|
import io.netty.buffer.ByteBuf;
|
||||||
import io.netty.buffer.UnpooledByteBufAllocator;
|
import io.netty.buffer.UnpooledByteBufAllocator;
|
||||||
import org.bukkit.Bukkit;
|
import org.bukkit.Bukkit;
|
||||||
import org.bukkit.entity.Player;
|
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
import java.util.function.BiFunction;
|
||||||
import java.util.logging.Level;
|
import java.util.logging.Level;
|
||||||
|
|
||||||
import static de.steamwar.fightsystem.utils.TechHider.bypass;
|
public class TechHider9 implements BiFunction<byte[], Integer, byte[]> {
|
||||||
|
|
||||||
public class TechHider12 extends PacketAdapter {
|
|
||||||
|
|
||||||
private final Set<Integer> hiddenBlockIds = BlockIdWrapper.impl.getHiddenBlockIds();
|
private final Set<Integer> hiddenBlockIds = BlockIdWrapper.impl.getHiddenBlockIds();
|
||||||
private final int obfuscateWith = BlockIdWrapper.impl.getObfuscateWith();
|
private final int obfuscateWith = BlockIdWrapper.impl.getObfuscateWith();
|
||||||
|
|
||||||
public TechHider12() {
|
|
||||||
super(FightSystem.getPlugin(), PacketType.Play.Server.MAP_CHUNK);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onPacketSending(PacketEvent e) {
|
public byte[] apply(byte[] data, Integer primaryBitMask) {
|
||||||
PacketContainer packet = e.getPacket();
|
|
||||||
StructureModifier<Integer> ints = packet.getIntegers();
|
|
||||||
|
|
||||||
int chunkX = ints.read(0);
|
|
||||||
int chunkZ = ints.read(1);
|
|
||||||
Player p = e.getPlayer();
|
|
||||||
if(bypass(p, chunkX, chunkZ))
|
|
||||||
return;
|
|
||||||
|
|
||||||
packet = packet.shallowClone();
|
|
||||||
e.setPacket(packet);
|
|
||||||
StructureModifier<List<NbtBase<?>>> list = packet.getListNbtModifier();
|
|
||||||
List<NbtBase<?>> nmsTags = list.read(0);
|
|
||||||
boolean changed = false;
|
|
||||||
for(int i = nmsTags.size() - 1; i >= 0; i--){
|
|
||||||
NbtCompound nbt = (NbtCompound)nmsTags.get(i);
|
|
||||||
if(Config.HiddenBlockEntities.contains(nbt.getString("id"))){
|
|
||||||
nmsTags.remove(i);
|
|
||||||
changed = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if(changed)
|
|
||||||
list.write(0, nmsTags);
|
|
||||||
|
|
||||||
changed = false;
|
|
||||||
StructureModifier<byte[]> byteArray = packet.getByteArrays();
|
|
||||||
byte [] data = byteArray.read(0);
|
|
||||||
ByteBuf buffer = UnpooledByteBufAllocator.DEFAULT.directBuffer(data.length + 100);
|
ByteBuf buffer = UnpooledByteBufAllocator.DEFAULT.directBuffer(data.length + 100);
|
||||||
int i = 0;
|
int i = 0;
|
||||||
|
|
||||||
@ -96,7 +53,6 @@ public class TechHider12 extends PacketAdapter {
|
|||||||
|
|
||||||
if(hiddenBlockIds.contains(entry)){
|
if(hiddenBlockIds.contains(entry)){
|
||||||
entry = obfuscateWith;
|
entry = obfuscateWith;
|
||||||
changed = true;
|
|
||||||
}
|
}
|
||||||
buffer.writeBytes(TechHider.writeVarInt(entry));
|
buffer.writeBytes(TechHider.writeVarInt(entry));
|
||||||
}
|
}
|
||||||
@ -115,10 +71,8 @@ public class TechHider12 extends PacketAdapter {
|
|||||||
i += 4096; //Skylight (Not in Nether/End!!!) 2048 + Blocklight 2048
|
i += 4096; //Skylight (Not in Nether/End!!!) 2048 + Blocklight 2048
|
||||||
}
|
}
|
||||||
|
|
||||||
if(changed){
|
data = new byte[buffer.readableBytes()];
|
||||||
data = new byte[buffer.readableBytes()];
|
buffer.readBytes(data);
|
||||||
buffer.readBytes(data);
|
return data;
|
||||||
byteArray.write(0, data);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -142,6 +142,8 @@ public class FightSystem extends JavaPlugin {
|
|||||||
getLogger().log(Level.SEVERE, "Failed to replace commands", e);
|
getLogger().log(Level.SEVERE, "Failed to replace commands", e);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
REntity.initWatchers();
|
||||||
|
|
||||||
if(Config.mode == ArenaMode.EVENT) {
|
if(Config.mode == ArenaMode.EVENT) {
|
||||||
setPreSchemState();
|
setPreSchemState();
|
||||||
}else if(Config.mode == ArenaMode.CHECK){
|
}else if(Config.mode == ArenaMode.CHECK){
|
||||||
|
@ -19,26 +19,21 @@
|
|||||||
|
|
||||||
package de.steamwar.fightsystem.fight;
|
package de.steamwar.fightsystem.fight;
|
||||||
|
|
||||||
import com.comphenix.protocol.PacketType;
|
import com.comphenix.tinyprotocol.Reflection;
|
||||||
import com.comphenix.protocol.ProtocolLibrary;
|
import com.mojang.authlib.GameProfile;
|
||||||
import com.comphenix.protocol.events.PacketContainer;
|
import de.steamwar.core.Core;
|
||||||
import com.comphenix.protocol.wrappers.EnumWrappers;
|
|
||||||
import com.comphenix.protocol.wrappers.PlayerInfoData;
|
|
||||||
import com.comphenix.protocol.wrappers.WrappedChatComponent;
|
|
||||||
import com.comphenix.protocol.wrappers.WrappedGameProfile;
|
|
||||||
import de.steamwar.fightsystem.ArenaMode;
|
import de.steamwar.fightsystem.ArenaMode;
|
||||||
import de.steamwar.fightsystem.Config;
|
import de.steamwar.fightsystem.Config;
|
||||||
import de.steamwar.fightsystem.FightSystem;
|
import de.steamwar.fightsystem.FightSystem;
|
||||||
import de.steamwar.fightsystem.record.GlobalRecorder;
|
import de.steamwar.fightsystem.record.GlobalRecorder;
|
||||||
|
import de.steamwar.fightsystem.utils.ProtocolAPI;
|
||||||
import org.bukkit.Bukkit;
|
import org.bukkit.Bukkit;
|
||||||
import org.bukkit.GameMode;
|
import org.bukkit.GameMode;
|
||||||
import org.bukkit.Sound;
|
import org.bukkit.Sound;
|
||||||
import org.bukkit.entity.Player;
|
import org.bukkit.entity.Player;
|
||||||
|
|
||||||
import java.lang.reflect.InvocationTargetException;
|
import java.util.Collections;
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.logging.Level;
|
|
||||||
|
|
||||||
public class Fight {
|
public class Fight {
|
||||||
private Fight(){}
|
private Fight(){}
|
||||||
@ -105,6 +100,7 @@ public class Fight {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("deprecation")
|
||||||
public static void setPlayerGamemode(Player player, GameMode gameMode) {
|
public static void setPlayerGamemode(Player player, GameMode gameMode) {
|
||||||
player.setGameMode(gameMode);
|
player.setGameMode(gameMode);
|
||||||
|
|
||||||
@ -134,17 +130,30 @@ public class Fight {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static final Class<?> playerInfoPacket = Reflection.getClass("{nms}.PacketPlayOutPlayerInfo");
|
||||||
|
private static final Reflection.ConstructorInvoker playerInfoConstructor = Reflection.getConstructor(playerInfoPacket);
|
||||||
|
private static final Class<?> playerInfoActionClass = Reflection.getClass("{nms}.PacketPlayOutPlayerInfo$EnumPlayerInfoAction");
|
||||||
|
public static final Object addPlayer = playerInfoActionClass.getEnumConstants()[0];
|
||||||
|
private static final Reflection.FieldAccessor<?> playerInfoAction = Reflection.getField(playerInfoPacket, playerInfoActionClass, 0);
|
||||||
|
private static final Object updateGamemode = playerInfoActionClass.getEnumConstants()[1];
|
||||||
|
public static final Object removePlayer = playerInfoActionClass.getEnumConstants()[4];
|
||||||
|
private static final Reflection.FieldAccessor<List> playerInfoData = Reflection.getField(playerInfoPacket, List.class, 0);
|
||||||
|
private static final Class<?> playerInfoDataClass = Reflection.getClass("{nms}.PacketPlayOutPlayerInfo$PlayerInfoData");
|
||||||
|
private static final Class<?> enumGamemode = Reflection.getClass(Core.getVersion() > 9 ? "{nms}.EnumGamemode" : "{nms}.WorldSettings$EnumGamemode");
|
||||||
|
public static final Object creative = enumGamemode.getEnumConstants()[2];
|
||||||
|
private static final Object spectator = enumGamemode.getEnumConstants()[4];
|
||||||
|
private static final Class<?> iChatBaseComponent = Reflection.getClass("{nms}.IChatBaseComponent");
|
||||||
|
|
||||||
|
private static final Reflection.ConstructorInvoker playerInfoDataConstructor = Reflection.getConstructor(playerInfoDataClass, playerInfoPacket, GameProfile.class, int.class, enumGamemode, iChatBaseComponent);
|
||||||
public static void pseudoSpectator(Player player, boolean enable) {
|
public static void pseudoSpectator(Player player, boolean enable) {
|
||||||
PacketContainer gm1packet = ProtocolLibrary.getProtocolManager().createPacket(PacketType.Play.Server.PLAYER_INFO);
|
ProtocolAPI.tinyProtocol.sendPacket(player, playerInfoPacket(updateGamemode, new GameProfile(player.getUniqueId(), player.getName()), enable ? creative : spectator));
|
||||||
gm1packet.getPlayerInfoAction().write(0, EnumWrappers.PlayerInfoAction.UPDATE_GAME_MODE);
|
}
|
||||||
List<PlayerInfoData> playerInfoActions = new ArrayList<>();
|
|
||||||
playerInfoActions.add(new PlayerInfoData(WrappedGameProfile.fromPlayer(player), 1, enable ? EnumWrappers.NativeGameMode.CREATIVE : EnumWrappers.NativeGameMode.SPECTATOR, WrappedChatComponent.fromText(player.getDisplayName())));
|
public static Object playerInfoPacket(Object action, GameProfile profile, Object mode) {
|
||||||
gm1packet.getPlayerInfoDataLists().write(0, playerInfoActions);
|
Object packet = playerInfoConstructor.invoke();
|
||||||
try {
|
playerInfoAction.set(packet, action);
|
||||||
ProtocolLibrary.getProtocolManager().sendServerPacket(player, gm1packet);
|
playerInfoData.set(packet, Collections.singletonList(playerInfoDataConstructor.invoke(packet, profile, 0, mode, null)));
|
||||||
} catch (InvocationTargetException e) {
|
return packet;
|
||||||
Bukkit.getLogger().log(Level.SEVERE, "Invocation target exception", e);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static int getMaxRank(){
|
public static int getMaxRank(){
|
||||||
|
@ -19,12 +19,7 @@
|
|||||||
|
|
||||||
package de.steamwar.fightsystem.listener;
|
package de.steamwar.fightsystem.listener;
|
||||||
|
|
||||||
import com.comphenix.protocol.PacketType;
|
import com.comphenix.tinyprotocol.Reflection;
|
||||||
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.wrappers.EnumWrappers;
|
|
||||||
import de.steamwar.fightsystem.ArenaMode;
|
import de.steamwar.fightsystem.ArenaMode;
|
||||||
import de.steamwar.fightsystem.FightSystem;
|
import de.steamwar.fightsystem.FightSystem;
|
||||||
import de.steamwar.fightsystem.fight.Fight;
|
import de.steamwar.fightsystem.fight.Fight;
|
||||||
@ -37,6 +32,7 @@ import de.steamwar.fightsystem.states.StateDependentListener;
|
|||||||
import de.steamwar.fightsystem.states.StateDependentTask;
|
import de.steamwar.fightsystem.states.StateDependentTask;
|
||||||
import de.steamwar.fightsystem.utils.BountifulWrapper;
|
import de.steamwar.fightsystem.utils.BountifulWrapper;
|
||||||
import de.steamwar.fightsystem.utils.FlatteningWrapper;
|
import de.steamwar.fightsystem.utils.FlatteningWrapper;
|
||||||
|
import de.steamwar.fightsystem.utils.ProtocolAPI;
|
||||||
import de.steamwar.fightsystem.utils.SWSound;
|
import de.steamwar.fightsystem.utils.SWSound;
|
||||||
import org.bukkit.Bukkit;
|
import org.bukkit.Bukkit;
|
||||||
import org.bukkit.Location;
|
import org.bukkit.Location;
|
||||||
@ -62,28 +58,6 @@ public class Recording implements Listener {
|
|||||||
private static final int AIR = 0;
|
private static final int AIR = 0;
|
||||||
private static final Random random = new Random();
|
private static final Random random = new Random();
|
||||||
private static final World world = Bukkit.getWorlds().get(0);
|
private static final World world = Bukkit.getWorlds().get(0);
|
||||||
private static final PacketAdapter BOW_PACKET_PROCESSOR = new PacketAdapter(FightSystem.getPlugin(), PacketType.Play.Client.BLOCK_PLACE) {
|
|
||||||
@Override
|
|
||||||
public void onPacketReceiving(PacketEvent event) {
|
|
||||||
PacketContainer packet = event.getPacket();
|
|
||||||
EnumWrappers.Hand hand = packet.getHands().read(0);
|
|
||||||
Player p = event.getPlayer();
|
|
||||||
|
|
||||||
if(!BountifulWrapper.impl.bowInHand(hand, p))
|
|
||||||
return;
|
|
||||||
|
|
||||||
GlobalRecorder.getInstance().bowSpan(p, true, hand != EnumWrappers.Hand.MAIN_HAND);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
private static final PacketAdapter BOW_PACKET_DEDRAW_PROCESSOR = new PacketAdapter(FightSystem.getPlugin(), PacketType.Play.Client.BLOCK_DIG) {
|
|
||||||
@Override
|
|
||||||
public void onPacketReceiving(PacketEvent e) {
|
|
||||||
PacketContainer packetDig = e.getPacket();
|
|
||||||
if(packetDig.getPlayerDigTypes().read(0) == EnumWrappers.PlayerDigType.RELEASE_USE_ITEM) {
|
|
||||||
GlobalRecorder.getInstance().bowSpan(e.getPlayer(), false, false);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
public static ItemStack disarmNull(ItemStack stack){
|
public static ItemStack disarmNull(ItemStack stack){
|
||||||
if(stack == null)
|
if(stack == null)
|
||||||
@ -118,14 +92,14 @@ public class Recording implements Listener {
|
|||||||
new StateDependent(ArenaMode.AntiReplay, FightState.Ingame) {
|
new StateDependent(ArenaMode.AntiReplay, FightState.Ingame) {
|
||||||
@Override
|
@Override
|
||||||
public void enable() {
|
public void enable() {
|
||||||
ProtocolLibrary.getProtocolManager().addPacketListener(BOW_PACKET_PROCESSOR);
|
ProtocolAPI.setIncomingHandler(blockPlacePacket, Recording.this::blockPlace);
|
||||||
ProtocolLibrary.getProtocolManager().addPacketListener(BOW_PACKET_DEDRAW_PROCESSOR);
|
ProtocolAPI.setIncomingHandler(blockDigPacket, Recording.this::blockDig);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void disable() {
|
public void disable() {
|
||||||
ProtocolLibrary.getProtocolManager().removePacketListener(BOW_PACKET_PROCESSOR);
|
ProtocolAPI.removeIncomingHandler(blockPlacePacket);
|
||||||
ProtocolLibrary.getProtocolManager().removePacketListener(BOW_PACKET_DEDRAW_PROCESSOR);
|
ProtocolAPI.removeIncomingHandler(blockDigPacket);
|
||||||
}
|
}
|
||||||
}.register();
|
}.register();
|
||||||
new StateDependentTask(ArenaMode.AntiReplay, FightState.All, () -> {
|
new StateDependentTask(ArenaMode.AntiReplay, FightState.All, () -> {
|
||||||
@ -141,6 +115,24 @@ public class Recording implements Listener {
|
|||||||
}, 1, 1);
|
}, 1, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static final Class<?> blockDigPacket = Reflection.getClass("{nms}.PacketPlayInBlockDig");
|
||||||
|
private static final Class<?> playerDigType = blockDigPacket.getDeclaredClasses()[0];
|
||||||
|
private static final Reflection.FieldAccessor<?> blockDigType = Reflection.getField(blockDigPacket, playerDigType, 0);
|
||||||
|
private static final Object releaseUseItem = playerDigType.getEnumConstants()[5];
|
||||||
|
private Object blockDig(Player p, Object packet) {
|
||||||
|
if(blockDigType.get(packet) == releaseUseItem)
|
||||||
|
GlobalRecorder.getInstance().bowSpan(p, false, false);
|
||||||
|
return packet;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static final Class<?> blockPlacePacket = Reflection.getClass("{nms}.PacketPlayInBlockPlace");
|
||||||
|
private Object blockPlace(Player p, Object packet) {
|
||||||
|
boolean mainHand = BountifulWrapper.impl.mainHand(packet);
|
||||||
|
if(BountifulWrapper.impl.bowInHand(mainHand, p))
|
||||||
|
GlobalRecorder.getInstance().bowSpan(p, true, !mainHand);
|
||||||
|
return packet;
|
||||||
|
}
|
||||||
|
|
||||||
@EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true)
|
@EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true)
|
||||||
public void onPlayerMove(PlayerMoveEvent e){
|
public void onPlayerMove(PlayerMoveEvent e){
|
||||||
if(isNotSent(e.getPlayer()))
|
if(isNotSent(e.getPlayer()))
|
||||||
@ -231,7 +223,7 @@ public class Recording implements Listener {
|
|||||||
Location loc = e.getLocation();
|
Location loc = e.getLocation();
|
||||||
GlobalRecorder.getInstance().entityDespawns(e.getEntity());
|
GlobalRecorder.getInstance().entityDespawns(e.getEntity());
|
||||||
GlobalRecorder.getInstance().particle(loc.getX(), loc.getY(), loc.getZ(), "EXPLOSION_HUGE");
|
GlobalRecorder.getInstance().particle(loc.getX(), loc.getY(), loc.getZ(), "EXPLOSION_HUGE");
|
||||||
GlobalRecorder.getInstance().sound(loc.getBlockX(), loc.getBlockY(), loc.getBlockZ(), SWSound.ENTITY_GENERIC_EXPLODE, EnumWrappers.SoundCategory.BLOCKS.name(), 4.0F, (1.0F + (random.nextFloat() - random.nextFloat()) * 0.2F) * 0.7F);
|
GlobalRecorder.getInstance().sound(loc.getBlockX(), loc.getBlockY(), loc.getBlockZ(), SWSound.ENTITY_GENERIC_EXPLODE, "BLOCKS", 4.0F, (1.0F + (random.nextFloat() - random.nextFloat()) * 0.2F) * 0.7F);
|
||||||
}
|
}
|
||||||
|
|
||||||
@EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true)
|
@EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true)
|
||||||
|
@ -19,18 +19,16 @@
|
|||||||
|
|
||||||
package de.steamwar.fightsystem.record;
|
package de.steamwar.fightsystem.record;
|
||||||
|
|
||||||
import com.comphenix.protocol.PacketType;
|
import com.comphenix.tinyprotocol.Reflection;
|
||||||
import com.comphenix.protocol.ProtocolLibrary;
|
|
||||||
import com.comphenix.protocol.events.PacketContainer;
|
|
||||||
import com.comphenix.protocol.reflect.StructureModifier;
|
|
||||||
import com.comphenix.protocol.wrappers.*;
|
|
||||||
import com.mojang.authlib.GameProfile;
|
import com.mojang.authlib.GameProfile;
|
||||||
import de.steamwar.core.Core;
|
import de.steamwar.core.Core;
|
||||||
|
import de.steamwar.fightsystem.fight.Fight;
|
||||||
import de.steamwar.fightsystem.listener.FightScoreboard;
|
import de.steamwar.fightsystem.listener.FightScoreboard;
|
||||||
import de.steamwar.fightsystem.utils.BlockIdWrapper;
|
import de.steamwar.fightsystem.utils.BlockIdWrapper;
|
||||||
|
import de.steamwar.fightsystem.utils.BountifulWrapper;
|
||||||
|
import de.steamwar.fightsystem.utils.FlatteningWrapper;
|
||||||
|
import de.steamwar.fightsystem.utils.ProtocolAPI;
|
||||||
import de.steamwar.sql.SteamwarUser;
|
import de.steamwar.sql.SteamwarUser;
|
||||||
import net.royawesome.jlibnoise.MathHelper;
|
|
||||||
import org.bukkit.Bukkit;
|
|
||||||
import org.bukkit.Material;
|
import org.bukkit.Material;
|
||||||
import org.bukkit.enchantments.Enchantment;
|
import org.bukkit.enchantments.Enchantment;
|
||||||
import org.bukkit.entity.EntityType;
|
import org.bukkit.entity.EntityType;
|
||||||
@ -39,9 +37,7 @@ import org.bukkit.inventory.ItemStack;
|
|||||||
import org.bukkit.scoreboard.NameTagVisibility;
|
import org.bukkit.scoreboard.NameTagVisibility;
|
||||||
import org.bukkit.scoreboard.Team;
|
import org.bukkit.scoreboard.Team;
|
||||||
|
|
||||||
import java.lang.reflect.InvocationTargetException;
|
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
import java.util.logging.Level;
|
|
||||||
|
|
||||||
public class REntity {
|
public class REntity {
|
||||||
|
|
||||||
@ -51,43 +47,48 @@ public class REntity {
|
|||||||
return entities.get(internalId);
|
return entities.get(internalId);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static Object entityStatusWatcher;
|
||||||
|
private static Object sneakingDataWatcher;
|
||||||
|
private static Object bowDrawnWatcher;
|
||||||
|
public static void initWatchers() {
|
||||||
|
// not during <clinit> to prevent cyclic class init.
|
||||||
|
entityStatusWatcher = BountifulWrapper.impl.getDataWatcherObject(0, Byte.class);
|
||||||
|
sneakingDataWatcher = BountifulWrapper.impl.getDataWatcherObject(Core.getVersion() > 12 ? 6 : 0, BlockIdWrapper.impl.getPose(true).getClass());
|
||||||
|
bowDrawnWatcher = BountifulWrapper.impl.getDataWatcherObject(Core.getVersion() > 12 ? 7 : 6, Byte.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
public static void tickFire() {
|
public static void tickFire() {
|
||||||
entities.forEach((integer, entity) -> {
|
entities.forEach((integer, entity) -> {
|
||||||
if(entity.fireTick > 0) {
|
if(entity.fireTick > 0) {
|
||||||
entity.fireTick--;
|
entity.fireTick--;
|
||||||
if(entity.fireTick == 0) {
|
if(entity.fireTick == 0) {
|
||||||
ProtocolLibrary.getProtocolManager().broadcastServerPacket(entity.getDataWatcherPacket(0, (byte)0));
|
ProtocolAPI.broadcastPacket(entity.getDataWatcherPacket(entityStatusWatcher, (byte)0));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void playerJoins(Player player) {
|
public static void playerJoins(Player player) {
|
||||||
try{
|
for(REntity entity : entities.values()){
|
||||||
for(REntity entity : entities.values()){
|
if(entity.entityType == EntityType.PLAYER){
|
||||||
if(entity.entityType == EntityType.PLAYER){
|
ProtocolAPI.tinyProtocol.sendPacket(player, entity.getPlayerInfoPacket());
|
||||||
ProtocolLibrary.getProtocolManager().sendServerPacket(player, entity.getPlayerInfoPacket());
|
ProtocolAPI.tinyProtocol.sendPacket(player, entity.getNamedSpawnPacket());
|
||||||
ProtocolLibrary.getProtocolManager().sendServerPacket(player, entity.getNamedSpawnPacket());
|
for (Map.Entry<String, ItemStack> entry : entity.itemSlots.entrySet()) {
|
||||||
for (Map.Entry<String, ItemStack> entry : entity.itemSlots.entrySet()) {
|
ProtocolAPI.tinyProtocol.sendPacket(player, entity.getEquipmentPacket(entry.getKey(), entry.getValue()));
|
||||||
ProtocolLibrary.getProtocolManager().sendServerPacket(player, entity.getEquipmentPacket(entry.getKey(), entry.getValue()));
|
|
||||||
}
|
|
||||||
}else{
|
|
||||||
ProtocolLibrary.getProtocolManager().sendServerPacket(player, entity.getSpawnEntityPacket());
|
|
||||||
}
|
|
||||||
//ProtocolLibrary.getProtocolManager().sendServerPacket(player, entity.getTeleportPacket()); Sollte nicht nötig sein?
|
|
||||||
if(entity.fireTick != 0) {
|
|
||||||
ProtocolLibrary.getProtocolManager().sendServerPacket(player, entity.getDataWatcherPacket(0, (byte) 1));
|
|
||||||
}
|
|
||||||
if(entity.sneaks) {
|
|
||||||
if(Core.getVersion() > 12){
|
|
||||||
ProtocolLibrary.getProtocolManager().sendServerPacket(player, entity.getDataWatcherPacket(6, BlockIdWrapper.impl.getPose(true)));
|
|
||||||
}else{
|
|
||||||
ProtocolLibrary.getProtocolManager().sendServerPacket(player, entity.getDataWatcherPacket(0, (byte) 2));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
}else{
|
||||||
|
ProtocolAPI.tinyProtocol.sendPacket(player, entity.getSpawnEntityPacket());
|
||||||
|
}
|
||||||
|
ProtocolAPI.tinyProtocol.sendPacket(player, entity.getTeleportPacket());
|
||||||
|
ProtocolAPI.tinyProtocol.sendPacket(player, entity.getHeadRotationPacket());
|
||||||
|
|
||||||
|
if(entity.fireTick != 0) {
|
||||||
|
ProtocolAPI.tinyProtocol.sendPacket(player, entity.getDataWatcherPacket(entityStatusWatcher, (byte) 1));
|
||||||
|
}
|
||||||
|
if(entity.sneaks) {
|
||||||
|
ProtocolAPI.tinyProtocol.sendPacket(player, entity.getDataWatcherPacket(sneakingDataWatcher, BlockIdWrapper.impl.getPose(true)));
|
||||||
}
|
}
|
||||||
}catch(InvocationTargetException e){
|
|
||||||
Bukkit.getLogger().log(Level.SEVERE, "Could not sync player", e);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -114,7 +115,7 @@ public class REntity {
|
|||||||
private final int entityId;
|
private final int entityId;
|
||||||
private final UUID uuid;
|
private final UUID uuid;
|
||||||
private final EntityType entityType;
|
private final EntityType entityType;
|
||||||
private final PlayerInfoData playerInfoData;
|
private final String name;
|
||||||
private final Map<String, ItemStack> itemSlots = new HashMap<>();
|
private final Map<String, ItemStack> itemSlots = new HashMap<>();
|
||||||
|
|
||||||
private double locX;
|
private double locX;
|
||||||
@ -133,23 +134,23 @@ public class REntity {
|
|||||||
|
|
||||||
SteamwarUser user = SteamwarUser.get(userId);
|
SteamwarUser user = SteamwarUser.get(userId);
|
||||||
this.uuid = user.getUUID();
|
this.uuid = user.getUUID();
|
||||||
this.playerInfoData = new PlayerInfoData(WrappedGameProfile.fromHandle(new GameProfile(uuid, user.getUserName())), 0, EnumWrappers.NativeGameMode.SURVIVAL, WrappedChatComponent.fromText(user.getUserName()));
|
this.name = user.getUserName();
|
||||||
entities.put(internalId, this);
|
entities.put(internalId, this);
|
||||||
|
|
||||||
ProtocolLibrary.getProtocolManager().broadcastServerPacket(getPlayerInfoPacket());
|
ProtocolAPI.broadcastPacket(getPlayerInfoPacket());
|
||||||
ProtocolLibrary.getProtocolManager().broadcastServerPacket(getNamedSpawnPacket());
|
ProtocolAPI.broadcastPacket(getNamedSpawnPacket());
|
||||||
team.addEntry(user.getUserName());
|
team.addEntry(name);
|
||||||
}
|
}
|
||||||
|
|
||||||
public REntity(int internalId, EntityType entityType){
|
public REntity(int internalId, EntityType entityType){
|
||||||
this.internalId = internalId;
|
this.internalId = internalId;
|
||||||
this.entityType = entityType;
|
this.entityType = entityType;
|
||||||
this.entityId = entityCount--;
|
this.entityId = entityCount--;
|
||||||
this.playerInfoData = null;
|
this.name = null;
|
||||||
this.uuid = new UUID(random.nextLong() & -61441L | 16384L, random.nextLong() & 4611686018427387903L | -9223372036854775808L);
|
this.uuid = new UUID(random.nextLong() & -61441L | 16384L, random.nextLong() & 4611686018427387903L | -9223372036854775808L);
|
||||||
entities.put(internalId, this);
|
entities.put(internalId, this);
|
||||||
|
|
||||||
ProtocolLibrary.getProtocolManager().broadcastServerPacket(getSpawnEntityPacket());
|
ProtocolAPI.broadcastPacket(getSpawnEntityPacket());
|
||||||
}
|
}
|
||||||
|
|
||||||
public void move(double locX, double locY, double locZ, float pitch, float yaw, byte headYaw){
|
public void move(double locX, double locY, double locZ, float pitch, float yaw, byte headYaw){
|
||||||
@ -159,43 +160,50 @@ public class REntity {
|
|||||||
this.yaw = (byte)((int)(yaw * 256.0F / 360.0F));
|
this.yaw = (byte)((int)(yaw * 256.0F / 360.0F));
|
||||||
this.pitch = (byte)((int)(pitch * 256.0F / 360.0F));
|
this.pitch = (byte)((int)(pitch * 256.0F / 360.0F));
|
||||||
this.headYaw = headYaw;
|
this.headYaw = headYaw;
|
||||||
ProtocolLibrary.getProtocolManager().broadcastServerPacket(getTeleportPacket());
|
ProtocolAPI.broadcastPacket(getTeleportPacket());
|
||||||
ProtocolLibrary.getProtocolManager().broadcastServerPacket(getHeadRotationPacket());
|
ProtocolAPI.broadcastPacket(getHeadRotationPacket());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static final Class<?> animationPacket = Reflection.getClass("{nms}.PacketPlayOutAnimation");
|
||||||
|
private static final Reflection.ConstructorInvoker animationConstructor = Reflection.getConstructor(animationPacket);
|
||||||
|
private static final Reflection.FieldAccessor<Integer> animationEntity = Reflection.getField(animationPacket, int.class, 0);
|
||||||
|
private static final Reflection.FieldAccessor<Integer> animationAnimation = Reflection.getField(animationPacket, int.class, 1);
|
||||||
public void animation(byte animation) {
|
public void animation(byte animation) {
|
||||||
PacketContainer animationPacket = ProtocolLibrary.getProtocolManager().createPacket(PacketType.Play.Server.ANIMATION);
|
Object packet = animationConstructor.invoke();
|
||||||
StructureModifier<Integer> ints = animationPacket.getIntegers();
|
animationEntity.set(packet, entityId);
|
||||||
ints.write(0, entityId);
|
animationAnimation.set(packet, (int) animation);
|
||||||
ints.write(1, (int) animation);
|
ProtocolAPI.broadcastPacket(packet);
|
||||||
ProtocolLibrary.getProtocolManager().broadcastServerPacket(animationPacket);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static final Class<?> velocityPacket = Reflection.getClass("{nms}.PacketPlayOutEntityVelocity");
|
||||||
|
private static final Reflection.ConstructorInvoker velocityConstructor = Reflection.getConstructor(velocityPacket);
|
||||||
|
private static final Reflection.FieldAccessor<Integer> velocityEntity = Reflection.getField(velocityPacket, int.class, 0);
|
||||||
|
private static final Reflection.FieldAccessor<Integer> velocityX = Reflection.getField(velocityPacket, int.class, 1);
|
||||||
|
private static final Reflection.FieldAccessor<Integer> velocityY = Reflection.getField(velocityPacket, int.class, 2);
|
||||||
|
private static final Reflection.FieldAccessor<Integer> velocityZ = Reflection.getField(velocityPacket, int.class, 3);
|
||||||
public void setVelocity(double dX, double dY, double dZ) {
|
public void setVelocity(double dX, double dY, double dZ) {
|
||||||
PacketContainer velocityPacket = ProtocolLibrary.getProtocolManager().createPacket(PacketType.Play.Server.ENTITY_VELOCITY);
|
Object packet = velocityConstructor.invoke();
|
||||||
StructureModifier<Integer> ints = velocityPacket.getIntegers();
|
velocityEntity.set(packet, entityId);
|
||||||
ints.write(0, entityId);
|
velocityX.set(packet, calcVelocity(dX));
|
||||||
ints.write(1, calcVelocity(dX));
|
velocityY.set(packet, calcVelocity(dY));
|
||||||
ints.write(2, calcVelocity(dY));
|
velocityZ.set(packet, calcVelocity(dZ));
|
||||||
ints.write(3, calcVelocity(dZ));
|
ProtocolAPI.broadcastPacket(packet);
|
||||||
ProtocolLibrary.getProtocolManager().broadcastServerPacket(velocityPacket);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static final Class<?> statusPacket = Reflection.getClass("{nms}.PacketPlayOutEntityStatus");
|
||||||
|
private static final Reflection.ConstructorInvoker statusConstructor = Reflection.getConstructor(statusPacket);
|
||||||
|
private static final Reflection.FieldAccessor<Integer> statusEntity = Reflection.getField(statusPacket, int.class, 0);
|
||||||
|
private static final Reflection.FieldAccessor<Byte> statusStatus = Reflection.getField(statusPacket, byte.class, 0);
|
||||||
public void damage() {
|
public void damage() {
|
||||||
PacketContainer statusPacket = ProtocolLibrary.getProtocolManager().createPacket(PacketType.Play.Server.ENTITY_STATUS);
|
Object packet = statusConstructor.invoke();
|
||||||
statusPacket.getIntegers().write(0, entityId);
|
statusEntity.set(packet, entityId);
|
||||||
statusPacket.getBytes().write(0, (byte) 2);
|
statusStatus.set(packet, (byte) 2);
|
||||||
ProtocolLibrary.getProtocolManager().broadcastServerPacket(statusPacket);
|
ProtocolAPI.broadcastPacket(packet);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void sneak(boolean sneaking) {
|
public void sneak(boolean sneaking) {
|
||||||
sneaks = sneaking;
|
sneaks = sneaking;
|
||||||
|
ProtocolAPI.broadcastPacket(getDataWatcherPacket(sneakingDataWatcher, BlockIdWrapper.impl.getPose(sneaking)));
|
||||||
if(Core.getVersion() > 12){
|
|
||||||
ProtocolLibrary.getProtocolManager().broadcastServerPacket(getDataWatcherPacket(6, BlockIdWrapper.impl.getPose(sneaking)));
|
|
||||||
}else{
|
|
||||||
ProtocolLibrary.getProtocolManager().broadcastServerPacket(getDataWatcherPacket(0, sneaking ? (byte) 2 : (byte) 0));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setOnFire(boolean perma) {
|
public void setOnFire(boolean perma) {
|
||||||
@ -205,14 +213,14 @@ public class REntity {
|
|||||||
fireTick = -1;
|
fireTick = -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
ProtocolLibrary.getProtocolManager().broadcastServerPacket(getDataWatcherPacket(0, (byte) 1));
|
ProtocolAPI.broadcastPacket(getDataWatcherPacket(entityStatusWatcher, (byte) 1));
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setBowDrawn(boolean drawn, boolean offHand) {
|
public void setBowDrawn(boolean drawn, boolean offHand) {
|
||||||
if(Core.getVersion() > 8){
|
if(Core.getVersion() > 8){
|
||||||
ProtocolLibrary.getProtocolManager().broadcastServerPacket(getDataWatcherPacket(Core.getVersion() > 12 ? 7 : 6, (byte) ((drawn ? 1 : 0) + (offHand ? 2 : 0))));
|
ProtocolAPI.broadcastPacket(getDataWatcherPacket(bowDrawnWatcher, (byte) ((drawn ? 1 : 0) + (offHand ? 2 : 0))));
|
||||||
}else{
|
}else{
|
||||||
ProtocolLibrary.getProtocolManager().broadcastServerPacket(getDataWatcherPacket(0, (byte)0x10));
|
ProtocolAPI.broadcastPacket(getDataWatcherPacket(entityStatusWatcher, (byte)0x10));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -222,7 +230,7 @@ public class REntity {
|
|||||||
stack.addUnsafeEnchantment(Enchantment.DURABILITY, 1);
|
stack.addUnsafeEnchantment(Enchantment.DURABILITY, 1);
|
||||||
itemSlots.put(slot, stack);
|
itemSlots.put(slot, stack);
|
||||||
|
|
||||||
ProtocolLibrary.getProtocolManager().broadcastServerPacket(getEquipmentPacket(slot, stack));
|
ProtocolAPI.broadcastPacket(getEquipmentPacket(slot, stack));
|
||||||
}
|
}
|
||||||
|
|
||||||
public void die(){
|
public void die(){
|
||||||
@ -230,144 +238,99 @@ public class REntity {
|
|||||||
entities.remove(internalId);
|
entities.remove(internalId);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static final Class<?> destroyPacket = Reflection.getClass("{nms}.PacketPlayOutEntityDestroy");
|
||||||
|
private static final Reflection.ConstructorInvoker destroyConstructor = Reflection.getConstructor(destroyPacket);
|
||||||
|
private static final Reflection.FieldAccessor<int[]> destroyEntities = Reflection.getField(destroyPacket, int[].class, 0);
|
||||||
private void broadcastDeath(){
|
private void broadcastDeath(){
|
||||||
if(entityType == EntityType.PLAYER){
|
if(entityType == EntityType.PLAYER){
|
||||||
PacketContainer infoPacket = ProtocolLibrary.getProtocolManager().createPacket(PacketType.Play.Server.PLAYER_INFO);
|
ProtocolAPI.broadcastPacket(Fight.playerInfoPacket(Fight.removePlayer, new GameProfile(uuid, name), Fight.creative));
|
||||||
infoPacket.getPlayerInfoAction().write(0, EnumWrappers.PlayerInfoAction.REMOVE_PLAYER);
|
team.removeEntry(name);
|
||||||
infoPacket.getPlayerInfoDataLists().write(0, Collections.singletonList(playerInfoData));
|
|
||||||
ProtocolLibrary.getProtocolManager().broadcastServerPacket(infoPacket);
|
|
||||||
team.removeEntry(playerInfoData.getProfile().getName());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
PacketContainer destroyPacket = ProtocolLibrary.getProtocolManager().createPacket(PacketType.Play.Server.ENTITY_DESTROY);
|
Object packet = destroyConstructor.invoke();
|
||||||
destroyPacket.getIntegerArrays().write(0, new int[]{entityId});
|
destroyEntities.set(packet, new int[]{entityId});
|
||||||
ProtocolLibrary.getProtocolManager().broadcastServerPacket(destroyPacket);
|
ProtocolAPI.broadcastPacket(packet);
|
||||||
}
|
}
|
||||||
|
|
||||||
private int calcVelocity(double value) {
|
private int calcVelocity(double value) {
|
||||||
return (int)(Math.max(-3.9, Math.min(value, 3.9)) * 8000);
|
return (int)(Math.max(-3.9, Math.min(value, 3.9)) * 8000);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void fillPositioningPacket(PacketContainer packet, StructureModifier<Integer> ints){
|
private static final Class<?> metadataPacket = Reflection.getClass("{nms}.PacketPlayOutEntityMetadata");
|
||||||
ints.write(0, entityId);
|
private static final Reflection.ConstructorInvoker metadataConstructor = Reflection.getConstructor(metadataPacket);
|
||||||
if(Core.getVersion() > 8){
|
private static final Reflection.FieldAccessor<Integer> metadataEntity = Reflection.getField(metadataPacket, int.class, 0);
|
||||||
StructureModifier<Double> doubles = packet.getDoubles();
|
private static final Reflection.FieldAccessor<List> metadataMetadata = Reflection.getField(metadataPacket, List.class, 0);
|
||||||
doubles.write(0, locX);
|
private Object getDataWatcherPacket(Object dataWatcherObject, Object value) {
|
||||||
doubles.write(1, locY);
|
Object packet = metadataConstructor.invoke();
|
||||||
doubles.write(2, locZ);
|
metadataEntity.set(packet, entityId);
|
||||||
}else{
|
metadataMetadata.set(packet, Collections.singletonList(BountifulWrapper.impl.getDataWatcherItem(dataWatcherObject, value)));
|
||||||
ints.write(1, MathHelper.floor(locX * 32));
|
return packet;
|
||||||
ints.write(2, MathHelper.floor(locY * 32));
|
|
||||||
ints.write(3, MathHelper.floor(locZ * 32));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void fillByteRotation(PacketContainer packet){
|
public static final Class<?> teleportPacket = Reflection.getClass("{nms}.PacketPlayOutEntityTeleport");
|
||||||
StructureModifier<Byte> bytes = packet.getBytes();
|
private static final Reflection.ConstructorInvoker teleportConstructor = Reflection.getConstructor(teleportPacket);
|
||||||
bytes.write(0, yaw);
|
private static final Reflection.FieldAccessor<Integer> teleportEntity = Reflection.getField(teleportPacket, int.class, 0);
|
||||||
bytes.write(1, pitch);
|
private static final Reflection.FieldAccessor<Byte> teleportYaw = Reflection.getField(teleportPacket, byte.class, 0);
|
||||||
|
private static final Reflection.FieldAccessor<Byte> teleportPitch = Reflection.getField(teleportPacket, byte.class, 1);
|
||||||
|
private Object getTeleportPacket(){
|
||||||
|
Object packet = teleportConstructor.invoke();
|
||||||
|
teleportEntity.set(packet, entityId);
|
||||||
|
BountifulWrapper.impl.setTeleportPacketPosition(packet, locX, locY, locZ);
|
||||||
|
teleportYaw.set(packet, yaw);
|
||||||
|
teleportPitch.set(packet, pitch);
|
||||||
|
return packet;
|
||||||
}
|
}
|
||||||
|
|
||||||
private PacketContainer getDataWatcherPacket(int index, Object value) {
|
private static final Class<?> headRotationPacket = Reflection.getClass("{nms}.PacketPlayOutEntityHeadRotation");
|
||||||
PacketContainer metadataPacket = ProtocolLibrary.getProtocolManager().createPacket(PacketType.Play.Server.ENTITY_METADATA);
|
private static final Reflection.ConstructorInvoker headRotationConstructor = Reflection.getConstructor(headRotationPacket);
|
||||||
metadataPacket.getIntegers().write(0, entityId);
|
private static final Reflection.FieldAccessor<Integer> headRotationEntity = Reflection.getField(headRotationPacket, int.class, 0);
|
||||||
WrappedWatchableObject watchable = new WrappedWatchableObject(new WrappedDataWatcher.WrappedDataWatcherObject(index, WrappedDataWatcher.Registry.get(value.getClass())), value);
|
private static final Reflection.FieldAccessor<Byte> headRotationYaw = Reflection.getField(headRotationPacket, byte.class, 0);
|
||||||
watchable.setDirtyState(true);
|
private Object getHeadRotationPacket(){
|
||||||
metadataPacket.getWatchableCollectionModifier().write(0, Collections.singletonList(watchable));
|
Object packet = headRotationConstructor.invoke();
|
||||||
return metadataPacket;
|
headRotationEntity.set(packet, entityId);
|
||||||
|
headRotationYaw.set(packet, headYaw);
|
||||||
|
return packet;
|
||||||
}
|
}
|
||||||
|
|
||||||
private PacketContainer getTeleportPacket(){
|
public static final Class<?> spawnPacket = Reflection.getClass("{nms}.PacketPlayOutSpawnEntity");
|
||||||
PacketContainer teleportPacket = ProtocolLibrary.getProtocolManager().createPacket(PacketType.Play.Server.ENTITY_TELEPORT);
|
private static final Reflection.ConstructorInvoker spawnConstructor = Reflection.getConstructor(spawnPacket);
|
||||||
fillPositioningPacket(teleportPacket, teleportPacket.getIntegers());
|
private static final Reflection.FieldAccessor<Integer> spawnEntity = Reflection.getField(spawnPacket, int.class, 0);
|
||||||
fillByteRotation(teleportPacket);
|
private Object getSpawnEntityPacket(){
|
||||||
return teleportPacket;
|
Object packet = spawnConstructor.invoke();
|
||||||
|
spawnEntity.set(packet, entityId);
|
||||||
|
BountifulWrapper.impl.setSpawnPacketUUID(packet, uuid);
|
||||||
|
FlatteningWrapper.impl.setSpawnPacketType(packet, entityType);
|
||||||
|
return packet;
|
||||||
}
|
}
|
||||||
|
|
||||||
private PacketContainer getHeadRotationPacket(){
|
public static final Class<?> equipmentPacket = Reflection.getClass("{nms}.PacketPlayOutEntityEquipment");
|
||||||
PacketContainer headRotation = ProtocolLibrary.getProtocolManager().createPacket(PacketType.Play.Server.ENTITY_HEAD_ROTATION);
|
private static final Reflection.ConstructorInvoker equipmentConstructor = Reflection.getConstructor(equipmentPacket);
|
||||||
headRotation.getIntegers().write(0, entityId);
|
private static final Reflection.FieldAccessor<Integer> equipmentEntity = Reflection.getField(equipmentPacket, int.class, 0);
|
||||||
headRotation.getBytes().write(0, headYaw);
|
private static final Class<?> itemStack = Reflection.getClass("{nms}.ItemStack");
|
||||||
return headRotation;
|
private static final Reflection.FieldAccessor<?> equipmentStack = Reflection.getField(equipmentPacket, itemStack, 0);
|
||||||
|
private static final Class<?> craftItemStack = Reflection.getClass("{obc}.inventory.CraftItemStack");
|
||||||
|
private static final Reflection.MethodInvoker asNMSCopy = Reflection.getTypedMethod(craftItemStack, "asNMSCopy", itemStack, ItemStack.class);
|
||||||
|
private Object getEquipmentPacket(String slot, ItemStack stack){
|
||||||
|
Object packet = equipmentConstructor.invoke();
|
||||||
|
equipmentEntity.set(packet, entityId);
|
||||||
|
BountifulWrapper.impl.setEquipmentPacketSlot(packet, slot);
|
||||||
|
equipmentStack.set(packet, asNMSCopy.invoke(null, stack));
|
||||||
|
return packet;
|
||||||
}
|
}
|
||||||
|
|
||||||
private PacketContainer getSpawnEntityPacket(){
|
private Object getPlayerInfoPacket(){
|
||||||
PacketContainer spawnPacket = ProtocolLibrary.getProtocolManager().createPacket(PacketType.Play.Server.SPAWN_ENTITY);
|
return Fight.playerInfoPacket(Fight.addPlayer, new GameProfile(uuid, name), Fight.creative);
|
||||||
StructureModifier<Integer> ints = spawnPacket.getIntegers();
|
|
||||||
fillPositioningPacket(spawnPacket, ints);
|
|
||||||
spawnPacket.getUUIDs().write(0, uuid);
|
|
||||||
if(Core.getVersion() > 8){
|
|
||||||
spawnPacket.getUUIDs().write(0, uuid);
|
|
||||||
ints.write(1, 0); // dX
|
|
||||||
ints.write(2, 0); // dY
|
|
||||||
ints.write(3, 0); // dZ
|
|
||||||
}
|
|
||||||
ints.write(4, (int)pitch);
|
|
||||||
ints.write(5, (int)yaw);
|
|
||||||
if(Core.getVersion() > 12){
|
|
||||||
spawnPacket.getEntityTypeModifier().write(0, entityType);
|
|
||||||
}else{
|
|
||||||
switch(entityType){
|
|
||||||
case PRIMED_TNT:
|
|
||||||
ints.write(6, 50);
|
|
||||||
break;
|
|
||||||
case ARROW:
|
|
||||||
ints.write(6, 60);
|
|
||||||
break;
|
|
||||||
case FIREBALL:
|
|
||||||
ints.write(6, 63);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return spawnPacket;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private PacketContainer getEquipmentPacket(String slot, ItemStack stack){
|
public static final Class<?> namedSpawnPacket = Reflection.getClass("{nms}.PacketPlayOutNamedEntitySpawn");
|
||||||
PacketContainer equipmentPacket = ProtocolLibrary.getProtocolManager().createPacket(PacketType.Play.Server.ENTITY_EQUIPMENT);
|
private static final Reflection.ConstructorInvoker namedSpawnConstructor = Reflection.getConstructor(namedSpawnPacket);
|
||||||
StructureModifier<Integer> ints = equipmentPacket.getIntegers();
|
private static final Reflection.FieldAccessor<Integer> namedSpawnEntity = Reflection.getField(namedSpawnPacket, int.class, 0);
|
||||||
ints.write(0, entityId);
|
private static final Reflection.FieldAccessor<UUID> namedSpawnUUID = Reflection.getField(namedSpawnPacket, UUID.class, 0);
|
||||||
if(Core.getVersion() == 8){
|
private Object getNamedSpawnPacket(){
|
||||||
switch(slot){
|
Object packet = namedSpawnConstructor.invoke();
|
||||||
case "MAINHAND":
|
namedSpawnEntity.set(packet, entityId);
|
||||||
case "OFFHAND":
|
namedSpawnUUID.set(packet, uuid);
|
||||||
ints.write(1, 0);
|
FlatteningWrapper.impl.setNamedSpawnPacketDataWatcher(packet);
|
||||||
break;
|
return packet;
|
||||||
case "HEAD":
|
|
||||||
ints.write(1, 4);
|
|
||||||
break;
|
|
||||||
case "CHEST":
|
|
||||||
ints.write(1, 3);
|
|
||||||
break;
|
|
||||||
case "LEGS":
|
|
||||||
ints.write(1, 2);
|
|
||||||
break;
|
|
||||||
case "FEET":
|
|
||||||
default:
|
|
||||||
ints.write(1, 1);
|
|
||||||
}
|
|
||||||
}else{
|
|
||||||
equipmentPacket.getItemSlots().write(0, EnumWrappers.ItemSlot.valueOf(slot));
|
|
||||||
}
|
|
||||||
equipmentPacket.getItemModifier().write(0, stack);
|
|
||||||
return equipmentPacket;
|
|
||||||
}
|
|
||||||
|
|
||||||
private PacketContainer getPlayerInfoPacket(){
|
|
||||||
PacketContainer infoPacket = ProtocolLibrary.getProtocolManager().createPacket(PacketType.Play.Server.PLAYER_INFO);
|
|
||||||
infoPacket.getPlayerInfoAction().write(0, EnumWrappers.PlayerInfoAction.ADD_PLAYER);
|
|
||||||
infoPacket.getPlayerInfoDataLists().write(0, Collections.singletonList(playerInfoData));
|
|
||||||
return infoPacket;
|
|
||||||
}
|
|
||||||
|
|
||||||
private PacketContainer getNamedSpawnPacket(){
|
|
||||||
PacketContainer namedSpawnPacket = ProtocolLibrary.getProtocolManager().createPacket(PacketType.Play.Server.NAMED_ENTITY_SPAWN);
|
|
||||||
StructureModifier<Integer> ints = namedSpawnPacket.getIntegers();
|
|
||||||
fillPositioningPacket(namedSpawnPacket, ints);
|
|
||||||
namedSpawnPacket.getUUIDs().write(0, uuid);
|
|
||||||
fillByteRotation(namedSpawnPacket);
|
|
||||||
if(Core.getVersion() < 13){
|
|
||||||
namedSpawnPacket.getDataWatcherModifier().write(0, new WrappedDataWatcher());
|
|
||||||
}
|
|
||||||
return namedSpawnPacket;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -19,7 +19,6 @@
|
|||||||
|
|
||||||
package de.steamwar.fightsystem.utils;
|
package de.steamwar.fightsystem.utils;
|
||||||
|
|
||||||
import com.comphenix.protocol.wrappers.EnumWrappers;
|
|
||||||
import de.steamwar.fightsystem.VersionDependent;
|
import de.steamwar.fightsystem.VersionDependent;
|
||||||
import net.md_5.bungee.api.chat.BaseComponent;
|
import net.md_5.bungee.api.chat.BaseComponent;
|
||||||
import org.bukkit.World;
|
import org.bukkit.World;
|
||||||
@ -27,13 +26,16 @@ import org.bukkit.entity.Player;
|
|||||||
import org.bukkit.event.Listener;
|
import org.bukkit.event.Listener;
|
||||||
import org.bukkit.scoreboard.Team;
|
import org.bukkit.scoreboard.Team;
|
||||||
|
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
public class BountifulWrapper {
|
public class BountifulWrapper {
|
||||||
private BountifulWrapper() {}
|
private BountifulWrapper() {}
|
||||||
|
|
||||||
public static final IBountifulWrapper impl = VersionDependent.getVersionImpl(BountifulWrapper.class.getName());
|
public static final IBountifulWrapper impl = VersionDependent.getVersionImpl(BountifulWrapper.class.getName());
|
||||||
|
|
||||||
public interface IBountifulWrapper {
|
public interface IBountifulWrapper {
|
||||||
boolean bowInHand(EnumWrappers.Hand hand, Player p);
|
boolean mainHand(Object packet);
|
||||||
|
boolean bowInHand(boolean mainHand, Player p);
|
||||||
|
|
||||||
void toActionbar(Player player, BaseComponent... components);
|
void toActionbar(Player player, BaseComponent... components);
|
||||||
void toChat(Player player, BaseComponent... components);
|
void toChat(Player player, BaseComponent... components);
|
||||||
@ -49,5 +51,11 @@ public class BountifulWrapper {
|
|||||||
Listener newHandSwapRecorder();
|
Listener newHandSwapRecorder();
|
||||||
|
|
||||||
void spawnParticle(World world, String particleName, double x, double y, double z);
|
void spawnParticle(World world, String particleName, double x, double y, double z);
|
||||||
|
|
||||||
|
Object getDataWatcherObject(int index, Class<?> type);
|
||||||
|
Object getDataWatcherItem(Object dataWatcherObject, Object value);
|
||||||
|
void setTeleportPacketPosition(Object packet, double x, double y, double z);
|
||||||
|
void setSpawnPacketUUID(Object packet, UUID uuid);
|
||||||
|
void setEquipmentPacketSlot(Object packet, String slot);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -24,6 +24,7 @@ import org.bukkit.DyeColor;
|
|||||||
import org.bukkit.Material;
|
import org.bukkit.Material;
|
||||||
import org.bukkit.World;
|
import org.bukkit.World;
|
||||||
import org.bukkit.block.Block;
|
import org.bukkit.block.Block;
|
||||||
|
import org.bukkit.entity.EntityType;
|
||||||
import org.bukkit.event.block.BlockPhysicsEvent;
|
import org.bukkit.event.block.BlockPhysicsEvent;
|
||||||
import org.bukkit.inventory.ItemStack;
|
import org.bukkit.inventory.ItemStack;
|
||||||
import org.bukkit.inventory.meta.ItemMeta;
|
import org.bukkit.inventory.meta.ItemMeta;
|
||||||
@ -49,5 +50,8 @@ public class FlatteningWrapper {
|
|||||||
void forceLoadChunk(World world, int cX, int cZ);
|
void forceLoadChunk(World world, int cX, int cZ);
|
||||||
|
|
||||||
boolean checkPistonMoving(Block block);
|
boolean checkPistonMoving(Block block);
|
||||||
|
|
||||||
|
void setNamedSpawnPacketDataWatcher(Object packet);
|
||||||
|
void setSpawnPacketType(Object packet, EntityType type);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
138
FightSystem_Core/src/de/steamwar/fightsystem/utils/ProtocolAPI.java
Normale Datei
138
FightSystem_Core/src/de/steamwar/fightsystem/utils/ProtocolAPI.java
Normale Datei
@ -0,0 +1,138 @@
|
|||||||
|
/*
|
||||||
|
This file is a part of the SteamWar software.
|
||||||
|
|
||||||
|
Copyright (C) 2021 SteamWar.de-Serverteam
|
||||||
|
|
||||||
|
This program is free software: you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU Affero General Public License as published by
|
||||||
|
the Free Software Foundation, either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU Affero General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU Affero General Public License
|
||||||
|
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package de.steamwar.fightsystem.utils;
|
||||||
|
|
||||||
|
import com.comphenix.tinyprotocol.TinyProtocol;
|
||||||
|
import de.steamwar.fightsystem.FightSystem;
|
||||||
|
import io.netty.channel.Channel;
|
||||||
|
import org.bukkit.Bukkit;
|
||||||
|
import org.bukkit.entity.Player;
|
||||||
|
|
||||||
|
import java.lang.reflect.Array;
|
||||||
|
import java.lang.reflect.Field;
|
||||||
|
import java.lang.reflect.Modifier;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.function.BiConsumer;
|
||||||
|
import java.util.function.BiFunction;
|
||||||
|
import java.util.function.UnaryOperator;
|
||||||
|
|
||||||
|
public class ProtocolAPI {
|
||||||
|
private ProtocolAPI() {}
|
||||||
|
|
||||||
|
private static final Map<Class<?>, BiFunction<Player, Object, Object>> outgoingHandler = new HashMap<>();
|
||||||
|
private static final Map<Class<?>, BiFunction<Player, Object, Object>> incomingHandler = new HashMap<>();
|
||||||
|
|
||||||
|
public static final TinyProtocol tinyProtocol = new TinyProtocol(FightSystem.getPlugin()) {
|
||||||
|
@Override
|
||||||
|
public Object onPacketOutAsync(Player receiver, Channel channel, Object packet) {
|
||||||
|
BiFunction<Player, Object, Object> handler = outgoingHandler.get(packet.getClass());
|
||||||
|
if(handler == null)
|
||||||
|
return packet;
|
||||||
|
return handler.apply(receiver, packet);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Object onPacketInAsync(Player sender, Channel channel, Object packet) {
|
||||||
|
BiFunction<Player, Object, Object> handler = incomingHandler.get(packet.getClass());
|
||||||
|
if(handler == null)
|
||||||
|
return packet;
|
||||||
|
return handler.apply(sender, packet);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
public static void setOutgoingHandler(Class<?> packetClass, BiFunction<Player, Object, Object> handler) {
|
||||||
|
outgoingHandler.put(packetClass, handler);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void removeOutgoingHandler(Class<?> packetClass) {
|
||||||
|
outgoingHandler.remove(packetClass);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void setIncomingHandler(Class<?> packetClass, BiFunction<Player, Object, Object> handler) {
|
||||||
|
incomingHandler.put(packetClass, handler);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void removeIncomingHandler(Class<?> packetClass) {
|
||||||
|
incomingHandler.remove(packetClass);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void broadcastPacket(Object packet) {
|
||||||
|
Bukkit.getOnlinePlayers().stream().map(tinyProtocol::getChannel).filter(tinyProtocol::hasInjected).forEach(channel -> tinyProtocol.sendPacket(channel, packet));
|
||||||
|
}
|
||||||
|
|
||||||
|
public static BiFunction<Object, UnaryOperator<Object>, Object> arrayCloneGenerator(Class<?> elementClass) {
|
||||||
|
return (array, worker) -> {
|
||||||
|
int length = Array.getLength(array);
|
||||||
|
Object result = Array.newInstance(elementClass, length);
|
||||||
|
|
||||||
|
for(int i = 0; i < length; i++)
|
||||||
|
Array.set(result, i, worker.apply(Array.get(array, i)));
|
||||||
|
|
||||||
|
return result;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
public static UnaryOperator<Object> shallowCloneGenerator(Class<?> clazz) {
|
||||||
|
BiConsumer<Object, Object> filler = shallowFill(clazz);
|
||||||
|
|
||||||
|
return source -> {
|
||||||
|
Object clone;
|
||||||
|
try {
|
||||||
|
clone = clazz.newInstance();
|
||||||
|
} catch (InstantiationException | IllegalAccessException e) {
|
||||||
|
throw new IllegalStateException("Could not clone " + clazz.getName(), e);
|
||||||
|
}
|
||||||
|
filler.accept(source, clone);
|
||||||
|
return clone;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
private static BiConsumer<Object, Object> shallowFill(Class<?> clazz) {
|
||||||
|
if(clazz == null)
|
||||||
|
return (source, clone) -> {};
|
||||||
|
|
||||||
|
BiConsumer<Object, Object> superFiller = shallowFill(clazz.getSuperclass());
|
||||||
|
|
||||||
|
Field[] fds = clazz.getDeclaredFields();
|
||||||
|
List<Field> fields = new ArrayList<>();
|
||||||
|
for(Field field : fds) {
|
||||||
|
if (Modifier.isStatic(field.getModifiers()))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
field.setAccessible(true);
|
||||||
|
fields.add(field);
|
||||||
|
}
|
||||||
|
|
||||||
|
return (source, clone) -> {
|
||||||
|
superFiller.accept(source, clone);
|
||||||
|
try {
|
||||||
|
for(Field field : fields) {
|
||||||
|
field.set(clone, field.get(source));
|
||||||
|
}
|
||||||
|
} catch (IllegalAccessException e) {
|
||||||
|
throw new IllegalStateException("Could not set field", e);
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
@ -19,21 +19,10 @@
|
|||||||
|
|
||||||
package de.steamwar.fightsystem.utils;
|
package de.steamwar.fightsystem.utils;
|
||||||
|
|
||||||
import com.comphenix.protocol.PacketType;
|
import com.comphenix.tinyprotocol.Reflection;
|
||||||
import com.comphenix.protocol.ProtocolLibrary;
|
|
||||||
import com.comphenix.protocol.ProtocolManager;
|
|
||||||
import com.comphenix.protocol.events.PacketAdapter;
|
|
||||||
import com.comphenix.protocol.events.PacketContainer;
|
|
||||||
import com.comphenix.protocol.events.PacketEvent;
|
|
||||||
import com.comphenix.protocol.reflect.StructureModifier;
|
|
||||||
import com.comphenix.protocol.wrappers.BlockPosition;
|
|
||||||
import com.comphenix.protocol.wrappers.ChunkCoordIntPair;
|
|
||||||
import com.comphenix.protocol.wrappers.MultiBlockChangeInfo;
|
|
||||||
import com.comphenix.protocol.wrappers.WrappedBlockData;
|
|
||||||
import com.google.common.primitives.Bytes;
|
import com.google.common.primitives.Bytes;
|
||||||
import de.steamwar.core.Core;
|
import de.steamwar.core.Core;
|
||||||
import de.steamwar.core.events.ChunkListener;
|
import de.steamwar.core.events.ChunkListener;
|
||||||
import de.steamwar.fightsystem.ArenaMode;
|
|
||||||
import de.steamwar.fightsystem.Config;
|
import de.steamwar.fightsystem.Config;
|
||||||
import de.steamwar.fightsystem.FightSystem;
|
import de.steamwar.fightsystem.FightSystem;
|
||||||
import de.steamwar.fightsystem.VersionDependent;
|
import de.steamwar.fightsystem.VersionDependent;
|
||||||
@ -41,212 +30,197 @@ import de.steamwar.fightsystem.fight.Fight;
|
|||||||
import de.steamwar.fightsystem.fight.FightTeam;
|
import de.steamwar.fightsystem.fight.FightTeam;
|
||||||
import de.steamwar.fightsystem.states.FightState;
|
import de.steamwar.fightsystem.states.FightState;
|
||||||
import de.steamwar.fightsystem.states.StateDependent;
|
import de.steamwar.fightsystem.states.StateDependent;
|
||||||
|
import io.netty.buffer.ByteBuf;
|
||||||
|
import io.netty.buffer.UnpooledByteBufAllocator;
|
||||||
import org.bukkit.Bukkit;
|
import org.bukkit.Bukkit;
|
||||||
import org.bukkit.GameMode;
|
import org.bukkit.GameMode;
|
||||||
import org.bukkit.Material;
|
import org.bukkit.Material;
|
||||||
import org.bukkit.entity.Player;
|
import org.bukkit.entity.Player;
|
||||||
|
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
|
import java.util.function.BiFunction;
|
||||||
|
import java.util.function.Function;
|
||||||
|
import java.util.function.UnaryOperator;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
public class TechHider extends StateDependent {
|
public class TechHider extends StateDependent {
|
||||||
|
|
||||||
|
private static final Class<?> blockPosition = Reflection.getClass("{nms}.BlockPosition");
|
||||||
|
private static final Class<?> baseBlockPosition = Reflection.getClass("{nms}.BaseBlockPosition");
|
||||||
|
private static final Reflection.FieldAccessor<Integer> blockPositionX = Reflection.getField(baseBlockPosition, int.class, 0);
|
||||||
|
private static final Reflection.FieldAccessor<Integer> blockPositionZ = Reflection.getField(baseBlockPosition, int.class, 2);
|
||||||
|
|
||||||
|
private static final Class<?> iBlockData = Reflection.getClass("{nms}.IBlockData");
|
||||||
|
private static final Class<?> block = Reflection.getClass("{nms}.Block");
|
||||||
|
private static final Reflection.MethodInvoker getBlockByBlockData = Reflection.getTypedMethod(iBlockData, "getBlock", block);
|
||||||
|
private static final Reflection.MethodInvoker getBlockDataByBlock = Reflection.getTypedMethod(block, "getBlockData", iBlockData);
|
||||||
|
|
||||||
|
private static final Class<?> craftMagicNumbers = Reflection.getClass("{obc}.util.CraftMagicNumbers");
|
||||||
|
private static final Reflection.MethodInvoker getMaterialByBlock = Reflection.getTypedMethod(craftMagicNumbers, "getMaterial", Material.class, block);
|
||||||
|
private static final Reflection.MethodInvoker getBlockByMaterial = Reflection.getTypedMethod(craftMagicNumbers, "getBlock", block, Material.class);
|
||||||
|
|
||||||
public static final boolean ENABLED = !Config.OnlyPublicSchematics && !Config.test() && Config.TechhiderActive;
|
public static final boolean ENABLED = !Config.OnlyPublicSchematics && !Config.test() && Config.TechhiderActive;
|
||||||
|
|
||||||
private final ProtocolManager protocolManager = ProtocolLibrary.getProtocolManager();
|
private final Object obfuscateIBlockData = getBlockDataByBlock.invoke(getBlockByMaterial.invoke(null, Material.getMaterial(Config.ObfuscateWith.toUpperCase())));
|
||||||
private final Map<PacketContainer, PacketContainer> packetCache = new HashMap<>();
|
private final Map<Class<?>, BiFunction<Player, Object, Object>> techhiders = new HashMap<>();
|
||||||
private final Material obfuscateMaterial;
|
private final BiFunction<byte[], Integer, byte[]> chunkDataHider;
|
||||||
private final PacketAdapter chunkHider;
|
|
||||||
private final int threadMultiplier;
|
|
||||||
|
|
||||||
public TechHider(){
|
public TechHider(){
|
||||||
super(ENABLED, FightState.Schem);
|
super(ENABLED, FightState.Schem);
|
||||||
|
|
||||||
obfuscateMaterial = Material.getMaterial(Config.ObfuscateWith.toUpperCase());
|
chunkDataHider = VersionDependent.getVersionImpl(TechHider.class.getName());
|
||||||
chunkHider = VersionDependent.getVersionImpl(TechHider.class.getName());
|
|
||||||
|
|
||||||
if(Config.mode == ArenaMode.EVENT)
|
techhiders.put(blockActionPacket, this::blockActionHider);
|
||||||
threadMultiplier = 4;
|
techhiders.put(blockChangePacket, this::blockChangeHider);
|
||||||
else
|
techhiders.put(tileEntityDataPacket, this::tileEntityDataHider);
|
||||||
threadMultiplier = 1;
|
techhiders.put(multiBlockChangePacket, this::multiBlockChangeHider);
|
||||||
|
if(Core.getVersion() > 8) {
|
||||||
Bukkit.getScheduler().runTaskTimer(FightSystem.getPlugin(), packetCache::clear, 1, 1);
|
techhiders.put(mapChunkPacket, this::mapChunkHider);
|
||||||
|
}
|
||||||
|
if(Core.getVersion() > 12) {
|
||||||
|
Class<?> blockBreakClass = Reflection.getClass("{nms}.PacketPlayOutBlockBreak");
|
||||||
|
techhiders.put(blockBreakClass, blockBreakHiderGenerator(blockBreakClass));
|
||||||
|
}
|
||||||
|
|
||||||
if(Core.getVersion() > 8){
|
if(Core.getVersion() > 8){
|
||||||
protocolManager.addPacketListener(new PacketAdapter(FightSystem.getPlugin(), PacketType.Play.Client.USE_ITEM) {
|
ProtocolAPI.setIncomingHandler(Reflection.getClass("{nms}.PacketPlayInUseItem"), (p, packet) -> p.getGameMode() == GameMode.SPECTATOR ? null : packet);
|
||||||
@Override
|
|
||||||
public void onPacketReceiving(PacketEvent e) {
|
|
||||||
Player p = e.getPlayer();
|
|
||||||
|
|
||||||
if(p == null || p.getGameMode() == GameMode.SPECTATOR)
|
|
||||||
e.setCancelled(true);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
protocolManager.addPacketListener(new PacketAdapter(FightSystem.getPlugin(), PacketType.Play.Client.USE_ENTITY) {
|
ProtocolAPI.setIncomingHandler(Reflection.getClass("{nms}.PacketPlayInUseEntity"), (p, packet) -> p.getGameMode() == GameMode.SPECTATOR ? null : packet);
|
||||||
@Override
|
|
||||||
public void onPacketReceiving(PacketEvent e) {
|
|
||||||
Player p = e.getPlayer();
|
|
||||||
|
|
||||||
if(p.getGameMode() == GameMode.SPECTATOR)
|
|
||||||
e.setCancelled(true);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
register();
|
register();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void enable() {
|
public void enable() {
|
||||||
protocolManager.addPacketListener(blockHider);
|
techhiders.forEach(ProtocolAPI::setOutgoingHandler);
|
||||||
protocolManager.addPacketListener(multiBlockHider);
|
|
||||||
protocolManager.addPacketListener(blockActionHider);
|
|
||||||
protocolManager.getAsynchronousManager().registerAsyncHandler(chunkHider).start(threadMultiplier * 4);
|
|
||||||
if(Core.getVersion() > 8) {
|
|
||||||
protocolManager.addPacketListener(updateBlockEntity);
|
|
||||||
}
|
|
||||||
if(Core.getVersion() > 12) {
|
|
||||||
protocolManager.addPacketListener(blockBreakHider);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void disable() {
|
public void disable() {
|
||||||
protocolManager.removePacketListener(blockHider);
|
techhiders.keySet().forEach(ProtocolAPI::removeOutgoingHandler);
|
||||||
protocolManager.removePacketListener(multiBlockHider);
|
|
||||||
protocolManager.removePacketListener(blockActionHider);
|
|
||||||
protocolManager.getAsynchronousManager().unregisterAsyncHandler(chunkHider);
|
|
||||||
if(Core.getVersion() > 8) {
|
|
||||||
protocolManager.removePacketListener(updateBlockEntity);
|
|
||||||
}
|
|
||||||
if(Core.getVersion() > 12) {
|
|
||||||
protocolManager.removePacketListener(blockBreakHider);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private final PacketAdapter multiBlockHider = new PacketAdapter(FightSystem.getPlugin(), PacketType.Play.Server.MULTI_BLOCK_CHANGE) {
|
private static final Class<?> nbtTagCompound = Reflection.getClass("{nms}.NBTTagCompound");
|
||||||
@Override
|
private static final Reflection.MethodInvoker nbtTagGetString = Reflection.getTypedMethod(nbtTagCompound, "getString", String.class, String.class);
|
||||||
public void onPacketSending(PacketEvent e) {
|
|
||||||
PacketContainer packet = e.getPacket();
|
|
||||||
|
|
||||||
Player p = e.getPlayer();
|
private static final Class<?> mapChunkPacket = Reflection.getClass("{nms}.PacketPlayOutMapChunk");
|
||||||
ChunkCoordIntPair pos = packet.getChunkCoordIntPairs().read(0);
|
private static final UnaryOperator<Object> mapChunkCloner = ProtocolAPI.shallowCloneGenerator(mapChunkPacket);
|
||||||
if(bypass(p, pos.getChunkX(), pos.getChunkZ()))
|
private static final Reflection.FieldAccessor<Integer> mapChunkX = Reflection.getField(mapChunkPacket, int.class, 0);
|
||||||
return;
|
private static final Reflection.FieldAccessor<Integer> mapChunkZ = Reflection.getField(mapChunkPacket, int.class, 1);
|
||||||
|
private static final Reflection.FieldAccessor<Integer> mapChunkBitMask;
|
||||||
PacketContainer cached = packetCache.get(packet);
|
private static final Reflection.FieldAccessor<List> mapChunkBlockEntities;
|
||||||
if(cached != null){
|
private static final Reflection.FieldAccessor<byte[]> mapChunkData;
|
||||||
e.setPacket(cached);
|
static {
|
||||||
return;
|
if(Core.getVersion() > 8) {
|
||||||
}
|
mapChunkBitMask = Reflection.getField(mapChunkPacket, int.class, 2);
|
||||||
|
mapChunkBlockEntities = Reflection.getField(mapChunkPacket, List.class, 0);
|
||||||
cached = packet.shallowClone();
|
mapChunkData = Reflection.getField(mapChunkPacket, byte[].class, 0);
|
||||||
packetCache.put(packet, cached);
|
}else {
|
||||||
e.setPacket(cached);
|
mapChunkBitMask = null;
|
||||||
StructureModifier<MultiBlockChangeInfo[]> blockStructure = cached.getMultiBlockChangeInfoArrays();
|
mapChunkBlockEntities = null;
|
||||||
MultiBlockChangeInfo[] changes = blockStructure.read(0).clone();
|
mapChunkData = null;
|
||||||
boolean changed = false;
|
|
||||||
for(MultiBlockChangeInfo mbci : changes){
|
|
||||||
WrappedBlockData block = mbci.getData();
|
|
||||||
if(Config.HiddenBlocks.contains(block.getType().name().toLowerCase())){
|
|
||||||
changed = true;
|
|
||||||
block.setType(obfuscateMaterial);
|
|
||||||
mbci.setData(block);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if(changed){
|
|
||||||
blockStructure.write(0, changes);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
};
|
}
|
||||||
|
private Object mapChunkHider(Player p, Object packet) {
|
||||||
|
if(bypass(p, mapChunkX.get(packet), mapChunkZ.get(packet)))
|
||||||
|
return packet;
|
||||||
|
|
||||||
private final PacketAdapter blockHider = new PacketAdapter(FightSystem.getPlugin(), PacketType.Play.Server.BLOCK_CHANGE) {
|
packet = mapChunkCloner.apply(packet);
|
||||||
@Override
|
mapChunkBlockEntities.set(packet, ((List<?>)mapChunkBlockEntities.get(packet)).stream().filter(
|
||||||
public void onPacketSending(PacketEvent e) {
|
nbttag -> Config.HiddenBlockEntities.contains((String) nbtTagGetString.invoke(nbttag, "id"))
|
||||||
PacketContainer packet = e.getPacket();
|
).collect(Collectors.toList()));
|
||||||
BlockPosition pos = packet.getBlockPositionModifier().read(0);
|
|
||||||
|
|
||||||
Player p = e.getPlayer();
|
byte[] data = chunkDataHider.apply(mapChunkData.get(packet), mapChunkBitMask.get(packet));
|
||||||
if(bypass(p, posToChunk(pos.getX()), posToChunk(pos.getZ())))
|
ByteBuf buffer = UnpooledByteBufAllocator.DEFAULT.directBuffer(data.length + 100);
|
||||||
return;
|
data = new byte[buffer.readableBytes()];
|
||||||
|
buffer.readBytes(data);
|
||||||
|
mapChunkData.set(packet, data);
|
||||||
|
|
||||||
PacketContainer cached = packetCache.get(packet);
|
return packet;
|
||||||
if(cached != null){
|
}
|
||||||
e.setPacket(cached);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
cached = packet.deepClone();
|
private static final Class<?> multiBlockChangePacket = Reflection.getClass("{nms}.PacketPlayOutMultiBlockChange");
|
||||||
packetCache.put(packet, cached);
|
private static final UnaryOperator<Object> multiBlockChangeCloner = ProtocolAPI.shallowCloneGenerator(multiBlockChangePacket);
|
||||||
e.setPacket(cached);
|
private static final Class<?> chunkCoordinateIntPair = Reflection.getClass("{nms}.ChunkCoordIntPair");
|
||||||
StructureModifier<WrappedBlockData> blockStructure = cached.getBlockData();
|
private static final Reflection.FieldAccessor<?> multiBlockChangeChunk = Reflection.getField(multiBlockChangePacket, chunkCoordinateIntPair, 0);
|
||||||
WrappedBlockData block = blockStructure.read(0);
|
private static final Reflection.FieldAccessor<Integer> chunkCoordinateX = Reflection.getField(chunkCoordinateIntPair, int.class, 0);
|
||||||
if(Config.HiddenBlocks.contains(block.getType().name().toLowerCase())){
|
private static final Reflection.FieldAccessor<Integer> chunkCoordinateZ = Reflection.getField(chunkCoordinateIntPair, int.class, 1);
|
||||||
block.setType(obfuscateMaterial);
|
private static final Class<?> multiBlockChangeInfo = Reflection.getClass("{nms}.PacketPlayOutMultiBlockChange$MultiBlockChangeInfo");
|
||||||
blockStructure.write(0, block);
|
private static final Reflection.ConstructorInvoker multiBlockChangeInfoConstructor = Reflection.getConstructor(multiBlockChangeInfo, multiBlockChangePacket, short.class, iBlockData);
|
||||||
}
|
private static final BiFunction<Object, UnaryOperator<Object>, Object> multiBlockChangeInfoArrayCloner = ProtocolAPI.arrayCloneGenerator(multiBlockChangeInfo);
|
||||||
|
private static final Reflection.FieldAccessor<?> multiBlockChangeInfoBlock = Reflection.getField(multiBlockChangeInfo, iBlockData, 0);
|
||||||
|
private static final Reflection.FieldAccessor<?> multiBlockChangeInfoPos = Reflection.getField(multiBlockChangeInfo, short.class, 0);
|
||||||
|
private static final Class<?> multiBlockChangeInfoArray = Reflection.getClass("[L{nms}.PacketPlayOutMultiBlockChange$MultiBlockChangeInfo;");
|
||||||
|
private static final Reflection.FieldAccessor<?> multiBlockChangeInfos = Reflection.getField(multiBlockChangePacket, multiBlockChangeInfoArray, 0);
|
||||||
|
private Object multiBlockChangeHider(Player p, Object packet) {
|
||||||
|
Object chunkCoords = multiBlockChangeChunk.get(packet);
|
||||||
|
if(bypass(p, chunkCoordinateX.get(chunkCoords), chunkCoordinateZ.get(chunkCoords)))
|
||||||
|
return packet;
|
||||||
|
|
||||||
|
Object modpacket = multiBlockChangeCloner.apply(packet);
|
||||||
|
multiBlockChangeInfos.set(modpacket, multiBlockChangeInfoArrayCloner.apply(multiBlockChangeInfos.get(modpacket), mbci -> {
|
||||||
|
if(Config.HiddenBlocks.contains(getMaterialByIBlockData(multiBlockChangeInfoBlock.get(mbci)).name().toLowerCase()))
|
||||||
|
return multiBlockChangeInfoConstructor.invoke(modpacket, multiBlockChangeInfoPos.get(mbci), obfuscateIBlockData);
|
||||||
|
return mbci;
|
||||||
|
}));
|
||||||
|
return modpacket;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static final Class<?> blockChangePacket = Reflection.getClass("{nms}.PacketPlayOutBlockChange");
|
||||||
|
private static final Function<Object, Object> blockChangeCloner = ProtocolAPI.shallowCloneGenerator(blockChangePacket);
|
||||||
|
private static final Reflection.FieldAccessor<?> blockChangePosition = Reflection.getField(blockChangePacket, blockPosition, 0);
|
||||||
|
private static final Reflection.FieldAccessor<?> blockChangeBlockData = Reflection.getField(blockChangePacket, iBlockData, 0);
|
||||||
|
private Object blockChangeHider(Player p, Object packet) {
|
||||||
|
Object pos = blockChangePosition.get(packet);
|
||||||
|
if(bypass(p, posToChunk(blockPositionX.get(pos)), posToChunk(blockPositionZ.get(pos))))
|
||||||
|
return packet;
|
||||||
|
|
||||||
|
if(Config.HiddenBlocks.contains(getMaterialByIBlockData(blockChangeBlockData.get(packet)).name().toLowerCase())){
|
||||||
|
packet = blockChangeCloner.apply(packet);
|
||||||
|
blockChangeBlockData.set(packet, obfuscateIBlockData);
|
||||||
}
|
}
|
||||||
};
|
return packet;
|
||||||
|
}
|
||||||
|
|
||||||
private final PacketAdapter blockActionHider = new PacketAdapter(FightSystem.getPlugin(), PacketType.Play.Server.BLOCK_ACTION) {
|
private static final Class<?> blockActionPacket = Reflection.getClass("{nms}.PacketPlayOutBlockAction");
|
||||||
@Override
|
private static final Reflection.FieldAccessor<?> blockActionPosition = Reflection.getField(blockActionPacket, blockPosition, 0);
|
||||||
public void onPacketSending(PacketEvent e) {
|
private Object blockActionHider(Player p, Object packet) {
|
||||||
PacketContainer packet = e.getPacket();
|
Object pos = blockActionPosition.get(packet);
|
||||||
BlockPosition pos = packet.getBlockPositionModifier().read(0);
|
if(bypass(p, posToChunk(blockPositionX.get(pos)), posToChunk(blockPositionZ.get(pos))))
|
||||||
|
return packet;
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
Player p = e.getPlayer();
|
private BiFunction<Player, Object, Object> blockBreakHiderGenerator(Class<?> blockBreakPacket){
|
||||||
if(bypass(p, posToChunk(pos.getX()), posToChunk(pos.getZ())))
|
UnaryOperator<Object> blockBreakCloner = ProtocolAPI.shallowCloneGenerator(blockBreakPacket);
|
||||||
return;
|
Reflection.FieldAccessor<?> blockBreakPosition = Reflection.getField(blockBreakPacket, blockPosition, 0);
|
||||||
|
Reflection.FieldAccessor<?> blockBreakBlockData = Reflection.getField(blockBreakPacket, iBlockData, 0);
|
||||||
|
|
||||||
e.setCancelled(true);
|
return (p, packet) -> {
|
||||||
}
|
Object pos = blockBreakPosition.get(packet);
|
||||||
};
|
if(bypass(p, posToChunk(blockPositionX.get(pos)), posToChunk(blockPositionZ.get(pos))))
|
||||||
|
return packet;
|
||||||
|
|
||||||
private final PacketAdapter blockBreakHider = new PacketAdapter(FightSystem.getPlugin(), PacketType.Play.Server.BLOCK_BREAK) {
|
if(Config.HiddenBlocks.contains(getMaterialByIBlockData(blockBreakBlockData.get(packet)).name().toLowerCase())){
|
||||||
@Override
|
packet = blockBreakCloner.apply(packet);
|
||||||
public void onPacketSending(PacketEvent e) {
|
blockBreakBlockData.set(packet, obfuscateIBlockData);
|
||||||
PacketContainer packet = e.getPacket();
|
|
||||||
BlockPosition pos = packet.getBlockPositionModifier().read(0);
|
|
||||||
|
|
||||||
Player p = e.getPlayer();
|
|
||||||
if(bypass(p, posToChunk(pos.getX()), posToChunk(pos.getZ())))
|
|
||||||
return;
|
|
||||||
|
|
||||||
|
|
||||||
PacketContainer cached = packetCache.get(packet);
|
|
||||||
if(cached != null){
|
|
||||||
e.setPacket(cached);
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
return packet;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
cached = packet.deepClone();
|
private static final Class<?> tileEntityDataPacket = Reflection.getClass("{nms}.PacketPlayOutTileEntityData");
|
||||||
packetCache.put(packet, cached);
|
private static final Reflection.FieldAccessor<?> tileEntityDataPosition = Reflection.getField(tileEntityDataPacket, blockPosition, 0);
|
||||||
e.setPacket(cached);
|
private static final Reflection.FieldAccessor<Integer> tileEntityDataAction = Reflection.getField(tileEntityDataPacket, int.class, 0);
|
||||||
StructureModifier<WrappedBlockData> blockStructure = cached.getBlockData();
|
private Object tileEntityDataHider(Player p, Object packet) {
|
||||||
WrappedBlockData block = blockStructure.read(0);
|
Object pos = tileEntityDataPosition.get(packet);
|
||||||
if(Config.HiddenBlocks.contains(block.getType().name().toLowerCase())){
|
if(bypass(p, posToChunk(blockPositionX.get(pos)), posToChunk(blockPositionZ.get(pos))))
|
||||||
block.setType(obfuscateMaterial);
|
return packet;
|
||||||
blockStructure.write(0, block);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
private final PacketAdapter updateBlockEntity = new PacketAdapter(FightSystem.getPlugin(), PacketType.Play.Server.TILE_ENTITY_DATA) {
|
if(tileEntityDataAction.get(packet) != 9)
|
||||||
@Override
|
return packet;
|
||||||
public void onPacketSending(PacketEvent event) {
|
return null;
|
||||||
PacketContainer packet = event.getPacket();
|
}
|
||||||
BlockPosition pos = packet.getBlockPositionModifier().read(0);
|
|
||||||
|
|
||||||
Player p = event.getPlayer();
|
|
||||||
if(bypass(p, posToChunk(pos.getX()), posToChunk(pos.getZ())))
|
|
||||||
return;
|
|
||||||
|
|
||||||
// 9 == Set sign text
|
|
||||||
if(packet.getIntegers().read(0) != 9)
|
|
||||||
return;
|
|
||||||
|
|
||||||
event.setCancelled(true);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
public static List<ChunkPos> prepareChunkReload(Player p, boolean hide){
|
public static List<ChunkPos> prepareChunkReload(Player p, boolean hide){
|
||||||
if(!ENABLED)
|
if(!ENABLED)
|
||||||
@ -284,6 +258,10 @@ public class TechHider extends StateDependent {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static Material getMaterialByIBlockData(Object iBlockData) {
|
||||||
|
return (Material) getMaterialByBlock.invoke(null, getBlockByBlockData.invoke(iBlockData));
|
||||||
|
}
|
||||||
|
|
||||||
private static int posToChunk(int c){
|
private static int posToChunk(int c){
|
||||||
int chunk = c / 16;
|
int chunk = c / 16;
|
||||||
if(c<0)
|
if(c<0)
|
||||||
|
@ -4,7 +4,7 @@ authors:
|
|||||||
- Yaruma3341
|
- Yaruma3341
|
||||||
- Lixfel
|
- Lixfel
|
||||||
main: de.steamwar.fightsystem.FightSystem
|
main: de.steamwar.fightsystem.FightSystem
|
||||||
depend: [SpigotCore, WorldEdit, ProtocolLib]
|
depend: [SpigotCore, WorldEdit]
|
||||||
api-version: "1.13"
|
api-version: "1.13"
|
||||||
|
|
||||||
commands:
|
commands:
|
||||||
|
7
pom.xml
7
pom.xml
@ -68,13 +68,6 @@
|
|||||||
<scope>system</scope>
|
<scope>system</scope>
|
||||||
<systemPath>${main.basedir}/lib/SpigotCore.jar</systemPath>
|
<systemPath>${main.basedir}/lib/SpigotCore.jar</systemPath>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
|
||||||
<groupId>steamwar</groupId>
|
|
||||||
<artifactId>ProtocolLib</artifactId>
|
|
||||||
<version>1.0</version>
|
|
||||||
<scope>system</scope>
|
|
||||||
<systemPath>${main.basedir}/lib/ProtocolLib.jar</systemPath>
|
|
||||||
</dependency>
|
|
||||||
</dependencies>
|
</dependencies>
|
||||||
|
|
||||||
</project>
|
</project>
|
||||||
|
In neuem Issue referenzieren
Einen Benutzer sperren