CoreHider #357
@ -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);
|
||||
}
|
||||
}
|
In neuem Issue referenzieren
Einen Benutzer sperren