Anti Xray
Dieser Commit ist enthalten in:
Ursprung
d67e55d367
Commit
fe142cdcd5
@ -1104,23 +1104,23 @@ index 183b2191fa1c1b27adedf39593e1b5a223fb1279..8ead66c134688b11dca15f6509147e72
|
||||
|
||||
private ClientboundLevelChunkWithLightPacket(RegistryFriendlyByteBuf buf) {
|
||||
diff --git a/src/main/java/net/minecraft/server/level/ServerLevel.java b/src/main/java/net/minecraft/server/level/ServerLevel.java
|
||||
index aee8d882783130ed45a713e6c266114aaf4c0d93..acc11fc7f30b6d4a3a4445b7db25bf99c93b39f2 100644
|
||||
index 104827e5ca729d7d2f1ad4bda3a5b87fbb939db5..9a7ac16914bd22a7ca0aaedd2a3ce1576ad2e09c 100644
|
||||
--- a/src/main/java/net/minecraft/server/level/ServerLevel.java
|
||||
+++ b/src/main/java/net/minecraft/server/level/ServerLevel.java
|
||||
@@ -491,7 +491,7 @@ public class ServerLevel extends Level implements WorldGenLevel, ca.spottedleaf.
|
||||
// Holder holder = worlddimension.type(); // CraftBukkit - decompile error
|
||||
@@ -344,7 +344,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe
|
||||
|
||||
// Objects.requireNonNull(minecraftserver); // CraftBukkit - decompile error
|
||||
- super(iworlddataserver, resourcekey, minecraftserver.registryAccess(), worlddimension.type(), minecraftserver::getProfiler, false, flag, i, minecraftserver.getMaxChainedNeighborUpdates(), gen, biomeProvider, env, spigotConfig -> minecraftserver.paperConfigurations.createWorldConfig(io.papermc.paper.configuration.PaperConfigurations.createWorldContextMap(convertable_conversionsession.levelDirectory.path(), iworlddataserver.getLevelName(), resourcekey.location(), spigotConfig, minecraftserver.registryAccess(), iworlddataserver.getGameRules()))); // Paper - create paper world configs
|
||||
+ super(iworlddataserver, resourcekey, minecraftserver.registryAccess(), worlddimension.type(), minecraftserver::getProfiler, false, flag, i, minecraftserver.getMaxChainedNeighborUpdates(), gen, biomeProvider, env, spigotConfig -> minecraftserver.paperConfigurations.createWorldConfig(io.papermc.paper.configuration.PaperConfigurations.createWorldContextMap(convertable_conversionsession.levelDirectory.path(), iworlddataserver.getLevelName(), resourcekey.location(), spigotConfig, minecraftserver.registryAccess(), iworlddataserver.getGameRules())), executor); // Paper - create paper world configs; Async-Anti-Xray: Pass executor
|
||||
// Add env and gen to constructor, IWorldDataServer -> WorldDataServer
|
||||
public ServerLevel(MinecraftServer minecraftserver, Executor executor, LevelStorageSource.LevelStorageAccess convertable_conversionsession, PrimaryLevelData iworlddataserver, ResourceKey<Level> resourcekey, LevelStem worlddimension, ChunkProgressListener worldloadlistener, boolean flag, long i, List<CustomSpawner> list, boolean flag1, @Nullable RandomSequences randomsequences, org.bukkit.World.Environment env, org.bukkit.generator.ChunkGenerator gen, org.bukkit.generator.BiomeProvider biomeProvider) {
|
||||
- super(iworlddataserver, resourcekey, minecraftserver.registryAccess(), worlddimension.type(), false, flag, i, minecraftserver.getMaxChainedNeighborUpdates(), gen, biomeProvider, env, spigotConfig -> minecraftserver.paperConfigurations.createWorldConfig(io.papermc.paper.configuration.PaperConfigurations.createWorldContextMap(convertable_conversionsession.levelDirectory.path(), iworlddataserver.getLevelName(), resourcekey.location(), spigotConfig, minecraftserver.registryAccess(), iworlddataserver.getGameRules()))); // Paper - create paper world configs
|
||||
+ super(iworlddataserver, resourcekey, minecraftserver.registryAccess(), worlddimension.type(), false, flag, i, minecraftserver.getMaxChainedNeighborUpdates(), gen, biomeProvider, env, spigotConfig -> minecraftserver.paperConfigurations.createWorldConfig(io.papermc.paper.configuration.PaperConfigurations.createWorldContextMap(convertable_conversionsession.levelDirectory.path(), iworlddataserver.getLevelName(), resourcekey.location(), spigotConfig, minecraftserver.registryAccess(), iworlddataserver.getGameRules())), executor); // Paper - create paper world configs; Async-Anti-Xray: Pass executor
|
||||
this.pvpMode = minecraftserver.isPvpAllowed();
|
||||
this.convertable = convertable_conversionsession;
|
||||
this.uuid = WorldUUID.getUUID(convertable_conversionsession.levelDirectory.path().toFile());
|
||||
diff --git a/src/main/java/net/minecraft/server/level/ServerPlayerGameMode.java b/src/main/java/net/minecraft/server/level/ServerPlayerGameMode.java
|
||||
index 415d9802ae4dd75b44055b8faf19672fa50c585f..e9dcdb1e09e84a9b451034ff4bdfa6eae2dd1c04 100644
|
||||
index c4bc1819cba3287c4a67ae5d00f8c4d6ab899732..f2dd272a01b4e946a6746865d55ebc9861f8361b 100644
|
||||
--- a/src/main/java/net/minecraft/server/level/ServerPlayerGameMode.java
|
||||
+++ b/src/main/java/net/minecraft/server/level/ServerPlayerGameMode.java
|
||||
@@ -50,7 +50,7 @@ import org.bukkit.event.player.PlayerInteractEvent;
|
||||
@@ -48,7 +48,7 @@ import org.bukkit.event.player.PlayerInteractEvent;
|
||||
public class ServerPlayerGameMode {
|
||||
|
||||
private static final Logger LOGGER = LogUtils.getLogger();
|
||||
@ -1129,7 +1129,7 @@ index 415d9802ae4dd75b44055b8faf19672fa50c585f..e9dcdb1e09e84a9b451034ff4bdfa6ea
|
||||
protected final ServerPlayer player;
|
||||
private GameType gameModeForPlayer;
|
||||
@Nullable
|
||||
@@ -334,6 +334,8 @@ public class ServerPlayerGameMode {
|
||||
@@ -332,6 +332,8 @@ public class ServerPlayerGameMode {
|
||||
}
|
||||
|
||||
}
|
||||
@ -1139,14 +1139,16 @@ index 415d9802ae4dd75b44055b8faf19672fa50c585f..e9dcdb1e09e84a9b451034ff4bdfa6ea
|
||||
|
||||
public void destroyAndAck(BlockPos pos, int sequence, String reason) {
|
||||
diff --git a/src/main/java/net/minecraft/server/network/PlayerChunkSender.java b/src/main/java/net/minecraft/server/network/PlayerChunkSender.java
|
||||
index 32634e45ac8433648e49e47e20081e15ad41ff15..dafa2cf7d3c49fc5bdcd68d2a952812774a1dfe4 100644
|
||||
index cdd66e6ce96e2613afe7f06ca8da3cfaa6704b2d..dafa2cf7d3c49fc5bdcd68d2a952812774a1dfe4 100644
|
||||
--- a/src/main/java/net/minecraft/server/network/PlayerChunkSender.java
|
||||
+++ b/src/main/java/net/minecraft/server/network/PlayerChunkSender.java
|
||||
@@ -79,7 +79,10 @@ public class PlayerChunkSender {
|
||||
@@ -78,8 +78,11 @@ public class PlayerChunkSender {
|
||||
}
|
||||
}
|
||||
|
||||
public static void sendChunk(ServerGamePacketListenerImpl handler, ServerLevel world, LevelChunk chunk) { // Paper - public
|
||||
- private static void sendChunk(ServerGamePacketListenerImpl handler, ServerLevel world, LevelChunk chunk) {
|
||||
- handler.send(new ClientboundLevelChunkWithLightPacket(chunk, world.getLightEngine(), null, null));
|
||||
+ public static void sendChunk(ServerGamePacketListenerImpl handler, ServerLevel world, LevelChunk chunk) { // Paper - public
|
||||
+ // Paper start - Anti-Xray
|
||||
+ final boolean shouldModify = world.chunkPacketBlockController.shouldModify(handler.player, chunk);
|
||||
+ handler.send(new ClientboundLevelChunkWithLightPacket(chunk, world.getLightEngine(), null, null, shouldModify));
|
||||
@ -1155,23 +1157,23 @@ index 32634e45ac8433648e49e47e20081e15ad41ff15..dafa2cf7d3c49fc5bdcd68d2a9528127
|
||||
if (io.papermc.paper.event.packet.PlayerChunkLoadEvent.getHandlerList().getRegisteredListeners().length > 0) {
|
||||
new io.papermc.paper.event.packet.PlayerChunkLoadEvent(new org.bukkit.craftbukkit.CraftChunk(chunk), handler.getPlayer().getBukkitEntity()).callEvent();
|
||||
diff --git a/src/main/java/net/minecraft/server/players/PlayerList.java b/src/main/java/net/minecraft/server/players/PlayerList.java
|
||||
index f6624d3fab88c4bd7199c8412f1977a6dab388ad..ced2417fdd87ee9624f459065a7abc9df4810850 100644
|
||||
index a4937d11b79cef41f3fbf79282c0c435e794dbfe..cde19fddfc9b1c8edbc565bec4f043803651313e 100644
|
||||
--- a/src/main/java/net/minecraft/server/players/PlayerList.java
|
||||
+++ b/src/main/java/net/minecraft/server/players/PlayerList.java
|
||||
@@ -414,7 +414,7 @@ public abstract class PlayerList {
|
||||
.getHolderOrThrow(net.minecraft.world.level.biome.Biomes.PLAINS);
|
||||
@@ -427,7 +427,7 @@ public abstract class PlayerList {
|
||||
.getHolderOrThrow(net.minecraft.world.level.biome.Biomes.PLAINS);
|
||||
player.connection.send(new net.minecraft.network.protocol.game.ClientboundLevelChunkWithLightPacket(
|
||||
new net.minecraft.world.level.chunk.EmptyLevelChunk(worldserver1, player.chunkPosition(), plains),
|
||||
- worldserver1.getLightEngine(), (java.util.BitSet)null, (java.util.BitSet) null)
|
||||
+ worldserver1.getLightEngine(), (java.util.BitSet)null, (java.util.BitSet) null, true)
|
||||
new net.minecraft.world.level.chunk.EmptyLevelChunk(worldserver1, player.chunkPosition(), plains),
|
||||
- worldserver1.getLightEngine(), (java.util.BitSet)null, (java.util.BitSet) null)
|
||||
+ worldserver1.getLightEngine(), (java.util.BitSet)null, (java.util.BitSet) null, true) // Paper - Anti-Xray
|
||||
);
|
||||
}
|
||||
// Paper end - Send empty chunk
|
||||
diff --git a/src/main/java/net/minecraft/world/level/Level.java b/src/main/java/net/minecraft/world/level/Level.java
|
||||
index 3272af72ae0609bb9c928d0e4a8ba2ca3d90d63a..c4ec80bbab850fe767a345d96f02103ca43eb3cb 100644
|
||||
index cef07ec3dfc8db3f3206fa2f5c2acf64c4b4aa65..ce6c9b82a64a32c4b952d1839260015b1a446365 100644
|
||||
--- a/src/main/java/net/minecraft/world/level/Level.java
|
||||
+++ b/src/main/java/net/minecraft/world/level/Level.java
|
||||
@@ -172,6 +172,7 @@ public abstract class Level implements LevelAccessor, AutoCloseable, ca.spottedl
|
||||
@@ -172,6 +172,7 @@ public abstract class Level implements LevelAccessor, AutoCloseable {
|
||||
}
|
||||
// Paper end - add paper world config
|
||||
|
||||
@ -1179,24 +1181,24 @@ index 3272af72ae0609bb9c928d0e4a8ba2ca3d90d63a..c4ec80bbab850fe767a345d96f02103c
|
||||
public final co.aikar.timings.WorldTimingsHandler timings; // Paper
|
||||
public static BlockPos lastPhysicsProblem; // Spigot
|
||||
private org.spigotmc.TickLimiter entityLimiter;
|
||||
@@ -683,7 +684,7 @@ public abstract class Level implements LevelAccessor, AutoCloseable, ca.spottedl
|
||||
}
|
||||
// Paper end - optimise random ticking
|
||||
@@ -206,7 +207,7 @@ public abstract class Level implements LevelAccessor, AutoCloseable {
|
||||
|
||||
- protected Level(WritableLevelData worlddatamutable, ResourceKey<Level> resourcekey, RegistryAccess iregistrycustom, Holder<DimensionType> holder, Supplier<ProfilerFiller> supplier, boolean flag, boolean flag1, long i, int j, org.bukkit.generator.ChunkGenerator gen, org.bukkit.generator.BiomeProvider biomeProvider, org.bukkit.World.Environment env, java.util.function.Function<org.spigotmc.SpigotWorldConfig, io.papermc.paper.configuration.WorldConfiguration> paperWorldConfigCreator) { // Paper - create paper world config
|
||||
+ protected Level(WritableLevelData worlddatamutable, ResourceKey<Level> resourcekey, RegistryAccess iregistrycustom, Holder<DimensionType> holder, Supplier<ProfilerFiller> supplier, boolean flag, boolean flag1, long i, int j, org.bukkit.generator.ChunkGenerator gen, org.bukkit.generator.BiomeProvider biomeProvider, org.bukkit.World.Environment env, java.util.function.Function<org.spigotmc.SpigotWorldConfig, io.papermc.paper.configuration.WorldConfiguration> paperWorldConfigCreator, java.util.concurrent.Executor executor) { // Paper - create paper world config & Anti-Xray
|
||||
public abstract ResourceKey<LevelStem> getTypeKey();
|
||||
|
||||
- protected Level(WritableLevelData worlddatamutable, ResourceKey<Level> resourcekey, RegistryAccess iregistrycustom, Holder<DimensionType> holder, boolean flag, boolean flag1, long i, int j, org.bukkit.generator.ChunkGenerator gen, org.bukkit.generator.BiomeProvider biomeProvider, org.bukkit.World.Environment env, java.util.function.Function<org.spigotmc.SpigotWorldConfig, io.papermc.paper.configuration.WorldConfiguration> paperWorldConfigCreator) { // Paper - create paper world config
|
||||
+ protected Level(WritableLevelData worlddatamutable, ResourceKey<Level> resourcekey, RegistryAccess iregistrycustom, Holder<DimensionType> holder, boolean flag, boolean flag1, long i, int j, org.bukkit.generator.ChunkGenerator gen, org.bukkit.generator.BiomeProvider biomeProvider, org.bukkit.World.Environment env, java.util.function.Function<org.spigotmc.SpigotWorldConfig, io.papermc.paper.configuration.WorldConfiguration> paperWorldConfigCreator, java.util.concurrent.Executor executor) { // Paper - create paper world config & Anti-Xray
|
||||
this.spigotConfig = new org.spigotmc.SpigotWorldConfig(((net.minecraft.world.level.storage.PrimaryLevelData) worlddatamutable).getLevelName()); // Spigot
|
||||
this.paperConfig = paperWorldConfigCreator.apply(this.spigotConfig); // Paper - create paper world config
|
||||
this.generator = gen;
|
||||
@@ -770,6 +771,7 @@ public abstract class Level implements LevelAccessor, AutoCloseable, ca.spottedl
|
||||
this.minSection = ca.spottedleaf.moonrise.common.util.WorldUtil.getMinSection(this);
|
||||
this.maxSection = ca.spottedleaf.moonrise.common.util.WorldUtil.getMaxSection(this);
|
||||
// Paper end - optimise collisions
|
||||
@@ -287,6 +288,7 @@ public abstract class Level implements LevelAccessor, AutoCloseable {
|
||||
this.timings = new co.aikar.timings.WorldTimingsHandler(this); // Paper - code below can generate new world and access timings
|
||||
this.entityLimiter = new org.spigotmc.TickLimiter(this.spigotConfig.entityMaxTickTime);
|
||||
this.tileLimiter = new org.spigotmc.TickLimiter(this.spigotConfig.tileMaxTickTime);
|
||||
+ this.chunkPacketBlockController = this.paperConfig().anticheat.antiXray.enabled ? new com.destroystokyo.paper.antixray.ChunkPacketBlockControllerAntiXray(this, executor) : com.destroystokyo.paper.antixray.ChunkPacketBlockController.NO_OPERATION_INSTANCE; // Paper - Anti-Xray
|
||||
}
|
||||
|
||||
// Paper start - Cancel hit for vanished players
|
||||
@@ -1047,6 +1049,7 @@ public abstract class Level implements LevelAccessor, AutoCloseable, ca.spottedl
|
||||
@@ -487,6 +489,7 @@ public abstract class Level implements LevelAccessor, AutoCloseable {
|
||||
// CraftBukkit end
|
||||
|
||||
BlockState iblockdata1 = chunk.setBlockState(pos, state, (flags & 64) != 0, (flags & 1024) == 0); // CraftBukkit custom NO_PLACE flag
|
||||
@ -1205,10 +1207,10 @@ index 3272af72ae0609bb9c928d0e4a8ba2ca3d90d63a..c4ec80bbab850fe767a345d96f02103c
|
||||
if (iblockdata1 == null) {
|
||||
// CraftBukkit start - remove blockstate if failed (or the same)
|
||||
diff --git a/src/main/java/net/minecraft/world/level/chunk/ChunkAccess.java b/src/main/java/net/minecraft/world/level/chunk/ChunkAccess.java
|
||||
index a7fc4b027cee8e1ed2678be7060040494a65682a..75c8125e20b70433fe9d143a3193d821043327c3 100644
|
||||
index a846dd210ed1de0dc3e8b686663ee346bff33dc8..63d7d6b93119d96d753230472df30a9dedd889dc 100644
|
||||
--- a/src/main/java/net/minecraft/world/level/chunk/ChunkAccess.java
|
||||
+++ b/src/main/java/net/minecraft/world/level/chunk/ChunkAccess.java
|
||||
@@ -159,7 +159,7 @@ public abstract class ChunkAccess implements BlockGetter, BiomeManager.NoiseBiom
|
||||
@@ -108,17 +108,17 @@ public abstract class ChunkAccess implements BiomeManager.NoiseBiomeSource, Ligh
|
||||
}
|
||||
}
|
||||
|
||||
@ -1216,8 +1218,7 @@ index a7fc4b027cee8e1ed2678be7060040494a65682a..75c8125e20b70433fe9d143a3193d821
|
||||
+ this.replaceMissingSections(biomeRegistry, this.sections); // Paper - Anti-Xray - make it a non-static method
|
||||
// CraftBukkit start
|
||||
this.biomeRegistry = biomeRegistry;
|
||||
// Paper start - rewrite chunk system
|
||||
@@ -176,10 +176,10 @@ public abstract class ChunkAccess implements BlockGetter, BiomeManager.NoiseBiom
|
||||
}
|
||||
public final Registry<Biome> biomeRegistry;
|
||||
// CraftBukkit end
|
||||
|
||||
@ -1231,39 +1232,39 @@ index a7fc4b027cee8e1ed2678be7060040494a65682a..75c8125e20b70433fe9d143a3193d821
|
||||
}
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/world/level/chunk/LevelChunk.java b/src/main/java/net/minecraft/world/level/chunk/LevelChunk.java
|
||||
index d94e24cfc56c195a47665c212f8fcc901648a4a1..b1a6dc25b04ab6a43e8d62378e14d88d1c60bbbe 100644
|
||||
index 325d1e38a72a4b30f30261267e9adfb8a8726b11..71dfd0abb930ecf4f1ba900c80c161fa2a858685 100644
|
||||
--- a/src/main/java/net/minecraft/world/level/chunk/LevelChunk.java
|
||||
+++ b/src/main/java/net/minecraft/world/level/chunk/LevelChunk.java
|
||||
@@ -91,7 +91,7 @@ public class LevelChunk extends ChunkAccess implements ca.spottedleaf.moonrise.p
|
||||
@@ -93,7 +93,7 @@ public class LevelChunk extends ChunkAccess {
|
||||
}
|
||||
|
||||
public LevelChunk(Level world, ChunkPos pos, UpgradeData upgradeData, LevelChunkTicks<Block> blockTickScheduler, LevelChunkTicks<Fluid> fluidTickScheduler, long inhabitedTime, @Nullable LevelChunkSection[] sectionArrayInitializer, @Nullable LevelChunk.PostLoadProcessor entityLoader, @Nullable BlendingData blendingData) {
|
||||
- super(pos, upgradeData, world, world.registryAccess().registryOrThrow(Registries.BIOME), inhabitedTime, sectionArrayInitializer, blendingData);
|
||||
+ super(pos, upgradeData, world, net.minecraft.server.MinecraftServer.getServer().registryAccess().registryOrThrow(Registries.BIOME), inhabitedTime, sectionArrayInitializer, blendingData); // Paper - Anti-Xray - The world isn't ready yet, use server singleton for registry
|
||||
- super(pos, upgradeData, world, world.registryAccess().lookupOrThrow(Registries.BIOME), inhabitedTime, sectionArrayInitializer, blendingData);
|
||||
+ super(pos, upgradeData, world, net.minecraft.server.MinecraftServer.getServer().registryAccess().lookupOrThrow(Registries.BIOME), inhabitedTime, sectionArrayInitializer, blendingData); // Paper - Anti-Xray - The world isn't ready yet, use server singleton for registry
|
||||
this.tickersInLevel = Maps.newHashMap();
|
||||
this.level = (ServerLevel) world; // CraftBukkit - type
|
||||
this.gameEventListenerRegistrySections = new Int2ObjectOpenHashMap();
|
||||
this.unsavedListener = (chunkcoordintpair1) -> {
|
||||
};
|
||||
diff --git a/src/main/java/net/minecraft/world/level/chunk/LevelChunkSection.java b/src/main/java/net/minecraft/world/level/chunk/LevelChunkSection.java
|
||||
index d7b8d984122ba6b6ef5a0be6e012a8828a1af22d..c3b1caa352b988ec44fa2b2eb0536517711f5460 100644
|
||||
index 52f44f14bbda60fe771c351e01e6ff470d7371e6..3dab36d00ea48101807ba40c7a7358b7eed12747 100644
|
||||
--- a/src/main/java/net/minecraft/world/level/chunk/LevelChunkSection.java
|
||||
+++ b/src/main/java/net/minecraft/world/level/chunk/LevelChunkSection.java
|
||||
@@ -55,9 +55,12 @@ public class LevelChunkSection implements ca.spottedleaf.moonrise.patches.block_
|
||||
@@ -39,9 +39,12 @@ public class LevelChunkSection {
|
||||
this.recalcBlockCounts();
|
||||
}
|
||||
|
||||
- public LevelChunkSection(Registry<Biome> biomeRegistry) {
|
||||
- this.states = new PalettedContainer<>(Block.BLOCK_STATE_REGISTRY, Blocks.AIR.defaultBlockState(), PalettedContainer.Strategy.SECTION_STATES);
|
||||
- this.biomes = new PalettedContainer<>(biomeRegistry.asHolderIdMap(), biomeRegistry.getHolderOrThrow(Biomes.PLAINS), PalettedContainer.Strategy.SECTION_BIOMES);
|
||||
- this.biomes = new PalettedContainer<>(biomeRegistry.asHolderIdMap(), biomeRegistry.getOrThrow(Biomes.PLAINS), PalettedContainer.Strategy.SECTION_BIOMES);
|
||||
+ // Paper start - Anti-Xray - Add parameters
|
||||
+ @Deprecated @io.papermc.paper.annotation.DoNotUse public LevelChunkSection(Registry<Biome> biomeRegistry) { this(biomeRegistry, null, null, 0); }
|
||||
+ public LevelChunkSection(Registry<Biome> biomeRegistry, net.minecraft.world.level.Level level, net.minecraft.world.level.ChunkPos chunkPos, int chunkSectionY) {
|
||||
+ // Paper end
|
||||
+ // Paper end
|
||||
+ this.states = new PalettedContainer<>(Block.BLOCK_STATE_REGISTRY, Blocks.AIR.defaultBlockState(), PalettedContainer.Strategy.SECTION_STATES, level == null || level.chunkPacketBlockController == null ? null : level.chunkPacketBlockController.getPresetBlockStates(level, chunkPos, chunkSectionY)); // Paper - Anti-Xray - Add preset block states
|
||||
+ this.biomes = new PalettedContainer<>(biomeRegistry.asHolderIdMap(), biomeRegistry.getHolderOrThrow(Biomes.PLAINS), PalettedContainer.Strategy.SECTION_BIOMES, null); // Paper - Anti-Xray - Add preset biomes
|
||||
+ this.biomes = new PalettedContainer<>(biomeRegistry.asHolderIdMap(), biomeRegistry.getOrThrow(Biomes.PLAINS), PalettedContainer.Strategy.SECTION_BIOMES, null); // Paper - Anti-Xray - Add preset biomes
|
||||
}
|
||||
|
||||
public BlockState getBlockState(int x, int y, int z) {
|
||||
@@ -236,10 +239,13 @@ public class LevelChunkSection implements ca.spottedleaf.moonrise.patches.block_
|
||||
@@ -178,10 +181,13 @@ public class LevelChunkSection {
|
||||
this.biomes = datapaletteblock;
|
||||
}
|
||||
|
||||
@ -1281,7 +1282,7 @@ index d7b8d984122ba6b6ef5a0be6e012a8828a1af22d..c3b1caa352b988ec44fa2b2eb0536517
|
||||
|
||||
public int getSerializedSize() {
|
||||
diff --git a/src/main/java/net/minecraft/world/level/chunk/PalettedContainer.java b/src/main/java/net/minecraft/world/level/chunk/PalettedContainer.java
|
||||
index 339cac6b34b9f2f53852cfcee821bec9e0286c50..13d3c877b006a4975e7370713e3919c661e7890f 100644
|
||||
index 112d1259dd37743076ff6c67ffd711d084ba8698..69d6f203366df658e1ade55d917f0aa2b8a49be9 100644
|
||||
--- a/src/main/java/net/minecraft/world/level/chunk/PalettedContainer.java
|
||||
+++ b/src/main/java/net/minecraft/world/level/chunk/PalettedContainer.java
|
||||
@@ -28,6 +28,7 @@ public class PalettedContainer<T> implements PaletteResize<T>, PalettedContainer
|
||||
@ -1289,7 +1290,7 @@ index 339cac6b34b9f2f53852cfcee821bec9e0286c50..13d3c877b006a4975e7370713e3919c6
|
||||
private final PaletteResize<T> dummyPaletteResize = (newSize, added) -> 0;
|
||||
public final IdMap<T> registry;
|
||||
+ private final T @org.jetbrains.annotations.Nullable [] presetValues; // Paper - Anti-Xray - Add preset values
|
||||
public volatile PalettedContainer.Data<T> data; // Paper - optimise collisions - public
|
||||
private volatile PalettedContainer.Data<T> data;
|
||||
private final PalettedContainer.Strategy strategy;
|
||||
// private final ThreadingDetector threadingDetector = new ThreadingDetector("PalettedContainer"); // Paper - unused
|
||||
@@ -40,14 +41,19 @@ public class PalettedContainer<T> implements PaletteResize<T>, PalettedContainer
|
||||
@ -1315,7 +1316,7 @@ index 339cac6b34b9f2f53852cfcee821bec9e0286c50..13d3c877b006a4975e7370713e3919c6
|
||||
)
|
||||
.map(result -> (PalettedContainerRO<T>)result);
|
||||
return codec(idList, entryCodec, paletteProvider, defaultValue, unpacker);
|
||||
@@ -71,25 +77,58 @@ public class PalettedContainer<T> implements PaletteResize<T>, PalettedContainer
|
||||
@@ -71,31 +77,65 @@ public class PalettedContainer<T> implements PaletteResize<T>, PalettedContainer
|
||||
);
|
||||
}
|
||||
|
||||
@ -1368,6 +1369,14 @@ index 339cac6b34b9f2f53852cfcee821bec9e0286c50..13d3c877b006a4975e7370713e3919c6
|
||||
this.data = data;
|
||||
}
|
||||
|
||||
- private PalettedContainer(PalettedContainer<T> container) {
|
||||
+ private PalettedContainer(PalettedContainer<T> container, T @org.jetbrains.annotations.Nullable [] presetValues) { // Paper - Anti-Xray - Add preset values
|
||||
+ this.presetValues = presetValues; // Paper - Anti-Xray - Add preset values
|
||||
this.registry = container.registry;
|
||||
this.strategy = container.strategy;
|
||||
this.data = container.data.copy(this);
|
||||
}
|
||||
|
||||
- public PalettedContainer(IdMap<T> idList, T object, PalettedContainer.Strategy paletteProvider) {
|
||||
+ // Paper start - Anti-Xray - Add preset values
|
||||
+ @Deprecated @io.papermc.paper.annotation.DoNotUse public PalettedContainer(IdMap<T> idList, T object, PalettedContainer.Strategy paletteProvider) { this(idList, object, paletteProvider, null); }
|
||||
@ -1377,7 +1386,7 @@ index 339cac6b34b9f2f53852cfcee821bec9e0286c50..13d3c877b006a4975e7370713e3919c6
|
||||
this.strategy = paletteProvider;
|
||||
this.registry = idList;
|
||||
this.data = this.createOrReuseData(null, 0);
|
||||
@@ -106,11 +145,33 @@ public class PalettedContainer<T> implements PaletteResize<T>, PalettedContainer
|
||||
@@ -112,11 +152,33 @@ public class PalettedContainer<T> implements PaletteResize<T>, PalettedContainer
|
||||
@Override
|
||||
public synchronized int onResize(int newBits, T object) { // Paper - synchronize
|
||||
PalettedContainer.Data<T> data = this.data;
|
||||
@ -1412,7 +1421,7 @@ index 339cac6b34b9f2f53852cfcee821bec9e0286c50..13d3c877b006a4975e7370713e3919c6
|
||||
|
||||
public T getAndSet(int x, int y, int z, T value) {
|
||||
this.acquire();
|
||||
@@ -177,24 +238,33 @@ public class PalettedContainer<T> implements PaletteResize<T>, PalettedContainer
|
||||
@@ -183,24 +245,33 @@ public class PalettedContainer<T> implements PaletteResize<T>, PalettedContainer
|
||||
data.palette.read(buf);
|
||||
buf.readLongArray(data.storage.getRaw());
|
||||
this.data = data;
|
||||
@ -1449,7 +1458,7 @@ index 339cac6b34b9f2f53852cfcee821bec9e0286c50..13d3c877b006a4975e7370713e3919c6
|
||||
) {
|
||||
List<T> list = serialized.paletteEntries();
|
||||
int i = paletteProvider.size();
|
||||
@@ -227,7 +297,7 @@ public class PalettedContainer<T> implements PaletteResize<T>, PalettedContainer
|
||||
@@ -233,7 +304,7 @@ public class PalettedContainer<T> implements PaletteResize<T>, PalettedContainer
|
||||
}
|
||||
}
|
||||
|
||||
@ -1458,12 +1467,12 @@ index 339cac6b34b9f2f53852cfcee821bec9e0286c50..13d3c877b006a4975e7370713e3919c6
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -284,12 +354,12 @@ public class PalettedContainer<T> implements PaletteResize<T>, PalettedContainer
|
||||
}
|
||||
@@ -291,12 +362,12 @@ public class PalettedContainer<T> implements PaletteResize<T>, PalettedContainer
|
||||
|
||||
@Override
|
||||
public PalettedContainer<T> copy() {
|
||||
- return new PalettedContainer<>(this.registry, this.strategy, this.data.copy());
|
||||
+ return new PalettedContainer<>(this.registry, this.strategy, this.data.copy(), this.presetValues); // Paper - Anti-Xray - Add preset values
|
||||
- return new PalettedContainer<>(this);
|
||||
+ return new PalettedContainer<>(this, this.presetValues); // Paper - Anti-Xray - Add preset values
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -1473,7 +1482,7 @@ index 339cac6b34b9f2f53852cfcee821bec9e0286c50..13d3c877b006a4975e7370713e3919c6
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -328,9 +398,18 @@ public class PalettedContainer<T> implements PaletteResize<T>, PalettedContainer
|
||||
@@ -335,9 +406,18 @@ public class PalettedContainer<T> implements PaletteResize<T>, PalettedContainer
|
||||
return 1 + this.palette.getSerializedSize() + VarInt.getByteSize(this.storage.getRaw().length) + this.storage.getRaw().length * 8;
|
||||
}
|
||||
|
||||
@ -1494,7 +1503,7 @@ index 339cac6b34b9f2f53852cfcee821bec9e0286c50..13d3c877b006a4975e7370713e3919c6
|
||||
}
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/world/level/chunk/PalettedContainerRO.java b/src/main/java/net/minecraft/world/level/chunk/PalettedContainerRO.java
|
||||
index 9a2bf744abd8916d492e901be889223591bac3fd..1dd415c96d17eff8e7555c33d3c52e57f2559fa5 100644
|
||||
index 303e59be721d0e16e8822cf4e407595348ee7abf..51f74dd7b276e858889803d7f341d735ea1d463a 100644
|
||||
--- a/src/main/java/net/minecraft/world/level/chunk/PalettedContainerRO.java
|
||||
+++ b/src/main/java/net/minecraft/world/level/chunk/PalettedContainerRO.java
|
||||
@@ -14,7 +14,10 @@ public interface PalettedContainerRO<T> {
|
||||
@ -1509,59 +1518,58 @@ index 9a2bf744abd8916d492e901be889223591bac3fd..1dd415c96d17eff8e7555c33d3c52e57
|
||||
|
||||
int getSerializedSize();
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/world/level/chunk/storage/ChunkSerializer.java b/src/main/java/net/minecraft/world/level/chunk/storage/ChunkSerializer.java
|
||||
index cb5196f0ff7b9a59927c60b9d24c987a150e69f1..711541a9b12b823c1da779ed6027a53e9078a733 100644
|
||||
--- a/src/main/java/net/minecraft/world/level/chunk/storage/ChunkSerializer.java
|
||||
+++ b/src/main/java/net/minecraft/world/level/chunk/storage/ChunkSerializer.java
|
||||
@@ -73,7 +73,7 @@ import org.slf4j.Logger;
|
||||
diff --git a/src/main/java/net/minecraft/world/level/chunk/storage/SerializableChunkData.java b/src/main/java/net/minecraft/world/level/chunk/storage/SerializableChunkData.java
|
||||
index b86b3bf713668999a21c4120b1d16c295531b2ad..57998a47fa39cac141226c75bd68d4b37e8424ae 100644
|
||||
--- a/src/main/java/net/minecraft/world/level/chunk/storage/SerializableChunkData.java
|
||||
+++ b/src/main/java/net/minecraft/world/level/chunk/storage/SerializableChunkData.java
|
||||
@@ -111,6 +111,7 @@ public record SerializableChunkData(Registry<Biome> biomeRegistry, ChunkPos chun
|
||||
|
||||
public class ChunkSerializer {
|
||||
@Nullable
|
||||
public static SerializableChunkData parse(LevelHeightAccessor world, RegistryAccess registryManager, CompoundTag nbt) {
|
||||
+ net.minecraft.server.level.ServerLevel serverLevel = (net.minecraft.server.level.ServerLevel) world; // Paper - Anti-Xray This is is seemingly only called from ChunkMap, where, we have a server level. We'll fight this later if needed.
|
||||
if (!nbt.contains("Status", 8)) {
|
||||
return null;
|
||||
} else {
|
||||
@@ -214,13 +215,17 @@ public record SerializableChunkData(Registry<Biome> biomeRegistry, ChunkPos chun
|
||||
|
||||
- public static final Codec<PalettedContainer<BlockState>> BLOCK_STATE_CODEC = PalettedContainer.codecRW(Block.BLOCK_STATE_REGISTRY, BlockState.CODEC, PalettedContainer.Strategy.SECTION_STATES, Blocks.AIR.defaultBlockState());
|
||||
+ public static final Codec<PalettedContainer<BlockState>> BLOCK_STATE_CODEC = PalettedContainer.codecRW(Block.BLOCK_STATE_REGISTRY, BlockState.CODEC, PalettedContainer.Strategy.SECTION_STATES, Blocks.AIR.defaultBlockState(), null); // Paper - Anti-Xray - Add preset block states
|
||||
private static final Logger LOGGER = LogUtils.getLogger();
|
||||
private static final String TAG_UPGRADE_DATA = "UpgradeData";
|
||||
private static final String BLOCK_TICKS_TAG = "block_ticks";
|
||||
@@ -141,13 +141,17 @@ public class ChunkSerializer {
|
||||
if (b0 >= world.getMinSectionY() && b0 <= world.getMaxSectionY()) {
|
||||
PalettedContainer datapaletteblock;
|
||||
+ // Paper start - Anti-Xray - Add preset block states
|
||||
+ BlockState[] presetBlockStates = serverLevel.chunkPacketBlockController.getPresetBlockStates(serverLevel, chunkcoordintpair, b0);
|
||||
+
|
||||
|
||||
if (k >= 0 && k < achunksection.length) {
|
||||
PalettedContainer datapaletteblock;
|
||||
+ // Paper start - Anti-Xray - Add preset block states
|
||||
+ BlockState[] presetBlockStates = world.chunkPacketBlockController.getPresetBlockStates(world, chunkPos, b0);
|
||||
if (nbttagcompound3.contains("block_states", 10)) {
|
||||
- datapaletteblock = (PalettedContainer) SerializableChunkData.BLOCK_STATE_CODEC.parse(NbtOps.INSTANCE, nbttagcompound3.getCompound("block_states")).promotePartial((s1) -> {
|
||||
+ Codec<PalettedContainer<BlockState>> blockStateCodec = presetBlockStates == null ? ChunkSerializer.BLOCK_STATE_CODEC : PalettedContainer.codecRW(Block.BLOCK_STATE_REGISTRY, BlockState.CODEC, PalettedContainer.Strategy.SECTION_STATES, Blocks.AIR.defaultBlockState(), presetBlockStates); // Paper - Anti-Xray
|
||||
+ datapaletteblock = blockStateCodec.parse(NbtOps.INSTANCE, nbttagcompound1.getCompound("block_states")).promotePartial((s1) -> { // Paper - Anti-Xray
|
||||
logErrors(chunkcoordintpair, b0, s1);
|
||||
}).getOrThrow(SerializableChunkData.ChunkReadException::new);
|
||||
} else {
|
||||
- datapaletteblock = new PalettedContainer<>(Block.BLOCK_STATE_REGISTRY, Blocks.AIR.defaultBlockState(), PalettedContainer.Strategy.SECTION_STATES);
|
||||
+ datapaletteblock = new PalettedContainer<>(Block.BLOCK_STATE_REGISTRY, Blocks.AIR.defaultBlockState(), PalettedContainer.Strategy.SECTION_STATES, presetBlockStates); // Paper - Anti-Xray
|
||||
}
|
||||
|
||||
if (nbttagcompound1.contains("block_states", 10)) {
|
||||
- datapaletteblock = (PalettedContainer) ChunkSerializer.BLOCK_STATE_CODEC.parse(NbtOps.INSTANCE, nbttagcompound1.getCompound("block_states")).promotePartial((s) -> {
|
||||
+ Codec<PalettedContainer<BlockState>> blockStateCodec = presetBlockStates == null ? ChunkSerializer.BLOCK_STATE_CODEC : PalettedContainer.codecRW(Block.BLOCK_STATE_REGISTRY, BlockState.CODEC, PalettedContainer.Strategy.SECTION_STATES, Blocks.AIR.defaultBlockState(), presetBlockStates);
|
||||
+ datapaletteblock = blockStateCodec.parse(NbtOps.INSTANCE, nbttagcompound1.getCompound("block_states")).promotePartial((s) -> {
|
||||
ChunkSerializer.logErrors(chunkPos, b0, s);
|
||||
}).getOrThrow(ChunkSerializer.ChunkReadException::new);
|
||||
} else {
|
||||
- datapaletteblock = new PalettedContainer<>(Block.BLOCK_STATE_REGISTRY, Blocks.AIR.defaultBlockState(), PalettedContainer.Strategy.SECTION_STATES);
|
||||
+ datapaletteblock = new PalettedContainer<>(Block.BLOCK_STATE_REGISTRY, Blocks.AIR.defaultBlockState(), PalettedContainer.Strategy.SECTION_STATES, presetBlockStates);
|
||||
+ // Paper end
|
||||
}
|
||||
PalettedContainer object; // CraftBukkit - read/write
|
||||
@@ -230,7 +235,7 @@ public record SerializableChunkData(Registry<Biome> biomeRegistry, ChunkPos chun
|
||||
logErrors(chunkcoordintpair, b0, s1);
|
||||
}).getOrThrow(SerializableChunkData.ChunkReadException::new);
|
||||
} else {
|
||||
- object = new PalettedContainer<>(iregistry.asHolderIdMap(), iregistry.getOrThrow(Biomes.PLAINS), PalettedContainer.Strategy.SECTION_BIOMES);
|
||||
+ object = new PalettedContainer<>(iregistry.asHolderIdMap(), iregistry.getOrThrow(Biomes.PLAINS), PalettedContainer.Strategy.SECTION_BIOMES, null); // Paper - Anti-Xray - Add preset biomes
|
||||
}
|
||||
|
||||
PalettedContainer object; // CraftBukkit - read/write
|
||||
@@ -157,7 +161,7 @@ public class ChunkSerializer {
|
||||
ChunkSerializer.logErrors(chunkPos, b0, s);
|
||||
}).getOrThrow(ChunkSerializer.ChunkReadException::new);
|
||||
} else {
|
||||
- object = new PalettedContainer<>(iregistry.asHolderIdMap(), iregistry.getHolderOrThrow(Biomes.PLAINS), PalettedContainer.Strategy.SECTION_BIOMES);
|
||||
+ object = new PalettedContainer<>(iregistry.asHolderIdMap(), iregistry.getHolderOrThrow(Biomes.PLAINS), PalettedContainer.Strategy.SECTION_BIOMES, null); // Paper - Anti-Xray - Add preset biomes
|
||||
}
|
||||
|
||||
LevelChunkSection chunksection = new LevelChunkSection(datapaletteblock, (PalettedContainer) object); // CraftBukkit - read/write
|
||||
@@ -339,7 +343,7 @@ public class ChunkSerializer {
|
||||
chunksection = new LevelChunkSection(datapaletteblock, (PalettedContainer) object); // CraftBukkit - read/write
|
||||
@@ -391,7 +396,7 @@ public record SerializableChunkData(Registry<Biome> biomeRegistry, ChunkPos chun
|
||||
|
||||
// CraftBukkit start - read/write
|
||||
private static Codec<PalettedContainer<Holder<Biome>>> makeBiomeCodecRW(Registry<Biome> iregistry) {
|
||||
- return PalettedContainer.codecRW(iregistry.asHolderIdMap(), iregistry.holderByNameCodec(), PalettedContainer.Strategy.SECTION_BIOMES, iregistry.getHolderOrThrow(Biomes.PLAINS));
|
||||
+ return PalettedContainer.codecRW(iregistry.asHolderIdMap(), iregistry.holderByNameCodec(), PalettedContainer.Strategy.SECTION_BIOMES, iregistry.getHolderOrThrow(Biomes.PLAINS), null); // Paper - Anti-Xray - Add preset biomes
|
||||
- return PalettedContainer.codecRW(iregistry.asHolderIdMap(), iregistry.holderByNameCodec(), PalettedContainer.Strategy.SECTION_BIOMES, iregistry.getOrThrow(Biomes.PLAINS));
|
||||
+ return PalettedContainer.codecRW(iregistry.asHolderIdMap(), iregistry.holderByNameCodec(), PalettedContainer.Strategy.SECTION_BIOMES, iregistry.getOrThrow(Biomes.PLAINS), null); // Paper - Anti-Xray - Add preset biomes
|
||||
}
|
||||
// CraftBukkit end
|
||||
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/CraftChunk.java b/src/main/java/org/bukkit/craftbukkit/CraftChunk.java
|
||||
index 33322b57b4c6922f4daad0f584733f0f24083911..45e262308aebafa377a2353661acdd122933b99e 100644
|
||||
index 5fc9e8e969debb3e15ed474b36a1c48b086d0449..f65cc95ab28e8a3b21eac2b16bd9ebe97e56e571 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/CraftChunk.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/CraftChunk.java
|
||||
@@ -56,7 +56,7 @@ public class CraftChunk implements Chunk {
|
||||
@ -1574,25 +1582,25 @@ index 33322b57b4c6922f4daad0f584733f0f24083911..45e262308aebafa377a2353661acdd12
|
||||
private static final byte[] EMPTY_LIGHT = new byte[2048];
|
||||
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/CraftServer.java b/src/main/java/org/bukkit/craftbukkit/CraftServer.java
|
||||
index 0bad47a4d45e9ca399de98edd0956efb90d21062..27f47383c8065cc3b421001028b6cba528c38865 100644
|
||||
index 6235d7caede85f4cf21dadde18d8080004672349..8548c4db6a1932d7de09bf27e583f51627f8c8ec 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/CraftServer.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/CraftServer.java
|
||||
@@ -2688,7 +2688,7 @@ public final class CraftServer implements Server {
|
||||
@@ -2655,7 +2655,7 @@ public final class CraftServer implements Server {
|
||||
public ChunkGenerator.ChunkData createChunkData(World world) {
|
||||
Preconditions.checkArgument(world != null, "World cannot be null");
|
||||
ServerLevel handle = ((CraftWorld) world).getHandle();
|
||||
- return new OldCraftChunkData(world.getMinHeight(), world.getMaxHeight(), handle.registryAccess().registryOrThrow(Registries.BIOME));
|
||||
+ return new OldCraftChunkData(world.getMinHeight(), world.getMaxHeight(), handle.registryAccess().registryOrThrow(Registries.BIOME), world); // Paper - Anti-Xray - Add parameters
|
||||
- return new OldCraftChunkData(world.getMinHeight(), world.getMaxHeight(), handle.registryAccess().lookupOrThrow(Registries.BIOME));
|
||||
+ return new OldCraftChunkData(world.getMinHeight(), world.getMaxHeight(), handle.registryAccess().lookupOrThrow(Registries.BIOME), world); // Paper - Anti-Xray - Add parameters
|
||||
}
|
||||
|
||||
@Override
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
|
||||
index 5ff343759cc0c5046a9d45e8f74d4e6ec63f0f91..359c5771f7e2a0843505787f051bb2a61e0dca57 100644
|
||||
index 149377347fc632358a8bb97e644b1c4ab9be413d..8367f0f344d42b6ccdfbe761be1735ac9a64bfab 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
|
||||
@@ -470,11 +470,16 @@ public class CraftWorld extends CraftRegionAccessor implements World {
|
||||
@@ -472,11 +472,16 @@ public class CraftWorld extends CraftRegionAccessor implements World {
|
||||
List<ServerPlayer> playersInRange = playerChunk.playerProvider.getPlayers(playerChunk.getPos(), false);
|
||||
if (playersInRange.isEmpty()) return true; // Paper - chunk system
|
||||
if (playersInRange.isEmpty()) return;
|
||||
|
||||
- ClientboundLevelChunkWithLightPacket refreshPacket = new ClientboundLevelChunkWithLightPacket(chunk, this.world.getLightEngine(), null, null);
|
||||
+ // Paper start - Anti-Xray bypass
|
||||
@ -1607,8 +1615,8 @@ index 5ff343759cc0c5046a9d45e8f74d4e6ec63f0f91..359c5771f7e2a0843505787f051bb2a6
|
||||
+ }));
|
||||
+ // Paper end - Anti-Xray bypass
|
||||
}
|
||||
// Paper - chunk system
|
||||
|
||||
});
|
||||
});
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/generator/OldCraftChunkData.java b/src/main/java/org/bukkit/craftbukkit/generator/OldCraftChunkData.java
|
||||
index e7f7a246e9c03e676dadfee59de87b8b2ac55ba3..03eb35d5c67f125c44cf46595c93d124ac7892b8 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/generator/OldCraftChunkData.java
|
In neuem Issue referenzieren
Einen Benutzer sperren