fixed bad links

This commit is contained in:
Frank Harris 2026-06-15 20:04:55 -05:00
parent b585aec260
commit 7e9a45f014
79 changed files with 2395 additions and 0 deletions

View file

@ -0,0 +1,506 @@
<?php
declare(strict_types=1);
require_once __DIR__ . '/paths.php';
if (defined('GSP_WEBSITE_BOOTSTRAPPED')) {
return;
}
define('GSP_WEBSITE_BOOTSTRAPPED', true);
error_reporting(E_ALL);
ini_set('display_errors', '0');
$websiteConfig = [];
$websiteConfigFiles = [
WEBSITE_CONFIG_DIR . '/config.php',
WEBSITE_CONFIG_DIR . '/config.local.php',
];
foreach ($websiteConfigFiles as $configFile) {
if (!is_readable($configFile)) {
continue;
}
$loaded = require $configFile;
if (is_array($loaded)) {
$websiteConfig = array_replace_recursive($websiteConfig, $loaded);
}
}
$websiteDefaults = [
'site_name' => 'Gameservers.World',
'site_tagline' => 'Virtual private game servers with dedicated resources and full configuration access.',
'meta_description' => 'Virtual private game servers with dedicated resources, predictable performance, full configuration access, mod support, and real human support.',
'base_path' => null,
'public_base_url' => null,
'billing_base_url' => '/billing',
'panel_url' => 'https://panel.iaregamer.com/',
'login_url' => 'https://panel.iaregamer.com/',
'discord_url' => null,
'support_url' => null,
'support_email' => null,
'admin_notice' => 'Server catalog is currently unavailable. Please contact support.',
'locations' => [
['name' => 'Los Angeles, USA', 'region' => 'West Coast coverage', 'host' => 'la-game-1.iaregamer.com'],
['name' => 'Kansas City, USA', 'region' => 'Central US coverage', 'host' => 'kc-game-2.iaregamer.com'],
['name' => 'Dallas, USA', 'region' => 'Southern US coverage', 'host' => 'dal-game-1.iaregamer.com'],
['name' => 'New York City, USA', 'region' => 'East Coast coverage', 'host' => 'nyc-game-1.iaregamer.com'],
['name' => 'Dublin, Ireland', 'region' => 'EU coverage', 'host' => 'dub-game-1.iaregamer.com'],
],
];
$websiteConfig = array_replace_recursive($websiteDefaults, $websiteConfig);
function website_config(?string $key = null, mixed $default = null): mixed
{
global $websiteConfig;
if ($key === null) {
return $websiteConfig;
}
return $websiteConfig[$key] ?? $default;
}
function website_log(string $message): void
{
error_log('[website] ' . $message);
}
function website_escape(mixed $value): string
{
return htmlspecialchars((string)$value, ENT_QUOTES, 'UTF-8');
}
function website_normalize_base_path(?string $path): string
{
$path = trim((string)$path);
if ($path === '' || $path === '/') {
return '';
}
return '/' . trim($path, '/');
}
function website_request_scheme(): string
{
$https = $_SERVER['HTTPS'] ?? '';
if ($https !== '' && strtolower((string)$https) !== 'off') {
return 'https';
}
$forwarded = $_SERVER['HTTP_X_FORWARDED_PROTO'] ?? '';
if ($forwarded !== '') {
return strtolower((string)$forwarded) === 'https' ? 'https' : 'http';
}
return 'http';
}
function website_base_path(): string
{
static $basePath = null;
if ($basePath !== null) {
return $basePath;
}
$configured = website_config('base_path');
if (is_string($configured) && $configured !== '') {
$basePath = website_normalize_base_path($configured);
return $basePath;
}
$scriptName = (string)($_SERVER['SCRIPT_NAME'] ?? '');
if ($scriptName === '') {
$basePath = '';
return $basePath;
}
$dir = str_replace('\\', '/', dirname($scriptName));
$basePath = ($dir === '/' || $dir === '.' || $dir === '') ? '' : website_normalize_base_path($dir);
return $basePath;
}
function website_public_base_url(): string
{
static $baseUrl = null;
if ($baseUrl !== null) {
return $baseUrl;
}
$configured = trim((string)website_config('public_base_url', ''));
if ($configured !== '') {
$baseUrl = rtrim($configured, '/');
return $baseUrl;
}
$host = trim((string)($_SERVER['HTTP_HOST'] ?? ''));
if ($host === '') {
$baseUrl = '';
return $baseUrl;
}
$baseUrl = website_request_scheme() . '://' . $host . website_base_path();
return $baseUrl;
}
function website_url(string $path = ''): string
{
$basePath = rtrim(website_base_path(), '/');
$path = ltrim($path, '/');
if ($path === '') {
return $basePath === '' ? '/' : $basePath . '/';
}
return ($basePath === '' ? '' : $basePath) . '/' . $path;
}
function website_asset(string $path): string
{
return website_url('assets/' . ltrim($path, '/'));
}
function website_join_external_url(string $base, string $path = ''): string
{
$base = trim($base);
if ($base === '') {
return website_url($path);
}
$base = rtrim($base, '/');
$path = ltrim($path, '/');
if ($path === '') {
return $base . '/';
}
return $base . '/' . $path;
}
function panel_url(string $path = ''): string
{
return website_join_external_url((string)website_config('panel_url', ''), $path);
}
function login_url(string $path = ''): string
{
return website_join_external_url((string)website_config('login_url', website_config('panel_url', '')), $path);
}
function billing_url(string $path = ''): string
{
return website_join_external_url((string)website_config('billing_base_url', ''), $path);
}
function documentation_url(?string $docSlug = null): string
{
if ($docSlug === null || $docSlug === '') {
return website_url('docs.php');
}
return website_url('docs.php?doc=' . rawurlencode($docSlug));
}
function website_canonical_url(string $path = ''): string
{
$base = website_public_base_url();
if ($base === '') {
return website_url($path);
}
$path = ltrim($path, '/');
if ($path === '') {
return $base . '/';
}
return rtrim($base, '/') . '/' . $path;
}
function website_read_php_assignments(string $filePath, array $variableNames): array
{
if (!is_readable($filePath)) {
return [];
}
$content = @file_get_contents($filePath);
if ($content === false) {
return [];
}
$result = [];
foreach ($variableNames as $variableName) {
$patternDouble = '/^\s*\$' . preg_quote($variableName, '/') . '\s*=\s*"([^"]*)"/m';
$patternSingle = '/^\s*\$' . preg_quote($variableName, '/') . "\s*=\s*'([^']*)'/m";
if (preg_match($patternDouble, $content, $match) === 1 || preg_match($patternSingle, $content, $match) === 1) {
$result[$variableName] = $match[1];
}
}
return $result;
}
function website_database_settings(): ?array
{
static $settings = null;
static $resolved = false;
if ($resolved) {
return $settings;
}
$resolved = true;
$keys = ['db_host', 'db_port', 'db_user', 'db_pass', 'db_name', 'table_prefix', 'db_type'];
$merged = [];
$panelConfig = WEBSITE_PANEL_INCLUDE_DIR . '/config.inc.php';
if (is_readable($panelConfig)) {
$merged = array_replace($merged, website_read_php_assignments($panelConfig, $keys));
}
$billingConfig = WEBSITE_BILLING_ROOT . '/includes/config.inc.php';
if (is_readable($billingConfig)) {
$merged = array_replace($merged, website_read_php_assignments($billingConfig, $keys));
}
foreach (['db_host', 'db_user', 'db_name', 'table_prefix'] as $requiredKey) {
if (empty($merged[$requiredKey])) {
$settings = null;
return $settings;
}
}
$settings = $merged;
return $settings;
}
function website_billing_config_present(): bool
{
return is_readable(WEBSITE_BILLING_ROOT . '/includes/config.inc.php');
}
function website_db(): ?mysqli
{
static $connection = false;
if ($connection instanceof mysqli) {
return $connection;
}
if ($connection === null) {
return null;
}
$settings = website_database_settings();
if ($settings === null) {
$connection = null;
return null;
}
$port = isset($settings['db_port']) && $settings['db_port'] !== '' ? (int)$settings['db_port'] : null;
$mysqli = @mysqli_connect(
(string)$settings['db_host'],
(string)($settings['db_user'] ?? ''),
(string)($settings['db_pass'] ?? ''),
(string)$settings['db_name'],
$port
);
if (!$mysqli instanceof mysqli) {
website_log('Database connection failed for public website.');
$connection = null;
return null;
}
@mysqli_set_charset($mysqli, 'utf8mb4');
$connection = $mysqli;
return $connection;
}
function website_table_prefix(): string
{
$settings = website_database_settings();
return (string)($settings['table_prefix'] ?? '');
}
function website_billing_available(): bool
{
return website_db() instanceof mysqli;
}
function website_billing_docs_root(): ?string
{
if (is_dir(WEBSITE_BILLING_DOCS_DIR)) {
return WEBSITE_BILLING_DOCS_DIR;
}
$legacyDocs = WEBSITE_LEGACY_SITE_ROOT . '/docs';
if (is_dir($legacyDocs)) {
return $legacyDocs;
}
return null;
}
function website_is_valid_doc_slug(string $slug): bool
{
return (bool)preg_match('/^[a-z0-9][a-z0-9_-]*$/i', $slug);
}
function website_doc_path(string $slug, string $fileName = 'index.php'): ?string
{
if (!website_is_valid_doc_slug($slug)) {
return null;
}
$docsRoot = website_billing_docs_root();
if ($docsRoot === null) {
return null;
}
$candidate = realpath($docsRoot . '/' . $slug . '/' . $fileName);
if ($candidate === false || strpos($candidate, realpath($docsRoot) ?: $docsRoot) !== 0) {
return null;
}
return $candidate;
}
function website_doc_icon_url(string $slug): ?string
{
foreach (['icon.png', 'icon.jpg', 'icon.jpeg', 'icon.webp'] as $fileName) {
if (website_doc_path($slug, $fileName) !== null) {
return website_url('doc_asset.php?doc=' . rawurlencode($slug) . '&file=' . rawurlencode($fileName));
}
}
return null;
}
function website_service_image_url(string $imageValue): string
{
$imageValue = trim($imageValue);
if ($imageValue === '') {
return website_asset('images/banner.png');
}
if (preg_match('#^https?://#i', $imageValue) === 1) {
return $imageValue;
}
$fileName = basename($imageValue);
if ($fileName === '') {
return website_asset('images/banner.png');
}
return website_asset('images/games/' . $fileName);
}
function website_fetch_services(int $limit = 0): array
{
$db = website_db();
if (!$db instanceof mysqli) {
return [];
}
$prefix = website_table_prefix();
if ($prefix === '') {
return [];
}
$sql = "SELECT bs.service_id,
bs.service_name,
bs.description,
bs.img_url,
bs.price_monthly,
bs.remote_server_id,
ch.game_name AS cfg_game_name,
ch.game_key AS cfg_game_key,
ch.home_cfg_file AS cfg_file
FROM `{$prefix}billing_services` bs
LEFT JOIN `{$prefix}config_homes` ch ON ch.home_cfg_id = bs.home_cfg_id
WHERE bs.enabled = 1
AND bs.remote_server_id <> ''
AND bs.remote_server_id IS NOT NULL
ORDER BY bs.service_name ASC";
if ($limit > 0) {
$sql .= ' LIMIT ' . max(1, $limit);
}
$result = @$db->query($sql);
if (!$result instanceof mysqli_result) {
website_log('Failed to query billing services for website catalog.');
return [];
}
$rows = [];
while ($row = $result->fetch_assoc()) {
$rows[] = $row;
}
$result->free();
return $rows;
}
function website_fetch_doc_index(): array
{
$docsRoot = website_billing_docs_root();
if ($docsRoot === null || !is_dir($docsRoot)) {
return [];
}
$entries = [];
foreach (array_diff(scandir($docsRoot) ?: [], ['.', '..']) as $folder) {
$docFolder = $docsRoot . '/' . $folder;
if (!is_dir($docFolder)) {
continue;
}
$indexPath = website_doc_path($folder, 'index.php');
$metadataPath = website_doc_path($folder, 'metadata.json');
if ($indexPath === null || $metadataPath === null) {
continue;
}
$metadataContent = @file_get_contents($metadataPath);
$metadataContent = $metadataContent === false ? '' : preg_replace('/^\xEF\xBB\xBF/', '', $metadataContent);
$metadata = json_decode((string)$metadataContent, true);
if (!is_array($metadata)) {
$metadata = [];
}
$entries[] = [
'slug' => $folder,
'name' => (string)($metadata['name'] ?? ucwords(str_replace(['-', '_'], ' ', $folder))),
'description' => (string)($metadata['description'] ?? ''),
'category' => (string)($metadata['category'] ?? 'other'),
'order' => (int)($metadata['order'] ?? 999),
'complete' => (bool)($metadata['complete'] ?? true),
'icon_url' => website_doc_icon_url($folder),
];
}
usort(
$entries,
static function (array $left, array $right): int {
if ($left['category'] !== $right['category']) {
return strcmp($left['category'], $right['category']);
}
if ($left['order'] !== $right['order']) {
return $left['order'] <=> $right['order'];
}
return strcasecmp($left['name'], $right['name']);
}
);
return $entries;
}
function website_render(string $pageTemplate, array $context = []): void
{
extract($context, EXTR_SKIP);
require WEBSITE_INCLUDE_DIR . '/header.php';
require WEBSITE_ROOT_DIR . '/pages/' . $pageTemplate;
require WEBSITE_INCLUDE_DIR . '/footer.php';
}