forked from SteamWar/SteamWar
Fix final formatting stuff
This commit is contained in:
@@ -227,7 +227,7 @@ public class TinyProtocol {
|
||||
}
|
||||
}
|
||||
|
||||
public <T> void addFilter(Class<T> packetType, BiFunction<Player, ? super T, Object> filter) {
|
||||
public <T extends Packet<?>> void addFilter(Class<T> packetType, BiFunction<Player, ? super T, Object> filter) {
|
||||
packetFilters.computeIfAbsent(packetType, c -> new CopyOnWriteArrayList<>()).add((BiFunction) filter);
|
||||
}
|
||||
|
||||
@@ -235,8 +235,8 @@ public class TinyProtocol {
|
||||
packetFilters.getOrDefault(packetType, Collections.emptyList()).remove(filter);
|
||||
}
|
||||
|
||||
public void addGlobalClientboundFilter(BiFunction<Player, Object, Object> filter) {
|
||||
globalClientboundFilters.add(filter);
|
||||
public void addGlobalClientboundFilter(BiFunction<Player, Packet<?>, Object> filter) {
|
||||
globalClientboundFilters.add((BiFunction) filter);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -453,7 +453,7 @@ public class TinyProtocol {
|
||||
try {
|
||||
msg = filterPacket(player, msg);
|
||||
|
||||
if(msg instanceof Packet<?>) {
|
||||
if (msg instanceof Packet<?>) {
|
||||
for (BiFunction<Player, Object, Object> filter : globalClientboundFilters) {
|
||||
msg = filter.apply(player, msg);
|
||||
if (msg == null) break;
|
||||
|
||||
@@ -24,9 +24,15 @@ import net.minecraft.world.level.block.entity.BlockEntityType;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
public interface AccessPrivilegeProvider {
|
||||
boolean isEveryonePrivilegedToAccessAllDataWithinChunk(int chunkX, int chunkZ);
|
||||
|
||||
boolean isPlayerPrivilegedToAccessPosition(Player p, int blockX, int blockY, int blockZ);
|
||||
|
||||
boolean isPlayerPrivilegedToAccessBlock(Player p, int blockX, int blockY, int blockZ, Block block);
|
||||
|
||||
boolean isPlayerPrivilegedToAccessEntity(Player p, int entityId);
|
||||
|
||||
boolean isPlayerPrivilegedToAccessBlockEntity(Player p, int blockX, int blockY, int blockZ, BlockEntityType<?> type);
|
||||
boolean isPlayerPrivalegedToPerformAction(Player p);
|
||||
|
||||
boolean isPlayerPrivilegedToPerformAction(Player p);
|
||||
}
|
||||
|
||||
@@ -19,17 +19,12 @@
|
||||
|
||||
package de.steamwar.techhider;
|
||||
|
||||
import de.steamwar.Reflection;
|
||||
import net.minecraft.core.IdMapper;
|
||||
import net.minecraft.core.registries.BuiltInRegistries;
|
||||
import net.minecraft.world.level.block.Block;
|
||||
import net.minecraft.world.level.block.state.BlockState;
|
||||
import net.minecraft.world.level.material.FluidState;
|
||||
import net.minecraft.world.level.material.Fluids;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.Registry;
|
||||
import org.bukkit.block.data.BlockData;
|
||||
import org.bukkit.block.data.Waterlogged;
|
||||
import org.bukkit.craftbukkit.util.CraftMagicNumbers;
|
||||
|
||||
import java.util.HashSet;
|
||||
|
||||
@@ -22,9 +22,6 @@ package de.steamwar.techhider;
|
||||
import de.steamwar.Reflection;
|
||||
import io.netty.buffer.ByteBuf;
|
||||
import io.netty.buffer.Unpooled;
|
||||
import it.unimi.dsi.fastutil.ints.Int2IntMap;
|
||||
import it.unimi.dsi.fastutil.ints.Int2IntOpenHashMap;
|
||||
import it.unimi.dsi.fastutil.ints.IntArrayList;
|
||||
import net.minecraft.core.SectionPos;
|
||||
import net.minecraft.network.protocol.game.ClientboundLevelChunkPacketData;
|
||||
import net.minecraft.network.protocol.game.ClientboundLevelChunkWithLightPacket;
|
||||
@@ -34,10 +31,9 @@ import net.minecraft.world.level.block.entity.BlockEntityType;
|
||||
import net.minecraft.world.level.block.state.BlockState;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.List;
|
||||
import java.util.function.UnaryOperator;
|
||||
|
||||
|
||||
public class ChunkHider {
|
||||
private static final UnaryOperator<Object> chunkPacketShallowCloner = ProtocolUtils.shallowCloneGenerator(ClientboundLevelChunkWithLightPacket.class);
|
||||
private static final UnaryOperator<Object> chunkDataShallowCloner = ProtocolUtils.shallowCloneGenerator(ClientboundLevelChunkPacketData.class);
|
||||
@@ -54,18 +50,16 @@ public class ChunkHider {
|
||||
private final int BLOCKS_PER_SECTION = 4096;
|
||||
private final int BIOMES_PER_SECTION = 64;
|
||||
|
||||
private final byte BITS_PER_LONG = Long.SIZE;
|
||||
|
||||
private final int blockIdUsedForHiding;
|
||||
private final AccessPrivilegeProvider accessPrivilegeProvider;
|
||||
|
||||
public ChunkHider(Block blockUsedForObfuscation, AccessPrivilegeProvider accessPrivilegeProvider) {
|
||||
blockIdUsedForHiding = Block.BLOCK_STATE_REGISTRY.getId(blockUsedForObfuscation.defaultBlockState());
|
||||
blockIdUsedForHiding = Block.BLOCK_STATE_REGISTRY.getId(blockUsedForObfuscation.defaultBlockState());
|
||||
this.accessPrivilegeProvider = accessPrivilegeProvider;
|
||||
}
|
||||
|
||||
private int getLongsRequiredToEncodeEntries(int bitsPerEntry, int entryCount) {
|
||||
int entriesPerLong = BITS_PER_LONG / bitsPerEntry;
|
||||
int entriesPerLong = Long.SIZE / bitsPerEntry;
|
||||
int dataLengthAsLongCount = (entryCount + entriesPerLong - 1) / entriesPerLong;
|
||||
|
||||
return dataLengthAsLongCount;
|
||||
@@ -75,7 +69,7 @@ public class ChunkHider {
|
||||
int dataLengthAsLongCount = getLongsRequiredToEncodeEntries(bitsPerEntry, entryCount);
|
||||
long[] dataArray = new long[dataLengthAsLongCount];
|
||||
|
||||
for(int i = 0; i < dataLengthAsLongCount; i++){
|
||||
for (int i = 0; i < dataLengthAsLongCount; i++) {
|
||||
dataArray[i] = dataSource.readLong();
|
||||
}
|
||||
|
||||
@@ -98,22 +92,21 @@ public class ChunkHider {
|
||||
|
||||
byte bitsPerBlock = in.readByte();
|
||||
|
||||
if(bitsPerBlock == 0) {
|
||||
if (bitsPerBlock == 0) {
|
||||
int sectionBlockId = ProtocolUtils.readVarInt(in);
|
||||
|
||||
out.writeShort(blockCount);
|
||||
out.writeByte(bitsPerBlock);
|
||||
ProtocolUtils.writeVarInt(out, sectionBlockId);
|
||||
}
|
||||
else if (bitsPerBlock <= BIT_PER_BLOCK_INDIRECTION_LIMIT) {
|
||||
} else if (bitsPerBlock <= BIT_PER_BLOCK_INDIRECTION_LIMIT) {
|
||||
int palletLength = ProtocolUtils.readVarInt(in);
|
||||
int[] pallet = ProtocolUtils.readVarIntArray(in, palletLength);
|
||||
|
||||
long[] rawData = readSectionDataFromBuffer(in, bitsPerBlock, BLOCKS_PER_SECTION);
|
||||
long[] rawData = readSectionDataFromBuffer(in, bitsPerBlock, BLOCKS_PER_SECTION);
|
||||
SimpleBitStorage data = new SimpleBitStorage(bitsPerBlock, BLOCKS_PER_SECTION, rawData);
|
||||
|
||||
int[] resolvedData = new int[BLOCKS_PER_SECTION];
|
||||
for(int i = 0; i < BLOCKS_PER_SECTION; i++){
|
||||
for (int i = 0; i < BLOCKS_PER_SECTION; i++) {
|
||||
int palletReference = data.get(i);
|
||||
resolvedData[i] = pallet[palletReference];
|
||||
}
|
||||
@@ -125,7 +118,7 @@ public class ChunkHider {
|
||||
|
||||
out.writeShort(blockCount);
|
||||
out.writeByte(15);
|
||||
for(long rawDataSegment : reEncodedData) {
|
||||
for (long rawDataSegment : reEncodedData) {
|
||||
out.writeLong(rawDataSegment);
|
||||
}
|
||||
/*
|
||||
@@ -158,9 +151,8 @@ public class ChunkHider {
|
||||
out.writeLong(rawDataSegment);
|
||||
}*/
|
||||
|
||||
}
|
||||
else {
|
||||
long[] rawData = readSectionDataFromBuffer(in, bitsPerBlock, BLOCKS_PER_SECTION);
|
||||
} else {
|
||||
long[] rawData = readSectionDataFromBuffer(in, bitsPerBlock, BLOCKS_PER_SECTION);
|
||||
|
||||
int[] blockData = resolveDirectBlockDataArray(rawData, bitsPerBlock);
|
||||
|
||||
@@ -171,7 +163,7 @@ public class ChunkHider {
|
||||
|
||||
out.writeShort(blockCount);
|
||||
out.writeByte(15);
|
||||
for(long rawDataSegment : reEncodedData) {
|
||||
for (long rawDataSegment : reEncodedData) {
|
||||
out.writeLong(rawDataSegment);
|
||||
}
|
||||
}
|
||||
@@ -205,15 +197,13 @@ public class ChunkHider {
|
||||
int worldZ = sectionZ + (SECTION_SPAN_SIZE * chunkZ);
|
||||
|
||||
int blockId = blockDataArray[blockDataIndex];
|
||||
BlockState blockState = Block.BLOCK_STATE_REGISTRY.byId(blockId);
|
||||
BlockState blockState = Block.BLOCK_STATE_REGISTRY.byId(blockId);
|
||||
Block block = blockState.getBlock();
|
||||
|
||||
|
||||
|
||||
if(accessPrivilegeProvider.isPlayerPrivilegedToAccessPosition(player, worldX, worldY, worldZ) && accessPrivilegeProvider.isPlayerPrivilegedToAccessBlock(player, worldX, worldY, worldZ, block)) {
|
||||
if (accessPrivilegeProvider.isPlayerPrivilegedToAccessPosition(player, worldX, worldY, worldZ) && accessPrivilegeProvider.isPlayerPrivilegedToAccessBlock(player, worldX, worldY, worldZ, block)) {
|
||||
obfuscatedData[blockDataIndex] = blockId;
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
obfuscatedData[blockDataIndex] = blockIdUsedForHiding;
|
||||
}
|
||||
}
|
||||
@@ -227,7 +217,7 @@ public class ChunkHider {
|
||||
SimpleBitStorage data = new SimpleBitStorage(bitsPerBlock, BLOCKS_PER_SECTION, rawDataArray);
|
||||
|
||||
int[] resolvedData = new int[BLOCKS_PER_SECTION];
|
||||
for(int i = 0; i < BLOCKS_PER_SECTION; i++){
|
||||
for (int i = 0; i < BLOCKS_PER_SECTION; i++) {
|
||||
resolvedData[i] = data.get(i);
|
||||
}
|
||||
|
||||
@@ -238,7 +228,7 @@ public class ChunkHider {
|
||||
int longsRequiredToEncodeData = getLongsRequiredToEncodeEntries(15, blockDataArray.length);
|
||||
|
||||
SimpleBitStorage reEncodedData = new SimpleBitStorage(15, BLOCKS_PER_SECTION, new long[longsRequiredToEncodeData]);
|
||||
for(int i = 0; i < blockDataArray.length; i++) {
|
||||
for (int i = 0; i < blockDataArray.length; i++) {
|
||||
int blockId = blockDataArray[i];
|
||||
|
||||
reEncodedData.set(i, blockId);
|
||||
@@ -256,7 +246,7 @@ public class ChunkHider {
|
||||
|
||||
levelChunkPacketDataField.set(clonedPacket, clonedPacketChunkData);
|
||||
|
||||
return clonedPacket;
|
||||
return clonedPacket;
|
||||
}
|
||||
|
||||
|
||||
@@ -265,6 +255,7 @@ public class ChunkHider {
|
||||
private static final Reflection.Field<BlockEntityType> blockEntityInfoTypeField = Reflection.getField(blockEntitiyInfoClass, BlockEntityType.class, 0);
|
||||
private static final Reflection.Field<Integer> packedXZField = Reflection.getField(blockEntitiyInfoClass, int.class, 0);
|
||||
private static final Reflection.Field<Integer> yField = Reflection.getField(blockEntitiyInfoClass, int.class, 1);
|
||||
|
||||
private List<Object> filterBlockEntities(Player player, List<Object> blockEntities) {
|
||||
return blockEntities.stream()
|
||||
.filter((blockEntityInfo) -> {
|
||||
@@ -280,33 +271,30 @@ public class ChunkHider {
|
||||
}).toList();
|
||||
}
|
||||
|
||||
private void copyOverSectionBiomeData(ByteBuf oldData, ByteBuf newData){
|
||||
private void copyOverSectionBiomeData(ByteBuf oldData, ByteBuf newData) {
|
||||
short bitsPerBiome = oldData.readByte();
|
||||
newData.writeByte(bitsPerBiome);
|
||||
if(bitsPerBiome == 0) {
|
||||
if (bitsPerBiome == 0) {
|
||||
int sectionBiomeId = ProtocolUtils.readVarInt(oldData);
|
||||
ProtocolUtils.writeVarInt(newData, sectionBiomeId);
|
||||
}
|
||||
else if(bitsPerBiome <= BIT_PER_BIOME_INDIRECTION_LIMIT) {
|
||||
} else if (bitsPerBiome <= BIT_PER_BIOME_INDIRECTION_LIMIT) {
|
||||
int palletLength = ProtocolUtils.readVarInt(oldData);
|
||||
ProtocolUtils.writeVarInt(newData, palletLength);
|
||||
|
||||
for(int i = 0; i < palletLength; i++) {
|
||||
for (int i = 0; i < palletLength; i++) {
|
||||
int palletEntry = ProtocolUtils.readVarInt(oldData);
|
||||
ProtocolUtils.writeVarInt(newData, palletEntry);
|
||||
}
|
||||
|
||||
long[] rawData = readSectionDataFromBuffer(oldData, bitsPerBiome, BIOMES_PER_SECTION);
|
||||
for(long rawDataSegment : rawData ) {
|
||||
long[] rawData = readSectionDataFromBuffer(oldData, bitsPerBiome, BIOMES_PER_SECTION);
|
||||
for (long rawDataSegment : rawData) {
|
||||
newData.writeLong(rawDataSegment);
|
||||
}
|
||||
} else {
|
||||
long[] rawData = readSectionDataFromBuffer(oldData, bitsPerBiome, BIOMES_PER_SECTION);
|
||||
for (long rawDataSegment : rawData) {
|
||||
newData.writeLong(rawDataSegment);
|
||||
}
|
||||
}
|
||||
else {
|
||||
long[] rawData = readSectionDataFromBuffer(oldData, bitsPerBiome, BIOMES_PER_SECTION);
|
||||
for(long rawDataSegment : rawData ) {
|
||||
newData.writeLong(rawDataSegment);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -143,7 +143,7 @@ public class ProtocolUtils {
|
||||
public static int[] readVarIntArray(ByteBuf buffer, int length) {
|
||||
int[] array = new int[length];
|
||||
|
||||
for(int i = 0; i < length; i++) {
|
||||
for (int i = 0; i < length; i++) {
|
||||
array[i] = readVarInt(buffer);
|
||||
}
|
||||
|
||||
@@ -162,8 +162,8 @@ public class ProtocolUtils {
|
||||
} while (value != 0);
|
||||
}
|
||||
|
||||
public static void writeVarIntArray(ByteBuf buf, int[] values){
|
||||
for(int varInt : values) {
|
||||
public static void writeVarIntArray(ByteBuf buf, int[] values) {
|
||||
for (int varInt : values) {
|
||||
writeVarInt(buf, varInt);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,34 +0,0 @@
|
||||
/*
|
||||
* 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/>.
|
||||
*/
|
||||
|
||||
package de.steamwar.techhider;
|
||||
|
||||
import de.steamwar.Reflection;
|
||||
import net.minecraft.core.SectionPos;
|
||||
import net.minecraft.world.level.block.entity.BlockEntityType;
|
||||
import net.minecraft.world.level.block.entity.SignBlockEntity;
|
||||
import net.minecraft.world.level.block.state.BlockState;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.function.BiFunction;
|
||||
|
||||
public class ProtocolWrapper {
|
||||
public static final ProtocolWrapper impl = new ProtocolWrapper();
|
||||
}
|
||||
@@ -25,10 +25,6 @@ import it.unimi.dsi.fastutil.ints.IntArrayList;
|
||||
import it.unimi.dsi.fastutil.ints.IntList;
|
||||
import it.unimi.dsi.fastutil.shorts.ShortArraySet;
|
||||
import it.unimi.dsi.fastutil.shorts.ShortSets;
|
||||
import net.minecraft.network.protocol.game.*;
|
||||
import net.minecraft.world.level.block.entity.BlockEntityType;
|
||||
import net.minecraft.world.phys.Vec3;
|
||||
import org.bukkit.entity.Player;
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.core.SectionPos;
|
||||
import net.minecraft.network.PacketListener;
|
||||
@@ -41,13 +37,11 @@ import net.minecraft.network.protocol.configuration.ClientboundUpdateEnabledFeat
|
||||
import net.minecraft.network.protocol.cookie.ClientboundCookieRequestPacket;
|
||||
import net.minecraft.network.protocol.game.*;
|
||||
import net.minecraft.network.protocol.login.*;
|
||||
import net.minecraft.network.protocol.login.ClientboundCustomQueryPacket;
|
||||
import net.minecraft.network.protocol.login.ClientboundHelloPacket;
|
||||
import net.minecraft.network.protocol.login.ClientboundLoginCompressionPacket;
|
||||
import net.minecraft.network.protocol.login.ClientboundLoginDisconnectPacket;
|
||||
import net.minecraft.network.protocol.login.ClientboundLoginFinishedPacket;
|
||||
import net.minecraft.world.level.block.Block;
|
||||
import net.minecraft.world.level.block.entity.BlockEntityType;
|
||||
import net.minecraft.world.level.block.state.BlockState;
|
||||
import net.minecraft.world.phys.Vec3;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.function.BiFunction;
|
||||
@@ -59,20 +53,21 @@ import java.util.function.ToIntFunction;
|
||||
* any packet must be explicitly whitelisted or processed in a
|
||||
* way that is also compliant with the principle of default-deny.
|
||||
*/
|
||||
public abstract class TechHider implements AccessPrivilegeProvider {
|
||||
public class TechHider {
|
||||
private final Set<Class<?>> bypassingPackets;
|
||||
private final Map<Class<? extends Packet<? extends PacketListener>>, BiFunction<Player, Packet<? extends PacketListener>, Packet<? extends PacketListener>>> packetProcessors;
|
||||
|
||||
private final Block blockUsedForObfuscation;
|
||||
private final BlockState blockStateUsedForObfuscation;
|
||||
private final ChunkHider chunkHider;
|
||||
|
||||
private final AccessPrivilegeProvider privilegeProvider;
|
||||
|
||||
// TODO handle packet bundle
|
||||
protected TechHider(Block blockUsedForObfuscation) {
|
||||
this.blockUsedForObfuscation = blockUsedForObfuscation;
|
||||
public TechHider(Block blockUsedForObfuscation, AccessPrivilegeProvider privilegeProvider) {
|
||||
this.blockStateUsedForObfuscation = blockUsedForObfuscation.defaultBlockState();
|
||||
|
||||
this.chunkHider = new ChunkHider(blockUsedForObfuscation, this);
|
||||
this.chunkHider = new ChunkHider(blockUsedForObfuscation, privilegeProvider);
|
||||
this.privilegeProvider = privilegeProvider;
|
||||
|
||||
this.bypassingPackets = new HashSet<>(List.of(
|
||||
// --- 5.1.x Login Protocol ---
|
||||
@@ -84,8 +79,7 @@ public abstract class TechHider implements AccessPrivilegeProvider {
|
||||
ClientboundCookieRequestPacket.class, // 5.1.6 Cookie Request
|
||||
|
||||
// --- 6.1.x Configuration Protocol ---
|
||||
ClientboundSelectKnownPacks.class,
|
||||
ClientboundCustomPayloadPacket.class, // 6.1.2 Clientbound Plugin Message
|
||||
ClientboundSelectKnownPacks.class, ClientboundCustomPayloadPacket.class, // 6.1.2 Clientbound Plugin Message
|
||||
ClientboundFinishConfigurationPacket.class, // 6.1.4 Finish Configuration
|
||||
ClientboundKeepAlivePacket.class, // 6.1.5 Clientbound Keep Alive
|
||||
ClientboundPingPacket.class, // 6.1.6 Ping
|
||||
@@ -98,7 +92,7 @@ public abstract class TechHider implements AccessPrivilegeProvider {
|
||||
ClientboundCustomReportDetailsPacket.class, // 6.1.16 Custom Report Details
|
||||
ClientboundServerLinksPacket.class, // 6.1.17 Server Links
|
||||
ClientboundSystemChatPacket.class, // 6.1.18/19 Dialogs are often handled via System Chat or Custom
|
||||
// Payloads
|
||||
// Payloads
|
||||
ClientboundServerDataPacket.class, // 6.1.20 Code of Conduct is usually in Server Data
|
||||
|
||||
// --- 7.1.x Play Protocol ---
|
||||
@@ -237,7 +231,7 @@ public abstract class TechHider implements AccessPrivilegeProvider {
|
||||
// 7.1.134 Projectile Power: projectile/entity signal.
|
||||
processors.put(ClientboundProjectilePowerPacket.class, this.buildEntityPacketProcessor(ClientboundProjectilePowerPacket::getId));
|
||||
// 7.1.123 Pickup Item: item/entity ids and pickup activity.
|
||||
processors.put(ClientboundTakeItemEntityPacket.class, this.buildEntityPacketProcessor(ClientboundTakeItemEntityPacket::getItemId));
|
||||
processors.put(ClientboundTakeItemEntityPacket.class, this.buildEntityPacketProcessor(ClientboundTakeItemEntityPacket::getItemId));
|
||||
// 7.1.67 Combat Death: entity/player ids and death message context.
|
||||
processors.put(ClientboundPlayerCombatKillPacket.class, this.buildEntityPacketProcessor(ClientboundPlayerCombatKillPacket::playerId));
|
||||
// 7.1.52/53/55 Update Entity Position/Rotation: entity id and movement signal.
|
||||
@@ -305,51 +299,50 @@ public abstract class TechHider implements AccessPrivilegeProvider {
|
||||
int blockZ = (int) pos.z;
|
||||
|
||||
|
||||
return proccessPositionBasedPacket(p, blockX, blockY, blockZ, packet);
|
||||
return proccessPositionBasedPacket(p, blockX, blockY, blockZ, packet);
|
||||
});
|
||||
|
||||
this.packetProcessors = processors;
|
||||
|
||||
TinyProtocol.instance.addGlobalClientboundFilter((player, rawPacket) -> {
|
||||
if(rawPacket instanceof ClientboundBundlePacket bundlePacket) {
|
||||
List<Packet<? super ClientGamePacketListener>> processedPackets = new ArrayList<>();
|
||||
try {
|
||||
if (rawPacket instanceof ClientboundBundlePacket bundlePacket) {
|
||||
List<Packet<? super ClientGamePacketListener>> processedPackets = new ArrayList<>();
|
||||
|
||||
for(Packet<? super ClientGamePacketListener> packet : bundlePacket.subPackets()) {
|
||||
Packet<? super ClientGamePacketListener> processedPacket = (Packet<? super ClientGamePacketListener>) processPacket(player, packet);
|
||||
for (Packet<? super ClientGamePacketListener> packet : bundlePacket.subPackets()) {
|
||||
Packet<? super ClientGamePacketListener> processedPacket = (Packet<? super ClientGamePacketListener>) processPacket(player, packet);
|
||||
|
||||
if(processedPacket != null) {
|
||||
processedPackets.add(processedPacket);
|
||||
if (processedPacket != null) {
|
||||
processedPackets.add(processedPacket);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return new ClientboundBundlePacket(processedPackets);
|
||||
}
|
||||
else if(rawPacket instanceof Packet) {
|
||||
return processPacket(player, (Packet<?>) rawPacket);
|
||||
}
|
||||
else {
|
||||
return new ClientboundBundlePacket(processedPackets);
|
||||
} else {
|
||||
return processPacket(player, rawPacket);
|
||||
}
|
||||
} catch (Throwable t) {
|
||||
t.printStackTrace();
|
||||
return null;
|
||||
}
|
||||
});
|
||||
|
||||
TinyProtocol.instance.addFilter(ServerboundUseItemOnPacket.class, (p, packet) -> isPlayerPrivalegedToPerformAction(p) ? packet : null);
|
||||
TinyProtocol.instance.addFilter(ServerboundInteractPacket.class, (p, packet) -> isPlayerPrivalegedToPerformAction(p) ? packet : null);
|
||||
TinyProtocol.instance.addFilter(ServerboundUseItemOnPacket.class, (p, packet) -> privilegeProvider.isPlayerPrivilegedToPerformAction(p) ? packet : null);
|
||||
TinyProtocol.instance.addFilter(ServerboundInteractPacket.class, (p, packet) -> privilegeProvider.isPlayerPrivilegedToPerformAction(p) ? packet : null);
|
||||
}
|
||||
|
||||
private Packet<?> processPacket(Player player, Packet<?> packet) {
|
||||
if(bypassingPackets.contains(packet.getClass())) {
|
||||
if (bypassingPackets.contains(packet.getClass())) {
|
||||
return packet;
|
||||
}
|
||||
else if(packetProcessors.containsKey(packet.getClass())) {
|
||||
return packetProcessors.get(packet.getClass()).apply(player, (Packet<? extends PacketListener>) packet);
|
||||
}
|
||||
else {
|
||||
} else if (packetProcessors.containsKey(packet.getClass())) {
|
||||
return packetProcessors.get(packet.getClass()).apply(player, packet);
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
private Packet<? extends PacketListener> processAddEntityPacket(Player player, ClientboundAddEntityPacket packet) {
|
||||
if(isPlayerPrivilegedToAccessEntity(player, packet.getId()) && isPlayerPrivilegedToAccessPosition(player, (int) packet.getX(), (int) packet.getY(), (int) packet.getZ())) {
|
||||
if (privilegeProvider.isPlayerPrivilegedToAccessEntity(player, packet.getId()) && privilegeProvider.isPlayerPrivilegedToAccessPosition(player, (int) packet.getX(), (int) packet.getY(), (int) packet.getZ())) {
|
||||
return packet;
|
||||
} else {
|
||||
return null;
|
||||
@@ -357,13 +350,14 @@ public abstract class TechHider implements AccessPrivilegeProvider {
|
||||
}
|
||||
|
||||
private Packet<? extends PacketListener> processEntityPacket(Player player, int entityId, Packet<? extends PacketListener> packet) {
|
||||
if(isPlayerPrivilegedToAccessEntity(player, entityId)) {
|
||||
if (privilegeProvider.isPlayerPrivilegedToAccessEntity(player, entityId)) {
|
||||
return packet;
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
private <TTargetPacket extends Packet<?>> BiFunction<Player, Packet<? extends PacketListener>, Packet<? extends PacketListener>> buildEntityPacketProcessor(ToIntFunction<TTargetPacket> entityIdExtractor) {
|
||||
|
||||
private <TTargetPacket extends Packet<?>> BiFunction<Player, Packet<? extends PacketListener>, Packet<? extends PacketListener>> buildEntityPacketProcessor(ToIntFunction<TTargetPacket> entityIdExtractor) {
|
||||
return (p, rawPacket) -> {
|
||||
TTargetPacket packet = (TTargetPacket) rawPacket;
|
||||
return processEntityPacket(p, entityIdExtractor.applyAsInt(packet), packet);
|
||||
@@ -371,25 +365,25 @@ public abstract class TechHider implements AccessPrivilegeProvider {
|
||||
}
|
||||
|
||||
private final Reflection.Field<Integer> moveEntityPacketEntityIdField = Reflection.getField(ClientboundMoveEntityPacket.class, int.class, 0);
|
||||
|
||||
private Packet<?> processMoveEntityPacket(Player player, ClientboundMoveEntityPacket packet) {
|
||||
int entityId = moveEntityPacketEntityIdField.get(packet);
|
||||
|
||||
if(isPlayerPrivilegedToAccessEntity(player, entityId)) {
|
||||
if (privilegeProvider.isPlayerPrivilegedToAccessEntity(player, entityId)) {
|
||||
return packet;
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
private final Reflection.Field<Integer> rotateHeadPacketEntityIdField = Reflection.getField(ClientboundRotateHeadPacket.class, int.class, 0);
|
||||
private final Reflection.Field<Integer> rotateHeadPacketEntityIdField = Reflection.getField(ClientboundRotateHeadPacket.class, int.class, 0);
|
||||
|
||||
private Packet<?> processRotateHeadPacket(Player player, ClientboundRotateHeadPacket packet) {
|
||||
int entityId = rotateHeadPacketEntityIdField.get(packet);
|
||||
|
||||
if(isPlayerPrivilegedToAccessEntity(player, entityId)) {
|
||||
if (privilegeProvider.isPlayerPrivilegedToAccessEntity(player, entityId)) {
|
||||
return packet;
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -397,9 +391,7 @@ public abstract class TechHider implements AccessPrivilegeProvider {
|
||||
private Packet<?> processRemoveEntitiesPacket(Player player, ClientboundRemoveEntitiesPacket packet) {
|
||||
IntList entityIdsToRemove = packet.getEntityIds();
|
||||
|
||||
IntList filteredEntitiesToRemove = entityIdsToRemove.intStream()
|
||||
.filter((id) -> isPlayerPrivilegedToAccessEntity(player, id))
|
||||
.collect(IntArrayList::new, IntList::add, IntList::addAll);
|
||||
IntList filteredEntitiesToRemove = entityIdsToRemove.intStream().filter((id) -> privilegeProvider.isPlayerPrivilegedToAccessEntity(player, id)).collect(IntArrayList::new, IntList::add, IntList::addAll);
|
||||
|
||||
return new ClientboundRemoveEntitiesPacket(filteredEntitiesToRemove);
|
||||
}
|
||||
@@ -408,10 +400,9 @@ public abstract class TechHider implements AccessPrivilegeProvider {
|
||||
int fromEntityId = packet.getSourceId();
|
||||
int toEntityId = packet.getDestId();
|
||||
|
||||
if(isPlayerPrivilegedToAccessEntity(player, fromEntityId) && isPlayerPrivilegedToAccessEntity(player, toEntityId)) {
|
||||
if (privilegeProvider.isPlayerPrivilegedToAccessEntity(player, fromEntityId) && privilegeProvider.isPlayerPrivilegedToAccessEntity(player, toEntityId)) {
|
||||
return packet;
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -423,7 +414,7 @@ public abstract class TechHider implements AccessPrivilegeProvider {
|
||||
int blockY = blockPos.getY();
|
||||
int blockZ = blockPos.getZ();
|
||||
|
||||
if (isPlayerPrivilegedToAccessPosition(player, blockX, blockY, blockZ) && isPlayerPrivilegedToAccessBlock(player, blockX, blockY, blockZ, block)) {
|
||||
if (privilegeProvider.isPlayerPrivilegedToAccessPosition(player, blockX, blockY, blockZ) && privilegeProvider.isPlayerPrivilegedToAccessBlock(player, blockX, blockY, blockZ, block)) {
|
||||
return packet;
|
||||
} else {
|
||||
return null;
|
||||
@@ -437,9 +428,9 @@ public abstract class TechHider implements AccessPrivilegeProvider {
|
||||
int blockY = blockPos.getY();
|
||||
int blockZ = blockPos.getZ();
|
||||
|
||||
if (isPlayerPrivilegedToAccessPosition(player, blockX, blockY, blockZ) && isPlayerPrivilegedToAccessBlock(player, blockX, blockY, blockZ, block)) {
|
||||
if (privilegeProvider.isPlayerPrivilegedToAccessPosition(player, blockX, blockY, blockZ) && privilegeProvider.isPlayerPrivilegedToAccessBlock(player, blockX, blockY, blockZ, block)) {
|
||||
return packet;
|
||||
} else if(isPlayerPrivilegedToAccessPosition(player, blockX, blockY, blockZ)) {
|
||||
} else if (privilegeProvider.isPlayerPrivilegedToAccessPosition(player, blockX, blockY, blockZ)) {
|
||||
return new ClientboundBlockUpdatePacket(blockPos, blockStateUsedForObfuscation);
|
||||
} else {
|
||||
return null;
|
||||
@@ -453,7 +444,7 @@ public abstract class TechHider implements AccessPrivilegeProvider {
|
||||
int blockY = blockPos.getY();
|
||||
int blockZ = blockPos.getZ();
|
||||
|
||||
if (isPlayerPrivilegedToAccessPosition(player, blockX, blockY, blockZ) && isPlayerPrivilegedToAccessBlockEntity(player, blockX, blockY, blockZ, blockEntityType)) {
|
||||
if (privilegeProvider.isPlayerPrivilegedToAccessPosition(player, blockX, blockY, blockZ) && privilegeProvider.isPlayerPrivilegedToAccessBlockEntity(player, blockX, blockY, blockZ, blockEntityType)) {
|
||||
return packet;
|
||||
} else {
|
||||
return null;
|
||||
@@ -464,10 +455,9 @@ public abstract class TechHider implements AccessPrivilegeProvider {
|
||||
BlockPos blockPos = packet.getPos();
|
||||
int entityBreakingBlockId = packet.getId();
|
||||
|
||||
if(isPlayerPrivilegedToAccessEntity(player, entityBreakingBlockId) && isPlayerPrivilegedToAccessPosition(player, blockPos.getX(), blockPos.getY(), blockPos.getZ())) {
|
||||
if (privilegeProvider.isPlayerPrivilegedToAccessEntity(player, entityBreakingBlockId) && privilegeProvider.isPlayerPrivilegedToAccessPosition(player, blockPos.getX(), blockPos.getY(), blockPos.getZ())) {
|
||||
return packet;
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -475,6 +465,7 @@ public abstract class TechHider implements AccessPrivilegeProvider {
|
||||
private final Reflection.Field<SectionPos> sectionPosField = Reflection.getField(ClientboundSectionBlocksUpdatePacket.class, SectionPos.class, 0);
|
||||
private final Reflection.Field<short[]> oldPosField = Reflection.getField(ClientboundSectionBlocksUpdatePacket.class, short[].class, 0);
|
||||
private final Reflection.Field<BlockState[]> oldStatesField = Reflection.getField(ClientboundSectionBlocksUpdatePacket.class, BlockState[].class, 0);
|
||||
|
||||
private ClientboundSectionBlocksUpdatePacket processSectionUpdate(Player p, ClientboundSectionBlocksUpdatePacket packet) {
|
||||
SectionPos sectionPos = sectionPosField.get(packet);
|
||||
short[] oldPos = oldPosField.get(packet);
|
||||
@@ -493,11 +484,11 @@ public abstract class TechHider implements AccessPrivilegeProvider {
|
||||
int worldY = sectionPos.relativeToBlockY(posShort);
|
||||
int worldZ = sectionPos.relativeToBlockZ(posShort);
|
||||
|
||||
if (isPlayerPrivilegedToAccessPosition(p, worldX, worldY, worldZ) && isPlayerPrivilegedToAccessBlock(p, worldX, worldY, worldZ, block)) {
|
||||
if (privilegeProvider.isPlayerPrivilegedToAccessPosition(p, worldX, worldY, worldZ) && privilegeProvider.isPlayerPrivilegedToAccessBlock(p, worldX, worldY, worldZ, block)) {
|
||||
// TODO statefull !!!
|
||||
filteredPos.add(posShort);
|
||||
filteredStates.add(state);
|
||||
} else if(isPlayerPrivilegedToAccessPosition(p, worldX, worldY, worldZ)){
|
||||
} else if (privilegeProvider.isPlayerPrivilegedToAccessPosition(p, worldX, worldY, worldZ)) {
|
||||
modified = true;
|
||||
filteredPos.add(posShort);
|
||||
filteredStates.add(blockStateUsedForObfuscation);
|
||||
@@ -518,11 +509,7 @@ public abstract class TechHider implements AccessPrivilegeProvider {
|
||||
|
||||
BlockState[] newStates = filteredStates.toArray(new BlockState[0]);
|
||||
|
||||
return new ClientboundSectionBlocksUpdatePacket(
|
||||
sectionPos,
|
||||
ShortSets.unmodifiable(new ShortArraySet(newPos)),
|
||||
newStates
|
||||
);
|
||||
return new ClientboundSectionBlocksUpdatePacket(sectionPos, ShortSets.unmodifiable(new ShortArraySet(newPos)), newStates);
|
||||
}
|
||||
|
||||
private Packet<?> processLevelParticlesPacket(Player player, ClientboundLevelParticlesPacket packet) {
|
||||
@@ -530,30 +517,29 @@ public abstract class TechHider implements AccessPrivilegeProvider {
|
||||
int blockY = (int) packet.getY();
|
||||
int blockZ = (int) packet.getZ();
|
||||
|
||||
if(isPlayerPrivilegedToAccessPosition(player, blockX, blockY, blockZ)) {
|
||||
return packet;
|
||||
}
|
||||
else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
private ClientboundLevelChunkWithLightPacket processChunkWithLight(Player p, ClientboundLevelChunkWithLightPacket packet) {
|
||||
if(isEveryonePrivilegedToAccessAllDataWithinChunk(packet.getX(), packet.getZ())) {
|
||||
return packet;
|
||||
}
|
||||
else {
|
||||
return chunkHider.processLevelChunkWithLightPacket(p, packet);
|
||||
}
|
||||
}
|
||||
|
||||
private Packet<? extends PacketListener> proccessPositionBasedPacket(Player player, int blockX, int blockY, int blockZ, Packet<? extends PacketListener> packet) {
|
||||
if(isPlayerPrivilegedToAccessPosition(player, blockX, blockY, blockZ)) {
|
||||
if (privilegeProvider.isPlayerPrivilegedToAccessPosition(player, blockX, blockY, blockZ)) {
|
||||
return packet;
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
private ClientboundLevelChunkWithLightPacket processChunkWithLight(Player p, ClientboundLevelChunkWithLightPacket packet) {
|
||||
if (privilegeProvider.isEveryonePrivilegedToAccessAllDataWithinChunk(packet.getX(), packet.getZ())) {
|
||||
return packet;
|
||||
} else {
|
||||
return chunkHider.processLevelChunkWithLightPacket(p, packet);
|
||||
}
|
||||
}
|
||||
|
||||
private Packet<? extends PacketListener> proccessPositionBasedPacket(Player player, int blockX, int blockY, int blockZ, Packet<? extends PacketListener> packet) {
|
||||
if (privilegeProvider.isPlayerPrivilegedToAccessPosition(player, blockX, blockY, blockZ)) {
|
||||
return packet;
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
private <TTargetPacket extends Packet<?>> BiFunction<Player, Packet<?>, Packet<?>> buildPositionBasedPacketProcessor(Function<TTargetPacket, BlockPos> positionExtractor) {
|
||||
return (p, rawPacket) -> {
|
||||
TTargetPacket packet = (TTargetPacket) rawPacket;
|
||||
@@ -565,12 +551,4 @@ public abstract class TechHider implements AccessPrivilegeProvider {
|
||||
return proccessPositionBasedPacket(p, blockX, blockY, blockZ, packet);
|
||||
};
|
||||
}
|
||||
|
||||
public abstract boolean isPlayerPrivilegedToAccessPosition(Player p, int blockX, int blockY, int blockZ);
|
||||
public abstract boolean isPlayerPrivilegedToAccessBlock(Player p, int blockX, int blockY, int blockZ, Block block);
|
||||
public abstract boolean isPlayerPrivilegedToAccessEntity(Player p, int entityId);
|
||||
public abstract boolean isEveryonePrivilegedToAccessAllDataWithinChunk(int chunkX, int chunkZ);
|
||||
public abstract boolean isPlayerPrivilegedToAccessBlockEntity(Player p, int blockX, int blockY, int blockZ, BlockEntityType<?> type);
|
||||
public abstract boolean isPlayerPrivalegedToPerformAction(Player p);
|
||||
|
||||
}
|
||||
|
||||
@@ -1,68 +0,0 @@
|
||||
/*
|
||||
* 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/>.
|
||||
*/
|
||||
|
||||
package de.steamwar.techhider.legacy;
|
||||
|
||||
import de.steamwar.Reflection;
|
||||
import net.minecraft.core.IdMapper;
|
||||
import net.minecraft.world.level.block.Block;
|
||||
import net.minecraft.world.level.block.state.BlockState;
|
||||
import net.minecraft.world.level.material.FluidState;
|
||||
import net.minecraft.world.level.material.Fluids;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.craftbukkit.util.CraftMagicNumbers;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
|
||||
public class BlockIds {
|
||||
public static final BlockIds impl = new BlockIds();
|
||||
|
||||
public int materialToId(Material material) {
|
||||
return getCombinedId(getBlock(material).defaultBlockState());
|
||||
}
|
||||
|
||||
private static final FluidState water = Fluids.WATER.getSource(false);
|
||||
private static final Iterable<BlockState> registryBlockId = (Iterable<BlockState>) Reflection.getField(TechHider.block, IdMapper.class, 0).get(null);
|
||||
|
||||
public Set<Integer> materialToAllIds(Material material) {
|
||||
Set<Integer> ids = new HashSet<>();
|
||||
for (BlockState data : getBlock(material).getStateDefinition().getPossibleStates()) {
|
||||
ids.add(getCombinedId(data));
|
||||
}
|
||||
|
||||
if (material == Material.WATER) {
|
||||
for (BlockState data : registryBlockId) {
|
||||
if (data.getFluidState() == water) {
|
||||
ids.add(getCombinedId(data));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return ids;
|
||||
}
|
||||
|
||||
private Block getBlock(Material material) {
|
||||
return CraftMagicNumbers.getBlock(material);
|
||||
}
|
||||
|
||||
public int getCombinedId(BlockState blockData) {
|
||||
return Block.getId(blockData);
|
||||
}
|
||||
}
|
||||
@@ -20,6 +20,7 @@
|
||||
package de.steamwar.techhider.legacy;
|
||||
|
||||
import de.steamwar.Reflection;
|
||||
import de.steamwar.techhider.ProtocolUtils;
|
||||
import io.netty.buffer.ByteBuf;
|
||||
import io.netty.buffer.Unpooled;
|
||||
import lombok.Getter;
|
||||
@@ -39,6 +40,7 @@ import java.util.function.BiFunction;
|
||||
import java.util.function.UnaryOperator;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@Deprecated
|
||||
public class ChunkHider {
|
||||
public static final ChunkHider impl = new ChunkHider();
|
||||
|
||||
|
||||
@@ -1,203 +0,0 @@
|
||||
/*
|
||||
* 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/>.
|
||||
*/
|
||||
|
||||
package de.steamwar.techhider.legacy;
|
||||
|
||||
import com.google.common.primitives.Bytes;
|
||||
import de.steamwar.Reflection;
|
||||
import io.netty.buffer.ByteBuf;
|
||||
|
||||
import java.lang.reflect.Array;
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.Modifier;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.function.BiConsumer;
|
||||
import java.util.function.BiFunction;
|
||||
import java.util.function.UnaryOperator;
|
||||
|
||||
public class ProtocolUtils {
|
||||
private ProtocolUtils() {
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
public static BiFunction<Object, UnaryOperator<Object>, Object> arrayCloneGenerator(Class<?> elementClass) {
|
||||
return (array, worker) -> {
|
||||
int length = Array.getLength(array);
|
||||
Object result = Array.newInstance(elementClass, length);
|
||||
|
||||
for (int i = 0; i < length; i++) {
|
||||
Array.set(result, i, worker.apply(Array.get(array, i)));
|
||||
}
|
||||
|
||||
return result;
|
||||
};
|
||||
}
|
||||
|
||||
public static UnaryOperator<Object> shallowCloneGenerator(Class<?> clazz) {
|
||||
BiConsumer<Object, Object> filler = shallowFill(clazz);
|
||||
|
||||
return source -> {
|
||||
Object clone = Reflection.newInstance(clazz);
|
||||
filler.accept(source, clone);
|
||||
return clone;
|
||||
};
|
||||
}
|
||||
|
||||
public static <T> UnaryOperator<T> shallowTypedCloneGenerator(Class<T> clazz) {
|
||||
BiConsumer<Object, Object> filler = shallowFill(clazz);
|
||||
|
||||
return source -> {
|
||||
Object clone = Reflection.newInstance(clazz);
|
||||
filler.accept(source, clone);
|
||||
return (T) clone;
|
||||
};
|
||||
}
|
||||
|
||||
private static BiConsumer<Object, Object> shallowFill(Class<?> clazz) {
|
||||
if (clazz == null) {
|
||||
return (source, clone) -> {
|
||||
};
|
||||
}
|
||||
|
||||
BiConsumer<Object, Object> superFiller = shallowFill(clazz.getSuperclass());
|
||||
|
||||
Field[] fds = clazz.getDeclaredFields();
|
||||
List<Field> fields = new ArrayList<>();
|
||||
for (Field field : fds) {
|
||||
if (Modifier.isStatic(field.getModifiers())) continue;
|
||||
|
||||
field.setAccessible(true);
|
||||
fields.add(field);
|
||||
}
|
||||
|
||||
return (source, clone) -> {
|
||||
superFiller.accept(source, clone);
|
||||
try {
|
||||
for (Field field : fields) {
|
||||
field.set(clone, field.get(source));
|
||||
}
|
||||
} catch (IllegalAccessException e) {
|
||||
throw new IllegalStateException("Could not set field", e);
|
||||
}
|
||||
|
||||
};
|
||||
}
|
||||
|
||||
public static int posToChunk(int c) {
|
||||
int chunk = c / 16;
|
||||
if (c < 0) chunk--;
|
||||
return chunk;
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
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 readVarInt(ByteBuf buf) {
|
||||
int numRead = 0;
|
||||
int result = 0;
|
||||
byte read;
|
||||
do {
|
||||
read = buf.readByte();
|
||||
int value = (read & 0b01111111);
|
||||
result |= (value << (7 * numRead));
|
||||
|
||||
if (++numRead > 5) throw new SecurityException("VarInt too long");
|
||||
} while ((read & 0b10000000) != 0);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
public static void writeVarInt(ByteBuf buf, int value) {
|
||||
do {
|
||||
int temp = 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;
|
||||
}
|
||||
buf.writeByte(temp);
|
||||
} while (value != 0);
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
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;
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
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);
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -29,6 +29,7 @@ import org.bukkit.entity.Player;
|
||||
import java.util.ArrayList;
|
||||
import java.util.function.BiFunction;
|
||||
|
||||
@Deprecated
|
||||
public class ProtocolWrapper {
|
||||
public static final ProtocolWrapper impl = new ProtocolWrapper();
|
||||
|
||||
@@ -88,8 +89,4 @@ public class ProtocolWrapper {
|
||||
public boolean unfilteredTileEntityDataAction(Object packet) {
|
||||
return tileEntityType.get(packet) != signType;
|
||||
}
|
||||
|
||||
public BiFunction<Player, Object, Object> blockBreakHiderGenerator(Class<?> blockBreakPacket, TechHider techHider) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -21,6 +21,8 @@ package de.steamwar.techhider.legacy;
|
||||
|
||||
import com.comphenix.tinyprotocol.TinyProtocol;
|
||||
import de.steamwar.Reflection;
|
||||
import de.steamwar.techhider.BlockIds;
|
||||
import de.steamwar.techhider.ProtocolUtils;
|
||||
import lombok.Getter;
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.core.Vec3i;
|
||||
@@ -39,6 +41,7 @@ import java.util.function.Function;
|
||||
import java.util.function.UnaryOperator;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@Deprecated
|
||||
public class TechHider {
|
||||
|
||||
public static final Class<?> blockPosition = BlockPos.class;
|
||||
@@ -87,7 +90,7 @@ public class TechHider {
|
||||
}
|
||||
|
||||
public void enable() {
|
||||
techhiders.forEach(TinyProtocol.instance::addFilter);
|
||||
techhiders.forEach((type, playerObjectBiFunction) -> TinyProtocol.instance.addFilter((Class) type, playerObjectBiFunction));
|
||||
}
|
||||
|
||||
public void disable() {
|
||||
|
||||
Reference in New Issue
Block a user