generated from AfonsoCMSousa/CPP-Template
hotfix: Fixed player award for clean lap
This commit is contained in:
parent
95f5a86dd5
commit
b39c74f294
@ -190,6 +190,8 @@ typedef struct api_packet {
|
||||
u_int8_t tracker_id;
|
||||
u_int8_t connected_players;
|
||||
|
||||
u_int8_t cars_colided[2]; // IDs of cars involved in a collision event IF [1] == 255, [0] is the only car involved (environment collision)
|
||||
|
||||
carAtributesAPI cars[64];
|
||||
trackAtributesAPI track_info;
|
||||
|
||||
@ -197,23 +199,24 @@ typedef struct api_packet {
|
||||
|
||||
// Telemetry packet structure (lightweight for streaming)
|
||||
struct telemetry_packet {
|
||||
u_int8_t server_id;
|
||||
u_int8_t car_count;
|
||||
|
||||
struct car_telemetry {
|
||||
u_int8_t carID;
|
||||
char driver_name[64];
|
||||
char driver_guid[64];
|
||||
char car_model[64];
|
||||
float normalizedSplinePos;
|
||||
float speed_kmh;
|
||||
u_int8_t gear;
|
||||
u_int16_t rpm;
|
||||
u_int32_t last_lap_time;
|
||||
u_int32_t best_lap_time;
|
||||
u_int16_t current_lap;
|
||||
u_int8_t position;
|
||||
} __attribute__((packed)) cars[64];
|
||||
u_int8_t server_id;
|
||||
u_int8_t car_count;
|
||||
|
||||
struct car_telemetry {
|
||||
u_int8_t carID;
|
||||
char driver_name[64];
|
||||
char driver_guid[64];
|
||||
char car_model[64];
|
||||
postion position;
|
||||
float normalizedSplinePos;
|
||||
float speed_kmh;
|
||||
u_int8_t gear;
|
||||
u_int16_t rpm;
|
||||
u_int32_t last_lap_time;
|
||||
u_int32_t best_lap_time;
|
||||
u_int16_t current_lap;
|
||||
u_int8_t position_rank; // RENAME: position -> position_rank to avoid conflict
|
||||
} __attribute__((packed)) cars[64];
|
||||
} __attribute__((packed));
|
||||
|
||||
enum ACSP_MessageType {
|
||||
|
||||
@ -5,115 +5,156 @@
|
||||
std::vector<int> telemetry_clients;
|
||||
pthread_mutex_t clients_mutex = PTHREAD_MUTEX_INITIALIZER;
|
||||
|
||||
// Helper struct for sorting cars by position
|
||||
struct CarPosition {
|
||||
int index;
|
||||
u_int16_t laps;
|
||||
float splinePos;
|
||||
|
||||
bool operator<(const CarPosition &other) const {
|
||||
// First compare by laps (more laps = better position)
|
||||
if (laps != other.laps) {
|
||||
return laps > other.laps;
|
||||
}
|
||||
// If same laps, compare by spline position (further along = better)
|
||||
return splinePos > other.splinePos;
|
||||
}
|
||||
};
|
||||
|
||||
// Broadcast telemetry to all connected clients
|
||||
void broadcast_telemetry(const api_packet& packet) {
|
||||
telemetry_packet telem;
|
||||
telem.server_id = packet.tracker_id;
|
||||
telem.car_count = 0;
|
||||
|
||||
// Convert api_packet to telemetry_packet
|
||||
for (int i = 0; i < MAX_PLAYERS; i++) {
|
||||
if (packet.cars[i].isConnected) {
|
||||
auto& car = telem.cars[telem.car_count];
|
||||
|
||||
car.carID = packet.cars[i].carID;
|
||||
strncpy(car.driver_name, packet.cars[i].driver_name, sizeof(car.driver_name) - 1);
|
||||
car.driver_name[sizeof(car.driver_name) - 1] = '\0';
|
||||
strncpy(car.driver_guid, packet.cars[i].driver_GUID, sizeof(car.driver_guid) - 1);
|
||||
car.driver_guid[sizeof(car.driver_guid) - 1] = '\0';
|
||||
strncpy(car.car_model, packet.cars[i].car_model, sizeof(car.car_model) - 1);
|
||||
car.car_model[sizeof(car.car_model) - 1] = '\0';
|
||||
car.normalizedSplinePos = packet.cars[i].normalizedSplinePos;
|
||||
|
||||
// Calculate speed from velocity vector (m/s to km/h)
|
||||
float speed_ms = std::sqrt(
|
||||
std::pow(packet.cars[i].velocity.x, 2.0f) +
|
||||
std::pow(packet.cars[i].velocity.y, 2.0f) +
|
||||
std::pow(packet.cars[i].velocity.z, 2.0f)
|
||||
);
|
||||
car.speed_kmh = speed_ms * 3.6f;
|
||||
|
||||
car.gear = packet.cars[i].carGear;
|
||||
car.rpm = packet.cars[i].carRPM;
|
||||
car.last_lap_time = packet.cars[i].lap_time;
|
||||
car.best_lap_time = 0; // TODO: Track best lap
|
||||
car.current_lap = packet.cars[i].total_laps_completed;
|
||||
car.position = telem.car_count + 1; // Temporary position
|
||||
|
||||
telem.car_count++;
|
||||
}
|
||||
}
|
||||
|
||||
// Broadcast to all connected clients
|
||||
pthread_mutex_lock(&clients_mutex);
|
||||
|
||||
for (auto it = telemetry_clients.begin(); it != telemetry_clients.end();) {
|
||||
ssize_t sent = send(*it, &telem, sizeof(telem), MSG_NOSIGNAL);
|
||||
|
||||
if (sent < 0) {
|
||||
// Client disconnected, remove from list
|
||||
printf("[T] Telemetry client %d disconnected\n", *it);
|
||||
close(*it);
|
||||
it = telemetry_clients.erase(it);
|
||||
} else {
|
||||
++it;
|
||||
}
|
||||
}
|
||||
|
||||
pthread_mutex_unlock(&clients_mutex);
|
||||
void broadcast_telemetry(const api_packet &packet) {
|
||||
telemetry_packet telem;
|
||||
telem.server_id = packet.tracker_id;
|
||||
telem.car_count = 0;
|
||||
|
||||
// Temporary storage for connected cars
|
||||
std::vector<CarPosition> positions;
|
||||
std::vector<int> carIndices; // Maps telem index to original packet index
|
||||
|
||||
// First pass: collect all connected cars
|
||||
for (int i = 0; i < MAX_PLAYERS; i++) {
|
||||
if (packet.cars[i].isConnected) {
|
||||
CarPosition pos;
|
||||
pos.index = telem.car_count;
|
||||
pos.laps = packet.cars[i].total_laps_completed;
|
||||
pos.splinePos = packet.cars[i].normalizedSplinePos;
|
||||
|
||||
positions.push_back(pos);
|
||||
carIndices.push_back(i);
|
||||
|
||||
auto &car = telem.cars[telem.car_count];
|
||||
|
||||
car.carID = packet.cars[i].carID;
|
||||
strncpy(car.driver_name, packet.cars[i].driver_name, sizeof(car.driver_name) - 1);
|
||||
car.driver_name[sizeof(car.driver_name) - 1] = '\0';
|
||||
strncpy(car.driver_guid, packet.cars[i].driver_GUID, sizeof(car.driver_guid) - 1);
|
||||
car.driver_guid[sizeof(car.driver_guid) - 1] = '\0';
|
||||
strncpy(car.car_model, packet.cars[i].car_model, sizeof(car.car_model) - 1);
|
||||
car.car_model[sizeof(car.car_model) - 1] = '\0';
|
||||
|
||||
car.position.x = packet.cars[i].position.x;
|
||||
car.position.y = packet.cars[i].position.y;
|
||||
car.position.z = packet.cars[i].position.z;
|
||||
|
||||
car.normalizedSplinePos = packet.cars[i].normalizedSplinePos;
|
||||
|
||||
// Calculate speed from velocity vector (m/s to km/h)
|
||||
float speed_ms = std::sqrt(std::pow(packet.cars[i].velocity.x, 2.0f) + std::pow(packet.cars[i].velocity.y, 2.0f) + std::pow(packet.cars[i].velocity.z, 2.0f));
|
||||
car.speed_kmh = speed_ms * 3.6f;
|
||||
|
||||
car.gear = packet.cars[i].carGear;
|
||||
car.rpm = packet.cars[i].carRPM;
|
||||
car.last_lap_time = packet.cars[i].lap_time;
|
||||
car.best_lap_time = 0; // TODO: Track best lap across session
|
||||
car.current_lap = packet.cars[i].total_laps_completed;
|
||||
|
||||
telem.car_count++;
|
||||
}
|
||||
}
|
||||
|
||||
// Sort cars by position
|
||||
std::sort(positions.begin(), positions.end());
|
||||
|
||||
// Assign positions (1-indexed)
|
||||
for (size_t i = 0; i < positions.size(); i++) {
|
||||
telem.cars[positions[i].index].position_rank = i + 1;
|
||||
}
|
||||
|
||||
// Broadcast to all connected clients
|
||||
pthread_mutex_lock(&clients_mutex);
|
||||
|
||||
// Calculate actual packet size (header + only connected cars)
|
||||
size_t header_size = 2; // server_id + car_count
|
||||
size_t car_size = sizeof(telemetry_packet::car_telemetry);
|
||||
size_t packet_size = header_size + (telem.car_count * car_size);
|
||||
|
||||
for (auto it = telemetry_clients.begin(); it != telemetry_clients.end();) {
|
||||
ssize_t sent = send(*it, &telem, packet_size, MSG_NOSIGNAL);
|
||||
|
||||
if (sent < 0) {
|
||||
// Client disconnected, remove from list
|
||||
printf("[T] Telemetry client %d disconnected\n", *it);
|
||||
close(*it);
|
||||
it = telemetry_clients.erase(it);
|
||||
} else {
|
||||
++it;
|
||||
}
|
||||
}
|
||||
|
||||
pthread_mutex_unlock(&clients_mutex);
|
||||
}
|
||||
|
||||
// Thread to accept telemetry client connections
|
||||
void* telemetry_server_thread(void* arg) {
|
||||
(void)arg;
|
||||
|
||||
int server_fd = socket(AF_UNIX, SOCK_STREAM, 0);
|
||||
if (server_fd < 0) {
|
||||
perror("[!] Telemetry socket creation failed");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
unlink(TELEMETRY_SOCKET_PATH);
|
||||
|
||||
struct sockaddr_un addr;
|
||||
addr.sun_family = AF_UNIX;
|
||||
strncpy(addr.sun_path, TELEMETRY_SOCKET_PATH, sizeof(addr.sun_path) - 1);
|
||||
addr.sun_path[sizeof(addr.sun_path) - 1] = '\0';
|
||||
|
||||
if (bind(server_fd, (struct sockaddr*)&addr, sizeof(addr)) < 0) {
|
||||
perror("[!] Telemetry socket bind failed");
|
||||
close(server_fd);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (listen(server_fd, 5) < 0) {
|
||||
perror("[!] Telemetry socket listen failed");
|
||||
close(server_fd);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
printf("[+] Telemetry server listening on %s\n", TELEMETRY_SOCKET_PATH);
|
||||
|
||||
while (1) {
|
||||
int client_fd = accept(server_fd, NULL, NULL);
|
||||
if (client_fd < 0) {
|
||||
perror("[!] Telemetry accept failed");
|
||||
continue;
|
||||
}
|
||||
|
||||
pthread_mutex_lock(&clients_mutex);
|
||||
|
||||
if (telemetry_clients.size() < (size_t)MAX_TELEMETRY_CLIENTS) {
|
||||
telemetry_clients.push_back(client_fd);
|
||||
printf("[+] Telemetry client connected (total: %zu)\n", telemetry_clients.size());
|
||||
} else {
|
||||
printf("[!] Max telemetry clients reached, rejecting connection\n");
|
||||
close(client_fd);
|
||||
}
|
||||
|
||||
pthread_mutex_unlock(&clients_mutex);
|
||||
}
|
||||
|
||||
close(server_fd);
|
||||
return NULL;
|
||||
void *telemetry_server_thread(void *arg) {
|
||||
(void)arg;
|
||||
|
||||
int server_fd = socket(AF_UNIX, SOCK_STREAM, 0);
|
||||
if (server_fd < 0) {
|
||||
perror("[!] Telemetry socket creation failed");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
unlink(TELEMETRY_SOCKET_PATH);
|
||||
|
||||
struct sockaddr_un addr;
|
||||
addr.sun_family = AF_UNIX;
|
||||
strncpy(addr.sun_path, TELEMETRY_SOCKET_PATH, sizeof(addr.sun_path) - 1);
|
||||
addr.sun_path[sizeof(addr.sun_path) - 1] = '\0';
|
||||
|
||||
if (bind(server_fd, (struct sockaddr *)&addr, sizeof(addr)) < 0) {
|
||||
perror("[!] Telemetry socket bind failed");
|
||||
close(server_fd);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (listen(server_fd, 5) < 0) {
|
||||
perror("[!] Telemetry socket listen failed");
|
||||
close(server_fd);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
printf("[+] Telemetry server listening on %s\n", TELEMETRY_SOCKET_PATH);
|
||||
|
||||
while (1) {
|
||||
int client_fd = accept(server_fd, NULL, NULL);
|
||||
if (client_fd < 0) {
|
||||
perror("[!] Telemetry accept failed");
|
||||
continue;
|
||||
}
|
||||
|
||||
pthread_mutex_lock(&clients_mutex);
|
||||
|
||||
if (telemetry_clients.size() < (size_t)MAX_TELEMETRY_CLIENTS) {
|
||||
telemetry_clients.push_back(client_fd);
|
||||
printf("[+] Telemetry client connected (total: %zu)\n", telemetry_clients.size());
|
||||
} else {
|
||||
printf("[!] Max telemetry clients reached, rejecting connection\n");
|
||||
close(client_fd);
|
||||
}
|
||||
|
||||
pthread_mutex_unlock(&clients_mutex);
|
||||
}
|
||||
|
||||
close(server_fd);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
199
source/main.cpp
199
source/main.cpp
@ -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);
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user