Implement basic techhider

This commit is contained in:
zOnlyKroks
2025-10-08 18:32:32 +02:00
parent 3bfac2d1cf
commit 2d172ffe6b
30 changed files with 292 additions and 4 deletions
@@ -0,0 +1,30 @@
/*
* This file is a part of the SteamWar software.
*
* Copyright (C) 2025 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/>.
*/
plugins {
steamwar.java
}
dependencies {
compileOnly(project(":CommonCore", "default"))
compileOnly(project(":HiderCore:HiderCore_TechHider", "default"))
compileOnly(project(":SpigotCore:SpigotCore_Main", "default"))
compileOnly(libs.nms8)
}
@@ -0,0 +1,44 @@
/*
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
public int getCombinedId(Object iBlockData) {
int id = (int) getCombinedId.invoke(null, iBlockData); // blockState << 12 | blockId
return (id & 4095) | (id >> 12);
}
@Override
@SuppressWarnings("deprecation")
public int materialToId(Material material) {
return material.getId() << 4;
}
@Override
public Set<Integer> materialToAllIds(Material material) {
return Collections.singleton(materialToId(material));
}
}
@@ -0,0 +1,39 @@
/*
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.Reflection;
import org.bukkit.entity.Player;
import java.util.function.BiFunction;
public class ChunkHider8 implements ChunkHider {
protected static final Class<?> mapChunkPacket = Reflection.getClass("net.minecraft.PacketPlayOutMapChunk");
@Override
public Class<?> mapChunkPacket() {
return mapChunkPacket;
}
@Override
public BiFunction<Player, Object, Object> chunkHiderGenerator(TechHider techHider) {
return (player, packet) -> packet;
}
}
@@ -0,0 +1,85 @@
/*
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.Reflection;
import org.bukkit.entity.Player;
import java.lang.reflect.Array;
import java.util.ArrayList;
import java.util.function.BiFunction;
public class ProtocolWrapper8 implements ProtocolWrapper {
private static final Class<?> chunkCoordinateIntPair = Reflection.getClass("net.minecraft.ChunkCoordIntPair");
private static final Reflection.Field<?> multiBlockChangeChunk = Reflection.getField(TechHider.multiBlockChangePacket, chunkCoordinateIntPair, 0);
private static final Reflection.Field<Integer> chunkCoordinateX = Reflection.getField(chunkCoordinateIntPair, int.class, 0);
private static final Reflection.Field<Integer> chunkCoordinateZ = Reflection.getField(chunkCoordinateIntPair, int.class, 1);
private static final Class<?> multiBlockChangeInfo = Reflection.getClass("net.minecraft.PacketPlayOutMultiBlockChange$MultiBlockChangeInfo");
private static final Reflection.Constructor multiBlockChangeInfoConstructor = Reflection.getConstructor(multiBlockChangeInfo, TechHider.multiBlockChangePacket, short.class, TechHider.iBlockData);
private static final Reflection.Field<?> multiBlockChangeInfoBlock = Reflection.getField(multiBlockChangeInfo, TechHider.iBlockData, 0);
private static final Reflection.Field<?> multiBlockChangeInfoPos = Reflection.getField(multiBlockChangeInfo, short.class, 0);
private static final Class<?> multiBlockChangeInfoArray = Reflection.getClass("[L" + Reflection.LEGACY_NET_MINECRAFT_SERVER + ".PacketPlayOutMultiBlockChange$MultiBlockChangeInfo;");
private static final Reflection.Field<?> multiBlockChangeInfos = Reflection.getField(TechHider.multiBlockChangePacket, multiBlockChangeInfoArray, 0);
@Override
public BiFunction<Player, Object, Object> multiBlockChangeGenerator(TechHider techHider) {
return (p, packet) -> {
TechHider.LocationEvaluator locationEvaluator = techHider.getLocationEvaluator();
Object chunkCoords = multiBlockChangeChunk.get(packet);
int chunkX = chunkCoordinateX.get(chunkCoords);
int chunkZ = chunkCoordinateZ.get(chunkCoords);
if(locationEvaluator.skipChunk(p, chunkX, chunkZ))
return packet;
packet = TechHider.multiBlockChangeCloner.apply(packet);
Object[] mbcis = (Object[]) multiBlockChangeInfos.get(packet);
ArrayList<Object> blockChangeInfos = new ArrayList<>(mbcis.length);
for(Object mbci : mbcis) {
short pos = (short) multiBlockChangeInfoPos.get(mbci);
switch(locationEvaluator.check(p, 16*chunkX + (pos >> 12 & 0xF), pos & 0xFF, 16*chunkZ + (pos >> 8 & 0xF))) {
case SKIP:
blockChangeInfos.add(mbci);
break;
case CHECK:
blockChangeInfos.add(techHider.iBlockDataHidden(multiBlockChangeInfoBlock.get(mbci)) ? multiBlockChangeInfoConstructor.invoke(packet, pos, techHider.getObfuscationTarget()) : mbci);
break;
default:
break;
}
}
if(blockChangeInfos.isEmpty())
return null;
multiBlockChangeInfos.set(packet, blockChangeInfos.toArray((Object[])Array.newInstance(multiBlockChangeInfo, 0)));
return packet;
};
}
private static final Reflection.Field<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, TechHider techHider) {
return null;
}
}