#include "mcnetwork.h" #include #include #include #include #include #include #include "mctypes.h" void send_handshake(int socket, int protocol, char* address, unsigned short port, int next_state) { void* raw_handshake; size_t handshake_size; handshake hs = { to_varint(protocol), { to_varint(strlen(address)), address }, port, to_varint(next_state) }; handshake_size = serialize_handshake(hs, &raw_handshake); send_packet(socket, 0x0, handshake_size, raw_handshake); free_handshake(hs); } void send_packet(int socket, int packet_id, size_t raw_size, void* raw_data) { void* raw_packet; size_t p_size; packet p = { to_varint(raw_size + size_varint(to_varint(packet_id))), to_varint(packet_id), raw_data }; p_size = serialize_packet(p, &raw_packet); free_packet(p); if (send(socket, raw_packet, p_size, 0) < 0) perror("packet failed"); } void connect_mc_server_ping(int socket, char* address, unsigned short port) { struct addrinfo* mc_info = malloc(sizeof(struct addrinfo)); memset(mc_info, 0, sizeof(struct addrinfo)); struct addrinfo hints; memset(&hints, 0, sizeof(struct addrinfo)); hints.ai_family = AF_INET; hints.ai_socktype = SOCK_STREAM; hints.ai_protocol = IPPROTO_TCP; if (getaddrinfo(address, "80", &hints, &mc_info) != 0) exit(1); struct sockaddr_in mc_sock; mc_sock.sin_family = AF_INET; mc_sock.sin_port = htons(port); memcpy(&mc_sock.sin_addr, mc_info->ai_addr->sa_data + 2, mc_info->ai_addrlen); // stupidity freeaddrinfo(mc_info); if (connect(socket, (struct sockaddr*)&mc_sock, sizeof(mc_sock)) < 0) exit(1); } varint recv_varint(int s) { unsigned long i = 0; varint v = NULL; do { v = reallocarray(v, i, sizeof(u_int8_t)); recv(s, v + i, 1, 0); i++; } while ((v[i - 1] & 0x80) != 0); return v; } packet recv_packet(int socket) { packet p; size_t data_size; p.length = recv_varint(socket); p.id = recv_varint(socket); data_size = from_varint(p.length) - size_varint(p.id); p.data = malloc(data_size); recv(socket, p.data, data_size, MSG_WAITALL); return p; }