Parameterize console.php; make Commit Mission atomic
- Config 'Update', 'Commit Mission', lock, and clearupdate now use db.php helpers with bound params (were injectable via ~20 raw $_GET values incl. nummercs and playerid). Pod toggles collapsed into a 16-iteration loop. - Commit Mission runs under the shared queue lock and one transaction so a registration can't slip into the mission mid-commit. - dev/migrations/002: pqs_currentmission + pqs_pastmissions -> InnoDB so the commit's snapshot/archive roll back with the queue delete (uses DELETE not TRUNCATE to stay in the transaction). Verified: commit moves players to current/past, empties queue, marks completed with nummercs; config update writes pods + settings; no errors. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
+82
-100
@@ -18,6 +18,8 @@ var auto_refreshpods = setInterval(function() {
|
|||||||
<body style='background: #000;'>
|
<body style='background: #000;'>
|
||||||
<?php
|
<?php
|
||||||
require_once("includes/config.php");
|
require_once("includes/config.php");
|
||||||
|
require_once("includes/db.php");
|
||||||
|
require_once("includes/queue.php");
|
||||||
date_default_timezone_set('America/Chicago');
|
date_default_timezone_set('America/Chicago');
|
||||||
$ttime = date('Hi');
|
$ttime = date('Hi');
|
||||||
$numberpods = 0;
|
$numberpods = 0;
|
||||||
@@ -25,128 +27,108 @@ $numberpods = 0;
|
|||||||
//var_dump($_GET);
|
//var_dump($_GET);
|
||||||
//var_dump($_POST);
|
//var_dump($_POST);
|
||||||
if (isset($_GET['clearcurrent'])) {
|
if (isset($_GET['clearcurrent'])) {
|
||||||
$link = mysqli_connect('localhost', 'pqs', 'pqs') or die('Could not connect: ' . mysqli_error($link));
|
pqs_db()->query("TRUNCATE TABLE pqs_currentmission");
|
||||||
mysqli_select_db($link, 'pqs') or die('Could not select database');
|
|
||||||
$sql = "TRUNCATE TABLE pqs_currentmission";
|
|
||||||
mysqli_query($link, $sql) or die('Query failed: ' . mysqli_error($link));
|
|
||||||
mysqli_close($link);
|
|
||||||
}
|
}
|
||||||
if (isset($_GET['submit'])) {$submit=$_GET['submit'];}else{$submit='';}
|
if (isset($_GET['submit'])) {$submit=$_GET['submit'];}else{$submit='';}
|
||||||
|
|
||||||
if ($submit=='Update'){
|
if ($submit=='Update'){
|
||||||
$pod01 = (isset($_GET['pod01'])) ? 1 : 0;
|
// Pod toggles: pod01..pod16, present in the query string => on.
|
||||||
$pod02 = (isset($_GET['pod02'])) ? 1 : 0;
|
$pods = array();
|
||||||
$pod03 = (isset($_GET['pod03'])) ? 1 : 0;
|
for ($p = 1; $p <= 16; $p++) {
|
||||||
$pod04 = (isset($_GET['pod04'])) ? 1 : 0;
|
$pods[$p] = isset($_GET[sprintf('pod%02d', $p)]) ? 1 : 0;
|
||||||
$pod05 = (isset($_GET['pod05'])) ? 1 : 0;
|
}
|
||||||
$pod06 = (isset($_GET['pod06'])) ? 1 : 0;
|
$numberpods = array_sum($pods);
|
||||||
$pod07 = (isset($_GET['pod07'])) ? 1 : 0;
|
|
||||||
$pod08 = (isset($_GET['pod08'])) ? 1 : 0;
|
|
||||||
$pod09 = (isset($_GET['pod09'])) ? 1 : 0;
|
|
||||||
$pod10 = (isset($_GET['pod10'])) ? 1 : 0;
|
|
||||||
$pod11 = (isset($_GET['pod11'])) ? 1 : 0;
|
|
||||||
$pod12 = (isset($_GET['pod12'])) ? 1 : 0;
|
|
||||||
$pod13 = (isset($_GET['pod13'])) ? 1 : 0;
|
|
||||||
$pod14 = (isset($_GET['pod14'])) ? 1 : 0;
|
|
||||||
$pod15 = (isset($_GET['pod15'])) ? 1 : 0;
|
|
||||||
$pod16 = (isset($_GET['pod16'])) ? 1 : 0;
|
|
||||||
$numberpods = $pod01 + $pod02 + $pod03 + $pod04 + $pod05 + $pod06 + $pod07 + $pod08 + $pod09 + $pod10 + $pod11 + $pod12 + $pod13 + $pod14 + $pod15 + $pod16;
|
|
||||||
$visibility = $_GET['visibility'];
|
|
||||||
$weather = $_GET['weather'];
|
|
||||||
$timeofday = $_GET['timeofday'];
|
|
||||||
$timelimit = $_GET['timelimit'];
|
|
||||||
$timetoreset = $_GET['timetoreset'];
|
|
||||||
$radar = $_GET['radar'];
|
|
||||||
$heat = (isset($_GET['heat'])) ? 1 : 0;
|
|
||||||
$friendlyfire = (isset($_GET['friendlyfire'])) ? 1 : 0;
|
|
||||||
$splashdamage = (isset($_GET['splashdamage'])) ? 1 : 0;
|
|
||||||
$limitedammo = (isset($_GET['limitedammo'])) ? 1 : 0;
|
|
||||||
$noreturn = (isset($_GET['noreturn'])) ? 1 : 0;
|
|
||||||
$printdebriefing = (isset($_GET['printdebriefing'])) ? 1 : 0;
|
|
||||||
$missionreview = (isset($_GET['missionreview'])) ? 1 : 0;
|
|
||||||
$weaponjam = (isset($_GET['weaponjam'])) ? 1 : 0;
|
|
||||||
$advancemode = (isset($_GET['advancemode'])) ? 1 : 0;
|
|
||||||
$armormode = (isset($_GET['armormode'])) ? 1 : 0;
|
|
||||||
$cameraship = $_GET['cameraship'];
|
|
||||||
$groupAvalible = (isset($_GET['groupAvalible'])) ? 1 : 0;
|
|
||||||
|
|
||||||
$link = mysqli_connect('localhost', 'pqs', 'pqs') or die('Could not connect: ' . mysqli_error($link));
|
// Numeric dropdowns.
|
||||||
mysqli_select_db($link, 'pqs') or die('Could not select database');
|
$visibility = (int)($_GET['visibility'] ?? 0);
|
||||||
|
$weather = (int)($_GET['weather'] ?? 0);
|
||||||
|
$timelimit = (int)($_GET['timelimit'] ?? 0);
|
||||||
|
$timetoreset = (int)($_GET['timetoreset'] ?? 0);
|
||||||
|
$radar = (int)($_GET['radar'] ?? 0);
|
||||||
|
// Checkbox flags.
|
||||||
|
$heat = isset($_GET['heat']) ? 1 : 0;
|
||||||
|
$friendlyfire = isset($_GET['friendlyfire']) ? 1 : 0;
|
||||||
|
$splashdamage = isset($_GET['splashdamage']) ? 1 : 0;
|
||||||
|
$limitedammo = isset($_GET['limitedammo']) ? 1 : 0;
|
||||||
|
$noreturn = isset($_GET['noreturn']) ? 1 : 0;
|
||||||
|
$printdebriefing = isset($_GET['printdebriefing'])? 1 : 0;
|
||||||
|
$missionreview = isset($_GET['missionreview']) ? 1 : 0;
|
||||||
|
$weaponjam = isset($_GET['weaponjam']) ? 1 : 0;
|
||||||
|
$advancemode = isset($_GET['advancemode']) ? 1 : 0;
|
||||||
|
$armormode = isset($_GET['armormode']) ? 1 : 0;
|
||||||
|
$groupAvalible = isset($_GET['groupAvalible']) ? 1 : 0;
|
||||||
|
|
||||||
$queryconfig = "UPDATE pqs_gameconfig SET numpods=" . $numberpods . ", timepergame=" . $timelimit . ", timetoreset=" . $timetoreset . ", timelimit=".$timelimit.", visibility=".$visibility.", weather=".$weather.", radar=".$radar.", heat=".$heat.", friendlyfire=".$friendlyfire.", splashdamage=".$splashdamage.", limitedammo=".$limitedammo.", noreturn=".$noreturn.", printdebriefing=".$printdebriefing.", missionreview=".$missionreview.", weaponjam=".$weaponjam.", advancemode=".$advancemode.", armormode=".$armormode.", GroupAvalible=".$groupAvalible." WHERE gamechoiceid=1";
|
// Note: timepergame is intentionally set to timelimit, and timeofday /
|
||||||
|
// cameraship are not written here (preserves the original behavior).
|
||||||
|
pqs_exec(
|
||||||
|
"UPDATE pqs_gameconfig SET numpods=?, timepergame=?, timetoreset=?, timelimit=?,
|
||||||
|
visibility=?, weather=?, radar=?, heat=?, friendlyfire=?, splashdamage=?,
|
||||||
|
limitedammo=?, noreturn=?, printdebriefing=?, missionreview=?, weaponjam=?,
|
||||||
|
advancemode=?, armormode=?, GroupAvalible=? WHERE gamechoiceid=1",
|
||||||
|
str_repeat('i', 18),
|
||||||
|
array($numberpods, $timelimit, $timetoreset, $timelimit, $visibility, $weather,
|
||||||
|
$radar, $heat, $friendlyfire, $splashdamage, $limitedammo, $noreturn,
|
||||||
|
$printdebriefing, $missionreview, $weaponjam, $advancemode, $armormode, $groupAvalible)
|
||||||
|
);
|
||||||
|
|
||||||
mysqli_query($link, $queryconfig) or die('Query failed: ' . mysqli_error($link));
|
pqs_exec(
|
||||||
|
"UPDATE pqs_pods SET pod01=?, pod02=?, pod03=?, pod04=?, pod05=?, pod06=?, pod07=?,
|
||||||
|
pod08=?, pod09=?, pod10=?, pod11=?, pod12=?, pod13=?, pod14=?, pod15=?, pod16=?",
|
||||||
|
str_repeat('i', 16),
|
||||||
|
array_values($pods)
|
||||||
|
);
|
||||||
|
|
||||||
$queryconfig = "UPDATE pqs_pods SET pod01=".$pod01.", pod02=".$pod02.", pod03=".$pod03.", pod04=".$pod04.", pod05=".$pod05.", pod06=".$pod06.", pod07=".$pod07.", pod08=".$pod08.", pod09=".$pod09.", pod10=".$pod10.",pod11=".$pod11.", pod12=".$pod12.", pod13=".$pod13.", pod14=".$pod14.", pod15=".$pod15.", pod16=".$pod16." ";
|
pqs_exec("UPDATE pqs_mission SET MissionSize=? WHERE Completed=0", 'i', array($numberpods));
|
||||||
|
|
||||||
mysqli_query($link, $queryconfig) or die('Query failed: ' . mysqli_error($link));
|
|
||||||
|
|
||||||
$queryconfig = "UPDATE pqs_mission SET MissionSize=" . $numberpods . " WHERE Completed=0";
|
|
||||||
mysqli_query($link, $queryconfig) or die('Query failed: ' . mysqli_error($link));
|
|
||||||
mysqli_close($link);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
if ($submit=='Commit Mission') {
|
if ($submit=='Commit Mission') {
|
||||||
$link = mysqli_connect('localhost', 'pqs', 'pqs') or die('Could not connect: ' . mysqli_error($link));
|
// Commit the next mission: snapshot to the current board, archive to history,
|
||||||
mysqli_select_db($link, 'pqs') or die('Could not select database');
|
// clear it from the queue and mark it completed. Runs under the shared queue
|
||||||
$sql = "SELECT MIN(MissionID) FROM pqs_queue";
|
// lock (so a registration can't slip in mid-commit) and as one transaction.
|
||||||
$getid = mysqli_query($link, $sql) or die('Query failed: ' . mysqli_error($link));
|
$nummercs = (int)($_GET['nummercs'] ?? 0);
|
||||||
$rs = mysqli_fetch_array($getid);
|
$mtime = (int) date('Hi');
|
||||||
$missionid = $rs[0];
|
pqs_with_queue_lock(function () use ($nummercs, $mtime) {
|
||||||
$sql = "TRUNCATE TABLE pqs_currentmission";
|
$db = pqs_db();
|
||||||
mysqli_query($link, $sql) or die('Query failed: ' . mysqli_error($link));
|
$db->begin_transaction();
|
||||||
$sql = "SELECT callsign, mech FROM pqs_queue where MissionID=$missionid";
|
try {
|
||||||
$getid = mysqli_query($link, $sql) or die('Query failed: ' . mysqli_error($link));
|
$missionid = (int) pqs_val("SELECT MIN(MissionID) FROM pqs_queue");
|
||||||
while ($rs = mysqli_fetch_array($getid)) {
|
$db->query("DELETE FROM pqs_currentmission");
|
||||||
$callsign = str_replace("'", "''", $rs[0]);
|
if ($missionid > 0) {
|
||||||
$sql = "INSERT INTO pqs_currentmission (callsign,missionid) VALUES ('$callsign',$missionid)";
|
$players = pqs_rows("SELECT callsign, mech FROM pqs_queue WHERE MissionID = ?", 'i', array($missionid));
|
||||||
mysqli_query($link, $sql) or die('DEBUG: Insert into currentmission failed: ' . mysqli_error($link));
|
foreach ($players as $p) {
|
||||||
$sql = "INSERT INTO pqs_pastmissions (callsign,mech,missionid) VALUES ('$callsign','$rs[1]',$missionid)";
|
pqs_exec("INSERT INTO pqs_currentmission (callsign, missionid) VALUES (?, ?)",
|
||||||
mysqli_query($link, $sql) or die('DEBUG: Insert into pastmissions failed: ' . mysqli_error($link));
|
'si', array($p['callsign'], $missionid));
|
||||||
|
pqs_exec("INSERT INTO pqs_pastmissions (callsign, mech, missionid) VALUES (?, ?, ?)",
|
||||||
|
'ssi', array($p['callsign'], $p['mech'], $missionid));
|
||||||
}
|
}
|
||||||
$sql = "DELETE FROM pqs_queue WHERE MissionID=$missionid";
|
pqs_exec("DELETE FROM pqs_queue WHERE MissionID = ?", 'i', array($missionid));
|
||||||
mysqli_query($link, $sql) or die('Query failed: ' . mysqli_error($link));
|
pqs_exec("UPDATE pqs_mission SET Completed = 1, nummercs = ?, missiontime = ? WHERE MissionID = ?",
|
||||||
$sql = "UPDATE pqs_mission SET Completed=1, nummercs=$_GET[nummercs], missiontime=$ttime WHERE MissionID=$missionid";
|
'iii', array($nummercs, $mtime, $missionid));
|
||||||
mysqli_query($link, $sql) or die('Query failed: ' . mysqli_error($link));
|
}
|
||||||
mysqli_close($link);
|
$db->commit();
|
||||||
|
} catch (Throwable $e) {
|
||||||
|
$db->rollback();
|
||||||
|
throw $e;
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
if (isset($_GET['lock'])) {
|
if (isset($_GET['lock'])) {
|
||||||
$link = mysqli_connect('localhost', 'pqs', 'pqs') or die('Could not connect: ' . mysqli_error($link));
|
$missionid = (int) pqs_val("SELECT MIN(MissionID) FROM pqs_queue");
|
||||||
mysqli_select_db($link, 'pqs') or die('Could not select database');
|
if ($missionid > 0) {
|
||||||
$sql = "SELECT MIN(MissionID) FROM pqs_queue";
|
pqs_exec("UPDATE pqs_mission SET locked = 1 WHERE MissionID = ?", 'i', array($missionid));
|
||||||
$getid = mysqli_query($link, $sql) or die('Query failed: ' . mysqli_error($link));
|
|
||||||
$rs = mysqli_fetch_array($getid);
|
|
||||||
$missionid = $rs[0];
|
|
||||||
$sql = "UPDATE pqs_mission SET locked=1 WHERE MissionID=$missionid";
|
|
||||||
mysqli_query($link, $sql) or die('Query failed: ' . mysqli_error($link));
|
|
||||||
mysqli_close($link);
|
|
||||||
}
|
}
|
||||||
if (isset($_GET['action'])) {
|
|
||||||
if ($_GET['action'] == 'clearupdate') {
|
|
||||||
if (isset($_GET['playerid'])) $playerid = $_GET['playerid'];
|
|
||||||
$link = mysqli_connect('localhost', 'pqs', 'pqs') or die('Could not connect: ' . mysqli_error($link));
|
|
||||||
mysqli_select_db($link, 'pqs') or die('Could not select database');
|
|
||||||
$sql = "UPDATE pqs_queue SET Updated = 0 WHERE ID = $playerid";
|
|
||||||
$result = mysqli_query($link, $sql) or die('Delete player from Queue failed: ' . mysqli_error($link));
|
|
||||||
mysqli_close($link);
|
|
||||||
}
|
}
|
||||||
|
if (isset($_GET['action']) && $_GET['action'] == 'clearupdate') {
|
||||||
|
$playerid = (int)($_GET['playerid'] ?? 0);
|
||||||
|
pqs_exec("UPDATE pqs_queue SET Updated = 0 WHERE ID = ?", 'i', array($playerid));
|
||||||
}
|
}
|
||||||
|
|
||||||
$link = mysqli_connect('localhost', 'pqs', 'pqs') or die('Could not connect: ' . mysqli_error($link));
|
$missionid = (int) pqs_val("SELECT MIN(MissionID) FROM pqs_queue");
|
||||||
mysqli_select_db($link, 'pqs') or die('Could not select database');
|
|
||||||
$sql = "SELECT MIN(MissionID) FROM pqs_queue";
|
|
||||||
$getid = mysqli_query($link, $sql) or die('Query failed: ' . mysqli_error($link));
|
|
||||||
$rs = mysqli_fetch_array($getid);
|
|
||||||
$missionid = $rs[0];
|
|
||||||
$locked = 0;
|
$locked = 0;
|
||||||
if ($missionid != 0) {
|
if ($missionid != 0) {
|
||||||
$sql = "SELECT locked FROM pqs_mission WHERE MissionId=$missionid";
|
$locked = (int) pqs_val("SELECT locked FROM pqs_mission WHERE MissionId = ?", 'i', array($missionid));
|
||||||
$getid = mysqli_query($link, $sql) or die('Query failed: ' . mysqli_error($link));
|
|
||||||
$rs = mysqli_fetch_array($getid);
|
|
||||||
$locked = $rs[0];
|
|
||||||
}
|
}
|
||||||
mysqli_close($link);
|
|
||||||
echo "<table width='450' border='0'>";
|
echo "<table width='450' border='0'>";
|
||||||
echo "<tr><td align='center'><a class='queuedisplayhead' href='console.php?clearcurrent=1'><font size='3'>Clear Current Queue</font></a> | ";
|
echo "<tr><td align='center'><a class='queuedisplayhead' href='console.php?clearcurrent=1'><font size='3'>Clear Current Queue</font></a> | ";
|
||||||
echo "<a class='queuedisplayhead' href='history.php?launch=console' target='_blank'><font size='3'>Open History Window</font></a></td></tr>";
|
echo "<a class='queuedisplayhead' href='history.php?launch=console' target='_blank'><font size='3'>Open History Window</font></a></td></tr>";
|
||||||
|
|||||||
@@ -0,0 +1,13 @@
|
|||||||
|
-- Migration 002: convert the mission-commit tables to InnoDB.
|
||||||
|
--
|
||||||
|
-- Why: console.php "Commit Mission" now snapshots to pqs_currentmission and
|
||||||
|
-- archives to pqs_pastmissions inside a transaction (with the queue delete +
|
||||||
|
-- mission completion). For that to roll back cleanly on error, these two must
|
||||||
|
-- be InnoDB as well. (DELETE, not TRUNCATE, is used on pqs_currentmission so it
|
||||||
|
-- stays inside the transaction.)
|
||||||
|
--
|
||||||
|
-- Safe and reversible; run once:
|
||||||
|
-- mysql -u pqs -ppqs pqs < dev/migrations/002-innodb-commit-tables.sql
|
||||||
|
|
||||||
|
ALTER TABLE pqs_currentmission ENGINE=InnoDB;
|
||||||
|
ALTER TABLE pqs_pastmissions ENGINE=InnoDB;
|
||||||
Reference in New Issue
Block a user