Search in sources :

Example 1 with MCVersion

use of com.loohp.interactivechat.utils.MCVersion in project InteractiveChat by LOOHP.

the class ServerPingVelocity method getPing.

@SuppressWarnings("deprecation")
public static CompletableFuture<ServerPingVelocity> getPing(ServerInfo server) {
    CompletableFuture<ServerPingVelocity> future = new CompletableFuture<>();
    new Thread(() -> {
        try (Socket socket = new Socket()) {
            InetSocketAddress address = server.getAddress();
            socket.connect(new InetSocketAddress(address.getHostName(), address.getPort()), 1500);
            if (socket.isConnected()) {
                DataInputStream input = new DataInputStream(socket.getInputStream());
                DataOutputStream output = new DataOutputStream(socket.getOutputStream());
                ByteArrayOutputStream buffer = new ByteArrayOutputStream();
                DataOutputStream out = new DataOutputStream(buffer);
                out.writeByte(0x00);
                DataStreamIO.writeVarInt(out, -1);
                DataStreamIO.writeString(out, Registry.PLUGIN_MESSAGING_PROTOCOL_IDENTIFIER, StandardCharsets.UTF_8);
                out.writeShort(25566);
                DataStreamIO.writeVarInt(out, 1);
                byte[] handshake = buffer.toByteArray();
                DataStreamIO.writeVarInt(output, handshake.length);
                output.write(handshake);
                buffer = new ByteArrayOutputStream();
                out = new DataOutputStream(buffer);
                out.writeByte(0x00);
                byte[] request = buffer.toByteArray();
                DataStreamIO.writeVarInt(output, request.length);
                output.write(request);
                DataStreamIO.readVarInt(input);
                int packetId = DataStreamIO.readVarInt(input);
                if (packetId == -1) {
                    throw new IOException("Premature end of stream.");
                }
                if (packetId != 0x00) {
                    // we want a status response
                    throw new IOException("Invalid packetID " + Integer.toHexString(packetId));
                }
                // length of json string
                int length = DataStreamIO.readVarInt(input);
                if (length == -1) {
                    throw new IOException("Premature end of stream.");
                }
                if (length == 0) {
                    throw new IOException("Invalid string length.");
                }
                byte[] in = new byte[length];
                input.readFully(in);
                String jsonStr = new String(in);
                boolean present;
                String version;
                MCVersion minecraftVersion;
                String exactMinecraftVersion;
                int protocol;
                try {
                    JSONObject json = (JSONObject) new JSONParser().parse(jsonStr);
                    Object descriptionObj = json.get("description");
                    JSONObject data;
                    if (descriptionObj instanceof JSONObject) {
                        JSONObject description = (JSONObject) json.get("description");
                        String descriptionAsStr = PlainTextComponentSerializer.plainText().serialize(InteractiveChatComponentSerializer.gson().deserialize(description.toJSONString()));
                        data = (JSONObject) new JSONParser().parse(descriptionAsStr);
                    } else {
                        data = (JSONObject) new JSONParser().parse(StringEscapeUtils.unescapeJava(descriptionObj.toString()));
                    }
                    present = (boolean) data.get("present");
                    version = (String) data.get("version");
                    minecraftVersion = MCVersion.fromNumber((int) (long) data.get("minecraftVersion"));
                    exactMinecraftVersion = (String) data.get("exactMinecraftVersion");
                    protocol = data.containsKey("protocol") ? (int) (long) data.get("protocol") : 0;
                } catch (Exception e) {
                    present = false;
                    version = UNKNOWN_VERSION;
                    minecraftVersion = MCVersion.UNSUPPORTED;
                    exactMinecraftVersion = UNKNOWN_VERSION;
                    protocol = UNKNOWN_PROTOCOL;
                }
                long start = System.currentTimeMillis();
                buffer = new ByteArrayOutputStream();
                out = new DataOutputStream(buffer);
                out.writeByte(0x01);
                out.writeLong(start);
                byte[] ping = buffer.toByteArray();
                DataStreamIO.writeVarInt(output, ping.length);
                output.write(ping);
                DataStreamIO.readVarInt(input);
                packetId = DataStreamIO.readVarInt(input);
                int pong = (int) (System.currentTimeMillis() - start);
                if (packetId == -1) {
                    throw new IOException("Premature end of stream.");
                }
                if (packetId != 0x01) {
                    // we want a pong
                    throw new IOException("Invalid packetID " + Integer.toHexString(packetId));
                }
                future.complete(new ServerPingVelocity(pong, present));
                BackendInteractiveChatData data = InteractiveChatVelocity.serverInteractiveChatInfo.get(server.getName());
                if (data == null) {
                    InteractiveChatVelocity.serverInteractiveChatInfo.put(server.getName(), new BackendInteractiveChatData(server.getName(), true, present, version, minecraftVersion, exactMinecraftVersion, pong, protocol));
                } else {
                    data.setPing(pong);
                    if (!data.isOnline()) {
                        data.setOnline(true);
                    }
                    if (data.hasInteractiveChat() != present) {
                        data.setInteractiveChat(present);
                    }
                    if (!data.getVersion().equals(version)) {
                        data.setVersion(version);
                    }
                    if (!data.getMinecraftVersion().equals(minecraftVersion)) {
                        data.setMinecraftVersion(minecraftVersion);
                    }
                    if (!data.getExactMinecraftVersion().equals(exactMinecraftVersion)) {
                        data.setExactMinecraftVersion(exactMinecraftVersion);
                    }
                    if (data.getProtocolVersion() != protocol) {
                        data.setProtocolVersion(protocol);
                    }
                }
            } else {
                future.complete(new ServerPingVelocity(-1, false));
                BackendInteractiveChatData data = InteractiveChatVelocity.serverInteractiveChatInfo.get(server.getName());
                if (data == null) {
                    InteractiveChatVelocity.serverInteractiveChatInfo.put(server.getName(), new BackendInteractiveChatData(server.getName(), false, false, UNKNOWN_VERSION, MCVersion.UNSUPPORTED, UNKNOWN_VERSION, -1, UNKNOWN_PROTOCOL));
                } else {
                    data.setPing(-1);
                    if (data.isOnline()) {
                        data.setOnline(false);
                    }
                    if (data.hasInteractiveChat()) {
                        data.setInteractiveChat(false);
                    }
                    if (!data.getVersion().equals(UNKNOWN_VERSION)) {
                        data.setVersion(UNKNOWN_VERSION);
                    }
                    if (data.getProtocolVersion() != UNKNOWN_PROTOCOL) {
                        data.setProtocolVersion(UNKNOWN_PROTOCOL);
                    }
                }
            }
        } catch (IOException e) {
            future.complete(new ServerPingVelocity(-1, false));
            BackendInteractiveChatData data = InteractiveChatVelocity.serverInteractiveChatInfo.get(server.getName());
            if (data == null) {
                InteractiveChatVelocity.serverInteractiveChatInfo.put(server.getName(), new BackendInteractiveChatData(server.getName(), false, false, UNKNOWN_VERSION, MCVersion.UNSUPPORTED, UNKNOWN_VERSION, -1, UNKNOWN_PROTOCOL));
            } else {
                data.setPing(-1);
                if (data.isOnline()) {
                    data.setOnline(false);
                }
                if (data.hasInteractiveChat()) {
                    data.setInteractiveChat(false);
                }
                if (!data.getVersion().equals(UNKNOWN_VERSION)) {
                    data.setVersion(UNKNOWN_VERSION);
                }
                if (data.getProtocolVersion() != UNKNOWN_PROTOCOL) {
                    data.setProtocolVersion(UNKNOWN_PROTOCOL);
                }
            }
        }
    }).start();
    return future;
}
Also used : InetSocketAddress(java.net.InetSocketAddress) DataOutputStream(java.io.DataOutputStream) BackendInteractiveChatData(com.loohp.interactivechat.proxy.objectholders.BackendInteractiveChatData) ByteArrayOutputStream(java.io.ByteArrayOutputStream) IOException(java.io.IOException) DataInputStream(java.io.DataInputStream) IOException(java.io.IOException) CompletableFuture(java.util.concurrent.CompletableFuture) MCVersion(com.loohp.interactivechat.utils.MCVersion) JSONObject(org.json.simple.JSONObject) JSONParser(org.json.simple.parser.JSONParser) JSONObject(org.json.simple.JSONObject) Socket(java.net.Socket)

