From 72234ac706d79986a778d461cf6848cbd21a3c4d Mon Sep 17 00:00:00 2001 From: Felix Cravic Date: Sun, 21 Jun 2020 22:11:56 +0200 Subject: [PATCH] Added PlayerPreLoginEvent --- .../net/minestom/server/entity/Entity.java | 9 +++ .../minestom/server/entity/EntityManager.java | 33 +++++++++ .../net/minestom/server/entity/Player.java | 17 +++-- .../event/player/PlayerPreLoginEvent.java | 71 +++++++++++++++++++ 4 files changed, 124 insertions(+), 6 deletions(-) create mode 100644 src/main/java/net/minestom/server/event/player/PlayerPreLoginEvent.java diff --git a/src/main/java/net/minestom/server/entity/Entity.java b/src/main/java/net/minestom/server/entity/Entity.java index a0a83f32a..7a778aec0 100644 --- a/src/main/java/net/minestom/server/entity/Entity.java +++ b/src/main/java/net/minestom/server/entity/Entity.java @@ -539,6 +539,15 @@ public abstract class Entity implements Viewable, EventHandler, DataContainer { return uuid; } + /** + * Change the internal entity UUID, mostly unsafe + * + * @param uuid the new entity uuid + */ + protected void setUuid(UUID uuid) { + this.uuid = uuid; + } + /** * Return false just after instantiation, set to true after calling {@link #setInstance(Instance)} * diff --git a/src/main/java/net/minestom/server/entity/EntityManager.java b/src/main/java/net/minestom/server/entity/EntityManager.java index 82d813e5b..0146f3e45 100644 --- a/src/main/java/net/minestom/server/entity/EntityManager.java +++ b/src/main/java/net/minestom/server/entity/EntityManager.java @@ -2,6 +2,7 @@ package net.minestom.server.entity; import net.minestom.server.MinecraftServer; import net.minestom.server.event.player.PlayerLoginEvent; +import net.minestom.server.event.player.PlayerPreLoginEvent; import net.minestom.server.instance.Chunk; import net.minestom.server.instance.Instance; import net.minestom.server.instance.InstanceManager; @@ -9,8 +10,10 @@ import net.minestom.server.utils.thread.MinestomThread; import net.minestom.server.utils.validate.Check; import java.util.Set; +import java.util.UUID; import java.util.concurrent.ConcurrentLinkedQueue; import java.util.concurrent.ExecutorService; +import java.util.function.Consumer; public final class EntityManager { @@ -178,8 +181,38 @@ public final class EntityManager { } } + /** + * Call the player initialization callbacks and the event {@link PlayerPreLoginEvent} + * If the player hasn't been kicked, add him to the waiting list + *

+ * Can be considered as a pre-init thing + * + * @param player the player to add + */ public void addWaitingPlayer(Player player) { + + // Init player (register events) + for (Consumer playerInitialization : MinecraftServer.getConnectionManager().getPlayerInitializations()) { + playerInitialization.accept(player); + } + + // Call pre login event + PlayerPreLoginEvent playerPreLoginEvent = new PlayerPreLoginEvent(player, player.getUsername(), player.getUuid()); + player.callEvent(PlayerPreLoginEvent.class, playerPreLoginEvent); + + // Ignore the player if he has been disconnected (kick) + final boolean online = player.isOnline(); + if (!online) + return; + + // Add him to the list and change his username/uuid if changed this.waitingPlayers.add(player); + + String username = playerPreLoginEvent.getUsername(); + UUID uuid = playerPreLoginEvent.getPlayerUuid(); + + player.setUsername(username); + player.setUuid(uuid); } /** diff --git a/src/main/java/net/minestom/server/entity/Player.java b/src/main/java/net/minestom/server/entity/Player.java index e2ec8adb9..347cd5ee1 100644 --- a/src/main/java/net/minestom/server/entity/Player.java +++ b/src/main/java/net/minestom/server/entity/Player.java @@ -167,12 +167,6 @@ public class Player extends LivingEntity implements CommandSender { * Init the player and spawn him */ protected void init() { - - // Init player (register events) - for (Consumer playerInitialization : MinecraftServer.getConnectionManager().getPlayerInitializations()) { - playerInitialization.accept(this); - } - // TODO complete login sequence with optionals packets JoinGamePacket joinGamePacket = new JoinGamePacket(); joinGamePacket.entityId = getEntityId(); @@ -950,6 +944,16 @@ public class Player extends LivingEntity implements CommandSender { return username; } + /** + * Change the internal player name, used for the {@link PlayerPreLoginEvent} + * mostly unsafe outside of it + * + * @param username the new player name + */ + protected void setUsername(String username) { + this.username = username; + } + private void sendChangeGameStatePacket(ChangeGameStatePacket.Reason reason, float value) { ChangeGameStatePacket changeGameStatePacket = new ChangeGameStatePacket(); changeGameStatePacket.reason = reason; @@ -1289,6 +1293,7 @@ public class Player extends LivingEntity implements CommandSender { disconnectPacket.message = Chat.toJsonString(textComponent); playerConnection.sendPacket(disconnectPacket); playerConnection.disconnect(); + playerConnection.refreshOnline(false); } /** diff --git a/src/main/java/net/minestom/server/event/player/PlayerPreLoginEvent.java b/src/main/java/net/minestom/server/event/player/PlayerPreLoginEvent.java new file mode 100644 index 000000000..59f98a6fe --- /dev/null +++ b/src/main/java/net/minestom/server/event/player/PlayerPreLoginEvent.java @@ -0,0 +1,71 @@ +package net.minestom.server.event.player; + +import net.minestom.server.entity.Player; +import net.minestom.server.event.Event; +import net.minestom.server.utils.validate.Check; + +import java.util.UUID; + +/** + * Called before the player initialization, it can be used to kick the player before any connection + * or to change its final username/uuid + */ +public class PlayerPreLoginEvent extends Event { + + private Player player; + private String username; + private UUID playerUuid; + + public PlayerPreLoginEvent(Player player, String username, UUID playerUuid) { + this.player = player; + this.username = username; + this.playerUuid = playerUuid; + } + + /** + * Get the player who is trying to connect + * + * @return the player + */ + public Player getPlayer() { + return player; + } + + /** + * Get the player username + * + * @return the player username + */ + public String getUsername() { + return username; + } + + /** + * Change the player username + * + * @param username the new player username + */ + public void setUsername(String username) { + Check.notNull(username, "The player username cannot be null"); + this.username = username; + } + + /** + * Get the player uuid + * + * @return the player uuid + */ + public UUID getPlayerUuid() { + return playerUuid; + } + + /** + * Change the player uuid + * + * @param playerUuid the new player uuid + */ + public void setPlayerUuid(UUID playerUuid) { + Check.notNull(playerUuid, "The player uuid cannot be null"); + this.playerUuid = playerUuid; + } +}