forked from SteamWar/SteamWar
Fix final formatting stuff
This commit is contained in:
@@ -37,6 +37,7 @@ import de.steamwar.fightsystem.states.StateDependentListener;
|
|||||||
import de.steamwar.fightsystem.states.StateDependentTask;
|
import de.steamwar.fightsystem.states.StateDependentTask;
|
||||||
import de.steamwar.fightsystem.utils.SWSound;
|
import de.steamwar.fightsystem.utils.SWSound;
|
||||||
import de.steamwar.linkage.Linked;
|
import de.steamwar.linkage.Linked;
|
||||||
|
import net.minecraft.network.protocol.Packet;
|
||||||
import net.minecraft.network.protocol.game.ServerboundPlayerActionPacket;
|
import net.minecraft.network.protocol.game.ServerboundPlayerActionPacket;
|
||||||
import net.minecraft.network.protocol.game.ServerboundUseItemPacket;
|
import net.minecraft.network.protocol.game.ServerboundUseItemPacket;
|
||||||
import net.minecraft.world.InteractionHand;
|
import net.minecraft.world.InteractionHand;
|
||||||
@@ -142,7 +143,7 @@ public class Recording implements Listener {
|
|||||||
GlobalRecorder.getInstance().entitySpeed(entity);
|
GlobalRecorder.getInstance().entitySpeed(entity);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static final Class<?> blockDigPacket = ServerboundPlayerActionPacket.class;
|
private static final Class<? extends Packet<?>> blockDigPacket = ServerboundPlayerActionPacket.class;
|
||||||
private static final Class<?> playerDigType = blockDigPacket.getDeclaredClasses()[0];
|
private static final Class<?> playerDigType = blockDigPacket.getDeclaredClasses()[0];
|
||||||
private static final Reflection.Field<?> blockDigType = Reflection.getField(blockDigPacket, playerDigType, 0);
|
private static final Reflection.Field<?> blockDigType = Reflection.getField(blockDigPacket, playerDigType, 0);
|
||||||
private static final Object releaseUseItem = playerDigType.getEnumConstants()[5];
|
private static final Object releaseUseItem = playerDigType.getEnumConstants()[5];
|
||||||
|
|||||||
+13
-19
@@ -22,7 +22,6 @@ package de.steamwar.fightsystem.utils;
|
|||||||
import de.steamwar.Reflection;
|
import de.steamwar.Reflection;
|
||||||
import de.steamwar.core.CraftbukkitWrapper;
|
import de.steamwar.core.CraftbukkitWrapper;
|
||||||
import de.steamwar.fightsystem.Config;
|
import de.steamwar.fightsystem.Config;
|
||||||
import de.steamwar.fightsystem.FightSystem;
|
|
||||||
import de.steamwar.fightsystem.events.BoardingEvent;
|
import de.steamwar.fightsystem.events.BoardingEvent;
|
||||||
import de.steamwar.fightsystem.events.TeamLeaveEvent;
|
import de.steamwar.fightsystem.events.TeamLeaveEvent;
|
||||||
import de.steamwar.fightsystem.events.TeamSpawnEvent;
|
import de.steamwar.fightsystem.events.TeamSpawnEvent;
|
||||||
@@ -31,6 +30,7 @@ import de.steamwar.fightsystem.fight.FightTeam;
|
|||||||
import de.steamwar.fightsystem.states.FightState;
|
import de.steamwar.fightsystem.states.FightState;
|
||||||
import de.steamwar.fightsystem.states.StateDependent;
|
import de.steamwar.fightsystem.states.StateDependent;
|
||||||
import de.steamwar.fightsystem.states.StateDependentListener;
|
import de.steamwar.fightsystem.states.StateDependentListener;
|
||||||
|
import de.steamwar.techhider.AccessPrivilegeProvider;
|
||||||
import de.steamwar.techhider.TechHider;
|
import de.steamwar.techhider.TechHider;
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
import net.minecraft.core.Holder;
|
import net.minecraft.core.Holder;
|
||||||
@@ -57,8 +57,6 @@ public class TechHiderWrapper extends StateDependent implements Listener {
|
|||||||
|
|
||||||
@Getter
|
@Getter
|
||||||
private final ConcurrentHashMap<Player, Region> hiddenRegion = new ConcurrentHashMap<>();
|
private final ConcurrentHashMap<Player, Region> hiddenRegion = new ConcurrentHashMap<>();
|
||||||
private final TechHider techHider;
|
|
||||||
|
|
||||||
|
|
||||||
public TechHiderWrapper(HullHider hullHider) {
|
public TechHiderWrapper(HullHider hullHider) {
|
||||||
super(ENABLED, FightState.All);
|
super(ENABLED, FightState.All);
|
||||||
@@ -80,7 +78,12 @@ public class TechHiderWrapper extends StateDependent implements Listener {
|
|||||||
})
|
})
|
||||||
.collect(Collectors.toUnmodifiableSet());
|
.collect(Collectors.toUnmodifiableSet());
|
||||||
|
|
||||||
techHider = new TechHider(CraftMagicNumbers.getBlock(Config.GameModeConfig.Techhider.ObfuscateWith)) {
|
new TechHider(CraftMagicNumbers.getBlock(Config.GameModeConfig.Techhider.ObfuscateWith), new AccessPrivilegeProvider() {
|
||||||
|
@Override
|
||||||
|
public boolean isEveryonePrivilegedToAccessAllDataWithinChunk(int chunkX, int chunkZ) {
|
||||||
|
return Fight.teams().stream().map(FightTeam::getExtendRegion).allMatch(region -> region.chunkOutside(chunkX, chunkZ));
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isPlayerPrivilegedToAccessPosition(Player p, int blockX, int blockY, int blockZ) {
|
public boolean isPlayerPrivilegedToAccessPosition(Player p, int blockX, int blockY, int blockZ) {
|
||||||
return !hullHider.isBlockHidden(p, blockX, blockY, blockZ);
|
return !hullHider.isBlockHidden(p, blockX, blockY, blockZ);
|
||||||
@@ -88,8 +91,7 @@ public class TechHiderWrapper extends StateDependent implements Listener {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isPlayerPrivilegedToAccessBlock(Player p, int blockX, int blockY, int blockZ, Block block) {
|
public boolean isPlayerPrivilegedToAccessBlock(Player p, int blockX, int blockY, int blockZ, Block block) {
|
||||||
Region hiddenRegion = getHiddenRegion(p);
|
return !getHiddenRegion(p).inRegion(blockX, blockY, blockZ) || !blocksToObfuscate.contains(block);
|
||||||
return !hiddenRegion.inRegion(blockX, blockY, blockZ) || !blocksToObfuscate.contains(block);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO will require entity tracking on the netty thread to prevent future race conditions
|
// TODO will require entity tracking on the netty thread to prevent future race conditions
|
||||||
@@ -99,28 +101,21 @@ public class TechHiderWrapper extends StateDependent implements Listener {
|
|||||||
|
|
||||||
if (nmsEntity != null) {
|
if (nmsEntity != null) {
|
||||||
return !hullHider.isBlockHidden(p, nmsEntity.getBlockX(), nmsEntity.getBlockY(), nmsEntity.getBlockZ());
|
return !hullHider.isBlockHidden(p, nmsEntity.getBlockX(), nmsEntity.getBlockY(), nmsEntity.getBlockZ());
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isPlayerPrivilegedToAccessBlockEntity(Player p, int blockX, int blockY, int blockZ, BlockEntityType<?> type) {
|
public boolean isPlayerPrivilegedToAccessBlockEntity(Player p, int blockX, int blockY, int blockZ, BlockEntityType<?> type) {
|
||||||
Region hiddenRegion = getHiddenRegion(p);
|
return !getHiddenRegion(p).inRegion(blockX, blockY, blockZ) || !blockEntityTypeToObfuscate.contains(type);
|
||||||
return !hiddenRegion.inRegion(blockX, blockY, blockZ) || !blockEntityTypeToObfuscate.contains(type);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isEveryonePrivilegedToAccessAllDataWithinChunk(int chunkX, int chunkZ) {
|
public boolean isPlayerPrivilegedToPerformAction(Player p) {
|
||||||
return Fight.teams().stream().map(FightTeam::getExtendRegion).allMatch(region -> region.chunkOutside(chunkX, chunkZ));
|
return p.getGameMode() != GameMode.SPECTATOR;
|
||||||
}
|
}
|
||||||
|
});
|
||||||
@Override
|
|
||||||
public boolean isPlayerPrivalegedToPerformAction(Player p) {
|
|
||||||
return !(p.getGameMode() == GameMode.SPECTATOR);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
new StateDependentListener(ENABLED, FightState.All, this);
|
new StateDependentListener(ENABLED, FightState.All, this);
|
||||||
register();
|
register();
|
||||||
@@ -128,7 +123,6 @@ public class TechHiderWrapper extends StateDependent implements Listener {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void enable() {
|
public void enable() {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -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);
|
packetFilters.computeIfAbsent(packetType, c -> new CopyOnWriteArrayList<>()).add((BiFunction) filter);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -235,8 +235,8 @@ public class TinyProtocol {
|
|||||||
packetFilters.getOrDefault(packetType, Collections.emptyList()).remove(filter);
|
packetFilters.getOrDefault(packetType, Collections.emptyList()).remove(filter);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void addGlobalClientboundFilter(BiFunction<Player, Object, Object> filter) {
|
public void addGlobalClientboundFilter(BiFunction<Player, Packet<?>, Object> filter) {
|
||||||
globalClientboundFilters.add(filter);
|
globalClientboundFilters.add((BiFunction) filter);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -24,9 +24,15 @@ import net.minecraft.world.level.block.entity.BlockEntityType;
|
|||||||
import org.bukkit.entity.Player;
|
import org.bukkit.entity.Player;
|
||||||
|
|
||||||
public interface AccessPrivilegeProvider {
|
public interface AccessPrivilegeProvider {
|
||||||
|
boolean isEveryonePrivilegedToAccessAllDataWithinChunk(int chunkX, int chunkZ);
|
||||||
|
|
||||||
boolean isPlayerPrivilegedToAccessPosition(Player p, int blockX, int blockY, int blockZ);
|
boolean isPlayerPrivilegedToAccessPosition(Player p, int blockX, int blockY, int blockZ);
|
||||||
|
|
||||||
boolean isPlayerPrivilegedToAccessBlock(Player p, int blockX, int blockY, int blockZ, Block block);
|
boolean isPlayerPrivilegedToAccessBlock(Player p, int blockX, int blockY, int blockZ, Block block);
|
||||||
|
|
||||||
boolean isPlayerPrivilegedToAccessEntity(Player p, int entityId);
|
boolean isPlayerPrivilegedToAccessEntity(Player p, int entityId);
|
||||||
|
|
||||||
boolean isPlayerPrivilegedToAccessBlockEntity(Player p, int blockX, int blockY, int blockZ, BlockEntityType<?> type);
|
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;
|
package de.steamwar.techhider;
|
||||||
|
|
||||||
import de.steamwar.Reflection;
|
|
||||||
import net.minecraft.core.IdMapper;
|
|
||||||
import net.minecraft.core.registries.BuiltInRegistries;
|
import net.minecraft.core.registries.BuiltInRegistries;
|
||||||
import net.minecraft.world.level.block.Block;
|
import net.minecraft.world.level.block.Block;
|
||||||
import net.minecraft.world.level.block.state.BlockState;
|
import net.minecraft.world.level.block.state.BlockState;
|
||||||
import net.minecraft.world.level.material.FluidState;
|
import net.minecraft.world.level.material.FluidState;
|
||||||
import net.minecraft.world.level.material.Fluids;
|
import net.minecraft.world.level.material.Fluids;
|
||||||
import org.bukkit.Material;
|
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 org.bukkit.craftbukkit.util.CraftMagicNumbers;
|
||||||
|
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
|
|||||||
@@ -22,9 +22,6 @@ package de.steamwar.techhider;
|
|||||||
import de.steamwar.Reflection;
|
import de.steamwar.Reflection;
|
||||||
import io.netty.buffer.ByteBuf;
|
import io.netty.buffer.ByteBuf;
|
||||||
import io.netty.buffer.Unpooled;
|
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.core.SectionPos;
|
||||||
import net.minecraft.network.protocol.game.ClientboundLevelChunkPacketData;
|
import net.minecraft.network.protocol.game.ClientboundLevelChunkPacketData;
|
||||||
import net.minecraft.network.protocol.game.ClientboundLevelChunkWithLightPacket;
|
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 net.minecraft.world.level.block.state.BlockState;
|
||||||
import org.bukkit.entity.Player;
|
import org.bukkit.entity.Player;
|
||||||
|
|
||||||
import java.util.*;
|
import java.util.List;
|
||||||
import java.util.function.UnaryOperator;
|
import java.util.function.UnaryOperator;
|
||||||
|
|
||||||
|
|
||||||
public class ChunkHider {
|
public class ChunkHider {
|
||||||
private static final UnaryOperator<Object> chunkPacketShallowCloner = ProtocolUtils.shallowCloneGenerator(ClientboundLevelChunkWithLightPacket.class);
|
private static final UnaryOperator<Object> chunkPacketShallowCloner = ProtocolUtils.shallowCloneGenerator(ClientboundLevelChunkWithLightPacket.class);
|
||||||
private static final UnaryOperator<Object> chunkDataShallowCloner = ProtocolUtils.shallowCloneGenerator(ClientboundLevelChunkPacketData.class);
|
private static final UnaryOperator<Object> chunkDataShallowCloner = ProtocolUtils.shallowCloneGenerator(ClientboundLevelChunkPacketData.class);
|
||||||
@@ -54,8 +50,6 @@ public class ChunkHider {
|
|||||||
private final int BLOCKS_PER_SECTION = 4096;
|
private final int BLOCKS_PER_SECTION = 4096;
|
||||||
private final int BIOMES_PER_SECTION = 64;
|
private final int BIOMES_PER_SECTION = 64;
|
||||||
|
|
||||||
private final byte BITS_PER_LONG = Long.SIZE;
|
|
||||||
|
|
||||||
private final int blockIdUsedForHiding;
|
private final int blockIdUsedForHiding;
|
||||||
private final AccessPrivilegeProvider accessPrivilegeProvider;
|
private final AccessPrivilegeProvider accessPrivilegeProvider;
|
||||||
|
|
||||||
@@ -65,7 +59,7 @@ public class ChunkHider {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private int getLongsRequiredToEncodeEntries(int bitsPerEntry, int entryCount) {
|
private int getLongsRequiredToEncodeEntries(int bitsPerEntry, int entryCount) {
|
||||||
int entriesPerLong = BITS_PER_LONG / bitsPerEntry;
|
int entriesPerLong = Long.SIZE / bitsPerEntry;
|
||||||
int dataLengthAsLongCount = (entryCount + entriesPerLong - 1) / entriesPerLong;
|
int dataLengthAsLongCount = (entryCount + entriesPerLong - 1) / entriesPerLong;
|
||||||
|
|
||||||
return dataLengthAsLongCount;
|
return dataLengthAsLongCount;
|
||||||
@@ -104,8 +98,7 @@ public class ChunkHider {
|
|||||||
out.writeShort(blockCount);
|
out.writeShort(blockCount);
|
||||||
out.writeByte(bitsPerBlock);
|
out.writeByte(bitsPerBlock);
|
||||||
ProtocolUtils.writeVarInt(out, sectionBlockId);
|
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 palletLength = ProtocolUtils.readVarInt(in);
|
||||||
int[] pallet = ProtocolUtils.readVarIntArray(in, palletLength);
|
int[] pallet = ProtocolUtils.readVarIntArray(in, palletLength);
|
||||||
|
|
||||||
@@ -158,8 +151,7 @@ public class ChunkHider {
|
|||||||
out.writeLong(rawDataSegment);
|
out.writeLong(rawDataSegment);
|
||||||
}*/
|
}*/
|
||||||
|
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
long[] rawData = readSectionDataFromBuffer(in, bitsPerBlock, BLOCKS_PER_SECTION);
|
long[] rawData = readSectionDataFromBuffer(in, bitsPerBlock, BLOCKS_PER_SECTION);
|
||||||
|
|
||||||
int[] blockData = resolveDirectBlockDataArray(rawData, bitsPerBlock);
|
int[] blockData = resolveDirectBlockDataArray(rawData, bitsPerBlock);
|
||||||
@@ -209,11 +201,9 @@ public class ChunkHider {
|
|||||||
Block block = blockState.getBlock();
|
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;
|
obfuscatedData[blockDataIndex] = blockId;
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
obfuscatedData[blockDataIndex] = blockIdUsedForHiding;
|
obfuscatedData[blockDataIndex] = blockIdUsedForHiding;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -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<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> packedXZField = Reflection.getField(blockEntitiyInfoClass, int.class, 0);
|
||||||
private static final Reflection.Field<Integer> yField = Reflection.getField(blockEntitiyInfoClass, int.class, 1);
|
private static final Reflection.Field<Integer> yField = Reflection.getField(blockEntitiyInfoClass, int.class, 1);
|
||||||
|
|
||||||
private List<Object> filterBlockEntities(Player player, List<Object> blockEntities) {
|
private List<Object> filterBlockEntities(Player player, List<Object> blockEntities) {
|
||||||
return blockEntities.stream()
|
return blockEntities.stream()
|
||||||
.filter((blockEntityInfo) -> {
|
.filter((blockEntityInfo) -> {
|
||||||
@@ -286,8 +277,7 @@ public class ChunkHider {
|
|||||||
if (bitsPerBiome == 0) {
|
if (bitsPerBiome == 0) {
|
||||||
int sectionBiomeId = ProtocolUtils.readVarInt(oldData);
|
int sectionBiomeId = ProtocolUtils.readVarInt(oldData);
|
||||||
ProtocolUtils.writeVarInt(newData, sectionBiomeId);
|
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);
|
int palletLength = ProtocolUtils.readVarInt(oldData);
|
||||||
ProtocolUtils.writeVarInt(newData, palletLength);
|
ProtocolUtils.writeVarInt(newData, palletLength);
|
||||||
|
|
||||||
@@ -300,13 +290,11 @@ public class ChunkHider {
|
|||||||
for (long rawDataSegment : rawData) {
|
for (long rawDataSegment : rawData) {
|
||||||
newData.writeLong(rawDataSegment);
|
newData.writeLong(rawDataSegment);
|
||||||
}
|
}
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
long[] rawData = readSectionDataFromBuffer(oldData, bitsPerBiome, BIOMES_PER_SECTION);
|
long[] rawData = readSectionDataFromBuffer(oldData, bitsPerBiome, BIOMES_PER_SECTION);
|
||||||
for (long rawDataSegment : rawData) {
|
for (long rawDataSegment : rawData) {
|
||||||
newData.writeLong(rawDataSegment);
|
newData.writeLong(rawDataSegment);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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.ints.IntList;
|
||||||
import it.unimi.dsi.fastutil.shorts.ShortArraySet;
|
import it.unimi.dsi.fastutil.shorts.ShortArraySet;
|
||||||
import it.unimi.dsi.fastutil.shorts.ShortSets;
|
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.BlockPos;
|
||||||
import net.minecraft.core.SectionPos;
|
import net.minecraft.core.SectionPos;
|
||||||
import net.minecraft.network.PacketListener;
|
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.cookie.ClientboundCookieRequestPacket;
|
||||||
import net.minecraft.network.protocol.game.*;
|
import net.minecraft.network.protocol.game.*;
|
||||||
import net.minecraft.network.protocol.login.*;
|
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.Block;
|
||||||
|
import net.minecraft.world.level.block.entity.BlockEntityType;
|
||||||
import net.minecraft.world.level.block.state.BlockState;
|
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.*;
|
||||||
import java.util.function.BiFunction;
|
import java.util.function.BiFunction;
|
||||||
@@ -59,20 +53,21 @@ import java.util.function.ToIntFunction;
|
|||||||
* any packet must be explicitly whitelisted or processed in a
|
* any packet must be explicitly whitelisted or processed in a
|
||||||
* way that is also compliant with the principle of default-deny.
|
* 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 Set<Class<?>> bypassingPackets;
|
||||||
private final Map<Class<? extends Packet<? extends PacketListener>>, BiFunction<Player, Packet<? extends PacketListener>, Packet<? extends PacketListener>>> packetProcessors;
|
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 BlockState blockStateUsedForObfuscation;
|
||||||
private final ChunkHider chunkHider;
|
private final ChunkHider chunkHider;
|
||||||
|
|
||||||
|
private final AccessPrivilegeProvider privilegeProvider;
|
||||||
|
|
||||||
// TODO handle packet bundle
|
// TODO handle packet bundle
|
||||||
protected TechHider(Block blockUsedForObfuscation) {
|
public TechHider(Block blockUsedForObfuscation, AccessPrivilegeProvider privilegeProvider) {
|
||||||
this.blockUsedForObfuscation = blockUsedForObfuscation;
|
|
||||||
this.blockStateUsedForObfuscation = blockUsedForObfuscation.defaultBlockState();
|
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(
|
this.bypassingPackets = new HashSet<>(List.of(
|
||||||
// --- 5.1.x Login Protocol ---
|
// --- 5.1.x Login Protocol ---
|
||||||
@@ -84,8 +79,7 @@ public abstract class TechHider implements AccessPrivilegeProvider {
|
|||||||
ClientboundCookieRequestPacket.class, // 5.1.6 Cookie Request
|
ClientboundCookieRequestPacket.class, // 5.1.6 Cookie Request
|
||||||
|
|
||||||
// --- 6.1.x Configuration Protocol ---
|
// --- 6.1.x Configuration Protocol ---
|
||||||
ClientboundSelectKnownPacks.class,
|
ClientboundSelectKnownPacks.class, ClientboundCustomPayloadPacket.class, // 6.1.2 Clientbound Plugin Message
|
||||||
ClientboundCustomPayloadPacket.class, // 6.1.2 Clientbound Plugin Message
|
|
||||||
ClientboundFinishConfigurationPacket.class, // 6.1.4 Finish Configuration
|
ClientboundFinishConfigurationPacket.class, // 6.1.4 Finish Configuration
|
||||||
ClientboundKeepAlivePacket.class, // 6.1.5 Clientbound Keep Alive
|
ClientboundKeepAlivePacket.class, // 6.1.5 Clientbound Keep Alive
|
||||||
ClientboundPingPacket.class, // 6.1.6 Ping
|
ClientboundPingPacket.class, // 6.1.6 Ping
|
||||||
@@ -311,6 +305,7 @@ public abstract class TechHider implements AccessPrivilegeProvider {
|
|||||||
this.packetProcessors = processors;
|
this.packetProcessors = processors;
|
||||||
|
|
||||||
TinyProtocol.instance.addGlobalClientboundFilter((player, rawPacket) -> {
|
TinyProtocol.instance.addGlobalClientboundFilter((player, rawPacket) -> {
|
||||||
|
try {
|
||||||
if (rawPacket instanceof ClientboundBundlePacket bundlePacket) {
|
if (rawPacket instanceof ClientboundBundlePacket bundlePacket) {
|
||||||
List<Packet<? super ClientGamePacketListener>> processedPackets = new ArrayList<>();
|
List<Packet<? super ClientGamePacketListener>> processedPackets = new ArrayList<>();
|
||||||
|
|
||||||
@@ -323,33 +318,31 @@ public abstract class TechHider implements AccessPrivilegeProvider {
|
|||||||
}
|
}
|
||||||
|
|
||||||
return new ClientboundBundlePacket(processedPackets);
|
return new ClientboundBundlePacket(processedPackets);
|
||||||
|
} else {
|
||||||
|
return processPacket(player, rawPacket);
|
||||||
}
|
}
|
||||||
else if(rawPacket instanceof Packet) {
|
} catch (Throwable t) {
|
||||||
return processPacket(player, (Packet<?>) rawPacket);
|
t.printStackTrace();
|
||||||
}
|
|
||||||
else {
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
TinyProtocol.instance.addFilter(ServerboundUseItemOnPacket.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) -> isPlayerPrivalegedToPerformAction(p) ? packet : null);
|
TinyProtocol.instance.addFilter(ServerboundInteractPacket.class, (p, packet) -> privilegeProvider.isPlayerPrivilegedToPerformAction(p) ? packet : null);
|
||||||
}
|
}
|
||||||
|
|
||||||
private Packet<?> processPacket(Player player, Packet<?> packet) {
|
private Packet<?> processPacket(Player player, Packet<?> packet) {
|
||||||
if (bypassingPackets.contains(packet.getClass())) {
|
if (bypassingPackets.contains(packet.getClass())) {
|
||||||
return packet;
|
return packet;
|
||||||
}
|
} else if (packetProcessors.containsKey(packet.getClass())) {
|
||||||
else if(packetProcessors.containsKey(packet.getClass())) {
|
return packetProcessors.get(packet.getClass()).apply(player, packet);
|
||||||
return packetProcessors.get(packet.getClass()).apply(player, (Packet<? extends PacketListener>) packet);
|
} else {
|
||||||
}
|
|
||||||
else {
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private Packet<? extends PacketListener> processAddEntityPacket(Player player, ClientboundAddEntityPacket packet) {
|
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;
|
return packet;
|
||||||
} else {
|
} else {
|
||||||
return null;
|
return null;
|
||||||
@@ -357,12 +350,13 @@ public abstract class TechHider implements AccessPrivilegeProvider {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private Packet<? extends PacketListener> processEntityPacket(Player player, int entityId, Packet<? extends PacketListener> packet) {
|
private Packet<? extends PacketListener> processEntityPacket(Player player, int entityId, Packet<? extends PacketListener> packet) {
|
||||||
if(isPlayerPrivilegedToAccessEntity(player, entityId)) {
|
if (privilegeProvider.isPlayerPrivilegedToAccessEntity(player, entityId)) {
|
||||||
return packet;
|
return packet;
|
||||||
} else {
|
} else {
|
||||||
return null;
|
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) -> {
|
return (p, rawPacket) -> {
|
||||||
TTargetPacket packet = (TTargetPacket) rawPacket;
|
TTargetPacket packet = (TTargetPacket) rawPacket;
|
||||||
@@ -371,25 +365,25 @@ public abstract class TechHider implements AccessPrivilegeProvider {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private final Reflection.Field<Integer> moveEntityPacketEntityIdField = Reflection.getField(ClientboundMoveEntityPacket.class, int.class, 0);
|
private final Reflection.Field<Integer> moveEntityPacketEntityIdField = Reflection.getField(ClientboundMoveEntityPacket.class, int.class, 0);
|
||||||
|
|
||||||
private Packet<?> processMoveEntityPacket(Player player, ClientboundMoveEntityPacket packet) {
|
private Packet<?> processMoveEntityPacket(Player player, ClientboundMoveEntityPacket packet) {
|
||||||
int entityId = moveEntityPacketEntityIdField.get(packet);
|
int entityId = moveEntityPacketEntityIdField.get(packet);
|
||||||
|
|
||||||
if(isPlayerPrivilegedToAccessEntity(player, entityId)) {
|
if (privilegeProvider.isPlayerPrivilegedToAccessEntity(player, entityId)) {
|
||||||
return packet;
|
return packet;
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
return null;
|
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) {
|
private Packet<?> processRotateHeadPacket(Player player, ClientboundRotateHeadPacket packet) {
|
||||||
int entityId = rotateHeadPacketEntityIdField.get(packet);
|
int entityId = rotateHeadPacketEntityIdField.get(packet);
|
||||||
|
|
||||||
if(isPlayerPrivilegedToAccessEntity(player, entityId)) {
|
if (privilegeProvider.isPlayerPrivilegedToAccessEntity(player, entityId)) {
|
||||||
return packet;
|
return packet;
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -397,9 +391,7 @@ public abstract class TechHider implements AccessPrivilegeProvider {
|
|||||||
private Packet<?> processRemoveEntitiesPacket(Player player, ClientboundRemoveEntitiesPacket packet) {
|
private Packet<?> processRemoveEntitiesPacket(Player player, ClientboundRemoveEntitiesPacket packet) {
|
||||||
IntList entityIdsToRemove = packet.getEntityIds();
|
IntList entityIdsToRemove = packet.getEntityIds();
|
||||||
|
|
||||||
IntList filteredEntitiesToRemove = entityIdsToRemove.intStream()
|
IntList filteredEntitiesToRemove = entityIdsToRemove.intStream().filter((id) -> privilegeProvider.isPlayerPrivilegedToAccessEntity(player, id)).collect(IntArrayList::new, IntList::add, IntList::addAll);
|
||||||
.filter((id) -> isPlayerPrivilegedToAccessEntity(player, id))
|
|
||||||
.collect(IntArrayList::new, IntList::add, IntList::addAll);
|
|
||||||
|
|
||||||
return new ClientboundRemoveEntitiesPacket(filteredEntitiesToRemove);
|
return new ClientboundRemoveEntitiesPacket(filteredEntitiesToRemove);
|
||||||
}
|
}
|
||||||
@@ -408,10 +400,9 @@ public abstract class TechHider implements AccessPrivilegeProvider {
|
|||||||
int fromEntityId = packet.getSourceId();
|
int fromEntityId = packet.getSourceId();
|
||||||
int toEntityId = packet.getDestId();
|
int toEntityId = packet.getDestId();
|
||||||
|
|
||||||
if(isPlayerPrivilegedToAccessEntity(player, fromEntityId) && isPlayerPrivilegedToAccessEntity(player, toEntityId)) {
|
if (privilegeProvider.isPlayerPrivilegedToAccessEntity(player, fromEntityId) && privilegeProvider.isPlayerPrivilegedToAccessEntity(player, toEntityId)) {
|
||||||
return packet;
|
return packet;
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -423,7 +414,7 @@ public abstract class TechHider implements AccessPrivilegeProvider {
|
|||||||
int blockY = blockPos.getY();
|
int blockY = blockPos.getY();
|
||||||
int blockZ = blockPos.getZ();
|
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;
|
return packet;
|
||||||
} else {
|
} else {
|
||||||
return null;
|
return null;
|
||||||
@@ -437,9 +428,9 @@ public abstract class TechHider implements AccessPrivilegeProvider {
|
|||||||
int blockY = blockPos.getY();
|
int blockY = blockPos.getY();
|
||||||
int blockZ = blockPos.getZ();
|
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;
|
return packet;
|
||||||
} else if(isPlayerPrivilegedToAccessPosition(player, blockX, blockY, blockZ)) {
|
} else if (privilegeProvider.isPlayerPrivilegedToAccessPosition(player, blockX, blockY, blockZ)) {
|
||||||
return new ClientboundBlockUpdatePacket(blockPos, blockStateUsedForObfuscation);
|
return new ClientboundBlockUpdatePacket(blockPos, blockStateUsedForObfuscation);
|
||||||
} else {
|
} else {
|
||||||
return null;
|
return null;
|
||||||
@@ -453,7 +444,7 @@ public abstract class TechHider implements AccessPrivilegeProvider {
|
|||||||
int blockY = blockPos.getY();
|
int blockY = blockPos.getY();
|
||||||
int blockZ = blockPos.getZ();
|
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;
|
return packet;
|
||||||
} else {
|
} else {
|
||||||
return null;
|
return null;
|
||||||
@@ -464,10 +455,9 @@ public abstract class TechHider implements AccessPrivilegeProvider {
|
|||||||
BlockPos blockPos = packet.getPos();
|
BlockPos blockPos = packet.getPos();
|
||||||
int entityBreakingBlockId = packet.getId();
|
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;
|
return packet;
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
return null;
|
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<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<short[]> oldPosField = Reflection.getField(ClientboundSectionBlocksUpdatePacket.class, short[].class, 0);
|
||||||
private final Reflection.Field<BlockState[]> oldStatesField = Reflection.getField(ClientboundSectionBlocksUpdatePacket.class, BlockState[].class, 0);
|
private final Reflection.Field<BlockState[]> oldStatesField = Reflection.getField(ClientboundSectionBlocksUpdatePacket.class, BlockState[].class, 0);
|
||||||
|
|
||||||
private ClientboundSectionBlocksUpdatePacket processSectionUpdate(Player p, ClientboundSectionBlocksUpdatePacket packet) {
|
private ClientboundSectionBlocksUpdatePacket processSectionUpdate(Player p, ClientboundSectionBlocksUpdatePacket packet) {
|
||||||
SectionPos sectionPos = sectionPosField.get(packet);
|
SectionPos sectionPos = sectionPosField.get(packet);
|
||||||
short[] oldPos = oldPosField.get(packet);
|
short[] oldPos = oldPosField.get(packet);
|
||||||
@@ -493,11 +484,11 @@ public abstract class TechHider implements AccessPrivilegeProvider {
|
|||||||
int worldY = sectionPos.relativeToBlockY(posShort);
|
int worldY = sectionPos.relativeToBlockY(posShort);
|
||||||
int worldZ = sectionPos.relativeToBlockZ(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 !!!
|
// TODO statefull !!!
|
||||||
filteredPos.add(posShort);
|
filteredPos.add(posShort);
|
||||||
filteredStates.add(state);
|
filteredStates.add(state);
|
||||||
} else if(isPlayerPrivilegedToAccessPosition(p, worldX, worldY, worldZ)){
|
} else if (privilegeProvider.isPlayerPrivilegedToAccessPosition(p, worldX, worldY, worldZ)) {
|
||||||
modified = true;
|
modified = true;
|
||||||
filteredPos.add(posShort);
|
filteredPos.add(posShort);
|
||||||
filteredStates.add(blockStateUsedForObfuscation);
|
filteredStates.add(blockStateUsedForObfuscation);
|
||||||
@@ -518,11 +509,7 @@ public abstract class TechHider implements AccessPrivilegeProvider {
|
|||||||
|
|
||||||
BlockState[] newStates = filteredStates.toArray(new BlockState[0]);
|
BlockState[] newStates = filteredStates.toArray(new BlockState[0]);
|
||||||
|
|
||||||
return new ClientboundSectionBlocksUpdatePacket(
|
return new ClientboundSectionBlocksUpdatePacket(sectionPos, ShortSets.unmodifiable(new ShortArraySet(newPos)), newStates);
|
||||||
sectionPos,
|
|
||||||
ShortSets.unmodifiable(new ShortArraySet(newPos)),
|
|
||||||
newStates
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private Packet<?> processLevelParticlesPacket(Player player, ClientboundLevelParticlesPacket packet) {
|
private Packet<?> processLevelParticlesPacket(Player player, ClientboundLevelParticlesPacket packet) {
|
||||||
@@ -530,30 +517,29 @@ public abstract class TechHider implements AccessPrivilegeProvider {
|
|||||||
int blockY = (int) packet.getY();
|
int blockY = (int) packet.getY();
|
||||||
int blockZ = (int) packet.getZ();
|
int blockZ = (int) packet.getZ();
|
||||||
|
|
||||||
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(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)) {
|
|
||||||
return packet;
|
return packet;
|
||||||
} else {
|
} else {
|
||||||
return null;
|
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) {
|
private <TTargetPacket extends Packet<?>> BiFunction<Player, Packet<?>, Packet<?>> buildPositionBasedPacketProcessor(Function<TTargetPacket, BlockPos> positionExtractor) {
|
||||||
return (p, rawPacket) -> {
|
return (p, rawPacket) -> {
|
||||||
TTargetPacket packet = (TTargetPacket) rawPacket;
|
TTargetPacket packet = (TTargetPacket) rawPacket;
|
||||||
@@ -565,12 +551,4 @@ public abstract class TechHider implements AccessPrivilegeProvider {
|
|||||||
return proccessPositionBasedPacket(p, blockX, blockY, blockZ, packet);
|
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;
|
package de.steamwar.techhider.legacy;
|
||||||
|
|
||||||
import de.steamwar.Reflection;
|
import de.steamwar.Reflection;
|
||||||
|
import de.steamwar.techhider.ProtocolUtils;
|
||||||
import io.netty.buffer.ByteBuf;
|
import io.netty.buffer.ByteBuf;
|
||||||
import io.netty.buffer.Unpooled;
|
import io.netty.buffer.Unpooled;
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
@@ -39,6 +40,7 @@ import java.util.function.BiFunction;
|
|||||||
import java.util.function.UnaryOperator;
|
import java.util.function.UnaryOperator;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
@Deprecated
|
||||||
public class ChunkHider {
|
public class ChunkHider {
|
||||||
public static final ChunkHider impl = new 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.ArrayList;
|
||||||
import java.util.function.BiFunction;
|
import java.util.function.BiFunction;
|
||||||
|
|
||||||
|
@Deprecated
|
||||||
public class ProtocolWrapper {
|
public class ProtocolWrapper {
|
||||||
public static final ProtocolWrapper impl = new ProtocolWrapper();
|
public static final ProtocolWrapper impl = new ProtocolWrapper();
|
||||||
|
|
||||||
@@ -88,8 +89,4 @@ public class ProtocolWrapper {
|
|||||||
public boolean unfilteredTileEntityDataAction(Object packet) {
|
public boolean unfilteredTileEntityDataAction(Object packet) {
|
||||||
return tileEntityType.get(packet) != signType;
|
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 com.comphenix.tinyprotocol.TinyProtocol;
|
||||||
import de.steamwar.Reflection;
|
import de.steamwar.Reflection;
|
||||||
|
import de.steamwar.techhider.BlockIds;
|
||||||
|
import de.steamwar.techhider.ProtocolUtils;
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
import net.minecraft.core.BlockPos;
|
import net.minecraft.core.BlockPos;
|
||||||
import net.minecraft.core.Vec3i;
|
import net.minecraft.core.Vec3i;
|
||||||
@@ -39,6 +41,7 @@ import java.util.function.Function;
|
|||||||
import java.util.function.UnaryOperator;
|
import java.util.function.UnaryOperator;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
@Deprecated
|
||||||
public class TechHider {
|
public class TechHider {
|
||||||
|
|
||||||
public static final Class<?> blockPosition = BlockPos.class;
|
public static final Class<?> blockPosition = BlockPos.class;
|
||||||
@@ -87,7 +90,7 @@ public class TechHider {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void enable() {
|
public void enable() {
|
||||||
techhiders.forEach(TinyProtocol.instance::addFilter);
|
techhiders.forEach((type, playerObjectBiFunction) -> TinyProtocol.instance.addFilter((Class) type, playerObjectBiFunction));
|
||||||
}
|
}
|
||||||
|
|
||||||
public void disable() {
|
public void disable() {
|
||||||
|
|||||||
Reference in New Issue
Block a user