From 946b7b7c45d441f0fe8606c5344ccd54861039fd Mon Sep 17 00:00:00 2001 From: DmitriyMX Date: Sat, 27 Aug 2016 10:56:52 +0300 Subject: [PATCH] =?UTF-8?q?=D0=9F=D0=BB=D0=B0=D0=B3=D0=B8=D0=BD=20=D0=B4?= =?UTF-8?q?=D0=BB=D1=8F=20BungeeCoord=20=D0=B4=D0=BB=D1=8F=20=D0=B2=D0=B7?= =?UTF-8?q?=D0=B0=D0=B8=D0=BC=D0=BE=D0=B4=D0=B5=D0=B9=D1=81=D1=82=D0=B2?= =?UTF-8?q?=D0=B8=D1=8F=20=D1=81=20ASys?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Bridge/pom.xml | 94 +++++++++++++++++++ Bridge/src/main/java/asys/bridge/Bridge.java | 90 ++++++++++++++++++ .../java/asys/bridge/BungeeServerAPI.java | 74 +++++++++++++++ .../main/java/asys/bridge/netty/Client.java | 72 ++++++++++++++ .../java/asys/bridge/netty/ClientHandler.java | 47 ++++++++++ Bridge/src/main/resources/bungee.yml | 3 + 6 files changed, 380 insertions(+) create mode 100644 Bridge/pom.xml create mode 100644 Bridge/src/main/java/asys/bridge/Bridge.java create mode 100644 Bridge/src/main/java/asys/bridge/BungeeServerAPI.java create mode 100644 Bridge/src/main/java/asys/bridge/netty/Client.java create mode 100644 Bridge/src/main/java/asys/bridge/netty/ClientHandler.java create mode 100644 Bridge/src/main/resources/bungee.yml diff --git a/Bridge/pom.xml b/Bridge/pom.xml new file mode 100644 index 0000000..696448e --- /dev/null +++ b/Bridge/pom.xml @@ -0,0 +1,94 @@ + + + 4.0.0 + ASys Bridge + http://dmitriymx.ru/ + + + UTF-8 + 1.8 + 1.8-SNAPSHOT + asys.bridge.Bridge + + + asys + bridge + 0.12 + jar + + + + bungee-repo + https://oss.sonatype.org/content/groups/public/ + + + + + + net.md-5 + bungeecord-api + ${bungee.version} + + + asys.lib + protocol + 0.3 + + + + + ${project.artifactId}-${project.version} + + + ${project.basedir}/src/main/resources + + ** + + true + + + + + org.apache.maven.plugins + maven-compiler-plugin + 3.5.1 + + ${java.version} + ${java.version} + ${project.build.sourceEncoding} + + + + org.apache.maven.plugins + maven-surefire-plugin + 2.15 + + -Dfile.encoding=${project.build.sourceEncoding} + + + + org.apache.maven.plugins + maven-shade-plugin + 1.6 + + + package + + shade + + + + + asys.lib:protocol + + + + + + + + + \ No newline at end of file diff --git a/Bridge/src/main/java/asys/bridge/Bridge.java b/Bridge/src/main/java/asys/bridge/Bridge.java new file mode 100644 index 0000000..ce21f5e --- /dev/null +++ b/Bridge/src/main/java/asys/bridge/Bridge.java @@ -0,0 +1,90 @@ +/* + * DmitriyMX + * 2016-08-24 + */ +package asys.bridge; + +import asys.bridge.netty.Client; +import net.md_5.bungee.api.plugin.Plugin; + +import java.io.IOException; +import java.net.ConnectException; + +public class Bridge extends Plugin { + private Client netty; + private BungeeServerAPI serverAPI; + + @Override + public void onEnable() { + try { + this.serverAPI = new BungeeServerAPI(); + } catch (IOException e) { + e.printStackTrace(); + return; + } + + new Thread(new WatchConnect(), "ASys Client").start(); + } + + @Override + public void onDisable() { + if (netty != null) + netty.disconnect(); + } + + public BungeeServerAPI getServerAPI() { + return serverAPI; + } + + private class WatchConnect implements Runnable { + @Override + public void run() { + // Попытка первого подключения + // Если false, значит попытка соединения прервана из вне + if (!tryConnect()) return; + + // Продолжаем следить за коннектом + while (netty != null) { + if (!netty.isConnected()) { + getLogger().warning("Lost connect! Try reconnect..."); + // Если false, значит попытка соединения прервана из вне + if (!tryConnect()) return; + } else { + try { + Thread.sleep(3000); + } catch (InterruptedException e) { + return; + } + } + } + } + + // Если false, значит попытка соединения прервана из вне + private boolean tryConnect() { + netty = new Client("127.0.0.1", (short)6251, Bridge.this); + + boolean _try = true; + do { + try { + netty.connect(); + _try = false; + } catch (InterruptedException e) { + netty.disconnect(); + netty = null; + return false; + } catch (ConnectException e) { + getLogger().warning(e.getMessage()); + try { + Thread.sleep(3000); + } catch (InterruptedException e1) { + netty = null; + return false; + } + } + } while (_try); + + getLogger().info("ASys connected"); + return true; + } + } +} diff --git a/Bridge/src/main/java/asys/bridge/BungeeServerAPI.java b/Bridge/src/main/java/asys/bridge/BungeeServerAPI.java new file mode 100644 index 0000000..3790f35 --- /dev/null +++ b/Bridge/src/main/java/asys/bridge/BungeeServerAPI.java @@ -0,0 +1,74 @@ +/* + * DmitriyMX + * 2016-08-26 + */ +package asys.bridge; + +import net.md_5.bungee.api.ProxyServer; +import net.md_5.bungee.api.config.ServerInfo; +import net.md_5.bungee.api.connection.ProxiedPlayer; +import net.md_5.bungee.config.Configuration; +import net.md_5.bungee.config.YamlConfiguration; + +import java.io.File; +import java.io.IOException; +import java.net.InetSocketAddress; +import java.util.Map; + +public class BungeeServerAPI { + private File file; + private Configuration bungeeConfig; + + public BungeeServerAPI() throws IOException { + file = new File(ProxyServer.getInstance().getPluginsFolder().getParentFile(), "config.yml"); + bungeeConfig = YamlConfiguration.getProvider(YamlConfiguration.class).load(file); + } + + public boolean addServer(String name, String address) { + if (getServers().get(name) != null) return false; + + String[] addrPort = address.split(":",2); + InetSocketAddress ipAddress = new InetSocketAddress(addrPort[0], Integer.valueOf(addrPort[1])); + + ServerInfo serverInfo = ProxyServer.getInstance().constructServerInfo(name, ipAddress, "", false); + getServers().put(serverInfo.getName(), serverInfo); + + bungeeConfig.set("servers." + serverInfo.getName() + ".motd", serverInfo.getMotd()); + bungeeConfig.set("servers." + serverInfo.getName() + ".address", serverInfo.getAddress().getAddress().getHostAddress() + ":" + serverInfo.getAddress().getPort()); + bungeeConfig.set("servers." + serverInfo.getName() + ".restricted", false); + + try { + YamlConfiguration.getProvider(YamlConfiguration.class).save(bungeeConfig, file); + } catch (IOException e) { + e.printStackTrace(); + } + + return true; + } + + public boolean removeServer(String name) { + ServerInfo serverInfo = getServers().get(name); + if (serverInfo == null) return false; + + //TODO не совсем корректно... + for (ProxiedPlayer player : serverInfo.getPlayers()) { + player.connect(getServers().get(player.getPendingConnection().getListener().getFallbackServer())); + } + + getServers().remove(name); + + bungeeConfig.set("servers." + name, null); + + try { + YamlConfiguration.getProvider(YamlConfiguration.class).save(bungeeConfig, file); + } catch (IOException e) { + e.printStackTrace(); + } + + return true; + } + + private Map getServers() { + return ProxyServer.getInstance().getServers(); + } +} diff --git a/Bridge/src/main/java/asys/bridge/netty/Client.java b/Bridge/src/main/java/asys/bridge/netty/Client.java new file mode 100644 index 0000000..39763fc --- /dev/null +++ b/Bridge/src/main/java/asys/bridge/netty/Client.java @@ -0,0 +1,72 @@ +/* + * DmitriyMX + * 2016-08-24 + */ +package asys.bridge.netty; + +import asys.bridge.Bridge; +import asys.lib.protocol.PacketDecoder; +import asys.lib.protocol.PacketEncoder; +import io.netty.bootstrap.Bootstrap; +import io.netty.channel.Channel; +import io.netty.channel.ChannelInitializer; +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.NioSocketChannel; + +import java.net.ConnectException; + +public class Client { + private String host; + private short port; + private Bridge bridge; + private EventLoopGroup group; + private Channel channel; + + public Client(String host, short port, Bridge bridge) { + this.host = host; + this.port = port; + this.bridge = bridge; + } + + public void connect() throws InterruptedException, ConnectException { + group = new NioEventLoopGroup(); + + Bootstrap bootstrap = prepare_Bootstrap(); + channel = bootstrap.connect(host, port).sync().channel(); + channel.closeFuture(); + } + + private Bootstrap prepare_Bootstrap() { + Bootstrap bootstrap = new Bootstrap(); + bootstrap.group(group) + .channel(NioSocketChannel.class) + .handler(prepare_ChannelInitializer()); + + 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 ClientHandler(bridge) + ); + } + }; + } + + public void disconnect() { + group.shutdownGracefully(); + } + + public boolean isConnected() { + return channel.isOpen(); + } +} diff --git a/Bridge/src/main/java/asys/bridge/netty/ClientHandler.java b/Bridge/src/main/java/asys/bridge/netty/ClientHandler.java new file mode 100644 index 0000000..a695149 --- /dev/null +++ b/Bridge/src/main/java/asys/bridge/netty/ClientHandler.java @@ -0,0 +1,47 @@ +/* + * DmitriyMX + * 2016-08-21 + */ +package asys.bridge.netty; + +import asys.bridge.Bridge; +import asys.lib.protocol.Packet; +import asys.lib.protocol.ServerInfoPacket; +import io.netty.channel.ChannelHandlerContext; +import io.netty.channel.SimpleChannelInboundHandler; + +public class ClientHandler extends SimpleChannelInboundHandler { + private Bridge bridge; + + public ClientHandler(Bridge bridge) { + this.bridge = bridge; + } + + @Override + public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception { + cause.printStackTrace(); + ctx.close(); + } + + @Override + protected void channelRead0(ChannelHandlerContext channelHandlerContext, Packet packet) throws Exception { + ServerInfoPacket infoPacket = (ServerInfoPacket)packet; + + if (infoPacket.getState() == 1) { + boolean result = bridge.getServerAPI().addServer(infoPacket.getServerId(), infoPacket.getAddress()); + if (result) bridge.getLogger().info(String.format("Add server '%s'", infoPacket.getServerId())); + else bridge.getLogger().warning(String.format("Server '%s' can't adding", infoPacket.getServerId())); + } else if (infoPacket.getState() == 0) { + boolean result = bridge.getServerAPI().removeServer(infoPacket.getServerId()); + if (result) bridge.getLogger().info(String.format("Remove server '%s'", infoPacket.getServerId())); + else bridge.getLogger().warning(String.format("Server '%s' can't removing", infoPacket.getServerId())); + } + + bridge.getLogger().config(String.format( + "Incomming packet: %d | %s | %s", + infoPacket.getState(), + infoPacket.getServerId(), + (infoPacket.getState() == 1 ? infoPacket.getAddress() : "") + )); + } +} diff --git a/Bridge/src/main/resources/bungee.yml b/Bridge/src/main/resources/bungee.yml new file mode 100644 index 0000000..4cfc632 --- /dev/null +++ b/Bridge/src/main/resources/bungee.yml @@ -0,0 +1,3 @@ +name: ASysBridge +main: ${bungee.mainclass} +version: ${project.version} \ No newline at end of file