geforkt von Mirrors/Velocity
Fix GS4 issues.
Dieser Commit ist enthalten in:
Ursprung
3e0df79c98
Commit
b5fcc1b34a
@ -50,84 +50,84 @@ public class GS4QueryHandler extends SimpleChannelInboundHandler<DatagramPacket>
|
|||||||
ByteBuf queryMessage = msg.content();
|
ByteBuf queryMessage = msg.content();
|
||||||
InetAddress senderAddress = msg.sender().getAddress();
|
InetAddress senderAddress = msg.sender().getAddress();
|
||||||
|
|
||||||
// Verify query packet magic
|
|
||||||
if (queryMessage.readUnsignedByte() != QUERY_MAGIC_FIRST && queryMessage.readUnsignedByte() != QUERY_MAGIC_SECOND) {
|
|
||||||
throw new IllegalStateException("Invalid query packet magic");
|
|
||||||
}
|
|
||||||
|
|
||||||
// Read packet header
|
|
||||||
short type = queryMessage.readUnsignedByte();
|
|
||||||
int sessionId = queryMessage.readInt();
|
|
||||||
|
|
||||||
// Allocate buffer for response
|
// Allocate buffer for response
|
||||||
ByteBuf queryResponse = ctx.alloc().buffer();
|
ByteBuf queryResponse = ctx.alloc().buffer();
|
||||||
DatagramPacket responsePacket = new DatagramPacket(queryResponse, msg.sender());
|
DatagramPacket responsePacket = new DatagramPacket(queryResponse, msg.sender());
|
||||||
|
|
||||||
switch(type) {
|
try {
|
||||||
case QUERY_TYPE_HANDSHAKE: {
|
// Verify query packet magic
|
||||||
// Generate new challenge token and put it into the sessions cache
|
if (queryMessage.readUnsignedByte() != QUERY_MAGIC_FIRST || queryMessage.readUnsignedByte() != QUERY_MAGIC_SECOND) {
|
||||||
int challengeToken = ThreadLocalRandom.current().nextInt();
|
throw new IllegalStateException("Invalid query packet magic");
|
||||||
sessions.put(senderAddress, challengeToken);
|
|
||||||
|
|
||||||
// Respond with challenge token
|
|
||||||
queryResponse.writeByte(QUERY_TYPE_HANDSHAKE);
|
|
||||||
queryResponse.writeInt(sessionId);
|
|
||||||
writeString(queryResponse, Integer.toString(challengeToken));
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
case QUERY_TYPE_STAT: {
|
// Read packet header
|
||||||
// Check if query was done with session previously generated using a handshake packet
|
short type = queryMessage.readUnsignedByte();
|
||||||
int challengeToken = queryMessage.readInt();
|
int sessionId = queryMessage.readInt();
|
||||||
Integer session = sessions.getIfPresent(senderAddress);
|
|
||||||
if (session == null || session != challengeToken) {
|
switch (type) {
|
||||||
throw new IllegalStateException("Invalid challenge token");
|
case QUERY_TYPE_HANDSHAKE: {
|
||||||
|
// Generate new challenge token and put it into the sessions cache
|
||||||
|
int challengeToken = ThreadLocalRandom.current().nextInt();
|
||||||
|
sessions.put(senderAddress, challengeToken);
|
||||||
|
|
||||||
|
// Respond with challenge token
|
||||||
|
queryResponse.writeByte(QUERY_TYPE_HANDSHAKE);
|
||||||
|
queryResponse.writeInt(sessionId);
|
||||||
|
writeString(queryResponse, Integer.toString(challengeToken));
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check which query response client expects
|
case QUERY_TYPE_STAT: {
|
||||||
if (queryMessage.readableBytes() != 0 && queryMessage.readableBytes() != 4) {
|
// Check if query was done with session previously generated using a handshake packet
|
||||||
throw new IllegalStateException("Invalid query packet");
|
int challengeToken = queryMessage.readInt();
|
||||||
|
Integer session = sessions.getIfPresent(senderAddress);
|
||||||
|
if (session == null || session != challengeToken) {
|
||||||
|
throw new IllegalStateException("Invalid challenge token");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check which query response client expects
|
||||||
|
if (queryMessage.readableBytes() != 0 && queryMessage.readableBytes() != 4) {
|
||||||
|
throw new IllegalStateException("Invalid query packet");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Packet header
|
||||||
|
queryResponse.writeByte(QUERY_TYPE_STAT);
|
||||||
|
queryResponse.writeInt(sessionId);
|
||||||
|
|
||||||
|
// Fetch information
|
||||||
|
VelocityServer server = VelocityServer.getServer();
|
||||||
|
Collection<Player> players = server.getAllPlayers();
|
||||||
|
|
||||||
|
// Start writing the response
|
||||||
|
ResponseWriter responseWriter = new ResponseWriter(queryResponse, queryMessage.readableBytes() == 0);
|
||||||
|
responseWriter.write("hostname", server.getConfiguration().getMotd());
|
||||||
|
responseWriter.write("gametype", "SMP");
|
||||||
|
|
||||||
|
responseWriter.write("game_id", "MINECRAFT");
|
||||||
|
responseWriter.write("version", ProtocolConstants.SUPPORTED_GENERIC_VERSION_STRING);
|
||||||
|
responseWriter.write("plugins", "");
|
||||||
|
|
||||||
|
responseWriter.write("map", "Velocity");
|
||||||
|
responseWriter.write("numplayers", players.size());
|
||||||
|
responseWriter.write("maxplayers", server.getConfiguration().getShowMaxPlayers());
|
||||||
|
responseWriter.write("hostport", server.getConfiguration().getBind().getPort());
|
||||||
|
responseWriter.write("hostip", server.getConfiguration().getBind().getHostString());
|
||||||
|
|
||||||
|
responseWriter.writePlayers(players);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Packet header
|
default: {
|
||||||
queryResponse.writeByte(QUERY_TYPE_STAT);
|
throw new IllegalStateException("Invalid query type: " + type);
|
||||||
queryResponse.writeInt(sessionId);
|
}
|
||||||
|
|
||||||
// Fetch information
|
|
||||||
VelocityServer server = VelocityServer.getServer();
|
|
||||||
Collection<Player> players = server.getAllPlayers();
|
|
||||||
|
|
||||||
// Start writing the response
|
|
||||||
ResponseWriter responseWriter = new ResponseWriter(queryResponse, queryMessage.readableBytes() == 0);
|
|
||||||
responseWriter.write("hostname", server.getConfiguration().getMotd());
|
|
||||||
responseWriter.write("gametype", "SMP");
|
|
||||||
|
|
||||||
responseWriter.write("game_id", "MINECRAFT");
|
|
||||||
responseWriter.write("version", ProtocolConstants.SUPPORTED_GENERIC_VERSION_STRING);
|
|
||||||
responseWriter.write("plugins", "");
|
|
||||||
|
|
||||||
responseWriter.write("map", "Velocity");
|
|
||||||
responseWriter.write("numplayers", players.size());
|
|
||||||
responseWriter.write("maxplayers", server.getConfiguration().getShowMaxPlayers());
|
|
||||||
responseWriter.write("hostport", server.getConfiguration().getBind().getPort());
|
|
||||||
responseWriter.write("hostip", server.getConfiguration().getBind().getHostString());
|
|
||||||
|
|
||||||
responseWriter.writePlayers(players);
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
default: {
|
// Send the response
|
||||||
throw new IllegalStateException("Invalid query type: " + type);
|
ctx.writeAndFlush(responsePacket);
|
||||||
}
|
} catch (Exception e) {
|
||||||
|
logger.warn("Error while trying to handle a query packet from {}", msg.sender(), e);
|
||||||
|
responsePacket.release();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Send the response
|
|
||||||
ctx.writeAndFlush(responsePacket);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
|
|
||||||
logger.warn("Error while trying to handle a query packet from {}", ctx.channel().remoteAddress(), cause);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void writeString(ByteBuf buf, String string) {
|
private static void writeString(ByteBuf buf, String string) {
|
||||||
|
Laden…
In neuem Issue referenzieren
Einen Benutzer sperren