diff --git a/PlayerTracker b/PlayerTracker index 6caf362..606f8a2 100755 Binary files a/PlayerTracker and b/PlayerTracker differ diff --git a/include/server_structs.h b/include/server_structs.h index ef7c1f0..968da3f 100644 --- a/include/server_structs.h +++ b/include/server_structs.h @@ -186,6 +186,7 @@ typedef struct trackAtributesAPI { typedef struct api_packet { u_int8_t tracker_id; u_int8_t last_updated_carid; + u_int8_t connected_cars; carAtributesAPI cars[64]; trackAtributesAPI track_info; diff --git a/source/main.cpp b/source/main.cpp index 9549755..5d92f9a 100644 --- a/source/main.cpp +++ b/source/main.cpp @@ -28,125 +28,140 @@ const int MAX_PLAYERS = 64; const int SERVER_ID = 130; api_packet current_packet; +int apiSent = 0; // INFO: This assumes Players pointer to be the same size of MAX_PLAYERS void update_api_packet(trackAtributes trackInfo, carAtributes *players, u_int8_t last_updated_carid) { - current_packet.tracker_id = SERVER_ID; + current_packet.tracker_id = SERVER_ID; - // Update track info - current_packet.track_info.protocol_version = trackInfo.protocol_version; - current_packet.track_info.session_index = trackInfo.session_index; - current_packet.track_info.current_session_index = trackInfo.current_session_index; - current_packet.track_info.session_count = trackInfo.session_count; - current_packet.track_info.session_type = trackInfo.session_type; - strncpy(current_packet.track_info.server_name, trackInfo.server_name, sizeof(current_packet.track_info.server_name) - 1); - strncpy(current_packet.track_info.track, trackInfo.track, sizeof(current_packet.track_info.track) - 1); - strncpy(current_packet.track_info.track_config, trackInfo.track_config, sizeof(current_packet.track_info.track_config) - 1); - strncpy(current_packet.track_info.session_name, trackInfo.session_name, sizeof(current_packet.track_info.session_name) - 1); - current_packet.track_info.typ = trackInfo.typ; - current_packet.track_info.time = trackInfo.time; - current_packet.track_info.laps = trackInfo.laps; - current_packet.track_info.wait_time = trackInfo.wait_time; - current_packet.track_info.ambient_temp = trackInfo.ambient_temp; - current_packet.track_info.road_temp = trackInfo.road_temp; - strncpy(current_packet.track_info.weather_graphics, trackInfo.weather_graphics, sizeof(current_packet.track_info.weather_graphics) - 1); - current_packet.track_info.elapsed_ms = trackInfo.elapsed_ms; + // Update track info + current_packet.track_info.protocol_version = trackInfo.protocol_version; + current_packet.track_info.session_index = trackInfo.session_index; + current_packet.track_info.current_session_index = trackInfo.current_session_index; + current_packet.track_info.session_count = trackInfo.session_count; + current_packet.track_info.session_type = trackInfo.session_type; + strncpy(current_packet.track_info.server_name, trackInfo.server_name, sizeof(current_packet.track_info.server_name) - 1); + strncpy(current_packet.track_info.track, trackInfo.track, sizeof(current_packet.track_info.track) - 1); + strncpy(current_packet.track_info.track_config, trackInfo.track_config, sizeof(current_packet.track_info.track_config) - 1); + strncpy(current_packet.track_info.session_name, trackInfo.session_name, sizeof(current_packet.track_info.session_name) - 1); + current_packet.track_info.typ = trackInfo.typ; + current_packet.track_info.time = trackInfo.time; + current_packet.track_info.laps = trackInfo.laps; + current_packet.track_info.wait_time = trackInfo.wait_time; + current_packet.track_info.ambient_temp = trackInfo.ambient_temp; + current_packet.track_info.road_temp = trackInfo.road_temp; + strncpy(current_packet.track_info.weather_graphics, trackInfo.weather_graphics, sizeof(current_packet.track_info.weather_graphics) - 1); + current_packet.track_info.elapsed_ms = trackInfo.elapsed_ms; - // Update car INFO - for (int i = 0; i < MAX_PLAYERS; i++) { - current_packet.cars[i].isConnected = players[i].isConnected; - current_packet.cars[i].isLoading = players[i].isLoading; + // Update car INFO + for (int i = 0; i < MAX_PLAYERS; i++) { + current_packet.cars[i].isConnected = players[i].isConnected; + current_packet.cars[i].isLoading = players[i].isLoading; - strncpy(current_packet.cars[i].car_model, players[i].car_model, sizeof(current_packet.cars[i].car_model) - 1); - strncpy(current_packet.cars[i].driver_GUID, players[i].driver_GUID, sizeof(current_packet.cars[i].driver_GUID) - 1); - strncpy(current_packet.cars[i].car_skin, players[i].car_skin, sizeof(current_packet.cars[i].car_skin) - 1); - strncpy(current_packet.cars[i].driver_name, players[i].driver_name, sizeof(current_packet.cars[i].driver_name) - 1); - strncpy(current_packet.cars[i].driver_team, players[i].driver_team, sizeof(current_packet.cars[i].driver_team) - 1); + strncpy(current_packet.cars[i].car_model, players[i].car_model, sizeof(current_packet.cars[i].car_model) - 1); + strncpy(current_packet.cars[i].driver_GUID, players[i].driver_GUID, sizeof(current_packet.cars[i].driver_GUID) - 1); + strncpy(current_packet.cars[i].car_skin, players[i].car_skin, sizeof(current_packet.cars[i].car_skin) - 1); + strncpy(current_packet.cars[i].driver_name, players[i].driver_name, sizeof(current_packet.cars[i].driver_name) - 1); + strncpy(current_packet.cars[i].driver_team, players[i].driver_team, sizeof(current_packet.cars[i].driver_team) - 1); - current_packet.cars[i].carID = players[i].carID; + current_packet.cars[i].carID = players[i].carID; - current_packet.cars[i].position = players[i].position; - current_packet.cars[i].velocity = players[i].velocity; + current_packet.cars[i].position = players[i].position; + current_packet.cars[i].velocity = players[i].velocity; - current_packet.cars[i].carGear = players[i].carGear; - current_packet.cars[i].carRPM = players[i].carRPM; - current_packet.cars[i].lap_time = players[i].lap_time; - current_packet.cars[i].cuts = players[i].cuts; - current_packet.cars[i].total_cuts = players[i].total_cuts; - current_packet.cars[i].total_cuts_alltime = players[i].total_cuts_alltime; + current_packet.cars[i].carGear = players[i].carGear; + current_packet.cars[i].carRPM = players[i].carRPM; + current_packet.cars[i].lap_time = players[i].lap_time; + current_packet.cars[i].cuts = players[i].cuts; + current_packet.cars[i].total_cuts = players[i].total_cuts; + current_packet.cars[i].total_cuts_alltime = players[i].total_cuts_alltime; - current_packet.cars[i].total_laps_completed = players[i].total_laps_completed; - current_packet.cars[i].contacts = players[i].contacts; - current_packet.cars[i].total_contacts = players[i].total_contacts; + current_packet.cars[i].total_laps_completed = players[i].total_laps_completed; + current_packet.cars[i].contacts = players[i].contacts; + current_packet.cars[i].total_contacts = players[i].total_contacts; - current_packet.cars[i].normalizedSplinePos = players[i].normalizedSplinePos; - } + current_packet.cars[i].normalizedSplinePos = players[i].normalizedSplinePos; + } - if (last_updated_carid == NULL) { - current_packet.last_updated_carid = 0xFF; // No specific car updated - } else { - current_packet.last_updated_carid = last_updated_carid; - } + if (last_updated_carid == NULL) { + current_packet.last_updated_carid = 0xFF; // No specific car updated + } else { + current_packet.last_updated_carid = last_updated_carid; + } + apiSent = 0; } void *send_to_api_socket(void *arg) { - int sock_fd; - struct sockaddr_un addr; + int sock_fd; + struct sockaddr_un addr; - addr.sun_family = AF_UNIX; - strcpy(addr.sun_path, API_SOCKET_PATH); + addr.sun_family = AF_UNIX; + strcpy(addr.sun_path, API_SOCKET_PATH); - // --- Connect loop --- - while (1) { - sock_fd = socket(AF_UNIX, SOCK_STREAM, 0); - if (sock_fd < 0) { - usleep(500000); - continue; - } + // --- Connect loop --- + while (1) { + sock_fd = socket(AF_UNIX, SOCK_STREAM, 0); + if (sock_fd < 0) { + usleep(500000); + continue; + } - if (connect(sock_fd, (struct sockaddr *)&addr, sizeof(addr)) < 0) { - close(sock_fd); - usleep(500000); - continue; - } - break; // connected - } + if (connect(sock_fd, (struct sockaddr *)&addr, sizeof(addr)) < 0) { + close(sock_fd); + usleep(500000); + continue; + } + break; // connected + } - printf("[+] Connected to API socket at %s\n", API_SOCKET_PATH); + printf("[+] Connected to API socket at %s\n", API_SOCKET_PATH); - while (1) { - if (current_packet.tracker_id == (u_int8_t)-1) { + // Handshake + const char *handshake_msg = "ACSP_API_CLIENT"; + send(sock_fd, handshake_msg, strlen(handshake_msg), MSG_NOSIGNAL); + + while (1) { + if (current_packet.tracker_id == (u_int8_t)-1) { + usleep(10000); + apiSent = 0; + continue; + } + + if (apiSent) { usleep(10000); continue; } - ssize_t sent_bytes = send(sock_fd, ¤t_packet, sizeof(api_packet), 0); - if (sent_bytes < 0) { - fprintf(stderr, "[!] Failed to send data to API socket, reconnecting...\n"); - close(sock_fd); - // Reconnect loop - while (1) { - sock_fd = socket(AF_UNIX, SOCK_STREAM, 0); - if (sock_fd < 0) { - usleep(500000); - continue; - } + ssize_t sent_bytes = send(sock_fd, ¤t_packet, sizeof(api_packet), MSG_NOSIGNAL); + if (sent_bytes < 0) { + fprintf(stderr, "[!] Failed to send data to API socket, reconnecting...\n"); + close(sock_fd); - if (connect(sock_fd, (struct sockaddr *)&addr, sizeof(addr)) < 0) { - close(sock_fd); - usleep(500000); - continue; - } - break; // connected - } + // Reconnect loop + while (1) { + sock_fd = socket(AF_UNIX, SOCK_STREAM, 0); + if (sock_fd < 0) { + usleep(500000); + continue; + } - printf("[+] Reconnected to API socket at %s\n", API_SOCKET_PATH); - } + if (connect(sock_fd, (struct sockaddr *)&addr, sizeof(addr)) < 0) { + close(sock_fd); + usleep(500000); + continue; + } + break; // connected + } - usleep(10000); // 10ms - } + printf("[+] Reconnected to API socket at %s\n", API_SOCKET_PATH); + } - return NULL; + apiSent = 1; + + usleep(10000); // 10ms + } + + return NULL; } void init_carupdate(carAtributes *car) { @@ -314,7 +329,7 @@ int main(void) { printf("\tWeather Graphics: %s\n", trackInfo.weather_graphics); printf("\tElapsed Time: %d ms (%2d:%2d:%2d)\n\n", trackInfo.elapsed_ms, trackInfo.elapsed_ms / 60000, (trackInfo.elapsed_ms % 60000) / 1000, (trackInfo.elapsed_ms % 60000) % 1000); - + update_api_packet(trackInfo, players, update.carID); break; case ACSP_NEW_CONNECTION: // DONE: @@ -341,7 +356,8 @@ int main(void) { } update.isConnected = 1; // Mark as connected - update.isLoading = 1; // Mark as loading + update.isLoading = 1; // Mark as Loading + current_packet.connected_cars++; printf("\tDriver Name: \"%s\"\n", update.driver_name); printf("\tDriver GUID: \"%s\"\n", update.driver_GUID); @@ -353,7 +369,7 @@ int main(void) { if (update.carID < MAX_PLAYERS) { memcpy(&players[update.carID], &update, sizeof(carAtributes)); } - + update_api_packet(trackInfo, players, update.carID); break; case ACSP_CONNECTION_CLOSED: // DONE: @@ -379,7 +395,9 @@ int main(void) { break; } + update.isConnected = 0; // Mark as disconnected + current_packet.connected_cars--; printf("\tDriver Name: \"%s\"\n", update.driver_name); printf("\tDriver GUID: \"%s\"\n", update.driver_GUID); @@ -391,7 +409,7 @@ int main(void) { if (update.carID < MAX_PLAYERS) { memcpy(&players[update.carID], &update, sizeof(carAtributes)); } - + update_api_packet(trackInfo, players, update.carID); break; case ACSP_CAR_UPDATE: // DONE: @@ -425,8 +443,11 @@ int main(void) { players[update.carID].carGear = update.carGear; players[update.carID].carRPM = update.carRPM; players[update.carID].normalizedSplinePos = update.normalizedSplinePos; + players[update.carID].carID = update.carID; + players[update.carID].isConnected = 1; // Ensure isConnected is set } + update_api_packet(trackInfo, players, update.carID); break; case ACSP_CAR_INFO: // DONE: @@ -464,6 +485,7 @@ int main(void) { memcpy(&players[update.carID], &update, sizeof(carAtributes)); } + update_api_packet(trackInfo, players, update.carID); break; case ACSP_END_SESSION: // DONE: (only session type cycling) @@ -483,6 +505,7 @@ int main(void) { printf("\tNext Session Name: %s\n", trackInfo.session_name); printf("\tNext Session Type: %d\n\n", trackInfo.session_type); + update_api_packet(trackInfo, players, update.carID); break; case ACSP_VERSION: // DONE: @@ -492,6 +515,7 @@ int main(void) { printf("\tProtocol Version: %d\n\n", trackInfo.protocol_version); + update_api_packet(trackInfo, players, update.carID); break; case ACSP_CHAT: // DONE: Receive chat messages @@ -505,7 +529,7 @@ int main(void) { printf("\tCar ID: %d (%s)\n", update.carID, players[update.carID].driver_name); printf("\tMessage: \"%s\"\n\n", message); - + update_api_packet(trackInfo, players, update.carID); break; case ACSP_CLIENT_LOADED: // DONE: Check for client loaded status @@ -516,7 +540,7 @@ int main(void) { players[update.carID].isLoading = 0; printf("\tCar ID: %d (%s) Finished Loading into the session\n\n", update.carID, players[update.carID].driver_name); - + update_api_packet(trackInfo, players, update.carID); break; case ACSP_ERROR: // DONE: Simple error message from server @@ -546,7 +570,7 @@ int main(void) { printf("\tLap Time: %5d ms\n", update.lap_time); printf("\tCuts this lap: %d\n", update.cuts); printf("\tTotal Cuts (this session): %d\n\n", update.total_cuts); - + update_api_packet(trackInfo, players, update.carID); break; // ============================ @@ -577,6 +601,7 @@ int main(void) { // TODO: Update total contacts for both players in the database // TAG:2 Update total contacts for both players + update_api_packet(trackInfo, players, update.carID); } break; case ACSP_CE_COLLISION_WITH_ENV: { @@ -588,6 +613,8 @@ int main(void) { // TODO: Update total contacts for the player in the database // TAG:2 Update total contacts for the player + + update_api_packet(trackInfo, players, update.carID); } break; } @@ -677,9 +704,7 @@ int main(void) { break; } - // OPTIMIZE: This should be done inside each case where data is updated otherwise we lose performance - update_api_packet(trackInfo, players, update.carID); - + // OPTIMIZE: This should be done inside each case where data is updated otherwise we lose performance usleep(10000); // Sleep for 10ms } close(send_sock_fd);