From 530326b8e4e31273686ec1472b757bcb0b49bdeb Mon Sep 17 00:00:00 2001 From: Cyd Date: Wed, 1 Jul 2026 14:04:04 -0500 Subject: [PATCH] Parameterize registration.php; atomic player delete - All staff paths (build, lock, edit, editgame, delete, add, search) and the render SELECTs now use db.php helpers with bound params. Removes SQL injection via playerid/missionid/callsign/newtype/newmap/buildmissions. - Delete routes through new pqs_remove_player() (shared lock + transaction, resyncs numplayers from real occupancy instead of a raw numplayers-1). - Drop a stray buggy line ($callsign from an undefined $line) and guard $_SERVER['SERVER_ADDR']. build now sets nummercs=0 (strict-mode safe). Verified on the stack: build/edit/delete/editgame/lock/search all work; delete resyncs numplayers; no errors. Co-Authored-By: Claude Opus 4.8 --- includes/queue.php | 24 +++++ registration.php | 236 +++++++++++++-------------------------------- 2 files changed, 91 insertions(+), 169 deletions(-) diff --git a/includes/queue.php b/includes/queue.php index a9200c3..3c520c7 100644 --- a/includes/queue.php +++ b/includes/queue.php @@ -96,6 +96,30 @@ function pqs_enqueue_player(string $callsign, string $mech, int $merc = 0): int }); } +/** + * Atomically remove a player from the queue and resync their mission's + * numplayers from actual occupancy. Under the shared lock so it can't race a + * concurrent registration/commit. + */ +function pqs_remove_player(int $playerid): void +{ + pqs_with_queue_lock(function () use ($playerid) { + $db = pqs_db(); + $db->begin_transaction(); + try { + $row = pqs_row("SELECT MissionID FROM pqs_queue WHERE ID = ?", 'i', [$playerid]); + pqs_exec("DELETE FROM pqs_queue WHERE ID = ?", 'i', [$playerid]); + if ($row !== null && $row['MissionID'] !== null) { + pqs_sync_numplayers((int) $row['MissionID']); + } + $db->commit(); + } catch (Throwable $e) { + $db->rollback(); + throw $e; + } + }); +} + /** * Atomically add a player to a SPECIFIC mission (staff "new" action). Does not * pick a mission or enforce capacity — staff may intentionally overfill — but diff --git a/registration.php b/registration.php index e6237fe..b1b8fca 100644 --- a/registration.php +++ b/registration.php @@ -20,6 +20,8 @@ var auto_refreshqueue = setInterval(function() { //var_dump($_POST); //var_dump($_SESSION); include_once("includes/config.php"); +require_once("includes/db.php"); +require_once("includes/queue.php"); date_default_timezone_set('America/Chicago'); $tdate = date('Ymd'); $ttime = date('Hi'); @@ -31,58 +33,36 @@ $merc = 0; $callsign = ""; $nummissions = 0; $mech = ""; -$server = $_SERVER['SERVER_ADDR']; +$server = $_SERVER['SERVER_ADDR'] ?? ''; if (isset($_GET['build'])) { - $buildmissions = $_GET['buildmissions']; - - while ($buildmissions > 0){ - $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 = "INSERT INTO pqs_mission (MissionDate, MissionSize, numplayers, MissionTime) VALUES ($tdate, $missionsize, 0, $ttime)"; - mysqli_query($link, $sql) or die('Query failed: ' . mysqli_error($link)); - $buildmissions--; + $buildmissions = (int)($_GET['buildmissions'] ?? 0); + for ($b = 0; $b < $buildmissions; $b++) { + pqs_exec("INSERT INTO pqs_mission (MissionDate, MissionSize, numplayers, nummercs, MissionTime) VALUES (?, ?, 0, 0, ?)", + 'iii', array((int)$tdate, (int)$missionsize, (int)$ttime)); } - } if (isset($_GET['clearcurrent'])) { - $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 = "TRUNCATE TABLE pqs_currentmission"; - mysqli_query($link, $sql) or die('Query failed: ' . mysqli_error($link)); - mysqli_close($link); + pqs_db()->query("TRUNCATE TABLE pqs_currentmission"); } if (isset($_GET['lock'])) { - $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'); if (isset($_GET['missionid'])) { - $missionid = $_GET['missionid']; - }else{ - $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]; + $missionid = (int)$_GET['missionid']; + } else { + $missionid = (int) pqs_val("SELECT MIN(MissionID) FROM pqs_queue"); + } + if ($missionid > 0) { + pqs_exec("UPDATE pqs_mission SET locked=1 WHERE MissionID=?", 'i', array($missionid)); } - - $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($_POST['edit'])) { - if (isset($_POST['playerid'])) $playerid = $_POST['playerid']; - if (isset($_POST['callsign'])) $callsign = str_replace("'", "''", $_POST['callsign']); - if (isset($_POST['mech'])) $mech = $_POST['mech']; - - $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 Callsign='$callsign', mech='$mech', Updated=1 WHERE id=$playerid"; - mysqli_query($link, $sql) or die('Update player in Queue failed: ' . mysqli_error($link)); - - mysqli_close($link); + $playerid = (int)($_POST['playerid'] ?? 0); + $callsign = isset($_POST['callsign']) ? $_POST['callsign'] : ''; + $mech = isset($_POST['mech']) ? $_POST['mech'] : ''; + pqs_exec("UPDATE pqs_queue SET Callsign=?, mech=?, Updated=1 WHERE id=?", 'ssi', array($callsign, $mech, $playerid)); } if (isset($_POST['add'])) { @@ -107,41 +87,28 @@ if (isset($_POST['new'])) { } if (isset($_POST['editgame'])) { - $newtype = $_POST['newtype']; - $newmap = $_POST['newmap']; - $missionid = $_GET['missionid']; - - $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_mission SET GameType='$newtype', map='$newmap' WHERE MissionID=$missionid"; - mysqli_query($link, $sql) or die('Update player in Queue failed: ' . mysqli_error($link)); - - mysqli_close($link); + $newtype = (int)($_POST['newtype'] ?? 0); + $newmap = (int)($_POST['newmap'] ?? 0); + $missionid = (int)($_GET['missionid'] ?? 0); + pqs_exec("UPDATE pqs_mission SET GameType=?, map=? WHERE MissionID=?", 'iii', array($newtype, $newmap, $missionid)); } if (isset($_GET['action'])) { $action = $_GET['action']; - if (isset($_GET['playerid'])) $playerid = $_GET['playerid']; - if (isset($_GET['missionid'])) $missionid = $_GET['missionid']; - if (isset($_GET['callsign'])) $callsign = $_GET['callsign']; - if (isset($_GET['mech'])) $mech = $_GET['mech']; - if (isset($_GET['oldmap'])) $oldmap = $_GET['oldmap']; - if (isset($_GET['oldtype'])) $oldtype = $_GET['oldtype']; - $callsign=str_replace("'", "'", $line[0]); + $playerid = (int)($_GET['playerid'] ?? 0); + $missionid = (int)($_GET['missionid'] ?? 0); + $mech = $_GET['mech'] ?? ''; + $oldmap = (int)($_GET['oldmap'] ?? 0); + $oldtype = (int)($_GET['oldtype'] ?? 0); + $callsign = ""; $nextmission = $missionid + 1; switch ($action) { case "edit": - $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'); + $row = pqs_row("SELECT * FROM pqs_queue WHERE ID = ?", 'i', array($playerid)); + $callsign = $row['CallSign'] ?? ''; + $mech = $row['Mech'] ?? ''; - $sql = "SELECT * FROM pqs_queue WHERE ID = $playerid"; - $result = mysqli_query($link, $sql) or die('Select player from Queue failed: ' . mysqli_error($link)); - $rs = mysqli_fetch_array($result); - $callsign = $rs[0]; - $mech = $rs[1]; - - echo "
"; + echo ""; echo "
"; echo "
"; echo ""; @@ -151,14 +118,10 @@ if (isset($_GET['action'])) { echo ""; @@ -167,39 +130,19 @@ if (isset($_GET['action'])) { echo ""; echo "
"; echo "
"; echo "
"; - - mysqli_close($link); break; case "delete": - $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 = "SELECT COUNT(CallSign) FROM pqs_queue"; - $result = mysqli_query($link, $sql) or die('Delete player from Queue failed: ' . mysqli_error($link)); - $line = mysqli_fetch_array($result); - $queuecount = $line[0]; - - $sql = "DELETE FROM pqs_queue WHERE id = $playerid"; - $result = mysqli_query($link, $sql) or die('Delete player from Queue failed: ' . mysqli_error($link)); - $sql = "UPDATE pqs_mission SET numplayers = numplayers - 1 WHERE missionid = $missionid"; - $result = mysqli_query($link, $sql) or die('Update mission after delete player failed: ' . mysqli_error($link)); - - mysqli_close($link); + pqs_remove_player($playerid); break; case "add": - $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 = "SELECT * FROM pqs_queue WHERE ID = $playerid"; - $result = mysqli_query($link, $sql) or die('Delete player from Queue failed: ' . mysqli_error($link)); - $rs = mysqli_fetch_array($result); - $callsign = str_replace("'", "'", $rs[0]); - $mech = $rs[1]; - $merc = $rs[4]; - $missionid = $rs[3]; - echo "
"; + $row = pqs_row("SELECT * FROM pqs_queue WHERE ID = ?", 'i', array($playerid)); + $callsign = str_replace("'", "'", $row['CallSign'] ?? ''); + $mech = $row['Mech'] ?? ''; + $merc = $row['Merc'] ?? 0; + $missionid = (int)($row['MissionID'] ?? 0); + echo ""; echo ""; echo "
"; echo "
"; @@ -215,14 +158,10 @@ if (isset($_GET['action'])) { echo ""; echo "
"; echo "
"; - mysqli_close($link); break; case "editgame": - $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'); - - echo "
"; + echo ""; echo ""; echo ""; echo ""; @@ -264,9 +189,6 @@ if (isset($_GET['action'])) { echo ""; echo "
"; echo "
"; @@ -231,32 +170,18 @@ if (isset($_GET['action'])) { echo "
"; echo ""; echo "
"; echo "
"; - - mysqli_close($link); - break; } } @@ -283,13 +205,8 @@ echo ""; // add player form if($missionid==0){ - $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'); - $query = 'SELECT min(MissionID) FROM pqs_queue'; - $result = mysqli_query($link, $query) or die('Query failed: ' . mysqli_error($link)); - $line = mysqli_fetch_array($result); - $missionid = $line[0]; - } + $missionid = (int) pqs_val('SELECT MIN(MissionID) FROM pqs_queue'); +} echo "
"; echo "
"; echo "
"; @@ -299,13 +216,8 @@ echo ""; echo ""; echo "
Back to CurrentM: $missionidCS: "; echo "
"; echo "
"; @@ -336,46 +248,32 @@ echo ""; // search results // if(isset($_GET['search'])){ - if (isset($_GET['callsign'])){ - $cs = str_replace("'", "&;", $_GET['callsign']); + $cs = isset($_GET['callsign']) ? str_replace("'", "&;", $_GET['callsign']) : ''; if($cs == ''){$cs = 'unknown';} - } echo "
"; echo ""; echo ""; - // fetch data // - $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'); - // get last commit time and mission id - $query = "SELECT max(MissionID), max(UNIX_TIMESTAMP(ctime)) FROM pqs_pastmissions"; - $getlct = mysqli_query($link, $query) or die('Query failed: ' . mysqli_error($link)); - $rs2 = mysqli_fetch_array($getlct); - $lastmission = $rs2[0]; - if(is_null($lastmission)){$lastmission = 0;} - $lastCommitTime = $rs2[1];// utc -H*mm*sc - if(is_null($lastCommitTime)){$lastCommitTime = time();}//-(6*60*60);} + $rs2 = pqs_row("SELECT max(MissionID) AS m, max(UNIX_TIMESTAMP(ctime)) AS t FROM pqs_pastmissions"); + $lastmission = (int)($rs2['m'] ?? 0); + $lastCommitTime = $rs2['t'] ?? null; + if(is_null($lastCommitTime)){$lastCommitTime = time();} // get time per game // - $query = "SELECT timepergame, timetoreset FROM pqs_gameconfig"; - $gettpg = mysqli_query($link, $query) or die('Query failed: ' . mysqli_error($link)); - $rs1 = mysqli_fetch_array($gettpg); - $tpg = $rs1[0]+$rs1[1]; + $cfg = pqs_row("SELECT timepergame, timetoreset FROM pqs_gameconfig"); + $tpg = (int)$cfg['timepergame'] + (int)$cfg['timetoreset']; - $query = "SELECT * FROM pqs_queue WHERE CallSign LIKE '$cs' ORDER BY MissionID"; - $result = mysqli_query($link, $query) or die('Query failed: ' . mysqli_error($link)); - - while ($line = mysqli_fetch_array($result)) { - - $mtd = ($line[3] - $lastmission) * $tpg; + foreach (pqs_rows("SELECT * FROM pqs_queue WHERE CallSign LIKE ? ORDER BY MissionID", 's', array($cs)) as $line) { + $mtd = ($line['MissionID'] - $lastmission) * $tpg; $d=strtotime("+$mtd Minutes",$lastCommitTime); $etd = date("h:i", $d); + $c = $line['CallSign']; $mid = $line['MissionID']; $pid = $line['ID']; $mch = $line['Mech']; - echo ""; }
Mission(s) : $cs
CallSignMissionETDMechEdit/Delete
$line[0]$line[3]$etd$line[1]"; - echo "  "; - echo "  "; + echo "
$c$mid$etd$mch"; + echo "  "; + echo "  "; echo "