Example 2 with MCVersion

use of com.loohp.interactivechat.utils.MCVersion in project InteractiveChat by LOOHP.

the class ServerPingBungee method getPing.

@SuppressWarnings("deprecation")
public static CompletableFuture<ServerPingBungee> getPing(ServerInfo server) {
    CompletableFuture<ServerPingBungee> future = new CompletableFuture<>();
    new Thread(() -> {
        try (Socket socket = new Socket()) {
            SocketAddress address = server.getSocketAddress();
            if (address instanceof InetSocketAddress) {
                InetSocketAddress inetAddress = (InetSocketAddress) address;
                socket.connect(new InetSocketAddress(inetAddress.getHostName(), inetAddress.getPort()), 1500);
            } else {
                socket.connect(address, 1500);
            }
            if (socket.isConnected()) {
                DataInputStream input = new DataInputStream(socket.getInputStream());
                DataOutputStream output = new DataOutputStream(socket.getOutputStream());
                ByteArrayOutputStream buffer = new ByteArrayOutputStream();
                DataOutputStream out = new DataOutputStream(buffer);
                out.writeByte(0x00);
                DataStreamIO.writeVarInt(out, -1);
                DataStreamIO.writeString(out, Registry.PLUGIN_MESSAGING_PROTOCOL_IDENTIFIER, StandardCharsets.UTF_8);
                out.writeShort(25566);
                DataStreamIO.writeVarInt(out, 1);
                byte[] handshake = buffer.toByteArray();
                DataStreamIO.writeVarInt(output, handshake.length);
                output.write(handshake);
                buffer = new ByteArrayOutputStream();
                out = new DataOutputStream(buffer);
                out.writeByte(0x00);
                byte[] request = buffer.toByteArray();
                DataStreamIO.writeVarInt(output, request.length);
                output.write(request);
                DataStreamIO.readVarInt(input);
                int packetId = DataStreamIO.readVarInt(input);
                if (packetId == -1) {
                    throw new IOException("Premature end of stream.");
                }
                if (packetId != 0x00) {
                    // we want a status response
                    throw new IOException("Invalid packetID " + Integer.toHexString(packetId));
                }
                // length of json string
                int length = DataStreamIO.readVarInt(input);
                if (length == -1) {
                    throw new IOException("Premature end of stream.");
                }
                if (length == 0) {
                    throw new IOException("Invalid string length.");
                }
                byte[] in = new byte[length];
                input.readFully(in);
                String jsonStr = new String(in);
                boolean present;
                String version;
                MCVersion minecraftVersion;
                String exactMinecraftVersion;
                int protocol;
                try {
                    JSONObject json = (JSONObject) new JSONParser().parse(jsonStr);
                    Object descriptionObj = json.get("description");
                    JSONObject data;
                    if (descriptionObj instanceof JSONObject) {
                        JSONObject description = (JSONObject) json.get("description");
                        String descriptionAsStr = ChatColor.stripColor(ComponentSerializer.parse(description.toJSONString())[0].toPlainText());
                        data = (JSONObject) new JSONParser().parse(descriptionAsStr);
                    } else {
                        data = (JSONObject) new JSONParser().parse(StringEscapeUtils.unescapeJava(descriptionObj.toString()));
                    }
                    present = (boolean) data.get("present");
                    version = (String) data.get("version");
                    minecraftVersion = MCVersion.fromNumber((int) (long) data.get("minecraftVersion"));
                    exactMinecraftVersion = (String) data.get("exactMinecraftVersion");
                    protocol = data.containsKey("protocol") ? (int) (long) data.get("protocol") : 0;
                } catch (Exception e) {
                    present = false;
                    version = UNKNOWN_VERSION;
                    minecraftVersion = MCVersion.UNSUPPORTED;
                    exactMinecraftVersion = UNKNOWN_VERSION;
                    protocol = UNKNOWN_PROTOCOL;
                }
                long start = System.currentTimeMillis();
                buffer = new ByteArrayOutputStream();
                out = new DataOutputStream(buffer);
                out.writeByte(0x01);
                out.writeLong(start);
                byte[] ping = buffer.toByteArray();
                DataStreamIO.writeVarInt(output, ping.length);
                output.write(ping);
                DataStreamIO.readVarInt(input);
                packetId = DataStreamIO.readVarInt(input);
                int pong = (int) (System.currentTimeMillis() - start);
                if (packetId == -1) {
                    throw new IOException("Premature end of stream.");
                }
                if (packetId != 0x01) {
                    // we want a pong
                    throw new IOException("Invalid packetID " + Integer.toHexString(packetId));
                }
                future.complete(new ServerPingBungee(pong, present));
                BackendInteractiveChatData data = InteractiveChatBungee.serverInteractiveChatInfo.get(server.getName());
                if (data == null) {
                    InteractiveChatBungee.serverInteractiveChatInfo.put(server.getName(), new BackendInteractiveChatData(server.getName(), true, present, version, minecraftVersion, exactMinecraftVersion, pong, protocol));
                } else {
                    data.setPing(pong);
                    if (!data.isOnline()) {
                        data.setOnline(true);
                    }
                    if (data.hasInteractiveChat() != present) {
                        data.setInteractiveChat(present);
                    }
                    if (!data.getVersion().equals(version)) {
                        data.setVersion(version);
                    }
                    if (!data.getMinecraftVersion().equals(minecraftVersion)) {
                        data.setMinecraftVersion(minecraftVersion);
                    }
                    if (!data.getExactMinecraftVersion().equals(exactMinecraftVersion)) {
                        data.setExactMinecraftVersion(exactMinecraftVersion);
                    }
                    if (data.getProtocolVersion() != protocol) {
                        data.setProtocolVersion(protocol);
                    }
                }
            } else {
                future.complete(new ServerPingBungee(-1, false));
                BackendInteractiveChatData data = InteractiveChatBungee.serverInteractiveChatInfo.get(server.getName());
                if (data == null) {
                    InteractiveChatBungee.serverInteractiveChatInfo.put(server.getName(), new BackendInteractiveChatData(server.getName(), false, false, UNKNOWN_VERSION, MCVersion.UNSUPPORTED, UNKNOWN_VERSION, -1, UNKNOWN_PROTOCOL));
                } else {
                    data.setPing(-1);
                    if (data.isOnline()) {
                        data.setOnline(false);
                    }
                    if (data.hasInteractiveChat()) {
                        data.setInteractiveChat(false);
                    }
                    if (!data.getVersion().equals(UNKNOWN_VERSION)) {
                        data.setVersion(UNKNOWN_VERSION);
                    }
                    if (data.getProtocolVersion() != UNKNOWN_PROTOCOL) {
                        data.setProtocolVersion(UNKNOWN_PROTOCOL);
                    }
                }
            }
        } catch (IOException e) {
            future.complete(new ServerPingBungee(-1, false));
            BackendInteractiveChatData data = InteractiveChatBungee.serverInteractiveChatInfo.get(server.getName());
            if (data == null) {
                InteractiveChatBungee.serverInteractiveChatInfo.put(server.getName(), new BackendInteractiveChatData(server.getName(), false, false, UNKNOWN_VERSION, MCVersion.UNSUPPORTED, UNKNOWN_VERSION, -1, UNKNOWN_PROTOCOL));
            } else {
                data.setPing(-1);
                if (data.isOnline()) {
                    data.setOnline(false);
                }
                if (data.hasInteractiveChat()) {
                    data.setInteractiveChat(false);
                }
                if (!data.getVersion().equals(UNKNOWN_VERSION)) {
                    data.setVersion(UNKNOWN_VERSION);
                }
                if (data.getProtocolVersion() != UNKNOWN_PROTOCOL) {
                    data.setProtocolVersion(UNKNOWN_PROTOCOL);
                }
            }
        }
    }).start();
    return future;
}
Also used : InetSocketAddress(java.net.InetSocketAddress) DataOutputStream(java.io.DataOutputStream) BackendInteractiveChatData(com.loohp.interactivechat.proxy.objectholders.BackendInteractiveChatData) ByteArrayOutputStream(java.io.ByteArrayOutputStream) IOException(java.io.IOException) DataInputStream(java.io.DataInputStream) IOException(java.io.IOException) CompletableFuture(java.util.concurrent.CompletableFuture) MCVersion(com.loohp.interactivechat.utils.MCVersion) JSONObject(org.json.simple.JSONObject) JSONParser(org.json.simple.parser.JSONParser) JSONObject(org.json.simple.JSONObject) SocketAddress(java.net.SocketAddress) InetSocketAddress(java.net.InetSocketAddress) Socket(java.net.Socket)

Aggregations

BackendInteractiveChatData (com.loohp.interactivechat.proxy.objectholders.BackendInteractiveChatData)2 MCVersion (com.loohp.interactivechat.utils.MCVersion)2 ByteArrayOutputStream (java.io.ByteArrayOutputStream)2 DataInputStream (java.io.DataInputStream)2 DataOutputStream (java.io.DataOutputStream)2 IOException (java.io.IOException)2 InetSocketAddress (java.net.InetSocketAddress)2 Socket (java.net.Socket)2 CompletableFuture (java.util.concurrent.CompletableFuture)2 JSONObject (org.json.simple.JSONObject)2 JSONParser (org.json.simple.parser.JSONParser)2 SocketAddress (java.net.SocketAddress)1