From 1b7ef9a50e72eac4a0b581614a4c42c23ead6c58 Mon Sep 17 00:00:00 2001 From: DmitriyMX Date: Sat, 27 Aug 2016 10:56:35 +0300 Subject: [PATCH] =?UTF-8?q?=D0=9E=D0=B1=D0=BD=D0=BE=D0=B2=D0=BB=D0=B5?= =?UTF-8?q?=D0=BD=D0=B8=D0=B5=20MultiServer:=20=D0=B4=D0=BE=D0=B1=D0=B0?= =?UTF-8?q?=D0=B2=D0=BB=D0=B5=D0=BD=20=D0=BF=D1=80=D0=BE=D1=82=D0=BE=D0=BA?= =?UTF-8?q?=D0=BE=D0=BB=20=D1=81=D0=B2=D1=8F=D0=B7=D0=B8=20=D0=BC=D0=B5?= =?UTF-8?q?=D0=B6=D0=B4=D1=83=20ASys=20=D0=B8=20BungeeCoord?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- MultiServer/pom.xml | 25 ++++++- .../main/java/asys/multiserver/Activator.java | 1 + .../main/java/asys/multiserver/Commands.java | 17 +++++ .../java/asys/multiserver/MultiServer.java | 23 +++++- .../java/asys/multiserver/netty/Server.java | 71 +++++++++++++++++++ .../asys/multiserver/netty/ServerHandler.java | 45 ++++++++++++ .../resources/asys-multiserver.properties | 4 +- 7 files changed, 183 insertions(+), 3 deletions(-) create mode 100644 MultiServer/src/main/java/asys/multiserver/netty/Server.java create mode 100644 MultiServer/src/main/java/asys/multiserver/netty/ServerHandler.java diff --git a/MultiServer/pom.xml b/MultiServer/pom.xml index 15881d9..bd35a0b 100644 --- a/MultiServer/pom.xml +++ b/MultiServer/pom.xml @@ -16,6 +16,7 @@ UTF-8 1.8 + 4.0.33.Final asys @@ -27,7 +28,7 @@ asys api - 0.10 + 0.11 org.osgi @@ -44,6 +45,27 @@ commons-io 2.5 + + io.netty + netty-transport + ${netty.version} + + + io.netty + netty-codec + ${netty.version} + + + io.netty + netty-handler + ${netty.version} + + + asys.lib + protocol + 0.3 + provided + @@ -70,6 +92,7 @@ ${project.groupId}.${project.artifactId} asys.multiserver.Activator asys.api, * + *;scope=provided diff --git a/MultiServer/src/main/java/asys/multiserver/Activator.java b/MultiServer/src/main/java/asys/multiserver/Activator.java index 7637300..fb45f9e 100644 --- a/MultiServer/src/main/java/asys/multiserver/Activator.java +++ b/MultiServer/src/main/java/asys/multiserver/Activator.java @@ -38,6 +38,7 @@ public class Activator implements BundleActivator { loadProps(GetProperty(bundleContext, "asys.config.dir", "conf")), mcServerFactoryTracker); multiServer.loadState(bankObjectTracker.getService()); + multiServer.startNetty(); serverManager = bundleContext.registerService(ServerManager.class.getName(), multiServer, null); commands = RegisterCommands(bundleContext, new Commands(multiServer), "asys.server"); diff --git a/MultiServer/src/main/java/asys/multiserver/Commands.java b/MultiServer/src/main/java/asys/multiserver/Commands.java index 419acc6..1def403 100644 --- a/MultiServer/src/main/java/asys/multiserver/Commands.java +++ b/MultiServer/src/main/java/asys/multiserver/Commands.java @@ -7,6 +7,7 @@ package asys.multiserver; import asys.api.ASysUtils; import asys.api.Command; import asys.api.MinecraftServer; +import asys.lib.protocol.ServerInfoPacket; import org.apache.felix.service.command.Descriptor; import java.io.IOException; @@ -95,6 +96,9 @@ public class Commands { } else if (!server.isAlive()) { server.start(); ASysUtils.Log("Server \"%s\" started", serverId); + + if (multiServer.nettyServer != null) + multiServer.nettyServer.send(new ServerInfoPacket(1, serverId, "127.0.0.1:"+server.getPort())); //TODO по хорошему бы, адрес давать не фиксированный локальный, а брать из MinecraftServer } } @@ -107,6 +111,9 @@ public class Commands { } else if (server.isAlive()) { server.stop(); ASysUtils.Log("Server \"%s\" stoppind", serverId); + + if (multiServer.nettyServer != null) + multiServer.nettyServer.send(new ServerInfoPacket(0, serverId, null)); } } @@ -119,6 +126,9 @@ public class Commands { } else if (server.isAlive()) { server.forceStop(); ASysUtils.Log("Server \"%s\" killing", serverId); + + if (multiServer.nettyServer != null) + multiServer.nettyServer.send(new ServerInfoPacket(0, serverId, null)); } } @@ -162,4 +172,11 @@ public class Commands { public void remove(@Descriptor("id сервера") String serverId) { //TODO удаляет сервер с диска } + + @Command + @Descriptor("Netty start") + public void netty() { + ASysUtils.Log("Netty server start"); + multiServer.startNetty(); + } } diff --git a/MultiServer/src/main/java/asys/multiserver/MultiServer.java b/MultiServer/src/main/java/asys/multiserver/MultiServer.java index 843fba6..37e5e8a 100644 --- a/MultiServer/src/main/java/asys/multiserver/MultiServer.java +++ b/MultiServer/src/main/java/asys/multiserver/MultiServer.java @@ -10,6 +10,7 @@ import asys.api.MinecraftServerFactory; import asys.api.ServerManager; import asys.multiserver.buildscript.BuildScript; import asys.multiserver.buildscript.CommandException; +import asys.multiserver.netty.Server; import org.osgi.util.tracker.ServiceTracker; import java.io.File; @@ -26,6 +27,7 @@ public class MultiServer implements ServerManager { private Random random = new Random(System.currentTimeMillis()); private ServiceTracker mcsfTracker; Path buildScriptPath, distrPath, serversPath; + Server nettyServer; public MultiServer(Properties properties, ServiceTracker mcServerFactoryTracker) { buildScriptPath = Paths.get(properties.getProperty("buildscript.dir", "scripts")); @@ -124,7 +126,7 @@ public class MultiServer implements ServerManager { MinecraftServerFactory serverFactory = null; try { serverFactory = mcsfTracker.waitForService(1000L); - } catch (InterruptedException e) { + } catch (InterruptedException ignored) { } if (serverFactory == null) @@ -168,6 +170,8 @@ public class MultiServer implements ServerManager { mapMcServers.put(server.getName(), server); } }); + + nettyServer = (Server) bankObject.get(MultiServer.class.getName()+"#startNetty"); } void saveState(BankObject bankObject) { @@ -181,5 +185,22 @@ public class MultiServer implements ServerManager { }); bankObject.save(MultiServer.class.getName()+"#servers", serversState); + bankObject.save(MultiServer.class.getName()+"#startNetty", nettyServer); + } + + public void startNetty() { + if (nettyServer != null) return; + nettyServer = new Server("0.0.0.0", (short)6251); + + new Thread(() -> { + try { + nettyServer.start(); + } catch (InterruptedException e) { + try { + nettyServer.stop(); + } catch (InterruptedException ignored) { + } + } + }, "Netty server").start(); } } diff --git a/MultiServer/src/main/java/asys/multiserver/netty/Server.java b/MultiServer/src/main/java/asys/multiserver/netty/Server.java new file mode 100644 index 0000000..2b37faa --- /dev/null +++ b/MultiServer/src/main/java/asys/multiserver/netty/Server.java @@ -0,0 +1,71 @@ +/* + * DmitriyMX + * 2016-08-21 + */ +package asys.multiserver.netty; + +import asys.lib.protocol.Packet; +import asys.lib.protocol.PacketDecoder; +import asys.lib.protocol.PacketEncoder; +import io.netty.bootstrap.ServerBootstrap; +import io.netty.channel.ChannelInitializer; +import io.netty.channel.ChannelOption; +import io.netty.channel.ChannelPipeline; +import io.netty.channel.EventLoopGroup; +import io.netty.channel.nio.NioEventLoopGroup; +import io.netty.channel.socket.SocketChannel; +import io.netty.channel.socket.nio.NioServerSocketChannel; + +public class Server { + private String host; + private short port; + private EventLoopGroup bossGroup; + private EventLoopGroup workerGroup; + + public Server(String host, short port) { + this.host = host; + this.port = port; + } + + public void start() throws InterruptedException { + bossGroup = new NioEventLoopGroup(); + workerGroup = new NioEventLoopGroup(); + + ServerBootstrap bootstrap = prepare_ServerBootstrap(); + bootstrap.bind(host, port).sync().channel().closeFuture().sync(); + } + + private ServerBootstrap prepare_ServerBootstrap() { + ServerBootstrap bootstrap = new ServerBootstrap(); + + bootstrap.group(bossGroup, workerGroup) + .channel(NioServerSocketChannel.class) + .childHandler(prepare_ChannelInitializer()) + .childOption(ChannelOption.SO_KEEPALIVE, true); + + return bootstrap; + } + + private ChannelInitializer prepare_ChannelInitializer() { + return new ChannelInitializer() { + @Override + protected void initChannel(SocketChannel channel) throws Exception { + ChannelPipeline pipeline = channel.pipeline(); + pipeline.addLast( + new PacketEncoder(), + new PacketDecoder(), + new ServerHandler() + ); + } + }; + } + + public void stop() throws InterruptedException { + workerGroup.shutdownGracefully(); + bossGroup.shutdownGracefully(); + } + + public void send(Packet packet) { + ServerHandler.Send(packet); + } +} diff --git a/MultiServer/src/main/java/asys/multiserver/netty/ServerHandler.java b/MultiServer/src/main/java/asys/multiserver/netty/ServerHandler.java new file mode 100644 index 0000000..0ddb8a7 --- /dev/null +++ b/MultiServer/src/main/java/asys/multiserver/netty/ServerHandler.java @@ -0,0 +1,45 @@ +/* + * DmitriyMX + * 2016-08-21 + */ +package asys.multiserver.netty; + +import asys.lib.protocol.Packet; +import io.netty.channel.Channel; +import io.netty.channel.ChannelFutureListener; +import io.netty.channel.ChannelHandlerContext; +import io.netty.channel.ChannelInboundHandlerAdapter; + +public class ServerHandler extends ChannelInboundHandlerAdapter { + private static Channel channel; + + @Override + public void channelActive(ChannelHandlerContext ctx) throws Exception { + if (channel != null) { + ctx.channel().close(); + } else { + channel = ctx.channel(); + } + } + + @Override + public void channelInactive(ChannelHandlerContext ctx) throws Exception { + if (channel != null && ctx.channel().equals(channel)) { + channel = null; + } + } + + @Override + public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception { + cause.printStackTrace(); + } + + private static boolean checkChannel() { + return channel != null && channel.isOpen(); + } + + public static void Send(Packet packet) { + if (checkChannel()) + channel.writeAndFlush(packet).addListener(ChannelFutureListener.CLOSE_ON_FAILURE); + } +} diff --git a/MultiServer/src/main/resources/asys-multiserver.properties b/MultiServer/src/main/resources/asys-multiserver.properties index 88114c0..c2a2e9b 100644 --- a/MultiServer/src/main/resources/asys-multiserver.properties +++ b/MultiServer/src/main/resources/asys-multiserver.properties @@ -1,3 +1,5 @@ buildscript.dir=scripts distributive.dir=distr -servers.dir=servers \ No newline at end of file +servers.dir=servers +connector.host=127.0.0.1 +connector.port=6251 \ No newline at end of file