MediaWiki:Common.js: Difference between revisions

From Survival Servers
Jump to navigation Jump to search
No edit summary
(Fix regex escapes and add StarRupture)
 
(One intermediate revision by the same user not shown)
Line 234: Line 234:
         // Stationeers
         // Stationeers
         'stationeers': { name: 'Stationeers', slug: 'stationeers', dbname: 'stationeers' },
         'stationeers': { name: 'Stationeers', slug: 'stationeers', dbname: 'stationeers' },
        // StarRupture
        'starrupture': { name: 'StarRupture', slug: 'starrupture', dbname: 'starrupture' },


         // Terraria
         // Terraria

Latest revision as of 11:36, 5 January 2026

/**
 * SurvivalServers Wiki - Game Server Banner System v5.4
 * Dark theme with gold accents matching main site design
 * Includes affiliate tracking: trckaff=3881, trckit=WIKI<PageName>
 * Fixed dbnames: ark (ASA), citadel, empyriongalacticsurvival, rune2
 * Smart linking: order form if pricing exists, service page if not
 */
(function() {
    'use strict';

    var TRACK_AFF_ID = '3881';
    var MAX_TRCKIT_LENGTH = 41;
    var API_URL = 'https://www.survivalservers.com/includes/wiki_pricing_api.php';
    var LOGO_URL = 'https://www.survivalservers.com/themes/epona/images/logo.png';
    var GAME_ICON_BASE = 'https://www.survivalservers.com/themes/epona/images/sspanel/game-server-icons-sm/';

    // SVG Icons (inline so no external library needed)
    var ICONS = {
        bolt: '<svg style="width:14px;height:14px;margin-right:5px;vertical-align:middle;" viewBox="0 0 320 512" fill="rgb(219,155,21)"><path d="M296 160H180.6l42.6-129.8C227.2 15 215.7 0 200 0H56C44 0 33.8 8.9 32.2 20.8l-32 240C-1.7 275.2 9.5 288 24 288h118.7L96.6 482.5c-3.6 15.2 8 29.5 23.3 29.5 8.4 0 16.4-4.4 20.8-12l176-304c9.3-15.9-2.2-36-20.7-36z"/></svg>',
        sliders: '<svg style="width:14px;height:14px;margin-right:5px;vertical-align:middle;" viewBox="0 0 512 512" fill="rgb(219,155,21)"><path d="M496 384H160v-16c0-8.8-7.2-16-16-16h-32c-8.8 0-16 7.2-16 16v16H16c-8.8 0-16 7.2-16 16v32c0 8.8 7.2 16 16 16h80v16c0 8.8 7.2 16 16 16h32c8.8 0 16-7.2 16-16v-16h336c8.8 0 16-7.2 16-16v-32c0-8.8-7.2-16-16-16zm0-160h-80v-16c0-8.8-7.2-16-16-16h-32c-8.8 0-16 7.2-16 16v16H16c-8.8 0-16 7.2-16 16v32c0 8.8 7.2 16 16 16h336v16c0 8.8 7.2 16 16 16h32c8.8 0 16-7.2 16-16v-16h80c8.8 0 16-7.2 16-16v-32c0-8.8-7.2-16-16-16zm0-160H288V48c0-8.8-7.2-16-16-16h-32c-8.8 0-16 7.2-16 16v16H16C7.2 64 0 71.2 0 80v32c0 8.8 7.2 16 16 16h208v16c0 8.8 7.2 16 16 16h32c8.8 0 16-7.2 16-16v-16h208c8.8 0 16-7.2 16-16V80c0-8.8-7.2-16-16-16z"/></svg>',
        rocket: '<svg style="width:14px;height:14px;margin-right:5px;vertical-align:middle;" viewBox="0 0 512 512" fill="rgb(219,155,21)"><path d="M505.12019,19.09375c-1.18945-5.53125-6.65819-11-12.207-12.1875C460.716,0,435.507,0,410.40747,0,307.17523,0,245.26909,55.20312,199.05238,128H94.83772c-16.34763,0-31.08301,9.59375-37.69531,24.5L3.14257,262.5C-.87883,270.625-1.03822,280.28125,2.67739,288.5s11.31445,14.5,19.69531,14.5H131.0701L93.43994,340.65625c-15.64063,15.625-15.64063,40.96875,0,56.59375,15.6289,15.625,40.97656,15.625,56.60547,0L187.92919,360H256v128c0,17.67188,14.32617,32,32,32s32-14.32812,32-32V303.0625c74.38477-46.03125,128-108.75,128-212.09375C448,70.59375,447.84058,50.1875,505.12019,19.09375Z"/></svg>',
        cart: '<svg style="width:14px;height:14px;margin-right:6px;vertical-align:middle;" viewBox="0 0 576 512" fill="currentColor"><path d="M528.12 301.319l47.273-208C578.806 78.301 567.391 64 551.99 64H159.208l-9.166-44.81C147.758 8.021 137.93 0 126.529 0H24C10.745 0 0 10.745 0 24v16c0 13.255 10.745 24 24 24h69.883l70.248 343.435C147.325 417.1 136 435.222 136 456c0 30.928 25.072 56 56 56s56-25.072 56-56c0-15.674-6.447-29.835-16.824-40h209.647C430.447 426.165 424 440.326 424 456c0 30.928 25.072 56 56 56s56-25.072 56-56c0-22.172-12.888-41.332-31.579-50.405l5.517-24.276c3.413-15.018-8.002-29.319-23.403-29.319H218.117l-6.545-32h293.145c11.206 0 20.92-7.754 23.403-18.681z"/></svg>',
        gamepad: '<svg style="width:16px;height:16px;margin-right:6px;vertical-align:middle;" viewBox="0 0 640 512" fill="currentColor"><path d="M480 96H160C71.6 96 0 167.6 0 256s71.6 160 160 160c44.8 0 85.2-18.4 114.2-48h91.5c29 29.6 69.5 48 114.2 48 88.4 0 160-71.6 160-160S568.4 96 480 96zM256 276c0 6.6-5.4 12-12 12h-52v52c0 6.6-5.4 12-12 12h-40c-6.6 0-12-5.4-12-12v-52H76c-6.6 0-12-5.4-12-12v-40c0-6.6 5.4-12 12-12h52v-52c0-6.6 5.4-12 12-12h40c6.6 0 12 5.4 12 12v52h52c6.6 0 12 5.4 12 12v40zm184 68c-26.5 0-48-21.5-48-48s21.5-48 48-48 48 21.5 48 48-21.5 48-48 48zm80-80c-26.5 0-48-21.5-48-48s21.5-48 48-48 48 21.5 48 48-21.5 48-48 48z"/></svg>'
    };

    var gameConfig = {
        // 7 Days to Die - including common abbreviation "7D2D"
        '7daystodie': { name: '7 Days to Die', slug: '7_days_to_die', dbname: 'sevendays' },
        '7days': { name: '7 Days to Die', slug: '7_days_to_die', dbname: 'sevendays' },
        '7d2d': { name: '7 Days to Die', slug: '7_days_to_die', dbname: 'sevendays' },

        // ARK: Survival Evolved - including PS4 variants and colon variations
        'ark': { name: 'ARK: Survival Evolved', slug: 'ark_survival_evolved', dbname: 'ark' },
        'ark:': { name: 'ARK: Survival Evolved', slug: 'ark_survival_evolved', dbname: 'ark' },
        'ark ps4': { name: 'ARK: Survival Evolved', slug: 'ark_survival_evolved', dbname: 'ark' },
        'arkps4': { name: 'ARK: Survival Evolved', slug: 'ark_survival_evolved', dbname: 'ark' },
        'ark: survival evolved': { name: 'ARK: Survival Evolved', slug: 'ark_survival_evolved', dbname: 'ark' },
        'ark:survival evolved': { name: 'ARK: Survival Evolved', slug: 'ark_survival_evolved', dbname: 'ark' },
        'arkon': { name: 'ARK: Survival Evolved', slug: 'ark_survival_evolved', dbname: 'ark' },
        'beacon': { name: 'ARK: Survival Evolved', slug: 'ark_survival_evolved', dbname: 'ark' },

        // ARK: Survival Ascended
        'arksurvivalascended': { name: 'ARK: Survival Ascended', slug: 'ark_survival_ascended', dbname: 'ark' },
        'asa': { name: 'ARK: Survival Ascended', slug: 'ark_survival_ascended', dbname: 'ark' },

        // Arma series
        'arma': { name: 'Arma 3', slug: 'arma3', dbname: 'arma3' },
        'arma 2': { name: 'Arma 3', slug: 'arma3', dbname: 'arma3' },
        'arma 3': { name: 'Arma 3', slug: 'arma3', dbname: 'arma3' },
        'arma3': { name: 'Arma 3', slug: 'arma3', dbname: 'arma3' },
        'arma reforger': { name: 'Arma Reforger', slug: 'arma_reforger', dbname: 'armareforger' },
        'epoch': { name: 'Arma 3', slug: 'arma3', dbname: 'arma3' },
        'exile': { name: 'Arma 3', slug: 'arma3', dbname: 'arma3' },
        'altis': { name: 'Arma 3', slug: 'arma3', dbname: 'arma3' },
        'wasteland': { name: 'Arma 3', slug: 'arma3', dbname: 'arma3' },
        'overpoch': { name: 'Arma 3', slug: 'arma3', dbname: 'arma3' },
        'pbo': { name: 'Arma 3', slug: 'arma3', dbname: 'arma3' },
        'infistar': { name: 'Arma 3', slug: 'arma3', dbname: 'arma3' },

        // Atlas
        'atlas': { name: 'Atlas', slug: 'atlas', dbname: 'atlas' },

        // Avorion
        'avorion': { name: 'Avorion', slug: 'avorion', dbname: 'avorion' },

        // Barotrauma
        'barotrauma': { name: 'Barotrauma', slug: 'barotrauma', dbname: 'barotrauma' },
        'barotrauam': { name: 'Barotrauma', slug: 'barotrauma', dbname: 'barotrauma' },

        // Battalion 1944
        'battalion': { name: 'Battalion 1944', slug: 'battalion_1944', dbname: 'battalion1944' },
        'battalion 1944': { name: 'Battalion 1944', slug: 'battalion_1944', dbname: 'battalion1944' },

        // Brickadia
        'brickadia': { name: 'Brickadia', slug: 'brickadia', dbname: 'brickadia' },

        // Citadel: Forged With Fire
        'citadel': { name: 'Citadel: Forged With Fire', slug: 'citadel_forged_with_fire', dbname: 'citadel' },

        // Conan Exiles
        'conan': { name: 'Conan Exiles', slug: 'conan_exiles', dbname: 'conanexiles' },
        'conanexiles': { name: 'Conan Exiles', slug: 'conan_exiles', dbname: 'conanexiles' },
        'conan exiles': { name: 'Conan Exiles', slug: 'conan_exiles', dbname: 'conanexiles' },

        // Core Keeper
        'corekeeper': { name: 'Core Keeper', slug: 'core_keeper', dbname: 'corekeeper' },
        'core keeper': { name: 'Core Keeper', slug: 'core_keeper', dbname: 'corekeeper' },

        // Counter-Strike 2 / CS2 / CSGO
        'csgo': { name: 'CS2', slug: 'counter_strike_2', dbname: 'csgo' },
        'cs2': { name: 'CS2', slug: 'counter_strike_2', dbname: 'csgo' },
        'counterstrike': { name: 'CS2', slug: 'counter_strike_2', dbname: 'csgo' },
        'counter strike': { name: 'CS2', slug: 'counter_strike_2', dbname: 'csgo' },
        'counter-strike': { name: 'CS2', slug: 'counter_strike_2', dbname: 'csgo' },

        // Dark and Light
        'dark and light': { name: 'Dark and Light', slug: 'dark_and_light', dbname: 'darkandlight' },
        'darkandlight': { name: 'Dark and Light', slug: 'dark_and_light', dbname: 'darkandlight' },

        // Day of Dragons
        'day of dragons': { name: 'Day of Dragons', slug: 'day_of_dragons', dbname: 'dayofdragons' },
        'dayofdragons': { name: 'Day of Dragons', slug: 'day_of_dragons', dbname: 'dayofdragons' },

        // DayZ
        'dayz': { name: 'DayZ', slug: 'dayz', dbname: 'dayz' },

        // Dead Matter
        'deadmatter': { name: 'Dead Matter', slug: 'dead_matter', dbname: 'deadmatter' },
        'dead matter': { name: 'Dead Matter', slug: 'dead_matter', dbname: 'deadmatter' },

        // Don't Starve Together
        'dontstarve': { name: "Don't Starve Together", slug: 'dont_starve_together', dbname: 'dontstarvetogether' },
        "don't starve": { name: "Don't Starve Together", slug: 'dont_starve_together', dbname: 'dontstarvetogether' },

        // Eco
        'eco': { name: 'Eco', slug: 'eco', dbname: 'eco' },

        // Empyrion
        'empyrion': { name: 'Empyrion', slug: 'empyrion_galactic_survival', dbname: 'empyriongalacticsurvival' },

        // Enshrouded
        'enshrouded': { name: 'Enshrouded', slug: 'enshrouded', dbname: 'enshrouded' },

        // Factorio
        'factorio': { name: 'Factorio', slug: 'factorio', dbname: 'factorio' },

        // FiveM / RedM
        'fivem': { name: 'FiveM', slug: 'grand_theft_auto_5', dbname: 'fivem' },
        'redm': { name: 'RedM', slug: 'red_dead_redemption', dbname: 'redm' },

        // Foundry
        'foundry': { name: 'Foundry', slug: 'foundry', dbname: 'foundry' },

        // Frozen Flame
        'frozen flame': { name: 'Frozen Flame', slug: 'frozen_flame', dbname: 'frozenflame' },
        'frozenflame': { name: 'Frozen Flame', slug: 'frozen_flame', dbname: 'frozenflame' },

        // Holdfast
        'holdfast': { name: 'Holdfast: Nations At War', slug: 'holdfast', dbname: 'holdfast' },

        // Hurtworld
        'hurtworld': { name: 'Hurtworld', slug: 'hurtworld', dbname: 'hurtworld' },

        // Hytale
        'hytale': { name: 'Hytale', slug: 'hytale', dbname: 'hytale' },

        // Icarus
        'icarus': { name: 'Icarus', slug: 'icarus', dbname: 'icarus' },

        // Last Oasis
        'last oasis': { name: 'Last Oasis', slug: 'last_oasis', dbname: 'lastoasis' },
        'lastoasis': { name: 'Last Oasis', slug: 'last_oasis', dbname: 'lastoasis' },

        // Left 4 Dead 2
        'left4dead': { name: 'Left 4 Dead 2', slug: 'left_4_dead_2', dbname: 'left4dead2' },
        'l4d2': { name: 'Left 4 Dead 2', slug: 'left_4_dead_2', dbname: 'left4dead2' },

        // Minecraft - including mods and tools
        'minecraft': { name: 'Minecraft', slug: 'minecraft', dbname: 'minecraft' },
        'mcrcon': { name: 'Minecraft', slug: 'minecraft', dbname: 'minecraft' },
        'craftbukkit': { name: 'Minecraft', slug: 'minecraft', dbname: 'minecraft' },
        'pixelmon': { name: 'Minecraft', slug: 'minecraft', dbname: 'minecraft' },

        // Miscreated
        'miscreated': { name: 'Miscreated', slug: 'miscreated', dbname: 'miscreated' },

        // Mordhau
        'mordhau': { name: 'Mordhau', slug: 'mordhau', dbname: 'mordhau' },

        // Mount & Blade 2: Bannerlord
        'bannerlord': { name: 'Mount & Blade 2: Bannerlord', slug: 'mount_and_blade_2_bannerlord', dbname: 'bannerlord' },

        // Myth of Empires
        'myth of empires': { name: 'Myth of Empires', slug: 'myth_of_empires', dbname: 'mythofempires' },
        'mythofempires': { name: 'Myth of Empires', slug: 'myth_of_empires', dbname: 'mythofempires' },

        // Nightingale
        'nightingale': { name: 'Nightingale', slug: 'nightingale', dbname: 'nightingale' },

        // No One Survived
        'no one survived': { name: 'No One Survived', slug: 'no_one_survived', dbname: 'noonesurvived' },
        'noonesurvived': { name: 'No One Survived', slug: 'no_one_survived', dbname: 'noonesurvived' },

        // Palworld
        'palworld': { name: 'Palworld', slug: 'palworld', dbname: 'palworld' },

        // Path of Titans
        'path of titans': { name: 'Path of Titans', slug: 'path_of_titans', dbname: 'pathoftitans' },
        'pathoftitans': { name: 'Path of Titans', slug: 'path_of_titans', dbname: 'pathoftitans' },

        // PixARK
        'pixark': { name: 'PixARK', slug: 'pixark', dbname: 'pixark' },

        // Project Zomboid
        'projectzomboid': { name: 'Project Zomboid', slug: 'project_zomboid', dbname: 'projectzomboid' },
        'zomboid': { name: 'Project Zomboid', slug: 'project_zomboid', dbname: 'projectzomboid' },
        'project zomboid': { name: 'Project Zomboid', slug: 'project_zomboid', dbname: 'projectzomboid' },

        // Rend
        'rend': { name: 'Rend', slug: 'rend', dbname: 'rend' },

        // Renown
        'renown': { name: 'Renown', slug: 'renown', dbname: 'renown' },

        // Rust
        'rust': { name: 'Rust', slug: 'rust', dbname: 'rust' },
        'rusty': { name: 'Rust', slug: 'rust', dbname: 'rust' },
        'oxide': { name: 'Rust', slug: 'rust', dbname: 'rust' },

        // Satisfactory
        'satisfactory': { name: 'Satisfactory', slug: 'satisfactory', dbname: 'satisfactory' },

        // SCUM
        'scum': { name: 'SCUM', slug: 'scum', dbname: 'scum' },

        // Sons of the Forest
        'sonsoftheforest': { name: 'Sons of the Forest', slug: 'sons_of_the_forest', dbname: 'sonsoftheforest' },
        'sons of the forest': { name: 'Sons of the Forest', slug: 'sons_of_the_forest', dbname: 'sonsoftheforest' },
        'sons of forest': { name: 'Sons of the Forest', slug: 'sons_of_the_forest', dbname: 'sonsoftheforest' },

        // Soulmask
        'soulmask': { name: 'Soulmask', slug: 'soulmask', dbname: 'soulmask' },

        // Space Engineers
        'spaceengineers': { name: 'Space Engineers', slug: 'space_engineers', dbname: 'spaceengineers' },
        'space engineers': { name: 'Space Engineers', slug: 'space_engineers', dbname: 'spaceengineers' },

        // Squad
        'squad': { name: 'Squad', slug: 'squad', dbname: 'squad' },

        // Starbound
        'starbound': { name: 'Starbound', slug: 'starbound', dbname: 'starbound' },

        // Stationeers
        'stationeers': { name: 'Stationeers', slug: 'stationeers', dbname: 'stationeers' },

        // StarRupture
        'starrupture': { name: 'StarRupture', slug: 'starrupture', dbname: 'starrupture' },

        // Terraria
        'terraria': { name: 'Terraria', slug: 'terraria', dbname: 'terraria' },

        // The Forest
        'theforest': { name: 'The Forest', slug: 'the_forest', dbname: 'theforest' },
        'forest': { name: 'The Forest', slug: 'the_forest', dbname: 'theforest' },
        'the forest': { name: 'The Forest', slug: 'the_forest', dbname: 'theforest' },

        // The Front
        'the front': { name: 'The Front', slug: 'the_front', dbname: 'thefront' },
        'thefront': { name: 'The Front', slug: 'the_front', dbname: 'thefront' },

        // The Isle
        'theisle': { name: 'The Isle', slug: 'the_isle', dbname: 'theisle' },
        'isle': { name: 'The Isle', slug: 'the_isle', dbname: 'theisle' },
        'the isle': { name: 'The Isle', slug: 'the_isle', dbname: 'theisle' },

        // Unturned
        'unturned': { name: 'Unturned', slug: 'unturned', dbname: 'unturned' },

        // V Rising
        'v rising': { name: 'V Rising', slug: 'v_rising', dbname: 'vrising' },
        'vrising': { name: 'V Rising', slug: 'v_rising', dbname: 'vrising' },

        // Valheim
        'valheim': { name: 'Valheim', slug: 'valheim', dbname: 'valheim' },
        'valheim plus': { name: 'Valheim', slug: 'valheim', dbname: 'valheim' },
        'valheimplus': { name: 'Valheim', slug: 'valheim', dbname: 'valheim' },

        // Vein
        'vein': { name: 'Vein', slug: 'vein', dbname: 'vein' },

        // Ylands
        'ylands': { name: 'Ylands', slug: 'ylands', dbname: 'ylands' },

        // Abiotic Factor
        'abiotic': { name: 'Abiotic Factor', slug: 'abiotic_factor', dbname: 'abioticfactor' },
        'abiotic factor': { name: 'Abiotic Factor', slug: 'abiotic_factor', dbname: 'abioticfactor' },

        // Aloft
        'aloft': { name: 'Aloft', slug: 'aloft', dbname: 'aloft' },

        // Assetto Corsa
        'assettocorsa': { name: 'Assetto Corsa', slug: 'assetto_corsa', dbname: 'assettocorsa' },
        'assetto': { name: 'Assetto Corsa', slug: 'assetto_corsa', dbname: 'assettocorsa' },

        // ASKA
        'aska': { name: 'ASKA', slug: 'aska', dbname: 'aska' },

        // Cube World
        'cube world': { name: 'Cube World', slug: 'cube_world', dbname: 'cubeworld' },
        'cubeworld': { name: 'Cube World', slug: 'cube_world', dbname: 'cubeworld' },

        // Rune / Rune 2
        'rune': { name: 'Rune: Ragnarok', slug: 'rune_ragnarok', dbname: 'rune2' },
        'rune 2': { name: 'Rune: Ragnarok', slug: 'rune_ragnarok', dbname: 'rune2' },

        // Subnautica
        'subnautica': { name: 'Subnautica', slug: 'subnautica', dbname: 'subnautica' },

        // Torch (Rust-related)
        'torch': { name: 'Rust', slug: 'rust', dbname: 'rust' }
    };

    function getPageName() {
        var urlParams = new URLSearchParams(window.location.search);
        var title = urlParams.get('title');
        if (!title) {
            var path = window.location.pathname;
            var match = path.match(/\/wiki\/(.+)$/);
            if (match) title = decodeURIComponent(match[1]);
        }
        if (!title) {
            var heading = document.getElementById('firstHeading');
            if (heading) title = heading.textContent;
        }
        if (title) {
            title = title.replace(/[^a-zA-Z0-9]/g, '_').replace(/_+/g, '_').substring(0, MAX_TRCKIT_LENGTH);
        }
        return title || 'Unknown';
    }

    function buildTrackingUrl(baseUrl, pageName) {
        var separator = baseUrl.indexOf('?') === -1 ? '?' : '&';
        return baseUrl + separator + 'trckaff=' + TRACK_AFF_ID + '&trckit=WIKI' + pageName;
    }

    function detectGame() {
        var pageTitle = document.title.toLowerCase();
        var bodyContent = document.getElementById('bodyContent');

        var manualGame = document.querySelector('[data-ss-game]');
        if (manualGame) return manualGame.getAttribute('data-ss-game').toLowerCase();

        var content = bodyContent ? bodyContent.innerHTML : '';
        var markerMatch = content.match(/<!--\s*SSGAME:\s*(\w+)\s*-->/i);
        if (markerMatch) return markerMatch[1].toLowerCase();

        var keywords = Object.keys(gameConfig).sort(function(a, b) { return b.length - a.length; });
        for (var i = 0; i < keywords.length; i++) {
            if (pageTitle.indexOf(keywords[i]) !== -1) return keywords[i];
        }
        return null;
    }

    function fetchPricing(gameSlug, callback) {
        var xhr = new XMLHttpRequest();
        xhr.open('GET', API_URL + '?game=' + encodeURIComponent(gameSlug), true);
        xhr.onreadystatechange = function() {
            if (xhr.readyState === 4) {
                if (xhr.status === 200) {
                    try {
                        var data = JSON.parse(xhr.responseText);
                        callback(data);
                    } catch (e) {
                        callback(null);
                    }
                } else {
                    callback(null);
                }
            }
        };
        xhr.send();
    }

    function createGameBanner(gameKey, pageName, pricingData) {
        var game = gameConfig[gameKey];
        if (!game) return null;
        // If pricing data exists, link to order form; otherwise link to service page
        var orderUrl = pricingData && pricingData.lowestPrice
            ? 'https://www.survivalservers.com/sspanel/?game=' + game.dbname
            : 'https://www.survivalservers.com/services/game_servers/' + game.slug + '/';
        var trackingUrl = buildTrackingUrl(orderUrl, pageName);
        var gameIconUrl = GAME_ICON_BASE + game.dbname + '.png';

        var priceHtml = '';
        if (pricingData && pricingData.lowestPrice) {
            if (pricingData.discount && pricingData.discountedPrice && pricingData.coupon) {
                priceHtml = '<span style="display: inline-flex; align-items: center; vertical-align: middle;">' +
                    '<span style="color: rgba(255,255,255,0.7); margin: 0 12px;">|</span>' +
                    '<span style="background: #00aa55; color: #fff; padding: 2px 8px; border-radius: 3px; font-size: 12px; font-weight: 700; display: inline-flex; align-items: center;">Use code ' + pricingData.coupon + ' for ' + pricingData.discount + '% OFF</span>' +
                    '<span style="color: rgba(255,255,255,0.5); margin: 0 8px;"></span>' +
                    '<span style="color: #888; text-decoration: line-through; font-size: 13px; display: inline-flex; align-items: center;">$' + pricingData.lowestPrice + '</span>' +
                    '<span style="color: #00ff88; font-weight: 700; margin-left: 6px; display: inline-flex; align-items: center;">$' + pricingData.discountedPrice + '/mo</span>' +
                '</span>';
            } else {
                priceHtml = '<span style="display: inline-flex; align-items: center; vertical-align: middle;">' +
                    '<span style="color: rgba(255,255,255,0.7); margin: 0 12px;">|</span>' +
                    '<span style="color: #00ff88; font-weight: 700; display: inline-flex; align-items: center;">From $' + pricingData.lowestPrice + '/mo</span>' +
                '</span>';
            }
        }

        var banner = document.createElement('div');
        banner.id = 'ss-game-banner';
        banner.innerHTML = '<div style="background: #1a1a1a; border-radius: 6px; padding: 0; margin: 0 0 20px 0; box-shadow: 0 2px 10px rgba(0,0,0,0.5); overflow: hidden; border: 2px solid rgb(219, 155, 21);">' +
            '<div style="padding: 16px 25px; display: flex; align-items: center; justify-content: space-between; flex-wrap: wrap; gap: 15px;">' +
                '<div style="display: flex; align-items: center; gap: 18px; flex: 1; min-width: 280px;">' +
                    '<a href="' + buildTrackingUrl('https://www.survivalservers.com/', pageName) + '" style="flex-shrink: 0; display: flex; align-items: center;"><img src="' + LOGO_URL + '" alt="SurvivalServers" style="height: 32px; width: auto; vertical-align: middle;"></a>' +
                    '<div style="height: 28px; width: 1px; background: rgba(255,255,255,0.2);"></div>' +
                    '<div style="display: flex; align-items: center; gap: 10px;">' +
                        '<img src="' + gameIconUrl + '" alt="" style="width: 28px; height: 28px; border-radius: 4px; vertical-align: middle;" onerror="this.style.display=\'none\'">' +
                        '<span style="color: rgb(219, 155, 21); font-weight: 600; font-size: 15px; display: inline-flex; align-items: center;">' + game.name + ' Server Hosting</span>' +
                    '</div>' +
                    priceHtml +
                '</div>' +
                '<div style="display: flex; align-items: center; gap: 20px;">' +
                    '<div style="color: rgba(255,255,255,0.8); font-size: 13px; display: flex; align-items: center; gap: 12px;">' +
                        '<span style="display: inline-flex; align-items: center;">' + ICONS.bolt + 'High Performance</span>' +
                        '<span style="color: rgba(255,255,255,0.4);">&#8226;</span>' +
                        '<span style="display: inline-flex; align-items: center;">' + ICONS.sliders + 'Custom Control Panel</span>' +
                        '<span style="color: rgba(255,255,255,0.4);">&#8226;</span>' +
                        '<span style="display: inline-flex; align-items: center;">' + ICONS.rocket + 'Instant Setup</span>' +
                    '</div>' +
                    '<a href="' + trackingUrl + '" style="background: rgb(219, 155, 21); color: #1a1a1a; padding: 10px 28px; border-radius: 4px; text-decoration: none; font-weight: 700; font-size: 14px; display: inline-flex; align-items: center; gap: 8px; transition: all 0.2s ease; white-space: nowrap;" onmouseover="this.style.background=\'rgb(239, 175, 41)\';this.style.transform=\'translateY(-1px)\';" onmouseout="this.style.background=\'rgb(219, 155, 21)\';this.style.transform=\'translateY(0)\';">' +
                        ICONS.cart + 'Order Now' +
                    '</a>' +
                '</div>' +
            '</div>' +
        '</div>';
        return banner;
    }

    function createGenericBanner(pageName, pricingData) {
        var trackingUrl = buildTrackingUrl('https://www.survivalservers.com/', pageName);

        var couponHtml = '';
        if (pricingData && pricingData.discount && pricingData.coupon) {
            couponHtml = '<span style="display: inline-flex; align-items: center; vertical-align: middle;">' +
                '<span style="color: rgba(255,255,255,0.7); margin: 0 12px;">|</span>' +
                '<span style="background: #00aa55; color: #fff; padding: 2px 8px; border-radius: 3px; font-size: 12px; font-weight: 700; display: inline-flex; align-items: center;">Use code ' + pricingData.coupon + ' for ' + pricingData.discount + '% OFF</span>' +
            '</span>';
        }

        var banner = document.createElement('div');
        banner.id = 'ss-game-banner';
        banner.innerHTML = '<div style="background: #1a1a1a; border-radius: 6px; padding: 0; margin: 0 0 20px 0; box-shadow: 0 2px 10px rgba(0,0,0,0.5); overflow: hidden; border: 2px solid rgb(219, 155, 21);">' +
            '<div style="padding: 16px 25px; display: flex; align-items: center; justify-content: space-between; flex-wrap: wrap; gap: 15px;">' +
                '<div style="display: flex; align-items: center; gap: 18px; flex: 1; min-width: 280px;">' +
                    '<a href="' + trackingUrl + '" style="flex-shrink: 0; display: flex; align-items: center;"><img src="' + LOGO_URL + '" alt="SurvivalServers" style="height: 32px; width: auto; vertical-align: middle;"></a>' +
                    '<div style="height: 28px; width: 1px; background: rgba(255,255,255,0.2);"></div>' +
                    '<span style="color: rgb(219, 155, 21); font-weight: 600; font-size: 15px; display: inline-flex; align-items: center;">Premium Game Server Hosting</span>' +
                    '<span style="color: rgba(255,255,255,0.7); margin: 0 8px; display: inline-flex; align-items: center;">|</span>' +
                    '<span style="color: rgba(255,255,255,0.9); font-size: 14px; display: inline-flex; align-items: center;">100+ Games Available</span>' +
                    couponHtml +
                '</div>' +
                '<div style="display: flex; align-items: center; gap: 20px;">' +
                    '<div style="color: rgba(255,255,255,0.8); font-size: 13px; display: flex; align-items: center; gap: 12px;">' +
                        '<span style="display: inline-flex; align-items: center;">' + ICONS.bolt + 'High Performance</span>' +
                        '<span style="color: rgba(255,255,255,0.4);">&#8226;</span>' +
                        '<span style="display: inline-flex; align-items: center;">' + ICONS.sliders + 'Custom Control Panel</span>' +
                        '<span style="color: rgba(255,255,255,0.4);">&#8226;</span>' +
                        '<span style="display: inline-flex; align-items: center;">' + ICONS.rocket + 'Instant Setup</span>' +
                    '</div>' +
                    '<a href="' + trackingUrl + '" style="background: rgb(219, 155, 21); color: #1a1a1a; padding: 10px 28px; border-radius: 4px; text-decoration: none; font-weight: 700; font-size: 14px; display: inline-flex; align-items: center; gap: 8px; transition: all 0.2s ease; white-space: nowrap;" onmouseover="this.style.background=\'rgb(239, 175, 41)\';this.style.transform=\'translateY(-1px)\';" onmouseout="this.style.background=\'rgb(219, 155, 21)\';this.style.transform=\'translateY(0)\';">' +
                        ICONS.gamepad + 'Browse Games' +
                    '</a>' +
                '</div>' +
            '</div>' +
        '</div>';
        return banner;
    }

    function insertBanner(banner) {
        if (!banner) return;
        var contentDiv = document.getElementById('bodyContent');
        if (contentDiv) contentDiv.insertBefore(banner, contentDiv.firstChild);
    }

    function updateExistingLinks(pageName) {
        // Find all links to survivalservers.com and add/fix tracking params
        var links = document.querySelectorAll('a[href*="survivalservers.com"]');
        for (var i = 0; i < links.length; i++) {
            var link = links[i];
            var href = link.getAttribute('href');

            // Skip if it's our banner (we already add tracking there)
            if (link.closest('#ss-game-banner')) continue;

            // Check if link has incomplete trckit=WIKI (without page name)
            // Match trckit=WIKI at end of string or followed by & or nothing after
            if (href.match(/trckit=WIKI(&|$)/)) {
                // Replace incomplete trckit with full page name
                href = href.replace(/trckit=WIKI(&|$)/, 'trckit=WIKI' + pageName + '$1');
                link.setAttribute('href', href);
                continue;
            }

            // Skip if already has complete tracking params
            if (href.indexOf('trckaff=') !== -1) continue;

            // Add tracking params
            var separator = href.indexOf('?') === -1 ? '?' : '&';
            link.setAttribute('href', href + separator + 'trckaff=' + TRACK_AFF_ID + '&trckit=WIKI' + pageName);
        }
    }

    function init() {
        var pageTitle = document.title;
        if (pageTitle.indexOf('Main Page') !== -1) return;
        if (window.location.href.indexOf('Special:') !== -1) return;

        var pageName = getPageName();
        var gameKey = detectGame();
        var game = gameKey ? gameConfig[gameKey] : null;

        // Update existing links on the page with tracking params
        updateExistingLinks(pageName);

        if (game) {
            fetchPricing(game.dbname, function(pricingData) {
                var banner = createGameBanner(gameKey, pageName, pricingData);
                insertBanner(banner);
            });
        } else {
            fetchPricing('', function(pricingData) {
                var banner = createGenericBanner(pageName, pricingData);
                insertBanner(banner);
            });
        }
    }

    if (document.readyState === 'loading') {
        document.addEventListener('DOMContentLoaded', init);
    } else {
        init();
    }
})();