Prevent retrieving null managers before their initialization and added annotations in ConnectionManager

This commit is contained in:
themode 2020-10-26 15:15:56 +01:00
parent 06f2ed6065
commit 44c912d7ec
2 changed files with 65 additions and 18 deletions

View File

@ -50,12 +50,14 @@ import net.minestom.server.utils.validate.Check;
import net.minestom.server.world.Difficulty; import net.minestom.server.world.Difficulty;
import net.minestom.server.world.DimensionTypeManager; import net.minestom.server.world.DimensionTypeManager;
import net.minestom.server.world.biomes.BiomeManager; import net.minestom.server.world.biomes.BiomeManager;
import org.jetbrains.annotations.Nullable;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import java.io.IOException; import java.io.IOException;
import java.net.Proxy; import java.net.Proxy;
import java.security.KeyPair; import java.security.KeyPair;
import java.util.Objects;
/** /**
* The main server class used to start the server and retrieve all the managers. * The main server class used to start the server and retrieve all the managers.
@ -64,6 +66,7 @@ import java.security.KeyPair;
* You should register all of your dimensions, biomes, commands, events, etc... in-between. * You should register all of your dimensions, biomes, commands, events, etc... in-between.
*/ */
public class MinecraftServer { public class MinecraftServer {
@Getter @Getter
private final static Logger LOGGER = LoggerFactory.getLogger(MinecraftServer.class); private final static Logger LOGGER = LoggerFactory.getLogger(MinecraftServer.class);
@ -134,6 +137,7 @@ public class MinecraftServer {
private static MinecraftServer minecraftServer; private static MinecraftServer minecraftServer;
// Data // Data
private static boolean initialized;
private static boolean started; private static boolean started;
private static int chunkViewDistance = 10; private static int chunkViewDistance = 10;
@ -207,6 +211,8 @@ public class MinecraftServer {
LOGGER.error("An error happened during resource gathering. Minestom will attempt to load anyway, but things may not work, and crashes can happen.", e); LOGGER.error("An error happened during resource gathering. Minestom will attempt to load anyway, but things may not work, and crashes can happen.", e);
} }
initialized = true;
minecraftServer = new MinecraftServer(); minecraftServer = new MinecraftServer();
return minecraftServer; return minecraftServer;
@ -283,6 +289,7 @@ public class MinecraftServer {
* @return the packet listener manager * @return the packet listener manager
*/ */
public static PacketListenerManager getPacketListenerManager() { public static PacketListenerManager getPacketListenerManager() {
checkInitStatus(packetListenerManager);
return packetListenerManager; return packetListenerManager;
} }
@ -292,6 +299,7 @@ public class MinecraftServer {
* @return the netty server * @return the netty server
*/ */
public static NettyServer getNettyServer() { public static NettyServer getNettyServer() {
checkInitStatus(nettyServer);
return nettyServer; return nettyServer;
} }
@ -301,6 +309,7 @@ public class MinecraftServer {
* @return the instance manager * @return the instance manager
*/ */
public static InstanceManager getInstanceManager() { public static InstanceManager getInstanceManager() {
checkInitStatus(instanceManager);
return instanceManager; return instanceManager;
} }
@ -310,6 +319,7 @@ public class MinecraftServer {
* @return the block manager * @return the block manager
*/ */
public static BlockManager getBlockManager() { public static BlockManager getBlockManager() {
checkInitStatus(blockManager);
return blockManager; return blockManager;
} }
@ -319,6 +329,7 @@ public class MinecraftServer {
* @return the entity manager * @return the entity manager
*/ */
public static EntityManager getEntityManager() { public static EntityManager getEntityManager() {
checkInitStatus(entityManager);
return entityManager; return entityManager;
} }
@ -328,6 +339,7 @@ public class MinecraftServer {
* @return the command manager * @return the command manager
*/ */
public static CommandManager getCommandManager() { public static CommandManager getCommandManager() {
checkInitStatus(commandManager);
return commandManager; return commandManager;
} }
@ -337,6 +349,7 @@ public class MinecraftServer {
* @return the recipe manager * @return the recipe manager
*/ */
public static RecipeManager getRecipeManager() { public static RecipeManager getRecipeManager() {
checkInitStatus(recipeManager);
return recipeManager; return recipeManager;
} }
@ -346,6 +359,7 @@ public class MinecraftServer {
* @return the storage manager * @return the storage manager
*/ */
public static StorageManager getStorageManager() { public static StorageManager getStorageManager() {
checkInitStatus(storageManager);
return storageManager; return storageManager;
} }
@ -355,6 +369,7 @@ public class MinecraftServer {
* @return the data manager * @return the data manager
*/ */
public static DataManager getDataManager() { public static DataManager getDataManager() {
checkInitStatus(dataManager);
return dataManager; return dataManager;
} }
@ -364,6 +379,7 @@ public class MinecraftServer {
* @return the team manager * @return the team manager
*/ */
public static TeamManager getTeamManager() { public static TeamManager getTeamManager() {
checkInitStatus(teamManager);
return teamManager; return teamManager;
} }
@ -373,6 +389,7 @@ public class MinecraftServer {
* @return the scheduler manager * @return the scheduler manager
*/ */
public static SchedulerManager getSchedulerManager() { public static SchedulerManager getSchedulerManager() {
checkInitStatus(schedulerManager);
return schedulerManager; return schedulerManager;
} }
@ -382,6 +399,7 @@ public class MinecraftServer {
* @return the benchmark manager * @return the benchmark manager
*/ */
public static BenchmarkManager getBenchmarkManager() { public static BenchmarkManager getBenchmarkManager() {
checkInitStatus(benchmarkManager);
return benchmarkManager; return benchmarkManager;
} }
@ -391,6 +409,7 @@ public class MinecraftServer {
* @return the connection manager * @return the connection manager
*/ */
public static ConnectionManager getConnectionManager() { public static ConnectionManager getConnectionManager() {
checkInitStatus(connectionManager);
return connectionManager; return connectionManager;
} }
@ -475,6 +494,7 @@ public class MinecraftServer {
* @return the response data consumer * @return the response data consumer
*/ */
public static ResponseDataConsumer getResponseDataConsumer() { public static ResponseDataConsumer getResponseDataConsumer() {
checkInitStatus(responseDataConsumer);
return responseDataConsumer; return responseDataConsumer;
} }
@ -484,6 +504,7 @@ public class MinecraftServer {
* @return the loot table manager * @return the loot table manager
*/ */
public static LootTableManager getLootTableManager() { public static LootTableManager getLootTableManager() {
checkInitStatus(lootTableManager);
return lootTableManager; return lootTableManager;
} }
@ -493,6 +514,7 @@ public class MinecraftServer {
* @return the dimension manager * @return the dimension manager
*/ */
public static DimensionTypeManager getDimensionTypeManager() { public static DimensionTypeManager getDimensionTypeManager() {
checkInitStatus(dimensionTypeManager);
return dimensionTypeManager; return dimensionTypeManager;
} }
@ -502,6 +524,7 @@ public class MinecraftServer {
* @return the biome manager * @return the biome manager
*/ */
public static BiomeManager getBiomeManager() { public static BiomeManager getBiomeManager() {
checkInitStatus(biomeManager);
return biomeManager; return biomeManager;
} }
@ -511,6 +534,7 @@ public class MinecraftServer {
* @return the advancement manager * @return the advancement manager
*/ */
public static AdvancementManager getAdvancementManager() { public static AdvancementManager getAdvancementManager() {
checkInitStatus(advancementManager);
return advancementManager; return advancementManager;
} }
@ -520,6 +544,7 @@ public class MinecraftServer {
* @return the extension manager * @return the extension manager
*/ */
public static ExtensionManager getExtensionManager() { public static ExtensionManager getExtensionManager() {
checkInitStatus(extensionManager);
return extensionManager; return extensionManager;
} }
@ -529,6 +554,7 @@ public class MinecraftServer {
* @return the tag manager * @return the tag manager
*/ */
public static TagManager getTagManager() { public static TagManager getTagManager() {
checkInitStatus(tagManager);
return tagManager; return tagManager;
} }
@ -538,6 +564,7 @@ public class MinecraftServer {
* @return the update manager * @return the update manager
*/ */
public static UpdateManager getUpdateManager() { public static UpdateManager getUpdateManager() {
checkInitStatus(updateManager);
return updateManager; return updateManager;
} }
@ -549,6 +576,9 @@ public class MinecraftServer {
* @param responseDataConsumer the response data consumer, can be null * @param responseDataConsumer the response data consumer, can be null
*/ */
public void start(String address, int port, ResponseDataConsumer responseDataConsumer) { public void start(String address, int port, ResponseDataConsumer responseDataConsumer) {
Check.stateCondition(!initialized, "#start can only be called after #init");
Check.stateCondition(started, "The server is already started");
LOGGER.info("Starting Minestom server."); LOGGER.info("Starting Minestom server.");
MinecraftServer.responseDataConsumer = responseDataConsumer; MinecraftServer.responseDataConsumer = responseDataConsumer;
updateManager.start(); updateManager.start();
@ -592,4 +622,10 @@ public class MinecraftServer {
LOGGER.info("Minestom server stopped successfully."); LOGGER.info("Minestom server stopped successfully.");
} }
private static void checkInitStatus(@Nullable Object object) {
Check.stateCondition(Objects.isNull(object),
"You cannot access the manager before MinecraftServer#init, " +
"if you are developing an extension be sure to retrieve them at least after Extension#preInitialize");
}
} }

View File

@ -7,6 +7,8 @@ import net.minestom.server.listener.manager.PacketConsumer;
import net.minestom.server.network.packet.client.login.LoginStartPacket; import net.minestom.server.network.packet.client.login.LoginStartPacket;
import net.minestom.server.network.packet.server.play.ChatMessagePacket; import net.minestom.server.network.packet.server.play.ChatMessagePacket;
import net.minestom.server.network.player.PlayerConnection; import net.minestom.server.network.player.PlayerConnection;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.*; import java.util.*;
import java.util.concurrent.CopyOnWriteArrayList; import java.util.concurrent.CopyOnWriteArrayList;
@ -37,7 +39,7 @@ public final class ConnectionManager {
* @param connection the player connection * @param connection the player connection
* @return the player linked to the connection * @return the player linked to the connection
*/ */
public Player getPlayer(PlayerConnection connection) { public Player getPlayer(@NotNull PlayerConnection connection) {
return connectionPlayerMap.get(connection); return connectionPlayerMap.get(connection);
} }
@ -46,6 +48,7 @@ public final class ConnectionManager {
* *
* @return an unmodifiable collection containing all the online players * @return an unmodifiable collection containing all the online players
*/ */
@NotNull
public Collection<Player> getOnlinePlayers() { public Collection<Player> getOnlinePlayers() {
return Collections.unmodifiableCollection(players); return Collections.unmodifiableCollection(players);
} }
@ -56,9 +59,10 @@ public final class ConnectionManager {
* This can cause issue if two or more players have the same username. * This can cause issue if two or more players have the same username.
* *
* @param username the player username (ignoreCase) * @param username the player username (ignoreCase)
* @return the first player who validate the username condition * @return the first player who validate the username condition, null if none was found
*/ */
public Player getPlayer(String username) { @Nullable
public Player getPlayer(@NotNull String username) {
for (Player player : getOnlinePlayers()) { for (Player player : getOnlinePlayers()) {
if (player.getUsername().equalsIgnoreCase(username)) if (player.getUsername().equalsIgnoreCase(username))
return player; return player;
@ -72,9 +76,10 @@ public final class ConnectionManager {
* This can cause issue if two or more players have the same UUID. * This can cause issue if two or more players have the same UUID.
* *
* @param uuid the player UUID * @param uuid the player UUID
* @return the first player who validate the UUID condition * @return the first player who validate the UUID condition, null if none was found
*/ */
public Player getPlayer(UUID uuid) { @Nullable
public Player getPlayer(@NotNull UUID uuid) {
for (Player player : getOnlinePlayers()) { for (Player player : getOnlinePlayers()) {
if (player.getUuid().equals(uuid)) if (player.getUuid().equals(uuid))
return player; return player;
@ -88,7 +93,7 @@ public final class ConnectionManager {
* @param jsonMessage the message to send, probably a {@link net.minestom.server.chat.ColoredText} or {@link net.minestom.server.chat.RichMessage} * @param jsonMessage the message to send, probably a {@link net.minestom.server.chat.ColoredText} or {@link net.minestom.server.chat.RichMessage}
* @param condition the condition to receive the message * @param condition the condition to receive the message
*/ */
public void broadcastMessage(JsonMessage jsonMessage, Function<Player, Boolean> condition) { public void broadcastMessage(@NotNull JsonMessage jsonMessage, @Nullable Function<Player, Boolean> condition) {
final Collection<Player> recipients = getRecipients(condition); final Collection<Player> recipients = getRecipients(condition);
if (!recipients.isEmpty()) { if (!recipients.isEmpty()) {
@ -102,17 +107,17 @@ public final class ConnectionManager {
* *
* @param jsonMessage the message to send, probably a {@link net.minestom.server.chat.ColoredText} or {@link net.minestom.server.chat.RichMessage} * @param jsonMessage the message to send, probably a {@link net.minestom.server.chat.ColoredText} or {@link net.minestom.server.chat.RichMessage}
*/ */
public void broadcastMessage(JsonMessage jsonMessage) { public void broadcastMessage(@NotNull JsonMessage jsonMessage) {
broadcastMessage(jsonMessage, null); broadcastMessage(jsonMessage, null);
} }
private void broadcastJson(String json, Collection<Player> recipients) { private void broadcastJson(@NotNull String json, @NotNull Collection<Player> recipients) {
ChatMessagePacket chatMessagePacket = ChatMessagePacket chatMessagePacket =
new ChatMessagePacket(json, ChatMessagePacket.Position.SYSTEM_MESSAGE); new ChatMessagePacket(json, ChatMessagePacket.Position.SYSTEM_MESSAGE);
PacketWriterUtils.writeAndSend(recipients, chatMessagePacket); PacketWriterUtils.writeAndSend(recipients, chatMessagePacket);
} }
private Collection<Player> getRecipients(Function<Player, Boolean> condition) { private Collection<Player> getRecipients(@Nullable Function<Player, Boolean> condition) {
Collection<Player> recipients; Collection<Player> recipients;
// Get the recipients // Get the recipients
@ -135,6 +140,7 @@ public final class ConnectionManager {
* *
* @return an unmodifiable list of packet's consumers * @return an unmodifiable list of packet's consumers
*/ */
@NotNull
public List<PacketConsumer> getReceivePacketConsumers() { public List<PacketConsumer> getReceivePacketConsumers() {
return Collections.unmodifiableList(receivePacketConsumers); return Collections.unmodifiableList(receivePacketConsumers);
} }
@ -144,7 +150,7 @@ public final class ConnectionManager {
* *
* @param packetConsumer the packet consumer * @param packetConsumer the packet consumer
*/ */
public void onPacketReceive(PacketConsumer packetConsumer) { public void onPacketReceive(@NotNull PacketConsumer packetConsumer) {
this.receivePacketConsumers.add(packetConsumer); this.receivePacketConsumers.add(packetConsumer);
} }
@ -153,10 +159,11 @@ public final class ConnectionManager {
* <p> * <p>
* Shouldn't be override if already defined. * Shouldn't be override if already defined.
* *
* @param uuidProvider the new player connection uuid provider * @param uuidProvider the new player connection uuid provider,
* setting it to null would apply a random UUID for each player connection
* @see #getPlayerConnectionUuid(PlayerConnection, String) * @see #getPlayerConnectionUuid(PlayerConnection, String)
*/ */
public void setUuidProvider(UuidProvider uuidProvider) { public void setUuidProvider(@Nullable UuidProvider uuidProvider) {
this.uuidProvider = uuidProvider; this.uuidProvider = uuidProvider;
} }
@ -166,10 +173,12 @@ public final class ConnectionManager {
* to give the player the right {@link UUID}. * to give the player the right {@link UUID}.
* *
* @param playerConnection the player connection * @param playerConnection the player connection
* @param username the username given by the connection
* @return the uuid based on {@code playerConnection} * @return the uuid based on {@code playerConnection}
* return a random UUID if no UUID provider is defined see {@link #setUuidProvider(UuidProvider)} * return a random UUID if no UUID provider is defined see {@link #setUuidProvider(UuidProvider)}
*/ */
public UUID getPlayerConnectionUuid(PlayerConnection playerConnection, String username) { @NotNull
public UUID getPlayerConnectionUuid(@NotNull PlayerConnection playerConnection, @NotNull String username) {
if (uuidProvider == null) if (uuidProvider == null)
return UUID.randomUUID(); return UUID.randomUUID();
return uuidProvider.provide(playerConnection, username); return uuidProvider.provide(playerConnection, username);
@ -180,7 +189,7 @@ public final class ConnectionManager {
* *
* @param playerProvider the new {@link PlayerProvider}, can be set to null to apply the default provider * @param playerProvider the new {@link PlayerProvider}, can be set to null to apply the default provider
*/ */
public void setPlayerProvider(PlayerProvider playerProvider) { public void setPlayerProvider(@Nullable PlayerProvider playerProvider) {
this.playerProvider = playerProvider; this.playerProvider = playerProvider;
} }
@ -189,6 +198,7 @@ public final class ConnectionManager {
* *
* @return the current {@link PlayerProvider} * @return the current {@link PlayerProvider}
*/ */
@NotNull
public PlayerProvider getPlayerProvider() { public PlayerProvider getPlayerProvider() {
return playerProvider == null ? playerProvider = Player::new : playerProvider; return playerProvider == null ? playerProvider = Player::new : playerProvider;
} }
@ -198,6 +208,7 @@ public final class ConnectionManager {
* *
* @return an unmodifiable list containing all the {@link Player} initialization consumer * @return an unmodifiable list containing all the {@link Player} initialization consumer
*/ */
@NotNull
public List<Consumer<Player>> getPlayerInitializations() { public List<Consumer<Player>> getPlayerInitializations() {
return Collections.unmodifiableList(playerInitializations); return Collections.unmodifiableList(playerInitializations);
} }
@ -208,7 +219,7 @@ public final class ConnectionManager {
* *
* @param playerInitialization the {@link Player} initialization consumer * @param playerInitialization the {@link Player} initialization consumer
*/ */
public void addPlayerInitialization(Consumer<Player> playerInitialization) { public void addPlayerInitialization(@NotNull Consumer<Player> playerInitialization) {
this.playerInitializations.add(playerInitialization); this.playerInitializations.add(playerInitialization);
} }
@ -220,7 +231,7 @@ public final class ConnectionManager {
* *
* @param player the player to add * @param player the player to add
*/ */
public void createPlayer(Player player) { public void createPlayer(@NotNull Player player) {
this.players.add(player); this.players.add(player);
this.connectionPlayerMap.put(player.getPlayerConnection(), player); this.connectionPlayerMap.put(player.getPlayerConnection(), player);
} }
@ -232,7 +243,7 @@ public final class ConnectionManager {
* @param username the new player username * @param username the new player username
* @param connection the new player connection * @param connection the new player connection
*/ */
public void createPlayer(UUID uuid, String username, PlayerConnection connection) { public void createPlayer(@NotNull UUID uuid, @NotNull String username, @NotNull PlayerConnection connection) {
final Player player = getPlayerProvider().createPlayer(uuid, username, connection); final Player player = getPlayerProvider().createPlayer(uuid, username, connection);
createPlayer(player); createPlayer(player);
} }
@ -244,7 +255,7 @@ public final class ConnectionManager {
* *
* @param connection the player connection * @param connection the player connection
*/ */
public void removePlayer(PlayerConnection connection) { public void removePlayer(@NotNull PlayerConnection connection) {
final Player player = this.connectionPlayerMap.get(connection); final Player player = this.connectionPlayerMap.get(connection);
if (player == null) if (player == null)
return; return;