isAdmin($user_id);
if (!$isAdmin) {
echo "
Access Denied: Admin privileges required.
";
return;
}
// -------------------------------------------------------------------
// Check whether is_default_for_billing column exists.
// It is added by db_version 8 migration; show a warning if missing.
// -------------------------------------------------------------------
$colExists = false;
$colCheck = $db->resultQuery(
"SELECT COUNT(*) AS cnt
FROM INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_SCHEMA = DATABASE()
AND TABLE_NAME = '{$db_prefix}config_mods'
AND COLUMN_NAME = 'is_default_for_billing'"
);
if (!empty($colCheck[0]['cnt']) && intval($colCheck[0]['cnt']) > 0) {
$colExists = true;
}
if (!$colExists) {
echo ""
. "
Database migration required. "
. "The is_default_for_billing column is not present in {$db_prefix}config_mods. "
. "Please run the billing module update (Admin → Module Manager → Update) to apply db_version 8.
"
. "
";
return;
}
// -------------------------------------------------------------------
// Handle POST: save default mod for a game (home_cfg_id)
// -------------------------------------------------------------------
$saveMsg = '';
if (isset($_POST['save_default']) && isset($_POST['home_cfg_id'])) {
$save_home_cfg_id = intval($_POST['home_cfg_id']);
$save_mod_cfg_id = intval($_POST['mod_cfg_id'] ?? 0);
// Clear all current defaults for this game first
$db->query(
"UPDATE `{$db_prefix}config_mods`
SET is_default_for_billing = 0
WHERE home_cfg_id = " . $save_home_cfg_id
);
if ($save_mod_cfg_id > 0) {
// Set the selected mod as default (only if it belongs to this game)
$updated = $db->query(
"UPDATE `{$db_prefix}config_mods`
SET is_default_for_billing = 1
WHERE mod_cfg_id = " . $save_mod_cfg_id . "
AND home_cfg_id = " . $save_home_cfg_id
);
$saveMsg = $updated
? "Default mod/build updated for game config #{$save_home_cfg_id}.
"
: "Failed to update default — mod may not belong to this game.
";
} else {
$saveMsg = "Default cleared for game config #{$save_home_cfg_id}. Billing will use the service-specific mod or fail with an admin-visible error if none is set.
";
}
}
echo $saveMsg;
echo "Game Mod/Build Defaults for Billing
";
echo "Mark one mod/build per game as the auto-install default used when billing provisions a new server. "
. "This is used when a billing service does not specify its own mod (mod_cfg_id = 0).
";
echo "Priority order during provisioning: "
. "1) Service-specific mod_cfg_id → 2) is_default_for_billing here → "
. "3) Single available mod (auto-selected) → 4) Fail with admin-visible error.
";
// -------------------------------------------------------------------
// Load all game configs that have at least one mod defined
// -------------------------------------------------------------------
$games = $db->resultQuery(
"SELECT ch.home_cfg_id, ch.home_name
FROM `{$db_prefix}config_homes` ch
WHERE EXISTS (
SELECT 1 FROM `{$db_prefix}config_mods` cm
WHERE cm.home_cfg_id = ch.home_cfg_id
)
ORDER BY ch.home_name ASC"
);
if (empty($games)) {
echo "No game configurations with mods found. Add mods via Admin → Game Manager → Configure Games.
";
return;
}
echo "";
echo "| Game | home_cfg_id | Available Mods/Builds | Current Default | Action |
";
foreach ((array)$games as $game) {
$hcfgid = intval($game['home_cfg_id']);
$gameName = htmlspecialchars($game['home_name'] ?? "Game #{$hcfgid}");
// Load mods for this game
$mods = $db->resultQuery(
"SELECT mod_cfg_id, mod_key, mod_name, is_default_for_billing
FROM `{$db_prefix}config_mods`
WHERE home_cfg_id = " . $hcfgid . "
ORDER BY mod_name ASC"
);
if (empty($mods)) {
continue;
}
$currentDefault = null;
foreach ($mods as $m) {
if (!empty($m['is_default_for_billing'])) {
$currentDefault = htmlspecialchars($m['mod_name'] . ' (mod_cfg_id=' . $m['mod_cfg_id'] . ')');
}
}
echo "";
echo "| {$gameName} | ";
echo "{$hcfgid} | ";
echo "";
$modNames = array_map(fn($m) => htmlspecialchars($m['mod_name']), $mods);
echo implode(' ', $modNames);
echo " | ";
echo "";
echo $currentDefault
? "✓ " . $currentDefault . ""
: "None";
echo " | ";
echo "";
// Form to set default
echo "";
echo " | ";
echo "
";
}
echo "
";
// -------------------------------------------------------------------
// Show billing_services with their current mod_cfg_id
// -------------------------------------------------------------------
echo "";
echo "
Billing Services — Mod/Build Override
";
echo "
Services below have an explicit mod_cfg_id set. This takes priority over the game default above. "
. "Set to 0 to fall back to the game default.
";
$services = $db->resultQuery(
"SELECT s.service_id, s.service_name, s.home_cfg_id, s.mod_cfg_id,
ch.home_name AS game_name,
cm.mod_name
FROM `{$db_prefix}billing_services` s
LEFT JOIN `{$db_prefix}config_homes` ch ON ch.home_cfg_id = s.home_cfg_id
LEFT JOIN `{$db_prefix}config_mods` cm ON cm.mod_cfg_id = s.mod_cfg_id
ORDER BY s.service_name ASC"
);
if (empty($services)) {
echo "
No billing services configured.
";
} else {
echo "
";
echo "| Service | Game | Current mod_cfg_id | Mod Name |
";
foreach ((array)$services as $svc) {
echo "";
echo "| ".htmlspecialchars($svc['service_name'] ?? '')." (#".intval($svc['service_id']).") | ";
echo "".htmlspecialchars($svc['game_name'] ?? 'N/A')." | ";
echo "".intval($svc['mod_cfg_id']).(intval($svc['mod_cfg_id']) === 0 ? " (use game default)" : "")." | ";
echo "".htmlspecialchars($svc['mod_name'] ?? ($svc['mod_cfg_id'] == 0 ? '—' : 'mod not found'))." | ";
echo "
";
}
echo "
";
echo "
To change a service's mod, edit it in Admin → Billing → Services.
";
}
echo "
";
}
?>