Mirror von
https://github.com/GeyserMC/Geyser.git
synchronisiert 2024-11-20 06:50:09 +01:00
Merge branch 'viaversion4.0.0' into feature/1.17
Dieser Commit ist enthalten in:
Commit
4f23066b88
@ -10,6 +10,13 @@
|
|||||||
</parent>
|
</parent>
|
||||||
<artifactId>bootstrap-spigot</artifactId>
|
<artifactId>bootstrap-spigot</artifactId>
|
||||||
|
|
||||||
|
<repositories>
|
||||||
|
<repository>
|
||||||
|
<id>viaversion-repo</id>
|
||||||
|
<url>https://repo.viaversion.com</url>
|
||||||
|
</repository>
|
||||||
|
</repositories>
|
||||||
|
|
||||||
<dependencies>
|
<dependencies>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.geysermc</groupId>
|
<groupId>org.geysermc</groupId>
|
||||||
@ -24,9 +31,9 @@
|
|||||||
<scope>provided</scope>
|
<scope>provided</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>us.myles</groupId>
|
<groupId>com.viaversion</groupId>
|
||||||
<artifactId>viaversion</artifactId>
|
<artifactId>viaversion</artifactId>
|
||||||
<version>3.2.0</version>
|
<version>4.0.0-1.17-pre3-SNAPSHOT</version>
|
||||||
<scope>provided</scope>
|
<scope>provided</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
|
@ -26,6 +26,10 @@
|
|||||||
package org.geysermc.platform.spigot;
|
package org.geysermc.platform.spigot;
|
||||||
|
|
||||||
import com.github.steveice10.mc.protocol.MinecraftConstants;
|
import com.github.steveice10.mc.protocol.MinecraftConstants;
|
||||||
|
import com.viaversion.viaversion.api.Via;
|
||||||
|
import com.viaversion.viaversion.api.data.MappingData;
|
||||||
|
import com.viaversion.viaversion.api.protocol.ProtocolPathEntry;
|
||||||
|
import com.viaversion.viaversion.api.protocol.version.ProtocolVersion;
|
||||||
import org.bukkit.Bukkit;
|
import org.bukkit.Bukkit;
|
||||||
import org.bukkit.plugin.java.JavaPlugin;
|
import org.bukkit.plugin.java.JavaPlugin;
|
||||||
import org.geysermc.common.PlatformType;
|
import org.geysermc.common.PlatformType;
|
||||||
@ -46,12 +50,6 @@ import org.geysermc.platform.spigot.command.SpigotCommandSender;
|
|||||||
import org.geysermc.platform.spigot.world.GeyserSpigot1_11CraftingListener;
|
import org.geysermc.platform.spigot.world.GeyserSpigot1_11CraftingListener;
|
||||||
import org.geysermc.platform.spigot.world.GeyserSpigotBlockPlaceListener;
|
import org.geysermc.platform.spigot.world.GeyserSpigotBlockPlaceListener;
|
||||||
import org.geysermc.platform.spigot.world.manager.*;
|
import org.geysermc.platform.spigot.world.manager.*;
|
||||||
import us.myles.ViaVersion.api.Pair;
|
|
||||||
import us.myles.ViaVersion.api.Via;
|
|
||||||
import us.myles.ViaVersion.api.data.MappingData;
|
|
||||||
import us.myles.ViaVersion.api.protocol.Protocol;
|
|
||||||
import us.myles.ViaVersion.api.protocol.ProtocolRegistry;
|
|
||||||
import us.myles.ViaVersion.api.protocol.ProtocolVersion;
|
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
@ -147,12 +145,18 @@ public class GeyserSpigotPlugin extends JavaPlugin implements GeyserBootstrap {
|
|||||||
|
|
||||||
this.geyserCommandManager = new GeyserSpigotCommandManager(this, connector);
|
this.geyserCommandManager = new GeyserSpigotCommandManager(this, connector);
|
||||||
|
|
||||||
boolean isViaVersion = (Bukkit.getPluginManager().getPlugin("ViaVersion") != null);
|
boolean isViaVersion = Bukkit.getPluginManager().getPlugin("ViaVersion") != null;
|
||||||
if (isViaVersion) {
|
if (isViaVersion) {
|
||||||
if (!isCompatible(Via.getAPI().getVersion().replace("-SNAPSHOT", ""), "3.2.0")) {
|
try {
|
||||||
|
// Ensure that we have the latest 4.0.0 changes and not an older ViaVersion version
|
||||||
|
Class.forName("com.viaversion.viaversion.api.ViaManager");
|
||||||
|
} catch (ClassNotFoundException e) {
|
||||||
geyserLogger.warning(LanguageUtils.getLocaleStringLog("geyser.bootstrap.viaversion.too_old",
|
geyserLogger.warning(LanguageUtils.getLocaleStringLog("geyser.bootstrap.viaversion.too_old",
|
||||||
"https://ci.viaversion.com/job/ViaVersion/"));
|
"https://ci.viaversion.com/job/ViaVersion-DEV/"));
|
||||||
isViaVersion = false;
|
isViaVersion = false;
|
||||||
|
if (this.geyserConfig.isDebugMode()) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Used to determine if Block.getBlockData() is present.
|
// Used to determine if Block.getBlockData() is present.
|
||||||
@ -311,14 +315,14 @@ public class GeyserSpigotPlugin extends JavaPlugin implements GeyserBootstrap {
|
|||||||
*/
|
*/
|
||||||
private boolean isViaVersionNeeded() {
|
private boolean isViaVersionNeeded() {
|
||||||
ProtocolVersion serverVersion = getServerProtocolVersion();
|
ProtocolVersion serverVersion = getServerProtocolVersion();
|
||||||
List<Pair<Integer, Protocol>> protocolList = ProtocolRegistry.getProtocolPath(MinecraftConstants.PROTOCOL_VERSION,
|
List<ProtocolPathEntry> protocolList = Via.getManager().getProtocolManager().getProtocolPath(MinecraftConstants.PROTOCOL_VERSION,
|
||||||
serverVersion.getVersion());
|
serverVersion.getVersion());
|
||||||
if (protocolList == null) {
|
if (protocolList == null) {
|
||||||
// No translation needed!
|
// No translation needed!
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
for (int i = protocolList.size() - 1; i >= 0; i--) {
|
for (int i = protocolList.size() - 1; i >= 0; i--) {
|
||||||
MappingData mappingData = protocolList.get(i).getValue().getMappingData();
|
MappingData mappingData = protocolList.get(i).getProtocol().getMappingData();
|
||||||
if (mappingData != null) {
|
if (mappingData != null) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -34,6 +34,12 @@ import com.github.steveice10.mc.protocol.data.game.recipe.data.ShapelessRecipeDa
|
|||||||
import com.nukkitx.protocol.bedrock.data.inventory.CraftingData;
|
import com.nukkitx.protocol.bedrock.data.inventory.CraftingData;
|
||||||
import com.nukkitx.protocol.bedrock.data.inventory.ItemData;
|
import com.nukkitx.protocol.bedrock.data.inventory.ItemData;
|
||||||
import com.nukkitx.protocol.bedrock.packet.CraftingDataPacket;
|
import com.nukkitx.protocol.bedrock.packet.CraftingDataPacket;
|
||||||
|
import com.viaversion.viaversion.api.Via;
|
||||||
|
import com.viaversion.viaversion.api.data.MappingData;
|
||||||
|
import com.viaversion.viaversion.api.protocol.ProtocolPathEntry;
|
||||||
|
import com.viaversion.viaversion.api.protocol.version.ProtocolVersion;
|
||||||
|
import com.viaversion.viaversion.protocols.protocol1_13to1_12_2.Protocol1_13To1_12_2;
|
||||||
|
import com.viaversion.viaversion.util.Pair;
|
||||||
import org.bukkit.Bukkit;
|
import org.bukkit.Bukkit;
|
||||||
import org.bukkit.event.EventHandler;
|
import org.bukkit.event.EventHandler;
|
||||||
import org.bukkit.event.Listener;
|
import org.bukkit.event.Listener;
|
||||||
@ -45,12 +51,6 @@ import org.geysermc.connector.GeyserConnector;
|
|||||||
import org.geysermc.connector.network.session.GeyserSession;
|
import org.geysermc.connector.network.session.GeyserSession;
|
||||||
import org.geysermc.connector.network.translators.item.ItemTranslator;
|
import org.geysermc.connector.network.translators.item.ItemTranslator;
|
||||||
import org.geysermc.connector.network.translators.item.RecipeRegistry;
|
import org.geysermc.connector.network.translators.item.RecipeRegistry;
|
||||||
import us.myles.ViaVersion.api.Pair;
|
|
||||||
import us.myles.ViaVersion.api.data.MappingData;
|
|
||||||
import us.myles.ViaVersion.api.protocol.Protocol;
|
|
||||||
import us.myles.ViaVersion.api.protocol.ProtocolRegistry;
|
|
||||||
import us.myles.ViaVersion.api.protocol.ProtocolVersion;
|
|
||||||
import us.myles.ViaVersion.protocols.protocol1_13to1_12_2.Protocol1_13To1_12_2;
|
|
||||||
|
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
|
|
||||||
@ -68,12 +68,12 @@ public class GeyserSpigot1_11CraftingListener implements Listener {
|
|||||||
/**
|
/**
|
||||||
* The list of all protocols from the client's version to 1.13.
|
* The list of all protocols from the client's version to 1.13.
|
||||||
*/
|
*/
|
||||||
private final List<Pair<Integer, Protocol>> protocolList;
|
private final List<ProtocolPathEntry> protocolList;
|
||||||
|
|
||||||
public GeyserSpigot1_11CraftingListener(GeyserConnector connector) {
|
public GeyserSpigot1_11CraftingListener(GeyserConnector connector) {
|
||||||
this.connector = connector;
|
this.connector = connector;
|
||||||
this.mappingData1_12to1_13 = ProtocolRegistry.getProtocol(Protocol1_13To1_12_2.class).getMappingData();
|
this.mappingData1_12to1_13 = Via.getManager().getProtocolManager().getProtocol(Protocol1_13To1_12_2.class).getMappingData();
|
||||||
this.protocolList = ProtocolRegistry.getProtocolPath(MinecraftConstants.PROTOCOL_VERSION,
|
this.protocolList = Via.getManager().getProtocolManager().getProtocolPath(MinecraftConstants.PROTOCOL_VERSION,
|
||||||
ProtocolVersion.v1_13.getVersion());
|
ProtocolVersion.v1_13.getVersion());
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -187,7 +187,7 @@ public class GeyserSpigot1_11CraftingListener implements Listener {
|
|||||||
}
|
}
|
||||||
|
|
||||||
for (int i = protocolList.size() - 1; i >= 0; i--) {
|
for (int i = protocolList.size() - 1; i >= 0; i--) {
|
||||||
MappingData mappingData = protocolList.get(i).getValue().getMappingData();
|
MappingData mappingData = protocolList.get(i).getProtocol().getMappingData();
|
||||||
if (mappingData != null) {
|
if (mappingData != null) {
|
||||||
itemId = mappingData.getNewItemId(itemId);
|
itemId = mappingData.getNewItemId(itemId);
|
||||||
}
|
}
|
||||||
|
@ -25,6 +25,8 @@
|
|||||||
|
|
||||||
package org.geysermc.platform.spigot.world.manager;
|
package org.geysermc.platform.spigot.world.manager;
|
||||||
|
|
||||||
|
import com.viaversion.viaversion.api.Via;
|
||||||
|
import com.viaversion.viaversion.protocols.protocol1_13to1_12_2.storage.BlockStorage;
|
||||||
import org.bukkit.Bukkit;
|
import org.bukkit.Bukkit;
|
||||||
import org.bukkit.entity.Player;
|
import org.bukkit.entity.Player;
|
||||||
import org.bukkit.plugin.Plugin;
|
import org.bukkit.plugin.Plugin;
|
||||||
@ -32,8 +34,6 @@ import org.geysermc.connector.network.session.GeyserSession;
|
|||||||
import org.geysermc.connector.network.translators.world.block.BlockTranslator;
|
import org.geysermc.connector.network.translators.world.block.BlockTranslator;
|
||||||
import org.geysermc.geyser.adapters.spigot.SpigotAdapters;
|
import org.geysermc.geyser.adapters.spigot.SpigotAdapters;
|
||||||
import org.geysermc.geyser.adapters.spigot.SpigotWorldAdapter;
|
import org.geysermc.geyser.adapters.spigot.SpigotWorldAdapter;
|
||||||
import us.myles.ViaVersion.api.Via;
|
|
||||||
import us.myles.ViaVersion.protocols.protocol1_13to1_12_2.storage.BlockStorage;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Used with ViaVersion and pre-1.13.
|
* Used with ViaVersion and pre-1.13.
|
||||||
@ -54,7 +54,7 @@ public class GeyserSpigot1_12NativeWorldManager extends GeyserSpigot1_12WorldMan
|
|||||||
return BlockTranslator.JAVA_AIR_ID;
|
return BlockTranslator.JAVA_AIR_ID;
|
||||||
}
|
}
|
||||||
// Get block entity storage
|
// Get block entity storage
|
||||||
BlockStorage storage = Via.getManager().getConnection(player.getUniqueId()).get(BlockStorage.class);
|
BlockStorage storage = Via.getManager().getConnectionManager().getConnectedClient(player.getUniqueId()).get(BlockStorage.class);
|
||||||
int blockId = adapter.getBlockAt(player.getWorld(), x, y, z);
|
int blockId = adapter.getBlockAt(player.getWorld(), x, y, z);
|
||||||
return getLegacyBlock(storage, blockId, x, y, z);
|
return getLegacyBlock(storage, blockId, x, y, z);
|
||||||
}
|
}
|
||||||
|
@ -25,21 +25,19 @@
|
|||||||
|
|
||||||
package org.geysermc.platform.spigot.world.manager;
|
package org.geysermc.platform.spigot.world.manager;
|
||||||
|
|
||||||
|
import com.viaversion.viaversion.api.Via;
|
||||||
|
import com.viaversion.viaversion.api.data.MappingData;
|
||||||
|
import com.viaversion.viaversion.api.minecraft.Position;
|
||||||
|
import com.viaversion.viaversion.api.protocol.ProtocolPathEntry;
|
||||||
|
import com.viaversion.viaversion.api.protocol.version.ProtocolVersion;
|
||||||
|
import com.viaversion.viaversion.protocols.protocol1_13to1_12_2.Protocol1_13To1_12_2;
|
||||||
|
import com.viaversion.viaversion.protocols.protocol1_13to1_12_2.storage.BlockStorage;
|
||||||
import org.bukkit.Bukkit;
|
import org.bukkit.Bukkit;
|
||||||
import org.bukkit.block.Block;
|
import org.bukkit.block.Block;
|
||||||
import org.bukkit.entity.Player;
|
import org.bukkit.entity.Player;
|
||||||
import org.bukkit.plugin.Plugin;
|
import org.bukkit.plugin.Plugin;
|
||||||
import org.geysermc.connector.network.session.GeyserSession;
|
import org.geysermc.connector.network.session.GeyserSession;
|
||||||
import org.geysermc.connector.network.translators.world.block.BlockTranslator;
|
import org.geysermc.connector.network.translators.world.block.BlockTranslator;
|
||||||
import us.myles.ViaVersion.api.Pair;
|
|
||||||
import us.myles.ViaVersion.api.Via;
|
|
||||||
import us.myles.ViaVersion.api.data.MappingData;
|
|
||||||
import us.myles.ViaVersion.api.minecraft.Position;
|
|
||||||
import us.myles.ViaVersion.api.protocol.Protocol;
|
|
||||||
import us.myles.ViaVersion.api.protocol.ProtocolRegistry;
|
|
||||||
import us.myles.ViaVersion.api.protocol.ProtocolVersion;
|
|
||||||
import us.myles.ViaVersion.protocols.protocol1_13to1_12_2.Protocol1_13To1_12_2;
|
|
||||||
import us.myles.ViaVersion.protocols.protocol1_13to1_12_2.storage.BlockStorage;
|
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
@ -58,12 +56,12 @@ public class GeyserSpigot1_12WorldManager extends GeyserSpigotWorldManager {
|
|||||||
/**
|
/**
|
||||||
* The list of all protocols from the client's version to 1.13.
|
* The list of all protocols from the client's version to 1.13.
|
||||||
*/
|
*/
|
||||||
private final List<Pair<Integer, Protocol>> protocolList;
|
private final List<ProtocolPathEntry> protocolList;
|
||||||
|
|
||||||
public GeyserSpigot1_12WorldManager(Plugin plugin) {
|
public GeyserSpigot1_12WorldManager(Plugin plugin) {
|
||||||
super(plugin);
|
super(plugin);
|
||||||
this.mappingData1_12to1_13 = ProtocolRegistry.getProtocol(Protocol1_13To1_12_2.class).getMappingData();
|
this.mappingData1_12to1_13 = Via.getManager().getProtocolManager().getProtocol(Protocol1_13To1_12_2.class).getMappingData();
|
||||||
this.protocolList = ProtocolRegistry.getProtocolPath(CLIENT_PROTOCOL_VERSION,
|
this.protocolList = Via.getManager().getProtocolManager().getProtocolPath(CLIENT_PROTOCOL_VERSION,
|
||||||
ProtocolVersion.v1_13.getVersion());
|
ProtocolVersion.v1_13.getVersion());
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -79,7 +77,7 @@ public class GeyserSpigot1_12WorldManager extends GeyserSpigotWorldManager {
|
|||||||
return BlockTranslator.JAVA_AIR_ID;
|
return BlockTranslator.JAVA_AIR_ID;
|
||||||
}
|
}
|
||||||
// Get block entity storage
|
// Get block entity storage
|
||||||
BlockStorage storage = Via.getManager().getConnection(player.getUniqueId()).get(BlockStorage.class);
|
BlockStorage storage = Via.getManager().getConnectionManager().getConnectedClient(player.getUniqueId()).get(BlockStorage.class);
|
||||||
Block block = player.getWorld().getBlockAt(x, y, z);
|
Block block = player.getWorld().getBlockAt(x, y, z);
|
||||||
// Black magic that gets the old block state ID
|
// Black magic that gets the old block state ID
|
||||||
int blockId = (block.getType().getId() << 4) | (block.getData() & 0xF);
|
int blockId = (block.getType().getId() << 4) | (block.getData() & 0xF);
|
||||||
@ -107,7 +105,7 @@ public class GeyserSpigot1_12WorldManager extends GeyserSpigotWorldManager {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
for (int i = protocolList.size() - 1; i >= 0; i--) {
|
for (int i = protocolList.size() - 1; i >= 0; i--) {
|
||||||
MappingData mappingData = protocolList.get(i).getValue().getMappingData();
|
MappingData mappingData = protocolList.get(i).getProtocol().getMappingData();
|
||||||
if (mappingData != null) {
|
if (mappingData != null) {
|
||||||
blockId = mappingData.getNewBlockStateId(blockId);
|
blockId = mappingData.getNewBlockStateId(blockId);
|
||||||
}
|
}
|
||||||
|
@ -26,16 +26,15 @@
|
|||||||
package org.geysermc.platform.spigot.world.manager;
|
package org.geysermc.platform.spigot.world.manager;
|
||||||
|
|
||||||
import com.github.steveice10.mc.protocol.MinecraftConstants;
|
import com.github.steveice10.mc.protocol.MinecraftConstants;
|
||||||
|
import com.viaversion.viaversion.api.Via;
|
||||||
|
import com.viaversion.viaversion.api.data.MappingData;
|
||||||
|
import com.viaversion.viaversion.api.protocol.ProtocolPathEntry;
|
||||||
|
import com.viaversion.viaversion.api.protocol.version.ProtocolVersion;
|
||||||
import it.unimi.dsi.fastutil.ints.Int2IntMap;
|
import it.unimi.dsi.fastutil.ints.Int2IntMap;
|
||||||
import it.unimi.dsi.fastutil.ints.Int2IntOpenHashMap;
|
import it.unimi.dsi.fastutil.ints.Int2IntOpenHashMap;
|
||||||
import it.unimi.dsi.fastutil.ints.IntList;
|
import it.unimi.dsi.fastutil.ints.IntList;
|
||||||
import org.geysermc.connector.network.session.GeyserSession;
|
import org.geysermc.connector.network.session.GeyserSession;
|
||||||
import org.geysermc.platform.spigot.GeyserSpigotPlugin;
|
import org.geysermc.platform.spigot.GeyserSpigotPlugin;
|
||||||
import us.myles.ViaVersion.api.Pair;
|
|
||||||
import us.myles.ViaVersion.api.data.MappingData;
|
|
||||||
import us.myles.ViaVersion.api.protocol.Protocol;
|
|
||||||
import us.myles.ViaVersion.api.protocol.ProtocolRegistry;
|
|
||||||
import us.myles.ViaVersion.api.protocol.ProtocolVersion;
|
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
@ -51,13 +50,13 @@ public class GeyserSpigotLegacyNativeWorldManager extends GeyserSpigotNativeWorl
|
|||||||
IntList allBlockStates = adapter.getAllBlockStates();
|
IntList allBlockStates = adapter.getAllBlockStates();
|
||||||
oldToNewBlockId = new Int2IntOpenHashMap(allBlockStates.size());
|
oldToNewBlockId = new Int2IntOpenHashMap(allBlockStates.size());
|
||||||
ProtocolVersion serverVersion = plugin.getServerProtocolVersion();
|
ProtocolVersion serverVersion = plugin.getServerProtocolVersion();
|
||||||
List<Pair<Integer, Protocol>> protocolList = ProtocolRegistry.getProtocolPath(MinecraftConstants.PROTOCOL_VERSION,
|
List<ProtocolPathEntry> protocolList = Via.getManager().getProtocolManager().getProtocolPath(MinecraftConstants.PROTOCOL_VERSION,
|
||||||
serverVersion.getVersion());
|
serverVersion.getVersion());
|
||||||
for (int oldBlockId : allBlockStates) {
|
for (int oldBlockId : allBlockStates) {
|
||||||
int newBlockId = oldBlockId;
|
int newBlockId = oldBlockId;
|
||||||
// protocolList should *not* be null; we checked for that before initializing this class
|
// protocolList should *not* be null; we checked for that before initializing this class
|
||||||
for (int i = protocolList.size() - 1; i >= 0; i--) {
|
for (int i = protocolList.size() - 1; i >= 0; i--) {
|
||||||
MappingData mappingData = protocolList.get(i).getValue().getMappingData();
|
MappingData mappingData = protocolList.get(i).getProtocol().getMappingData();
|
||||||
if (mappingData != null) {
|
if (mappingData != null) {
|
||||||
newBlockId = mappingData.getNewBlockStateId(newBlockId);
|
newBlockId = mappingData.getNewBlockStateId(newBlockId);
|
||||||
}
|
}
|
||||||
|
4
pom.xml
4
pom.xml
@ -61,10 +61,6 @@
|
|||||||
<enabled>true</enabled>
|
<enabled>true</enabled>
|
||||||
</snapshots>
|
</snapshots>
|
||||||
</repository>
|
</repository>
|
||||||
<repository>
|
|
||||||
<id>viaversion-repo</id>
|
|
||||||
<url>https://repo.viaversion.com</url>
|
|
||||||
</repository>
|
|
||||||
<repository>
|
<repository>
|
||||||
<id>sonatype</id>
|
<id>sonatype</id>
|
||||||
<url>https://oss.sonatype.org/content/repositories/snapshots/</url>
|
<url>https://oss.sonatype.org/content/repositories/snapshots/</url>
|
||||||
|
Laden…
In neuem Issue referenzieren
Einen Benutzer sperren