diff --git a/src/main.c b/src/main.c index fb49fe4..145e34b 100644 --- a/src/main.c +++ b/src/main.c @@ -6,6 +6,7 @@ #include #include #include +#include const char *LOCALHOST = "127.0.0.1"; @@ -47,7 +48,12 @@ int rcon_connect(int port) { memset(&server_addr, 0, sizeof(server_addr)); server_addr.sin_family = AF_INET; server_addr.sin_port = htons(port); - inet_pton(AF_INET, LOCALHOST, &server_addr.sin_addr); + + if (inet_pton(AF_INET, LOCALHOST, &server_addr.sin_addr) <= 0) { + perror("invalid address"); + close(sockfd); + exit(EXIT_FAILURE); + } if (connect(sockfd, (struct sockaddr *)&server_addr, sizeof(server_addr)) < 0) { perror("connection failed"); @@ -61,24 +67,68 @@ int rcon_connect(int port) { void send_packet(int sockfd, int32_t id, int32_t type, const char *body) { int body_len = strlen(body); - int32_t size = 10 + body_len; // 4 (id) + 4 (type) + body + 2 (null terminators) + int32_t size = 10 + body_len; - send(sockfd, &size, sizeof(int32_t), 0); - send(sockfd, &id, sizeof(int32_t), 0); - send(sockfd, &type, sizeof(int32_t), 0); - send(sockfd, body, body_len + 1, 0); + printf("DEBUG: sending packet - id=%d, type=%d, size=%d, body='%s'\n", + id, type, size, body); + + if (send(sockfd, &size, sizeof(int32_t), 0) < 0) { + perror("send size failed"); + return; + } + if (send(sockfd, &id, sizeof(int32_t), 0) < 0) { + perror("send id failed"); + return; + } + if (send(sockfd, &type, sizeof(int32_t), 0) < 0) { + perror("send type failed"); + return; + } + if (send(sockfd, body, body_len + 1, 0) < 0) { + perror("send body failed"); + return; + } const char null = '\0'; - send(sockfd, &null, 1, 0); + if (send(sockfd, &null, 1, 0) < 0) { + perror("send null failed"); + return; + } + + printf("DEBUG: packet sent successfully\n"); } int recv_packet(int sockfd, rcon_packet_t *packet) { - if (recv(sockfd, &packet->size, sizeof(int32_t), 0) <= 0) { return -1; } - if (recv(sockfd, &packet->id, sizeof(int32_t), 0) <= 0) { return -1; } - if (recv(sockfd, &packet->type, sizeof(int32_t), 0) <= 0) { return -1; } + ssize_t bytes; + + bytes = recv(sockfd, &packet->size, sizeof(int32_t), 0); + if (bytes <= 0) { + if (bytes == 0) { + fprintf(stderr, "connection closed by server (no data received)\n"); + } else { + perror("recv size failed"); + } + return -1; + } + + printf("DEBUG: received size=%d\n", packet->size); + + bytes = recv(sockfd, &packet->id, sizeof(int32_t), 0); + if (bytes <= 0) { + perror("recv id failed"); + return -1; + } + + bytes = recv(sockfd, &packet->type, sizeof(int32_t), 0); + if (bytes <= 0) { + perror("recv type failed"); + return -1; + } int body_size = packet->size - 10; - if (body_size > 0 && body_size < sizeof(packet->body)) { - if (recv(sockfd, packet->body, body_size + 2, 0) <= 0) { + if (body_size > 0 && body_size < (int)sizeof(packet->body)) { + bytes = recv(sockfd, packet->body, body_size + 2, 0); + if (bytes <= 0) { + perror("recv body failed"); return -1; } packet->body[body_size] = '\0'; @@ -86,20 +136,34 @@ int recv_packet(int sockfd, rcon_packet_t *packet) { packet->body[0] = '\0'; } + printf("DEBUG: received packet - id=%d, type=%d, body='%s'\n", + packet->id, packet->type, packet->body); + return 0; } int rcon_authenticate(int sockfd, const char *password) { + printf("authenticating with password: '%s' (length=%zu)\n", + password, strlen(password)); + send_packet(sockfd, 1, SERVERDATA_AUTH, password); - rcon_packet_t response; - if (recv_packet(sockfd, &response) < 0) { - perror("failed to receive auth response\n"); + printf("waiting for auth responses...\n"); + + rcon_packet_t response1; + if (recv_packet(sockfd, &response1) < 0) { + fprintf(stderr, "failed to receive first auth response\n"); return -1; } - if (response.id == -1) { - perror("authentication failed\n"); + rcon_packet_t response2; + if (recv_packet(sockfd, &response2) < 0) { + fprintf(stderr, "failed to receive second auth response\n"); + return -1; + } + + if (response2.id == -1) { + fprintf(stderr, "authentication failed - invalid password\n"); return -1; } @@ -117,11 +181,10 @@ char* rcon_command_multipacket(int sockfd, const char *command) { send_packet(sockfd, cmd_id, SERVERDATA_EXECCOMMAND, command); send_packet(sockfd, dummy_id, SERVERDATA_EXECCOMMAND, ""); - // read packets until we get the dummy response while (1) { rcon_packet_t response; if (recv_packet(sockfd, &response) < 0) { - perror("failed to receive command response\n"); + fprintf(stderr, "failed to receive command response\n"); return NULL; } if (response.id == dummy_id) { @@ -140,11 +203,15 @@ int main(int argc, char **argv) { const char *password = getenv("RCON_PASSWORD"); if (password == NULL) { - perror("error: RCON_PASSWORD environment variable not set.\n"); + fprintf(stderr, "error: RCON_PASSWORD environment variable not set.\n"); exit(EXIT_FAILURE); } + printf("=== RCON Configuration ===\n"); printf("port: %d\n", PORT_NUM); + printf("password: '%s'\n", password); + printf("password length: %zu bytes\n", strlen(password)); + printf("==========================\n\n"); int sockfd = rcon_connect(PORT_NUM); @@ -154,13 +221,14 @@ int main(int argc, char **argv) { } const char *get_player_positions_cmd = "execute as @a run data get entity @s Pos"; + printf("\nexecuting command: %s\n", get_player_positions_cmd); char *response = rcon_command_multipacket(sockfd, get_player_positions_cmd); if (response) { printf("\n=== player positions ===\n"); printf("%s\n", response); } else { - perror("failed to get player positions\n"); + fprintf(stderr, "failed to get player positions\n"); } close(sockfd);