From 589df91151b49178838a01f7cc1865476ed70430 Mon Sep 17 00:00:00 2001 From: DmitriyMX Date: Mon, 1 May 2017 12:28:53 +0300 Subject: [PATCH] =?UTF-8?q?MCSM:=20=D0=BF=D1=80=D0=B8=D0=BD=D0=B8=D0=BC?= =?UTF-8?q?=D0=B0=D0=B5=D0=BC=20=D0=BF=D0=B8=D0=BD=D0=B3-=D0=BF=D0=B0?= =?UTF-8?q?=D0=BA=D0=B5=D1=82=D1=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- mcserver-manager/build.gradle | 2 +- .../main/java/asys/mcsmanager/Activator.java | 4 +- .../main/java/asys/mcsmanager/Manager.java | 56 +++++++++++++++++++ .../mcsmanager/server/HandshakeResult.java | 1 + .../java/asys/mcsmanager/server/Server.java | 5 +- .../server/ServerPacketHandler.java | 56 +++++++++++++++---- 6 files changed, 111 insertions(+), 13 deletions(-) create mode 100644 mcserver-manager/src/main/java/asys/mcsmanager/Manager.java diff --git a/mcserver-manager/build.gradle b/mcserver-manager/build.gradle index 449b573..d785d31 100644 --- a/mcserver-manager/build.gradle +++ b/mcserver-manager/build.gradle @@ -1,5 +1,5 @@ group = 'asys' -version = '0.7.1-SNAPSHOT' +version = '0.8-SNAPSHOT' apply plugin: 'osgi' diff --git a/mcserver-manager/src/main/java/asys/mcsmanager/Activator.java b/mcserver-manager/src/main/java/asys/mcsmanager/Activator.java index 60ebd89..5c2c2c0 100644 --- a/mcserver-manager/src/main/java/asys/mcsmanager/Activator.java +++ b/mcserver-manager/src/main/java/asys/mcsmanager/Activator.java @@ -29,6 +29,8 @@ public class Activator implements BundleActivator, ServiceListener { Config config = serviceConfigTracker.getService(); if (config == null) throw new RuntimeException("Service 'Config' is not avalable!"); + Manager manager = new Manager(); + module = new MCSM_WebModule(); logger.debug("Get service: {}", Webinterface.class); @@ -42,7 +44,7 @@ public class Activator implements BundleActivator, ServiceListener { String passcode = config.getString("asys.mcsmanager.passcode", "testpasscode"); logger.debug("Start server manager: {}:{}", host, port); serverManager = new Server(); - serverManager.start(host, port, passcode); + serverManager.start(host, port, passcode, manager); serviceConfigTracker.close(); } diff --git a/mcserver-manager/src/main/java/asys/mcsmanager/Manager.java b/mcserver-manager/src/main/java/asys/mcsmanager/Manager.java new file mode 100644 index 0000000..b248277 --- /dev/null +++ b/mcserver-manager/src/main/java/asys/mcsmanager/Manager.java @@ -0,0 +1,56 @@ +/* + * DmitriyMX + * 2017-05-01 + */ +package asys.mcsmanager; + +import asys.mcsmanager.packets.CS_Ping; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.util.*; + +public class Manager { + private Logger logger = LoggerFactory.getLogger(Manager.class); + private Map> serversMap = new HashMap<>(); + + /** + * Добавляем в список ClientID + * @param clientId id сервера. Чувствителен к регистру + * @return false, если сервер с таким id уже имеется + */ + public boolean addClientId(String clientId) { + if (serversMap.containsKey(clientId)) { + return false; + } + + logger.debug("addClientId: {}", clientId); + serversMap.put(clientId, new LinkedList<>()); + return true; + } + + /** + * Дополнить информация о сервере. + * Если сервер отсутствует в списке, информация будет потеряна. + * @param clientId id сервера. Чувствителен к регистру + * @param pingPacket + */ + public void putInfo(String clientId, CS_Ping pingPacket) { + if (!serversMap.containsKey(clientId)) return; + + Deque list = serversMap.get(clientId); + if (list.size() == 720) { + list.removeFirst(); + } + list.addLast(pingPacket); + logger.debug("putInfo: {} [{}]", clientId, pingPacket.getTime()); + } + + public Set getServerList() { + return serversMap.keySet(); + } + + public Deque getInfo(String clientId) { + return serversMap.get(clientId); + } +} diff --git a/mcserver-manager/src/main/java/asys/mcsmanager/server/HandshakeResult.java b/mcserver-manager/src/main/java/asys/mcsmanager/server/HandshakeResult.java index 86e72c8..ec386ad 100644 --- a/mcserver-manager/src/main/java/asys/mcsmanager/server/HandshakeResult.java +++ b/mcserver-manager/src/main/java/asys/mcsmanager/server/HandshakeResult.java @@ -9,4 +9,5 @@ import asys.mcsmanager.packets.SC_HandshakeResult; abstract class HandshakeResult { static final SC_HandshakeResult OK = new SC_HandshakeResult(0, "OK"); static final SC_HandshakeResult INVALID_PASSCODE = new SC_HandshakeResult(1, "Invalid passcode"); + static final SC_HandshakeResult CLIENTID_EXISTS = new SC_HandshakeResult(2, "ClientID is already use"); } diff --git a/mcserver-manager/src/main/java/asys/mcsmanager/server/Server.java b/mcserver-manager/src/main/java/asys/mcsmanager/server/Server.java index e0d0f49..f2743f5 100644 --- a/mcserver-manager/src/main/java/asys/mcsmanager/server/Server.java +++ b/mcserver-manager/src/main/java/asys/mcsmanager/server/Server.java @@ -4,6 +4,7 @@ */ package asys.mcsmanager.server; +import asys.mcsmanager.Manager; import asys.mcsmanager.packets.CS_Ping; import asys.mcsmanager.packets.Packet; import asys.mcsmanager.packets.codec.PacketDecoder; @@ -24,9 +25,11 @@ public class Server { ); private EventLoopGroup bossGroup, workerGroup; static String passcode; + static Manager manager; - public void start(String host, int port, String passcode) { + public void start(String host, int port, String passcode, Manager manager) { Server.passcode = passcode; + Server.manager = manager; bossGroup = new NioEventLoopGroup(1); workerGroup = new NioEventLoopGroup(); diff --git a/mcserver-manager/src/main/java/asys/mcsmanager/server/ServerPacketHandler.java b/mcserver-manager/src/main/java/asys/mcsmanager/server/ServerPacketHandler.java index cf6dabd..91c9abc 100644 --- a/mcserver-manager/src/main/java/asys/mcsmanager/server/ServerPacketHandler.java +++ b/mcserver-manager/src/main/java/asys/mcsmanager/server/ServerPacketHandler.java @@ -4,19 +4,20 @@ */ package asys.mcsmanager.server; -import asys.mcsmanager.packets.CS_Handshake; -import asys.mcsmanager.packets.IPacketHandler; -import asys.mcsmanager.packets.Packet; -import asys.mcsmanager.packets.SC_HandshakeResult; -import asys.mcsmanager.packets.codec.Params; +import asys.mcsmanager.packets.*; import com.google.common.collect.BiMap; import com.google.common.collect.ImmutableBiMap; import com.google.common.collect.ImmutableMap; import io.netty.channel.ChannelHandlerContext; import io.netty.channel.ChannelInboundHandlerAdapter; +import io.netty.util.AttributeKey; import java.util.Map; +import static asys.mcsmanager.packets.codec.Params.KNOWN_HANDLERS; +import static asys.mcsmanager.packets.codec.Params.KNOWN_PACKETS; +import static asys.mcsmanager.server.Server.manager; + class ServerPacketHandler extends ChannelInboundHandlerAdapter implements IPacketHandler { private static final BiMap> handshakePackets = ImmutableBiMap.of( 1, CS_Handshake.class, @@ -24,24 +25,41 @@ class ServerPacketHandler extends ChannelInboundHandlerAdapter implements IPacke ); private static Map, IPacketHandler> handshakeHandlers; + private static final BiMap> pingPackets = ImmutableBiMap.of( + 3, CS_Ping.class + ); + private static Map, IPacketHandler> pingHandlers; + + private static final AttributeKey CLIENTID = AttributeKey.valueOf("ClientId"); + ServerPacketHandler() { if (handshakeHandlers == null) { handshakeHandlers = ImmutableMap.of( CS_Handshake.class, this ); } + + if (pingHandlers == null) { + pingHandlers = ImmutableMap.of( + CS_Ping.class, this + ); + } } @Override public void channelActive(ChannelHandlerContext context) throws Exception { - context.channel().attr(Params.KNOWN_PACKETS).set(handshakePackets); - context.channel().attr(Params.KNOWN_HANDLERS).set(handshakeHandlers); + context.channel().attr(KNOWN_PACKETS).set(handshakePackets); + context.channel().attr(KNOWN_HANDLERS).set(handshakeHandlers); super.channelActive(context); } @Override public void handle(Packet packet, ChannelHandlerContext context) { - if (packet.getClass() == CS_Handshake.class) handleCSHandshake((CS_Handshake) packet, context); + if (packet.getClass() == CS_Handshake.class) { + handleCSHandshake((CS_Handshake) packet, context); + } else if (packet.getClass() == CS_Ping.class) { + handleCSPing((CS_Ping) packet, context); + } } private void handleCSHandshake(CS_Handshake packet, ChannelHandlerContext context) { @@ -51,8 +69,26 @@ class ServerPacketHandler extends ChannelInboundHandlerAdapter implements IPacke } catch (InterruptedException ignore) { // ignore } - } else { - context.channel().writeAndFlush(HandshakeResult.OK); + return; } + + if (!manager.addClientId(packet.getClientId())) { + try { + context.channel().writeAndFlush(HandshakeResult.CLIENTID_EXISTS).sync().channel().close(); + } catch (InterruptedException ignore) { + // ignore + } + return; + } + + context.channel().write(HandshakeResult.OK); + context.channel().attr(CLIENTID).set(packet.getClientId()); + context.channel().attr(KNOWN_PACKETS).set(pingPackets); + context.channel().attr(KNOWN_HANDLERS).set(pingHandlers); + context.channel().flush(); + } + + private void handleCSPing(CS_Ping packet, ChannelHandlerContext context) { + manager.putInfo(context.channel().attr(CLIENTID).get(), packet); } }