This commit is contained in:
D4rkr34lm
2026-05-15 16:14:05 +02:00
parent 42808f40c0
commit 9a75f38226
@@ -7,6 +7,8 @@ import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.function.BiFunction;
import java.util.function.ToDoubleFunction;
import java.util.function.ToIntFunction;
import org.bukkit.entity.Player;
import org.bukkit.plugin.Plugin;
@@ -169,58 +171,50 @@ import net.minecraft.world.level.block.state.BlockState;
* any packet must be explicitly whitelisted or processed in a
* way that is also compliant with the principle of default-deny.
*/
public class TechHider {
public abstract class TechHider {
private final Set<Class<? extends Packet<? extends PacketListener>>> bypassingPackets;
private final Map<Class<? extends Packet<? extends PacketListener>>, BiFunction<Player, Packet<? extends PacketListener>, Packet<? extends PacketListener>>> packetProcessors;
private final TinyProtocol interceptor;
private final Set<Integer> blockIdsToObfuscate;
private final Set<String> blockEntitiesToHide;
private final BlockState blockToObfuscateTo;
private final BlockState blockUsedForObfuscation;
//TODO handle packet bundle
public TechHider(Plugin plugin, Set<Integer> blockIdsToObfuscate, BlockState blockToObfuscateTo, Set<String> blockEntitiesToHide) {
this.blockIdsToObfuscate = blockIdsToObfuscate;
this.blockToObfuscateTo = blockToObfuscateTo;
this.blockEntitiesToHide = blockEntitiesToHide;
// TODO handle packet bundle
public TechHider(Plugin plugin, BlockState blockUsedForObfuscation) {
this.blockUsedForObfuscation = blockUsedForObfuscation;
this.bypassingPackets = new HashSet<>(List.of(
// --- 5.1.x Login Protocol ---
ClientboundLoginDisconnectPacket.class, // 5.1.1 Disconnect
ClientboundHelloPacket.class, // 5.1.2 Encryption Request
ClientboundLoginFinishedPacket.class, // 5.1.3 Login Success
ClientboundHelloPacket.class, // 5.1.2 Encryption Request
ClientboundLoginFinishedPacket.class, // 5.1.3 Login Success
ClientboundLoginCompressionPacket.class, // 5.1.4 Set Compression
ClientboundCustomQueryPacket.class, // 5.1.5 Login Plugin Request
ClientboundCookieRequestPacket.class, // 5.1.6 Cookie Request
ClientboundCustomQueryPacket.class, // 5.1.5 Login Plugin Request
ClientboundCookieRequestPacket.class, // 5.1.6 Cookie Request
// --- 6.1.x Configuration Protocol ---
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
ClientboundPingPacket.class, // 6.1.6 Ping
ClientboundRegistryDataPacket.class, // 6.1.8 Registry Data
ClientboundResourcePackPopPacket.class, // 6.1.9 Remove Resource Pack
ClientboundResourcePackPushPacket.class, // 6.1.10 Add Resource Pack
ClientboundStoreCookiePacket.class, // 6.1.11 Store Cookie
ClientboundTransferPacket.class, // 6.1.12 Transfer
ClientboundTransferPacket.class, // 6.1.12 Transfer
ClientboundUpdateEnabledFeaturesPacket.class, // 6.1.13 Feature Flags
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
ClientboundServerDataPacket.class, // 6.1.20 Code of Conduct is usually in Server Data
ClientboundSystemChatPacket.class, // 6.1.18/19 Dialogs are often handled via System Chat or Custom
// Payloads
ClientboundServerDataPacket.class, // 6.1.20 Code of Conduct is usually in Server Data
// --- 7.1.x Play Protocol: packets that do not expose hidden blocks, light, sounds, or entities ---
// --- 7.1.x Play Protocol ---
// --- Safe packets; Not involved with a critical subdomain ---
ClientboundBundleDelimiterPacket.class, // 7.1.1 Bundle Delimiter
ClientboundAwardStatsPacket.class, // 7.1.4 Award Statistics
ClientboundBossEventPacket.class, // 7.1.10 Boss Bar
ClientboundChangeDifficultyPacket.class, // 7.1.11 Change Difficulty
ClientboundChunkBatchFinishedPacket.class, // 7.1.12 Chunk Batch Finished
ClientboundChunkBatchStartPacket.class, // 7.1.13 Chunk Batch Start
ClientboundClearTitlesPacket.class, // 7.1.15 Clear Titles
ClientboundCommandSuggestionsPacket.class, // 7.1.16 Command Suggestions Response
ClientboundCommandsPacket.class, // 7.1.17 Commands
ClientboundContainerClosePacket.class, // 7.1.18 Close Container
ClientboundContainerSetContentPacket.class, // 7.1.19 Set Container Content
ClientboundContainerSetDataPacket.class, // 7.1.20 Set Container Property
ClientboundContainerSetSlotPacket.class, // 7.1.21 Set Container Slot
ClientboundCookieRequestPacket.class, // 7.1.22 Cookie Request (play)
ClientboundCooldownPacket.class, // 7.1.23 Set Cooldown
ClientboundCustomChatCompletionsPacket.class, // 7.1.24 Chat Suggestions
@@ -241,8 +235,9 @@ public class TechHider {
ClientboundPlayerChatPacket.class, // 7.1.64 Player Chat Message
ClientboundPlayerCombatEndPacket.class, // 7.1.65 End Combat
ClientboundPlayerCombatEnterPacket.class, // 7.1.66 Enter Combat
ClientboundPlayerLookAtPacket.class, // 7.1.70 Look At (Player owning channel)
ClientboundPlayerPositionPacket.class, // 7.1.71 Synchronize Player Position (Player owning the channel)
ClientboundPlayerRotationPacket.class, // 7.1.72 Player Rotation (Player owning the channel
ClientboundPlayerRotationPacket.class, // 7.1.72 Player Rotation (Player owning the channel)
ClientboundRecipeBookAddPacket.class, // 7.1.73 Recipe Book Add
ClientboundRecipeBookRemovePacket.class, // 7.1.74 Recipe Book Remove
ClientboundRecipeBookSettingsPacket.class, // 7.1.75 Recipe Book Settings
@@ -258,16 +253,16 @@ public class TechHider {
ClientboundSetBorderSizePacket.class, // 7.1.89 Set Border Size
ClientboundSetBorderWarningDelayPacket.class, // 7.1.90 Set Border Warning Delay
ClientboundSetBorderWarningDistancePacket.class, // 7.1.91 Set Border Warning Distance
ClientboundSetChunkCacheCenterPacket.class, // 7.1.93 Set Center Chunk
ClientboundSetChunkCacheRadiusPacket.class, // 7.1.94 Set Render Distance
ClientboundSetCursorItemPacket.class, // 7.1.95 Set Cursor Item
ClientboundSetDefaultSpawnPositionPacket.class, // 7.1.96 Set Default Spawn Position
ClientboundSetDisplayObjectivePacket.class, // 7.1.97 Display Objective
ClientboundSetExperiencePacket.class, // 7.1.102 Set Experience
ClientboundSetHealthPacket.class, // 7.1.103 Set Health
ClientboundSetHeldSlotPacket.class, // 7.1.104 Set Held Item (clientbound)
ClientboundSetHealthPacket.class, // 7.1.103 Set Health, Saturation and food (Player owning the channel)
ClientboundSetHeldSlotPacket.class, // 7.1.104 Set Held Item (Player owning the channel)
ClientboundSetObjectivePacket.class, // 7.1.105 Update Objectives
ClientboundSetPlayerInventoryPacket.class, // 7.1.107 Set Player Inventory Slot
ClientboundSetPlayerInventoryPacket.class, // 7.1.107 Set Player Inventory Slot (Player owning the
// channel)
ClientboundSetScorePacket.class, // 7.1.109 Update Score
ClientboundSetSimulationDistancePacket.class, // 7.1.110 Set Simulation Distance
ClientboundSetSubtitleTextPacket.class, // 7.1.111 Set Subtitle Text
@@ -288,24 +283,34 @@ public class TechHider {
ClientboundClearDialogPacket.class, // 7.1.138 Clear Dialog (play)
ClientboundShowDialogPacket.class, // 7.1.139 Show Dialog (play)
// --- Play packets required manual review after update ---
// They include world data but non that can reveal critical information
ClientboundBlockChangedAckPacket.class, // 7.1.5 Acknowledge Block Change
ClientboundChunksBiomesPacket.class // 7.1.14 Chunk Biomes
// --- Mostly safe packets; Are involved with critical subdomain, but in not
// critical way ---
ClientboundBlockChangedAckPacket.class, // 7.1.5 Acknowledge Block Change
ClientboundChunkBatchFinishedPacket.class, // 7.1.12 Chunk Batch Finished (Delimiter)
ClientboundChunkBatchStartPacket.class, // 7.1.13 Chunk Batch Start (Delimiter)
ClientboundChunksBiomesPacket.class, // 7.1.14 Chunk Biomes
ClientboundContainerClosePacket.class, // 7.1.18 Close Container
ClientboundSetChunkCacheCenterPacket.class, // 7.1.93 Set Center Chunk
ClientboundForgetLevelChunkPacket.class, // 7.1.38 Unload Chunk
ClientboundUpdateTagsPacket.class, // 7.1.133 Update Tags (play)
ClientboundPlayerInfoRemovePacket.class, // 7.1.68 Player Info Remove
ClientboundPlayerInfoUpdatePacket.class // 7.1.69 Player Info Update
));
BiFunction<Player, Packet<? extends PacketListener>, Packet<? extends PacketListener>> tossPacket = (p, packet) -> null;
Map<Class<? extends Packet<? extends PacketListener>>, BiFunction<Player, Packet<? extends PacketListener>, Packet<? extends PacketListener>>> processors = new HashMap<>();
// 7.1.x Bundle Packet: packet container; blocked until nested packets are safely unbundled/processed.
// 7.1.x Bundle Packet: packet container; blocked until nested packets are
// safely unbundled/processed.
processors.put(ClientboundBundlePacket.class, tossPacket);
// --- Entity packets ---
// --- Entity packets -
// 7.1.2 Spawn Entity: entity type and position can reveal hidden contraptions.
processors.put(ClientboundAddEntityPacket.class, tossPacket);
processors.put(ClientboundAddEntityPacket.class, this.<ClientboundAddEntityPacket>buildEntityWithPositionProcessor(ClientboundAddEntityPacket::getId, ClientboundAddEntityPacket::getX, ClientboundAddEntityPacket::getY, ClientboundAddEntityPacket::getZ));
// 7.1.3 Entity Animation: entity id based signal, keep blocked until entity visibility is modeled.
processors.put(ClientboundAnimatePacket.class, tossPacket);
// 7.1.26 Damage Event: entity ids and damage source location can leak hidden activity.
// 7.1.26 Damage Event: entity ids and damage source location can leak hidden
// activity.
processors.put(ClientboundDamageEventPacket.class, tossPacket);
// 7.1.35 Entity Event: entity id based signal.
processors.put(ClientboundEntityEventPacket.class, tossPacket);
@@ -318,6 +323,16 @@ public class TechHider {
processors.put(Pos.class, tossPacket);
processors.put(PosRot.class, tossPacket);
processors.put(Rot.class, tossPacket);
// 7.1.100 Set Entity Velocity: entity id and movement.
processors.put(ClientboundSetEntityMotionPacket.class, tossPacket);
// 7.1.101 Set Equipment: entity equipment can reveal wargear.
processors.put(ClientboundSetEquipmentPacket.class, tossPacket);
// 7.1.106 Set Passengers: entity relationship signal.
processors.put(ClientboundSetPassengersPacket.class, tossPacket);
// 7.1.130 Update Attributes: entity id and attribute state.
processors.put(ClientboundUpdateAttributesPacket.class, tossPacket);
// 7.1.131 Entity Effect: entity id and effect state.
processors.put(ClientboundUpdateMobEffectPacket.class, tossPacket);
// 7.1.76 Remove Entities: entity id visibility side channel.
processors.put(ClientboundRemoveEntitiesPacket.class, tossPacket);
// 7.1.77 Remove Entity Effect: entity id and effect state.
@@ -328,36 +343,25 @@ public class TechHider {
processors.put(ClientboundSetEntityDataPacket.class, tossPacket);
// 7.1.99 Link Entities: entity relationship signal.
processors.put(ClientboundSetEntityLinkPacket.class, tossPacket);
// 7.1.100 Set Entity Velocity: entity id and movement.
processors.put(ClientboundSetEntityMotionPacket.class, tossPacket);
// 7.1.101 Set Equipment: entity equipment can reveal wargear.
processors.put(ClientboundSetEquipmentPacket.class, tossPacket);
// 7.1.106 Set Passengers: entity relationship signal.
processors.put(ClientboundSetPassengersPacket.class, tossPacket);
// 7.1.130 Update Attributes: entity id and attribute state.
processors.put(ClientboundUpdateAttributesPacket.class, tossPacket);
// 7.1.131 Entity Effect: entity id and effect state.
processors.put(ClientboundUpdateMobEffectPacket.class, tossPacket);
// --- Block entity packets ---
// 7.1.7 Block Entity Data: currently filtered by block position and allowed tile-entity actions.
// 7.1.7 Block Entity Data: currently filtered by block position and allowed
// tile-entity actions.
processors.put(ClientboundBlockEntityDataPacket.class, (p, packet) -> processBlockEntityDataPacket(p, (ClientboundBlockEntityDataPacket) packet));
// 7.1.122 Tag Query Response: block-entity query result.
processors.put(ClientboundTagQueryPacket.class, tossPacket);
// --- Block packets ---
// 7.1.6 Set Block Destroy Stage: block position and mining progress can reveal activity.
// 7.1.6 Set Block Destroy Stage: block position and mining progress can reveal
// activity.
processors.put(ClientboundBlockDestructionPacket.class, tossPacket);
// 7.1.8 Block Action: currently filtered by block position.
processors.put(ClientboundBlockEventPacket.class, (p, packet) -> processBlockEventPacket(p, (ClientboundBlockEventPacket) packet));
// 7.1.9 Block Update: currently filtered/obfuscated by block position and block id.
// 7.1.9 Block Update: currently filtered/obfuscated by block position and block
// id.
processors.put(ClientboundBlockUpdatePacket.class, (p, packet) -> processBlockUpdatePacket(p, (ClientboundBlockUpdatePacket) packet));
// --- Chunk packets ---
// 7.1.38 Unload Chunk: chunk visibility side channel.
processors.put(ClientboundForgetLevelChunkPacket.class, tossPacket);
// 7.1.45 Chunk Data and Update Light: currently filtered/obfuscated by chunk data processor.
processors.put(ClientboundLevelChunkWithLightPacket.class, (p, packet) -> processChunkWithLight(p, (ClientboundLevelChunkWithLightPacket) packet));
@@ -365,29 +369,27 @@ public class TechHider {
// 7.1.83 Update Section Blocks: currently filtered/obfuscated by section block processor.
processors.put(ClientboundSectionBlocksUpdatePacket.class, (p, packet) -> processSectionUpdate(p, (ClientboundSectionBlocksUpdatePacket) packet));
// --- Particle packets ---
// 7.1.47 Particle: particle type and position can reveal hidden machinery.
processors.put(ClientboundLevelParticlesPacket.class, tossPacket);
// --- Sound packets ---
// 7.1.115 Entity Sound Effect: entity id and sound.
processors.put(ClientboundSoundEntityPacket.class, tossPacket);
// 7.1.116 Sound Effect: sound type and position.
processors.put(ClientboundSoundPacket.class, tossPacket);
// 7.1.118 Stop Sound: sound state side channel.
processors.put(ClientboundStopSoundPacket.class, tossPacket);
// --- Lighting packets ---
// 7.1.48 Update Light: lighting can reveal hidden blocks/operations.
processors.put(ClientboundLightUpdatePacket.class, tossPacket);
// --- Others ---
// --- Container packets ---
// 7.1.19 Set Container Content
processors.put(ClientboundContainerSetContentPacket.class, tossPacket);
// 7.1.20 Set Container Property
processors.put(ClientboundContainerSetDataPacket.class, tossPacket);
// 7.1.21 Set Container Slot
processors.put(ClientboundContainerSetSlotPacket.class, tossPacket);
// 7.1.37 Explosion: position, affected blocks, and knockback can reveal TNT/tech.
// --- Others ---
// 7.1.37 Explosion: position, affected blocks, and knockback can reveal
// TNT/tech.
processors.put(ClientboundExplodePacket.class, tossPacket);
// 7.1.46 World Event: block position/event id can leak activity.
// 7.1.46 World Event: block position/event id can leak activity.
processors.put(ClientboundLevelEventPacket.class, tossPacket);
// 7.1.50 Map Data: map pixels/icons can reveal player/world state.
processors.put(ClientboundMapItemDataPacket.class, tossPacket);
@@ -404,18 +406,8 @@ public class TechHider {
// 7.1.137 Waypoint: world/entity tracking signal.
processors.put(ClientboundTrackedWaypointPacket.class, tossPacket);
// --- Safe; should be added to bypass ---
// 7.1.133 Update Tags (play): registry/tag data can be added back after review.
processors.put(ClientboundUpdateTagsPacket.class, tossPacket);
// 7.1.70 Look At: target position/entity.
processors.put(ClientboundPlayerLookAtPacket.class, tossPacket);
// 7.1.68 Player Info Remove: other-player identity/state.
processors.put(ClientboundPlayerInfoRemovePacket.class, tossPacket);
// 7.1.69 Player Info Update: other-player identity/state.
processors.put(ClientboundPlayerInfoUpdatePacket.class, tossPacket);
// --- Safe enough (not enough relevant data) to leak critical information; review and add to bypass ---
// --- Safe enough (not enough relevant data) to leak critical information;
// review and add to bypass ---
// 7.1.123 Pickup Item: item/entity ids and pickup activity.
processors.put(ClientboundTakeItemEntityPacket.class, tossPacket);
// 7.1.92 Set Camera: entity id.
@@ -425,6 +417,14 @@ public class TechHider {
// 7.1.67 Combat Death: entity/player ids and death message context.
processors.put(ClientboundPlayerCombatKillPacket.class, tossPacket);
// --- Sound packets natural part of the game -> should not be hidden ---
// 7.1.115 Entity Sound Effect: entity id and sound.
processors.put(ClientboundSoundEntityPacket.class, tossPacket);
// 7.1.116 Sound Effect: sound type and position.
processors.put(ClientboundSoundPacket.class, tossPacket);
// 7.1.118 Stop Sound: sound state side channel.
processors.put(ClientboundStopSoundPacket.class, tossPacket);
this.packetProcessors = processors;
this.interceptor = new TinyProtocol(plugin) {
@@ -435,20 +435,47 @@ public class TechHider {
return packet;
}
BiFunction<Player, Packet<? extends PacketListener>, Packet<? extends PacketListener>> processor = packetProcessors.get(packet.getClass());
return processor == null ? null : processor.apply(receiver, (Packet<? extends PacketListener>) packet);
} catch(Error e) {
BiFunction<Player, Packet<? extends PacketListener>, Packet<? extends PacketListener>> processor = packetProcessors
.get(packet.getClass());
return processor == null ? null
: processor.apply(receiver, (Packet<? extends PacketListener>) packet);
} catch (Error e) {
// Errors during packet processing leeding to packet being tossed
e.printStackTrace();
return null;
}
}
};
}
private Packet<? extends PacketListener> processEntityPacketWithPosition(Player player, int entityId, double entityX, double entityY, double entityZ, Packet<? extends PacketListener> packet) {
if(isPlayerPrivilegedToAccessEntity(player, entityId) && isPlayerPrivilegedToAccessPosition(player, (int) entityX, (int) entityY, (int) entityZ)) {
return packet;
} else {
return new ClientboundRemoveEntitiesPacket(entityId);
}
}
private <TTargetPacket extends Packet<?>> BiFunction<Player, Packet<? extends PacketListener>, Packet<? extends PacketListener>> buildEntityWithPositionProcessor(ToIntFunction<TTargetPacket> entityIdExtractor, ToDoubleFunction<TTargetPacket> xExtractor, ToDoubleFunction<TTargetPacket> yExtractor, ToDoubleFunction<TTargetPacket> zExtractor) {
return (p, rawPacket) -> {
TTargetPacket packet = (TTargetPacket) rawPacket;
processEntityPacketWithPosition(p, entityIdExtractor.applyAsInt(packet), xExtractor.applyAsDouble(packet), yExtractor.applyAsDouble(packet), zExtractor.applyAsDouble(packet), packet)
};
}
private Packet<? extends PacketListener> processEntityPacket(Player player, int entityId, Packet<? extends PacketListener> packet) {
if(isPlayerPrivilegedToAccessEntity(player, entityId)) {
return packet;
} else {
return new ClientboundRemoveEntitiesPacket(entityId);
}
}
private ClientboundBlockEventPacket processBlockEventPacket(Player player, ClientboundBlockEventPacket packet) {
BlockPos blockPos = packet.getPos();
if (isPlayerPrivilegedToAccessBlockPos(player, blockPos.getX(), blockPos.getY(), blockPos.getZ())) {
if (isPlayerPrivilegedToAccessPosition(player, blockPos.getX(), blockPos.getY(), blockPos.getZ())) {
return packet;
} else {
return null;
@@ -459,18 +486,19 @@ public class TechHider {
BlockPos blockPos = packet.getPos();
int id = BlockIds.impl.getCombinedId(packet.getBlockState());
if(isPlayerPrivilegedToAccessBlockPos(player, blockPos.getX(), blockPos.getY(), blockPos.getZ())) {
if (isPlayerPrivilegedToAccessBlockPos(player, blockPos.getX(), blockPos.getY(), blockPos.getZ())) {
return packet;
}
else if (blockIdsToObfuscate.contains(id)) {
ClientboundBlockUpdatePacket modifiedPacket = new ClientboundBlockUpdatePacket(packet.getPos(), blockToObfuscateTo);
} else if (blockIdsToObfuscate.contains(id)) {
ClientboundBlockUpdatePacket modifiedPacket = new ClientboundBlockUpdatePacket(packet.getPos(),
blockToObfuscateTo);
return modifiedPacket;
} else {
return packet;
}
}
private ClientboundBlockEntityDataPacket processBlockEntityDataPacket(Player p, ClientboundBlockEntityDataPacket packet) {
private ClientboundBlockEntityDataPacket processBlockEntityDataPacket(Player p,
ClientboundBlockEntityDataPacket packet) {
BlockPos blockPos = packet.getPos();
if (isPlayerPrivilegedToAccessBlockPos(p, blockPos.getX(), blockPos.getY(), blockPos.getZ())) {
@@ -483,8 +511,8 @@ public class TechHider {
}
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 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);
@@ -527,7 +555,6 @@ public class TechHider {
return packet;
}
short[] newPos = new short[filteredPos.size()];
for (int i = 0; i < newPos.length; i++) {
newPos[i] = filteredPos.get(i);
@@ -543,14 +570,14 @@ public class TechHider {
}
private final ChunkHider chunkHider = new ChunkHider();
private ClientboundLevelChunkWithLightPacket processChunkWithLight(Player p, ClientboundLevelChunkWithLightPacket packet) {
return chunkHider.processLevelChunkWithLightPacket(p, blockEntitiesToHide, this::isPlayerPrivilegedToAccessBlockPos,blockToObfuscateTo, blockIdsToObfuscate, packet);
private ClientboundLevelChunkWithLightPacket processChunkWithLight(Player p, ClientboundLevelChunkWithLightPacket packet) {
return chunkHider.processLevelChunkWithLightPacket(p, blockEntitiesToHide, this::isPlayerPrivilegedToAccessBlockPos, blockToObfuscateTo, blockIdsToObfuscate, packet);
}
private boolean isPlayerPrivilegedToAccessBlockPos(Player p, int blockX, int blockY, int blockZ) {
return false;
}
public abstract boolean isPlayerPrivilegedToAccessPosition(Player p, int blockX, int blockY, int blockZ);
public abstract boolean isPlayerPrivilegedToAccessBlock(Player p, int blockMaterialId, int blockX, int blockY,int blockZ);
public abstract boolean isPlayerPrivilegedToAccessBlockEntity(Player p, String blockEntityType, int blockX,int blockY, int blockZ);
public abstract boolean isPlayerPrivilegedToAccessEntity(Player p, int entityId);
public abstract boolean isPlayerPrivilegedToAccessContainer(Player p, int containerId);
}