125 lines
3.4 KiB
C
125 lines
3.4 KiB
C
#include "sides.h"
|
|
|
|
#include <stdint.h>
|
|
#include <stdlib.h>
|
|
#include <stdio.h>
|
|
#include <memory.h>
|
|
|
|
#include <unistd.h>
|
|
#include <netdb.h>
|
|
|
|
static const value_string protocolId_version[] = {
|
|
{340, "1.12.2"}
|
|
};
|
|
|
|
int client_packet_handler(HANDLER_ARGS) {
|
|
int ret;
|
|
uint32_t current=0, parsedint;
|
|
|
|
ret=VarIntToUint(buffer + current, &parsedint, (uint8_t)len);
|
|
current+=(uint32_t)ret;
|
|
|
|
if(ctx->clientState == Handshake) {
|
|
if(parsedint == 0) {
|
|
//Protocol version
|
|
ret = VarIntToUint(buffer + current, &parsedint, (uint8_t)(len - current));
|
|
current += (uint32_t)ret;
|
|
ctx->protocol_version = parsedint;
|
|
|
|
//Server address len
|
|
//Should be lower or euqal 255*4=1020
|
|
ret = VarIntToUint(buffer + current, &parsedint, (uint8_t)(len - current));
|
|
current += (uint32_t)ret;
|
|
|
|
ctx->serveraddr = malloc(parsedint+1);//Null termination
|
|
if(ctx->serveraddr == NULL)
|
|
return -1;
|
|
memcpy(ctx->serveraddr, buffer + current, parsedint);
|
|
ctx->serveraddr[parsedint] = 0;
|
|
current += parsedint;
|
|
|
|
ctx->port = (uint16_t)(( *(buffer+current)) << 8) | *(buffer+current+1);
|
|
current += 2;
|
|
if(ctx->port == 25545)
|
|
ctx->port = 25565;
|
|
|
|
ret = VarIntToUint(buffer + current, &parsedint, (uint8_t)(len - current));
|
|
current += (uint32_t)ret;
|
|
if(parsedint == 1)
|
|
ctx->clientState = SLP;
|
|
else if(parsedint == 2)
|
|
ctx->clientState = Login;
|
|
|
|
printf("Connecting to %s:%u\nProtocol version: %u\n", ctx->serveraddr, ctx->port, ctx->protocol_version);
|
|
|
|
int id = -1;
|
|
for(size_t i = 0; i < sizeof(protocolId_version)/sizeof(protocolId_version[0]); i++) {
|
|
if(protocolId_version[i].value == ctx->protocol_version)
|
|
id = (int)i;
|
|
}
|
|
|
|
if(id == -1)
|
|
printf("Unknown game version\n");
|
|
else
|
|
printf("Game version: %s\n", protocolId_version[id].strptr);
|
|
|
|
struct addrinfo *ai;
|
|
ret = getaddrinfo(ctx->serveraddr, NULL, NULL, &ai);
|
|
|
|
if(ret) {
|
|
printf("Client tired to connect unknown to server\n");
|
|
freeaddrinfo(ai);
|
|
if(ctx->clientState == Login) {
|
|
//Send disconnect packet
|
|
static const char *reason = "{\"text\":\"Bad address\"}";
|
|
const size_t buflen = strlen(reason) + 3;
|
|
uint8_t *tmpbuf = alloca(buflen);
|
|
prepare_disconnect_buffer(tmpbuf, reason, (uint8_t)(buflen - 3));
|
|
send(ctx->client_fd, tmpbuf, buflen, MSG_NOSIGNAL);
|
|
}
|
|
return -1;
|
|
}
|
|
|
|
if (ai->ai_family == AF_INET)
|
|
((struct sockaddr_in*)ai->ai_addr)->sin_port=htons(ctx->port);
|
|
else if (ai->ai_family == AF_INET6)
|
|
((struct sockaddr_in6*)ai->ai_addr)->sin6_port=htons(ctx->port);
|
|
|
|
ctx->server_fd = socket(ai->ai_family, SOCK_STREAM, IPPROTO_TCP);
|
|
if(ctx->server_fd == -1) {
|
|
goto failconnect;
|
|
}
|
|
|
|
ret = connect(ctx->server_fd, ai->ai_addr, ai->ai_addrlen);
|
|
if(ret == -1) {
|
|
failconnect:
|
|
close(ctx->server_fd);
|
|
printf("Failed to connect\n");
|
|
freeaddrinfo(ai);
|
|
if(ctx->clientState == Login) {
|
|
//Send disconnect packet
|
|
static const char *reason = "{\"text\":\"Failed to connect\"}";
|
|
const size_t buflen = strlen(reason) + 3;
|
|
uint8_t *tmpbuf = alloca(buflen);
|
|
prepare_disconnect_buffer(tmpbuf, reason, (uint8_t)(buflen - 3));
|
|
send(ctx->client_fd, tmpbuf, buflen, MSG_NOSIGNAL);
|
|
}
|
|
return -1;
|
|
}
|
|
|
|
freeaddrinfo(ai);
|
|
ctx->serverState = ctx->clientState;
|
|
|
|
//Init replay
|
|
if(id != -1)
|
|
replay_init_context(ctx, protocolId_version[id].strptr/*, buffer, len*/);
|
|
|
|
return 1;
|
|
} else {
|
|
printf("Failed to parse handshake\n");
|
|
return -1;
|
|
}
|
|
}
|
|
return 0;
|
|
}
|