Hello MPGH. I'm a hobby programmer and I've been playing with Java, C++ and some other languages for a few years. I have been playing this game for over 7 years and only recently wanted to start playing with the game after looking at NRelay. I decided I wanted to write a relay (proxy server). My language of choice is Java, I was going to go with TypeScript and Node but I don't have much experience with either.
I ran into a problem: no matter what I do, I can't send data between the client and the server. I started by creating a ServerSocket on port 2050 that waits and accepts a socket (new connection from a client), opens a connection to one of the game servers and just starts relaying. What I was doing was just read()-ing bytes and sending them to the opposite (client -> server, server -> client) but it just didn't work. I've looked at other projects but the code is just messy. I would appreciate it if someone could guide me or provide some tips. Thanks
Heres an implementation for a client only listener I made, just copy paste everything one more time and have the buffers for server/client sockets be written to eachother.
Code:
public class ClientListener implements Runnable {
private Socket socket;
private DataInputStream in;
private DataOutputStream out;
private boolean connected;
private static final String RC4_OUTGOING_KEY = "c79332b197f92ba85ed281a023";
private static final String RC4_INCOMING_KEY = "6a39570cc9de4ec71d64821894";
private RC4 inRC4;
private RC4 outRC4;
public ClientListener(Socket socket) {
this.socket = socket;
}
@override
public void run() {
try {
System.out.println(" *** Connection from: " + this.socket.getInetAddress().getHostName() + " ***");
this.in = new DataInputStream(this.socket.getInputStream());
this.out = new DataOutputStream(this.socket.getOutputStream());
this.connected = true;
int bufferSize = -1;
byte bufferId = -1;
long lastData = System.currentTimeMillis();
this.inRC4 = new RC4(RC4_INCOMING_KEY);
this.outRC4 = new RC4(RC4_OUTGOING_KEY);
while (this.connected) {
try {
if (lastData > System.currentTimeMillis() + (1000 * 15)) this.disconnect(); // Exit loop after data timeout
if (this.in.available() >= 5 && bufferSize == -1) {
lastData = System.currentTimeMillis();
bufferSize = this.in.readInt() - 5;
bufferId = this.in.readByte();
} else if (this.in.available() >= bufferSize && bufferSize != -1) {
lastData = System.currentTimeMillis();
PacketType type = PacketType.fromId(bufferId);
byte[] buf = new byte[bufferSize];
this.in.readFully(buf);
bufferSize = -1;
if (type == PacketType.UNKNOWN) continue; // Dont bother if the packet is of an unknown type
buf = this.inRC4.cypher(buf);
ByteArrayInputStream bis = new ByteArrayInputStream(buf);
DataInputStream dis = new DataInputStream(bis);
try {
Packet p = type.create();
p.read(dis);
this.invokeOnPacket(p);
} catch (IOException e) {
e.printStackTrace();
} finally {
bis.close();
dis.close();
}
}
Thread.sleep(100); // Only check socket for connections 10 times / second to prevent cpu hogging
} catch (Exception e) {
e.printStackTrace(); // debug
break;
}
}
} catch (Exception e) {
e.printStackTrace(); // debug
this.disconnect();
}
this.disconnect();
}
private void sendPacket(Packet p) {
if (!this.socket.isConnected()) return;
ByteArrayOutputStream baos = new ByteArrayOutputStream();
DataOutputStream out = new DataOutputStream(baos);
try {
p.write(out);
} catch (IOException e) {
e.printStackTrace();
return;
} finally {
try {
baos.close();
out.close();
} catch (IOException e) {
e.printStackTrace();
}
}
byte[] buf = this.outRC4.cypher(baos.toByteArray());
try {
this.out.writeInt(buf.length + 5);
this.out.writeByte(p.getType().id);
this.out.write(buf);
} catch (IOException e) {
e.printStackTrace();
}
}
private void invokeOnPacket(Packet p) {}
private void disconnect() {
if (!this.connected) return;
try {
System.out.println(" *** Disconnected from: " + this.socket.getInetAddress().getHostName() + " ***");
this.connected = false;
this.socket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
if you need help feel free to add me on discord: Ark Died#7316