12
1

CoreHider #357

Zusammengeführt
Lixfel hat 5 Commits von coreHider nach master 2022-08-23 14:31:20 +02:00 zusammengeführt
Nur Änderungen aus Commit 332c47d4b4 werden angezeigt - Alle Commits anzeigen

Datei anzeigen

@ -1,128 +0,0 @@
/*
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);
}
}