Zond: соединение с ASys
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
group = 'asys'
|
||||
version = '0.1-SNAPSHOT'
|
||||
version = '0.2-SNAPSHOT'
|
||||
|
||||
apply plugin: 'application'
|
||||
|
||||
@@ -10,7 +10,13 @@ configurations {
|
||||
compile.extendsFrom included
|
||||
}
|
||||
|
||||
compileJava {
|
||||
dependsOn ':bridge-protocol:compileJava'
|
||||
}
|
||||
|
||||
jar {
|
||||
dependsOn ':bridge-protocol:jar'
|
||||
dependsOn configurations.included
|
||||
manifest {
|
||||
attributes 'Implementation-Title': 'ASys Zond',
|
||||
'Implementation-Version': version,
|
||||
@@ -20,7 +26,14 @@ jar {
|
||||
from { configurations.included.collect { it.isDirectory() ? it : zipTree(it) } }
|
||||
}
|
||||
|
||||
ext {
|
||||
nettyVersion = '4.0.23.Final'
|
||||
}
|
||||
|
||||
dependencies {
|
||||
included files(project(':bridge-protocol').sourceSets.main.output.classesDir)
|
||||
included group: 'org.fusesource.jansi', name: 'jansi', version: '1.11'
|
||||
included group: 'org.apache.commons', name: 'commons-exec', version: '1.3'
|
||||
included group: 'io.netty', name: 'netty-codec', version: nettyVersion
|
||||
included group: 'com.google.guava', name: 'guava', version: '21.0'
|
||||
}
|
||||
|
||||
35
zond/src/main/java/asys/zond/Config.java
Normal file
35
zond/src/main/java/asys/zond/Config.java
Normal file
@@ -0,0 +1,35 @@
|
||||
/*
|
||||
* DmitriyMX <d.mihailov@samson-rus.com>
|
||||
* 2017-06-08
|
||||
*/
|
||||
package asys.zond;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.util.Properties;
|
||||
|
||||
public class Config {
|
||||
private static Properties properties = new Properties();
|
||||
|
||||
private Config(){
|
||||
}
|
||||
|
||||
public static void load(InputStream inputStream) throws IOException {
|
||||
properties.load(inputStream);
|
||||
if (properties.size() == 0) {
|
||||
throw new IOException("Config empty!");
|
||||
}
|
||||
}
|
||||
|
||||
public static String getString(String key) {
|
||||
return properties.getProperty(key);
|
||||
}
|
||||
|
||||
public static int getInt(String key) {
|
||||
try {
|
||||
return Integer.parseInt(properties.getProperty(key));
|
||||
} catch (NumberFormatException e) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -5,6 +5,7 @@
|
||||
*/
|
||||
package asys.zond;
|
||||
|
||||
import asys.zond.proxy.Client;
|
||||
import org.apache.commons.exec.CommandLine;
|
||||
import org.apache.commons.exec.DefaultExecutor;
|
||||
import org.apache.commons.exec.ExecuteException;
|
||||
@@ -13,13 +14,22 @@ import org.fusesource.jansi.Ansi;
|
||||
import org.fusesource.jansi.Ansi.Color;
|
||||
import org.fusesource.jansi.AnsiConsole;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.*;
|
||||
import java.util.Arrays;
|
||||
import java.util.concurrent.Executors;
|
||||
import java.util.concurrent.ScheduledExecutorService;
|
||||
import java.util.concurrent.ScheduledFuture;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import static org.fusesource.jansi.Ansi.ansi;
|
||||
|
||||
public class Main {
|
||||
private static Client client;
|
||||
private static ScheduledExecutorService ses;
|
||||
private static ScheduledFuture<?> sesFuture;
|
||||
private static int tryConnect = 0;
|
||||
|
||||
public static void main(String[] args) throws IOException {
|
||||
if (Boolean.getBoolean("ansi.install")) {
|
||||
AnsiConsole.systemInstall();
|
||||
@@ -36,6 +46,21 @@ public class Main {
|
||||
return;
|
||||
}
|
||||
|
||||
loadConfig();
|
||||
startReconnect();
|
||||
|
||||
int resultCode = executeProcess(args);
|
||||
|
||||
stopReconnect();
|
||||
ses.shutdown();
|
||||
client.disconnect();
|
||||
|
||||
System.out.print(ansi().reset().newline()
|
||||
.fg(Color.GREEN).a("Process Finished. Code: ")
|
||||
.bold().fg(Color.WHITE).a(resultCode).reset().newline());
|
||||
}
|
||||
|
||||
private static int executeProcess(String[] args) {
|
||||
String cmdLine = Arrays.stream(args).collect(Collectors.joining(" "));
|
||||
CommandLine commandLine = CommandLine.parse(cmdLine);
|
||||
DefaultExecutor executor = new DefaultExecutor();
|
||||
@@ -46,9 +71,56 @@ public class Main {
|
||||
try {
|
||||
resultCode = executor.execute(commandLine);
|
||||
} catch (ExecuteException ignore) {
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
resultCode = -1;
|
||||
}
|
||||
|
||||
return resultCode;
|
||||
}
|
||||
|
||||
private static void loadConfig() throws IOException {
|
||||
File zondPropertiesFile = new File("zond.properties");
|
||||
if (!zondPropertiesFile.exists()) {
|
||||
InputStream stream = Main.class.getResourceAsStream("/zond.properties");
|
||||
FileOutputStream fos = new FileOutputStream(zondPropertiesFile);
|
||||
byte[] buff = new byte[65536];
|
||||
int len;
|
||||
while ((len = stream.read(buff)) > 0) {
|
||||
fos.write(buff, 0, len);
|
||||
}
|
||||
fos.flush();
|
||||
fos.close();
|
||||
}
|
||||
|
||||
FileInputStream fis = new FileInputStream(zondPropertiesFile);
|
||||
Config.load(fis);
|
||||
fis.close();
|
||||
}
|
||||
|
||||
public static void log(String message){
|
||||
System.out.println("[ASys Zond] " + message);
|
||||
}
|
||||
|
||||
public static void startReconnect() {
|
||||
client = new Client();
|
||||
ses = Executors.newScheduledThreadPool(2);
|
||||
sesFuture = ses.scheduleAtFixedRate(() -> {
|
||||
log(String.format("Connect(%d) to ASys...", ++tryConnect));
|
||||
client.connect(Config.getString("host"), Config.getInt("port"));
|
||||
if (client.isConnected()) {
|
||||
stopReconnect();
|
||||
} else {
|
||||
log(String.format("Connection(%d) fail. Try reconnect...", tryConnect));
|
||||
}
|
||||
}, 0L, 5L, TimeUnit.SECONDS);
|
||||
}
|
||||
|
||||
private static void stopReconnect() {
|
||||
if (sesFuture != null) {
|
||||
sesFuture.cancel(false);
|
||||
sesFuture = null;
|
||||
tryConnect = 0;
|
||||
}
|
||||
System.out.print(ansi().reset().newline()
|
||||
.fg(Color.GREEN).a("Process Finished. Code: ")
|
||||
.bold().fg(Color.WHITE).a(resultCode).reset().newline());
|
||||
}
|
||||
}
|
||||
|
||||
60
zond/src/main/java/asys/zond/proxy/Client.java
Normal file
60
zond/src/main/java/asys/zond/proxy/Client.java
Normal file
@@ -0,0 +1,60 @@
|
||||
/*
|
||||
* DmitriyMX <d.mihailov@samson-rus.com>
|
||||
* 2017-06-08
|
||||
*/
|
||||
package asys.zond.proxy;
|
||||
|
||||
import asys.mcsmanager.packets.codec.PacketDecoder;
|
||||
import asys.mcsmanager.packets.codec.PacketEncoder;
|
||||
import asys.mcsmanager.packets.codec.PacketHandler;
|
||||
import io.netty.bootstrap.Bootstrap;
|
||||
import io.netty.channel.ChannelFuture;
|
||||
import io.netty.channel.ChannelInitializer;
|
||||
import io.netty.channel.EventLoopGroup;
|
||||
import io.netty.channel.nio.NioEventLoopGroup;
|
||||
import io.netty.channel.socket.SocketChannel;
|
||||
import io.netty.channel.socket.nio.NioSocketChannel;
|
||||
|
||||
public class Client {
|
||||
private EventLoopGroup group;
|
||||
private Bootstrap bootstrap;
|
||||
private ChannelFuture channelFuture;
|
||||
|
||||
public void connect(String host, int port) {
|
||||
if (group == null || bootstrap == null) {
|
||||
group = new NioEventLoopGroup();
|
||||
bootstrap = createBootstrap();
|
||||
}
|
||||
}
|
||||
|
||||
public boolean isConnected() {
|
||||
return (channelFuture != null && channelFuture.isSuccess());
|
||||
}
|
||||
|
||||
public void disconnect() {
|
||||
group.shutdownGracefully();
|
||||
}
|
||||
|
||||
private Bootstrap createBootstrap() {
|
||||
Bootstrap bootstrap = new Bootstrap();
|
||||
bootstrap.group(group)
|
||||
.channel(NioSocketChannel.class)
|
||||
.handler(createChannelInitializer());
|
||||
|
||||
return bootstrap;
|
||||
}
|
||||
|
||||
private ChannelInitializer createChannelInitializer() {
|
||||
return new ChannelInitializer<SocketChannel>() {
|
||||
@Override
|
||||
protected void initChannel(SocketChannel socketChannel) throws Exception {
|
||||
socketChannel.pipeline().addLast(
|
||||
new PacketEncoder(),
|
||||
new PacketDecoder(),
|
||||
new PacketHandler(),
|
||||
new ClientPacketHandler()
|
||||
);
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
79
zond/src/main/java/asys/zond/proxy/ClientPacketHandler.java
Normal file
79
zond/src/main/java/asys/zond/proxy/ClientPacketHandler.java
Normal file
@@ -0,0 +1,79 @@
|
||||
/*
|
||||
* DmitriyMX <d.mihailov@samson-rus.com>
|
||||
* 2017-06-08
|
||||
*/
|
||||
package asys.zond.proxy;
|
||||
|
||||
import asys.mcsmanager.packets.*;
|
||||
import asys.zond.Config;
|
||||
import asys.zond.Main;
|
||||
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 java.util.Map;
|
||||
|
||||
import static asys.mcsmanager.packets.codec.Params.KNOWN_HANDLERS;
|
||||
import static asys.mcsmanager.packets.codec.Params.KNOWN_PACKETS;
|
||||
import static asys.zond.Main.log;
|
||||
|
||||
public class ClientPacketHandler extends ChannelInboundHandlerAdapter implements IPacketHandler {
|
||||
private static final BiMap<Integer, Class<? extends Packet>> handshakePackets = ImmutableBiMap.of(
|
||||
1, CS_Handshake.class,
|
||||
2, SC_HandshakeResult.class
|
||||
);
|
||||
private static Map<Class<? extends Packet>, IPacketHandler> handshakeHandlers;
|
||||
|
||||
private static final BiMap<Integer, Class<? extends Packet>> knownPackets = ImmutableBiMap.of(
|
||||
3, CS_Ping.class,
|
||||
4, CS_ConsoleMessage.class
|
||||
);
|
||||
|
||||
ClientPacketHandler() {
|
||||
if (handshakeHandlers == null) {
|
||||
handshakeHandlers = ImmutableMap.of(
|
||||
SC_HandshakeResult.class, this
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void channelActive(ChannelHandlerContext ctx) throws Exception {
|
||||
log("channelActive");
|
||||
ctx.channel().attr(KNOWN_PACKETS).set(handshakePackets);
|
||||
ctx.channel().attr(KNOWN_HANDLERS).set(handshakeHandlers);
|
||||
|
||||
CS_Handshake packet = new CS_Handshake(
|
||||
Config.getString("clientId"),
|
||||
Config.getString("passcode"));
|
||||
log("send Handshake packet...");
|
||||
ctx.channel().writeAndFlush(packet);
|
||||
|
||||
super.channelActive(ctx);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void channelInactive(ChannelHandlerContext ctx) throws Exception {
|
||||
log("Lost connection!");
|
||||
log("Try reconnect...");
|
||||
Main.startReconnect();
|
||||
|
||||
ctx.channel().attr(KNOWN_PACKETS).remove();
|
||||
ctx.channel().attr(KNOWN_HANDLERS).remove();
|
||||
super.channelInactive(ctx);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handle(Packet packet, ChannelHandlerContext context) {
|
||||
log("handle : " + packet.getClass().getSimpleName());
|
||||
SC_HandshakeResult pkt = (SC_HandshakeResult) packet;
|
||||
if (pkt.getErrorCode() != 0) {
|
||||
log(String.format("Handshake: #%d %s", pkt.getErrorCode(), pkt.getMessage()));
|
||||
} else {
|
||||
context.channel().attr(KNOWN_PACKETS).set(knownPackets);
|
||||
log("Handshake: OK");
|
||||
}
|
||||
}
|
||||
}
|
||||
4
zond/src/main/resources/zond.properties
Normal file
4
zond/src/main/resources/zond.properties
Normal file
@@ -0,0 +1,4 @@
|
||||
clientId = SpigotServer0
|
||||
host = 127.0.0.1
|
||||
port = 8779
|
||||
passcode = testpassphrase
|
||||
Reference in New Issue
Block a user