hotfix: Fixed player award for clean lap

This commit is contained in:
2026-01-07 01:15:06 +00:00
parent 95f5a86dd5
commit b39c74f294
4 changed files with 359 additions and 132 deletions
+191 -8
View File
@@ -65,7 +65,190 @@ void *db_write_thread(void *arg) {
continue; // Skip database write for handshake packets
}
broadcast_telemetry(packet);
// Check if it was a crash report
if (packet.message_type == ACSP_CE_COLLISION_WITH_ENV) {
printf("[!] Crash report packet received for server \"%s\" (%d), skipping database write.\n", packet.track_info.server_name, packet.tracker_id);
printf("[!] Single car collision detected. Car ID: %d\n", packet.cars_colided[0]);
// Get current driver_rank for the car
const char *get_rank_query = "SELECT user_rank FROM users WHERE driver_guid = $1;";
const char *driver_guid = packet.cars[packet.cars_colided[0]].driver_GUID;
const char *get_rank_paramValues[1] = {driver_guid};
PGresult *rank_res = PQexecParams(conn, get_rank_query, 1, nullptr, get_rank_paramValues, nullptr, nullptr, 0);
if (PQresultStatus(rank_res) != PGRES_TUPLES_OK) {
printf("[!] Failed to retrieve driver rank for GUID %s: %s", driver_guid, PQerrorMessage(conn));
} else {
// Get driver contacts_alltime
const char *get_contacts_query = "SELECT contacts_alltime FROM users WHERE driver_guid = $1;";
PGresult *contacts_res = PQexecParams(conn, get_contacts_query, 1, nullptr, get_rank_paramValues, nullptr, nullptr, 0);
int contacts_alltime = 0;
if (PQresultStatus(contacts_res) == PGRES_TUPLES_OK) {
if (PQntuples(contacts_res) > 0) {
char *contacts_str = PQgetvalue(contacts_res, 0, 0);
contacts_alltime = atoi(contacts_str);
printf("[*] Driver contacts_alltime for GUID %s is %d\n", driver_guid, contacts_alltime);
}
} else {
printf("[!] Failed to retrieve contacts_alltime for GUID %s: %s", driver_guid, PQerrorMessage(conn));
}
PQclear(contacts_res);
if (PQntuples(rank_res) > 0) {
char *rank_str = PQgetvalue(rank_res, 0, 0);
int driver_rank = atoi(rank_str);
printf("[*] Driver rank for GUID %s is %d\n", driver_guid, driver_rank);
driver_rank -= 10;
if (driver_rank < 0)
driver_rank = 0;
// Update driver_rank in the database
const char *update_rank_query = "UPDATE users SET user_rank = $1, contacts_alltime = $2 WHERE driver_guid = $3;";
std::string new_rank_s = std::to_string(driver_rank);
std::string contacts_alltime_s = std::to_string(contacts_alltime + 1);
const char *update_rank_paramValues[3] = {new_rank_s.c_str(), contacts_alltime_s.c_str(), driver_guid};
PGresult *update_rank_res = PQexecParams(conn, update_rank_query, 3, nullptr, update_rank_paramValues, nullptr, nullptr, 0);
if (PQresultStatus(update_rank_res) != PGRES_COMMAND_OK) {
printf("[!] Failed to update driver rank for GUID %s: %s", driver_guid, PQerrorMessage(conn));
} else {
printf("[*] Driver rank for GUID %s updated to %d\n", driver_guid, driver_rank);
}
PQclear(update_rank_res);
} else {
printf("[!] No driver found with GUID %s to retrieve rank.\n", driver_guid);
}
}
PQclear(rank_res);
continue; // Skip database write for crash report api_packet_storages
}
// Check if it was a crash report
if (packet.message_type == ACSP_CE_COLLISION_WITH_CAR) {
printf("[!] Crash report packet received for server \"%s\" (%d), skipping database write.\n", packet.track_info.server_name, packet.tracker_id);
printf("[!] Multi-car collision detected. Car IDs: %d and %d\n", packet.cars_colided[0], packet.cars_colided[1]);
for (int i = 0; i < 2; i++) {
u_int8_t car_id = packet.cars_colided[i];
const char *driver_guid = packet.cars[car_id].driver_GUID;
// Get current driver_rank for the car
const char *get_rank_query = "SELECT user_rank FROM users WHERE driver_guid = $1;";
const char *get_rank_paramValues[1] = {driver_guid};
PGresult *rank_res = PQexecParams(conn, get_rank_query, 1, nullptr, get_rank_paramValues, nullptr, nullptr, 0);
if (PQresultStatus(rank_res) != PGRES_TUPLES_OK) {
printf("[!] Failed to retrieve driver rank for GUID %s: %s", driver_guid, PQerrorMessage(conn));
} else {
if (PQntuples(rank_res) > 0) {
char *rank_str = PQgetvalue(rank_res, 0, 0);
int driver_rank = atoi(rank_str);
printf("[*] Driver rank for GUID %s is %d\n", driver_guid, driver_rank);
driver_rank -= 5;
if (driver_rank < 0)
driver_rank = 0;
// Update driver_rank in the database
const char *update_rank_query = "UPDATE user SET driver_rank = $1 WHERE driver_guid = $2;";
std::string new_rank_s = std::to_string(driver_rank);
const char *update_rank_paramValues[2] = {new_rank_s.c_str(), driver_guid};
PGresult *update_rank_res = PQexecParams(conn, update_rank_query, 2, nullptr, update_rank_paramValues, nullptr, nullptr, 0);
if (PQresultStatus(update_rank_res) != PGRES_COMMAND_OK) {
printf("[!] Failed to update driver rank for GUID %s: %s", driver_guid, PQerrorMessage(conn));
} else {
printf("[*] Driver rank for GUID %s updated to %d\n", driver_guid, driver_rank);
}
PQclear(update_rank_res);
} else {
printf("[!] No driver found with GUID %s to retrieve rank.\n", driver_guid);
}
}
PQclear(rank_res);
}
continue; // Skip database write for crash report api_packet_storages
}
if (packet.message_type == ACSP_LAP_COMPLETED) {
printf("[+] Lap completed by (%d).\n", packet.cars_colided[0]);
const char *get_rank_query = "UPDATE users SET user_rank = user_rank + 20 WHERE driver_guid = $1;";
const char *driver_guid = packet.cars[packet.cars_colided[0]].driver_GUID;
const char *get_rank_paramValues[1] = {driver_guid};
PGresult *rank_res = PQexecParams(conn, get_rank_query, 1, nullptr, get_rank_paramValues, nullptr, nullptr, 0);
if (PQresultStatus(rank_res) != PGRES_TUPLES_OK) {
printf("[!] Failed to UPDATE driver Rank for GUID %s: %s", driver_guid, PQerrorMessage(conn));
} else {
printf("[+] Increase driver rank +20\n");
}
}
// INFO: Deprecated because packet.car[ID].total_laps_completed was already being updated by the parser alone
// TAG:4 Might be useful in future for other purposes
/* if (packet.message_type == ACSP_LAP_COMPLETED) {
u_int8_t car_id = packet.cars_colided[0]; // In this case, cars_colided[0] holds the carID that completed the lap
const char *driver_guid = packet.cars[car_id].driver_GUID;
// Update laps_completed in the database
const char *update_laps_query = "UPDATE users SET laps_completed = laps_completed + 1, user_rank = user_rank + 25 WHERE driver_guid = $1;";
const char *update_laps_paramValues[1] = {driver_guid};
PGresult *update_laps_res = PQexecParams(conn, update_laps_query, 1, nullptr, update_laps_paramValues, nullptr, nullptr, 0);
if (PQresultStatus(update_laps_res) != PGRES_COMMAND_OK) {
printf("[!] Failed to update laps completed for GUID %s: %s", driver_guid, PQerrorMessage(conn));
} else {
printf("[*] Laps completed updated for GUID %s\n", driver_guid);
}
PQclear(update_laps_res);
continue; // Skip database write for lap completed api_packet_storages
} */
/*
// DEBUG: OUTPUT ALL PACKET DATA
printf("[D] API Packet Data for Server \"%s\" (ID: %d):\n", packet.track_info.server_name, packet.tracker_id);
printf(" Session Type: %d\n", packet.track_info.session_type);
printf(" Session Count: %d\n", packet.track_info.session_count);
printf(" Track: %s\n", packet.track_info.track);
printf(" Config: %s\n", packet.track_info.track_config);
printf(" Weather/Graphics: %s\n", packet.track_info.weather_graphics);
printf(" Time: %d\n", packet.track_info.time);
printf(" Laps: %d\n", packet.track_info.laps);
printf(" Wait Time: %d\n", packet.track_info.wait_time);
printf(" Ambient Temp: %d\n", packet.track_info.ambient_temp);
printf(" Road Temp: %d\n", packet.track_info.road_temp);
printf(" Elapsed Time (ms): %d\n", packet.track_info.elapsed_ms);
printf(" Connected Players: %d\n", packet.connected_players);
for (int i = 0; i < MAX_PLAYERS; i++) {
if (packet.cars[i].isConnected) {
printf(" [D] Car ID: %d\n", packet.cars[i].carID);
printf(" Driver GUID: %s\n", packet.cars[i].driver_GUID);
printf(" Driver Name: %s\n", packet.cars[i].driver_name);
printf(" Driver Team: %s\n", packet.cars[i].driver_team);
printf(" Car Model: %s\n", packet.cars[i].car_model);
printf(" Car Skin: %s\n", packet.cars[i].car_skin);
printf(" Total Cuts Alltime: %d\n", packet.cars[i].total_cuts_alltime);
printf(" Total Contacts: %d\n", packet.cars[i].total_contacts);
printf(" Total Laps Completed: %d\n", packet.cars[i].total_laps_completed);
printf(" Is Connected: %d\n", packet.cars[i].isConnected);
printf(" Is Loading: %d\n", packet.cars[i].isLoading);
}
}
*/
broadcast_telemetry(packet);
// DEBUG
printf("[W] Writing packet for Server with tracker ID: %d to database.\tQueue: %u/%d\n", packet.tracker_id, (unsigned int)api_queue.size(), STACK_SIZE);
@@ -193,6 +376,7 @@ void *db_write_thread(void *arg) {
printf("[D] Processing user \(%d\): GUID=%s, Name=%s, Team=%s Car Model=%s, Skin=%s, Cuts=%s, Contacts=%s, Laps=%s, IsConnect=%s, IsLoading=%s, CurrentServer=%s\n",
i, driver_guid, driver_name, driver_team, car_model, car_skin, cuts_alltime_s.c_str(), contacts_alltime_s.c_str(), laps_completed_s.c_str(),
is_connect_s.c_str(), is_loading_s.c_str(), current_server_s.c_str());
printf("[D] Player Position: (X: %.2f, Y: %.2f, Z: %.2f)\n", packet.cars[car_id].position.x, packet.cars[car_id].position.y, packet.cars[car_id].position.z);
const char *user_paramValues[11] = {driver_guid,
driver_name,
@@ -219,7 +403,6 @@ void *db_write_thread(void *arg) {
} else {
usleep(1000); // Sleep for 1ms if no packets are available
}
}
PQfinish(conn);
@@ -296,12 +479,12 @@ int main(void) {
// detach the thread so it cleans up after itself
pthread_detach(db_thread);
pthread_t telemetry_thread;
if (pthread_create(&telemetry_thread, NULL, telemetry_server_thread, NULL) != 0) {
perror("[!] Failed to create telemetry server thread");
return EXIT_FAILURE;
}
pthread_detach(telemetry_thread);
pthread_t telemetry_thread;
if (pthread_create(&telemetry_thread, NULL, telemetry_server_thread, NULL) != 0) {
perror("[!] Failed to create telemetry server thread");
return EXIT_FAILURE;
}
pthread_detach(telemetry_thread);
printf("[+] Server listening on %s\n", SERVER_SOCKET_PATH);