Add MC packets
This commit is contained in:
parent
16403673d3
commit
68a3000498
26
src/main/java/me/braydon/mc/common/EnumUtils.java
Normal file
26
src/main/java/me/braydon/mc/common/EnumUtils.java
Normal file
@ -0,0 +1,26 @@
|
||||
package me.braydon.mc.common;
|
||||
|
||||
import lombok.NonNull;
|
||||
import lombok.experimental.UtilityClass;
|
||||
|
||||
/**
|
||||
* @author Braydon
|
||||
*/
|
||||
@UtilityClass
|
||||
public final class EnumUtils {
|
||||
/**
|
||||
* Get the enum constant of the specified enum type with the specified name.
|
||||
*
|
||||
* @param enumType the enum type
|
||||
* @param name the name of the constant to return
|
||||
* @param <T> the type of the enum
|
||||
* @return the enum constant of the specified enum type with the specified name
|
||||
*/
|
||||
public <T extends Enum<T>> T getEnumConstant(@NonNull Class<T> enumType, @NonNull String name) {
|
||||
try {
|
||||
return Enum.valueOf(enumType, name);
|
||||
} catch (IllegalArgumentException ex) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,65 @@
|
||||
package me.braydon.mc.common.packet;
|
||||
|
||||
import lombok.NonNull;
|
||||
|
||||
import java.io.DataInputStream;
|
||||
import java.io.DataOutputStream;
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
* Represents a packet in
|
||||
* the Minecraft protocol.
|
||||
*
|
||||
* @author Braydon
|
||||
*/
|
||||
public abstract class MinecraftPacket {
|
||||
/**
|
||||
* Process this packet.
|
||||
*
|
||||
* @param inputStream the input stream to read from
|
||||
* @param outputStream the output stream to write to
|
||||
* @throws IOException if an I/O error occurs
|
||||
*/
|
||||
public abstract void process(@NonNull DataInputStream inputStream, @NonNull DataOutputStream outputStream) throws IOException;
|
||||
|
||||
/**
|
||||
* Write a variable integer to the output stream.
|
||||
*
|
||||
* @param outputStream the output stream to write to
|
||||
* @param paramInt the integer to write
|
||||
* @throws IOException if an I/O error occurs
|
||||
*/
|
||||
protected final void writeVarInt(DataOutputStream outputStream, int paramInt) throws IOException {
|
||||
while (true) {
|
||||
if ((paramInt & 0xFFFFFF80) == 0) {
|
||||
outputStream.writeByte(paramInt);
|
||||
return;
|
||||
}
|
||||
outputStream.writeByte(paramInt & 0x7F | 0x80);
|
||||
paramInt >>>= 7;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Read a variable integer from the input stream.
|
||||
*
|
||||
* @param inputStream the input stream to read from
|
||||
* @return the integer that was read
|
||||
* @throws IOException if an I/O error occurs
|
||||
*/
|
||||
protected final int readVarInt(@NonNull DataInputStream inputStream) throws IOException {
|
||||
int i = 0;
|
||||
int j = 0;
|
||||
while (true) {
|
||||
int k = inputStream.readByte();
|
||||
i |= (k & 0x7F) << j++ * 7;
|
||||
if (j > 5) {
|
||||
throw new RuntimeException("VarInt too big");
|
||||
}
|
||||
if ((k & 0x80) != 128) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
return i;
|
||||
}
|
||||
}
|
@ -0,0 +1,64 @@
|
||||
package me.braydon.mc.common.packet.impl;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.NonNull;
|
||||
import lombok.ToString;
|
||||
import me.braydon.mc.common.packet.MinecraftPacket;
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.DataInputStream;
|
||||
import java.io.DataOutputStream;
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
* This packet is sent by the client to the server to set
|
||||
* the hostname, port, and protocol version of the client.
|
||||
*
|
||||
* @author Braydon
|
||||
* @see <a href="https://wiki.vg/Protocol#Handshake">Protocol Docs</a>
|
||||
*/
|
||||
@AllArgsConstructor @ToString
|
||||
public final class PacketHandshakingInSetProtocol extends MinecraftPacket {
|
||||
private static final byte ID = 0x00; // The ID of the packet
|
||||
private static final int STATUS_HANDSHAKE = 1; // The status handshake ID
|
||||
|
||||
/**
|
||||
* The hostname of the server.
|
||||
*/
|
||||
@NonNull private final String hostname;
|
||||
|
||||
/**
|
||||
* The port of the server.
|
||||
*/
|
||||
private final int port;
|
||||
|
||||
/**
|
||||
* The protocol version of the server.
|
||||
*/
|
||||
private final int protocolVersion;
|
||||
|
||||
/**
|
||||
* Process this packet.
|
||||
*
|
||||
* @param inputStream the input stream to read from
|
||||
* @param outputStream the output stream to write to
|
||||
* @throws IOException if an I/O error occurs
|
||||
*/
|
||||
@Override
|
||||
public void process(@NonNull DataInputStream inputStream, @NonNull DataOutputStream outputStream) throws IOException {
|
||||
try (ByteArrayOutputStream handshakeBytes = new ByteArrayOutputStream();
|
||||
DataOutputStream handshake = new DataOutputStream(handshakeBytes)
|
||||
) {
|
||||
handshake.writeByte(ID); // Write the ID of the packet
|
||||
writeVarInt(handshake, protocolVersion); // Write the protocol version
|
||||
writeVarInt(handshake, hostname.length()); // Write the length of the hostname
|
||||
handshake.writeBytes(hostname); // Write the hostname
|
||||
handshake.writeShort(port); // Write the port
|
||||
writeVarInt(handshake, STATUS_HANDSHAKE); // Write the status handshake ID
|
||||
|
||||
// Write the handshake bytes to the output stream
|
||||
writeVarInt(outputStream, handshakeBytes.size());
|
||||
outputStream.write(handshakeBytes.toByteArray());
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,62 @@
|
||||
package me.braydon.mc.common.packet.impl;
|
||||
|
||||
import lombok.Getter;
|
||||
import lombok.NonNull;
|
||||
import me.braydon.mc.common.packet.MinecraftPacket;
|
||||
|
||||
import java.io.DataInputStream;
|
||||
import java.io.DataOutputStream;
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
* This packet is sent by the client to the server to request the
|
||||
* status of the server. The server will respond with a json object
|
||||
* containing the server's status.
|
||||
*
|
||||
* @author Braydon
|
||||
* @see <a href="https://wiki.vg/Protocol#Status_Request">Protocol Docs</a>
|
||||
*/
|
||||
@Getter
|
||||
public final class PacketStatusInStart extends MinecraftPacket {
|
||||
private static final byte ID = 0x00; // The ID of the packet
|
||||
|
||||
/**
|
||||
* The response json from the server, null if none.
|
||||
*/
|
||||
private String response;
|
||||
|
||||
/**
|
||||
* Process this packet.
|
||||
*
|
||||
* @param inputStream the input stream to read from
|
||||
* @param outputStream the output stream to write to
|
||||
* @throws IOException if an I/O error occurs
|
||||
*/
|
||||
@Override
|
||||
public void process(@NonNull DataInputStream inputStream, @NonNull DataOutputStream outputStream) throws IOException {
|
||||
// Send the status request
|
||||
outputStream.writeByte(0x01); // Size of packet
|
||||
outputStream.writeByte(ID);
|
||||
|
||||
// Read the status response
|
||||
readVarInt(inputStream); // Size of the response
|
||||
int id = readVarInt(inputStream);
|
||||
if (id == -1) { // The stream was prematurely ended
|
||||
throw new IOException("Server prematurely ended stream.");
|
||||
} else if (id != ID) { // Invalid packet ID
|
||||
throw new IOException("Server returned invalid packet ID.");
|
||||
}
|
||||
|
||||
int length = readVarInt(inputStream); // Length of the response
|
||||
if (length == -1) { // The stream was prematurely ended
|
||||
throw new IOException("Server prematurely ended stream.");
|
||||
} else if (length == 0) {
|
||||
throw new IOException("Server returned unexpected value.");
|
||||
}
|
||||
|
||||
// Get the json response
|
||||
byte[] data = new byte[length];
|
||||
inputStream.readFully(data);
|
||||
response = new String(data);
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user