mirror of
https://github.com/ayunami2000/ayungee.git
synced 2024-12-22 06:44:11 -08:00
Kicking & slight bungee plugin compatibility!!
poggers!!
This commit is contained in:
parent
36bfd5469e
commit
d79fe57f16
81
src/main/java/me/ayunami2000/ayungee/ChatHandler.java
Normal file
81
src/main/java/me/ayunami2000/ayungee/ChatHandler.java
Normal file
|
@ -0,0 +1,81 @@
|
||||||
|
package me.ayunami2000.ayungee;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.nio.ByteBuffer;
|
||||||
|
|
||||||
|
public class ChatHandler {
|
||||||
|
// return true to cancel being sent to server/client
|
||||||
|
|
||||||
|
public static boolean fromServer(Client client, String message) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean fromClient(Client client, String message) {
|
||||||
|
if (!message.startsWith("/")) return false;
|
||||||
|
int ind = message.indexOf(' ');
|
||||||
|
String commandBase = message.substring(1, ind != -1 ? ind : message.length()).toLowerCase();
|
||||||
|
String args = ind != -1 ? message.substring(ind + 1) : "";
|
||||||
|
switch (commandBase) {
|
||||||
|
case "server":
|
||||||
|
if (args.isEmpty()) {
|
||||||
|
//usage msg
|
||||||
|
client.conn.send(new byte[] { 3, 0, 25, 0, (byte) 167, 0, 57, 0, 85, 0, 115, 0, 97, 0, 103, 0, 101, 0, 58, 0, 32, 0, 47, 0, 115, 0, 101, 0, 114, 0, 118, 0, 101, 0, 114, 0, 32, 0, 60, 0, 110, 0, 117, 0, 109, 0, 98, 0, 101, 0, 114, 0, 62 });
|
||||||
|
} else {
|
||||||
|
try {
|
||||||
|
int destServer = Integer.parseInt(args);
|
||||||
|
client.server = Math.max(0, Math.min(Main.servers.size() - 1, destServer));
|
||||||
|
try {
|
||||||
|
client.socket.close();
|
||||||
|
} catch (IOException ignored) {}
|
||||||
|
} catch (NumberFormatException e) {
|
||||||
|
//not a number
|
||||||
|
client.conn.send(new byte[] { 3, 0, 29, 0, (byte) 167, 0, 57, 0, 84, 0, 104, 0, 97, 0, 116, 0, 32, 0, 105, 0, 115, 0, 32, 0, 110, 0, 111, 0, 116, 0, 32, 0, 97, 0, 32, 0, 118, 0, 97, 0, 108, 0, 105, 0, 100, 0, 32, 0, 110, 0, 117, 0, 109, 0, 98, 0, 101, 0, 114, 0, 33 });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
/*
|
||||||
|
case "register":
|
||||||
|
|
||||||
|
break;
|
||||||
|
case "login":
|
||||||
|
|
||||||
|
break;
|
||||||
|
*/
|
||||||
|
default:
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean serverChatMessage(Client client, byte[] packet) {
|
||||||
|
return fireChatMessage(client, true, packet);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean clientChatMessage(Client client, byte[] packet) {
|
||||||
|
return fireChatMessage(client, false, packet);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static boolean fireChatMessage(Client client, boolean fromServer, byte[] packet) {
|
||||||
|
if (packet.length >= 3 && packet[0] == 3) {
|
||||||
|
ByteBuffer bb = ByteBuffer.wrap(packet);
|
||||||
|
bb.get();
|
||||||
|
int msgLen = bb.getShort(); //(short) ((msg[1] << 8) + msg[2] & 0xff);
|
||||||
|
if (msgLen >= 0) {
|
||||||
|
if (packet.length >= 3 + msgLen * 2) {
|
||||||
|
//byte[] chatBytes = new byte[msgLen];
|
||||||
|
//for (int i = 0; i < chatBytes.length; i++) chatBytes[i] = msg[4 + i * 2];
|
||||||
|
//String chatMsg = new String(chatBytes);
|
||||||
|
StringBuilder chatBuilder = new StringBuilder();
|
||||||
|
for (int i = 0; i < msgLen; i++) chatBuilder.append(bb.getChar());
|
||||||
|
String chatMsg = chatBuilder.toString();
|
||||||
|
if (fromServer) {
|
||||||
|
return fromServer(client, chatMsg);
|
||||||
|
} else {
|
||||||
|
return fromClient(client, chatMsg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,5 +1,7 @@
|
||||||
package me.ayunami2000.ayungee;
|
package me.ayunami2000.ayungee;
|
||||||
|
|
||||||
|
import org.java_websocket.WebSocket;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.io.OutputStream;
|
import java.io.OutputStream;
|
||||||
|
@ -14,6 +16,8 @@ public class Client {
|
||||||
|
|
||||||
public List<byte[]> msgCache =new ArrayList<>();
|
public List<byte[]> msgCache =new ArrayList<>();
|
||||||
|
|
||||||
|
public WebSocket conn;
|
||||||
|
|
||||||
public String username;
|
public String username;
|
||||||
|
|
||||||
public int server = 0;
|
public int server = 0;
|
||||||
|
@ -33,7 +37,12 @@ public class Client {
|
||||||
socketIn = sock.getInputStream();
|
socketIn = sock.getInputStream();
|
||||||
}
|
}
|
||||||
|
|
||||||
public Client(String uname) {
|
public Client(WebSocket c, String uname) {
|
||||||
|
conn = c;
|
||||||
username = uname;
|
username = uname;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public String toString() {
|
||||||
|
return username + " (" + Main.getIp(conn) + ")";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,7 +14,6 @@ import java.nio.file.StandardCopyOption;
|
||||||
import java.time.Instant;
|
import java.time.Instant;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
import java.util.regex.Pattern;
|
import java.util.regex.Pattern;
|
||||||
import java.util.stream.Collectors;
|
|
||||||
|
|
||||||
public class Main {
|
public class Main {
|
||||||
public static List<ServerItem> servers = new ArrayList<>();
|
public static List<ServerItem> servers = new ArrayList<>();
|
||||||
|
@ -92,7 +91,7 @@ public class Main {
|
||||||
Files.copy(cc.getInputStream(), Paths.get("origin_blacklist.txt"), StandardCopyOption.REPLACE_EXISTING);
|
Files.copy(cc.getInputStream(), Paths.get("origin_blacklist.txt"), StandardCopyOption.REPLACE_EXISTING);
|
||||||
readUrlBlacklist();
|
readUrlBlacklist();
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
System.out.println("An error occurred attempting to update the origin blacklist!");
|
printMsg("An error occurred attempting to update the origin blacklist!");
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
Thread.sleep(300000);
|
Thread.sleep(300000);
|
||||||
|
@ -161,16 +160,49 @@ public class Main {
|
||||||
|
|
||||||
BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
|
BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
|
||||||
boolean running = true;
|
boolean running = true;
|
||||||
System.out.println("ayungee started!");
|
printMsg("ayungee started!");
|
||||||
while (running) {
|
while (running) {
|
||||||
//System.out.print("> ");
|
|
||||||
String cmd = reader.readLine();
|
String cmd = reader.readLine();
|
||||||
String[] pieces = cmd.split(" ");
|
String[] pieces = cmd.split(" ");
|
||||||
pieces[0] = pieces[0].toLowerCase();
|
pieces[0] = pieces[0].toLowerCase();
|
||||||
switch (pieces[0]) {
|
switch (pieces[0]) {
|
||||||
case "help":
|
case "help":
|
||||||
case "?":
|
case "?":
|
||||||
System.out.println("help ; unban <ip> ; banip <ip> ; ban <username> ; send <username> <serverid> ; stop");
|
printMsg("help ; unban <ip> ; banip <ip> ; ban <username> ; kickip <ip> ; kick <username> ; send <username> <serverid> ; stop");
|
||||||
|
break;
|
||||||
|
case "kick":
|
||||||
|
if (pieces.length == 1) {
|
||||||
|
printMsg("Usage: " + pieces[0] + " <username>");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
//there should NEVER be duplicate usernames...
|
||||||
|
Client[] targetClientss = clients.values().stream().filter(client -> client.username.equals(pieces[1])).toArray(Client[]::new);
|
||||||
|
if (targetClientss.length == 0) targetClientss = clients.values().stream().filter(client -> client.username.equalsIgnoreCase(pieces[1])).toArray(Client[]::new);
|
||||||
|
if (targetClientss.length == 0) {
|
||||||
|
printMsg("Unable to find any user with that username!");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
for (Client targetClient : targetClientss) {
|
||||||
|
targetClient.conn.close();
|
||||||
|
printMsg("Successfully kicked user " + targetClient);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case "kickip":
|
||||||
|
case "kick-ip":
|
||||||
|
if (pieces.length == 1) {
|
||||||
|
printMsg("Usage: " + pieces[0] + " <ip>");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
//there should NEVER be duplicate usernames...
|
||||||
|
Client[] targetClientsss = clients.values().stream().filter(client -> getIp(client.conn).equals(pieces[1])).toArray(Client[]::new);
|
||||||
|
if (targetClientsss.length == 0) {
|
||||||
|
printMsg("Unable to find any user with that IP!");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
for (Client targetClient : targetClientsss) {
|
||||||
|
targetClient.conn.close();
|
||||||
|
printMsg("Successfully kicked user " + targetClient);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case "unban":
|
case "unban":
|
||||||
case "pardon":
|
case "pardon":
|
||||||
|
@ -179,103 +211,105 @@ public class Main {
|
||||||
case "pardon-ip":
|
case "pardon-ip":
|
||||||
case "pardonip":
|
case "pardonip":
|
||||||
if (pieces.length == 1) {
|
if (pieces.length == 1) {
|
||||||
System.out.println("Usage: " + pieces[0] + " <ip>");
|
printMsg("Usage: " + pieces[0] + " <ip>");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (bans.remove(pieces[1])) {
|
if (bans.remove(pieces[1])) {
|
||||||
System.out.println("Successfully unbanned IP " + pieces[1]);
|
printMsg("Successfully unbanned IP " + pieces[1]);
|
||||||
saveBans();
|
saveBans();
|
||||||
} else {
|
} else {
|
||||||
System.out.println("IP " + pieces[1] + " is not banned!");
|
printMsg("IP " + pieces[1] + " is not banned!");
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case "ban":
|
case "ban":
|
||||||
if (pieces.length == 1) {
|
if (pieces.length == 1) {
|
||||||
System.out.println("Usage: " + pieces[0] + " <username>");
|
printMsg("Usage: " + pieces[0] + " <username>");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
//there should NEVER be duplicate usernames...
|
//there should NEVER be duplicate usernames...
|
||||||
Client[] targetClients = clients.values().stream().filter(client -> client.username.equals(pieces[1])).toArray(Client[]::new);
|
Client[] targetClients = clients.values().stream().filter(client -> client.username.equals(pieces[1])).toArray(Client[]::new);
|
||||||
if (targetClients.length == 0) targetClients = clients.values().stream().filter(client -> client.username.equalsIgnoreCase(pieces[1])).toArray(Client[]::new);
|
if (targetClients.length == 0) targetClients = clients.values().stream().filter(client -> client.username.equalsIgnoreCase(pieces[1])).toArray(Client[]::new);
|
||||||
if (targetClients.length == 0) {
|
if (targetClients.length == 0) {
|
||||||
System.out.println("Unable to find any user with that username! (note: they must be online)");
|
printMsg("Unable to find any user with that username! (note: they must be online)");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
for (Client targetClient : targetClients) {
|
for (Client targetClient : targetClients) {
|
||||||
WebSocket targetWebSocket = getKeysByValue(clients, targetClient).stream().findFirst().orElse(null);
|
WebSocket targetWebSocket = targetClient.conn;
|
||||||
if (targetWebSocket == null) {
|
|
||||||
System.out.println("An internal error occurred which should never happen! Oops...");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
String ipToBan = getIp(targetWebSocket);
|
String ipToBan = getIp(targetWebSocket);
|
||||||
if (bans.add(ipToBan)) {
|
if (bans.add(ipToBan)) {
|
||||||
System.out.println("Successfully banned user " + targetClient.username + " with IP " + ipToBan);
|
printMsg("Successfully banned user " + targetClient.username + " with IP " + ipToBan);
|
||||||
try {
|
try {
|
||||||
saveBans();
|
saveBans();
|
||||||
} catch (IOException ignored) {}
|
} catch (IOException ignored) {}
|
||||||
} else {
|
} else {
|
||||||
System.out.println("IP " + ipToBan + " is already banned!");
|
printMsg("IP " + ipToBan + " is already banned!");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case "ban-ip":
|
case "ban-ip":
|
||||||
case "banip":
|
case "banip":
|
||||||
if (pieces.length == 1) {
|
if (pieces.length == 1) {
|
||||||
System.out.println("Usage: " + pieces[0] + " <ip>");
|
printMsg("Usage: " + pieces[0] + " <ip>");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (bans.add(pieces[1])) {
|
if (bans.add(pieces[1])) {
|
||||||
System.out.println("Successfully banned IP " + pieces[1]);
|
Client[] targetClientssss = clients.values().stream().filter(client -> getIp(client.conn).equals(pieces[1])).toArray(Client[]::new);
|
||||||
|
for (Client client : targetClientssss) client.conn.close();
|
||||||
|
printMsg("Successfully banned IP " + pieces[1]);
|
||||||
saveBans();
|
saveBans();
|
||||||
} else {
|
} else {
|
||||||
System.out.println("IP " + pieces[1] + " is already banned!");
|
printMsg("IP " + pieces[1] + " is already banned!");
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case "send":
|
case "send":
|
||||||
case "server":
|
case "server":
|
||||||
if (pieces.length == 1 || pieces.length == 2) {
|
if (pieces.length == 1 || pieces.length == 2) {
|
||||||
System.out.println("Usage: " + pieces[0] + " <username> <serverindex>");
|
printMsg("Usage: " + pieces[0] + " <username> <serverindex>");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
Client targetUser = clients.values().stream().filter(client -> client.username.equals(pieces[1])).findFirst().orElse(clients.values().stream().filter(client -> client.username.equalsIgnoreCase(pieces[1])).findFirst().orElse(null));
|
Client targetUser = clients.values().stream().filter(client -> client.username.equals(pieces[1])).findFirst().orElse(clients.values().stream().filter(client -> client.username.equalsIgnoreCase(pieces[1])).findFirst().orElse(null));
|
||||||
if (targetUser == null) {
|
if (targetUser == null) {
|
||||||
System.out.println("Unable to find any user with that username!");
|
printMsg("Unable to find any user with that username!");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
// 99% sure don't need to worry about this
|
||||||
|
/*
|
||||||
|
if (!targetUser.hasLoginHappened) {
|
||||||
|
printMsg("This user is still logging in to a server; please wait until they have logged in to change their server!");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
*/
|
||||||
try {
|
try {
|
||||||
int destServer = Integer.parseInt(pieces[2]);
|
int destServer = Integer.parseInt(pieces[2]);
|
||||||
targetUser.server = Math.max(0, Math.min(servers.size() - 1, destServer));
|
targetUser.server = Math.max(0, Math.min(servers.size() - 1, destServer));
|
||||||
|
targetUser.socket.close();
|
||||||
|
printMsg("Successfully send user " + targetUser + " to server " + destServer + "!");
|
||||||
} catch (NumberFormatException e) {
|
} catch (NumberFormatException e) {
|
||||||
System.out.println("That is not a valid number!");
|
printMsg("That is not a valid number!");
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case "stop":
|
case "stop":
|
||||||
case "end":
|
case "end":
|
||||||
case "exit":
|
case "exit":
|
||||||
case "quit":
|
case "quit":
|
||||||
System.out.println("Stopping!");
|
printMsg("Stopping!");
|
||||||
running = false;
|
running = false;
|
||||||
webSocketServer.stop(10);
|
webSocketServer.stop(10);
|
||||||
System.exit(0);
|
System.exit(0);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
System.out.println("Command not found!");
|
printMsg("Command not found!");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static String getIp(WebSocket conn) {
|
public static void printMsg(String msg) {
|
||||||
return conn.getAttachment();
|
System.out.println(msg);
|
||||||
|
//System.out.print("> "); // todo: copy current input to after the >
|
||||||
}
|
}
|
||||||
|
|
||||||
// https://stackoverflow.com/a/2904266/6917520
|
public static String getIp(WebSocket conn) {
|
||||||
|
return conn.getAttachment();
|
||||||
public static <T, E> Set<T> getKeysByValue(Map<T, E> map, E value) {
|
|
||||||
return map.entrySet()
|
|
||||||
.stream()
|
|
||||||
.filter(entry -> Objects.equals(entry.getValue(), value))
|
|
||||||
.map(Map.Entry::getKey)
|
|
||||||
.collect(Collectors.toSet());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void saveBans() throws IOException {
|
private static void saveBans() throws IOException {
|
||||||
|
|
65
src/main/java/me/ayunami2000/ayungee/PluginMessages.java
Normal file
65
src/main/java/me/ayunami2000/ayungee/PluginMessages.java
Normal file
|
@ -0,0 +1,65 @@
|
||||||
|
package me.ayunami2000.ayungee;
|
||||||
|
|
||||||
|
import java.io.ByteArrayInputStream;
|
||||||
|
import java.io.DataInputStream;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.nio.ByteBuffer;
|
||||||
|
|
||||||
|
public class PluginMessages {
|
||||||
|
// return true to cancel being sent to server/client
|
||||||
|
|
||||||
|
public static boolean fromServer(Client client, String name, byte[] data) {
|
||||||
|
if (name.equals("BungeeCord")) { // eat all bungeecord messages
|
||||||
|
DataInputStream dataIn = new DataInputStream(new ByteArrayInputStream(data));
|
||||||
|
try {
|
||||||
|
String bungeeTag = dataIn.readUTF();
|
||||||
|
if (bungeeTag.equals("Connect")) { // actually send current player to server :D
|
||||||
|
String destServer = dataIn.readUTF();
|
||||||
|
try {
|
||||||
|
int destServerInt = Integer.parseInt(destServer);
|
||||||
|
client.server = Math.max(0, Math.min(Main.servers.size() - 1, destServerInt));
|
||||||
|
} catch (NumberFormatException ignored) {}
|
||||||
|
}
|
||||||
|
} catch (IOException e) {
|
||||||
|
// broken packet
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean fromClient(Client client, String name, byte[] data) {
|
||||||
|
return Skins.setSkin(client.username, client.conn, name, data);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean serverPluginMessage(Client client, byte[] packet) {
|
||||||
|
return firePluginMessage(client, true, packet);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean clientPluginMessage(Client client, byte[] packet) {
|
||||||
|
return firePluginMessage(client, false, packet);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static boolean firePluginMessage(Client client, boolean fromServer, byte[] packet) {
|
||||||
|
if(packet.length >= 3 && packet[0] == (byte) 250) {
|
||||||
|
ByteBuffer bb = ByteBuffer.wrap(packet);
|
||||||
|
bb.get();
|
||||||
|
int tagLen = bb.getShort();
|
||||||
|
if (tagLen < 0 || tagLen * 2 > packet.length - 3) return false;
|
||||||
|
StringBuilder tagBuilder = new StringBuilder();
|
||||||
|
for (int i = 0; i < tagLen; i++) tagBuilder.append(bb.getChar());
|
||||||
|
//int dataLen = bb.getShort();
|
||||||
|
int dataLen = bb.remaining() - 2; // - 2 for the 2 bytes specifying data length
|
||||||
|
String tag = tagBuilder.toString();
|
||||||
|
int offset = 3 + tagLen * 2 + 2; // - 2 for the 2 bytes specifying data length
|
||||||
|
byte[] msg = new byte[dataLen];
|
||||||
|
System.arraycopy(packet, offset, msg, 0, dataLen);
|
||||||
|
if (fromServer) {
|
||||||
|
return fromServer(client, tag, msg);
|
||||||
|
} else {
|
||||||
|
return fromClient(client, tag, msg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
|
@ -4,7 +4,6 @@ import org.java_websocket.WebSocket;
|
||||||
|
|
||||||
import java.io.ByteArrayOutputStream;
|
import java.io.ByteArrayOutputStream;
|
||||||
import java.io.DataOutputStream;
|
import java.io.DataOutputStream;
|
||||||
import java.nio.ByteBuffer;
|
|
||||||
import java.nio.charset.StandardCharsets;
|
import java.nio.charset.StandardCharsets;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
|
|
||||||
|
@ -16,21 +15,9 @@ public class Skins {
|
||||||
private static final int[] SKIN_DATA_SIZE = new int[] { 64*32*4, 64*64*4, -9, -9, 1, 64*64*4, -9 }; // 128 pixel skins crash clients
|
private static final int[] SKIN_DATA_SIZE = new int[] { 64*32*4, 64*64*4, -9, -9, 1, 64*64*4, -9 }; // 128 pixel skins crash clients
|
||||||
private static final int[] CAPE_DATA_SIZE = new int[] { 32*32*4, -9, 1 };
|
private static final int[] CAPE_DATA_SIZE = new int[] { 32*32*4, -9, 1 };
|
||||||
|
|
||||||
public static boolean setSkin(String user, WebSocket conn, byte[] initMsg) {
|
public static boolean setSkin(String user, WebSocket conn, String tag, byte[] msg) {
|
||||||
if(initMsg.length >= 3) {
|
if(msg.length >= 3) {
|
||||||
try {
|
try {
|
||||||
ByteBuffer bb = ByteBuffer.wrap(initMsg);
|
|
||||||
bb.get();
|
|
||||||
int tagLen = bb.getShort();
|
|
||||||
if (!(tagLen >= 0 && tagLen < initMsg.length - 1)) return false;
|
|
||||||
StringBuilder tagBuilder = new StringBuilder();
|
|
||||||
for (int i = 0; i < tagLen; i++) tagBuilder.append(bb.getChar());
|
|
||||||
//int dataLen = bb.getShort();
|
|
||||||
int dataLen = bb.remaining() - 2;
|
|
||||||
String tag = tagBuilder.toString();
|
|
||||||
int offset = 3 + tagLen * 2 + 2;
|
|
||||||
byte[] msg = new byte[dataLen];
|
|
||||||
System.arraycopy(initMsg, offset, msg, 0, dataLen);
|
|
||||||
if("EAG|MySkin".equals(tag)) {
|
if("EAG|MySkin".equals(tag)) {
|
||||||
if(!skinCollection.containsKey(user)) {
|
if(!skinCollection.containsKey(user)) {
|
||||||
int t = (int)msg[0] & 0xFF;
|
int t = (int)msg[0] & 0xFF;
|
||||||
|
|
|
@ -62,7 +62,7 @@ public class WebSocketProxy extends WebSocketServer {
|
||||||
public void onClose(WebSocket conn, int code, String reason, boolean remote) {
|
public void onClose(WebSocket conn, int code, String reason, boolean remote) {
|
||||||
Client selfClient = Main.clients.remove(conn);
|
Client selfClient = Main.clients.remove(conn);
|
||||||
if (selfClient != null) {
|
if (selfClient != null) {
|
||||||
System.out.println("Player " + selfClient.username + " (" + Main.getIp(conn) + ") left!");
|
Main.printMsg("Player " + selfClient + " left!");
|
||||||
Skins.removeSkin(selfClient.username);
|
Skins.removeSkin(selfClient.username);
|
||||||
if (selfClient.socket.isClosed()) {
|
if (selfClient.socket.isClosed()) {
|
||||||
try {
|
try {
|
||||||
|
@ -97,31 +97,33 @@ public class WebSocketProxy extends WebSocketServer {
|
||||||
if (!conn.isOpen()) return;
|
if (!conn.isOpen()) return;
|
||||||
byte[] msg = message.array();
|
byte[] msg = message.array();
|
||||||
if (!Main.clients.containsKey(conn)) {
|
if (!Main.clients.containsKey(conn)) {
|
||||||
if (msg.length > 3 && msg[1] == (byte) 69) {
|
if (msg.length > 3 && msg[0] == 2 && msg[1] == 69) {
|
||||||
// todo: it uses shorts dumbass, get with the system
|
message.get();
|
||||||
short unameLen = (short) ((msg[2] << 8) + msg[3] & 0xff);
|
message.get();
|
||||||
|
short unameLen = message.getShort();
|
||||||
if (unameLen < 3 || unameLen > 16) {
|
if (unameLen < 3 || unameLen > 16) {
|
||||||
conn.close();
|
conn.close();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (msg.length < 5 + msg[3] * 2) {
|
if (msg.length < 5 + unameLen * 2) {
|
||||||
conn.close();
|
conn.close();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
byte[] uname = new byte[unameLen];
|
StringBuilder unameBuilder = new StringBuilder();
|
||||||
for (int i = 0; i < uname.length; i++) uname[i] = msg[5 + i * 2];
|
for (int i = 0; i < unameLen; i++) unameBuilder.append(message.getChar());
|
||||||
String username = new String(uname);
|
String username = unameBuilder.toString();
|
||||||
if (Main.clients.values().stream().anyMatch(client -> client.username.equals(username))) {
|
if (Main.clients.values().stream().anyMatch(client -> client.username.equals(username) || client.conn == conn)) {
|
||||||
conn.close();
|
conn.close();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
Client selfClient = new Client(username);
|
Client selfClient = new Client(conn, username);
|
||||||
Main.clients.put(conn, selfClient);
|
Main.clients.put(conn, selfClient);
|
||||||
new Thread(() -> {
|
new Thread(() -> {
|
||||||
try {
|
try {
|
||||||
while (conn.isOpen()) {
|
while (conn.isOpen()) {
|
||||||
int currServer = selfClient.server;
|
int currServer = selfClient.server;
|
||||||
selfClient.hasLoginHappened = false;
|
selfClient.hasLoginHappened = false;
|
||||||
|
if (!selfClient.firstTime) Main.printMsg("Player " + selfClient + " joined server " + selfClient.server + "!");
|
||||||
ServerItem chosenServer = Main.servers.get(currServer);
|
ServerItem chosenServer = Main.servers.get(currServer);
|
||||||
Socket selfSocket = new Socket(chosenServer.host, chosenServer.port);
|
Socket selfSocket = new Socket(chosenServer.host, chosenServer.port);
|
||||||
selfClient.setSocket(selfSocket);
|
selfClient.setSocket(selfSocket);
|
||||||
|
@ -142,12 +144,16 @@ public class WebSocketProxy extends WebSocketServer {
|
||||||
} else {
|
} else {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (data[0] == 1 && !selfClient.hasLoginHappened) selfClient.hasLoginHappened = true;
|
if (ChatHandler.serverChatMessage(selfClient, data)) continue;
|
||||||
if (selfClient.firstTime && data[0] == 1) selfClient.clientEntityId = selfClient.serverEntityId = EntityMap.readInt(data, 1);
|
if (PluginMessages.serverPluginMessage(selfClient, data)) continue;
|
||||||
if (!selfClient.firstTime && data[0] == 1) {
|
boolean loginPacket = data[0] == 1;
|
||||||
|
if (loginPacket && !selfClient.hasLoginHappened) selfClient.hasLoginHappened = true;
|
||||||
|
if (selfClient.firstTime && loginPacket) selfClient.clientEntityId = selfClient.serverEntityId = EntityMap.readInt(data, 1);
|
||||||
|
if (!selfClient.firstTime && loginPacket) {
|
||||||
selfClient.serverEntityId = EntityMap.readInt(data, 1);
|
selfClient.serverEntityId = EntityMap.readInt(data, 1);
|
||||||
// assume server is giving valid data; we don't have to validate it because it isn't a potentially malicious client
|
// assume server is giving valid data; we don't have to validate it because it isn't a potentially malicious client
|
||||||
byte[] worldByte = new byte[data[6] * 2 + 2];
|
short worldByteLen = (short) ((data[5] << 8) + data[6] & 0xff);
|
||||||
|
byte[] worldByte = new byte[worldByteLen * 2 + 2];
|
||||||
System.arraycopy(data, 5, worldByte, 0, worldByte.length);
|
System.arraycopy(data, 5, worldByte, 0, worldByte.length);
|
||||||
byte gamemode = data[worldByte.length + 5];
|
byte gamemode = data[worldByte.length + 5];
|
||||||
byte dimension = data[worldByte.length + 6];
|
byte dimension = data[worldByte.length + 6];
|
||||||
|
@ -169,6 +175,7 @@ public class WebSocketProxy extends WebSocketServer {
|
||||||
}
|
}
|
||||||
EntityMap.rewrite(data, selfClient.serverEntityId, selfClient.clientEntityId);
|
EntityMap.rewrite(data, selfClient.serverEntityId, selfClient.clientEntityId);
|
||||||
if (conn.isOpen()) conn.send(data);
|
if (conn.isOpen()) conn.send(data);
|
||||||
|
if (loginPacket) sendToServer(new byte[] { (byte) 250, 0, 8, 0, 82, 0, 69, 0, 71, 0, 73, 0, 83, 0, 84, 0, 69, 0, 82, 0, 10, 66, 117, 110, 103, 101, 101, 67, 111, 114, 100 }, selfClient);
|
||||||
}
|
}
|
||||||
if (conn.isOpen() && selfClient.server == currServer) conn.close();
|
if (conn.isOpen() && selfClient.server == currServer) conn.close();
|
||||||
if (!selfSocket.isClosed()) selfSocket.close();
|
if (!selfSocket.isClosed()) selfSocket.close();
|
||||||
|
@ -181,42 +188,15 @@ public class WebSocketProxy extends WebSocketServer {
|
||||||
}).start();
|
}).start();
|
||||||
msg[1] = (byte) 61;
|
msg[1] = (byte) 61;
|
||||||
selfClient.handshake = msg;
|
selfClient.handshake = msg;
|
||||||
System.out.println("Player " + username + " (" + Main.getIp(conn) + ") joined!");
|
Main.printMsg("Player " + selfClient + " joined!");
|
||||||
} else {
|
} else {
|
||||||
conn.close();
|
conn.close();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Client currClient = Main.clients.get(conn);
|
Client currClient = Main.clients.get(conn);
|
||||||
if (msg.length >= 3 && msg[0] == 3) {
|
if (ChatHandler.clientChatMessage(currClient, msg)) return;
|
||||||
int msgLen = (short) ((msg[1] << 8) + msg[2] & 0xff);
|
if (PluginMessages.clientPluginMessage(currClient, msg)) return;
|
||||||
if (msgLen != 0) {
|
|
||||||
if (msg.length >= 3 + msgLen * 2) {
|
|
||||||
byte[] chatBytes = new byte[msgLen];
|
|
||||||
for (int i = 0; i < chatBytes.length; i++) chatBytes[i] = msg[4 + i * 2];
|
|
||||||
String chatMsg = new String(chatBytes);
|
|
||||||
if (chatMsg.toLowerCase().startsWith("/server")) {
|
|
||||||
String msgArgs = chatMsg.substring(7 + (chatMsg.contains(" ") ? 1 : 0));
|
|
||||||
if (msgArgs.isEmpty()) {
|
|
||||||
//usage msg
|
|
||||||
conn.send(new byte[] { 3, 0, 25, 0, (byte) 167, 0, 57, 0, 85, 0, 115, 0, 97, 0, 103, 0, 101, 0, 58, 0, 32, 0, 47, 0, 115, 0, 101, 0, 114, 0, 118, 0, 101, 0, 114, 0, 32, 0, 60, 0, 110, 0, 117, 0, 109, 0, 98, 0, 101, 0, 114, 0, 62 });
|
|
||||||
} else {
|
|
||||||
try {
|
|
||||||
int destServer = Integer.parseInt(msgArgs);
|
|
||||||
currClient.server = Math.max(0, Math.min(Main.servers.size() - 1, destServer));
|
|
||||||
} catch (NumberFormatException e) {
|
|
||||||
//not a number
|
|
||||||
conn.send(new byte[] { 3, 0, 29, 0, (byte) 167, 0, 57, 0, 84, 0, 104, 0, 97, 0, 116, 0, 32, 0, 105, 0, 115, 0, 32, 0, 110, 0, 111, 0, 116, 0, 32, 0, 97, 0, 32, 0, 118, 0, 97, 0, 108, 0, 105, 0, 100, 0, 32, 0, 110, 0, 117, 0, 109, 0, 98, 0, 101, 0, 114, 0, 33 });
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return; // don't send to underlying server
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (msg.length > 0 && msg[0] == (byte) 250) {
|
|
||||||
if (Skins.setSkin(currClient.username, conn, msg)) return;
|
|
||||||
}
|
|
||||||
if (!currClient.firstTime && !currClient.hasLoginHappened && !(msg[0] == 1 || msg[0] == 2)) return;
|
if (!currClient.firstTime && !currClient.hasLoginHappened && !(msg[0] == 1 || msg[0] == 2)) return;
|
||||||
if (currClient.socketOut == null || currClient.socket.isOutputShutdown()) {
|
if (currClient.socketOut == null || currClient.socket.isOutputShutdown()) {
|
||||||
currClient.msgCache.add(msg);
|
currClient.msgCache.add(msg);
|
||||||
|
|
Binary file not shown.
Loading…
Reference in New Issue
Block a user