Обновление MultiServer: добавлен протокол связи между ASys и BungeeCoord
This commit is contained in:
@@ -16,6 +16,7 @@
|
|||||||
<properties>
|
<properties>
|
||||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||||
<java.version>1.8</java.version>
|
<java.version>1.8</java.version>
|
||||||
|
<netty.version>4.0.33.Final</netty.version>
|
||||||
</properties>
|
</properties>
|
||||||
|
|
||||||
<groupId>asys</groupId>
|
<groupId>asys</groupId>
|
||||||
@@ -27,7 +28,7 @@
|
|||||||
<dependency>
|
<dependency>
|
||||||
<groupId>asys</groupId>
|
<groupId>asys</groupId>
|
||||||
<artifactId>api</artifactId>
|
<artifactId>api</artifactId>
|
||||||
<version>0.10</version>
|
<version>0.11</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.osgi</groupId>
|
<groupId>org.osgi</groupId>
|
||||||
@@ -44,6 +45,27 @@
|
|||||||
<artifactId>commons-io</artifactId>
|
<artifactId>commons-io</artifactId>
|
||||||
<version>2.5</version>
|
<version>2.5</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>io.netty</groupId>
|
||||||
|
<artifactId>netty-transport</artifactId>
|
||||||
|
<version>${netty.version}</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>io.netty</groupId>
|
||||||
|
<artifactId>netty-codec</artifactId>
|
||||||
|
<version>${netty.version}</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>io.netty</groupId>
|
||||||
|
<artifactId>netty-handler</artifactId>
|
||||||
|
<version>${netty.version}</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>asys.lib</groupId>
|
||||||
|
<artifactId>protocol</artifactId>
|
||||||
|
<version>0.3</version>
|
||||||
|
<scope>provided</scope>
|
||||||
|
</dependency>
|
||||||
</dependencies>
|
</dependencies>
|
||||||
|
|
||||||
<build>
|
<build>
|
||||||
@@ -70,6 +92,7 @@
|
|||||||
<Bundle-SymbolicName>${project.groupId}.${project.artifactId}</Bundle-SymbolicName>
|
<Bundle-SymbolicName>${project.groupId}.${project.artifactId}</Bundle-SymbolicName>
|
||||||
<Bundle-Activator>asys.multiserver.Activator</Bundle-Activator>
|
<Bundle-Activator>asys.multiserver.Activator</Bundle-Activator>
|
||||||
<Import-Package>asys.api, *</Import-Package>
|
<Import-Package>asys.api, *</Import-Package>
|
||||||
|
<Embed-Dependency>*;scope=provided</Embed-Dependency>
|
||||||
</instructions>
|
</instructions>
|
||||||
</configuration>
|
</configuration>
|
||||||
</plugin>
|
</plugin>
|
||||||
|
|||||||
@@ -38,6 +38,7 @@ public class Activator implements BundleActivator {
|
|||||||
loadProps(GetProperty(bundleContext, "asys.config.dir", "conf")),
|
loadProps(GetProperty(bundleContext, "asys.config.dir", "conf")),
|
||||||
mcServerFactoryTracker);
|
mcServerFactoryTracker);
|
||||||
multiServer.loadState(bankObjectTracker.getService());
|
multiServer.loadState(bankObjectTracker.getService());
|
||||||
|
multiServer.startNetty();
|
||||||
serverManager = bundleContext.registerService(ServerManager.class.getName(), multiServer, null);
|
serverManager = bundleContext.registerService(ServerManager.class.getName(), multiServer, null);
|
||||||
|
|
||||||
commands = RegisterCommands(bundleContext, new Commands(multiServer), "asys.server");
|
commands = RegisterCommands(bundleContext, new Commands(multiServer), "asys.server");
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ package asys.multiserver;
|
|||||||
import asys.api.ASysUtils;
|
import asys.api.ASysUtils;
|
||||||
import asys.api.Command;
|
import asys.api.Command;
|
||||||
import asys.api.MinecraftServer;
|
import asys.api.MinecraftServer;
|
||||||
|
import asys.lib.protocol.ServerInfoPacket;
|
||||||
import org.apache.felix.service.command.Descriptor;
|
import org.apache.felix.service.command.Descriptor;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
@@ -95,6 +96,9 @@ public class Commands {
|
|||||||
} else if (!server.isAlive()) {
|
} else if (!server.isAlive()) {
|
||||||
server.start();
|
server.start();
|
||||||
ASysUtils.Log("Server \"%s\" started", serverId);
|
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()) {
|
} else if (server.isAlive()) {
|
||||||
server.stop();
|
server.stop();
|
||||||
ASysUtils.Log("Server \"%s\" stoppind", serverId);
|
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()) {
|
} else if (server.isAlive()) {
|
||||||
server.forceStop();
|
server.forceStop();
|
||||||
ASysUtils.Log("Server \"%s\" killing", serverId);
|
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) {
|
public void remove(@Descriptor("id сервера") String serverId) {
|
||||||
//TODO удаляет сервер с диска
|
//TODO удаляет сервер с диска
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Command
|
||||||
|
@Descriptor("Netty start")
|
||||||
|
public void netty() {
|
||||||
|
ASysUtils.Log("Netty server start");
|
||||||
|
multiServer.startNetty();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ import asys.api.MinecraftServerFactory;
|
|||||||
import asys.api.ServerManager;
|
import asys.api.ServerManager;
|
||||||
import asys.multiserver.buildscript.BuildScript;
|
import asys.multiserver.buildscript.BuildScript;
|
||||||
import asys.multiserver.buildscript.CommandException;
|
import asys.multiserver.buildscript.CommandException;
|
||||||
|
import asys.multiserver.netty.Server;
|
||||||
import org.osgi.util.tracker.ServiceTracker;
|
import org.osgi.util.tracker.ServiceTracker;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
@@ -26,6 +27,7 @@ public class MultiServer implements ServerManager {
|
|||||||
private Random random = new Random(System.currentTimeMillis());
|
private Random random = new Random(System.currentTimeMillis());
|
||||||
private ServiceTracker<?, MinecraftServerFactory> mcsfTracker;
|
private ServiceTracker<?, MinecraftServerFactory> mcsfTracker;
|
||||||
Path buildScriptPath, distrPath, serversPath;
|
Path buildScriptPath, distrPath, serversPath;
|
||||||
|
Server nettyServer;
|
||||||
|
|
||||||
public MultiServer(Properties properties, ServiceTracker<?, MinecraftServerFactory> mcServerFactoryTracker) {
|
public MultiServer(Properties properties, ServiceTracker<?, MinecraftServerFactory> mcServerFactoryTracker) {
|
||||||
buildScriptPath = Paths.get(properties.getProperty("buildscript.dir", "scripts"));
|
buildScriptPath = Paths.get(properties.getProperty("buildscript.dir", "scripts"));
|
||||||
@@ -124,7 +126,7 @@ public class MultiServer implements ServerManager {
|
|||||||
MinecraftServerFactory serverFactory = null;
|
MinecraftServerFactory serverFactory = null;
|
||||||
try {
|
try {
|
||||||
serverFactory = mcsfTracker.waitForService(1000L);
|
serverFactory = mcsfTracker.waitForService(1000L);
|
||||||
} catch (InterruptedException e) {
|
} catch (InterruptedException ignored) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (serverFactory == null)
|
if (serverFactory == null)
|
||||||
@@ -168,6 +170,8 @@ public class MultiServer implements ServerManager {
|
|||||||
mapMcServers.put(server.getName(), server);
|
mapMcServers.put(server.getName(), server);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
nettyServer = (Server) bankObject.get(MultiServer.class.getName()+"#startNetty");
|
||||||
}
|
}
|
||||||
|
|
||||||
void saveState(BankObject bankObject) {
|
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()+"#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();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
71
MultiServer/src/main/java/asys/multiserver/netty/Server.java
Normal file
71
MultiServer/src/main/java/asys/multiserver/netty/Server.java
Normal file
@@ -0,0 +1,71 @@
|
|||||||
|
/*
|
||||||
|
* DmitriyMX <mail@dmitriymx.ru>
|
||||||
|
* 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<SocketChannel>() {
|
||||||
|
@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);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,45 @@
|
|||||||
|
/*
|
||||||
|
* DmitriyMX <mail@dmitriymx.ru>
|
||||||
|
* 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);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,3 +1,5 @@
|
|||||||
buildscript.dir=scripts
|
buildscript.dir=scripts
|
||||||
distributive.dir=distr
|
distributive.dir=distr
|
||||||
servers.dir=servers
|
servers.dir=servers
|
||||||
|
connector.host=127.0.0.1
|
||||||
|
connector.port=6251
|
||||||
Reference in New Issue
Block a user