Initial Netty implementation for networking
Split into 1 LoginServer and 1 ChannelServer per channel. There is still a lot of cleanup and refactoring to be done. Currently, the reliance on IoSession holding client state is the most pressing issue to be addressed.
This commit is contained in:
@@ -26,7 +26,10 @@ import config.YamlConfig;
|
|||||||
import constants.game.GameConstants;
|
import constants.game.GameConstants;
|
||||||
import io.netty.channel.ChannelHandlerContext;
|
import io.netty.channel.ChannelHandlerContext;
|
||||||
import io.netty.channel.ChannelInboundHandlerAdapter;
|
import io.netty.channel.ChannelInboundHandlerAdapter;
|
||||||
|
import net.MaplePacketHandler;
|
||||||
|
import net.PacketProcessor;
|
||||||
import net.netty.InvalidPacketHeaderException;
|
import net.netty.InvalidPacketHeaderException;
|
||||||
|
import net.packet.InPacket;
|
||||||
import net.server.Server;
|
import net.server.Server;
|
||||||
import net.server.audit.locks.MonitoredLockType;
|
import net.server.audit.locks.MonitoredLockType;
|
||||||
import net.server.audit.locks.factory.MonitoredReentrantLockFactory;
|
import net.server.audit.locks.factory.MonitoredReentrantLockFactory;
|
||||||
@@ -38,6 +41,8 @@ import net.server.guild.MapleGuild;
|
|||||||
import net.server.guild.MapleGuildCharacter;
|
import net.server.guild.MapleGuildCharacter;
|
||||||
import net.server.world.*;
|
import net.server.world.*;
|
||||||
import org.apache.mina.core.session.IoSession;
|
import org.apache.mina.core.session.IoSession;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
import scripting.AbstractPlayerInteraction;
|
import scripting.AbstractPlayerInteraction;
|
||||||
import scripting.event.EventInstanceManager;
|
import scripting.event.EventInstanceManager;
|
||||||
import scripting.event.EventManager;
|
import scripting.event.EventManager;
|
||||||
@@ -51,6 +56,8 @@ import server.maps.FieldLimit;
|
|||||||
import server.maps.MapleMap;
|
import server.maps.MapleMap;
|
||||||
import server.maps.MapleMiniDungeonInfo;
|
import server.maps.MapleMiniDungeonInfo;
|
||||||
import tools.*;
|
import tools.*;
|
||||||
|
import tools.data.input.ByteArrayByteStream;
|
||||||
|
import tools.data.input.GenericSeekableLittleEndianAccessor;
|
||||||
|
|
||||||
import javax.script.ScriptEngine;
|
import javax.script.ScriptEngine;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
@@ -65,6 +72,7 @@ import java.util.concurrent.Semaphore;
|
|||||||
import java.util.concurrent.locks.Lock;
|
import java.util.concurrent.locks.Lock;
|
||||||
|
|
||||||
public class MapleClient extends ChannelInboundHandlerAdapter {
|
public class MapleClient extends ChannelInboundHandlerAdapter {
|
||||||
|
private static final Logger log = LoggerFactory.getLogger(MapleClient.class);
|
||||||
|
|
||||||
public static final int LOGIN_NOTLOGGEDIN = 0;
|
public static final int LOGIN_NOTLOGGEDIN = 0;
|
||||||
public static final int LOGIN_SERVER_TRANSITION = 1;
|
public static final int LOGIN_SERVER_TRANSITION = 1;
|
||||||
@@ -77,6 +85,7 @@ public class MapleClient extends ChannelInboundHandlerAdapter {
|
|||||||
private MapleAESOFB send;
|
private MapleAESOFB send;
|
||||||
private MapleAESOFB receive;
|
private MapleAESOFB receive;
|
||||||
private final IoSession session;
|
private final IoSession session;
|
||||||
|
private PacketProcessor packetProcessor;
|
||||||
private MapleCharacter player;
|
private MapleCharacter player;
|
||||||
private int channel = 1;
|
private int channel = 1;
|
||||||
private int accId = -4;
|
private int accId = -4;
|
||||||
@@ -121,7 +130,10 @@ public class MapleClient extends ChannelInboundHandlerAdapter {
|
|||||||
return lastPacket;
|
return lastPacket;
|
||||||
}
|
}
|
||||||
|
|
||||||
public MapleClient() {
|
public MapleClient(PacketProcessor packetProcessor, int world, int channel) {
|
||||||
|
this.packetProcessor = packetProcessor;
|
||||||
|
this.world = world;
|
||||||
|
this.channel = channel;
|
||||||
this.session = null; // TODO remove once the other constructor is removed
|
this.session = null; // TODO remove once the other constructor is removed
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -133,6 +145,28 @@ public class MapleClient extends ChannelInboundHandlerAdapter {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
|
public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
|
||||||
|
// InPacket packet = new ByteBufInPacket((ByteBuf) msg);
|
||||||
|
if (!(msg instanceof InPacket packet)) {
|
||||||
|
log.warn("Received invalid message: {}", msg);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
short opcode = packet.readShort();
|
||||||
|
final MaplePacketHandler handler = packetProcessor.getHandler(opcode);
|
||||||
|
if (handler != null && handler.validateState(this)) {
|
||||||
|
// TODO: pass InPacket directly to handler once all handlers have been ported,
|
||||||
|
// this is just a temporary workaround
|
||||||
|
GenericSeekableLittleEndianAccessor accessor = new GenericSeekableLittleEndianAccessor(new ByteArrayByteStream(packet.getBytes()));
|
||||||
|
try {
|
||||||
|
MapleLogger.logRecv(this, opcode, msg);
|
||||||
|
handler.handlePacket(accessor, this);
|
||||||
|
} catch (final Throwable t) {
|
||||||
|
FilePrinter.printError(FilePrinter.PACKET_HANDLER + handler.getClass().getName() + ".txt", t, "Error for " + (getPlayer() == null ? "" : "player ; " + getPlayer() + " on map ; " + getPlayer().getMapId() + " - ") + "account ; " + getAccountName() + "\r\n" + accessor);
|
||||||
|
//client.announce(MaplePacketCreator.enableActions());//bugs sometimes
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
updateLastPacket();
|
||||||
super.channelRead(ctx, msg);
|
super.channelRead(ctx, msg);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -21,6 +21,7 @@
|
|||||||
*/
|
*/
|
||||||
package net;
|
package net;
|
||||||
|
|
||||||
|
import net.netty.LoginServer;
|
||||||
import net.opcodes.RecvOpcode;
|
import net.opcodes.RecvOpcode;
|
||||||
import net.server.channel.handlers.*;
|
import net.server.channel.handlers.*;
|
||||||
import net.server.handlers.CustomPacketHandler;
|
import net.server.handlers.CustomPacketHandler;
|
||||||
@@ -47,7 +48,7 @@ public final class PacketProcessor {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static PacketProcessor getLoginServerProcessor() {
|
public static PacketProcessor getLoginServerProcessor() {
|
||||||
return getProcessor(-1, -1);
|
return getProcessor(LoginServer.WORLD, LoginServer.CHANNEL);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static PacketProcessor getChannelServerProcessor(int world, int channel) {
|
public static PacketProcessor getChannelServerProcessor(int world, int channel) {
|
||||||
|
|||||||
12
src/main/java/net/netty/AbstractServer.java
Normal file
12
src/main/java/net/netty/AbstractServer.java
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
package net.netty;
|
||||||
|
|
||||||
|
public abstract class AbstractServer {
|
||||||
|
final int port;
|
||||||
|
|
||||||
|
AbstractServer(int port) {
|
||||||
|
this.port = port;
|
||||||
|
}
|
||||||
|
|
||||||
|
public abstract void start();
|
||||||
|
public abstract void stop();
|
||||||
|
}
|
||||||
40
src/main/java/net/netty/ChannelServer.java
Normal file
40
src/main/java/net/netty/ChannelServer.java
Normal file
@@ -0,0 +1,40 @@
|
|||||||
|
package net.netty;
|
||||||
|
|
||||||
|
import io.netty.bootstrap.ServerBootstrap;
|
||||||
|
import io.netty.channel.Channel;
|
||||||
|
import io.netty.channel.EventLoopGroup;
|
||||||
|
import io.netty.channel.nio.NioEventLoopGroup;
|
||||||
|
import io.netty.channel.socket.nio.NioServerSocketChannel;
|
||||||
|
|
||||||
|
public class ChannelServer extends AbstractServer {
|
||||||
|
private final int world;
|
||||||
|
private final int channel;
|
||||||
|
private Channel nettyChannel;
|
||||||
|
|
||||||
|
public ChannelServer(int port, int world, int channel) {
|
||||||
|
super(port);
|
||||||
|
this.world = world;
|
||||||
|
this.channel = channel;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void start() {
|
||||||
|
EventLoopGroup parentGroup = new NioEventLoopGroup();
|
||||||
|
EventLoopGroup childGroup = new NioEventLoopGroup();
|
||||||
|
ServerBootstrap bootstrap = new ServerBootstrap()
|
||||||
|
.group(parentGroup, childGroup)
|
||||||
|
.channel(NioServerSocketChannel.class)
|
||||||
|
.childHandler(new ChannelServerInitializer(world, channel));
|
||||||
|
|
||||||
|
this.nettyChannel = bootstrap.bind(port).syncUninterruptibly().channel();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void stop() {
|
||||||
|
if (nettyChannel == null) {
|
||||||
|
throw new IllegalStateException("Must start ChannelServer before stopping it");
|
||||||
|
}
|
||||||
|
|
||||||
|
nettyChannel.close().syncUninterruptibly();
|
||||||
|
}
|
||||||
|
}
|
||||||
31
src/main/java/net/netty/ChannelServerInitializer.java
Normal file
31
src/main/java/net/netty/ChannelServerInitializer.java
Normal file
@@ -0,0 +1,31 @@
|
|||||||
|
package net.netty;
|
||||||
|
|
||||||
|
import client.MapleClient;
|
||||||
|
import io.netty.channel.socket.SocketChannel;
|
||||||
|
import net.PacketProcessor;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
public class ChannelServerInitializer extends ServerChannelInitializer {
|
||||||
|
private static final Logger log = LoggerFactory.getLogger(ChannelServerInitializer.class);
|
||||||
|
|
||||||
|
private final int world;
|
||||||
|
private final int channel;
|
||||||
|
|
||||||
|
public ChannelServerInitializer(int world, int channel) {
|
||||||
|
this.world = world;
|
||||||
|
this.channel = channel;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void initChannel(SocketChannel socketChannel) {
|
||||||
|
final String clientIp = socketChannel.remoteAddress().getHostName();
|
||||||
|
log.debug("Client connected to world {}, channel {} from {}", world, channel, clientIp);
|
||||||
|
|
||||||
|
PacketProcessor packetProcessor = PacketProcessor.getChannelServerProcessor(world, channel);
|
||||||
|
final MapleClient client = new MapleClient(packetProcessor, world, channel);
|
||||||
|
client.setSessionId(sessionId.getAndIncrement());
|
||||||
|
|
||||||
|
initPipeline(socketChannel, client);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -12,9 +12,9 @@ public class ClientCyphers {
|
|||||||
this.receive = receive;
|
this.receive = receive;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static ClientCyphers generateNew() {
|
public static ClientCyphers of(InitializationVector sendIv, InitializationVector receiveIv) {
|
||||||
MapleAESOFB send = new MapleAESOFB(InitializationVector.generateSend(), ServerConstants.VERSION);
|
MapleAESOFB send = new MapleAESOFB(sendIv, (short) (0xFFFF - ServerConstants.VERSION));
|
||||||
MapleAESOFB receive = new MapleAESOFB(InitializationVector.generateReceive(), ServerConstants.VERSION);
|
MapleAESOFB receive = new MapleAESOFB(receiveIv, ServerConstants.VERSION);
|
||||||
return new ClientCyphers(send, receive);
|
return new ClientCyphers(send, receive);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,20 +0,0 @@
|
|||||||
package net.netty;
|
|
||||||
|
|
||||||
import client.MapleClient;
|
|
||||||
import io.netty.channel.ChannelInitializer;
|
|
||||||
import io.netty.channel.socket.SocketChannel;
|
|
||||||
import org.slf4j.Logger;
|
|
||||||
import org.slf4j.LoggerFactory;
|
|
||||||
|
|
||||||
public class ClientInitializer extends ChannelInitializer<SocketChannel> {
|
|
||||||
private static final Logger log = LoggerFactory.getLogger(ClientInitializer.class);
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void initChannel(SocketChannel socketChannel) {
|
|
||||||
final String clientIp = socketChannel.remoteAddress().getHostName();
|
|
||||||
log.debug("Client initiated new connection from: {}", clientIp);
|
|
||||||
|
|
||||||
socketChannel.pipeline().addLast("PacketCodec", new PacketCodec(ClientCyphers.generateNew()));
|
|
||||||
socketChannel.pipeline().addLast("MapleClient", new MapleClient());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
38
src/main/java/net/netty/LoginServer.java
Normal file
38
src/main/java/net/netty/LoginServer.java
Normal file
@@ -0,0 +1,38 @@
|
|||||||
|
package net.netty;
|
||||||
|
|
||||||
|
import io.netty.bootstrap.ServerBootstrap;
|
||||||
|
import io.netty.channel.Channel;
|
||||||
|
import io.netty.channel.EventLoopGroup;
|
||||||
|
import io.netty.channel.nio.NioEventLoopGroup;
|
||||||
|
import io.netty.channel.socket.nio.NioServerSocketChannel;
|
||||||
|
|
||||||
|
public class LoginServer extends AbstractServer {
|
||||||
|
public static final int WORLD = -1;
|
||||||
|
public static final int CHANNEL = -1;
|
||||||
|
private Channel channel;
|
||||||
|
|
||||||
|
public LoginServer(int port) {
|
||||||
|
super(port);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void start() {
|
||||||
|
EventLoopGroup parentGroup = new NioEventLoopGroup();
|
||||||
|
EventLoopGroup childGroup = new NioEventLoopGroup();
|
||||||
|
ServerBootstrap bootstrap = new ServerBootstrap()
|
||||||
|
.group(parentGroup, childGroup)
|
||||||
|
.channel(NioServerSocketChannel.class)
|
||||||
|
.childHandler(new LoginServerInitializer());
|
||||||
|
|
||||||
|
this.channel = bootstrap.bind(port).syncUninterruptibly().channel();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void stop() {
|
||||||
|
if (channel == null) {
|
||||||
|
throw new IllegalStateException("Must start LoginServer before stopping it");
|
||||||
|
}
|
||||||
|
|
||||||
|
channel.close().syncUninterruptibly();
|
||||||
|
}
|
||||||
|
}
|
||||||
23
src/main/java/net/netty/LoginServerInitializer.java
Normal file
23
src/main/java/net/netty/LoginServerInitializer.java
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
package net.netty;
|
||||||
|
|
||||||
|
import client.MapleClient;
|
||||||
|
import io.netty.channel.socket.SocketChannel;
|
||||||
|
import net.PacketProcessor;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
public class LoginServerInitializer extends ServerChannelInitializer {
|
||||||
|
private static final Logger log = LoggerFactory.getLogger(LoginServerInitializer.class);
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void initChannel(SocketChannel socketChannel) {
|
||||||
|
final String clientIp = socketChannel.remoteAddress().getHostName();
|
||||||
|
log.debug("Client connected to login server from {} ", clientIp);
|
||||||
|
|
||||||
|
PacketProcessor packetProcessor = PacketProcessor.getLoginServerProcessor();
|
||||||
|
final MapleClient client = new MapleClient(packetProcessor, LoginServer.WORLD, LoginServer.CHANNEL);
|
||||||
|
client.setSessionId(sessionId.getAndIncrement());
|
||||||
|
|
||||||
|
initPipeline(socketChannel, client);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,9 +1,11 @@
|
|||||||
package net.netty;
|
package net.netty;
|
||||||
|
|
||||||
import io.netty.buffer.ByteBuf;
|
import io.netty.buffer.ByteBuf;
|
||||||
|
import io.netty.buffer.Unpooled;
|
||||||
import io.netty.channel.ChannelHandlerContext;
|
import io.netty.channel.ChannelHandlerContext;
|
||||||
import io.netty.handler.codec.ReplayingDecoder;
|
import io.netty.handler.codec.ReplayingDecoder;
|
||||||
import net.mina.MapleCustomEncryption;
|
import net.mina.MapleCustomEncryption;
|
||||||
|
import net.packet.ByteBufInPacket;
|
||||||
import tools.MapleAESOFB;
|
import tools.MapleAESOFB;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
@@ -28,7 +30,7 @@ public class PacketDecoder extends ReplayingDecoder<Void> {
|
|||||||
in.readBytes(packet);
|
in.readBytes(packet);
|
||||||
receiveCypher.crypt(packet);
|
receiveCypher.crypt(packet);
|
||||||
MapleCustomEncryption.decryptData(packet);
|
MapleCustomEncryption.decryptData(packet);
|
||||||
out.add(packet);
|
out.add(new ByteBufInPacket(Unpooled.wrappedBuffer(packet)));
|
||||||
// TODO conditionally log the packet
|
// TODO conditionally log the packet
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
22
src/main/java/net/netty/ServerChannelInitializer.java
Normal file
22
src/main/java/net/netty/ServerChannelInitializer.java
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
package net.netty;
|
||||||
|
|
||||||
|
import client.MapleClient;
|
||||||
|
import constants.net.ServerConstants;
|
||||||
|
import io.netty.buffer.Unpooled;
|
||||||
|
import io.netty.channel.ChannelInitializer;
|
||||||
|
import io.netty.channel.socket.SocketChannel;
|
||||||
|
import tools.MaplePacketCreator;
|
||||||
|
|
||||||
|
import java.util.concurrent.atomic.AtomicLong;
|
||||||
|
|
||||||
|
public abstract class ServerChannelInitializer extends ChannelInitializer<SocketChannel> {
|
||||||
|
static final AtomicLong sessionId = new AtomicLong(7777);
|
||||||
|
|
||||||
|
void initPipeline(SocketChannel socketChannel, MapleClient client) {
|
||||||
|
final InitializationVector sendIv = InitializationVector.generateSend();
|
||||||
|
final InitializationVector recvIv = InitializationVector.generateReceive();
|
||||||
|
socketChannel.writeAndFlush(Unpooled.wrappedBuffer(MaplePacketCreator.getHello(ServerConstants.VERSION, sendIv, recvIv)));
|
||||||
|
socketChannel.pipeline().addLast("PacketCodec", new PacketCodec(ClientCyphers.of(sendIv, recvIv)));
|
||||||
|
socketChannel.pipeline().addLast("MapleClient", client);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -37,6 +37,7 @@ import constants.net.OpcodeConstants;
|
|||||||
import constants.net.ServerConstants;
|
import constants.net.ServerConstants;
|
||||||
import net.MapleServerHandler;
|
import net.MapleServerHandler;
|
||||||
import net.mina.MapleCodecFactory;
|
import net.mina.MapleCodecFactory;
|
||||||
|
import net.netty.LoginServer;
|
||||||
import net.server.audit.ThreadTracker;
|
import net.server.audit.ThreadTracker;
|
||||||
import net.server.audit.locks.MonitoredLockType;
|
import net.server.audit.locks.MonitoredLockType;
|
||||||
import net.server.audit.locks.MonitoredReadLock;
|
import net.server.audit.locks.MonitoredReadLock;
|
||||||
@@ -106,6 +107,7 @@ public class Server {
|
|||||||
private static final List<Integer> activeCoupons = new LinkedList<>();
|
private static final List<Integer> activeCoupons = new LinkedList<>();
|
||||||
|
|
||||||
private IoAcceptor acceptor;
|
private IoAcceptor acceptor;
|
||||||
|
private LoginServer loginServer;
|
||||||
private List<Map<Integer, String>> channels = new LinkedList<>();
|
private List<Map<Integer, String>> channels = new LinkedList<>();
|
||||||
private List<World> worlds = new ArrayList<>();
|
private List<World> worlds = new ArrayList<>();
|
||||||
private final Properties subnetInfo = new Properties();
|
private final Properties subnetInfo = new Properties();
|
||||||
@@ -906,17 +908,8 @@ public class Server {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
IoBuffer.setUseDirectBuffer(false); // join IO operations performed by lxconan
|
// acceptor = initAcceptor(8484);
|
||||||
IoBuffer.setAllocator(new SimpleBufferAllocator());
|
loginServer = initLoginServer(8484);
|
||||||
acceptor = new NioSocketAcceptor();
|
|
||||||
acceptor.getFilterChain().addLast("codec", new ProtocolCodecFilter(new MapleCodecFactory()));
|
|
||||||
acceptor.getSessionConfig().setIdleTime(IdleStatus.BOTH_IDLE, 30);
|
|
||||||
acceptor.setHandler(new MapleServerHandler());
|
|
||||||
try {
|
|
||||||
acceptor.bind(new InetSocketAddress(8484));
|
|
||||||
} catch (IOException ex) {
|
|
||||||
ex.printStackTrace();
|
|
||||||
}
|
|
||||||
|
|
||||||
log.info("Listening on port 8484");
|
log.info("Listening on port 8484");
|
||||||
|
|
||||||
@@ -932,6 +925,28 @@ public class Server {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private LoginServer initLoginServer(int port) {
|
||||||
|
LoginServer loginServer = new LoginServer(port);
|
||||||
|
loginServer.start();
|
||||||
|
return loginServer;
|
||||||
|
}
|
||||||
|
|
||||||
|
private IoAcceptor initAcceptor(int port) {
|
||||||
|
IoBuffer.setUseDirectBuffer(false); // join IO operations performed by lxconan
|
||||||
|
IoBuffer.setAllocator(new SimpleBufferAllocator());
|
||||||
|
acceptor = new NioSocketAcceptor();
|
||||||
|
acceptor.getFilterChain().addLast("codec", new ProtocolCodecFilter(new MapleCodecFactory()));
|
||||||
|
acceptor.getSessionConfig().setIdleTime(IdleStatus.BOTH_IDLE, 30);
|
||||||
|
acceptor.setHandler(new MapleServerHandler());
|
||||||
|
try {
|
||||||
|
acceptor.bind(new InetSocketAddress(port));
|
||||||
|
} catch (IOException ex) {
|
||||||
|
ex.printStackTrace();
|
||||||
|
}
|
||||||
|
|
||||||
|
return acceptor;
|
||||||
|
}
|
||||||
|
|
||||||
private static void setAllLoggedOut(Connection con) throws SQLException {
|
private static void setAllLoggedOut(Connection con) throws SQLException {
|
||||||
try (PreparedStatement ps = con.prepareStatement("UPDATE accounts SET loggedin = 0")) {
|
try (PreparedStatement ps = con.prepareStatement("UPDATE accounts SET loggedin = 0")) {
|
||||||
ps.executeUpdate();
|
ps.executeUpdate();
|
||||||
|
|||||||
@@ -26,6 +26,7 @@ import config.YamlConfig;
|
|||||||
import constants.game.GameConstants;
|
import constants.game.GameConstants;
|
||||||
import net.MapleServerHandler;
|
import net.MapleServerHandler;
|
||||||
import net.mina.MapleCodecFactory;
|
import net.mina.MapleCodecFactory;
|
||||||
|
import net.netty.ChannelServer;
|
||||||
import net.server.PlayerStorage;
|
import net.server.PlayerStorage;
|
||||||
import net.server.Server;
|
import net.server.Server;
|
||||||
import net.server.audit.LockCollector;
|
import net.server.audit.LockCollector;
|
||||||
@@ -58,6 +59,7 @@ import tools.MaplePacketCreator;
|
|||||||
import tools.Pair;
|
import tools.Pair;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
|
import java.io.IOException;
|
||||||
import java.net.InetSocketAddress;
|
import java.net.InetSocketAddress;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
import java.util.Map.Entry;
|
import java.util.Map.Entry;
|
||||||
@@ -69,6 +71,7 @@ public final class Channel {
|
|||||||
private int port = 7575;
|
private int port = 7575;
|
||||||
private PlayerStorage players = new PlayerStorage();
|
private PlayerStorage players = new PlayerStorage();
|
||||||
private int world, channel;
|
private int world, channel;
|
||||||
|
private ChannelServer channelServer;
|
||||||
private IoAcceptor acceptor;
|
private IoAcceptor acceptor;
|
||||||
private String ip, serverMessage;
|
private String ip, serverMessage;
|
||||||
private MapleMapManager mapManager;
|
private MapleMapManager mapManager;
|
||||||
@@ -122,14 +125,8 @@ public final class Channel {
|
|||||||
port = 7575 + this.channel - 1;
|
port = 7575 + this.channel - 1;
|
||||||
port += (world * 100);
|
port += (world * 100);
|
||||||
ip = YamlConfig.config.server.HOST + ":" + port;
|
ip = YamlConfig.config.server.HOST + ":" + port;
|
||||||
IoBuffer.setUseDirectBuffer(false);
|
// acceptor = initAcceptor();
|
||||||
IoBuffer.setAllocator(new SimpleBufferAllocator());
|
channelServer = initServer(port, world, channel);
|
||||||
acceptor = new NioSocketAcceptor();
|
|
||||||
acceptor.setHandler(new MapleServerHandler(world, channel));
|
|
||||||
acceptor.getSessionConfig().setIdleTime(IdleStatus.BOTH_IDLE, 30);
|
|
||||||
acceptor.getFilterChain().addLast("codec", new ProtocolCodecFilter(new MapleCodecFactory()));
|
|
||||||
acceptor.bind(new InetSocketAddress(port));
|
|
||||||
((SocketSessionConfig) acceptor.getSessionConfig()).setTcpNoDelay(true);
|
|
||||||
expedType.addAll(Arrays.asList(MapleExpeditionType.values()));
|
expedType.addAll(Arrays.asList(MapleExpeditionType.values()));
|
||||||
|
|
||||||
if (Server.getInstance().isOnline()) { // postpone event loading to improve boot time... thanks Riizade, daronhudson for noticing slow startup times
|
if (Server.getInstance().isOnline()) { // postpone event loading to improve boot time... thanks Riizade, daronhudson for noticing slow startup times
|
||||||
@@ -156,6 +153,24 @@ public final class Channel {
|
|||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private IoAcceptor initAcceptor() throws IOException {
|
||||||
|
IoBuffer.setUseDirectBuffer(false);
|
||||||
|
IoBuffer.setAllocator(new SimpleBufferAllocator());
|
||||||
|
IoAcceptor acceptor = new NioSocketAcceptor();
|
||||||
|
acceptor.setHandler(new MapleServerHandler(world, channel));
|
||||||
|
acceptor.getSessionConfig().setIdleTime(IdleStatus.BOTH_IDLE, 30);
|
||||||
|
acceptor.getFilterChain().addLast("codec", new ProtocolCodecFilter(new MapleCodecFactory()));
|
||||||
|
acceptor.bind(new InetSocketAddress(port));
|
||||||
|
((SocketSessionConfig) acceptor.getSessionConfig()).setTcpNoDelay(true);
|
||||||
|
return acceptor;
|
||||||
|
}
|
||||||
|
|
||||||
|
private ChannelServer initServer(int port, int world, int channel) {
|
||||||
|
this.channelServer = new ChannelServer(port, world, channel);
|
||||||
|
channelServer.start();
|
||||||
|
return channelServer;
|
||||||
|
}
|
||||||
|
|
||||||
public synchronized void reloadEventScriptManager(){
|
public synchronized void reloadEventScriptManager(){
|
||||||
if (finishedShutdown) {
|
if (finishedShutdown) {
|
||||||
|
|||||||
@@ -26,5 +26,6 @@
|
|||||||
</Root>
|
</Root>
|
||||||
<Logger name="org.apache.mina" level="info"/>
|
<Logger name="org.apache.mina" level="info"/>
|
||||||
<Logger name="com.zaxxer.hikari" level="info"/>
|
<Logger name="com.zaxxer.hikari" level="info"/>
|
||||||
|
<Logger name="io.netty" level="info"/>
|
||||||
</Loggers>
|
</Loggers>
|
||||||
</Configuration>
|
</Configuration>
|
||||||
Reference in New Issue
Block a user