diff --git a/PlayerTracker b/PlayerTracker index 6b30aed..6fe5eb1 100755 Binary files a/PlayerTracker and b/PlayerTracker differ diff --git a/include/mapper.hpp b/include/mapper.hpp new file mode 100644 index 0000000..fac161e --- /dev/null +++ b/include/mapper.hpp @@ -0,0 +1,45 @@ +#ifndef MAPPER_HPP +#define MAPPER_HPP + +#include +#include + +#include "parcer.h" +#include "server_structs.h" + +// INFO: This is basically a identity mapper between raw byte buffer and structs defined in server_structs.h +class Mapper { + private: + const uint_least8_t *buffer; + size_t buffer_size; + size_t offset; + bool ok; + + public: + Mapper(const uint_least8_t *buf, size_t buf_size); + + uint8_t get_message_type(); + bool is_ok() const { return ok; } + + void parse_new_session(trackAtributes &track); + void parse_new_connection(carAtributes &car); + void parse_connection_closed(carAtributes &car); + void parse_car_update(carAtributes &car); + void parse_car_info(carAtributes &car); + void parse_lap_completed(uint8_t &car_id, uint32_t &lap_time, uint32_t &cuts); + void parse_collision_event(uint8_t &car1, uint8_t &car2, uint8_t &event_type); + void parse_chat(uint8_t &car_id, char *message, size_t max_len); + void parse_client_loaded(uint8_t &car_id); + + void set_size(size_t size) { this->buffer_size = size; } + void update_buffer(const uint8_t *buf, size_t size) { + this->buffer = buf; + this->buffer_size = size; + reset(); + } + private: + // INFO: Reset the offset to 1 because the first byte is message type + void reset() { offset = 1; ok = true; } +}; + +#endif // MAPPER_HPP diff --git a/include/parcer.h b/include/parcer.h index 55565da..d2e24cf 100644 --- a/include/parcer.h +++ b/include/parcer.h @@ -27,6 +27,10 @@ u_int8_t read_uint8(const u_int8_t *buf, size_t recv_len, size_t *offset, int *o // Advances the offset by 2 bytes. u_int16_t read_uint16(const u_int8_t *buf, size_t recv_len, size_t *offset, int *ok); +// Reads a 16-bit unsigned integer from the buffer in little-endian byte order. +// Advances the offset by 2 bytes. +u_int16_t read_uint16_le(const u_int8_t *buf, size_t recv_len, size_t *offset, int *ok); + // Reads a 32-bit unsigned integer from the buffer in network byte order. // Advances the offset by 4 bytes. u_int32_t read_uint32(const u_int8_t *buf, size_t recv_len, size_t *offset, int *ok); diff --git a/source/main.cpp b/source/main.cpp index 7a3d4cd..584ef1c 100644 --- a/source/main.cpp +++ b/source/main.cpp @@ -14,6 +14,7 @@ #include "net.hpp" // for socket operations #include "server_structs.h" // for api_packet and ACSP_MessageType #include "session.hpp" // for SessionManager +#include "mapper.hpp" // for Mapper const u_int8_t UPDATE_INTERVAL = 120; // in milliseconds @@ -33,9 +34,18 @@ int main(int argc, char *argv[]) { Socket sock; - SessionManager session_manager(app.app_id); // Server ID 1 for now + SessionManager session_manager(app.app_id); - char buffer[2048]; + uint8_t buffer[1028]; + Mapper map(buffer, 1028); + + trackAtributes track; + + track.server_name = new char[256]; + track.track = new char[64]; + track.track_config = new char[64]; + track.session_name = new char[64]; + track.weather_graphics = new char[64]; try { // Connect socket to API @@ -60,11 +70,11 @@ int main(int argc, char *argv[]) { sock.send_server(request, sizeof(request)); log_debug("Info:\n"); - log_debug("\tApp ID: %d\n", app.app_id); - log_debug("\tAPI Socket Path: %s\n", app.app_api_socket_path.c_str()); - log_debug("\tServer Out IP: %s\n", app.app_server_out_ip.c_str()); - log_debug("\tApp Port In: %d\n", app.app_port_in); - log_debug("\tApp Port Out: %d\n", app.app_port_out); + log_debug("\t\tApp ID: %d\n", app.app_id); + log_debug("\t\tAPI Socket Path: %s\n", app.app_api_socket_path.c_str()); + log_debug("\t\tServer Out IP: %s\n", app.app_server_out_ip.c_str()); + log_debug("\t\tApp Port In: %d\n", app.app_port_in); + log_debug("\t\tApp Port Out: %d\n", app.app_port_out); } catch (const runtime_error &e) { cerr << "Error: " << e.what() << endl; @@ -78,10 +88,13 @@ int main(int argc, char *argv[]) { while (STOP_PROGRAM == false) { // Receive data from server ssize_t received = sock.receive_server(buffer, sizeof(buffer)); + + if (received > 0) { - switch (buffer[0]) { + map.update_buffer(buffer, static_cast(received)); + switch (map.get_message_type()) { // DONE: - case ACSP_VERSION: { + case ACSP_VERSION: { log_warn("Received Version Again? (Probably server restart) Resending Update Request @ %ums\n", UPDATE_INTERVAL); char request[516] = {0}; @@ -101,7 +114,28 @@ int main(int argc, char *argv[]) { // TODO: case ACSP_NEW_SESSION: { log_info("New session started.\n"); - break; + map.parse_new_session(track); + if (map.is_ok()) { + session_manager.on_new_session(track); + } else { + log_error("Failed to parse new session data.\n"); + } + + // TESTING: Print track info + log_info("Track Info:\n"); + log_info("\t\tServer Name: %s\n", track.server_name); + log_info("\t\tTrack: %s\n", track.track); + log_info("\t\tTrack Config: %s\n", track.track_config); + log_info("\t\tSession Name: %s\n", track.session_name); + log_info("\t\tWeather Graphics: %s\n", track.weather_graphics); + log_info("\t\tSession Type: %d\n", track.session_type); + log_info("\t\tLaps: %d\n", track.laps); + log_info("\t\tTime: %d\n", track.time); + log_info("\t\tAmbient Temp: %d\n", track.ambient_temp); + log_info("\t\tRoad Temp: %d\n", track.road_temp); + log_info("\t\tElapsed MS: %u\n", track.elapsed_ms); + + break; } default: { @@ -111,5 +145,10 @@ int main(int argc, char *argv[]) { } } + delete[] track.server_name; + delete[] track.track; + delete[] track.track_config; + delete[] track.session_name; + delete[] track.weather_graphics; return 0; } diff --git a/source/mapper.cpp b/source/mapper.cpp new file mode 100644 index 0000000..5b67fa3 --- /dev/null +++ b/source/mapper.cpp @@ -0,0 +1,56 @@ +#include "mapper.hpp" +#include "parcer.h" + +Mapper::Mapper(const uint8_t *buf, size_t size) : buffer(buf), buffer_size(size), offset(0), ok(1) {} + +uint8_t Mapper::get_message_type() { + if (buffer_size < 1) { + this->ok = false; + return 0; + } + + return buffer[0]; +} + +void Mapper::parse_new_session(trackAtributes &track) { + reset(); + int __ok; + + track.protocol_version = read_uint8(buffer, buffer_size, &offset, &__ok); + track.session_index = read_uint8(buffer, buffer_size, &offset, &__ok); + track.current_session_index = read_uint8(buffer, buffer_size, &offset, &__ok); + track.session_count = read_uint8(buffer, buffer_size, &offset, &__ok); + + track.session_type = (SessionType)track.session_index; + + uint8_t str_len = read_uint8(buffer, buffer_size, &offset, &__ok); + read_utf32le_string(buffer, buffer_size, &offset, track.server_name, str_len, &__ok); + + str_len = read_uint8(buffer, buffer_size, &offset, &__ok); + read_string(buffer, buffer_size, &offset, track.track, str_len, &__ok); + + str_len = read_uint8(buffer, buffer_size, &offset, &__ok); + read_string(buffer, buffer_size, &offset, track.track_config, str_len, &__ok); + + str_len = read_uint8(buffer, buffer_size, &offset, &__ok); + read_string(buffer, buffer_size, &offset, track.session_name, str_len, &__ok); + + track.typ = read_uint8(buffer, buffer_size, &offset, &__ok); + track.time = read_uint16_le(buffer, buffer_size, &offset, &__ok); + track.laps = read_uint16_le(buffer, buffer_size, &offset, &__ok); + track.wait_time = read_uint16_le(buffer, buffer_size, &offset, &__ok); + track.ambient_temp = read_uint8(buffer, buffer_size, &offset, &__ok); + track.road_temp = read_uint8(buffer, buffer_size, &offset, &__ok); + + str_len = read_uint8(buffer, buffer_size, &offset, &__ok); + read_string(buffer, buffer_size, &offset, track.weather_graphics, str_len, &__ok); + + track.elapsed_ms = read_uint32(buffer, buffer_size, &offset, &__ok); + + if (__ok == 0) { + this->ok = false; + } else { + this->ok = true; + } +} + diff --git a/source/parcer.c b/source/parcer.c index 0c877fd..ff5c4f1 100644 --- a/source/parcer.c +++ b/source/parcer.c @@ -1,8 +1,8 @@ #include "parcer.h" #include "server_structs.h" +#include #include #include -#include int ensure(size_t recv_len, size_t offset, size_t need) { return (offset + need <= recv_len); @@ -27,9 +27,22 @@ u_int16_t read_uint16(const u_int8_t *buf, size_t recv_len, size_t *offset, int u_int16_t v; memcpy(&v, buf + *offset, sizeof(v)); *offset += sizeof(v); + return (u_int16_t)ntohs(v); } +u_int16_t read_uint16_le(const u_int8_t *buf, size_t recv_len, size_t *offset, int *ok) { + if (!ensure(recv_len, *offset, sizeof(uint16_t))) { + *ok = 0; + return 0; + } + u_int16_t v; + memcpy(&v, buf + *offset, sizeof(v)); + *offset += sizeof(v); + + return v; +} + u_int32_t read_uint32(const u_int8_t *buf, size_t recv_len, size_t *offset, int *ok) { if (!ensure(recv_len, *offset, sizeof(uint32_t))) { *ok = 0; @@ -140,4 +153,3 @@ void read_string(const u_int8_t *buf, size_t recv_len, size_t *offset, char *out *offset += len; *ok = 1; } -