Archived
0

Zond: соединение с ASys

This commit is contained in:
2017-06-08 13:18:29 +03:00
parent 2d53066132
commit 118e4fe896
6 changed files with 268 additions and 5 deletions

View 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;
}
}
}

View File

@@ -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());
}
}

View 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()
);
}
};
}
}

View 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");
}
}
}