SteamWar/FightSystem
Archiviert
13
1

Merge pull request '1.18' (#323) from 1.18 into master
Alle Prüfungen waren erfolgreich
SteamWarCI Build successful

Reviewed-on: #323
Reviewed-by: YoyoNow <jwsteam@nidido.de>
Dieser Commit ist enthalten in:
Lixfel 2022-02-19 19:38:32 +01:00
Commit 735c2004f2
27 geänderte Dateien mit 987 neuen und 296 gelöschten Zeilen

Datei anzeigen

@ -0,0 +1,48 @@
/*
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.Reflection;
import org.bukkit.entity.Player;
import java.util.function.BiFunction;
import java.util.function.UnaryOperator;
public class ProtocolWrapper12 extends ProtocolWrapper8 {
@Override
public BiFunction<Player, Object, Object> blockBreakHiderGenerator(Class<?> blockBreakPacket){
UnaryOperator<Object> blockBreakCloner = ProtocolAPI.shallowCloneGenerator(blockBreakPacket);
Reflection.FieldAccessor<?> blockBreakPosition = Reflection.getField(blockBreakPacket, TechHider.blockPosition, 0);
Reflection.FieldAccessor<?> blockBreakBlockData = Reflection.getField(blockBreakPacket, TechHider.iBlockData, 0);
return (p, packet) -> {
Object pos = blockBreakPosition.get(packet);
if(TechHider.bypass(p, TechHider.posToChunk(TechHider.blockPositionX.get(pos)), TechHider.posToChunk(TechHider.blockPositionZ.get(pos))))
return packet;
if(ProtocolWrapper.impl.iBlockDataHidden(blockBreakBlockData.get(packet))){
packet = blockBreakCloner.apply(packet);
blockBreakBlockData.set(packet, TechHider.obfuscateIBlockData);
}
return packet;
};
}
}

Datei anzeigen

@ -37,5 +37,10 @@
<artifactId>FightSystem_Core</artifactId> <artifactId>FightSystem_Core</artifactId>
<version>1.0</version> <version>1.0</version>
</dependency> </dependency>
<dependency>
<groupId>steamwar</groupId>
<artifactId>FightSystem_9</artifactId>
<version>1.0</version>
</dependency>
</dependencies> </dependencies>
</project> </project>

Datei anzeigen

@ -19,15 +19,12 @@
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;
@ -119,24 +116,4 @@ public class FlatteningWrapper14 implements FlatteningWrapper.IFlatteningWrapper
public void setNamedSpawnPacketDataWatcher(Object packet) { public void setNamedSpawnPacketDataWatcher(Object packet) {
// field not present // 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;
}
}
} }

Datei anzeigen

@ -24,16 +24,11 @@ import io.netty.buffer.UnpooledByteBufAllocator;
import java.nio.ByteBuffer; import java.nio.ByteBuffer;
import java.nio.LongBuffer; import java.nio.LongBuffer;
import java.util.Set;
import java.util.function.BiFunction;
public class TechHider14 implements BiFunction<byte[], Integer, byte[]> { public class TechHider14 extends TechHider9 {
private final Set<Integer> hiddenBlockIds = BlockIdWrapper.impl.getHiddenBlockIds();
private final int obfuscateWith = BlockIdWrapper.impl.getObfuscateWith();
@Override @Override
public byte[] apply(byte[] data, Integer primaryBitMask) { protected byte[] dataHider(byte[] data, Integer primaryBitMask) {
ByteBuf buffer = UnpooledByteBufAllocator.DEFAULT.directBuffer(data.length + 100); ByteBuf buffer = UnpooledByteBufAllocator.DEFAULT.directBuffer(data.length + 100);
int i = 0; int i = 0;

84
FightSystem_18/pom.xml Normale Datei
Datei anzeigen

@ -0,0 +1,84 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
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/>.
-->
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>steamwar</groupId>
<artifactId>FightSystem</artifactId>
<version>1.0</version>
</parent>
<properties>
<main.basedir>${project.basedir}/..</main.basedir>
</properties>
<artifactId>FightSystem_18</artifactId>
<version>1.0</version>
<dependencies>
<dependency>
<groupId>org.spigotmc</groupId>
<artifactId>spigot-api</artifactId>
<version>1.18-R0.1-SNAPSHOT</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>com.mojang</groupId>
<artifactId>datafixerupper</artifactId>
<version>4.0.26</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>io.netty</groupId>
<artifactId>netty-all</artifactId>
<version>4.1.68.Final</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>com.mojang</groupId>
<artifactId>authlib</artifactId>
<version>1.5.25</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>steamwar</groupId>
<artifactId>Spigot</artifactId>
<version>1.18</version>
<scope>system</scope>
<systemPath>${main.basedir}/lib/Spigot-1.18.jar</systemPath>
</dependency>
<dependency>
<groupId>steamwar</groupId>
<artifactId>WorldEdit</artifactId>
<version>1.0</version>
<scope>system</scope>
<systemPath>${main.basedir}/lib/WorldEdit-1.15.jar</systemPath>
</dependency>
<dependency>
<groupId>steamwar</groupId>
<artifactId>FightSystem_Core</artifactId>
<version>1.0</version>
</dependency>
</dependencies>
</project>

Datei anzeigen

@ -0,0 +1,87 @@
/*
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 de.steamwar.fightsystem.Config;
import net.minecraft.core.BlockPosition;
import net.minecraft.core.IRegistry;
import net.minecraft.resources.MinecraftKey;
import net.minecraft.server.level.WorldServer;
import net.minecraft.world.entity.EntityPose;
import net.minecraft.world.level.block.state.IBlockData;
import net.minecraft.world.level.material.Fluid;
import net.minecraft.world.level.material.FluidTypes;
import org.bukkit.World;
import org.bukkit.block.Block;
import org.bukkit.craftbukkit.v1_18_R1.CraftWorld;
import org.bukkit.craftbukkit.v1_18_R1.block.CraftBlock;
import java.util.HashSet;
import java.util.Objects;
import java.util.Set;
public class BlockIdWrapper18 implements BlockIdWrapper.IBlockIdWrapper {
@Override
public int blockToId(Block block) {
return net.minecraft.world.level.block.Block.i(((CraftBlock)block).getNMS());
}
@Override
public void setBlock(World world, int x, int y, int z, int blockState) {
IBlockData blockData = Objects.requireNonNull(net.minecraft.world.level.block.Block.a(blockState));
WorldServer cworld = ((CraftWorld)world).getHandle();
BlockPosition pos = new BlockPosition(x, y, z);
cworld.m(pos);
cworld.a(pos, blockData, 1042);
cworld.k().a(pos);
}
@Override
public Set<Integer> getHiddenBlockIds() {
Set<Integer> hiddenBlockIds = new HashSet<>();
for(String tag : Config.HiddenBlocks){
for(IBlockData data : IRegistry.X.a(new MinecraftKey(tag)).m().a()){
hiddenBlockIds.add(net.minecraft.world.level.block.Block.i(data));
}
}
if(Config.HiddenBlocks.contains("water")){
Fluid water = FluidTypes.c.h();
for(IBlockData data : net.minecraft.world.level.block.Block.p) {
if(data.n() == water) {
hiddenBlockIds.add(net.minecraft.world.level.block.Block.i(data));
}
}
}
return hiddenBlockIds;
}
@Override
public int getObfuscateWith() { //ResourceLocation, DefaultedRegistry
return net.minecraft.world.level.block.Block.i(IRegistry.X.a(new MinecraftKey(Config.ObfuscateWith)).n());
}
@Override
public Object getPose(boolean sneaking) {
return sneaking ? EntityPose.f : EntityPose.a;
}
}

Datei anzeigen

@ -0,0 +1,63 @@
/*
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 net.minecraft.world.level.chunk.Chunk;
import org.bukkit.World;
import org.bukkit.craftbukkit.v1_18_R1.CraftWorld;
import org.bukkit.craftbukkit.v1_18_R1.entity.CraftEntity;
import org.bukkit.craftbukkit.v1_18_R1.entity.CraftPlayer;
import org.bukkit.craftbukkit.v1_18_R1.inventory.CraftItemStack;
import org.bukkit.entity.Entity;
import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemStack;
import java.util.HashSet;
import java.util.Set;
public class CraftbukkitWrapper18 implements CraftbukkitWrapper.ICraftbukkitWrapper {
@Override
public void resetChunk(World world, World backup, int x, int z) {
net.minecraft.world.level.World w = ((CraftWorld) world).getHandle();
Chunk chunk = w.d(x, z);
Chunk backupChunk = ((CraftWorld) backup).getHandle().d(x, z);
System.arraycopy(backupChunk.d(), 0, chunk.d(), 0, chunk.d().length);
}
@Override
public void sendResourcePack(Player player, String pack, String sha1) {
((CraftPlayer)player).getHandle().a(pack, sha1, true, null);
}
@Override
public float headRotation(Entity e) {
return ((CraftEntity)e).getHandle().ce();
}
@Override
public boolean hasItems(ItemStack stack) {
Set<String> keys = new HashSet<>(CraftItemStack.asNMSCopy(stack).s().d());
keys.remove("Enchantments");
keys.remove("Damage");
return !keys.isEmpty();
}
}

Datei anzeigen

@ -0,0 +1,130 @@
/*
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.Reflection;
import com.mojang.authlib.GameProfile;
import com.mojang.datafixers.util.Pair;
import de.steamwar.fightsystem.Config;
import de.steamwar.fightsystem.fight.Fight;
import de.steamwar.fightsystem.record.REntity;
import net.minecraft.core.IRegistry;
import net.minecraft.core.SectionPosition;
import net.minecraft.network.protocol.game.PacketPlayOutBlockBreak;
import net.minecraft.world.entity.EntityTypes;
import net.minecraft.world.level.block.entity.TileEntityTypes;
import net.minecraft.world.level.block.state.IBlockData;
import org.bukkit.entity.EntityType;
import org.bukkit.entity.Player;
import java.util.Collections;
import java.util.List;
import java.util.function.BiFunction;
import java.util.function.UnaryOperator;
public class ProtocolWrapper18 implements ProtocolWrapper {
private static final Reflection.FieldAccessor<List> equipmentStack = Reflection.getField(REntity.equipmentPacket, List.class, 0);
@Override
public void setEquipmentPacketStack(Object packet, String slot, Object stack) {
equipmentStack.set(packet, Collections.singletonList(new Pair<>(getSlot(slot), stack)));
}
private static final Reflection.FieldAccessor<?> spawnType = Reflection.getField(REntity.spawnPacket, EntityTypes.class, 0);
@Override
public void setSpawnPacketType(Object packet, EntityType type) {
switch(type) {
case PRIMED_TNT:
spawnType.set(packet, EntityTypes.as);
break;
case ARROW:
spawnType.set(packet, EntityTypes.d);
break;
case FIREBALL:
spawnType.set(packet, EntityTypes.S);
break;
}
}
private static final Class<?> enumItemSlot = Reflection.getClass("{nms.world.entity}.EnumItemSlot");
private static final Object[] itemSlots = enumItemSlot.getEnumConstants();
private static Object getSlot(String slot) {
switch(slot){
case "HEAD":
return itemSlots[5];
case "CHEST":
return itemSlots[4];
case "LEGS":
return itemSlots[3];
case "FEET":
return itemSlots[2];
case "OFFHAND":
return itemSlots[1];
case "MAINHAND":
default:
return itemSlots[0];
}
}
private static final Reflection.FieldAccessor<SectionPosition> multiBlockChangeChunk = Reflection.getField(TechHider.multiBlockChangePacket, SectionPosition.class, 0);
private static final Reflection.FieldAccessor<IBlockData[]> multiBlockChangeBlocks = Reflection.getField(TechHider.multiBlockChangePacket, IBlockData[].class, 0);
private static final BiFunction<Object, UnaryOperator<Object>, Object> iBlockDataArrayCloner = ProtocolAPI.arrayCloneGenerator(TechHider.iBlockData);
@Override
public Object multiBlockChangeHider(Player p, Object packet) {
Object chunkCoords = multiBlockChangeChunk.get(packet);
if(TechHider.bypass(p, TechHider.blockPositionX.get(chunkCoords), TechHider.blockPositionZ.get(chunkCoords)))
return packet;
packet = TechHider.multiBlockChangeCloner.apply(packet);
multiBlockChangeBlocks.set(packet, iBlockDataArrayCloner.apply(multiBlockChangeBlocks.get(packet), block -> ProtocolWrapper.impl.iBlockDataHidden(block) ? TechHider.obfuscateIBlockData : block));
return packet;
}
private static final Reflection.FieldAccessor<TileEntityTypes> tileEntityType = Reflection.getField(TechHider.tileEntityDataPacket, TileEntityTypes.class, 0);
@Override
public boolean unfilteredTileEntityDataAction(Object packet) {
return tileEntityType.get(packet) != TileEntityTypes.h;
}
@Override
public BiFunction<Player, Object, Object> blockBreakHiderGenerator(Class<?> blockBreakPacket) {
return (p, packet) -> {
PacketPlayOutBlockBreak breakPacket = (PacketPlayOutBlockBreak) packet;
if(TechHider.bypass(p, TechHider.posToChunk(TechHider.blockPositionX.get(breakPacket.b())), TechHider.posToChunk(TechHider.blockPositionZ.get(breakPacket.b()))))
return packet;
if(!ProtocolWrapper.impl.iBlockDataHidden(breakPacket.c()))
return packet;
return new PacketPlayOutBlockBreak(breakPacket.b(), (IBlockData) TechHider.obfuscateIBlockData, breakPacket.d(), breakPacket.a());
};
}
private static final Reflection.ConstructorInvoker playerInfoDataConstructor = Reflection.getConstructor(Fight.playerInfoDataClass, GameProfile.class, int.class, Fight.enumGamemode, Fight.iChatBaseComponent);
@Override
public Object playerInfoDataConstructor(Object packet, GameProfile profile, Object mode) {
return playerInfoDataConstructor.invoke(profile, 0, mode, null);
}
@Override
public boolean iBlockDataHidden(Object iBlockData) {
return Config.HiddenBlocks.contains(IRegistry.X.b(((IBlockData) iBlockData).b()).a());
}
}

Datei anzeigen

@ -0,0 +1,174 @@
/*
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.Reflection;
import de.steamwar.fightsystem.Config;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.UnpooledByteBufAllocator;
import net.minecraft.core.IRegistry;
import net.minecraft.network.protocol.game.ClientboundLevelChunkPacketData;
import net.minecraft.network.protocol.game.ClientboundLevelChunkWithLightPacket;
import net.minecraft.world.level.block.entity.TileEntityTypes;
import org.bukkit.World;
import org.bukkit.entity.Player;
import java.nio.ByteBuffer;
import java.nio.LongBuffer;
import java.util.List;
import java.util.Set;
import java.util.function.IntFunction;
import java.util.function.UnaryOperator;
import java.util.stream.Collectors;
public class TechHider18 implements TechHider.ChunkHider {
@Override
public Class<?> mapChunkPacket() {
return ClientboundLevelChunkWithLightPacket.class;
}
private static final UnaryOperator<Object> chunkPacketCloner = ProtocolAPI.shallowCloneGenerator(ClientboundLevelChunkWithLightPacket.class);
private static final UnaryOperator<Object> chunkDataCloner = ProtocolAPI.shallowCloneGenerator(ClientboundLevelChunkPacketData.class);
private static final Reflection.FieldAccessor<Integer> chunkX = Reflection.getField(ClientboundLevelChunkWithLightPacket.class, int.class, 0);
private static final Reflection.FieldAccessor<Integer> chunkZ = Reflection.getField(ClientboundLevelChunkWithLightPacket.class, int.class, 1);
private static final Reflection.FieldAccessor<ClientboundLevelChunkPacketData> chunkData = Reflection.getField(ClientboundLevelChunkWithLightPacket.class, ClientboundLevelChunkPacketData.class, 0);
private static final Reflection.FieldAccessor<byte[]> dataField = Reflection.getField(ClientboundLevelChunkPacketData.class, byte[].class, 0);
private static final Reflection.FieldAccessor<List> tileEntities = Reflection.getField(ClientboundLevelChunkPacketData.class, List.class, 0);
public static final Class<?> tileEntity = Reflection.getClass("net.minecraft.network.protocol.game.ClientboundLevelChunkPacketData$a");
private static final Reflection.FieldAccessor<TileEntityTypes> entityType = Reflection.getField(tileEntity, TileEntityTypes.class, 0);
private final Set<Integer> hiddenBlockIds = BlockIdWrapper.impl.getHiddenBlockIds();
private final int obfuscateWith = BlockIdWrapper.impl.getObfuscateWith();
@Override
public Object mapChunkHider(Player p, Object packet) {
if(TechHider.bypass(p, chunkX.get(packet), chunkZ.get(packet)))
return packet;
packet = chunkPacketCloner.apply(packet);
Object data = chunkDataCloner.apply(chunkData.get(packet));
tileEntities.set(data, ((List<?>)tileEntities.get(data)).stream().filter(
tile -> Config.HiddenBlockEntities.contains(IRegistry.ad.b(entityType.get(tile)).a())
).collect(Collectors.toList()));
World world = p.getWorld();
int sections = (world.getMaxHeight() - world.getMinHeight()) / 16;
dataField.set(data, dataHider(dataField.get(data), sections));
chunkData.set(packet, data);
return packet;
}
private byte[] dataHider(byte[] data, int sections) {
ByteBuf buffer = UnpooledByteBufAllocator.DEFAULT.directBuffer(data.length + 100);
int i = 0;
while(sections-- > 0) {
buffer.writeBytes(data, i, 2); // Block count
i += 2;
i = containerWalker(data, buffer, i, 15, blockId -> hiddenBlockIds.contains(blockId) ? obfuscateWith : blockId, (curI, dataArrayLength, bitsPerBlock) -> {
if(bitsPerBlock < 15) {
buffer.writeBytes(data, curI, dataArrayLength * 8);
} else {
ByteBuffer source = ByteBuffer.wrap(data, curI, dataArrayLength * 8);
VariableValueArray values = new VariableValueArray(bitsPerBlock, dataArrayLength, source.asLongBuffer());
for (int pos = 0; pos < 4096; pos++) {
if (hiddenBlockIds.contains(values.get(pos))) {
values.set(pos, obfuscateWith);
}
}
for (long l : values.backing)
buffer.writeLong(l);
}
});
i = containerWalker(data, buffer, i, 6, value -> value, (curI, dataArrayLength, bitsPerBlock) -> buffer.writeBytes(data, curI, dataArrayLength * 8));
}
buffer.writeBytes(data, i, data.length - i); // MC appends a 0 byte at the end if there is a full chunk, idk why
byte[] outdata = new byte[buffer.readableBytes()];
buffer.readBytes(outdata);
return outdata;
}
private int containerWalker(byte[] data, ByteBuf buffer, int i, int globalPalette, IntFunction<Integer> palette, Region.TriConsumer<Integer, Integer, Byte> dataArray) {
byte bitsPerBlock = data[i++];
buffer.writeByte(bitsPerBlock);
if(bitsPerBlock == 0) {
int paletteValue = TechHider.readVarInt(data, i);
i += TechHider.readVarIntLength(data, i);
buffer.writeBytes(TechHider.writeVarInt(palette.apply(paletteValue)));
}else if(bitsPerBlock < globalPalette) {
int paletteLength = TechHider.readVarInt(data, i);
int paletteLengthLength = TechHider.readVarIntLength(data, i);
buffer.writeBytes(data, i, paletteLengthLength);
i += paletteLengthLength;
for(int actPaletteId = 0; actPaletteId < paletteLength; actPaletteId++) {
int paletteValue = TechHider.readVarInt(data, i);
i += TechHider.readVarIntLength(data, i);
buffer.writeBytes(TechHider.writeVarInt(palette.apply(paletteValue)));
}
}
int dataArrayLength = TechHider.readVarInt(data, i);
int dataArrayLengthLength = TechHider.readVarIntLength(data, i);
buffer.writeBytes(data, i, dataArrayLengthLength);
i += dataArrayLengthLength;
dataArray.accept(i, dataArrayLength, bitsPerBlock);
i += dataArrayLength * 8;
return i;
}
private static final class VariableValueArray {
private final long[] backing;
private final int bitsPerValue;
private final long valueMask;
private final int valuesPerLong;
public VariableValueArray(int bitsPerEntry, int dataArrayLength, LongBuffer buffer) {
this.bitsPerValue = bitsPerEntry;
this.backing = new long[dataArrayLength];
buffer.get(backing);
this.valueMask = (1L << this.bitsPerValue) - 1;
this.valuesPerLong = 64 / bitsPerEntry;
}
public int get(int index) {
return (int)((backing[index / valuesPerLong] >> ((index % valuesPerLong) * bitsPerValue)) & valueMask);
}
public void set(int index, int value) {
int i0 = index / valuesPerLong;
int i1 = index % valuesPerLong;
backing[i0] = backing[i0] & ~(this.valueMask << i1) | (value & valueMask) << i1;
}
}
}

Datei anzeigen

@ -128,29 +128,6 @@ public class BountifulWrapper8 implements BountifulWrapper.IBountifulWrapper {
// field not present // 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);
}
}
private final Set<Player> seesDragon = new HashSet<>(); private final Set<Player> seesDragon = new HashSet<>();
private final PacketPlayOutSpawnEntityLiving spawnDragon; private final PacketPlayOutSpawnEntityLiving spawnDragon;
private final int spawnDragonId; private final int spawnDragonId;

Datei anzeigen

@ -20,13 +20,11 @@
package de.steamwar.fightsystem.utils; package de.steamwar.fightsystem.utils;
import com.comphenix.tinyprotocol.Reflection; import com.comphenix.tinyprotocol.Reflection;
import de.steamwar.core.Core;
import de.steamwar.fightsystem.record.REntity; 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;
@ -90,20 +88,4 @@ public class FlatteningWrapper8 implements FlatteningWrapper.IFlatteningWrapper
public void setNamedSpawnPacketDataWatcher(Object packet) { public void setNamedSpawnPacketDataWatcher(Object packet) {
namedSpawnDataWatcher.set(packet, dataWatcherConstructor.invoke((Object) null)); 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;
}
}
} }

Datei anzeigen

@ -0,0 +1,158 @@
/*
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.Reflection;
import com.mojang.authlib.GameProfile;
import de.steamwar.core.Core;
import de.steamwar.fightsystem.Config;
import de.steamwar.fightsystem.fight.Fight;
import de.steamwar.fightsystem.record.REntity;
import org.bukkit.Material;
import org.bukkit.entity.EntityType;
import org.bukkit.entity.Player;
import java.util.function.BiFunction;
import java.util.function.UnaryOperator;
public class ProtocolWrapper8 implements ProtocolWrapper {
private static final Reflection.FieldAccessor<?> equipmentSlot;
private static final Object[] itemSlots;
static {
if(Core.getVersion() == 8) {
equipmentSlot = Reflection.getField(REntity.equipmentPacket, int.class, 1);
itemSlots = new Integer[]{0, 0, 1, 2, 3, 4};
} else {
Class<?> enumItemSlot = Reflection.getClass("{nms.world.entity}.EnumItemSlot");
equipmentSlot = Reflection.getField(REntity.equipmentPacket, enumItemSlot, 0);
itemSlots = enumItemSlot.getEnumConstants();
}
}
private static final Reflection.FieldAccessor<?> equipmentStack = Reflection.getField(REntity.equipmentPacket, REntity.itemStack, 0);
@Override
public void setEquipmentPacketStack(Object packet, String slot, Object stack) {
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]);
}
equipmentStack.set(packet, stack);
}
private static final Reflection.FieldAccessor<?> spawnType;
private static final Object tnt;
private static final Object arrow;
private static final Object fireball;
static {
if(Core.getVersion() < 14) {
spawnType = Reflection.getField(REntity.spawnPacket, int.class, Core.getVersion() > 8 ? 6 : 9);
tnt = 50;
arrow = 60;
fireball = 63;
} else {
Class<?> entityTypes = Reflection.getClass("{nms.world.entity}.EntityTypes");
spawnType = Reflection.getField(REntity.spawnPacket, entityTypes, 0);
tnt = Reflection.getField(entityTypes, "TNT", entityTypes).get(null);
arrow = Reflection.getField(entityTypes, "ARROW", entityTypes).get(null);
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;
}
}
private static final Class<?> chunkCoordinateIntPair = Reflection.getClass("{nms}.ChunkCoordIntPair");
private static final Reflection.FieldAccessor<?> multiBlockChangeChunk = Reflection.getField(TechHider.multiBlockChangePacket, chunkCoordinateIntPair, 0);
private static final Reflection.FieldAccessor<Integer> chunkCoordinateX = Reflection.getField(chunkCoordinateIntPair, int.class, 0);
private static final Reflection.FieldAccessor<Integer> chunkCoordinateZ = Reflection.getField(chunkCoordinateIntPair, int.class, 1);
private static final Class<?> multiBlockChangeInfo = Reflection.getClass("{nms}.PacketPlayOutMultiBlockChange$MultiBlockChangeInfo");
private static final Reflection.ConstructorInvoker multiBlockChangeInfoConstructor = Reflection.getConstructor(multiBlockChangeInfo, TechHider.multiBlockChangePacket, short.class, TechHider.iBlockData);
private static final BiFunction<Object, UnaryOperator<Object>, Object> multiBlockChangeInfoArrayCloner = ProtocolAPI.arrayCloneGenerator(multiBlockChangeInfo);
private static final Reflection.FieldAccessor<?> multiBlockChangeInfoBlock = Reflection.getField(multiBlockChangeInfo, TechHider.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(TechHider.multiBlockChangePacket, multiBlockChangeInfoArray, 0);
@Override
public Object multiBlockChangeHider(Player p, Object packet) {
Object chunkCoords = multiBlockChangeChunk.get(packet);
if(TechHider.bypass(p, chunkCoordinateX.get(chunkCoords), chunkCoordinateZ.get(chunkCoords)))
return packet;
Object modpacket = TechHider.multiBlockChangeCloner.apply(packet);
multiBlockChangeInfos.set(modpacket, multiBlockChangeInfoArrayCloner.apply(multiBlockChangeInfos.get(modpacket), mbci -> {
if(ProtocolWrapper.impl.iBlockDataHidden(multiBlockChangeInfoBlock.get(mbci)))
return multiBlockChangeInfoConstructor.invoke(modpacket, multiBlockChangeInfoPos.get(mbci), TechHider.obfuscateIBlockData);
return mbci;
}));
return modpacket;
}
private static final Reflection.FieldAccessor<Integer> tileEntityDataAction = Reflection.getField(TechHider.tileEntityDataPacket, int.class, 0);
@Override
public boolean unfilteredTileEntityDataAction(Object packet) {
return tileEntityDataAction.get(packet) != 9;
}
@Override
public BiFunction<Player, Object, Object> blockBreakHiderGenerator(Class<?> blockBreakPacket) {
return null;
}
private static final Reflection.ConstructorInvoker playerInfoDataConstructor = Reflection.getConstructor(Fight.playerInfoDataClass, Fight.playerInfoPacket, GameProfile.class, int.class, Fight.enumGamemode, Fight.iChatBaseComponent);
@Override
public Object playerInfoDataConstructor(Object packet, GameProfile profile, Object mode) {
return playerInfoDataConstructor.invoke(packet, profile, 0, mode, null);
}
private static final Reflection.MethodInvoker getBlockByBlockData = Reflection.getTypedMethod(TechHider.iBlockData, null, TechHider.block);
private static final Reflection.MethodInvoker getMaterialByBlock = Reflection.getTypedMethod(TechHider.craftMagicNumbers, "getMaterial", Material.class, TechHider.block);
@Override
public boolean iBlockDataHidden(Object iBlockData) {
return Config.HiddenBlocks.contains(((Material) getMaterialByBlock.invoke(null, getBlockByBlockData.invoke(iBlockData))).name().toLowerCase());
}
}

Datei anzeigen

@ -19,13 +19,19 @@
package de.steamwar.fightsystem.utils; package de.steamwar.fightsystem.utils;
import java.util.function.BiFunction; import com.comphenix.tinyprotocol.Reflection;
import org.bukkit.entity.Player;
public class TechHider8 implements BiFunction<byte[], Integer, byte[]> { public class TechHider8 implements TechHider.ChunkHider {
protected static final Class<?> mapChunkPacket = Reflection.getClass("{nms}.PacketPlayOutMapChunk");
@Override
public Class<?> mapChunkPacket() {
return mapChunkPacket;
}
@Override @Override
public byte[] apply(byte[] data, Integer primaryBitMask) { public Object mapChunkHider(Player p, Object packet) {
// No implementation availible return packet;
return data;
} }
} }

Datei anzeigen

@ -23,6 +23,11 @@
<artifactId>FightSystem_Core</artifactId> <artifactId>FightSystem_Core</artifactId>
<version>1.0</version> <version>1.0</version>
</dependency> </dependency>
<dependency>
<groupId>steamwar</groupId>
<artifactId>FightSystem_8</artifactId>
<version>1.0</version>
</dependency>
<dependency> <dependency>
<groupId>steamwar</groupId> <groupId>steamwar</groupId>
<artifactId>WorldEdit</artifactId> <artifactId>WorldEdit</artifactId>

Datei anzeigen

@ -46,7 +46,7 @@ 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 Class<?> enumHand = Reflection.getClass("{nms.world}.EnumHand");
private static final Object mainHand = enumHand.getEnumConstants()[0]; private static final Object mainHand = enumHand.getEnumConstants()[0];
private static final Reflection.FieldAccessor<?> blockPlaceHand = Reflection.getField(Recording.blockPlacePacket, enumHand, 0); private static final Reflection.FieldAccessor<?> blockPlaceHand = Reflection.getField(Recording.blockPlacePacket, enumHand, 0);
@ -118,9 +118,9 @@ public class BountifulWrapper9 implements BountifulWrapper.IBountifulWrapper {
} }
private static final Class<?> dataWatcherObject = Reflection.getClass("{nms}.DataWatcherObject"); private static final Class<?> dataWatcherObject = Reflection.getClass("{nms.network.syncher}.DataWatcherObject");
private static final Class<?> dataWatcherRegistry = Reflection.getClass("{nms}.DataWatcherRegistry"); private static final Class<?> dataWatcherRegistry = Reflection.getClass("{nms.network.syncher}.DataWatcherRegistry");
private static final Class<?> dataWatcherSerializer = Reflection.getClass("{nms}.DataWatcherSerializer"); private static final Class<?> dataWatcherSerializer = Reflection.getClass("{nms.network.syncher}.DataWatcherSerializer");
private static final Reflection.ConstructorInvoker dataWatcherObjectConstructor = Reflection.getConstructor(dataWatcherObject, int.class, dataWatcherSerializer); private static final Reflection.ConstructorInvoker dataWatcherObjectConstructor = Reflection.getConstructor(dataWatcherObject, int.class, dataWatcherSerializer);
@Override @Override
public Object getDataWatcherObject(int index, Class<?> type) { public Object getDataWatcherObject(int index, Class<?> type) {
@ -136,7 +136,7 @@ public class BountifulWrapper9 implements BountifulWrapper.IBountifulWrapper {
throw new SecurityException("Could not find Serializer for " + type.getName()); throw new SecurityException("Could not find Serializer for " + type.getName());
} }
private static final Class<?> item = Reflection.getClass("{nms}.DataWatcher$Item"); private static final Class<?> item = Reflection.getClass("{nms.network.syncher}.DataWatcher$Item");
private static final Reflection.ConstructorInvoker itemConstructor = Reflection.getConstructor(item, dataWatcherObject, Object.class); private static final Reflection.ConstructorInvoker itemConstructor = Reflection.getConstructor(item, dataWatcherObject, Object.class);
@Override @Override
public Object getDataWatcherItem(Object dwo, Object value) { public Object getDataWatcherItem(Object dwo, Object value) {
@ -159,32 +159,6 @@ public class BountifulWrapper9 implements BountifulWrapper.IBountifulWrapper {
spawnUUID.set(packet, 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]);
}
}
private final Map<Player, BossBar> barMap = new HashMap<>(); private final Map<Player, BossBar> barMap = new HashMap<>();
@Override @Override

Datei anzeigen

@ -19,21 +19,52 @@
package de.steamwar.fightsystem.utils; package de.steamwar.fightsystem.utils;
import com.comphenix.tinyprotocol.Reflection;
import de.steamwar.fightsystem.Config;
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.function.UnaryOperator;
import java.util.logging.Level; import java.util.logging.Level;
import java.util.stream.Collectors;
public class TechHider9 implements BiFunction<byte[], Integer, byte[]> { public class TechHider9 extends TechHider8 {
private final Set<Integer> hiddenBlockIds = BlockIdWrapper.impl.getHiddenBlockIds(); private static final UnaryOperator<Object> mapChunkCloner = ProtocolAPI.shallowCloneGenerator(mapChunkPacket);
private final int obfuscateWith = BlockIdWrapper.impl.getObfuscateWith();
private static final Reflection.FieldAccessor<Integer> mapChunkX = Reflection.getField(mapChunkPacket, int.class, 0);
private static final Reflection.FieldAccessor<Integer> mapChunkZ = Reflection.getField(mapChunkPacket, int.class, 1);
private static final Reflection.FieldAccessor<Integer> mapChunkBitMask = Reflection.getField(mapChunkPacket, int.class, 2);
private static final Reflection.FieldAccessor<List> mapChunkBlockEntities = Reflection.getField(mapChunkPacket, List.class, 0);
private static final Reflection.FieldAccessor<byte[]> mapChunkData = Reflection.getField(mapChunkPacket, byte[].class, 0);
private static final Class<?> nbtTagCompound = Reflection.getClass("{nms.nbt}.NBTTagCompound");
private static final Reflection.MethodInvoker nbtTagGetString = Reflection.getTypedMethod(nbtTagCompound, null, String.class, String.class);
protected final Set<Integer> hiddenBlockIds = BlockIdWrapper.impl.getHiddenBlockIds();
protected final int obfuscateWith = BlockIdWrapper.impl.getObfuscateWith();
@Override @Override
public byte[] apply(byte[] data, Integer primaryBitMask) { public Object mapChunkHider(Player p, Object packet) {
if(TechHider.bypass(p, mapChunkX.get(packet), mapChunkZ.get(packet)))
return packet;
packet = mapChunkCloner.apply(packet);
mapChunkBlockEntities.set(packet, ((List<?>)mapChunkBlockEntities.get(packet)).stream().filter(
nbttag -> Config.HiddenBlockEntities.contains((String) nbtTagGetString.invoke(nbttag, "id"))
).collect(Collectors.toList()));
byte[] data = dataHider(mapChunkData.get(packet), mapChunkBitMask.get(packet));
mapChunkData.set(packet, data);
return packet;
}
protected byte[] dataHider(byte[] data, Integer primaryBitMask) {
ByteBuf buffer = UnpooledByteBufAllocator.DEFAULT.directBuffer(data.length + 100); ByteBuf buffer = UnpooledByteBufAllocator.DEFAULT.directBuffer(data.length + 100);
int i = 0; int i = 0;

Datei anzeigen

@ -19,11 +19,28 @@
<dependencies> <dependencies>
<dependency> <dependency>
<groupId>steamwar</groupId> <groupId>org.spigotmc</groupId>
<artifactId>Spigot</artifactId> <artifactId>spigot-api</artifactId>
<version>1.15</version> <version>1.18-R0.1-SNAPSHOT</version>
<scope>system</scope> <scope>provided</scope>
<systemPath>${main.basedir}/lib/Spigot-1.15.jar</systemPath> </dependency>
<dependency>
<groupId>it.unimi.dsi</groupId>
<artifactId>fastutil</artifactId>
<version>8.5.6</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>io.netty</groupId>
<artifactId>netty-all</artifactId>
<version>4.1.68.Final</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>com.mojang</groupId>
<artifactId>authlib</artifactId>
<version>1.5.25</version>
<scope>provided</scope>
</dependency> </dependency>
<dependency> <dependency>
<groupId>steamwar</groupId> <groupId>steamwar</groupId>

Datei anzeigen

@ -27,6 +27,8 @@ 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 de.steamwar.fightsystem.utils.ProtocolWrapper;
import org.bukkit.Bukkit; import org.bukkit.Bukkit;
import org.bukkit.GameMode; import org.bukkit.GameMode;
import org.bukkit.Sound; import org.bukkit.Sound;
@ -130,29 +132,27 @@ public class Fight {
} }
} }
private static final Class<?> playerInfoPacket = Reflection.getClass("{nms}.PacketPlayOutPlayerInfo"); public static final Class<?> playerInfoPacket = Reflection.getClass("{nms.network.protocol.game}.PacketPlayOutPlayerInfo");
private static final Reflection.ConstructorInvoker playerInfoConstructor = Reflection.getConstructor(playerInfoPacket); private static final Class<?> playerInfoActionClass = Reflection.getClass("{nms.network.protocol.game}.PacketPlayOutPlayerInfo$EnumPlayerInfoAction");
private static final Class<?> playerInfoActionClass = Reflection.getClass("{nms}.PacketPlayOutPlayerInfo$EnumPlayerInfoAction");
public static final Object addPlayer = playerInfoActionClass.getEnumConstants()[0]; public static final Object addPlayer = playerInfoActionClass.getEnumConstants()[0];
private static final Reflection.FieldAccessor<?> playerInfoAction = Reflection.getField(playerInfoPacket, playerInfoActionClass, 0); private static final Reflection.FieldAccessor<?> playerInfoAction = Reflection.getField(playerInfoPacket, playerInfoActionClass, 0);
private static final Object updateGamemode = playerInfoActionClass.getEnumConstants()[1]; private static final Object updateGamemode = playerInfoActionClass.getEnumConstants()[1];
public static final Object removePlayer = playerInfoActionClass.getEnumConstants()[4]; public static final Object removePlayer = playerInfoActionClass.getEnumConstants()[4];
private static final Reflection.FieldAccessor<List> playerInfoData = Reflection.getField(playerInfoPacket, List.class, 0); private static final Reflection.FieldAccessor<List> playerInfoData = Reflection.getField(playerInfoPacket, List.class, 0);
private static final Class<?> playerInfoDataClass = Reflection.getClass("{nms}.PacketPlayOutPlayerInfo$PlayerInfoData"); public static final Class<?> playerInfoDataClass = Reflection.getClass("{nms.network.protocol.game}.PacketPlayOutPlayerInfo$PlayerInfoData");
private static final Class<?> enumGamemode = Reflection.getClass(Core.getVersion() > 9 ? "{nms}.EnumGamemode" : "{nms}.WorldSettings$EnumGamemode"); public static final Class<?> enumGamemode = Reflection.getClass(Core.getVersion() > 9 ? "{nms.world.level}.EnumGamemode" : "{nms}.WorldSettings$EnumGamemode");
public static final Object creative = enumGamemode.getEnumConstants()[2]; public static final Object creative = enumGamemode.getEnumConstants()[Core.getVersion() > 15 ? 1 : 2];
private static final Object spectator = enumGamemode.getEnumConstants()[4]; private static final Object spectator = enumGamemode.getEnumConstants()[Core.getVersion() > 15 ? 3 : 4];
private static final Class<?> iChatBaseComponent = Reflection.getClass("{nms}.IChatBaseComponent"); public static final Class<?> iChatBaseComponent = Reflection.getClass("{nms.network.chat}.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) {
TinyProtocol.instance.sendPacket(player, playerInfoPacket(updateGamemode, new GameProfile(player.getUniqueId(), player.getName()), enable ? creative : spectator)); TinyProtocol.instance.sendPacket(player, playerInfoPacket(updateGamemode, new GameProfile(player.getUniqueId(), player.getName()), enable ? creative : spectator));
} }
public static Object playerInfoPacket(Object action, GameProfile profile, Object mode) { public static Object playerInfoPacket(Object action, GameProfile profile, Object mode) {
Object packet = playerInfoConstructor.invoke(); Object packet = ProtocolAPI.construct(playerInfoPacket);
playerInfoAction.set(packet, action); playerInfoAction.set(packet, action);
playerInfoData.set(packet, Collections.singletonList(playerInfoDataConstructor.invoke(packet, profile, 0, mode, null))); playerInfoData.set(packet, Collections.singletonList(ProtocolWrapper.impl.playerInfoDataConstructor(packet, profile, mode)));
return packet; return packet;
} }

Datei anzeigen

@ -115,7 +115,7 @@ public class Recording implements Listener {
}, 1, 1); }, 1, 1);
} }
private static final Class<?> blockDigPacket = Reflection.getClass("{nms}.PacketPlayInBlockDig"); private static final Class<?> blockDigPacket = Reflection.getClass("{nms.network.protocol.game}.PacketPlayInBlockDig");
private static final Class<?> playerDigType = blockDigPacket.getDeclaredClasses()[0]; private static final Class<?> playerDigType = blockDigPacket.getDeclaredClasses()[0];
private static final Reflection.FieldAccessor<?> blockDigType = Reflection.getField(blockDigPacket, playerDigType, 0); private static final Reflection.FieldAccessor<?> blockDigType = Reflection.getField(blockDigPacket, playerDigType, 0);
private static final Object releaseUseItem = playerDigType.getEnumConstants()[5]; private static final Object releaseUseItem = playerDigType.getEnumConstants()[5];
@ -125,7 +125,7 @@ public class Recording implements Listener {
return packet; return packet;
} }
public static final Class<?> blockPlacePacket = Reflection.getClass("{nms}.PacketPlayInBlockPlace"); public static final Class<?> blockPlacePacket = Reflection.getClass("{nms.network.protocol.game}.PacketPlayInBlockPlace");
private Object blockPlace(Player p, Object packet) { private Object blockPlace(Player p, Object packet) {
boolean mainHand = BountifulWrapper.impl.mainHand(packet); boolean mainHand = BountifulWrapper.impl.mainHand(packet);
if(BountifulWrapper.impl.bowInHand(mainHand, p)) if(BountifulWrapper.impl.bowInHand(mainHand, p))

Datei anzeigen

@ -26,11 +26,10 @@ import de.steamwar.core.Core;
import de.steamwar.fightsystem.FightSystem; import de.steamwar.fightsystem.FightSystem;
import de.steamwar.fightsystem.fight.Fight; 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.*;
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 it.unimi.dsi.fastutil.ints.IntArrayList;
import it.unimi.dsi.fastutil.ints.IntList;
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;
@ -174,25 +173,23 @@ public class REntity {
ProtocolAPI.broadcastPacket(getHeadRotationPacket()); ProtocolAPI.broadcastPacket(getHeadRotationPacket());
} }
private static final Class<?> animationPacket = Reflection.getClass("{nms}.PacketPlayOutAnimation"); private static final Class<?> animationPacket = Reflection.getClass("{nms.network.protocol.game}.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> animationEntity = Reflection.getField(animationPacket, int.class, 0);
private static final Reflection.FieldAccessor<Integer> animationAnimation = Reflection.getField(animationPacket, int.class, 1); private static final Reflection.FieldAccessor<Integer> animationAnimation = Reflection.getField(animationPacket, int.class, 1);
public void animation(byte animation) { public void animation(byte animation) {
Object packet = animationConstructor.invoke(); Object packet = ProtocolAPI.construct(animationPacket);
animationEntity.set(packet, entityId); animationEntity.set(packet, entityId);
animationAnimation.set(packet, (int) animation); animationAnimation.set(packet, (int) animation);
ProtocolAPI.broadcastPacket(packet); ProtocolAPI.broadcastPacket(packet);
} }
private static final Class<?> velocityPacket = Reflection.getClass("{nms}.PacketPlayOutEntityVelocity"); private static final Class<?> velocityPacket = Reflection.getClass("{nms.network.protocol.game}.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> 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> 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> velocityY = Reflection.getField(velocityPacket, int.class, 2);
private static final Reflection.FieldAccessor<Integer> velocityZ = Reflection.getField(velocityPacket, int.class, 3); 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) {
Object packet = velocityConstructor.invoke(); Object packet = ProtocolAPI.construct(velocityPacket);
velocityEntity.set(packet, entityId); velocityEntity.set(packet, entityId);
velocityX.set(packet, calcVelocity(dX)); velocityX.set(packet, calcVelocity(dX));
velocityY.set(packet, calcVelocity(dY)); velocityY.set(packet, calcVelocity(dY));
@ -200,12 +197,11 @@ public class REntity {
ProtocolAPI.broadcastPacket(packet); ProtocolAPI.broadcastPacket(packet);
} }
private static final Class<?> statusPacket = Reflection.getClass("{nms}.PacketPlayOutEntityStatus"); private static final Class<?> statusPacket = Reflection.getClass("{nms.network.protocol.game}.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<Integer> statusEntity = Reflection.getField(statusPacket, int.class, 0);
private static final Reflection.FieldAccessor<Byte> statusStatus = Reflection.getField(statusPacket, byte.class, 0); private static final Reflection.FieldAccessor<Byte> statusStatus = Reflection.getField(statusPacket, byte.class, 0);
public void damage() { public void damage() {
Object packet = statusConstructor.invoke(); Object packet = ProtocolAPI.construct(statusPacket);
statusEntity.set(packet, entityId); statusEntity.set(packet, entityId);
statusStatus.set(packet, (byte) 2); statusStatus.set(packet, (byte) 2);
ProtocolAPI.broadcastPacket(packet); ProtocolAPI.broadcastPacket(packet);
@ -248,17 +244,23 @@ public class REntity {
entities.remove(internalId); entities.remove(internalId);
} }
private static final Class<?> destroyPacket = Reflection.getClass("{nms}.PacketPlayOutEntityDestroy"); private static final Class<?> destroyPacket = Reflection.getClass("{nms.network.protocol.game}.PacketPlayOutEntityDestroy");
private static final Reflection.ConstructorInvoker destroyConstructor = Reflection.getConstructor(destroyPacket); private static final Reflection.FieldAccessor<?> destroyEntities;
private static final Reflection.FieldAccessor<int[]> destroyEntities = Reflection.getField(destroyPacket, int[].class, 0); static {
if(Core.getVersion() > 15)
destroyEntities = Reflection.getField(destroyPacket, IntList.class, 0);
else
destroyEntities = Reflection.getField(destroyPacket, int[].class, 0);
}
private void broadcastDeath(){ private void broadcastDeath(){
if(entityType == EntityType.PLAYER){ if(entityType == EntityType.PLAYER){
ProtocolAPI.broadcastPacket(Fight.playerInfoPacket(Fight.removePlayer, new GameProfile(uuid, name), Fight.creative)); ProtocolAPI.broadcastPacket(Fight.playerInfoPacket(Fight.removePlayer, new GameProfile(uuid, name), Fight.creative));
team.removeEntry(name); team.removeEntry(name);
} }
Object packet = destroyConstructor.invoke(); Object packet = ProtocolAPI.construct(destroyPacket);
destroyEntities.set(packet, new int[]{entityId}); destroyEntities.set(packet, Core.getVersion() > 15 ? new IntArrayList(new int[]{entityId}) : new int[]{entityId});
ProtocolAPI.broadcastPacket(packet); ProtocolAPI.broadcastPacket(packet);
} }
@ -266,24 +268,22 @@ public class REntity {
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 static final Class<?> metadataPacket = Reflection.getClass("{nms}.PacketPlayOutEntityMetadata"); private static final Class<?> metadataPacket = Reflection.getClass("{nms.network.protocol.game}.PacketPlayOutEntityMetadata");
private static final Reflection.ConstructorInvoker metadataConstructor = Reflection.getConstructor(metadataPacket);
private static final Reflection.FieldAccessor<Integer> metadataEntity = Reflection.getField(metadataPacket, int.class, 0); private static final Reflection.FieldAccessor<Integer> metadataEntity = Reflection.getField(metadataPacket, int.class, 0);
private static final Reflection.FieldAccessor<List> metadataMetadata = Reflection.getField(metadataPacket, List.class, 0); private static final Reflection.FieldAccessor<List> metadataMetadata = Reflection.getField(metadataPacket, List.class, 0);
private Object getDataWatcherPacket(Object dataWatcherObject, Object value) { private Object getDataWatcherPacket(Object dataWatcherObject, Object value) {
Object packet = metadataConstructor.invoke(); Object packet = ProtocolAPI.construct(metadataPacket);
metadataEntity.set(packet, entityId); metadataEntity.set(packet, entityId);
metadataMetadata.set(packet, Collections.singletonList(BountifulWrapper.impl.getDataWatcherItem(dataWatcherObject, value))); metadataMetadata.set(packet, Collections.singletonList(BountifulWrapper.impl.getDataWatcherItem(dataWatcherObject, value)));
return packet; return packet;
} }
public static final Class<?> teleportPacket = Reflection.getClass("{nms}.PacketPlayOutEntityTeleport"); public static final Class<?> teleportPacket = Reflection.getClass("{nms.network.protocol.game}.PacketPlayOutEntityTeleport");
private static final Reflection.ConstructorInvoker teleportConstructor = Reflection.getConstructor(teleportPacket);
private static final Reflection.FieldAccessor<Integer> teleportEntity = Reflection.getField(teleportPacket, int.class, 0); private static final Reflection.FieldAccessor<Integer> teleportEntity = Reflection.getField(teleportPacket, int.class, 0);
private static final Reflection.FieldAccessor<Byte> teleportYaw = Reflection.getField(teleportPacket, byte.class, 0); 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 static final Reflection.FieldAccessor<Byte> teleportPitch = Reflection.getField(teleportPacket, byte.class, 1);
private Object getTeleportPacket(){ private Object getTeleportPacket(){
Object packet = teleportConstructor.invoke(); Object packet = ProtocolAPI.construct(teleportPacket);
teleportEntity.set(packet, entityId); teleportEntity.set(packet, entityId);
BountifulWrapper.impl.setTeleportPacketPosition(packet, locX, locY, locZ); BountifulWrapper.impl.setTeleportPacketPosition(packet, locX, locY, locZ);
teleportYaw.set(packet, yaw); teleportYaw.set(packet, yaw);
@ -291,40 +291,36 @@ public class REntity {
return packet; return packet;
} }
private static final Class<?> headRotationPacket = Reflection.getClass("{nms}.PacketPlayOutEntityHeadRotation"); private static final Class<?> headRotationPacket = Reflection.getClass("{nms.network.protocol.game}.PacketPlayOutEntityHeadRotation");
private static final Reflection.ConstructorInvoker headRotationConstructor = Reflection.getConstructor(headRotationPacket);
private static final Reflection.FieldAccessor<Integer> headRotationEntity = Reflection.getField(headRotationPacket, int.class, 0); private static final Reflection.FieldAccessor<Integer> headRotationEntity = Reflection.getField(headRotationPacket, int.class, 0);
private static final Reflection.FieldAccessor<Byte> headRotationYaw = Reflection.getField(headRotationPacket, byte.class, 0); private static final Reflection.FieldAccessor<Byte> headRotationYaw = Reflection.getField(headRotationPacket, byte.class, 0);
private Object getHeadRotationPacket(){ private Object getHeadRotationPacket(){
Object packet = headRotationConstructor.invoke(); Object packet = ProtocolAPI.construct(headRotationPacket);
headRotationEntity.set(packet, entityId); headRotationEntity.set(packet, entityId);
headRotationYaw.set(packet, headYaw); headRotationYaw.set(packet, headYaw);
return packet; return packet;
} }
public static final Class<?> spawnPacket = Reflection.getClass("{nms}.PacketPlayOutSpawnEntity"); public static final Class<?> spawnPacket = Reflection.getClass("{nms.network.protocol.game}.PacketPlayOutSpawnEntity");
private static final Reflection.ConstructorInvoker spawnConstructor = Reflection.getConstructor(spawnPacket);
private static final Reflection.FieldAccessor<Integer> spawnEntity = Reflection.getField(spawnPacket, int.class, 0); private static final Reflection.FieldAccessor<Integer> spawnEntity = Reflection.getField(spawnPacket, int.class, 0);
private Object getSpawnEntityPacket(){ private Object getSpawnEntityPacket(){
Object packet = spawnConstructor.invoke(); Object packet = ProtocolAPI.construct(spawnPacket);
spawnEntity.set(packet, entityId); spawnEntity.set(packet, entityId);
BountifulWrapper.impl.setSpawnPacketUUID(packet, uuid); BountifulWrapper.impl.setSpawnPacketUUID(packet, uuid);
FlatteningWrapper.impl.setSpawnPacketType(packet, entityType); ProtocolWrapper.impl.setSpawnPacketType(packet, entityType);
return packet; return packet;
} }
public static final Class<?> equipmentPacket = Reflection.getClass("{nms}.PacketPlayOutEntityEquipment"); public static final Class<?> equipmentPacket = Reflection.getClass("{nms.network.protocol.game}.PacketPlayOutEntityEquipment");
private static final Reflection.ConstructorInvoker equipmentConstructor = Reflection.getConstructor(equipmentPacket);
private static final Reflection.FieldAccessor<Integer> equipmentEntity = Reflection.getField(equipmentPacket, int.class, 0); private static final Reflection.FieldAccessor<Integer> equipmentEntity = Reflection.getField(equipmentPacket, int.class, 0);
private static final Class<?> itemStack = Reflection.getClass("{nms}.ItemStack");
private static final Reflection.FieldAccessor<?> equipmentStack = Reflection.getField(equipmentPacket, itemStack, 0); public static final Class<?> itemStack = Reflection.getClass("{nms.world.item}.ItemStack");
private static final Class<?> craftItemStack = Reflection.getClass("{obc}.inventory.CraftItemStack"); private static final Class<?> craftItemStack = Reflection.getClass("{obc}.inventory.CraftItemStack");
private static final Reflection.MethodInvoker asNMSCopy = Reflection.getTypedMethod(craftItemStack, "asNMSCopy", itemStack, ItemStack.class); private static final Reflection.MethodInvoker asNMSCopy = Reflection.getTypedMethod(REntity.craftItemStack, "asNMSCopy", REntity.itemStack, ItemStack.class);
private Object getEquipmentPacket(String slot, ItemStack stack){ private Object getEquipmentPacket(String slot, ItemStack stack){
Object packet = equipmentConstructor.invoke(); Object packet = ProtocolAPI.construct(equipmentPacket);
equipmentEntity.set(packet, entityId); equipmentEntity.set(packet, entityId);
BountifulWrapper.impl.setEquipmentPacketSlot(packet, slot); ProtocolWrapper.impl.setEquipmentPacketStack(packet, slot, asNMSCopy.invoke(null, stack));
equipmentStack.set(packet, asNMSCopy.invoke(null, stack));
return packet; return packet;
} }
@ -332,12 +328,11 @@ public class REntity {
return Fight.playerInfoPacket(Fight.addPlayer, new GameProfile(uuid, name), Fight.creative); return Fight.playerInfoPacket(Fight.addPlayer, new GameProfile(uuid, name), Fight.creative);
} }
public static final Class<?> namedSpawnPacket = Reflection.getClass("{nms}.PacketPlayOutNamedEntitySpawn"); public static final Class<?> namedSpawnPacket = Reflection.getClass("{nms.network.protocol.game}.PacketPlayOutNamedEntitySpawn");
private static final Reflection.ConstructorInvoker namedSpawnConstructor = Reflection.getConstructor(namedSpawnPacket);
private static final Reflection.FieldAccessor<Integer> namedSpawnEntity = Reflection.getField(namedSpawnPacket, int.class, 0); private static final Reflection.FieldAccessor<Integer> namedSpawnEntity = Reflection.getField(namedSpawnPacket, int.class, 0);
private static final Reflection.FieldAccessor<UUID> namedSpawnUUID = Reflection.getField(namedSpawnPacket, UUID.class, 0); private static final Reflection.FieldAccessor<UUID> namedSpawnUUID = Reflection.getField(namedSpawnPacket, UUID.class, 0);
private Object getNamedSpawnPacket(){ private Object getNamedSpawnPacket(){
Object packet = namedSpawnConstructor.invoke(); Object packet = ProtocolAPI.construct(namedSpawnPacket);
namedSpawnEntity.set(packet, entityId); namedSpawnEntity.set(packet, entityId);
namedSpawnUUID.set(packet, uuid); namedSpawnUUID.set(packet, uuid);
FlatteningWrapper.impl.setNamedSpawnPacketDataWatcher(packet); FlatteningWrapper.impl.setNamedSpawnPacketDataWatcher(packet);

Datei anzeigen

@ -54,7 +54,6 @@ public class BountifulWrapper {
Object getDataWatcherItem(Object dataWatcherObject, Object value); Object getDataWatcherItem(Object dataWatcherObject, Object value);
void setTeleportPacketPosition(Object packet, double x, double y, double z); void setTeleportPacketPosition(Object packet, double x, double y, double z);
void setSpawnPacketUUID(Object packet, UUID uuid); void setSpawnPacketUUID(Object packet, UUID uuid);
void setEquipmentPacketSlot(Object packet, String slot);
void sendBar(Player player, FightTeam team, double progress, String text); void sendBar(Player player, FightTeam team, double progress, String text);
} }

Datei anzeigen

@ -24,7 +24,6 @@ import de.steamwar.fightsystem.FightSystem;
import org.bukkit.DyeColor; import org.bukkit.DyeColor;
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;
@ -52,6 +51,5 @@ public class FlatteningWrapper {
boolean checkPistonMoving(Block block); boolean checkPistonMoving(Block block);
void setNamedSpawnPacketDataWatcher(Object packet); void setNamedSpawnPacketDataWatcher(Object packet);
void setSpawnPacketType(Object packet, EntityType type);
} }
} }

Datei anzeigen

@ -20,6 +20,7 @@
package de.steamwar.fightsystem.utils; package de.steamwar.fightsystem.utils;
import com.comphenix.tinyprotocol.TinyProtocol; import com.comphenix.tinyprotocol.TinyProtocol;
import jdk.internal.misc.Unsafe;
import org.bukkit.Bukkit; import org.bukkit.Bukkit;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
@ -87,16 +88,19 @@ public class ProtocolAPI {
}; };
} }
public static <T> T construct(Class<T> clazz) {
try {
return (T) Unsafe.getUnsafe().allocateInstance(clazz);
} catch (InstantiationException e) {
throw new IllegalStateException(e);
}
}
public static UnaryOperator<Object> shallowCloneGenerator(Class<?> clazz) { public static UnaryOperator<Object> shallowCloneGenerator(Class<?> clazz) {
BiConsumer<Object, Object> filler = shallowFill(clazz); BiConsumer<Object, Object> filler = shallowFill(clazz);
return source -> { return source -> {
Object clone; Object clone = construct(clazz);
try {
clone = clazz.newInstance();
} catch (InstantiationException | IllegalAccessException e) {
throw new IllegalStateException("Could not clone " + clazz.getName(), e);
}
filler.accept(source, clone); filler.accept(source, clone);
return clone; return clone;
}; };

Datei anzeigen

@ -0,0 +1,46 @@
/*
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.mojang.authlib.GameProfile;
import de.steamwar.core.VersionDependent;
import de.steamwar.fightsystem.FightSystem;
import org.bukkit.entity.EntityType;
import org.bukkit.entity.Player;
import java.util.function.BiFunction;
public interface ProtocolWrapper {
ProtocolWrapper impl = VersionDependent.getVersionImpl(FightSystem.getPlugin());
void setEquipmentPacketStack(Object packet, String slot, Object stack);
void setSpawnPacketType(Object packet, EntityType type);
Object multiBlockChangeHider(Player p, Object packet);
boolean unfilteredTileEntityDataAction(Object packet);
BiFunction<Player, Object, Object> blockBreakHiderGenerator(Class<?> blockBreakPacket);
Object playerInfoDataConstructor(Object packet, GameProfile profile, Object mode);
boolean iBlockDataHidden(Object iBlockData);
}

Datei anzeigen

@ -39,51 +39,51 @@ import java.util.*;
import java.util.function.BiFunction; import java.util.function.BiFunction;
import java.util.function.Function; import java.util.function.Function;
import java.util.function.UnaryOperator; 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"); public static final Class<?> blockPosition = Reflection.getClass("{nms.core}.BlockPosition");
private static final Class<?> baseBlockPosition = Reflection.getClass("{nms}.BaseBlockPosition"); private static final Class<?> baseBlockPosition = Reflection.getClass("{nms.core}.BaseBlockPosition");
private static final Reflection.FieldAccessor<Integer> blockPositionX = Reflection.getField(baseBlockPosition, int.class, 0); public 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); public static final Reflection.FieldAccessor<Integer> blockPositionZ = Reflection.getField(baseBlockPosition, int.class, 2);
private static final Class<?> iBlockData = Reflection.getClass("{nms}.IBlockData"); public static final Class<?> iBlockData = Reflection.getClass("{nms.world.level.block.state}.IBlockData");
private static final Class<?> block = Reflection.getClass("{nms}.Block"); public static final Class<?> block = Reflection.getClass("{nms.world.level.block}.Block");
private static final Reflection.MethodInvoker getBlockByBlockData = Reflection.getTypedMethod(iBlockData, "getBlock", block); private static final Reflection.MethodInvoker getBlockDataByBlock = Reflection.getTypedMethod(block, null, iBlockData);
private static final Reflection.MethodInvoker getBlockDataByBlock = Reflection.getTypedMethod(block, "getBlockData", iBlockData);
private static final Class<?> craftMagicNumbers = Reflection.getClass("{obc}.util.CraftMagicNumbers"); public 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); 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 Object obfuscateIBlockData = getBlockDataByBlock.invoke(getBlockByMaterial.invoke(null, Material.getMaterial(Config.ObfuscateWith.toUpperCase()))); public static final Object obfuscateIBlockData = getBlockDataByBlock.invoke(getBlockByMaterial.invoke(null, Material.getMaterial(Config.ObfuscateWith.toUpperCase())));
private final Map<Class<?>, BiFunction<Player, Object, Object>> techhiders = new HashMap<>(); private final Map<Class<?>, BiFunction<Player, Object, Object>> techhiders = new HashMap<>();
private final BiFunction<byte[], Integer, byte[]> chunkDataHider;
public interface ChunkHider {
Class<?> mapChunkPacket();
Object mapChunkHider(Player p, Object packet);
}
public TechHider(){ public TechHider(){
super(ENABLED, FightState.Schem); super(ENABLED, FightState.Schem);
chunkDataHider = VersionDependent.getVersionImpl(FightSystem.getPlugin());
techhiders.put(blockActionPacket, this::blockActionHider); techhiders.put(blockActionPacket, this::blockActionHider);
techhiders.put(blockChangePacket, this::blockChangeHider); techhiders.put(blockChangePacket, this::blockChangeHider);
techhiders.put(tileEntityDataPacket, this::tileEntityDataHider); techhiders.put(tileEntityDataPacket, this::tileEntityDataHider);
techhiders.put(multiBlockChangePacket, this::multiBlockChangeHider); techhiders.put(multiBlockChangePacket, ProtocolWrapper.impl::multiBlockChangeHider);
if(Core.getVersion() > 8) {
techhiders.put(mapChunkPacket, this::mapChunkHider); ChunkHider chunkHider = VersionDependent.getVersionImpl(FightSystem.getPlugin());
} techhiders.put(chunkHider.mapChunkPacket(), chunkHider::mapChunkHider);
if(Core.getVersion() > 12) { if(Core.getVersion() > 12) {
Class<?> blockBreakClass = Reflection.getClass("{nms}.PacketPlayOutBlockBreak"); Class<?> blockBreakClass = Reflection.getClass("{nms.network.protocol.game}.PacketPlayOutBlockBreak");
techhiders.put(blockBreakClass, blockBreakHiderGenerator(blockBreakClass)); techhiders.put(blockBreakClass, ProtocolWrapper.impl.blockBreakHiderGenerator(blockBreakClass));
} }
if(Core.getVersion() > 8){ if(Core.getVersion() > 8){
ProtocolAPI.setIncomingHandler(Reflection.getClass("{nms}.PacketPlayInUseItem"), (p, packet) -> p.getGameMode() == GameMode.SPECTATOR ? null : packet); ProtocolAPI.setIncomingHandler(Reflection.getClass("{nms.network.protocol.game}.PacketPlayInUseItem"), (p, packet) -> p.getGameMode() == GameMode.SPECTATOR ? null : packet);
} }
ProtocolAPI.setIncomingHandler(Reflection.getClass("{nms}.PacketPlayInUseEntity"), (p, packet) -> p.getGameMode() == GameMode.SPECTATOR ? null : packet); ProtocolAPI.setIncomingHandler(Reflection.getClass("{nms.network.protocol.game}.PacketPlayInUseEntity"), (p, packet) -> p.getGameMode() == GameMode.SPECTATOR ? null : packet);
register(); register();
} }
@ -98,70 +98,10 @@ public class TechHider extends StateDependent {
techhiders.keySet().forEach(ProtocolAPI::removeOutgoingHandler); techhiders.keySet().forEach(ProtocolAPI::removeOutgoingHandler);
} }
private static final Class<?> nbtTagCompound = Reflection.getClass("{nms}.NBTTagCompound"); public static final Class<?> multiBlockChangePacket = Reflection.getClass("{nms.network.protocol.game}.PacketPlayOutMultiBlockChange");
private static final Reflection.MethodInvoker nbtTagGetString = Reflection.getTypedMethod(nbtTagCompound, "getString", String.class, String.class); public static final UnaryOperator<Object> multiBlockChangeCloner = ProtocolAPI.shallowCloneGenerator(TechHider.multiBlockChangePacket);
private static final Class<?> mapChunkPacket = Reflection.getClass("{nms}.PacketPlayOutMapChunk"); private static final Class<?> blockChangePacket = Reflection.getClass("{nms.network.protocol.game}.PacketPlayOutBlockChange");
private static final UnaryOperator<Object> mapChunkCloner = ProtocolAPI.shallowCloneGenerator(mapChunkPacket);
private static final Reflection.FieldAccessor<Integer> mapChunkX = Reflection.getField(mapChunkPacket, int.class, 0);
private static final Reflection.FieldAccessor<Integer> mapChunkZ = Reflection.getField(mapChunkPacket, int.class, 1);
private static final Reflection.FieldAccessor<Integer> mapChunkBitMask;
private static final Reflection.FieldAccessor<List> mapChunkBlockEntities;
private static final Reflection.FieldAccessor<byte[]> mapChunkData;
static {
if(Core.getVersion() > 8) {
mapChunkBitMask = Reflection.getField(mapChunkPacket, int.class, 2);
mapChunkBlockEntities = Reflection.getField(mapChunkPacket, List.class, 0);
mapChunkData = Reflection.getField(mapChunkPacket, byte[].class, 0);
}else {
mapChunkBitMask = null;
mapChunkBlockEntities = null;
mapChunkData = null;
}
}
private Object mapChunkHider(Player p, Object packet) {
if(bypass(p, mapChunkX.get(packet), mapChunkZ.get(packet)))
return packet;
packet = mapChunkCloner.apply(packet);
mapChunkBlockEntities.set(packet, ((List<?>)mapChunkBlockEntities.get(packet)).stream().filter(
nbttag -> Config.HiddenBlockEntities.contains((String) nbtTagGetString.invoke(nbttag, "id"))
).collect(Collectors.toList()));
byte[] data = chunkDataHider.apply(mapChunkData.get(packet), mapChunkBitMask.get(packet));
mapChunkData.set(packet, data);
return packet;
}
private static final Class<?> multiBlockChangePacket = Reflection.getClass("{nms}.PacketPlayOutMultiBlockChange");
private static final UnaryOperator<Object> multiBlockChangeCloner = ProtocolAPI.shallowCloneGenerator(multiBlockChangePacket);
private static final Class<?> chunkCoordinateIntPair = Reflection.getClass("{nms}.ChunkCoordIntPair");
private static final Reflection.FieldAccessor<?> multiBlockChangeChunk = Reflection.getField(multiBlockChangePacket, chunkCoordinateIntPair, 0);
private static final Reflection.FieldAccessor<Integer> chunkCoordinateX = Reflection.getField(chunkCoordinateIntPair, int.class, 0);
private static final Reflection.FieldAccessor<Integer> chunkCoordinateZ = Reflection.getField(chunkCoordinateIntPair, int.class, 1);
private static final Class<?> multiBlockChangeInfo = Reflection.getClass("{nms}.PacketPlayOutMultiBlockChange$MultiBlockChangeInfo");
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 Function<Object, Object> blockChangeCloner = ProtocolAPI.shallowCloneGenerator(blockChangePacket);
private static final Reflection.FieldAccessor<?> blockChangePosition = Reflection.getField(blockChangePacket, blockPosition, 0); private static final Reflection.FieldAccessor<?> blockChangePosition = Reflection.getField(blockChangePacket, blockPosition, 0);
private static final Reflection.FieldAccessor<?> blockChangeBlockData = Reflection.getField(blockChangePacket, iBlockData, 0); private static final Reflection.FieldAccessor<?> blockChangeBlockData = Reflection.getField(blockChangePacket, iBlockData, 0);
@ -170,14 +110,14 @@ public class TechHider extends StateDependent {
if(bypass(p, posToChunk(blockPositionX.get(pos)), posToChunk(blockPositionZ.get(pos)))) if(bypass(p, posToChunk(blockPositionX.get(pos)), posToChunk(blockPositionZ.get(pos))))
return packet; return packet;
if(Config.HiddenBlocks.contains(getMaterialByIBlockData(blockChangeBlockData.get(packet)).name().toLowerCase())){ if(ProtocolWrapper.impl.iBlockDataHidden(blockChangeBlockData.get(packet))) {
packet = blockChangeCloner.apply(packet); packet = blockChangeCloner.apply(packet);
blockChangeBlockData.set(packet, obfuscateIBlockData); blockChangeBlockData.set(packet, obfuscateIBlockData);
} }
return packet; return packet;
} }
private static final Class<?> blockActionPacket = Reflection.getClass("{nms}.PacketPlayOutBlockAction"); private static final Class<?> blockActionPacket = Reflection.getClass("{nms.network.protocol.game}.PacketPlayOutBlockAction");
private static final Reflection.FieldAccessor<?> blockActionPosition = Reflection.getField(blockActionPacket, blockPosition, 0); private static final Reflection.FieldAccessor<?> blockActionPosition = Reflection.getField(blockActionPacket, blockPosition, 0);
private Object blockActionHider(Player p, Object packet) { private Object blockActionHider(Player p, Object packet) {
Object pos = blockActionPosition.get(packet); Object pos = blockActionPosition.get(packet);
@ -186,33 +126,14 @@ public class TechHider extends StateDependent {
return null; return null;
} }
private BiFunction<Player, Object, Object> blockBreakHiderGenerator(Class<?> blockBreakPacket){ public static final Class<?> tileEntityDataPacket = Reflection.getClass("{nms.network.protocol.game}.PacketPlayOutTileEntityData");
UnaryOperator<Object> blockBreakCloner = ProtocolAPI.shallowCloneGenerator(blockBreakPacket);
Reflection.FieldAccessor<?> blockBreakPosition = Reflection.getField(blockBreakPacket, blockPosition, 0);
Reflection.FieldAccessor<?> blockBreakBlockData = Reflection.getField(blockBreakPacket, iBlockData, 0);
return (p, packet) -> {
Object pos = blockBreakPosition.get(packet);
if(bypass(p, posToChunk(blockPositionX.get(pos)), posToChunk(blockPositionZ.get(pos))))
return packet;
if(Config.HiddenBlocks.contains(getMaterialByIBlockData(blockBreakBlockData.get(packet)).name().toLowerCase())){
packet = blockBreakCloner.apply(packet);
blockBreakBlockData.set(packet, obfuscateIBlockData);
}
return packet;
};
}
private static final Class<?> tileEntityDataPacket = Reflection.getClass("{nms}.PacketPlayOutTileEntityData");
private static final Reflection.FieldAccessor<?> tileEntityDataPosition = Reflection.getField(tileEntityDataPacket, blockPosition, 0); private static final Reflection.FieldAccessor<?> tileEntityDataPosition = Reflection.getField(tileEntityDataPacket, blockPosition, 0);
private static final Reflection.FieldAccessor<Integer> tileEntityDataAction = Reflection.getField(tileEntityDataPacket, int.class, 0);
private Object tileEntityDataHider(Player p, Object packet) { private Object tileEntityDataHider(Player p, Object packet) {
Object pos = tileEntityDataPosition.get(packet); Object pos = tileEntityDataPosition.get(packet);
if(bypass(p, posToChunk(blockPositionX.get(pos)), posToChunk(blockPositionZ.get(pos)))) if(bypass(p, posToChunk(blockPositionX.get(pos)), posToChunk(blockPositionZ.get(pos))))
return packet; return packet;
if(tileEntityDataAction.get(packet) != 9) if(ProtocolWrapper.impl.unfilteredTileEntityDataAction(packet))
return packet; return packet;
return null; return null;
} }
@ -239,7 +160,7 @@ public class TechHider extends StateDependent {
}, 40); }, 40);
} }
static boolean bypass(Player p, int chunkX, int chunkZ){ public static boolean bypass(Player p, int chunkX, int chunkZ){
if(p == FightSystem.getEventLeiter()) if(p == FightSystem.getEventLeiter())
return true; return true;
@ -253,11 +174,7 @@ public class TechHider extends StateDependent {
} }
} }
private static Material getMaterialByIBlockData(Object iBlockData) { public static int posToChunk(int c){
return (Material) getMaterialByBlock.invoke(null, getBlockByBlockData.invoke(iBlockData));
}
private static int posToChunk(int c){
int chunk = c / 16; int chunk = c / 16;
if(c<0) if(c<0)
chunk--; chunk--;

Datei anzeigen

@ -92,6 +92,12 @@
<version>1.0</version> <version>1.0</version>
<scope>compile</scope> <scope>compile</scope>
</dependency> </dependency>
<dependency>
<groupId>steamwar</groupId>
<artifactId>FightSystem_18</artifactId>
<version>1.0</version>
<scope>compile</scope>
</dependency>
<dependency> <dependency>
<groupId>steamwar</groupId> <groupId>steamwar</groupId>
<artifactId>FightSystem_Core</artifactId> <artifactId>FightSystem_Core</artifactId>

13
pom.xml
Datei anzeigen

@ -57,10 +57,23 @@
<module>FightSystem_12</module> <module>FightSystem_12</module>
<module>FightSystem_14</module> <module>FightSystem_14</module>
<module>FightSystem_15</module> <module>FightSystem_15</module>
<module>FightSystem_18</module>
<module>FightSystem_Core</module> <module>FightSystem_Core</module>
<module>FightSystem_Main</module> <module>FightSystem_Main</module>
</modules> </modules>
<repositories>
<repository>
<id>minecraft-libraries</id>
<name>Minecraft Libraries</name>
<url>https://libraries.minecraft.net</url>
</repository>
<repository>
<id>spigot-repo</id>
<url>https://hub.spigotmc.org/nexus/content/repositories/snapshots/</url>
</repository>
</repositories>
<dependencies> <dependencies>
<dependency> <dependency>
<groupId>steamwar</groupId> <groupId>steamwar</groupId>