CoreHider #357
@ -19,16 +19,13 @@
|
||||
|
||||
package de.steamwar.fightsystem.utils;
|
||||
|
||||
import de.steamwar.fightsystem.Config;
|
||||
import net.minecraft.server.v1_14_R1.*;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.block.Block;
|
||||
import org.bukkit.craftbukkit.v1_14_R1.CraftWorld;
|
||||
import org.bukkit.craftbukkit.v1_14_R1.block.CraftBlock;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.Objects;
|
||||
import java.util.Set;
|
||||
|
||||
public class BlockIdWrapper14 implements BlockIdWrapper {
|
||||
@Override
|
||||
@ -46,32 +43,6 @@ public class BlockIdWrapper14 implements BlockIdWrapper {
|
||||
cworld.getChunkProvider().flagDirty(pos);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<Integer> getHiddenBlockIds() {
|
||||
Set<Integer> hiddenBlockIds = new HashSet<>();
|
||||
for(String tag : Config.HiddenBlocks){
|
||||
for(IBlockData data : IRegistry.BLOCK.get(new MinecraftKey(tag)).getStates().a()){
|
||||
hiddenBlockIds.add(net.minecraft.server.v1_14_R1.Block.getCombinedId(data));
|
||||
}
|
||||
}
|
||||
|
||||
if(Config.HiddenBlocks.contains("water")){
|
||||
Fluid water = FluidTypes.WATER.a(false);
|
||||
for(IBlockData data : net.minecraft.server.v1_14_R1.Block.REGISTRY_ID){
|
||||
if(data.p() == water){
|
||||
hiddenBlockIds.add(net.minecraft.server.v1_14_R1.Block.getCombinedId(data));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return hiddenBlockIds;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getObfuscateWith() {
|
||||
return net.minecraft.server.v1_14_R1.Block.getCombinedId(IRegistry.BLOCK.get(new MinecraftKey(Config.ObfuscateWith)).getBlockData());
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getPose(boolean sneaking) {
|
||||
return sneaking ? EntityPose.SNEAKING : EntityPose.STANDING;
|
||||
|
52
FightSystem_14/src/de/steamwar/techhider/BlockIds14.java
Normale Datei
52
FightSystem_14/src/de/steamwar/techhider/BlockIds14.java
Normale Datei
@ -0,0 +1,52 @@
|
||||
/*
|
||||
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.techhider;
|
||||
|
||||
import net.minecraft.server.v1_14_R1.*;
|
||||
import org.bukkit.Material;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
|
||||
public class BlockIds14 implements BlockIds {
|
||||
@Override
|
||||
public int materialToId(Material material) {
|
||||
return Block.getCombinedId(IRegistry.BLOCK.get(new MinecraftKey(material.name().toLowerCase())).getBlockData());
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<Integer> materialToAllIds(Material material) {
|
||||
Set<Integer> ids = new HashSet<>();
|
||||
for(IBlockData data : IRegistry.BLOCK.get(new MinecraftKey(material.name().toLowerCase())).getStates().a()) {
|
||||
ids.add(Block.getCombinedId(data));
|
||||
}
|
||||
|
||||
if(material == Material.WATER){
|
||||
Fluid water = FluidTypes.WATER.a(false);
|
||||
for(IBlockData data : Block.REGISTRY_ID){
|
||||
if(data.p() == water){
|
||||
ids.add(Block.getCombinedId(data));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return ids;
|
||||
}
|
||||
}
|
@ -1,7 +1,7 @@
|
||||
/*
|
||||
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
|
||||
it under the terms of the GNU Affero General Public License as published by
|
||||
@ -17,18 +17,19 @@
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package de.steamwar.fightsystem.utils;
|
||||
package de.steamwar.techhider;
|
||||
|
||||
import io.netty.buffer.ByteBuf;
|
||||
import io.netty.buffer.UnpooledByteBufAllocator;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.LongBuffer;
|
||||
import java.util.Set;
|
||||
|
||||
public class TechHider14 extends TechHider9 {
|
||||
public class ChunkHider14 extends ChunkHider9 {
|
||||
|
||||
@Override
|
||||
protected byte[] dataHider(byte[] data, Integer primaryBitMask) {
|
||||
protected byte[] dataHider(int obfuscationTarget, Set<Integer> obfuscate, byte[] data, Integer primaryBitMask) {
|
||||
ByteBuf buffer = UnpooledByteBufAllocator.DEFAULT.directBuffer(data.length + 100);
|
||||
int i = 0;
|
||||
|
||||
@ -43,16 +44,16 @@ public class TechHider14 extends TechHider9 {
|
||||
buffer.writeByte(bitsPerBlock);
|
||||
|
||||
if(bitsPerBlock < 9){
|
||||
int paletteLength = TechHider.readVarInt(data, i);
|
||||
int paletteLengthLength = TechHider.readVarIntLength(data, i);
|
||||
int paletteLength = ProtocolUtils.readVarInt(data, i);
|
||||
int paletteLengthLength = ProtocolUtils.readVarIntLength(data, i);
|
||||
buffer.writeBytes(data, i, paletteLengthLength);
|
||||
i += paletteLengthLength;
|
||||
for(int actPaletteId = 0; actPaletteId < paletteLength; actPaletteId++){
|
||||
int blockId = TechHider.readVarInt(data, i);
|
||||
int actPaletteLength = TechHider.readVarIntLength(data, i);
|
||||
int blockId = ProtocolUtils.readVarInt(data, i);
|
||||
int actPaletteLength = ProtocolUtils.readVarIntLength(data, i);
|
||||
|
||||
if(hiddenBlockIds.contains(blockId)){
|
||||
buffer.writeBytes(TechHider.writeVarInt(obfuscateWith));
|
||||
if(obfuscate.contains(blockId)){
|
||||
buffer.writeBytes(ProtocolUtils.writeVarInt(obfuscationTarget));
|
||||
}else{
|
||||
buffer.writeBytes(data, i, actPaletteLength);
|
||||
}
|
||||
@ -60,15 +61,15 @@ public class TechHider14 extends TechHider9 {
|
||||
}
|
||||
|
||||
//We modify only the chunk palette for performance reasons
|
||||
int dataArrayLength = TechHider.readVarInt(data, i);
|
||||
int dataArrayLengthLength = TechHider.readVarIntLength(data, i);
|
||||
int dataArrayLength = ProtocolUtils.readVarInt(data, i);
|
||||
int dataArrayLengthLength = ProtocolUtils.readVarIntLength(data, i);
|
||||
buffer.writeBytes(data, i, dataArrayLength * 8 + dataArrayLengthLength);
|
||||
i += dataArrayLengthLength;
|
||||
i += dataArrayLength * 8;
|
||||
}else{
|
||||
//Full Chunk/no palette, so the chunk has to be crawled through
|
||||
int dataArrayLength = TechHider.readVarInt(data, i);
|
||||
int dataArrayLengthLength = TechHider.readVarIntLength(data, i);
|
||||
int dataArrayLength = ProtocolUtils.readVarInt(data, i);
|
||||
int dataArrayLengthLength = ProtocolUtils.readVarIntLength(data, i);
|
||||
buffer.writeBytes(data, i, dataArrayLengthLength);
|
||||
i += dataArrayLengthLength;
|
||||
|
||||
@ -76,8 +77,8 @@ public class TechHider14 extends TechHider9 {
|
||||
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);
|
||||
if(obfuscate.contains(values.get(pos))){
|
||||
values.set(pos, obfuscationTarget);
|
||||
}
|
||||
}
|
||||
|
@ -17,30 +17,32 @@
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package de.steamwar.fightsystem.utils;
|
||||
package de.steamwar.techhider;
|
||||
|
||||
import com.comphenix.tinyprotocol.Reflection;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
import java.util.Set;
|
||||
import java.util.function.BiFunction;
|
||||
import java.util.function.UnaryOperator;
|
||||
|
||||
public class ProtocolWrapper12 extends ProtocolWrapper8 {
|
||||
public class ProtocolWrapper14 extends ProtocolWrapper8 {
|
||||
|
||||
@Override
|
||||
public BiFunction<Player, Object, Object> blockBreakHiderGenerator(Class<?> blockBreakPacket){
|
||||
UnaryOperator<Object> blockBreakCloner = ProtocolAPI.shallowCloneGenerator(blockBreakPacket);
|
||||
public BiFunction<Player, Object, Object> blockBreakHiderGenerator(Class<?> blockBreakPacket, Object obfuscationTarget, Set<Material> obfuscate, TechHider.BypassEvaluator bypass) {
|
||||
UnaryOperator<Object> blockBreakCloner = ProtocolUtils.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))))
|
||||
if(bypass.bypass(p, ProtocolUtils.posToChunk(TechHider.blockPositionX.get(pos)), ProtocolUtils.posToChunk(TechHider.blockPositionZ.get(pos))))
|
||||
return packet;
|
||||
|
||||
if(ProtocolWrapper.impl.iBlockDataHidden(blockBreakBlockData.get(packet))){
|
||||
if(ProtocolWrapper.impl.iBlockDataHidden(obfuscate, blockBreakBlockData.get(packet))){
|
||||
packet = blockBreakCloner.apply(packet);
|
||||
blockBreakBlockData.set(packet, TechHider.obfuscateIBlockData);
|
||||
blockBreakBlockData.set(packet, obfuscationTarget);
|
||||
}
|
||||
return packet;
|
||||
};
|
@ -19,16 +19,13 @@
|
||||
|
||||
package de.steamwar.fightsystem.utils;
|
||||
|
||||
import de.steamwar.fightsystem.Config;
|
||||
import net.minecraft.server.v1_15_R1.*;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.block.Block;
|
||||
import org.bukkit.craftbukkit.v1_15_R1.CraftWorld;
|
||||
import org.bukkit.craftbukkit.v1_15_R1.block.CraftBlock;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.Objects;
|
||||
import java.util.Set;
|
||||
|
||||
public class BlockIdWrapper15 implements BlockIdWrapper {
|
||||
@Override
|
||||
@ -46,32 +43,6 @@ public class BlockIdWrapper15 implements BlockIdWrapper {
|
||||
cworld.getChunkProvider().flagDirty(pos);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<Integer> getHiddenBlockIds() {
|
||||
Set<Integer> hiddenBlockIds = new HashSet<>();
|
||||
for(String tag : Config.HiddenBlocks){
|
||||
for(IBlockData data : IRegistry.BLOCK.get(new MinecraftKey(tag)).getStates().a()){
|
||||
hiddenBlockIds.add(net.minecraft.server.v1_15_R1.Block.getCombinedId(data));
|
||||
}
|
||||
}
|
||||
|
||||
if(Config.HiddenBlocks.contains("water")){
|
||||
Fluid water = FluidTypes.WATER.a(false);
|
||||
for(IBlockData data : net.minecraft.server.v1_15_R1.Block.REGISTRY_ID){
|
||||
if(data.getFluid() == water){
|
||||
hiddenBlockIds.add(net.minecraft.server.v1_15_R1.Block.getCombinedId(data));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return hiddenBlockIds;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getObfuscateWith() {
|
||||
return net.minecraft.server.v1_15_R1.Block.getCombinedId(IRegistry.BLOCK.get(new MinecraftKey(Config.ObfuscateWith)).getBlockData());
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getPose(boolean sneaking) {
|
||||
return sneaking ? EntityPose.CROUCHING : EntityPose.STANDING;
|
||||
|
52
FightSystem_15/src/de/steamwar/techhider/BlockIds15.java
Normale Datei
52
FightSystem_15/src/de/steamwar/techhider/BlockIds15.java
Normale Datei
@ -0,0 +1,52 @@
|
||||
/*
|
||||
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.techhider;
|
||||
|
||||
import net.minecraft.server.v1_15_R1.*;
|
||||
import org.bukkit.Material;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
|
||||
public class BlockIds15 implements BlockIds {
|
||||
@Override
|
||||
public int materialToId(Material material) {
|
||||
return Block.getCombinedId(IRegistry.BLOCK.get(new MinecraftKey(material.name().toLowerCase())).getBlockData());
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<Integer> materialToAllIds(Material material) {
|
||||
Set<Integer> ids = new HashSet<>();
|
||||
for(IBlockData data : IRegistry.BLOCK.get(new MinecraftKey(material.name().toLowerCase())).getStates().a()) {
|
||||
ids.add(Block.getCombinedId(data));
|
||||
}
|
||||
|
||||
if(material == Material.WATER){
|
||||
Fluid water = FluidTypes.WATER.a(false);
|
||||
for(IBlockData data : Block.REGISTRY_ID){
|
||||
if(data.getFluid() == water){
|
||||
ids.add(Block.getCombinedId(data));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return ids;
|
||||
}
|
||||
}
|
@ -19,23 +19,16 @@
|
||||
|
||||
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_R2.CraftWorld;
|
||||
import org.bukkit.craftbukkit.v1_18_R2.block.CraftBlock;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.Objects;
|
||||
import java.util.Set;
|
||||
|
||||
public class BlockIdWrapper18 implements BlockIdWrapper {
|
||||
|
||||
@ -54,32 +47,6 @@ public class BlockIdWrapper18 implements BlockIdWrapper {
|
||||
cworld.k().a(pos);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<Integer> getHiddenBlockIds() {
|
||||
Set<Integer> hiddenBlockIds = new HashSet<>();
|
||||
for(String tag : Config.HiddenBlocks){
|
||||
for(IBlockData data : IRegistry.U.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.o) {
|
||||
if(data.o() == 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.U.a(new MinecraftKey(Config.ObfuscateWith)).n());
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getPose(boolean sneaking) {
|
||||
return sneaking ? EntityPose.f : EntityPose.a;
|
||||
|
@ -22,22 +22,13 @@ 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 {
|
||||
|
||||
@ -83,48 +74,9 @@ public class ProtocolWrapper18 implements ProtocolWrapper {
|
||||
}
|
||||
}
|
||||
|
||||
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.U.b(((IBlockData) iBlockData).b()).a());
|
||||
}
|
||||
}
|
||||
|
57
FightSystem_18/src/de/steamwar/techhider/BlockIds18.java
Normale Datei
57
FightSystem_18/src/de/steamwar/techhider/BlockIds18.java
Normale Datei
@ -0,0 +1,57 @@
|
||||
/*
|
||||
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.techhider;
|
||||
|
||||
import net.minecraft.core.IRegistry;
|
||||
import net.minecraft.resources.MinecraftKey;
|
||||
import net.minecraft.world.level.block.Block;
|
||||
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.Material;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
|
||||
public class BlockIds18 implements BlockIds {
|
||||
@Override
|
||||
public int materialToId(Material material) {
|
||||
return Block.i(IRegistry.U.a(new MinecraftKey(material.name().toLowerCase())).n());
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<Integer> materialToAllIds(Material material) {
|
||||
Set<Integer> ids = new HashSet<>();
|
||||
for(IBlockData data : IRegistry.U.a(new MinecraftKey(material.name().toLowerCase())).m().a()){
|
||||
ids.add(Block.i(data));
|
||||
}
|
||||
|
||||
if(material == Material.WATER){
|
||||
Fluid water = FluidTypes.c.h();
|
||||
for(IBlockData data : Block.o) {
|
||||
if(data.o() == water) {
|
||||
ids.add(Block.i(data));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return ids;
|
||||
}
|
||||
}
|
@ -17,10 +17,9 @@
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package de.steamwar.fightsystem.utils;
|
||||
package de.steamwar.techhider;
|
||||
|
||||
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;
|
||||
@ -34,19 +33,19 @@ import org.bukkit.entity.Player;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.function.BiFunction;
|
||||
import java.util.function.IntFunction;
|
||||
import java.util.function.UnaryOperator;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
public class TechHider18 implements TechHider.ChunkHider {
|
||||
|
||||
public class ChunkHider18 implements 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 UnaryOperator<Object> chunkPacketCloner = ProtocolUtils.shallowCloneGenerator(ClientboundLevelChunkWithLightPacket.class);
|
||||
private static final UnaryOperator<Object> chunkDataCloner = ProtocolUtils.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);
|
||||
@ -57,32 +56,31 @@ public class TechHider18 implements TechHider.ChunkHider {
|
||||
public static final Class<?> tileEntity = Reflection.getClass("net.minecraft.network.protocol.game.ClientboundLevelChunkPacketData$a");
|
||||
protected 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)))
|
||||
public BiFunction<Player, Object, Object> chunkHiderGenerator(TechHider.BypassEvaluator bypass, int obfuscationTarget, Set<Integer> obfuscate, Set<String> hiddenBlockEntities) {
|
||||
return (p, packet) -> {
|
||||
if(bypass.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(this::tileEntityVisible).collect(Collectors.toList()));
|
||||
tileEntities.set(data, ((List<?>)tileEntities.get(data)).stream().filter(te -> tileEntityVisible(hiddenBlockEntities, te)).collect(Collectors.toList()));
|
||||
|
||||
World world = p.getWorld();
|
||||
int sections = (world.getMaxHeight() - world.getMinHeight()) / 16;
|
||||
dataField.set(data, dataHider(dataField.get(data), sections));
|
||||
dataField.set(data, dataHider(obfuscationTarget, obfuscate, dataField.get(data), sections));
|
||||
|
||||
chunkData.set(packet, data);
|
||||
return packet;
|
||||
};
|
||||
}
|
||||
|
||||
protected boolean tileEntityVisible(Object tile) {
|
||||
return !Config.HiddenBlockEntities.contains(IRegistry.aa.b(entityType.get(tile)).a());
|
||||
protected boolean tileEntityVisible(Set<String> hiddenBlockEntities, Object tile) {
|
||||
return !hiddenBlockEntities.contains(IRegistry.aa.b(entityType.get(tile)).a());
|
||||
}
|
||||
|
||||
private byte[] dataHider(byte[] data, int sections) {
|
||||
private byte[] dataHider(int obfuscationTarget, Set<Integer> obfuscate, byte[] data, int sections) {
|
||||
ByteBuf buffer = UnpooledByteBufAllocator.DEFAULT.directBuffer(data.length + 100);
|
||||
int i = 0;
|
||||
|
||||
@ -90,7 +88,7 @@ public class TechHider18 implements TechHider.ChunkHider {
|
||||
buffer.writeBytes(data, i, 2); // Block count
|
||||
i += 2;
|
||||
|
||||
i = containerWalker(data, buffer, i, 15, blockId -> hiddenBlockIds.contains(blockId) ? obfuscateWith : blockId, (curI, dataArrayLength, bitsPerBlock) -> {
|
||||
i = containerWalker(data, buffer, i, 15, blockId -> obfuscate.contains(blockId) ? obfuscationTarget : blockId, (curI, dataArrayLength, bitsPerBlock) -> {
|
||||
if(bitsPerBlock < 15) {
|
||||
buffer.writeBytes(data, curI, dataArrayLength * 8);
|
||||
} else {
|
||||
@ -100,8 +98,8 @@ public class TechHider18 implements TechHider.ChunkHider {
|
||||
SimpleBitStorage values = new SimpleBitStorage(bitsPerBlock, 4096, array);
|
||||
|
||||
for (int pos = 0; pos < 4096; pos++) {
|
||||
if (hiddenBlockIds.contains(values.a(pos))) {
|
||||
values.b(pos, obfuscateWith);
|
||||
if (obfuscate.contains(values.a(pos))) {
|
||||
values.b(pos, obfuscationTarget);
|
||||
}
|
||||
}
|
||||
|
||||
@ -118,29 +116,29 @@ public class TechHider18 implements TechHider.ChunkHider {
|
||||
return outdata;
|
||||
}
|
||||
|
||||
private int containerWalker(byte[] data, ByteBuf buffer, int i, int globalPalette, IntFunction<Integer> palette, Region.TriConsumer<Integer, Integer, Byte> dataArray) {
|
||||
private int containerWalker(byte[] data, ByteBuf buffer, int i, int globalPalette, IntFunction<Integer> palette, 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)));
|
||||
int paletteValue = ProtocolUtils.readVarInt(data, i);
|
||||
i += ProtocolUtils.readVarIntLength(data, i);
|
||||
buffer.writeBytes(ProtocolUtils.writeVarInt(palette.apply(paletteValue)));
|
||||
}else if(bitsPerBlock < globalPalette) {
|
||||
int paletteLength = TechHider.readVarInt(data, i);
|
||||
int paletteLengthLength = TechHider.readVarIntLength(data, i);
|
||||
int paletteLength = ProtocolUtils.readVarInt(data, i);
|
||||
int paletteLengthLength = ProtocolUtils.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 paletteValue = ProtocolUtils.readVarInt(data, i);
|
||||
i += ProtocolUtils.readVarIntLength(data, i);
|
||||
buffer.writeBytes(ProtocolUtils.writeVarInt(palette.apply(paletteValue)));
|
||||
}
|
||||
}
|
||||
|
||||
int dataArrayLength = TechHider.readVarInt(data, i);
|
||||
int dataArrayLengthLength = TechHider.readVarIntLength(data, i);
|
||||
int dataArrayLength = ProtocolUtils.readVarInt(data, i);
|
||||
int dataArrayLengthLength = ProtocolUtils.readVarIntLength(data, i);
|
||||
buffer.writeBytes(data, i, dataArrayLengthLength);
|
||||
i += dataArrayLengthLength;
|
||||
|
||||
@ -149,4 +147,8 @@ public class TechHider18 implements TechHider.ChunkHider {
|
||||
|
||||
return i;
|
||||
}
|
||||
|
||||
private interface TriConsumer<X, Y, Z> {
|
||||
void accept(X x, Y y, Z z);
|
||||
}
|
||||
}
|
77
FightSystem_18/src/de/steamwar/techhider/ProtocolWrapper18.java
Normale Datei
77
FightSystem_18/src/de/steamwar/techhider/ProtocolWrapper18.java
Normale Datei
@ -0,0 +1,77 @@
|
||||
/*
|
||||
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.techhider;
|
||||
|
||||
import com.comphenix.tinyprotocol.Reflection;
|
||||
import net.minecraft.core.IRegistry;
|
||||
import net.minecraft.core.SectionPosition;
|
||||
import net.minecraft.network.protocol.game.PacketPlayOutBlockBreak;
|
||||
import net.minecraft.world.level.block.entity.TileEntityTypes;
|
||||
import net.minecraft.world.level.block.state.IBlockData;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
import java.util.Set;
|
||||
import java.util.function.BiFunction;
|
||||
import java.util.function.UnaryOperator;
|
||||
|
||||
public class ProtocolWrapper18 implements ProtocolWrapper {
|
||||
|
||||
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 = ProtocolUtils.arrayCloneGenerator(TechHider.iBlockData);
|
||||
@Override
|
||||
public BiFunction<Player, Object, Object> multiBlockChangeGenerator(Object obfuscationTarget, Set<Material> obfuscate, TechHider.BypassEvaluator bypass) {
|
||||
return (p, packet) -> {
|
||||
Object chunkCoords = multiBlockChangeChunk.get(packet);
|
||||
if(bypass.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(obfuscate, block) ? obfuscationTarget : 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, Object obfuscationTarget, Set<Material> obfuscate, TechHider.BypassEvaluator bypass) {
|
||||
return (p, packet) -> {
|
||||
PacketPlayOutBlockBreak breakPacket = (PacketPlayOutBlockBreak) packet;
|
||||
if(bypass.bypass(p, ProtocolUtils.posToChunk(TechHider.blockPositionX.get(breakPacket.b())), ProtocolUtils.posToChunk(TechHider.blockPositionZ.get(breakPacket.b()))))
|
||||
return packet;
|
||||
|
||||
if(!ProtocolWrapper.impl.iBlockDataHidden(obfuscate, breakPacket.c()))
|
||||
return packet;
|
||||
|
||||
return new PacketPlayOutBlockBreak(breakPacket.b(), (IBlockData) obfuscationTarget, breakPacket.d(), breakPacket.a());
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean iBlockDataHidden(Set<Material> obfuscate, Object iBlockData) {
|
||||
return obfuscate.contains(Material.getMaterial(IRegistry.U.b(((IBlockData) iBlockData).b()).a().toUpperCase()));
|
||||
}
|
||||
}
|
@ -19,23 +19,16 @@
|
||||
|
||||
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_19_R1.CraftWorld;
|
||||
import org.bukkit.craftbukkit.v1_19_R1.block.CraftBlock;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.Objects;
|
||||
import java.util.Set;
|
||||
|
||||
public class BlockIdWrapper19 implements BlockIdWrapper {
|
||||
|
||||
@ -54,32 +47,6 @@ public class BlockIdWrapper19 implements BlockIdWrapper {
|
||||
cworld.k().a(pos);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<Integer> getHiddenBlockIds() {
|
||||
Set<Integer> hiddenBlockIds = new HashSet<>();
|
||||
for(String tag : Config.HiddenBlocks){
|
||||
for(IBlockData data : IRegistry.V.a(new MinecraftKey(tag)).k().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.o) {
|
||||
if(data.p() == 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.V.a(new MinecraftKey(Config.ObfuscateWith)).m());
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getPose(boolean sneaking) {
|
||||
return sneaking ? EntityPose.f : EntityPose.a;
|
||||
|
@ -22,21 +22,13 @@ 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.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 ProtocolWrapper19 implements ProtocolWrapper {
|
||||
|
||||
@ -82,39 +74,9 @@ public class ProtocolWrapper19 implements ProtocolWrapper {
|
||||
}
|
||||
}
|
||||
|
||||
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 null;
|
||||
}
|
||||
|
||||
private static final Reflection.ConstructorInvoker playerInfoDataConstructor = Reflection.getConstructor(Fight.playerInfoDataClass, GameProfile.class, int.class, Fight.enumGamemode, Fight.iChatBaseComponent, Reflection.getClass("net.minecraft.world.entity.player.ProfilePublicKey$a"));
|
||||
@Override
|
||||
public Object playerInfoDataConstructor(Object packet, GameProfile profile, Object mode) {
|
||||
return playerInfoDataConstructor.invoke(profile, 0, mode, null, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean iBlockDataHidden(Object iBlockData) {
|
||||
return Config.HiddenBlocks.contains(IRegistry.V.b(((IBlockData) iBlockData).b()).a());
|
||||
}
|
||||
}
|
||||
|
57
FightSystem_19/src/de/steamwar/techhider/BlockIds19.java
Normale Datei
57
FightSystem_19/src/de/steamwar/techhider/BlockIds19.java
Normale Datei
@ -0,0 +1,57 @@
|
||||
/*
|
||||
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.techhider;
|
||||
|
||||
import net.minecraft.core.IRegistry;
|
||||
import net.minecraft.resources.MinecraftKey;
|
||||
import net.minecraft.world.level.block.Block;
|
||||
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.Material;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
|
||||
public class BlockIds19 implements BlockIds {
|
||||
@Override
|
||||
public int materialToId(Material material) {
|
||||
return Block.i(IRegistry.V.a(new MinecraftKey(material.name().toLowerCase())).m());
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<Integer> materialToAllIds(Material material) {
|
||||
Set<Integer> ids = new HashSet<>();
|
||||
for(IBlockData data : IRegistry.V.a(new MinecraftKey(material.name().toLowerCase())).k().a()){
|
||||
ids.add(Block.i(data));
|
||||
}
|
||||
|
||||
if(material == Material.WATER){
|
||||
Fluid water = FluidTypes.c.h();
|
||||
for(IBlockData data : Block.o) {
|
||||
if(data.p() == water) {
|
||||
ids.add(Block.i(data));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return ids;
|
||||
}
|
||||
}
|
@ -17,15 +17,15 @@
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package de.steamwar.fightsystem.utils;
|
||||
package de.steamwar.techhider;
|
||||
|
||||
import de.steamwar.fightsystem.Config;
|
||||
import net.minecraft.core.IRegistry;
|
||||
|
||||
public class TechHider19 extends TechHider18 {
|
||||
import java.util.Set;
|
||||
|
||||
public class ChunkHider19 extends ChunkHider18 {
|
||||
@Override
|
||||
protected boolean tileEntityVisible(Object tile) {
|
||||
return !Config.HiddenBlockEntities.contains(IRegistry.ab.b(entityType.get(tile)).a());
|
||||
protected boolean tileEntityVisible(Set<String> hiddenBlockEntities, Object tile) {
|
||||
return !hiddenBlockEntities.contains(IRegistry.ab.b(entityType.get(tile)).a());
|
||||
}
|
||||
}
|
67
FightSystem_19/src/de/steamwar/techhider/ProtocolWrapper19.java
Normale Datei
67
FightSystem_19/src/de/steamwar/techhider/ProtocolWrapper19.java
Normale Datei
@ -0,0 +1,67 @@
|
||||
/*
|
||||
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.techhider;
|
||||
|
||||
import com.comphenix.tinyprotocol.Reflection;
|
||||
import net.minecraft.core.IRegistry;
|
||||
import net.minecraft.core.SectionPosition;
|
||||
import net.minecraft.world.level.block.entity.TileEntityTypes;
|
||||
import net.minecraft.world.level.block.state.IBlockData;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
import java.util.Set;
|
||||
import java.util.function.BiFunction;
|
||||
import java.util.function.UnaryOperator;
|
||||
|
||||
public class ProtocolWrapper19 implements ProtocolWrapper {
|
||||
|
||||
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 = ProtocolUtils.arrayCloneGenerator(TechHider.iBlockData);
|
||||
@Override
|
||||
public BiFunction<Player, Object, Object> multiBlockChangeGenerator(Object obfuscationTarget, Set<Material> obfuscate, TechHider.BypassEvaluator bypass) {
|
||||
return (p, packet) -> {
|
||||
Object chunkCoords = multiBlockChangeChunk.get(packet);
|
||||
if(bypass.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(obfuscate, block) ? obfuscationTarget : 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, Object obfuscationTarget, Set<Material> obfuscate, TechHider.BypassEvaluator bypass) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean iBlockDataHidden(Set<Material> obfuscate, Object iBlockData) {
|
||||
return obfuscate.contains(Material.getMaterial(IRegistry.V.b(((IBlockData) iBlockData).b()).a().toUpperCase()));
|
||||
}
|
||||
}
|
@ -19,14 +19,9 @@
|
||||
|
||||
package de.steamwar.fightsystem.utils;
|
||||
|
||||
import de.steamwar.fightsystem.Config;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.block.Block;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
|
||||
public class BlockIdWrapper8 implements BlockIdWrapper {
|
||||
@Override
|
||||
@SuppressWarnings("deprecation")
|
||||
@ -40,22 +35,6 @@ public class BlockIdWrapper8 implements BlockIdWrapper {
|
||||
world.getBlockAt(x, y, z).setTypeIdAndData(blockState >> 4, (byte)(blockState & 0b1111), false);
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("deprecation")
|
||||
public Set<Integer> getHiddenBlockIds() {
|
||||
Set<Integer> hiddenBlockIds = new HashSet<>();
|
||||
for(String tag : Config.HiddenBlocks){
|
||||
hiddenBlockIds.add(Material.matchMaterial(tag).getId() << 4);
|
||||
}
|
||||
return hiddenBlockIds;
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("deprecation")
|
||||
public int getObfuscateWith() {
|
||||
return Material.matchMaterial(Config.ObfuscateWith).getId() << 4;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getPose(boolean sneaking) {
|
||||
return Byte.valueOf((byte)(sneaking ? 2 : 0));
|
||||
|
@ -22,15 +22,9 @@ 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 {
|
||||
|
||||
@ -106,53 +100,9 @@ public class ProtocolWrapper8 implements ProtocolWrapper {
|
||||
}
|
||||
}
|
||||
|
||||
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());
|
||||
}
|
||||
}
|
||||
|
38
FightSystem_8/src/de/steamwar/techhider/BlockIds8.java
Normale Datei
38
FightSystem_8/src/de/steamwar/techhider/BlockIds8.java
Normale Datei
@ -0,0 +1,38 @@
|
||||
/*
|
||||
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.techhider;
|
||||
|
||||
import org.bukkit.Material;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.Set;
|
||||
|
||||
public class BlockIds8 implements BlockIds {
|
||||
@Override
|
||||
@SuppressWarnings("deprecation")
|
||||
public int materialToId(Material material) {
|
||||
return material.getId() << 4;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<Integer> materialToAllIds(Material material) {
|
||||
return Collections.singleton(materialToId(material));
|
||||
}
|
||||
}
|
@ -17,12 +17,15 @@
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package de.steamwar.fightsystem.utils;
|
||||
package de.steamwar.techhider;
|
||||
|
||||
import com.comphenix.tinyprotocol.Reflection;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
public class TechHider8 implements TechHider.ChunkHider {
|
||||
import java.util.Set;
|
||||
import java.util.function.BiFunction;
|
||||
|
||||
public class ChunkHider8 implements ChunkHider {
|
||||
|
||||
protected static final Class<?> mapChunkPacket = Reflection.getClass("{nms}.PacketPlayOutMapChunk");
|
||||
@Override
|
||||
@ -31,7 +34,7 @@ public class TechHider8 implements TechHider.ChunkHider {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object mapChunkHider(Player p, Object packet) {
|
||||
return packet;
|
||||
public BiFunction<Player, Object, Object> chunkHiderGenerator(TechHider.BypassEvaluator bypass, int obfuscationTarget, Set<Integer> obfuscate, Set<String> hiddenBlockEntities) {
|
||||
return null;
|
||||
}
|
||||
}
|
76
FightSystem_8/src/de/steamwar/techhider/ProtocolWrapper8.java
Normale Datei
76
FightSystem_8/src/de/steamwar/techhider/ProtocolWrapper8.java
Normale Datei
@ -0,0 +1,76 @@
|
||||
/*
|
||||
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.techhider;
|
||||
|
||||
import com.comphenix.tinyprotocol.Reflection;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
import java.util.Set;
|
||||
import java.util.function.BiFunction;
|
||||
import java.util.function.UnaryOperator;
|
||||
|
||||
public class ProtocolWrapper8 implements ProtocolWrapper {
|
||||
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 = ProtocolUtils.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 BiFunction<Player, Object, Object> multiBlockChangeGenerator(Object obfuscationTarget, Set<Material> obfuscate, TechHider.BypassEvaluator bypass) {
|
||||
return (p, packet) -> {
|
||||
Object chunkCoords = multiBlockChangeChunk.get(packet);
|
||||
if(bypass.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(obfuscate, multiBlockChangeInfoBlock.get(mbci)))
|
||||
return multiBlockChangeInfoConstructor.invoke(modpacket, multiBlockChangeInfoPos.get(mbci), obfuscationTarget);
|
||||
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, Object obfuscationTarget, Set<Material> obfuscate, TechHider.BypassEvaluator bypass) {
|
||||
return 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(Set<Material> obfuscate, Object iBlockData) {
|
||||
return obfuscate.contains((Material) getMaterialByBlock.invoke(null, getBlockByBlockData.invoke(iBlockData)));
|
||||
}
|
||||
}
|
@ -17,10 +17,9 @@
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package de.steamwar.fightsystem.utils;
|
||||
package de.steamwar.techhider;
|
||||
|
||||
import com.comphenix.tinyprotocol.Reflection;
|
||||
import de.steamwar.fightsystem.Config;
|
||||
import io.netty.buffer.ByteBuf;
|
||||
import io.netty.buffer.UnpooledByteBufAllocator;
|
||||
import org.bukkit.Bukkit;
|
||||
@ -28,13 +27,14 @@ import org.bukkit.entity.Player;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.function.BiFunction;
|
||||
import java.util.function.UnaryOperator;
|
||||
import java.util.logging.Level;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
public class TechHider9 extends TechHider8 {
|
||||
public class ChunkHider9 extends ChunkHider8 {
|
||||
|
||||
private static final UnaryOperator<Object> mapChunkCloner = ProtocolAPI.shallowCloneGenerator(mapChunkPacket);
|
||||
private static final UnaryOperator<Object> mapChunkCloner = ProtocolUtils.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);
|
||||
@ -45,26 +45,25 @@ public class TechHider9 extends TechHider8 {
|
||||
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
|
||||
public Object mapChunkHider(Player p, Object packet) {
|
||||
if(TechHider.bypass(p, mapChunkX.get(packet), mapChunkZ.get(packet)))
|
||||
public BiFunction<Player, Object, Object> chunkHiderGenerator(TechHider.BypassEvaluator bypass, int obfuscationTarget, Set<Integer> obfuscate, Set<String> hiddenBlockEntities) {
|
||||
return (p, packet) -> {
|
||||
if(bypass.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"))
|
||||
nbttag -> !hiddenBlockEntities.contains((String) nbtTagGetString.invoke(nbttag, "id"))
|
||||
).collect(Collectors.toList()));
|
||||
|
||||
byte[] data = dataHider(mapChunkData.get(packet), mapChunkBitMask.get(packet));
|
||||
byte[] data = dataHider(obfuscationTarget, obfuscate, mapChunkData.get(packet), mapChunkBitMask.get(packet));
|
||||
mapChunkData.set(packet, data);
|
||||
|
||||
return packet;
|
||||
};
|
||||
}
|
||||
|
||||
protected byte[] dataHider(byte[] data, Integer primaryBitMask) {
|
||||
protected byte[] dataHider(int obfuscationTarget, Set<Integer> obfuscate, byte[] data, Integer primaryBitMask) {
|
||||
ByteBuf buffer = UnpooledByteBufAllocator.DEFAULT.directBuffer(data.length + 100);
|
||||
int i = 0;
|
||||
|
||||
@ -73,27 +72,27 @@ public class TechHider9 extends TechHider8 {
|
||||
buffer.writeByte(bitsPerBlock);
|
||||
|
||||
if(bitsPerBlock != 13){
|
||||
int paletteLength = TechHider.readVarInt(data, i);
|
||||
int paletteLengthLength = TechHider.readVarIntLength(data, i);
|
||||
int paletteLength = ProtocolUtils.readVarInt(data, i);
|
||||
int paletteLengthLength = ProtocolUtils.readVarIntLength(data, i);
|
||||
buffer.writeBytes(data, i, paletteLengthLength);
|
||||
i += paletteLengthLength;
|
||||
|
||||
for(int actPaletteId = 0; actPaletteId < paletteLength; actPaletteId++){
|
||||
int entry = TechHider.readVarInt(data, i);
|
||||
i += TechHider.readVarIntLength(data, i);
|
||||
int entry = ProtocolUtils.readVarInt(data, i);
|
||||
i += ProtocolUtils.readVarIntLength(data, i);
|
||||
|
||||
if(hiddenBlockIds.contains(entry)){
|
||||
entry = obfuscateWith;
|
||||
if(obfuscate.contains(entry)){
|
||||
entry = obfuscationTarget;
|
||||
}
|
||||
buffer.writeBytes(TechHider.writeVarInt(entry));
|
||||
buffer.writeBytes(ProtocolUtils.writeVarInt(entry));
|
||||
}
|
||||
}else{
|
||||
buffer.writeByte(data[++i]); //Empty palette
|
||||
Bukkit.getLogger().log(Level.SEVERE, "Full chunk occured");
|
||||
}
|
||||
|
||||
int dataArrayLength = TechHider.readVarInt(data, i);
|
||||
int dataArrayLengthLength = TechHider.readVarIntLength(data, i);
|
||||
int dataArrayLength = ProtocolUtils.readVarInt(data, i);
|
||||
int dataArrayLengthLength = ProtocolUtils.readVarIntLength(data, i);
|
||||
buffer.writeBytes(data, i, dataArrayLength*8 + dataArrayLengthLength);
|
||||
i += dataArrayLengthLength;
|
||||
i += dataArrayLength * 8;
|
@ -48,6 +48,7 @@ public class FightSystem extends JavaPlugin {
|
||||
private Message message;
|
||||
private FightTeam lastWinner;
|
||||
private String lastWinreason;
|
||||
private TechHiderWrapper techHider;
|
||||
|
||||
@Override
|
||||
public void onLoad() {
|
||||
@ -94,7 +95,7 @@ public class FightSystem extends JavaPlugin {
|
||||
new OneShotStateDependent(ArenaMode.All, FightState.PreSchemSetup, () -> Fight.playSound(SWSound.BLOCK_NOTE_PLING.getSound(), 100.0f, 2.0f));
|
||||
|
||||
new EnterHandler();
|
||||
new TechHider();
|
||||
techHider = new TechHiderWrapper();
|
||||
new FightWorld();
|
||||
new FightUI();
|
||||
new FightStatistics();
|
||||
@ -192,6 +193,10 @@ public class FightSystem extends JavaPlugin {
|
||||
return plugin.lastWinreason;
|
||||
}
|
||||
|
||||
public static TechHiderWrapper getTechHider() {
|
||||
return plugin.techHider;
|
||||
}
|
||||
|
||||
public static void shutdown() {
|
||||
//Staggered kick to prevent lobby overloading
|
||||
if(Bukkit.getOnlinePlayers().isEmpty()){
|
||||
|
@ -24,7 +24,7 @@ import de.steamwar.fightsystem.FightSystem;
|
||||
import de.steamwar.fightsystem.fight.FightPlayer;
|
||||
import de.steamwar.fightsystem.utils.Message;
|
||||
import de.steamwar.fightsystem.utils.SWSound;
|
||||
import de.steamwar.fightsystem.utils.TechHider;
|
||||
import de.steamwar.techhider.ProtocolUtils;
|
||||
import net.md_5.bungee.api.ChatMessageType;
|
||||
|
||||
import java.util.List;
|
||||
@ -32,7 +32,7 @@ import java.util.List;
|
||||
public class EnternCountdown extends Countdown {
|
||||
|
||||
private final FightPlayer fightPlayer;
|
||||
private List<TechHider.ChunkPos> chunkPos;
|
||||
private List<ProtocolUtils.ChunkPos> chunkPos;
|
||||
|
||||
public EnternCountdown(FightPlayer fp) {
|
||||
super(Config.EnterStages.get(fp.getKit().getEnterStage()), new Message("ENTERN_COUNTDOWN"), SWSound.BLOCK_NOTE_PLING, false);
|
||||
@ -43,12 +43,12 @@ public class EnternCountdown extends Countdown {
|
||||
@Override
|
||||
public void countdownFinished() {
|
||||
FightSystem.getMessage().sendPrefixless("ENTERN_ALLOWED", fightPlayer.getPlayer(), ChatMessageType.ACTION_BAR);
|
||||
TechHider.reloadChunks(fightPlayer.getPlayer(), chunkPos, false);
|
||||
FightSystem.getTechHider().reloadChunks(fightPlayer.getPlayer(), chunkPos, false);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void prepareFinish() {
|
||||
chunkPos = TechHider.prepareChunkReload(fightPlayer.getPlayer(), false);
|
||||
chunkPos = FightSystem.getTechHider().prepareChunkReload(fightPlayer.getPlayer(), false);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -35,6 +35,7 @@ import de.steamwar.fightsystem.utils.*;
|
||||
import de.steamwar.inventory.SWItem;
|
||||
import de.steamwar.sql.SchematicNode;
|
||||
import de.steamwar.sql.SteamwarUser;
|
||||
import de.steamwar.techhider.ProtocolUtils;
|
||||
import net.md_5.bungee.api.ChatMessageType;
|
||||
import org.bukkit.*;
|
||||
import org.bukkit.enchantments.Enchantment;
|
||||
@ -244,7 +245,7 @@ public class FightTeam {
|
||||
}
|
||||
|
||||
public void addMember(Player player, boolean silent) {
|
||||
final List<TechHider.ChunkPos> chunksToReload = TechHider.prepareChunkReload(player, false);
|
||||
final List<ProtocolUtils.ChunkPos> chunksToReload = FightSystem.getTechHider().prepareChunkReload(player, false);
|
||||
FightPlayer fightPlayer = new FightPlayer(player, this);
|
||||
players.put(player, fightPlayer);
|
||||
invited.remove(player);
|
||||
@ -258,7 +259,7 @@ public class FightTeam {
|
||||
player.teleport(spawn);
|
||||
memberKit.loadToPlayer(player);
|
||||
GlobalRecorder.getInstance().playerJoins(player);
|
||||
TechHider.reloadChunks(player, chunksToReload, false);
|
||||
FightSystem.getTechHider().reloadChunks(player, chunksToReload, false);
|
||||
|
||||
if(isLeaderless())
|
||||
setLeader(fightPlayer, silent);
|
||||
@ -270,7 +271,7 @@ public class FightTeam {
|
||||
FightPlayer fightPlayer = getFightPlayer(player);
|
||||
|
||||
PersonalKitCreator.closeIfInKitCreator(player);
|
||||
List<TechHider.ChunkPos> chunksToReload = TechHider.prepareChunkReload(player, true);
|
||||
List<ProtocolUtils.ChunkPos> chunksToReload = FightSystem.getTechHider().prepareChunkReload(player, true);
|
||||
players.remove(player);
|
||||
team.removeEntry(player.getName());
|
||||
|
||||
@ -285,7 +286,7 @@ public class FightTeam {
|
||||
player.getInventory().clear();
|
||||
|
||||
if(player.isOnline()){
|
||||
TechHider.reloadChunks(player, chunksToReload, true);
|
||||
FightSystem.getTechHider().reloadChunks(player, chunksToReload, true);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -20,6 +20,7 @@
|
||||
package de.steamwar.fightsystem.listener;
|
||||
|
||||
import com.comphenix.tinyprotocol.Reflection;
|
||||
import com.comphenix.tinyprotocol.TinyProtocol;
|
||||
import de.steamwar.fightsystem.ArenaMode;
|
||||
import de.steamwar.fightsystem.FightSystem;
|
||||
import de.steamwar.fightsystem.fight.Fight;
|
||||
@ -48,6 +49,7 @@ import org.bukkit.event.player.*;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
|
||||
import java.util.Random;
|
||||
import java.util.function.BiFunction;
|
||||
import java.util.function.Consumer;
|
||||
import java.util.function.Predicate;
|
||||
|
||||
@ -89,16 +91,19 @@ public class Recording implements Listener {
|
||||
}
|
||||
}.register();
|
||||
new StateDependent(ArenaMode.AntiReplay, FightState.Ingame) {
|
||||
private final BiFunction<Player, Object, Object> place = Recording.this::blockPlace;
|
||||
private final BiFunction<Player, Object, Object> dig = Recording.this::blockDig;
|
||||
|
||||
@Override
|
||||
public void enable() {
|
||||
ProtocolAPI.setIncomingHandler(blockPlacePacket, Recording.this::blockPlace);
|
||||
ProtocolAPI.setIncomingHandler(blockDigPacket, Recording.this::blockDig);
|
||||
TinyProtocol.instance.addFilter(blockPlacePacket, place);
|
||||
TinyProtocol.instance.addFilter(blockDigPacket, dig);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void disable() {
|
||||
ProtocolAPI.removeIncomingHandler(blockPlacePacket);
|
||||
ProtocolAPI.removeIncomingHandler(blockDigPacket);
|
||||
TinyProtocol.instance.removeFilter(blockPlacePacket, place);
|
||||
TinyProtocol.instance.removeFilter(blockDigPacket, dig);
|
||||
}
|
||||
}.register();
|
||||
new StateDependentTask(ArenaMode.AntiReplay, FightState.All, () -> {
|
||||
|
@ -33,11 +33,13 @@ import de.steamwar.fightsystem.states.FightState;
|
||||
import de.steamwar.fightsystem.utils.*;
|
||||
import de.steamwar.sql.SchematicNode;
|
||||
import de.steamwar.sql.Team;
|
||||
import de.steamwar.techhider.BlockIds;
|
||||
import net.md_5.bungee.api.ChatMessageType;
|
||||
import net.md_5.bungee.api.chat.BaseComponent;
|
||||
import net.md_5.bungee.api.chat.TextComponent;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.Sound;
|
||||
import org.bukkit.entity.EntityType;
|
||||
import org.bukkit.scheduler.BukkitTask;
|
||||
@ -46,6 +48,7 @@ import java.io.EOFException;
|
||||
import java.io.IOException;
|
||||
import java.util.*;
|
||||
import java.util.logging.Level;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
public class PacketProcessor {
|
||||
|
||||
@ -64,8 +67,8 @@ public class PacketProcessor {
|
||||
private final PacketSource source;
|
||||
private final BukkitTask task;
|
||||
private final LinkedList<Runnable> syncList = new LinkedList<>();
|
||||
private final Set<Integer> hiddenBlockIds = BlockIdWrapper.impl.getHiddenBlockIds();
|
||||
private final int obfuscateWith = BlockIdWrapper.impl.getObfuscateWith();
|
||||
private final Set<Integer> hiddenBlockIds = Config.HiddenBlocks.stream().map(Material::getMaterial).flatMap(m -> BlockIds.impl.materialToAllIds(m).stream()).collect(Collectors.toSet());
|
||||
private final int obfuscateWith = BlockIds.impl.materialToId(Material.getMaterial(Config.ObfuscateWith));
|
||||
private final FreezeWorld freezer = new FreezeWorld();
|
||||
|
||||
private boolean rotateZ = false;
|
||||
@ -345,7 +348,7 @@ public class PacketProcessor {
|
||||
if(!Config.ArenaRegion.in2dRegion(x, z))
|
||||
return; //Outside of the arena
|
||||
|
||||
execSync(() -> BlockIdWrapper.impl.setBlock(Config.world, x, y, z, TechHider.ENABLED && hiddenBlockIds.contains(blockState) ? obfuscateWith : blockState));
|
||||
execSync(() -> BlockIdWrapper.impl.setBlock(Config.world, x, y, z, TechHiderWrapper.ENABLED && hiddenBlockIds.contains(blockState) ? obfuscateWith : blockState));
|
||||
}
|
||||
|
||||
private void particle() throws IOException {
|
||||
|
@ -28,6 +28,7 @@ import de.steamwar.fightsystem.fight.Fight;
|
||||
import de.steamwar.fightsystem.listener.FightScoreboard;
|
||||
import de.steamwar.fightsystem.utils.*;
|
||||
import de.steamwar.sql.SteamwarUser;
|
||||
import de.steamwar.techhider.ProtocolUtils;
|
||||
import it.unimi.dsi.fastutil.ints.IntArrayList;
|
||||
import it.unimi.dsi.fastutil.ints.IntList;
|
||||
import org.bukkit.Material;
|
||||
@ -65,7 +66,7 @@ public class REntity {
|
||||
if(entity.fireTick > 0) {
|
||||
entity.fireTick--;
|
||||
if(entity.fireTick == 0) {
|
||||
ProtocolAPI.broadcastPacket(entity.getDataWatcherPacket(entityStatusWatcher, (byte)0));
|
||||
ProtocolUtils.broadcastPacket(entity.getDataWatcherPacket(entityStatusWatcher, (byte)0));
|
||||
}
|
||||
}
|
||||
});
|
||||
@ -148,7 +149,7 @@ public class REntity {
|
||||
this.name = user.getUserName();
|
||||
entities.put(internalId, this);
|
||||
|
||||
ProtocolAPI.broadcastPacket(getPlayerInfoPacket());
|
||||
ProtocolUtils.broadcastPacket(getPlayerInfoPacket());
|
||||
team.addEntry(name);
|
||||
}
|
||||
|
||||
@ -160,7 +161,7 @@ public class REntity {
|
||||
this.uuid = new UUID(random.nextLong() & -61441L | 16384L, random.nextLong() & 4611686018427387903L | -9223372036854775808L);
|
||||
entities.put(internalId, this);
|
||||
|
||||
ProtocolAPI.broadcastPacket(getSpawnEntityPacket());
|
||||
ProtocolUtils.broadcastPacket(getSpawnEntityPacket());
|
||||
}
|
||||
|
||||
public void move(double locX, double locY, double locZ, float pitch, float yaw, byte headYaw){
|
||||
@ -168,15 +169,15 @@ public class REntity {
|
||||
this.locY = locY;
|
||||
this.locZ = locZ;
|
||||
if(entityType == EntityType.PLAYER && !playerSpawned) {
|
||||
ProtocolAPI.broadcastPacket(getNamedSpawnPacket());
|
||||
ProtocolUtils.broadcastPacket(getNamedSpawnPacket());
|
||||
playerSpawned = true;
|
||||
}
|
||||
|
||||
this.yaw = (byte)((int)(yaw * 256.0F / 360.0F));
|
||||
this.pitch = (byte)((int)(pitch * 256.0F / 360.0F));
|
||||
this.headYaw = headYaw;
|
||||
ProtocolAPI.broadcastPacket(getTeleportPacket());
|
||||
ProtocolAPI.broadcastPacket(getHeadRotationPacket());
|
||||
ProtocolUtils.broadcastPacket(getTeleportPacket());
|
||||
ProtocolUtils.broadcastPacket(getHeadRotationPacket());
|
||||
}
|
||||
|
||||
private static final Class<?> animationPacket = Reflection.getClass("{nms.network.protocol.game}.PacketPlayOutAnimation");
|
||||
@ -186,7 +187,7 @@ public class REntity {
|
||||
Object packet = Reflection.newInstance(animationPacket);
|
||||
animationEntity.set(packet, entityId);
|
||||
animationAnimation.set(packet, (int) animation);
|
||||
ProtocolAPI.broadcastPacket(packet);
|
||||
ProtocolUtils.broadcastPacket(packet);
|
||||
}
|
||||
|
||||
private static final Class<?> velocityPacket = Reflection.getClass("{nms.network.protocol.game}.PacketPlayOutEntityVelocity");
|
||||
@ -200,7 +201,7 @@ public class REntity {
|
||||
velocityX.set(packet, calcVelocity(dX));
|
||||
velocityY.set(packet, calcVelocity(dY));
|
||||
velocityZ.set(packet, calcVelocity(dZ));
|
||||
ProtocolAPI.broadcastPacket(packet);
|
||||
ProtocolUtils.broadcastPacket(packet);
|
||||
}
|
||||
|
||||
private static final Class<?> statusPacket = Reflection.getClass("{nms.network.protocol.game}.PacketPlayOutEntityStatus");
|
||||
@ -210,12 +211,12 @@ public class REntity {
|
||||
Object packet = Reflection.newInstance(statusPacket);
|
||||
statusEntity.set(packet, entityId);
|
||||
statusStatus.set(packet, (byte) 2);
|
||||
ProtocolAPI.broadcastPacket(packet);
|
||||
ProtocolUtils.broadcastPacket(packet);
|
||||
}
|
||||
|
||||
public void sneak(boolean sneaking) {
|
||||
sneaks = sneaking;
|
||||
ProtocolAPI.broadcastPacket(getDataWatcherPacket(sneakingDataWatcher, BlockIdWrapper.impl.getPose(sneaking)));
|
||||
ProtocolUtils.broadcastPacket(getDataWatcherPacket(sneakingDataWatcher, BlockIdWrapper.impl.getPose(sneaking)));
|
||||
}
|
||||
|
||||
public void setOnFire(boolean perma) {
|
||||
@ -225,14 +226,14 @@ public class REntity {
|
||||
fireTick = -1;
|
||||
}
|
||||
|
||||
ProtocolAPI.broadcastPacket(getDataWatcherPacket(entityStatusWatcher, (byte) 1));
|
||||
ProtocolUtils.broadcastPacket(getDataWatcherPacket(entityStatusWatcher, (byte) 1));
|
||||
}
|
||||
|
||||
public void setBowDrawn(boolean drawn, boolean offHand) {
|
||||
if(Core.getVersion() > 8){
|
||||
ProtocolAPI.broadcastPacket(getDataWatcherPacket(bowDrawnWatcher, (byte) ((drawn ? 1 : 0) + (offHand ? 2 : 0))));
|
||||
ProtocolUtils.broadcastPacket(getDataWatcherPacket(bowDrawnWatcher, (byte) ((drawn ? 1 : 0) + (offHand ? 2 : 0))));
|
||||
}else{
|
||||
ProtocolAPI.broadcastPacket(getDataWatcherPacket(entityStatusWatcher, (byte)0x10));
|
||||
ProtocolUtils.broadcastPacket(getDataWatcherPacket(entityStatusWatcher, (byte)0x10));
|
||||
}
|
||||
}
|
||||
|
||||
@ -242,7 +243,7 @@ public class REntity {
|
||||
stack.addUnsafeEnchantment(Enchantment.DURABILITY, 1);
|
||||
itemSlots.put(slot, stack);
|
||||
|
||||
ProtocolAPI.broadcastPacket(getEquipmentPacket(slot, stack));
|
||||
ProtocolUtils.broadcastPacket(getEquipmentPacket(slot, stack));
|
||||
}
|
||||
|
||||
public void die(){
|
||||
@ -261,13 +262,13 @@ public class REntity {
|
||||
|
||||
private void broadcastDeath(){
|
||||
if(entityType == EntityType.PLAYER){
|
||||
ProtocolAPI.broadcastPacket(Fight.playerInfoPacket(Fight.removePlayer, new GameProfile(uuid, name), Fight.creative));
|
||||
ProtocolUtils.broadcastPacket(Fight.playerInfoPacket(Fight.removePlayer, new GameProfile(uuid, name), Fight.creative));
|
||||
team.removeEntry(name);
|
||||
}
|
||||
|
||||
Object packet = Reflection.newInstance(destroyPacket);
|
||||
destroyEntities.set(packet, Core.getVersion() > 15 ? new IntArrayList(new int[]{entityId}) : new int[]{entityId});
|
||||
ProtocolAPI.broadcastPacket(packet);
|
||||
ProtocolUtils.broadcastPacket(packet);
|
||||
}
|
||||
|
||||
private int calcVelocity(double value) {
|
||||
|
@ -24,16 +24,11 @@ import de.steamwar.fightsystem.FightSystem;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.block.Block;
|
||||
|
||||
import java.util.Set;
|
||||
|
||||
public interface BlockIdWrapper {
|
||||
BlockIdWrapper impl = VersionDependent.getVersionImpl(FightSystem.getPlugin());
|
||||
|
||||
int blockToId(Block block);
|
||||
void setBlock(World world, int x, int y, int z, int blockState);
|
||||
|
||||
Set<Integer> getHiddenBlockIds();
|
||||
int getObfuscateWith();
|
||||
|
||||
Object getPose(boolean sneaking);
|
||||
}
|
||||
|
@ -23,9 +23,6 @@ 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());
|
||||
@ -34,13 +31,6 @@ public interface ProtocolWrapper {
|
||||
|
||||
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);
|
||||
}
|
||||
|
@ -1,247 +0,0 @@
|
||||
/*
|
||||
This file is a part of the SteamWar software.
|
||||
|
||||
Copyright (C) 2020 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.google.common.primitives.Bytes;
|
||||
import de.steamwar.core.Core;
|
||||
import de.steamwar.core.CraftbukkitWrapper;
|
||||
import de.steamwar.core.VersionDependent;
|
||||
import de.steamwar.fightsystem.Config;
|
||||
import de.steamwar.fightsystem.FightSystem;
|
||||
import de.steamwar.fightsystem.fight.Fight;
|
||||
import de.steamwar.fightsystem.fight.FightTeam;
|
||||
import de.steamwar.fightsystem.states.FightState;
|
||||
import de.steamwar.fightsystem.states.StateDependent;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.GameMode;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.function.BiFunction;
|
||||
import java.util.function.Function;
|
||||
import java.util.function.UnaryOperator;
|
||||
|
||||
public class TechHider extends StateDependent {
|
||||
|
||||
public static final Class<?> blockPosition = Reflection.getClass("{nms.core}.BlockPosition");
|
||||
private static final Class<?> baseBlockPosition = Reflection.getClass("{nms.core}.BaseBlockPosition");
|
||||
public static final Reflection.FieldAccessor<Integer> blockPositionX = Reflection.getField(baseBlockPosition, int.class, 0);
|
||||
public static final Reflection.FieldAccessor<Integer> blockPositionZ = Reflection.getField(baseBlockPosition, int.class, 2);
|
||||
|
||||
public static final Class<?> iBlockData = Reflection.getClass("{nms.world.level.block.state}.IBlockData");
|
||||
public static final Class<?> block = Reflection.getClass("{nms.world.level.block}.Block");
|
||||
private static final Reflection.MethodInvoker getBlockDataByBlock = Reflection.getTypedMethod(block, null, iBlockData);
|
||||
|
||||
public static final Class<?> craftMagicNumbers = Reflection.getClass("{obc}.util.CraftMagicNumbers");
|
||||
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 Object obfuscateIBlockData = getBlockDataByBlock.invoke(getBlockByMaterial.invoke(null, Material.getMaterial(Config.ObfuscateWith.toUpperCase())));
|
||||
private final Map<Class<?>, BiFunction<Player, Object, Object>> techhiders = new HashMap<>();
|
||||
|
||||
public interface ChunkHider {
|
||||
Class<?> mapChunkPacket();
|
||||
Object mapChunkHider(Player p, Object packet);
|
||||
}
|
||||
|
||||
public TechHider(){
|
||||
super(ENABLED, FightState.Schem);
|
||||
|
||||
techhiders.put(blockActionPacket, this::blockActionHider);
|
||||
techhiders.put(blockChangePacket, this::blockChangeHider);
|
||||
techhiders.put(tileEntityDataPacket, this::tileEntityDataHider);
|
||||
techhiders.put(multiBlockChangePacket, ProtocolWrapper.impl::multiBlockChangeHider);
|
||||
|
||||
ChunkHider chunkHider = VersionDependent.getVersionImpl(FightSystem.getPlugin());
|
||||
techhiders.put(chunkHider.mapChunkPacket(), chunkHider::mapChunkHider);
|
||||
|
||||
if(Core.getVersion() > 12 && Core.getVersion() < 19) {
|
||||
Class<?> blockBreakClass = Reflection.getClass("{nms.network.protocol.game}.PacketPlayOutBlockBreak");
|
||||
techhiders.put(blockBreakClass, ProtocolWrapper.impl.blockBreakHiderGenerator(blockBreakClass));
|
||||
}
|
||||
|
||||
if(Core.getVersion() > 8){
|
||||
ProtocolAPI.setIncomingHandler(Reflection.getClass("{nms.network.protocol.game}.PacketPlayInUseItem"), (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();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void enable() {
|
||||
techhiders.forEach(ProtocolAPI::setOutgoingHandler);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void disable() {
|
||||
techhiders.keySet().forEach(ProtocolAPI::removeOutgoingHandler);
|
||||
}
|
||||
|
||||
public static final Class<?> multiBlockChangePacket = Reflection.getClass("{nms.network.protocol.game}.PacketPlayOutMultiBlockChange");
|
||||
public static final UnaryOperator<Object> multiBlockChangeCloner = ProtocolAPI.shallowCloneGenerator(TechHider.multiBlockChangePacket);
|
||||
|
||||
private static final Class<?> blockChangePacket = Reflection.getClass("{nms.network.protocol.game}.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(ProtocolWrapper.impl.iBlockDataHidden(blockChangeBlockData.get(packet))) {
|
||||
packet = blockChangeCloner.apply(packet);
|
||||
blockChangeBlockData.set(packet, obfuscateIBlockData);
|
||||
}
|
||||
return packet;
|
||||
}
|
||||
|
||||
private static final Class<?> blockActionPacket = Reflection.getClass("{nms.network.protocol.game}.PacketPlayOutBlockAction");
|
||||
private static final Reflection.FieldAccessor<?> blockActionPosition = Reflection.getField(blockActionPacket, blockPosition, 0);
|
||||
private Object blockActionHider(Player p, Object packet) {
|
||||
Object pos = blockActionPosition.get(packet);
|
||||
if(bypass(p, posToChunk(blockPositionX.get(pos)), posToChunk(blockPositionZ.get(pos))))
|
||||
return packet;
|
||||
return null;
|
||||
}
|
||||
|
||||
public static final Class<?> tileEntityDataPacket = Reflection.getClass("{nms.network.protocol.game}.PacketPlayOutTileEntityData");
|
||||
private static final Reflection.FieldAccessor<?> tileEntityDataPosition = Reflection.getField(tileEntityDataPacket, blockPosition, 0);
|
||||
private Object tileEntityDataHider(Player p, Object packet) {
|
||||
Object pos = tileEntityDataPosition.get(packet);
|
||||
if(bypass(p, posToChunk(blockPositionX.get(pos)), posToChunk(blockPositionZ.get(pos))))
|
||||
return packet;
|
||||
|
||||
if(ProtocolWrapper.impl.unfilteredTileEntityDataAction(packet))
|
||||
return packet;
|
||||
return null;
|
||||
}
|
||||
|
||||
public static List<ChunkPos> prepareChunkReload(Player p, boolean hide){
|
||||
if(!ENABLED)
|
||||
return Collections.emptyList();
|
||||
List<ChunkPos> chunksToReload = new ArrayList<>();
|
||||
Config.ArenaRegion.forEachChunk((x, z) -> {
|
||||
if(bypass(p, x, z) == hide)
|
||||
chunksToReload.add(new ChunkPos(x, z));
|
||||
});
|
||||
return chunksToReload;
|
||||
}
|
||||
|
||||
public static void reloadChunks(Player p, List<ChunkPos> chunksToReload, boolean hide){
|
||||
if(!ENABLED || !FightState.Schem.contains(FightState.getFightState()))
|
||||
return;
|
||||
Bukkit.getScheduler().runTaskLater(FightSystem.getPlugin(), () -> {
|
||||
for(ChunkPos chunk : chunksToReload){
|
||||
if(bypass(p, chunk.x(), chunk.z()) != hide)
|
||||
CraftbukkitWrapper.impl.sendChunk(p, chunk.x(), chunk.z());
|
||||
}
|
||||
}, 40);
|
||||
}
|
||||
|
||||
public static boolean bypass(Player p, int chunkX, int chunkZ){
|
||||
if(Config.isReferee(p))
|
||||
return true;
|
||||
|
||||
FightTeam ft = Fight.getPlayerTeam(p);
|
||||
if(ft == null){
|
||||
return Config.ArenaRegion.chunkOutside(chunkX, chunkZ);
|
||||
}else if(ft.isBlue()){
|
||||
return ft.canPlayerEntern(p) || Config.RedExtendRegion.chunkOutside(chunkX, chunkZ);
|
||||
}else{
|
||||
return ft.canPlayerEntern(p) || Config.BlueExtendRegion.chunkOutside(chunkX, chunkZ);
|
||||
}
|
||||
}
|
||||
|
||||
public static int posToChunk(int c){
|
||||
int chunk = c / 16;
|
||||
if(c<0)
|
||||
chunk--;
|
||||
return chunk;
|
||||
}
|
||||
|
||||
static int readVarInt(byte[] array, int startPos) {
|
||||
int numRead = 0;
|
||||
int result = 0;
|
||||
byte read;
|
||||
do {
|
||||
read = array[startPos + numRead];
|
||||
int value = (read & 0b01111111);
|
||||
result |= (value << (7 * numRead));
|
||||
|
||||
numRead++;
|
||||
if (numRead > 5) {
|
||||
break;
|
||||
}
|
||||
} while ((read & 0b10000000) != 0);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static int readVarIntLength(byte[] array, int startPos) {
|
||||
int numRead = 0;
|
||||
byte read;
|
||||
do {
|
||||
read = array[startPos + numRead];
|
||||
numRead++;
|
||||
if (numRead > 5) {
|
||||
break;
|
||||
}
|
||||
} while ((read & 0b10000000) != 0);
|
||||
|
||||
return numRead;
|
||||
}
|
||||
|
||||
static byte[] writeVarInt(int value) {
|
||||
List<Byte> buffer = new ArrayList<>(5);
|
||||
do {
|
||||
byte temp = (byte)(value & 0b01111111);
|
||||
// Note: >>> means that the sign bit is shifted with the rest of the number rather than being left alone
|
||||
value >>>= 7;
|
||||
if (value != 0) {
|
||||
temp |= 0b10000000;
|
||||
}
|
||||
buffer.add(temp);
|
||||
} while (value != 0);
|
||||
return Bytes.toArray(buffer);
|
||||
}
|
||||
|
||||
public static class ChunkPos{
|
||||
final int x;
|
||||
final int z;
|
||||
|
||||
ChunkPos(int x, int z){
|
||||
this.x = x;
|
||||
this.z = z;
|
||||
}
|
||||
|
||||
final int x(){
|
||||
return x;
|
||||
}
|
||||
|
||||
final int z(){
|
||||
return z;
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,98 @@
|
||||
/*
|
||||
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.core.CraftbukkitWrapper;
|
||||
import de.steamwar.fightsystem.Config;
|
||||
import de.steamwar.fightsystem.FightSystem;
|
||||
import de.steamwar.fightsystem.fight.Fight;
|
||||
import de.steamwar.fightsystem.fight.FightTeam;
|
||||
import de.steamwar.fightsystem.states.FightState;
|
||||
import de.steamwar.fightsystem.states.StateDependent;
|
||||
import de.steamwar.techhider.ProtocolUtils;
|
||||
import de.steamwar.techhider.TechHider;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
public class TechHiderWrapper extends StateDependent {
|
||||
|
||||
public static final boolean ENABLED = !Config.OnlyPublicSchematics && !Config.test() && Config.TechhiderActive;
|
||||
private final TechHider techHider;
|
||||
|
||||
public TechHiderWrapper() {
|
||||
super(ENABLED, FightState.Schem);
|
||||
techHider = new TechHider(this::bypass, Material.getMaterial(Config.ObfuscateWith), Config.HiddenBlocks.stream().map(Material::getMaterial).collect(Collectors.toSet()), Config.HiddenBlockEntities);
|
||||
register();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void enable() {
|
||||
techHider.enable();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void disable() {
|
||||
techHider.disable();
|
||||
}
|
||||
|
||||
public List<ProtocolUtils.ChunkPos> prepareChunkReload(Player p, boolean hide) {
|
||||
if(!ENABLED)
|
||||
return Collections.emptyList();
|
||||
|
||||
List<ProtocolUtils.ChunkPos> chunksToReload = new ArrayList<>();
|
||||
Config.ArenaRegion.forEachChunk((x, z) -> {
|
||||
if(bypass(p, x, z) == hide)
|
||||
chunksToReload.add(new ProtocolUtils.ChunkPos(x, z));
|
||||
});
|
||||
return chunksToReload;
|
||||
}
|
||||
|
||||
public void reloadChunks(Player p, List<ProtocolUtils.ChunkPos> chunksToReload, boolean hide) {
|
||||
if(!ENABLED || !FightState.Schem.contains(FightState.getFightState()))
|
||||
return;
|
||||
|
||||
Bukkit.getScheduler().runTaskLater(FightSystem.getPlugin(), () -> {
|
||||
for(ProtocolUtils.ChunkPos chunk : chunksToReload){
|
||||
if(bypass(p, chunk.x(), chunk.z()) != hide)
|
||||
CraftbukkitWrapper.impl.sendChunk(p, chunk.x(), chunk.z());
|
||||
}
|
||||
}, 40);
|
||||
}
|
||||
|
||||
private boolean bypass(Player p, int chunkX, int chunkZ){
|
||||
if(Config.isReferee(p))
|
||||
return true;
|
||||
|
||||
FightTeam ft = Fight.getPlayerTeam(p);
|
||||
if(ft == null){
|
||||
return Config.ArenaRegion.chunkOutside(chunkX, chunkZ);
|
||||
}else if(ft.isBlue()){
|
||||
return ft.canPlayerEntern(p) || Config.RedExtendRegion.chunkOutside(chunkX, chunkZ);
|
||||
}else{
|
||||
return ft.canPlayerEntern(p) || Config.BlueExtendRegion.chunkOutside(chunkX, chunkZ);
|
||||
}
|
||||
}
|
||||
}
|
33
FightSystem_Core/src/de/steamwar/techhider/BlockIds.java
Normale Datei
33
FightSystem_Core/src/de/steamwar/techhider/BlockIds.java
Normale Datei
@ -0,0 +1,33 @@
|
||||
/*
|
||||
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.techhider;
|
||||
|
||||
import de.steamwar.core.VersionDependent;
|
||||
import de.steamwar.fightsystem.FightSystem;
|
||||
import org.bukkit.Material;
|
||||
|
||||
import java.util.Set;
|
||||
|
||||
public interface BlockIds {
|
||||
BlockIds impl = VersionDependent.getVersionImpl(FightSystem.getPlugin());
|
||||
|
||||
int materialToId(Material material);
|
||||
Set<Integer> materialToAllIds(Material material);
|
||||
}
|
34
FightSystem_Core/src/de/steamwar/techhider/ChunkHider.java
Normale Datei
34
FightSystem_Core/src/de/steamwar/techhider/ChunkHider.java
Normale Datei
@ -0,0 +1,34 @@
|
||||
/*
|
||||
This file is a part of the SteamWar software.
|
||||
|
||||
Copyright (C) 2022 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.techhider;
|
||||
|
||||
import de.steamwar.core.VersionDependent;
|
||||
import de.steamwar.fightsystem.FightSystem;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
import java.util.Set;
|
||||
import java.util.function.BiFunction;
|
||||
|
||||
public interface ChunkHider {
|
||||
ChunkHider impl = VersionDependent.getVersionImpl(FightSystem.getPlugin());
|
||||
|
||||
Class<?> mapChunkPacket();
|
||||
BiFunction<Player, Object, Object> chunkHiderGenerator(TechHider.BypassEvaluator bypass, int obfuscationTarget, Set<Integer> obfuscate, Set<String> hiddenBlockEntities);
|
||||
}
|
@ -1,7 +1,7 @@
|
||||
/*
|
||||
This file is a part of the SteamWar software.
|
||||
|
||||
Copyright (C) 2021 SteamWar.de-Serverteam
|
||||
Copyright (C) 2022 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
|
||||
@ -17,60 +17,24 @@
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package de.steamwar.fightsystem.utils;
|
||||
package de.steamwar.techhider;
|
||||
|
||||
import com.comphenix.tinyprotocol.Reflection;
|
||||
import com.comphenix.tinyprotocol.TinyProtocol;
|
||||
import com.google.common.primitives.Bytes;
|
||||
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<>();
|
||||
|
||||
static {
|
||||
TinyProtocol.instance.setOutFilter((receiver, channel, packet) -> {
|
||||
BiFunction<Player, Object, Object> handler = outgoingHandler.get(packet.getClass());
|
||||
if(handler == null)
|
||||
return packet;
|
||||
return handler.apply(receiver, packet);
|
||||
});
|
||||
TinyProtocol.instance.setInFilter((sender, channel, 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 class ProtocolUtils {
|
||||
private ProtocolUtils() {}
|
||||
|
||||
public static void broadcastPacket(Object packet) {
|
||||
Bukkit.getOnlinePlayers().stream().map(TinyProtocol.instance::getChannel).filter(TinyProtocol.instance::hasInjected).forEach(channel -> TinyProtocol.instance.sendPacket(channel, packet));
|
||||
@ -126,4 +90,75 @@ public class ProtocolAPI {
|
||||
|
||||
};
|
||||
}
|
||||
|
||||
public static int posToChunk(int c){
|
||||
int chunk = c / 16;
|
||||
if(c<0)
|
||||
chunk--;
|
||||
return chunk;
|
||||
}
|
||||
|
||||
public static int readVarInt(byte[] array, int startPos) {
|
||||
int numRead = 0;
|
||||
int result = 0;
|
||||
byte read;
|
||||
do {
|
||||
read = array[startPos + numRead];
|
||||
int value = (read & 0b01111111);
|
||||
result |= (value << (7 * numRead));
|
||||
|
||||
numRead++;
|
||||
if (numRead > 5) {
|
||||
break;
|
||||
}
|
||||
} while ((read & 0b10000000) != 0);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
public static int readVarIntLength(byte[] array, int startPos) {
|
||||
int numRead = 0;
|
||||
byte read;
|
||||
do {
|
||||
read = array[startPos + numRead];
|
||||
numRead++;
|
||||
if (numRead > 5) {
|
||||
break;
|
||||
}
|
||||
} while ((read & 0b10000000) != 0);
|
||||
|
||||
return numRead;
|
||||
}
|
||||
|
||||
public static byte[] writeVarInt(int value) {
|
||||
List<Byte> buffer = new ArrayList<>(5);
|
||||
do {
|
||||
byte temp = (byte)(value & 0b01111111);
|
||||
// Note: >>> means that the sign bit is shifted with the rest of the number rather than being left alone
|
||||
value >>>= 7;
|
||||
if (value != 0) {
|
||||
temp |= 0b10000000;
|
||||
}
|
||||
buffer.add(temp);
|
||||
} while (value != 0);
|
||||
return Bytes.toArray(buffer);
|
||||
}
|
||||
|
||||
public static class ChunkPos{
|
||||
final int x;
|
||||
final int z;
|
||||
|
||||
public ChunkPos(int x, int z){
|
||||
this.x = x;
|
||||
this.z = z;
|
||||
}
|
||||
|
||||
public final int x(){
|
||||
return x;
|
||||
}
|
||||
|
||||
public final int z(){
|
||||
return z;
|
||||
}
|
||||
}
|
||||
}
|
41
FightSystem_Core/src/de/steamwar/techhider/ProtocolWrapper.java
Normale Datei
41
FightSystem_Core/src/de/steamwar/techhider/ProtocolWrapper.java
Normale Datei
@ -0,0 +1,41 @@
|
||||
/*
|
||||
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.techhider;
|
||||
|
||||
import de.steamwar.core.VersionDependent;
|
||||
import de.steamwar.fightsystem.FightSystem;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
import java.util.Set;
|
||||
import java.util.function.BiFunction;
|
||||
|
||||
public interface ProtocolWrapper {
|
||||
ProtocolWrapper impl = VersionDependent.getVersionImpl(FightSystem.getPlugin());
|
||||
|
||||
|
||||
boolean unfilteredTileEntityDataAction(Object packet);
|
||||
|
||||
BiFunction<Player, Object, Object> blockBreakHiderGenerator(Class<?> blockBreakPacket, Object obfuscationTarget, Set<Material> obfuscate, TechHider.BypassEvaluator bypass);
|
||||
|
||||
BiFunction<Player, Object, Object> multiBlockChangeGenerator(Object obfuscationTarget, Set<Material> obfuscate, TechHider.BypassEvaluator bypass);
|
||||
|
||||
boolean iBlockDataHidden(Set<Material> obfuscate, Object iBlockData);
|
||||
}
|
128
FightSystem_Core/src/de/steamwar/techhider/TechHider.java
Normale Datei
128
FightSystem_Core/src/de/steamwar/techhider/TechHider.java
Normale Datei
@ -0,0 +1,128 @@
|
||||
/*
|
||||
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.techhider;
|
||||
|
||||
import com.comphenix.tinyprotocol.Reflection;
|
||||
import com.comphenix.tinyprotocol.TinyProtocol;
|
||||
import de.steamwar.core.Core;
|
||||
import org.bukkit.GameMode;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
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 {
|
||||
|
||||
public static final Class<?> blockPosition = Reflection.getClass("{nms.core}.BlockPosition");
|
||||
private static final Class<?> baseBlockPosition = Reflection.getClass("{nms.core}.BaseBlockPosition");
|
||||
public static final Reflection.FieldAccessor<Integer> blockPositionX = Reflection.getField(baseBlockPosition, int.class, 0);
|
||||
public static final Reflection.FieldAccessor<Integer> blockPositionZ = Reflection.getField(baseBlockPosition, int.class, 2);
|
||||
|
||||
public static final Class<?> iBlockData = Reflection.getClass("{nms.world.level.block.state}.IBlockData");
|
||||
public static final Class<?> block = Reflection.getClass("{nms.world.level.block}.Block");
|
||||
private static final Reflection.MethodInvoker getBlockDataByBlock = Reflection.getTypedMethod(block, null, iBlockData);
|
||||
|
||||
public static final Class<?> craftMagicNumbers = Reflection.getClass("{obc}.util.CraftMagicNumbers");
|
||||
private static final Reflection.MethodInvoker getBlockByMaterial = Reflection.getTypedMethod(craftMagicNumbers, "getBlock", block, Material.class);
|
||||
|
||||
private final Map<Class<?>, BiFunction<Player, Object, Object>> techhiders = new HashMap<>();
|
||||
private final BypassEvaluator bypass;
|
||||
private final Object obfuscationTarget;
|
||||
private final Set<Material> obfuscate;
|
||||
|
||||
public TechHider(BypassEvaluator bypass, Material obfuscationTarget, Set<Material> obfuscate, Set<String> hiddenBlockEntities) {
|
||||
this.bypass = bypass;
|
||||
this.obfuscate = obfuscate;
|
||||
this.obfuscationTarget = getBlockDataByBlock.invoke(getBlockByMaterial.invoke(null, obfuscationTarget));
|
||||
|
||||
techhiders.put(blockActionPacket, this::blockActionHider);
|
||||
techhiders.put(blockChangePacket, this::blockChangeHider);
|
||||
techhiders.put(tileEntityDataPacket, this::tileEntityDataHider);
|
||||
techhiders.put(multiBlockChangePacket,ProtocolWrapper.impl.multiBlockChangeGenerator(obfuscationTarget, obfuscate, bypass));
|
||||
techhiders.put(ChunkHider.impl.mapChunkPacket(), ChunkHider.impl.chunkHiderGenerator(bypass, BlockIds.impl.materialToId(obfuscationTarget), obfuscate.stream().flatMap(m -> BlockIds.impl.materialToAllIds(m).stream()).collect(Collectors.toSet()), hiddenBlockEntities));
|
||||
|
||||
if(Core.getVersion() > 12 && Core.getVersion() < 19) {
|
||||
Class<?> blockBreakClass = Reflection.getClass("{nms.network.protocol.game}.PacketPlayOutBlockBreak");
|
||||
techhiders.put(blockBreakClass, ProtocolWrapper.impl.blockBreakHiderGenerator(blockBreakClass, obfuscationTarget, obfuscate, bypass));
|
||||
}
|
||||
|
||||
if(Core.getVersion() > 8){
|
||||
techhiders.put(Reflection.getClass("{nms.network.protocol.game}.PacketPlayInUseItem"), (p, packet) -> p.getGameMode() == GameMode.SPECTATOR ? null : packet);
|
||||
}
|
||||
techhiders.put(Reflection.getClass("{nms.network.protocol.game}.PacketPlayInUseEntity"), (p, packet) -> p.getGameMode() == GameMode.SPECTATOR ? null : packet);
|
||||
|
||||
}
|
||||
|
||||
public void enable() {
|
||||
techhiders.forEach(TinyProtocol.instance::addFilter);
|
||||
}
|
||||
|
||||
public void disable() {
|
||||
techhiders.forEach(TinyProtocol.instance::removeFilter);
|
||||
}
|
||||
|
||||
public static final Class<?> multiBlockChangePacket = Reflection.getClass("{nms.network.protocol.game}.PacketPlayOutMultiBlockChange");
|
||||
public static final UnaryOperator<Object> multiBlockChangeCloner = ProtocolUtils.shallowCloneGenerator(TechHider.multiBlockChangePacket);
|
||||
|
||||
private static final Class<?> blockChangePacket = Reflection.getClass("{nms.network.protocol.game}.PacketPlayOutBlockChange");
|
||||
private static final Function<Object, Object> blockChangeCloner = ProtocolUtils.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.bypass(p, ProtocolUtils.posToChunk(blockPositionX.get(pos)), ProtocolUtils.posToChunk(blockPositionZ.get(pos))))
|
||||
return packet;
|
||||
|
||||
if(ProtocolWrapper.impl.iBlockDataHidden(obfuscate, blockChangeBlockData.get(packet))) {
|
||||
packet = blockChangeCloner.apply(packet);
|
||||
blockChangeBlockData.set(packet, obfuscationTarget);
|
||||
}
|
||||
return packet;
|
||||
}
|
||||
|
||||
private static final Class<?> blockActionPacket = Reflection.getClass("{nms.network.protocol.game}.PacketPlayOutBlockAction");
|
||||
private static final Reflection.FieldAccessor<?> blockActionPosition = Reflection.getField(blockActionPacket, blockPosition, 0);
|
||||
private Object blockActionHider(Player p, Object packet) {
|
||||
Object pos = blockActionPosition.get(packet);
|
||||
if(bypass.bypass(p, ProtocolUtils.posToChunk(blockPositionX.get(pos)), ProtocolUtils.posToChunk(blockPositionZ.get(pos))))
|
||||
return packet;
|
||||
return null;
|
||||
}
|
||||
|
||||
public static final Class<?> tileEntityDataPacket = Reflection.getClass("{nms.network.protocol.game}.PacketPlayOutTileEntityData");
|
||||
private static final Reflection.FieldAccessor<?> tileEntityDataPosition = Reflection.getField(tileEntityDataPacket, blockPosition, 0);
|
||||
private Object tileEntityDataHider(Player p, Object packet) {
|
||||
Object pos = tileEntityDataPosition.get(packet);
|
||||
if(bypass.bypass(p, ProtocolUtils.posToChunk(blockPositionX.get(pos)), ProtocolUtils.posToChunk(blockPositionZ.get(pos))))
|
||||
return packet;
|
||||
|
||||
if(ProtocolWrapper.impl.unfilteredTileEntityDataAction(packet))
|
||||
return packet;
|
||||
return null;
|
||||
}
|
||||
|
||||
public interface BypassEvaluator {
|
||||
boolean bypass(Player p, int chunkX, int chunkZ);
|
||||
}
|
||||
}
|
In neuem Issue referenzieren
Einen Benutzer sperren
Outdated Copyright