mirror of
https://github.com/Nan1t/NanoLimbo.git
synced 2025-07-12 12:40:14 +02:00
113 lines
3.6 KiB
Java
113 lines
3.6 KiB
Java
package ru.nanit.limbo.server;
|
|
|
|
import io.netty.bootstrap.ServerBootstrap;
|
|
import io.netty.channel.ChannelOption;
|
|
import io.netty.channel.EventLoopGroup;
|
|
import io.netty.channel.ServerChannel;
|
|
import io.netty.channel.epoll.Epoll;
|
|
import io.netty.channel.epoll.EpollEventLoopGroup;
|
|
import io.netty.channel.epoll.EpollServerSocketChannel;
|
|
import io.netty.channel.nio.NioEventLoopGroup;
|
|
import io.netty.channel.socket.nio.NioServerSocketChannel;
|
|
import io.netty.util.ResourceLeakDetector;
|
|
import ru.nanit.limbo.configuration.LimboConfig;
|
|
import ru.nanit.limbo.connection.ClientChannelInitializer;
|
|
import ru.nanit.limbo.connection.ClientConnection;
|
|
import ru.nanit.limbo.util.Logger;
|
|
import ru.nanit.limbo.world.DimensionRegistry;
|
|
|
|
import java.nio.file.Paths;
|
|
import java.util.concurrent.ScheduledFuture;
|
|
import java.util.concurrent.TimeUnit;
|
|
|
|
public final class LimboServer {
|
|
|
|
private LimboConfig config;
|
|
private Connections connections;
|
|
private DimensionRegistry dimensionRegistry;
|
|
private ScheduledFuture<?> keepAliveTask;
|
|
|
|
private EventLoopGroup bossGroup;
|
|
private EventLoopGroup workerGroup;
|
|
|
|
public LimboConfig getConfig() {
|
|
return config;
|
|
}
|
|
|
|
public Connections getConnections() {
|
|
return connections;
|
|
}
|
|
|
|
public DimensionRegistry getDimensionRegistry() {
|
|
return dimensionRegistry;
|
|
}
|
|
|
|
public void start() throws Exception {
|
|
Logger.info("Starting server...");
|
|
|
|
ResourceLeakDetector.setLevel(ResourceLeakDetector.Level.DISABLED);
|
|
|
|
config = new LimboConfig(Paths.get("./"));
|
|
config.load();
|
|
|
|
Logger.setLevel(config.getDebugLevel());
|
|
|
|
dimensionRegistry = new DimensionRegistry();
|
|
dimensionRegistry.load(this, config.getDimensionType());
|
|
connections = new Connections();
|
|
|
|
ClientConnection.preInitPackets(this);
|
|
|
|
startBootstrap();
|
|
|
|
keepAliveTask = workerGroup.scheduleAtFixedRate(this::broadcastKeepAlive, 0L, 5L, TimeUnit.SECONDS);
|
|
|
|
Runtime.getRuntime().addShutdownHook(new Thread(this::stop, "NanoLimbo shutdown thread"));
|
|
|
|
Logger.info("Server started on %s", config.getAddress());
|
|
}
|
|
|
|
private void startBootstrap() {
|
|
Class<? extends ServerChannel> channelClass;
|
|
|
|
if (config.isUseEpoll() && Epoll.isAvailable()) {
|
|
bossGroup = new EpollEventLoopGroup(config.getBossGroupSize());
|
|
workerGroup = new EpollEventLoopGroup(config.getWorkerGroupSize());
|
|
channelClass = EpollServerSocketChannel.class;
|
|
Logger.debug("Using Epoll transport type");
|
|
} else {
|
|
bossGroup = new NioEventLoopGroup(config.getBossGroupSize());
|
|
workerGroup = new NioEventLoopGroup(config.getWorkerGroupSize());
|
|
channelClass = NioServerSocketChannel.class;
|
|
Logger.debug("Using Java NIO transport type");
|
|
}
|
|
|
|
new ServerBootstrap()
|
|
.group(bossGroup, workerGroup)
|
|
.channel(channelClass)
|
|
.childHandler(new ClientChannelInitializer(this))
|
|
.childOption(ChannelOption.TCP_NODELAY, true)
|
|
.localAddress(config.getAddress())
|
|
.bind();
|
|
}
|
|
|
|
private void broadcastKeepAlive() {
|
|
connections.getAllConnections().forEach(ClientConnection::sendKeepAlive);
|
|
}
|
|
|
|
private void stop() {
|
|
if (keepAliveTask != null) {
|
|
keepAliveTask.cancel(true);
|
|
}
|
|
|
|
if (bossGroup != null) {
|
|
bossGroup.shutdownGracefully();
|
|
}
|
|
|
|
if (workerGroup != null) {
|
|
workerGroup.shutdownGracefully();
|
|
}
|
|
}
|
|
|
|
}
|