diff --git a/src/main/java/net/minestom/server/MinecraftServer.java b/src/main/java/net/minestom/server/MinecraftServer.java index 2242a98c9..d77d22ea0 100644 --- a/src/main/java/net/minestom/server/MinecraftServer.java +++ b/src/main/java/net/minestom/server/MinecraftServer.java @@ -17,7 +17,6 @@ import net.minestom.server.network.PacketProcessor; import net.minestom.server.network.packet.server.play.PluginMessagePacket; import net.minestom.server.network.packet.server.play.ServerDifficultyPacket; import net.minestom.server.network.socket.Server; -import net.minestom.server.ping.ResponseDataConsumer; import net.minestom.server.recipe.RecipeManager; import net.minestom.server.scoreboard.TeamManager; import net.minestom.server.storage.StorageManager; @@ -31,13 +30,13 @@ import net.minestom.server.world.DimensionTypeManager; import net.minestom.server.world.biomes.BiomeManager; import org.jetbrains.annotations.ApiStatus; import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.UnknownNullability; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.io.IOException; import java.net.InetSocketAddress; +import java.net.SocketAddress; /** * The main server class used to start the server and retrieve all the managers. @@ -74,7 +73,6 @@ public final class MinecraftServer { private static int entityViewDistance = Integer.getInteger("minestom.entity-view-distance", 5); private static int compressionThreshold = 256; private static boolean terminalEnabled = System.getProperty("minestom.terminal.disabled") == null; - private static ResponseDataConsumer responseDataConsumer; private static String brandName = "Minestom"; private static Difficulty difficulty = Difficulty.NORMAL; @@ -312,7 +310,7 @@ public final class MinecraftServer { /** * Changes the compression threshold of the server. *

- * WARNING: this need to be called before {@link #start(String, int, ResponseDataConsumer)}. + * WARNING: this need to be called before {@link #start(SocketAddress)}. * * @param compressionThreshold the new compression threshold, 0 to disable compression * @throws IllegalStateException if this is called after the server started @@ -341,17 +339,6 @@ public final class MinecraftServer { MinecraftServer.terminalEnabled = enabled; } - /** - * Gets the consumer executed to show server-list data. - * - * @return the response data consumer - * @deprecated listen to the {@link net.minestom.server.event.server.ServerListPingEvent} instead - */ - @Deprecated - public static ResponseDataConsumer getResponseDataConsumer() { - return responseDataConsumer; - } - public static DimensionTypeManager getDimensionTypeManager() { return serverProcess.dimension(); } @@ -381,30 +368,16 @@ public final class MinecraftServer { *

* It should be called after {@link #init()} and probably your own initialization code. * - * @param address the server address - * @param port the server port - * @param responseDataConsumer the response data consumer, can be null + * @param address the server address * @throws IllegalStateException if called before {@link #init()} or if the server is already running - * @deprecated use {@link #start(String, int)} and listen to the {@link net.minestom.server.event.server.ServerListPingEvent} event instead of ResponseDataConsumer */ - @Deprecated - public void start(@NotNull String address, int port, @Nullable ResponseDataConsumer responseDataConsumer) { - MinecraftServer.responseDataConsumer = responseDataConsumer; - start(address, port); + public void start(@NotNull SocketAddress address) { + serverProcess.start(address); + new TickSchedulerThread(serverProcess).start(); } - /** - * Starts the server. - *

- * It should be called after {@link #init()} and probably your own initialization code. - * - * @param address the server address - * @param port the server port - * @throws IllegalStateException if called before {@link #init()} or if the server is already running - */ public void start(@NotNull String address, int port) { - serverProcess.start(new InetSocketAddress(address, port)); - new TickSchedulerThread(serverProcess).start(); + start(new InetSocketAddress(address, port)); } /** diff --git a/src/main/java/net/minestom/server/event/server/ServerListPingEvent.java b/src/main/java/net/minestom/server/event/server/ServerListPingEvent.java index 633a0ea14..be299151f 100644 --- a/src/main/java/net/minestom/server/event/server/ServerListPingEvent.java +++ b/src/main/java/net/minestom/server/event/server/ServerListPingEvent.java @@ -1,10 +1,8 @@ package net.minestom.server.event.server; -import net.minestom.server.MinecraftServer; import net.minestom.server.event.trait.CancellableEvent; import net.minestom.server.network.player.PlayerConnection; import net.minestom.server.ping.ResponseData; -import net.minestom.server.ping.ResponseDataConsumer; import net.minestom.server.ping.ServerListPingType; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -38,14 +36,7 @@ public class ServerListPingEvent implements CancellableEvent { * @param type the ping type to respond with */ public ServerListPingEvent(@Nullable PlayerConnection connection, @NotNull ServerListPingType type) { - //noinspection deprecation we need to continue doing this until the consumer is removed - todo remove - ResponseDataConsumer consumer = MinecraftServer.getResponseDataConsumer(); this.responseData = new ResponseData(); - - if (consumer != null) { - consumer.accept(connection, responseData); - } - this.connection = connection; this.type = type; } diff --git a/src/main/java/net/minestom/server/extensions/ExtensionManager.java b/src/main/java/net/minestom/server/extensions/ExtensionManager.java index e2b430934..d1d5c1210 100644 --- a/src/main/java/net/minestom/server/extensions/ExtensionManager.java +++ b/src/main/java/net/minestom/server/extensions/ExtensionManager.java @@ -7,7 +7,6 @@ import net.minestom.dependencies.maven.MavenRepository; import net.minestom.server.ServerProcess; import net.minestom.server.event.Event; import net.minestom.server.event.EventNode; -import net.minestom.server.ping.ResponseDataConsumer; import net.minestom.server.utils.validate.Check; import org.jetbrains.annotations.ApiStatus; import org.jetbrains.annotations.NotNull; @@ -56,7 +55,7 @@ public class ExtensionManager { *

* Default value is 'true'. * - * @return true if extensions are loaded in {@link net.minestom.server.MinecraftServer#start(String, int, ResponseDataConsumer)} + * @return true if extensions are loaded in {@link net.minestom.server.MinecraftServer#start(java.net.SocketAddress)} */ public boolean shouldLoadOnStartup() { return state != State.DO_NOT_START; diff --git a/src/main/java/net/minestom/server/network/socket/Server.java b/src/main/java/net/minestom/server/network/socket/Server.java index f271c1a51..95077533a 100644 --- a/src/main/java/net/minestom/server/network/socket/Server.java +++ b/src/main/java/net/minestom/server/network/socket/Server.java @@ -6,12 +6,12 @@ import org.jetbrains.annotations.ApiStatus; import org.jetbrains.annotations.NotNull; import java.io.IOException; -import java.net.InetSocketAddress; -import java.net.SocketAddress; +import java.net.*; import java.nio.channels.SelectionKey; import java.nio.channels.Selector; import java.nio.channels.ServerSocketChannel; import java.nio.channels.SocketChannel; +import java.nio.file.Files; import java.util.Arrays; import java.util.List; @@ -31,6 +31,7 @@ public final class Server { private int index; private ServerSocketChannel serverSocket; + private SocketAddress socketAddress; private String address; private int port; @@ -43,16 +44,25 @@ public final class Server { @ApiStatus.Internal public void init(SocketAddress address) throws IOException { + ProtocolFamily family; if (address instanceof InetSocketAddress inetSocketAddress) { this.address = inetSocketAddress.getHostString(); this.port = inetSocketAddress.getPort(); - } // TODO unix domain support + family = inetSocketAddress.getAddress().getAddress().length == 4 ? StandardProtocolFamily.INET : StandardProtocolFamily.INET6; + } else if (address instanceof UnixDomainSocketAddress unixDomainSocketAddress) { + this.address = "unix://" + unixDomainSocketAddress.getPath(); + this.port = 0; + family = StandardProtocolFamily.UNIX; + } else { + throw new IllegalArgumentException("Address must be an InetSocketAddress or a UnixDomainSocketAddress"); + } - ServerSocketChannel server = ServerSocketChannel.open(); + ServerSocketChannel server = ServerSocketChannel.open(family); server.bind(address); server.configureBlocking(false); server.register(selector, SelectionKey.OP_ACCEPT); this.serverSocket = server; + this.socketAddress = address; } @ApiStatus.Internal @@ -77,6 +87,14 @@ public final class Server { MinecraftServer.getExceptionManager().handleException(e); } } + try { + serverSocket.close(); + if (socketAddress instanceof UnixDomainSocketAddress unixDomainSocketAddress) { + Files.deleteIfExists(unixDomainSocketAddress.getPath()); + } + } catch (IOException e) { + MinecraftServer.getExceptionManager().handleException(e); + } }, "Ms-entrypoint").start(); } @@ -95,9 +113,8 @@ public final class Server { return packetProcessor; } - @ApiStatus.Internal - public List workers() { - return workers; + public SocketAddress socketAddress() { + return socketAddress; } public String getAddress() { diff --git a/src/main/java/net/minestom/server/ping/ResponseDataConsumer.java b/src/main/java/net/minestom/server/ping/ResponseDataConsumer.java deleted file mode 100644 index 21795703f..000000000 --- a/src/main/java/net/minestom/server/ping/ResponseDataConsumer.java +++ /dev/null @@ -1,24 +0,0 @@ -package net.minestom.server.ping; - -import net.minestom.server.network.player.PlayerConnection; - -/** - * Consumer used to fill a {@link ResponseData} object before being sent to a connection. - * - *

Can be specified in {@link net.minestom.server.MinecraftServer#start(String, int, - * ResponseDataConsumer)}. - * - * @deprecated listen to the {@link net.minestom.server.event.server.ServerListPingEvent} instead - */ -@FunctionalInterface -@Deprecated -public interface ResponseDataConsumer { - - /** - * A method to fill the data of the response. - * - * @param playerConnection The player connection to which the response should be sent. - * @param responseData The data for the response. - */ - void accept(PlayerConnection playerConnection, ResponseData responseData); -} diff --git a/src/test/java/net/minestom/server/network/socket/ServerAddressTest.java b/src/test/java/net/minestom/server/network/socket/ServerAddressTest.java new file mode 100644 index 000000000..b5361451a --- /dev/null +++ b/src/test/java/net/minestom/server/network/socket/ServerAddressTest.java @@ -0,0 +1,44 @@ +package net.minestom.server.network.socket; + +import net.minestom.server.network.PacketProcessor; +import org.junit.jupiter.api.Test; + +import java.io.IOException; +import java.net.InetSocketAddress; +import java.net.UnixDomainSocketAddress; +import java.nio.file.Files; + +import static org.junit.jupiter.api.Assertions.*; + +public class ServerAddressTest { + + @Test + public void inetAddressTest() throws IOException { + InetSocketAddress address = new InetSocketAddress("localhost", 25565); + var server = new Server(new PacketProcessor()); + server.init(address); + assertSame(address, server.socketAddress()); + assertEquals(address.getHostString(), server.getAddress()); + assertEquals(address.getPort(), server.getPort()); + + assertDoesNotThrow(server::start); + assertDoesNotThrow(server::stop); + } + + @Test + public void unixAddressTest() throws IOException, InterruptedException { + UnixDomainSocketAddress address = UnixDomainSocketAddress.of("minestom.sock"); + var server = new Server(new PacketProcessor()); + server.init(address); + assertTrue(Files.exists(address.getPath())); + assertSame(address, server.socketAddress()); + assertEquals("unix://" + address.getPath(), server.getAddress()); + assertEquals(0, server.getPort()); + + assertDoesNotThrow(server::start); + assertDoesNotThrow(server::stop); + + Thread.sleep(250); + assertFalse(Files.exists(address.getPath()), "The socket file should be deleted"); + } +}