Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- package TestProject;
- import java.io.ByteArrayOutputStream;
- import java.io.DataInputStream;
- import java.io.DataOutputStream;
- import java.io.IOException;
- import java.net.InetSocketAddress;
- import java.net.Socket;
- import java.nio.charset.Charset;
- import java.nio.charset.StandardCharsets;
- import java.util.Arrays;
- public class Main {
- public static void main(String[] args) throws IOException, InterruptedException {
- String address = "localhost";
- int port = 25565;
- int version = 578; // 1.15.2's protocol version is 578.
- String username = "username";
- System.out.println("Connecting to Address: " + address + ":" + port + " ...");
- InetSocketAddress host = new InetSocketAddress(address, port);
- Socket socket = new Socket();
- System.out.println("Connecting to Server...");
- while (!socket.isConnected()) {
- socket.connect(host, 4000);
- Thread.sleep(500);
- }
- System.out.println("Making Streams...");
- DataOutputStream output = new DataOutputStream(socket.getOutputStream());
- DataInputStream input = new DataInputStream(socket.getInputStream());
- System.out.println("Attempting Handshake with: " + host.getAddress().toString() + " ...");
- int packetId = getHandshakeAndReturn(version, address, port, 1, output, input);
- if (packetId == -1) {
- throw new IOException("Error: Premature End of Stream.");
- }
- if (packetId != 0x00) { // we want a status response
- throw new IOException("Error: Invalid packetID; expected 0x00 but got " + packetId + " instead.");
- }
- int length = readVarInt(input); // length of json string
- if (length == -1) {
- throw new IOException("Error: Premature End of Stream.");
- }
- if (length == 0) {
- throw new IOException("Error: Invalid String Length.");
- }
- byte[] in = new byte[length];
- input.readFully(in); // read json string
- String json = new String(in);
- // C->S : Ping
- long now = System.currentTimeMillis();
- output.writeByte(0x09); // size of packet
- output.writeByte(0x01); // 0x01 for ping
- output.writeLong(now); // send system time in ms
- // S->C : Pong
- readVarInt(input);
- packetId = readVarInt(input);
- if (packetId == -1) {
- throw new IOException("Error: Premature End of Stream.");
- }
- if (packetId != 0x01) {
- throw new IOException("Error: Invalid packetID; expected 0x01 but got " + packetId + " instead.");
- }
- long pingtime = input.readLong(); // read response
- if (pingtime == now) {
- System.out.println("Successfully Connected to Server...");
- } else {
- throw new IOException("Error: Ping-Pong Mismatch.");
- }
- // print out server info
- System.out.println(json);
- System.out.println("Logging In to: " + address + ":" + port + " ...");
- System.out.println("Logging In... (1/3)"); // C -> S handshake2
- socket.close();
- Socket socket2 = new Socket();
- while (!socket2.isConnected()) {
- socket2.connect(host, 4000);
- Thread.sleep(500);
- }
- DataOutputStream out2 = new DataOutputStream(socket2.getOutputStream());
- DataInputStream in2 = new DataInputStream(socket2.getInputStream());
- int packetId2 = getHandshakeAndReturn(version, address, port, 2, out2, in2);
- byte[] test = new byte[readVarInt(in2)];
- in2.readFully(test);
- System.out.println(new String(test));
- System.out.println("Logging In... (2/3)"); // C -> S login start
- int userLength = username.getBytes(StandardCharsets.UTF_8).length; //get username length
- if (userLength > 16) {
- throw new IOException("Error: Username is Too Long.");
- } else if (userLength < 3) {
- throw new IOException("Error: Username is Too Short.");
- }
- out2.writeByte(userLength + 1);
- out2.writeByte(0x00);
- writeString(out2, username, StandardCharsets.UTF_8);
- System.out.println("Logging In... (3/3)"); // S -> C login success
- Thread.sleep(500);
- int loginSuccessSize = readVarInt(in2);
- int loginSuccessPacketId = readVarInt(in2);
- if (loginSuccessPacketId == -1) {
- throw new IOException("Error: Premature End of Stream; Login Failed.");
- }
- if (loginSuccessPacketId != 0x02) {
- throw new IOException("Error: Invalid packetID; expected 0x02 but got " + packetId + " instead; Login Failed.");
- }
- byte[] loginSuccessIn = new byte[readVarInt(in2)];
- in2.readFully(loginSuccessIn);
- String loginSuccessJson = new String(loginSuccessIn);
- System.out.println("Successfully Logged In to Server:");
- System.out.println(loginSuccessJson);
- }
- public static int getHandshakeAndReturn(int version, String address, int port, int state, DataOutputStream output, DataInputStream input) throws IOException, InterruptedException {
- byte[] handshakeMessage = createHandshakeMessage(version, address, port, state);
- // print handshake message as string
- System.out.println("Sending Handshake: " + Arrays.toString(handshakeMessage) + " ...");
- // C->S : Handshake State=state
- // send packet length and packet
- writeVarInt(output, handshakeMessage.length);
- output.write(handshakeMessage);
- // C->S : Request
- output.writeByte(0x01); // size is only 1
- output.writeByte(0x00); // packet id for ping
- Thread.sleep(500);
- // S->C : Response
- readVarInt(input);
- return readVarInt(input);
- }
- public static byte[] createHandshakeMessage(int version, String host, int port, int state) throws IOException {
- ByteArrayOutputStream buffer = new ByteArrayOutputStream();
- DataOutputStream handshake = new DataOutputStream(buffer);
- handshake.writeByte(0x00); //packet id for handshake
- writeVarInt(handshake, version); //protocol version
- writeString(handshake, host, StandardCharsets.UTF_8);
- handshake.writeShort(port); //port
- writeVarInt(handshake, state); //state (1 for handshake)
- return buffer.toByteArray();
- }
- public static void writeString(DataOutputStream out, String string, Charset charset) throws IOException {
- byte[] bytes = string.getBytes(charset);
- writeVarInt(out, bytes.length);
- out.write(bytes);
- }
- public static void writeVarInt(DataOutputStream out, int paramInt) throws IOException {
- while (true) {
- if ((paramInt & 0xFFFFFF80) == 0) {
- out.writeByte(paramInt);
- return;
- }
- out.writeByte(paramInt & 0x7F | 0x80);
- paramInt >>>= 7;
- }
- }
- public static int readVarInt(DataInputStream in) throws IOException {
- int i = 0;
- int j = 0;
- while (true) {
- int k = in.readByte();
- i |= (k & 0x7F) << j++ * 7;
- if (j > 5) throw new RuntimeException("VarInt is Too Big.");
- if ((k & 0x80) != 128) break;
- }
- return i;
- }
- }
Add Comment
Please, Sign In to add comment