Skip to content

Commit 98c282d

Browse files
committed
Support Xtense2 JSON, add logging and UI updates
Parse Xtense2/XTense v2 report payloads in attack_rc with robust json decoding, proper extraction of coordinates/loot/losses/timestamp, duplicate detection and storage using xtense_user_data. Add structured logging calls ($log) across attack, archives and attaques flows and harden read_config for missing values. Update attack_rr to use xtense_user_data. Convert admin/archives/attaques UI/output to modern markup and safer strings (HTML entities, trimmed layout), add timezone setting in admin and use DateTime/DateTimeZone for local timestamp handling and conversions. Misc: improve menu output, adjust SQL date range comparisons (>=/<=), join to show player display name, and other small refinements (button styles, messages).
1 parent d162853 commit 98c282d

13 files changed

Lines changed: 406 additions & 637 deletions

‎_xtense.php‎

Lines changed: 110 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -61,49 +61,115 @@ public function getCallbacks()
6161
*/
6262
function attack_rc($rapport)
6363
{
64-
global $db, $table_prefix, $attack_config, $user_data;
64+
global $db, $table_prefix, $attack_config, $user_data, $xtense_user_data, $log;
6565
define("TABLE_ATTAQUES_ATTAQUES", $table_prefix . "attaques_attaques");
6666
read_config();
6767

68-
if (!isset($rapport['json']))
68+
$log->debug('Attaques::attack_rc called', ['rapport_keys' => array_keys($rapport)]);
69+
70+
if (!isset($rapport['json'])) {
71+
$log->warning('Attaques::attack_rc: rapport[json] missing');
6972
return false;
73+
}
7074

71-
//On regarde dans les coordonnées de l'espace personnel du joueur qui insère les données via le plugin si il fait partie des attaquants et/ou des défenseurs
75+
// $rapport['json'] is the full outer xtense wrapper JSON string.
76+
// The actual RC payload is in the 'data' field (itself a JSON string).
77+
$outer = json_decode($rapport['json'], true);
78+
$log->debug('Attaques::attack_rc: outer decode', [
79+
'json_error' => json_last_error_msg(),
80+
'outer_keys' => is_array($outer) ? array_keys($outer) : 'NOT_ARRAY',
81+
]);
82+
if (!isset($outer['data'])) {
83+
$log->warning('Attaques::attack_rc: outer[data] missing');
84+
return false;
85+
}
7286

73-
$query = "SELECT `coordinates` FROM " . TABLE_USER_BUILDING . " WHERE `user_id` ='" . $user_data['id'] . "'";
74-
//log_('debug', $query);
75-
$result = $db->sql_query($query);
76-
$coordinates = array();
77-
while ($coordinate = $db->sql_fetch_row($result)) {
78-
$coordinates[] = $coordinate[0];
87+
$rc = json_decode($outer['data'], true);
88+
$log->debug('Attaques::attack_rc: inner decode', [
89+
'json_error' => json_last_error_msg(),
90+
'rc_keys' => is_array($rc) ? array_keys($rc) : 'NOT_ARRAY',
91+
]);
92+
if (!is_array($rc)) {
93+
$log->warning('Attaques::attack_rc: inner data is not an array');
94+
return false;
7995
}
80-
$rc = json_decode($rapport['json']);
8196

82-
//Coordonnées où a eu lieu l'attaque
83-
$coord_attaque = "{$rc->coordinates->galaxy}:{$rc->coordinates->system}:{$rc->coordinates->position}";
84-
//log_('debug', $coord_attaque);
97+
// Coordonnées où a eu lieu l'attaque — stored as "g:s:p" in the new format
98+
$coord_attaque = $rc['coordinates'] ?? null;
99+
$log->debug('Attaques::attack_rc: coordinates', ['coord_attaque' => $coord_attaque]);
100+
if ($coord_attaque === null) {
101+
$log->warning('Attaques::attack_rc: rc[coordinates] missing');
102+
return false;
103+
}
85104

86-
if ($rc->result != 'attacker') //Si l'attaquant ne gagne pas alors il ne prend pas de ressources !
87-
{
88-
$winmetal = 0;
105+
// Winner / loot
106+
$winner = $rc['result']['winner'] ?? '';
107+
$log->debug('Attaques::attack_rc: winner', ['winner' => $winner]);
108+
if ($winner !== 'attacker') {
109+
$winmetal = 0;
89110
$wincristal = 0;
90-
$windeut = 0;
111+
$windeut = 0;
91112
} else {
92-
$winmetal = $rc->loot->metal;
93-
$wincristal = $rc->loot->crystal;
94-
$windeut = $rc->loot->deuterium;
113+
$winmetal = 0;
114+
$wincristal = 0;
115+
$windeut = 0;
116+
foreach ($rc['result']['loot']['resources'] ?? [] as $resource) {
117+
switch ($resource['resource']) {
118+
case 'metal': $winmetal = (int)$resource['amount']; break;
119+
case 'crystal': $wincristal = (int)$resource['amount']; break;
120+
case 'deuterium': $windeut = (int)$resource['amount']; break;
121+
}
122+
}
95123
}
124+
$log->debug('Attaques::attack_rc: loot', ['metal' => $winmetal, 'crystal' => $wincristal, 'deut' => $windeut]);
96125

97-
$pertes = $rc->statistic->lostUnitsAttacker;
98-
$timestamp = $rc->event_timestamp;
126+
// Unit losses
127+
$pertes_attacker = 0;
128+
$pertes_defender = 0;
129+
foreach ($rc['result']['totalValueOfUnitsLost'] ?? [] as $loss) {
130+
if ($loss['side'] === 'attacker') $pertes_attacker = (int)$loss['value'];
131+
if ($loss['side'] === 'defender') $pertes_defender = (int)$loss['value'];
132+
}
133+
$pertes = $pertes_attacker;
134+
$log->debug('Attaques::attack_rc: losses', ['attacker' => $pertes_attacker, 'defender' => $pertes_defender]);
135+
136+
$timestamp = $rc['timestamp'] ?? null;
137+
$log->debug('Attaques::attack_rc: timestamp', ['timestamp' => $timestamp]);
138+
if ($timestamp === null) {
139+
$log->warning('Attaques::attack_rc: rc[timestamp] missing');
140+
return false;
141+
}
99142

100-
//Récupération des coordonnées des attaquants
143+
// Récupération des coordonnées des attaquants et défenseurs
101144
$coords_attaquants = array();
102145
$coords_defenseurs = array();
103-
foreach ($rc->attacker as $attacker)
104-
$coords_attaquants[] = $attacker->ownerCoordinates;
105-
foreach ($rc->defender as $defender)
106-
$coords_defenseurs[] = $defender->ownerCoordinates;
146+
foreach ($rc['fleets'] ?? [] as $fleet) {
147+
$c = $fleet['spaceObject']['coordinates'] ?? null;
148+
if ($c === null) {
149+
$log->warning('Attaques::attack_rc: fleet missing spaceObject.coordinates', ['fleet_side' => $fleet['side'] ?? 'unknown']);
150+
continue;
151+
}
152+
$coord = "{$c['galaxy']}:{$c['system']}:{$c['position']}";
153+
if ($fleet['side'] === 'attacker') {
154+
$coords_attaquants[] = $coord;
155+
} else {
156+
$coords_defenseurs[] = $coord;
157+
}
158+
}
159+
$log->debug('Attaques::attack_rc: fleet coords', [
160+
'attackers' => $coords_attaquants,
161+
'defenders' => $coords_defenseurs,
162+
]);
163+
164+
//On regarde dans les coordonnées de l'espace personnel du joueur qui insère les données via le plugin si il fait partie des attaquants et/ou des défenseurs
165+
$log->debug('Attaques::attack_rc: user_id', ['id' => $xtense_user_data['id'] ?? 'NULL']);
166+
$query = "SELECT CONCAT(`galaxy`, ':', `system`, ':', `row`) FROM " . TABLE_USER_BUILDING . " WHERE `last_update_user_id` = '" . (int)$xtense_user_data['id'] . "'";
167+
$result = $db->sql_query($query);
168+
$coordinates = array();
169+
while ($coordinate = $db->sql_fetch_row($result)) {
170+
$coordinates[] = $coordinate[0];
171+
}
172+
$log->debug('Attaques::attack_rc: user coordinates', ['count' => count($coordinates), 'coords' => $coordinates]);
107173

108174
$attaquant = 0;
109175
$defenseur = 0;
@@ -114,43 +180,42 @@ function attack_rc($rapport)
114180
if (count(array_intersect($coords_defenseurs, $coordinates)) > 0) {
115181
$defenseur = 1;
116182
}
183+
$log->debug('Attaques::attack_rc: role', ['attaquant' => $attaquant, 'defenseur' => $defenseur, 'config_defenseur' => $attack_config['defenseur'] ?? 0]);
117184

118-
// le rapport ne concerne pas l'utilisateur, ou que l'on ne tiens pas compte des attaques subies
119-
// On ne va pas plus loin
120-
//log_('debug', "Attack Config: " . $attack_config['defenseur']);
121-
//log_('debug', "I am the Attacker: " . $attaquant);
122-
//log_('debug', "I am the Defender: " . $defenseur);
123185
/*Cas 1 : Attaquant = 0 Def = 0 Config = 0|1 -> RC Refusé
124186
Cas 2 : Attaquant = 0 Def = 1 Config = 0 -> RC Refusé
125187
Cas 3 : Attaquant = 0 Def = 1 Config = 1 -> RC Accepté
126188
Cas 4 : Attaquant = 1 Def = 0 Config = 0 -> RC Accepté
127189
Cas 5 : Attaquant = 1 Def = 0 Config = 1 -> RC Accepté
128190
Cas 6 : Impossible Att toujours différent de Def
129191
*/
130-
if ($attaquant !== 1 && ($defenseur !== 1 || $attack_config['defenseur'] !== 1)) { // vrai & faux | vrai
131-
//log_('debug', "Erreur : RC non pris en compte");
192+
if ($attaquant !== 1 && ($defenseur !== 1 || ($attack_config['defenseur'] ?? 0) !== 1)) {
193+
$log->debug('Attaques::attack_rc: RC refusé (utilisateur non impliqué)');
132194
return false;
133195
} else {
134-
if ($defenseur === 1 && $attack_config['defenseur'] === 1) {
196+
if ($defenseur === 1 && ($attack_config['defenseur'] ?? 0) === 1) {
135197
//Récupération des pertes défenseurs
136-
$pertes = $rc->statistic->lostUnitsDefender;
198+
$pertes = $pertes_defender;
137199
//On soustrait les ressources volées
138200
$winmetal = -$winmetal;
139201
$wincristal = -$wincristal;
140202
$windeut = -$windeut;
141203
}
142204

143205
//On vérifie que cette attaque n'a pas déja été enregistrée
144-
$query = "SELECT `attack_id` FROM " . TABLE_ATTAQUES_ATTAQUES . " WHERE `attack_user_id` ='" . $user_data['id'] . "' AND `attack_date`='$timestamp' AND `attack_coord`='$coord_attaque' ";
206+
$query = "SELECT `attack_id` FROM " . TABLE_ATTAQUES_ATTAQUES . " WHERE `attack_user_id` ='" . $xtense_user_data['id'] . "' AND `attack_date`='$timestamp' AND `attack_coord`='$coord_attaque' ";
145207
$result = $db->sql_query($query);
146208
$nb = $db->sql_numrows($result);
147209

148210
if ($nb == 0) {
149211
//On insere ces données dans la base de données
150212
$query = "INSERT INTO " . TABLE_ATTAQUES_ATTAQUES . " ( `attack_id` , `attack_user_id` , `attack_coord` , `attack_date` , `attack_metal` , `attack_cristal` , `attack_deut` , `attack_pertes` )
151213
VALUES (
152-
NULL , '" . $user_data['id'] . "', '" . $coord_attaque . "', '" . $timestamp . "', '" . $winmetal . "', '" . $wincristal . "', '" . $windeut . "', '" . $pertes . "')";
214+
NULL , '" . $xtense_user_data['id'] . "', '" . $coord_attaque . "', '" . $timestamp . "', '" . $winmetal . "', '" . $wincristal . "', '" . $windeut . "', '" . $pertes . "')";
153215
$db->sql_query($query);
216+
$log->info('Attaques::attack_rc: RC enregistré', ['coord' => $coord_attaque, 'timestamp' => $timestamp]);
217+
} else {
218+
$log->debug('Attaques::attack_rc: RC déjà enregistré (doublon ignoré)', ['coord' => $coord_attaque, 'timestamp' => $timestamp]);
154219
}
155220
}
156221

@@ -163,7 +228,7 @@ function attack_rc($rapport)
163228
*/
164229
function attack_rr($rapport)
165230
{
166-
global $db, $table_prefix, $user_data;
231+
global $db, $table_prefix, $user_data, $xtense_user_data;
167232

168233
define("TABLE_ATTAQUES_RECYCLAGES", $table_prefix . "attaques_recyclages");
169234

@@ -173,15 +238,15 @@ function attack_rr($rapport)
173238
$timestamp = $rapport['time'];
174239
$coordonne = $rapport['coords'][0] . ":" . $rapport['coords'][1] . ":" . $rapport['coords'][2];
175240
//On vérifie que ce recyclage n'a pas déja été enregistrée
176-
$query = "SELECT `recy_id` FROM " . TABLE_ATTAQUES_RECYCLAGES . " WHERE `recy_user_id` ='" . $user_data['id'] . "' AND `recy_date` ='$timestamp' AND `recy_coord` ='$coordonne' ";
241+
$query = "SELECT `recy_id` FROM " . TABLE_ATTAQUES_RECYCLAGES . " WHERE `recy_user_id` ='" . $xtense_user_data['id'] . "' AND `recy_date` ='$timestamp' AND `recy_coord` ='$coordonne' ";
177242
$result = $db->sql_query($query);
178243
$nb = $db->sql_numrows($result);
179244
// Si on ne trouve rien
180245
if ($nb == 0) {
181246
//On insere ces données dans la base de données
182247
$query = "INSERT INTO " . TABLE_ATTAQUES_RECYCLAGES . " ( `recy_id` , `recy_user_id` , `recy_coord` , `recy_date` , `recy_metal` , `recy_cristal` )
183248
VALUES (
184-
NULL , '" . $user_data['id'] . "', '" . $coordonne . "', '" . $timestamp . "', '" . $rapport['M_reco'] . "', '" . $rapport['C_reco'] . "')";
249+
NULL , '" . $xtense_user_data['id'] . "', '" . $coordonne . "', '" . $timestamp . "', '" . $rapport['M_reco'] . "', '" . $rapport['C_reco'] . "')";
185250
$db->sql_query($query);
186251
}
187252
return true;
@@ -196,6 +261,9 @@ function read_config()
196261
$request = "SELECT `value` FROM `" . TABLE_MOD_CFG . "` WHERE `mod` = 'Attaques' AND `config` = 'config'";
197262
$queryResult = $db->sql_query($request);
198263
$configs = $db->sql_fetch_row($queryResult);
199-
$attack_config = json_decode($configs[0], true);
264+
$attack_config = isset($configs[0]) ? json_decode($configs[0], true) : [];
265+
if (!is_array($attack_config)) {
266+
$attack_config = [];
267+
}
200268
}
201269

0 commit comments

Comments
 (0)