diff --git a/src/main/java/net/minestom/server/MinecraftServer.java b/src/main/java/net/minestom/server/MinecraftServer.java index c8ee70346..fe291a08f 100644 --- a/src/main/java/net/minestom/server/MinecraftServer.java +++ b/src/main/java/net/minestom/server/MinecraftServer.java @@ -9,9 +9,10 @@ import net.minestom.server.advancements.AdvancementManager; import net.minestom.server.benchmark.BenchmarkManager; import net.minestom.server.command.CommandManager; import net.minestom.server.data.DataManager; +import net.minestom.server.data.DataType; +import net.minestom.server.data.SerializableData; import net.minestom.server.entity.EntityManager; import net.minestom.server.entity.EntityType; -import net.minestom.server.entity.Player; import net.minestom.server.extras.mojangAuth.MojangCrypt; import net.minestom.server.fluids.Fluid; import net.minestom.server.gamedata.loottables.LootTableManager; @@ -20,6 +21,8 @@ import net.minestom.server.instance.Biome; import net.minestom.server.instance.InstanceManager; import net.minestom.server.instance.block.Block; import net.minestom.server.instance.block.BlockManager; +import net.minestom.server.instance.block.CustomBlock; +import net.minestom.server.instance.block.rule.BlockPlacementRule; import net.minestom.server.item.Enchantment; import net.minestom.server.item.Material; import net.minestom.server.listener.manager.PacketListenerManager; @@ -80,10 +83,10 @@ public class MinecraftServer { public static final int CHUNK_VIEW_DISTANCE = 10; public static final int ENTITY_VIEW_DISTANCE = 5; public static final int COMPRESSION_THRESHOLD = 256; - // Can be modified at performance cost when decreased + // Can be modified at performance cost when increased + public static final int TICK_PER_SECOND = 20; private static final int MS_TO_SEC = 1000; - public static final int TICK_MS = MS_TO_SEC / 20; - public static final int TICK_PER_SECOND = MS_TO_SEC / TICK_MS; + public static final int TICK_MS = MS_TO_SEC / TICK_PER_SECOND; //Extras @Getter @@ -91,7 +94,6 @@ public class MinecraftServer { private static boolean fixLighting = true; //Rate Limiting - @Getter @Setter private static int rateLimit = 0; // Networking @@ -208,96 +210,227 @@ public class MinecraftServer { PacketWriterUtils.writeAndSend(connectionManager.getOnlinePlayers(), brandMessage); } + /** + * Get the max number of packets a client can send over 1 second + * + * @return the packet count limit over 1 second + */ + public static int getRateLimit() { + return rateLimit; + } + + /** + * Change the number of packet a client can send over 1 second without being disconnected + * + * @param rateLimit the number of packet, 0 to disable + */ + public static void setRateLimit(int rateLimit) { + MinecraftServer.rateLimit = rateLimit; + } + + /** + * Get the server difficulty showed in game option + * + * @return the server difficulty + */ public static Difficulty getDifficulty() { return difficulty; } + /** + * Change the server difficulty and send the appropriate packet to all connected clients + * + * @param difficulty the new server difficulty + */ public static void setDifficulty(Difficulty difficulty) { MinecraftServer.difficulty = difficulty; - for (Player player : connectionManager.getOnlinePlayers()) { - ServerDifficultyPacket serverDifficultyPacket = new ServerDifficultyPacket(); - serverDifficultyPacket.difficulty = difficulty; - serverDifficultyPacket.locked = true; - player.getPlayerConnection().sendPacket(serverDifficultyPacket); - } + + // The difficulty packet + ServerDifficultyPacket serverDifficultyPacket = new ServerDifficultyPacket(); + serverDifficultyPacket.difficulty = difficulty; + serverDifficultyPacket.locked = true; // Can only be modified on singleplayer + // Send the packet to all online players + PacketWriterUtils.writeAndSend(connectionManager.getOnlinePlayers(), serverDifficultyPacket); } + /** + * Get the manager handling all incoming packets + * + * @return the packet listener manager + */ public static PacketListenerManager getPacketListenerManager() { return packetListenerManager; } + /** + * Get the netty server + * + * @return the netty server + */ public static NettyServer getNettyServer() { return nettyServer; } + /** + * Get the manager handling all registered instances + * + * @return the instance manager + */ public static InstanceManager getInstanceManager() { return instanceManager; } + /** + * Get the manager handling {@link CustomBlock} and {@link BlockPlacementRule} + * + * @return the block manager + */ public static BlockManager getBlockManager() { return blockManager; } + /** + * Get the manager handling waiting players + * + * @return the entity manager + */ public static EntityManager getEntityManager() { return entityManager; } + /** + * Get the manager handling commands + * + * @return the command manager + */ public static CommandManager getCommandManager() { return commandManager; } + /** + * Get the manager handling recipes show to the clients + * + * @return the recipe manager + */ public static RecipeManager getRecipeManager() { return recipeManager; } + /** + * Get the manager handling storage + * + * @return the storage manager + */ public static StorageManager getStorageManager() { return storageManager; } + /** + * Get the manager handling {@link DataType} used by {@link SerializableData} + * + * @return the data manager + */ public static DataManager getDataManager() { return dataManager; } + /** + * Get the manager handling teams + * + * @return the team manager + */ public static TeamManager getTeamManager() { return teamManager; } + /** + * Get the manager handling scheduled tasks + * + * @return the scheduler manager + */ public static SchedulerManager getSchedulerManager() { return schedulerManager; } + /** + * Get the manager handling server monitoring + * + * @return the benchmark manager + */ public static BenchmarkManager getBenchmarkManager() { return benchmarkManager; } + /** + * Get the manager handling server connections + * + * @return the connection manager + */ public static ConnectionManager getConnectionManager() { return connectionManager; } + /** + * Get the consumer executed to show server-list data + * + * @return the response data consumer + */ public static ResponseDataConsumer getResponseDataConsumer() { return responseDataConsumer; } + /** + * Get the manager handling loot tables + * + * @return the loot table manager + */ public static LootTableManager getLootTableManager() { return lootTableManager; } + /** + * Get the manager handling dimensions + * + * @return the dimension manager + */ public static DimensionTypeManager getDimensionTypeManager() { return dimensionTypeManager; } + /** + * Get the manager handling advancements + * + * @return the advancement manager + */ public static AdvancementManager getAdvancementManager() { return advancementManager; } + /** + * Get the manager handling tags + * + * @return the tag manager + */ public static TagManager getTagManager() { return tagManager; } + /** + * Get the manager handling the server ticks + * + * @return the update manager + */ public static UpdateManager getUpdateManager() { return updateManager; } + /** + * Start the server + * + * @param address the server address + * @param port the server port + * @param responseDataConsumer the response data consumer, can be null + */ public void start(String address, int port, ResponseDataConsumer responseDataConsumer) { LOGGER.info("Starting Minestom server."); MinecraftServer.responseDataConsumer = responseDataConsumer; @@ -306,6 +439,12 @@ public class MinecraftServer { LOGGER.info("Minestom server started successfully."); } + /** + * Start the server + * + * @param address the server address + * @param port the server port + */ public void start(String address, int port) { start(address, port, null); } diff --git a/src/main/java/net/minestom/server/entity/Entity.java b/src/main/java/net/minestom/server/entity/Entity.java index 242f8be4d..6e4ff7561 100644 --- a/src/main/java/net/minestom/server/entity/Entity.java +++ b/src/main/java/net/minestom/server/entity/Entity.java @@ -14,7 +14,10 @@ import net.minestom.server.event.entity.EntitySpawnEvent; import net.minestom.server.event.entity.EntityTickEvent; import net.minestom.server.event.entity.EntityVelocityEvent; import net.minestom.server.event.handler.EventHandler; -import net.minestom.server.instance.*; +import net.minestom.server.instance.Chunk; +import net.minestom.server.instance.Instance; +import net.minestom.server.instance.InstanceManager; +import net.minestom.server.instance.WorldBorder; import net.minestom.server.instance.block.CustomBlock; import net.minestom.server.network.packet.PacketWriter; import net.minestom.server.network.packet.server.play.*; @@ -634,13 +637,11 @@ public abstract class Entity implements Viewable, EventHandler, DataContainer { * * @param instance the new instance of the entity * @throws NullPointerException if {@code instance} is null - * @throws IllegalStateException if {@code instance} has not been registered in - * {@link InstanceManager#createInstanceContainer()} or - * {@link InstanceManager#createSharedInstance(InstanceContainer)} + * @throws IllegalStateException if {@code instance} has not been registered in {@link InstanceManager} */ public void setInstance(Instance instance) { Check.notNull(instance, "instance cannot be null!"); - Check.stateCondition(!MinecraftServer.getInstanceManager().getInstances().contains(instance), + Check.stateCondition(!instance.isRegistered(), "Instances need to be registered with InstanceManager#createInstanceContainer or InstanceManager#createSharedInstance"); if (this.instance != null) { diff --git a/src/main/java/net/minestom/server/instance/Instance.java b/src/main/java/net/minestom/server/instance/Instance.java index fbca1d2da..a86c8274d 100644 --- a/src/main/java/net/minestom/server/instance/Instance.java +++ b/src/main/java/net/minestom/server/instance/Instance.java @@ -49,6 +49,8 @@ public abstract class Instance implements BlockModifier, EventHandler, DataConta protected static final BlockManager BLOCK_MANAGER = MinecraftServer.getBlockManager(); protected static final UpdateManager UPDATE_MANAGER = MinecraftServer.getUpdateManager(); + private boolean registered; + private DimensionType dimensionType; private WorldBorder worldBorder; @@ -306,6 +308,26 @@ public abstract class Instance implements BlockModifier, EventHandler, DataConta // + /** + * Get if the instance has been registered in {@link InstanceManager} + * + * @return true if the instance has been registered + */ + public boolean isRegistered() { + return registered; + } + + /** + * Change the registered field + *
+ * WARNING: should only be used by {@link InstanceManager} + * + * @param registered true to mark the instance as registered + */ + protected void setRegistered(boolean registered) { + this.registered = registered; + } + /** * Get the instance dimension * diff --git a/src/main/java/net/minestom/server/instance/InstanceContainer.java b/src/main/java/net/minestom/server/instance/InstanceContainer.java index 0bf10a310..b7b812ceb 100644 --- a/src/main/java/net/minestom/server/instance/InstanceContainer.java +++ b/src/main/java/net/minestom/server/instance/InstanceContainer.java @@ -518,6 +518,13 @@ public class InstanceContainer extends Instance { return position.getY() < -64; } + /** + * Assign a {@link SharedInstance} to this container + *
+ * Only used by {@link InstanceManager}
+ *
+ * @param sharedInstance the shared instance to assign to this container
+ */
protected void addSharedInstance(SharedInstance sharedInstance) {
this.sharedInstances.add(sharedInstance);
}
diff --git a/src/main/java/net/minestom/server/instance/InstanceManager.java b/src/main/java/net/minestom/server/instance/InstanceManager.java
index 3fda23367..fe8d298fd 100644
--- a/src/main/java/net/minestom/server/instance/InstanceManager.java
+++ b/src/main/java/net/minestom/server/instance/InstanceManager.java
@@ -5,54 +5,119 @@ import net.minestom.server.utils.validate.Check;
import net.minestom.server.world.DimensionType;
import java.util.Collections;
-import java.util.HashSet;
import java.util.Set;
import java.util.UUID;
+import java.util.concurrent.CopyOnWriteArraySet;
+/**
+ * Used to register instances
+ */
public final class InstanceManager {
- private Set
+ * WARNING: the shared instance needs to have an {@link InstanceContainer} assigned to it
+ *
+ * @param sharedInstance the instance to register
+ * @return the registered {@link SharedInstance}
+ * @throws NullPointerException if the shared instance doesn't have an {@link InstanceContainer} assigned to it
+ */
+ public SharedInstance registerSharedInstance(SharedInstance sharedInstance) {
final InstanceContainer instanceContainer = sharedInstance.getInstanceContainer();
Check.notNull(instanceContainer, "SharedInstance needs to have an InstanceContainer to be created!");
instanceContainer.addSharedInstance(sharedInstance);
- this.instances.add(sharedInstance);
+ registerInstance(sharedInstance);
return sharedInstance;
}
+ /**
+ * Create and register a {@link SharedInstance}
+ *
+ * @param instanceContainer the container assigned to the shared instance
+ * @return the created {@link SharedInstance}
+ * @throws IllegalStateException if {@code instanceContainer} is not registered
+ */
public SharedInstance createSharedInstance(InstanceContainer instanceContainer) {
Check.notNull(instanceContainer, "Instance container cannot be null when creating a SharedInstance!");
+ Check.stateCondition(!instanceContainer.isRegistered(), "The container needs to be register in the InstanceManager");
final SharedInstance sharedInstance = new SharedInstance(UUID.randomUUID(), instanceContainer);
- return createSharedInstance(sharedInstance);
+ return registerSharedInstance(sharedInstance);
}
+ /**
+ * Get all the registered instances
+ *
+ * @return an unmodifiable set containing all the registered instances
+ */
public Set