Madjor Fix: New Player data overwrites old/connected players

This commit is contained in:
2025-10-29 13:52:37 +00:00
parent 2d3f52a9a5
commit 15f87631e2
7 changed files with 328 additions and 81 deletions
+54 -31
View File
@@ -4,6 +4,9 @@
#include <sys/cdefs.h>
#include <sys/types.h>
#define MAX_PLAYERS 64
const int MAX_TELEMETRY_CLIENTS = 128;
typedef struct handshake {
// [not used in the current Remote Telemtry version by AC]
// In future versions it will identify the platform type of the client.
@@ -59,17 +62,17 @@ typedef struct postion {
} __attribute__((packed)) postion;
typedef enum flag {
NO_FLAG = 0,
YELLOW_FLAG = 1,
BLUE_FLAG = 2,
BLACK_FLAG = 3,
CHECKERED_FLAG = 4,
NO_FLAG = 0,
YELLOW_FLAG = 1,
BLUE_FLAG = 2,
BLACK_FLAG = 3,
CHECKERED_FLAG = 4,
} __attribute__((packed)) flag;
typedef struct carAtributes {
// Related to ACSP_CAR_INFO
u_char isConnected; // 1 = connected, 0 = disconnected
u_char isLoading; // 1 = loading, 0 = not isLoading
u_char isLoading; // 1 = loading, 0 = not isLoading
char *car_model;
char *car_skin;
@@ -83,16 +86,16 @@ typedef struct carAtributes {
postion velocity;
u_int8_t carGear;
u_int16_t carRPM;
u_int32_t lap_time;
u_int32_t cuts;
u_int32_t total_cuts;
u_int32_t total_cuts_alltime;
u_int16_t total_laps_completed;
u_int16_t contacts;
u_int16_t total_contacts;
u_int32_t lap_time;
u_int32_t cuts;
u_int32_t total_cuts;
u_int32_t total_cuts_alltime;
u_int16_t total_laps_completed;
u_int16_t contacts;
u_int16_t total_contacts;
flag current_flag; // TODO: implement flag status updates
// TAG:3
flag current_flag; // TODO: implement flag status updates
// TAG:3
float normalizedSplinePos;
} __attribute__((packed)) carAtributes;
@@ -100,7 +103,7 @@ typedef struct carAtributes {
typedef struct carAtributesAPI {
// Related to ACSP_CAR_INFO
u_char isConnected; // 1 = connected, 0 = disconnected
u_char isLoading; // 1 = loading, 0 = not isLoading
u_char isLoading; // 1 = loading, 0 = not isLoading
char car_model[64];
char car_skin[64];
@@ -114,21 +117,20 @@ typedef struct carAtributesAPI {
postion velocity;
u_int8_t carGear;
u_int16_t carRPM;
u_int32_t lap_time;
u_int32_t cuts;
u_int32_t total_cuts;
u_int32_t total_cuts_alltime;
u_int16_t total_laps_completed;
u_int16_t contacts;
u_int16_t total_contacts;
u_int32_t lap_time;
u_int32_t cuts;
u_int32_t total_cuts;
u_int32_t total_cuts_alltime;
u_int16_t total_laps_completed;
u_int16_t contacts;
u_int16_t total_contacts;
flag current_flag; // TODO: implement flag status updates
// TAG:3
flag current_flag; // TODO: implement flag status updates
// TAG:3
float normalizedSplinePos;
} __attribute__((packed)) carAtributesAPI;
typedef enum SessionType {
PRACTICE = 0,
RACE = 1,
@@ -184,15 +186,36 @@ typedef struct trackAtributesAPI {
} __attribute__((packed)) trackAtributesAPI;
typedef struct api_packet {
u_int8_t tracker_id;
u_int8_t last_updated_carid;
u_int8_t connected_cars;
u_char message_type; // ACSP_MessageType
u_int8_t tracker_id;
u_int8_t connected_players;
carAtributesAPI cars[64];
trackAtributesAPI track_info;
carAtributesAPI cars[64];
trackAtributesAPI track_info;
} __attribute__((packed)) 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];
} __attribute__((packed));
enum ACSP_MessageType {
// ============================
// PROTOCOL VERSION
+4
View File
@@ -46,3 +46,7 @@ bool Stack::peek(api_packet &item) {
size_t Stack::size() {
return top + 1;
}
size_t Stack::getCapacity() {
return capacity;
}
+1
View File
@@ -20,6 +20,7 @@ class Stack {
bool pop(api_packet &item);
bool peek(api_packet &item);
size_t size();
size_t getCapacity();
};
#endif // STACK_H
+119
View File
@@ -0,0 +1,119 @@
// include/telemetry.cpp
// Telemetry server implementation for broadcasting car telemetry data to connected clients.
#include "telemetry.h"
std::vector<int> telemetry_clients;
pthread_mutex_t clients_mutex = PTHREAD_MUTEX_INITIALIZER;
// 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);
}
// 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;
}
+25
View File
@@ -0,0 +1,25 @@
// include/telemetry.h
// Header for telemetry server and broadcasting functionality
#ifndef TELEMETRY_H
#define TELEMETRY_H
#include "server_structs.h"
#include <pthread.h>
#include <cstdio>
#include <algorithm>
#include <cmath>
#include <cstring>
#include <sys/socket.h>
#include <sys/un.h>
#include <unistd.h>
#include <vector>
#define TELEMETRY_SOCKET_PATH "/tmp/ACtelemetry_socket"
void *telemetry_server_thread(void *arg);
void broadcast_telemetry(const api_packet &packet);
#endif // TELEMETRY_H