<?php
require_once __DIR__ . '/../utils/Config.php'; require_once SRC_PATH . '/models/Upgrade.php'; require_once SRC_PATH . '/classes/LanguageController.php'; class UpgradeManager { private $db; private $gameState; public function __construct($db, $gameState) { $this->db = $db; $this->gameState = $gameState; $this->initializeUpgradesIfNeeded(); } public function initializeUpgradesIfNeeded() { $result = $this->db->query("SELECT COUNT(*) as count FROM upgrades")->fetch(); if ($result['count'] == 0) { $this->initializeUpgrades(); } else { $this->ensureMiningUpgrades(); $this->ensureToolsUpgrades(); } } public function initializeUpgrades() { $this->db->query( "INSERT INTO upgrades (name, type, level, max_level, base_cost, release_year, description, effects)
            VALUES (?, ?, ?, ?, ?, ?, ?, ?)", [ t("game.upgrades.types.shared_hosting"), Upgrade::TYPE_HOSTING, 1, 5, 1000, 2000, t("game.upgrades.descriptions.shared_hosting"), json_encode([ 'capacity' => 100, 'speed' => 10, 'monthly_cost' => 0.001 ]) ] ); $this->db->query( "INSERT INTO upgrades (name, type, level, max_level, base_cost, release_year, description, effects)
            VALUES (?, ?, ?, ?, ?, ?, ?, ?)", [ t("game.upgrades.types.dedicated_server"), Upgrade::TYPE_DEDICATED_SERVER, 0, 5, 10000, 2003, t("game.upgrades.descriptions.dedicated_server"), json_encode([ 'capacity' => 1000, 'speed' => 100, 'monthly_cost' => 0.01 ]) ] ); $hostingAddons = [ [ 'name' => t("game.upgrades.types.load_balancer"), 'release_year' => 2002, 'cost' => 5000, 'description' => t("game.upgrades.descriptions.load_balancer"), 'effects' => json_encode([ 'capacity' => 100, 'satisfaction' => 0.1 ]) ], [ 'name' => t("game.upgrades.types.bandwidth_booster"), 'release_year' => 2002, 'cost' => 3000, 'description' => t("game.upgrades.descriptions.bandwidth_booster"), 'effects' => json_encode([ 'speed' => 50, 'satisfaction' => 0.1 ]) ], [ 'name' => t("game.upgrades.types.ai_analyzer"), 'release_year' => 2008, 'cost' => 8000, 'description' => t("game.upgrades.descriptions.ai_analyzer"), 'effects' => json_encode([ 'visitors' => 50, 'satisfaction' => 0.2 ]) ], [ 'name' => t("game.upgrades.types.cdn"), 'release_year' => 2006, 'cost' => 7500, 'description' => t("game.upgrades.descriptions.cdn"), 'effects' => json_encode([ 'capacity' => 200, 'visitors' => 100 ]) ] ]; foreach ($hostingAddons as $addon) { $this->db->query( "INSERT INTO upgrades (name, type, level, max_level, base_cost, release_year, description, effects)
                VALUES (?, ?, ?, ?, ?, ?, ?, ?)", [ $addon['name'], Upgrade::TYPE_HOSTING_ADDON, 0, 1, $addon['cost'], $addon['release_year'], $addon['description'], $addon['effects'] ] ); } $securityUpgrades = [ [ 'name' => t("game.upgrades.types.vpn_layer"), 'release_year' => 2001, 'cost' => 5000, 'max_level' => 1, 'description' => t("game.upgrades.descriptions.vpn_layer"), 'effects' => json_encode([ 'attention_reduction' => 0.2 ]) ], [ 'name' => t("game.upgrades.types.decoy_site"), 'release_year' => 2004, 'cost' => 3000, 'max_level' => 1, 'description' => t("game.upgrades.descriptions.decoy_site"), 'effects' => json_encode([ 'attention_reduction' => 0.1 ]) ], [ 'name' => t("game.upgrades.types.firewall_upgrade"), 'release_year' => 2002, 'cost' => 4000, 'max_level' => 1, 'description' => t("game.upgrades.descriptions.firewall_upgrade"), 'effects' => json_encode([ 'attack_reduction' => 0.5 ]) ], [ 'name' => t("game.upgrades.types.honeypot"), 'release_year' => 2007, 'cost' => 10000, 'max_level' => 1, 'description' => t("game.upgrades.descriptions.honeypot"), 'effects' => json_encode([ 'attention_reset' => 50 ]) ], [ 'name' => t("game.upgrades.types.encryption"), 'release_year' => 2003, 'cost' => 7500, 'max_level' => 1, 'description' => t("game.upgrades.descriptions.encryption"), 'effects' => json_encode([ 'daily_attention_reduction' => 1 ]) ] ]; foreach ($securityUpgrades as $upgrade) { $this->db->query( "INSERT INTO upgrades (name, type, level, max_level, base_cost, release_year, description, effects)
                VALUES (?, ?, ?, ?, ?, ?, ?, ?)", [ $upgrade['name'], Upgrade::TYPE_SECURITY, 0, $upgrade['max_level'], $upgrade['cost'], $upgrade['release_year'], $upgrade['description'], $upgrade['effects'] ] ); } $toolsUpgrades = [ [ 'name' => t("game.upgrades.types.ad_revenue_booster"), 'release_year' => 2001, 'cost' => 2000, 'max_level' => 1, 'description' => t("game.upgrades.descriptions.ad_revenue_booster"), 'effects' => json_encode([ 'ad_revenue_boost' => 0.2 ]) ], [ 'name' => t("game.upgrades.types.auto_crack"), 'release_year' => 2005, 'cost' => 5000, 'max_level' => 1, 'description' => t("game.upgrades.descriptions.auto_crack"), 'effects' => json_encode([ 'auto_crack_stage_1' => true ]) ], [ 'name' => t("game.upgrades.types.auto_defense_basic"), 'release_year' => 2003, 'cost' => 3000, 'max_level' => 1, 'description' => t("game.upgrades.descriptions.auto_defense_basic"), 'effects' => json_encode([ 'auto_defense_chance' => 0.30 ]) ], [ 'name' => t("game.upgrades.types.auto_defense_advanced"), 'release_year' => 2004, 'cost' => 6000, 'max_level' => 1, 'description' => t("game.upgrades.descriptions.auto_defense_advanced"), 'effects' => json_encode([ 'auto_defense_chance' => 0.50 ]) ], [ 'name' => t("game.upgrades.types.auto_defense_pro"), 'release_year' => 2007, 'cost' => 12000, 'max_level' => 1, 'description' => t("game.upgrades.descriptions.auto_defense_pro"), 'effects' => json_encode([ 'auto_defense_chance' => 0.85 ]) ] ]; foreach ($toolsUpgrades as $upgrade) { $this->db->query( "INSERT INTO upgrades (name, type, level, max_level, base_cost, release_year, description, effects)
                VALUES (?, ?, ?, ?, ?, ?, ?, ?)", [ $upgrade['name'], Upgrade::TYPE_TOOLS, 0, $upgrade['max_level'], $upgrade['cost'], $upgrade['release_year'], $upgrade['description'], $upgrade['effects'] ] ); } $internetUpgrades = [ [ 'name' => t("game.upgrades.types.speed_16"), 'release_year' => 2002, 'cost' => 2000, 'max_level' => 1, 'description' => t("game.upgrades.descriptions.speed_16"), 'effects' => json_encode([ 'speed' => 16, 'upload_boost' => 0.1 ]) ], [ 'name' => t("game.upgrades.types.speed_24"), 'release_year' => 2004, 'cost' => 4000, 'max_level' => 1, 'description' => t("game.upgrades.descriptions.speed_24"), 'effects' => json_encode([ 'speed' => 24, 'upload_boost' => 0.15 ]) ], [ 'name' => t("game.upgrades.types.speed_50"), 'release_year' => 2006, 'cost' => 8000, 'max_level' => 1, 'description' => t("game.upgrades.descriptions.speed_50"), 'effects' => json_encode([ 'speed' => 50, 'upload_boost' => 0.25 ]) ], [ 'name' => t("game.upgrades.types.speed_100"), 'release_year' => 2008, 'cost' => 15000, 'max_level' => 1, 'description' => t("game.upgrades.descriptions.speed_100"), 'effects' => json_encode([ 'speed' => 100, 'upload_boost' => 0.4 ]) ], [ 'name' => t("game.upgrades.types.speed_250"), 'release_year' => 2010, 'cost' => 25000, 'max_level' => 1, 'description' => t("game.upgrades.descriptions.speed_250"), 'effects' => json_encode([ 'speed' => 250, 'upload_boost' => 0.6 ]) ] ]; foreach ($internetUpgrades as $upgrade) { $this->db->query( "INSERT INTO upgrades (name, type, level, max_level, base_cost, release_year, description, effects)
                VALUES (?, ?, ?, ?, ?, ?, ?, ?)", [ $upgrade['name'], Upgrade::TYPE_INTERNET, 0, $upgrade['max_level'], $upgrade['cost'], $upgrade['release_year'], $upgrade['description'], $upgrade['effects'] ] ); } $storageUpgrades = [ [ 'name' => t("game.upgrades.types.storage_5gb"), 'release_year' => 2000, 'cost' => 500, 'description' => t("game.upgrades.descriptions.storage_5gb"), 'effects' => json_encode([ 'capacity' => 5 ]) ], [ 'name' => t("game.upgrades.types.storage_10gb"), 'release_year' => 2002, 'cost' => 1000, 'description' => t("game.upgrades.descriptions.storage_10gb"), 'effects' => json_encode([ 'capacity' => 10 ]) ], [ 'name' => t("game.upgrades.types.storage_20gb"), 'release_year' => 2004, 'cost' => 2500, 'description' => t("game.upgrades.descriptions.storage_20gb"), 'effects' => json_encode([ 'capacity' => 20 ]) ], [ 'name' => t("game.upgrades.types.storage_50gb"), 'release_year' => 2005, 'cost' => 5000, 'description' => t("game.upgrades.descriptions.storage_50gb"), 'effects' => json_encode([ 'capacity' => 50 ]) ], [ 'name' => t("game.upgrades.types.storage_75gb"), 'release_year' => 2008, 'cost' => 8000, 'description' => t("game.upgrades.descriptions.storage_75gb"), 'effects' => json_encode([ 'capacity' => 75 ]) ], [ 'name' => t("game.upgrades.types.storage_100gb"), 'release_year' => 2009, 'cost' => 12000, 'description' => t("game.upgrades.descriptions.storage_100gb"), 'effects' => json_encode([ 'capacity' => 100 ]) ] ]; foreach ($storageUpgrades as $upgrade) { $this->db->query( "INSERT INTO upgrades (name, type, level, max_level, base_cost, release_year, description, effects)
                VALUES (?, ?, ?, ?, ?, ?, ?, ?)", [ $upgrade['name'], Upgrade::TYPE_UPLOAD_STORAGE, 0, 1, $upgrade['cost'], $upgrade['release_year'], $upgrade['description'], $upgrade['effects'] ] ); } $websiteUpgrades = [ [ 'name' => t("game.upgrades.types.community_forum"), 'release_year' => 2002, 'cost' => 5000, 'description' => t("game.upgrades.descriptions.community_forum"), 'effects' => json_encode([ 'visitors' => 50, 'satisfaction' => 0.1 ]) ], [ 'name' => t("game.upgrades.types.request_system"), 'release_year' => 2003, 'cost' => 3000, 'description' => t("game.upgrades.descriptions.request_system"), 'effects' => json_encode([ 'visitors' => 50, 'satisfaction' => 0.1 ]) ], [ 'name' => t("game.upgrades.types.mirror_sites"), 'release_year' => 2004, 'cost' => 8000, 'description' => t("game.upgrades.descriptions.mirror_sites"), 'effects' => json_encode([ 'visitors' => 50, 'satisfaction' => 0.1 ]) ], [ 'name' => t("game.upgrades.types.fake_reviews"), 'release_year' => 2001, 'cost' => 2000, 'description' => t("game.upgrades.descriptions.fake_reviews"), 'effects' => json_encode([ 'visitors' => 50, 'satisfaction' => 0.1 ]) ] ]; foreach ($websiteUpgrades as $upgrade) { $this->db->query( "INSERT INTO upgrades (name, type, level, max_level, base_cost, release_year, description, effects)
                VALUES (?, ?, ?, ?, ?, ?, ?, ?)", [ $upgrade['name'], Upgrade::TYPE_WEBSITE, 0, 1, $upgrade['cost'], $upgrade['release_year'], $upgrade['description'], $upgrade['effects'] ] ); } $marketingUpgrades = [ [ 'name' => t("game.upgrades.types.ads_campaign"), 'release_year' => 2001, 'cost' => 3000, 'max_level' => 5, 'description' => t("game.upgrades.descriptions.ads_campaign"), 'effects' => json_encode([ 'visitors' => 100, 'attention' => 5 ]) ], [ 'name' => t("game.upgrades.types.referral_program"), 'release_year' => 2004, 'cost' => 5000, 'description' => t("game.upgrades.descriptions.referral_program"), 'effects' => json_encode([ 'visitors' => 100 ]) ], [ 'name' => t("game.upgrades.types.seo_tools"), 'release_year' => 2006, 'cost' => 8000, 'description' => t("game.upgrades.descriptions.seo_tools"), 'effects' => json_encode([ 'visitors' => 200 ]) ] ]; foreach ($marketingUpgrades as $upgrade) { $this->db->query( "INSERT INTO upgrades (name, type, level, max_level, base_cost, release_year, description, effects)
                VALUES (?, ?, ?, ?, ?, ?, ?, ?)", [ $upgrade['name'], Upgrade::TYPE_MARKETING, 0, $upgrade['max_level'] ?? 1, $upgrade['cost'], $upgrade['release_year'], $upgrade['description'], $upgrade['effects'] ] ); } $this->ensureMiningUpgrades(); } private function ensureMiningUpgrades() { $exists = $this->db->query("SELECT COUNT(*) as c FROM upgrades WHERE type = ?", [Upgrade::TYPE_MINING])->fetch(PDO::FETCH_ASSOC); if ($exists && intval($exists['c']) > 0) { return; } $this->db->query( "INSERT INTO upgrades (name, type, level, max_level, base_cost, release_year, description, effects)
            VALUES (?, ?, 0, 1, ?, ?, ?, ?)", [ t("game.upgrades.types.mining_software"), Upgrade::TYPE_MINING, 2500, 2002, t("game.upgrades.descriptions.mining_software"), json_encode([ 'mining_unlocked' => true ]) ] ); $this->db->query( "INSERT INTO upgrades (name, type, level, max_level, base_cost, release_year, description, effects)
            VALUES (?, ?, 0, 5, ?, ?, ?, ?)", [ t("game.upgrades.types.mining_yield_booster"), Upgrade::TYPE_MINING, 3000, 2002, t("game.upgrades.descriptions.mining_yield_booster"), json_encode([ 'mining_yield_multiplier_per_level' => 0.10 ]) ] ); $this->db->query( "INSERT INTO upgrades (name, type, level, max_level, base_cost, release_year, description, effects)
            VALUES (?, ?, 0, 5, ?, ?, ?, ?)", [ t("game.upgrades.types.mining_scan_optimizer"), Upgrade::TYPE_MINING, 2000, 2002, t("game.upgrades.descriptions.mining_scan_optimizer"), json_encode([ 'scan_cost_reduction_per_level' => 0.05 ]) ] ); $this->db->query( "INSERT INTO upgrades (name, type, level, max_level, base_cost, release_year, description, effects)
            VALUES (?, ?, 0, 5, ?, ?, ?, ?)", [ t("game.upgrades.types.mining_stability_suite"), Upgrade::TYPE_MINING, 3500, 2003, t("game.upgrades.descriptions.mining_stability_suite"), json_encode([ 'loss_chance_reduction_per_level' => 0.02 ]) ] ); $this->db->query( "INSERT INTO upgrades (name, type, level, max_level, base_cost, release_year, description, effects)
            VALUES (?, ?, 0, 5, ?, ?, ?, ?)", [ t("game.upgrades.types.mining_installer_pro"), Upgrade::TYPE_MINING, 1500, 2002, t("game.upgrades.descriptions.mining_installer_pro"), json_encode([ 'install_time_reduction_per_level' => 0.10 ]) ] ); } private function ensureToolsUpgrades() { $exists = $this->db->query( "SELECT COUNT(*) as c FROM upgrades WHERE type = ? AND effects LIKE ?", [Upgrade::TYPE_TOOLS, '%auto_crack_stage_1%'] )->fetch(PDO::FETCH_ASSOC); if ($exists && intval($exists['c']) > 0) { return; } $vpnExists = $this->db->query( "SELECT COUNT(*) as c FROM upgrades WHERE type = ? AND name LIKE ?", [Upgrade::TYPE_TOOLS, '%VPN%'] )->fetch(PDO::FETCH_ASSOC); if (!$vpnExists || intval($vpnExists['c']) == 0) { $this->db->query( "INSERT INTO upgrades (name, type, level, max_level, base_cost, release_year, description, effects)
                VALUES (?, ?, 0, 1, ?, ?, ?, ?)", [ 'VPN Protection Package', Upgrade::TYPE_TOOLS, 500, 2024, 'Advanced VPN service that reduces trace accumulation during VDS missions. Each activation provides 30 trace reductions (2 commands = 1 trace instead of 1:1).', json_encode([ 'vpn_protection' => true, 'trace_reduction' => 0.5, 'capacity' => 30 ]) ] ); } $adBoosterExists = $this->db->query( "SELECT COUNT(*) as c FROM upgrades WHERE type = ? AND effects LIKE ?", [Upgrade::TYPE_TOOLS, '%ad_revenue_boost%'] )->fetch(PDO::FETCH_ASSOC); if (!$adBoosterExists || intval($adBoosterExists['c']) == 0) { $this->db->query( "INSERT INTO upgrades (name, type, level, max_level, base_cost, release_year, description, effects)
                VALUES (?, ?, 0, 1, ?, ?, ?, ?)", [ t("game.upgrades.types.ad_revenue_booster"), Upgrade::TYPE_TOOLS, 2000, 2001, t("game.upgrades.descriptions.ad_revenue_booster"), json_encode([ 'ad_revenue_boost' => 0.2 ]) ] ); } $this->db->query( "INSERT INTO upgrades (name, type, level, max_level, base_cost, release_year, description, effects)
            VALUES (?, ?, 0, 1, ?, ?, ?, ?)", [ t("game.upgrades.types.auto_crack"), Upgrade::TYPE_TOOLS, 5000, 2005, t("game.upgrades.descriptions.auto_crack"), json_encode([ 'auto_crack_stage_1' => true ]) ] ); $this->db->query( "INSERT INTO upgrades (name, type, level, max_level, base_cost, release_year, description, effects)
            VALUES (?, ?, 0, 1, ?, ?, ?, ?)", [ t("game.upgrades.types.auto_defense_basic"), Upgrade::TYPE_TOOLS, 3000, 2003, t("game.upgrades.descriptions.auto_defense_basic"), json_encode([ 'auto_defense_chance' => 0.30 ]) ] ); $this->db->query( "INSERT INTO upgrades (name, type, level, max_level, base_cost, release_year, description, effects)
            VALUES (?, ?, 0, 1, ?, ?, ?, ?)", [ t("game.upgrades.types.auto_defense_advanced"), Upgrade::TYPE_TOOLS, 6000, 2004, t("game.upgrades.descriptions.auto_defense_advanced"), json_encode([ 'auto_defense_chance' => 0.50 ]) ] ); $this->db->query( "INSERT INTO upgrades (name, type, level, max_level, base_cost, release_year, description, effects)
            VALUES (?, ?, 0, 1, ?, ?, ?, ?)", [ t("game.upgrades.types.auto_defense_pro"), Upgrade::TYPE_TOOLS, 12000, 2007, t("game.upgrades.descriptions.auto_defense_pro"), json_encode([ 'auto_defense_chance' => 0.85 ]) ] ); } public function getAvailableUpgrades() { $query = "
            SELECT u.*
            FROM upgrades u
            JOIN (
                SELECT type, name, MAX(id) as max_id
                FROM upgrades
                GROUP BY type, name
            ) as unique_upgrades
            ON u.id = unique_upgrades.max_id
            ORDER BY u.type, u.release_year, u.base_cost
        "; $allUpgrades = $this->db->query($query)->fetchAll(PDO::FETCH_ASSOC); $gameYear = $this->gameState['current_year']; $categorizedUpgrades = [ 'hosting' => [], 'dedicated_server' => [], 'hosting_addon' => [], 'security' => [], 'tools' => [], 'internet' => [], 'upload_storage' => [], 'website' => [], 'marketing' => [], 'mining' => [] ]; $currentHostingLevel = isset($this->gameState['hosting_level']) ? $this->gameState['hosting_level'] : 0; $currentDedicatedLevel = isset($this->gameState['dedicated_server']) ? $this->gameState['dedicated_server'] : 0; $hostingAdded = false; $dedicatedAdded = false; $miningUnlockedRow = $this->db->query( "SELECT COUNT(*) as c FROM upgrades WHERE type = ? AND effects LIKE ? AND (acquired = 1 OR level > 0)", [Upgrade::TYPE_MINING, '%mining_unlocked%'] )->fetch(PDO::FETCH_ASSOC); $miningUnlocked = ($miningUnlockedRow && intval($miningUnlockedRow['c']) > 0); foreach ($allUpgrades as $upgradeData) { $upgrade = new Upgrade($upgradeData); $type = $upgrade->getType(); $isFutureUpgrade = $upgrade->getReleaseYear() > $gameYear; $isMaxedOut = $upgrade->getLevel() >= $upgrade->getMaxLevel(); $isOneTimeAndAcquired = $upgrade->isOneTime() && $upgrade->isAcquired(); if ($type === Upgrade::TYPE_HOSTING) { if ($currentDedicatedLevel > 0) { continue; } if ($currentHostingLevel >= $upgrade->getMaxLevel()) { continue; } if (!$hostingAdded) { $nextLevel = $currentHostingLevel + 1; $baseCapacity = 100; $baseSpeed = 10; $baseCost = $upgrade->getBaseCost(); $cost = $baseCost * pow(2, $nextLevel - 1); $upgradeInfo = [ 'id' => $upgrade->getId(), 'name' => t("game.upgrades.types.shared_hosting"), 'description' => t("game.upgrades.info.hosting_level_description", [ 'level' => $nextLevel, 'capacity' => $baseCapacity * $nextLevel, 'speed' => $baseSpeed * $nextLevel ]), 'cost' => $cost, 'available' => !$isFutureUpgrade && $this->gameState['credits'] >= $cost, 'future' => $isFutureUpgrade, 'release_year' => $upgrade->getReleaseYear(), 'level' => $currentHostingLevel, 'max_level' => $upgrade->getMaxLevel(), 'type' => $type, 'effects' => [ 'capacity' => $baseCapacity * $nextLevel, 'speed' => $baseSpeed * $nextLevel ] ]; $categorizedUpgrades[$type][] = $upgradeInfo; $hostingAdded = true; } continue; } if ($type === Upgrade::TYPE_DEDICATED_SERVER) { if ($currentHostingLevel < 5 && $currentDedicatedLevel == 0) { continue; } if ($currentDedicatedLevel >= $upgrade->getMaxLevel()) { continue; } if (!$dedicatedAdded) { $nextLevel = $currentDedicatedLevel + 1; $baseCapacity = 1000; $baseSpeed = 100; $baseCost = $upgrade->getBaseCost(); $cost = $baseCost * ($nextLevel == 1 ? 1 : pow(2, $nextLevel - 1)); $upgradeInfo = [ 'id' => $upgrade->getId(), 'name' => t("game.upgrades.types.dedicated_server"), 'description' => t("game.upgrades.info.dedicated_level_description", [ 'level' => $nextLevel, 'capacity' => $baseCapacity * $nextLevel, 'speed' => $baseSpeed * $nextLevel ]), 'cost' => $cost, 'available' => !$isFutureUpgrade && $this->gameState['credits'] >= $cost, 'future' => $isFutureUpgrade, 'release_year' => $upgrade->getReleaseYear(), 'level' => $currentDedicatedLevel, 'max_level' => $upgrade->getMaxLevel(), 'type' => $type, 'effects' => [ 'capacity' => $baseCapacity * $nextLevel, 'speed' => $baseSpeed * $nextLevel ] ]; $categorizedUpgrades[$type][] = $upgradeInfo; $dedicatedAdded = true; } continue; } if (!$isMaxedOut && !$isOneTimeAndAcquired) { $canAfford = $this->gameState['credits'] >= $upgrade->calculateCost(); $upgradeInfo = [ 'id' => $upgrade->getId(), 'name' => $upgrade->getName(), 'description' => $upgrade->getDescription(), 'cost' => $upgrade->calculateCost(), 'available' => !$isFutureUpgrade && $canAfford && ( $type !== Upgrade::TYPE_MINING || isset($upgrade->getEffects()['mining_unlocked']) || $miningUnlocked ), 'future' => $isFutureUpgrade, 'release_year' => $upgrade->getReleaseYear(), 'level' => $upgrade->getLevel(), 'max_level' => $upgrade->getMaxLevel(), 'type' => $upgrade->getType(), 'acquired' => $upgrade->isAcquired(), 'effects' => $upgrade->getEffects() ]; if ($type === Upgrade::TYPE_MINING && isset($upgradeInfo['effects']['mining_unlocked'])) { array_unshift($categorizedUpgrades[$type], $upgradeInfo); } else { $categorizedUpgrades[$upgrade->getType()][] = $upgradeInfo; } } } return $categorizedUpgrades; } public function purchaseUpgrade($id) { $upgrade = Upgrade::getById($this->db, $id); if (!$upgrade) { return [ 'success' => false, 'message' => t("game.upgrades.purchase_failed") ]; } $cost = $upgrade->calculateCost(); $gameState = $this->db->query("SELECT * FROM game_state WHERE id = 1")->fetch(PDO::FETCH_ASSOC); $this->gameState = $gameState; if ($this->gameState['credits'] < $cost) { return [ 'success' => false, 'message' => t("game.software.insufficient_credits") ]; } if ($upgrade->getType() === Upgrade::TYPE_MINING) { $effects = $upgrade->getEffects(); $isMiningSoftware = isset($effects['mining_unlocked']); if (!$isMiningSoftware) { $miningUnlockedRow = $this->db->query( "SELECT COUNT(*) as c FROM upgrades WHERE type = ? AND effects LIKE ? AND (acquired = 1 OR level > 0)", [Upgrade::TYPE_MINING, '%mining_unlocked%'] )->fetch(PDO::FETCH_ASSOC); $miningUnlocked = ($miningUnlockedRow && intval($miningUnlockedRow['c']) > 0); if (!$miningUnlocked) { return [ 'success' => false, 'message' => '' ]; } } } if (!$upgrade->canUpgrade($this->gameState['current_year'])) { return [ 'success' => false, 'message' => t("game.upgrades.not_available") ]; } $this->db->query( "UPDATE game_state SET credits = credits - ? WHERE id = 1", [$cost] ); $effects = $upgrade->getEffects(); $currentLevel = $upgrade->getLevel(); $nextLevel = $currentLevel + 1; if ($upgrade->getType() === Upgrade::TYPE_DEDICATED_SERVER && $this->gameState['dedicated_server'] === 0) { $this->db->query( "UPDATE game_state SET dedicated_server = 1, hosting_level = 0 WHERE id = 1" ); } switch ($upgrade->getType()) { case Upgrade::TYPE_HOSTING: $this->db->query( "UPDATE game_state SET hosting_level = ? WHERE id = 1", [$nextLevel] ); $capacity = 100 * $nextLevel; $speed = 10 * $nextLevel; $monthlyCost = 0.001 * $nextLevel; $newEffects = json_encode([ 'capacity' => $capacity, 'speed' => $speed, 'monthly_cost' => $monthlyCost ]); $this->db->query( "UPDATE upgrades SET effects = ? WHERE id = ?", [$newEffects, $upgrade->getId()] ); break; case Upgrade::TYPE_DEDICATED_SERVER: $this->db->query( "UPDATE game_state SET dedicated_server = ? WHERE id = 1", [$nextLevel] ); $capacity = 1000 * $nextLevel; $speed = 100 * $nextLevel; $monthlyCost = 0.01 * $nextLevel; $newEffects = json_encode([ 'capacity' => $capacity, 'speed' => $speed, 'monthly_cost' => $monthlyCost ]); $this->db->query( "UPDATE upgrades SET effects = ? WHERE id = ?", [$newEffects, $upgrade->getId()] ); break; case Upgrade::TYPE_INTERNET: if (isset($effects['speed'])) { $this->db->query( "UPDATE game_state SET internet_speed = ? WHERE id = 1", [$effects['speed']] ); } break; case Upgrade::TYPE_UPLOAD_STORAGE: if (isset($effects['capacity'])) { $storageCapacity = $effects['capacity']; try { $this->db->query( "UPDATE game_state SET storage_capacity = ? WHERE id = 1", [$storageCapacity] ); } catch (Exception $e) { return [ 'success' => false, 'message' => t("game.upgrades.storage_update_failed", ['error' => $e->getMessage()]) ]; } } break; case Upgrade::TYPE_WEBSITE: if (isset($effects['visitor_bonus'])) { $visitorBonus = $effects['visitor_bonus']; $this->db->query( "UPDATE game_state SET current_visitors = current_visitors + ? WHERE id = 1", [$visitorBonus] ); } if (isset($effects['satisfaction_bonus'])) { $satisfactionBonus = $effects['satisfaction_bonus']; $this->db->query( "UPDATE game_state SET visitor_satisfaction = CASE
                            WHEN visitor_satisfaction + ? > 1.0 THEN 1.0
                            ELSE visitor_satisfaction + ?
                            END WHERE id = 1", [$satisfactionBonus, $satisfactionBonus] ); } break; case Upgrade::TYPE_MARKETING: if (isset($effects['visitor_bonus'])) { $visitorBonus = $effects['visitor_bonus']; $this->db->query( "UPDATE game_state SET current_visitors = current_visitors + ? WHERE id = 1", [$visitorBonus] ); } if (isset($effects['attention_bonus'])) { $attentionBonus = $effects['attention_bonus']; $this->db->query( "UPDATE game_state SET attention_level = CASE
                            WHEN attention_level + ? > 100 THEN 100
                            ELSE attention_level + ?
                            END WHERE id = 1", [$attentionBonus, $attentionBonus] ); } break; case Upgrade::TYPE_TOOLS: if (isset($effects['vpn_protection']) && $effects['vpn_protection']) { $capacity = $effects['capacity'] ?? 30; $this->db->query( "UPDATE game_state SET 
                            vpn_owned = 1, 
                            vpn_capacity = ?, 
                            vpn_max_capacity = ? 
                        WHERE id = 1", [$capacity, $capacity] ); } break; } $upgrade->upgrade(); $upgrade->save($this->db); return [ 'success' => true, 'message' => t("game.upgrades.purchase_success", ['name' => $upgrade->getName()]), 'upgrade' => [ 'id' => $upgrade->getId(), 'name' => $upgrade->getName(), 'type' => $upgrade->getType(), 'level' => $upgrade->getLevel(), 'effects' => $upgrade->getEffects() ] ]; } public function getActiveUpgrades() { $result = $this->db->query( "SELECT * FROM upgrades WHERE acquired = 1 OR level > 0" )->fetchAll(PDO::FETCH_ASSOC); $upgrades = []; foreach ($result as $data) { $upgrades[] = new Upgrade($data); } return $upgrades; } public function calculateVisitorEffects() { $activeUpgrades = $this->getActiveUpgrades(); $effects = [ 'capacity' => 0, 'base_visitors' => 0, 'satisfaction' => 1.0, 'attention_reduction' => 0, 'attention_reset' => null, 'daily_attention_reduction' => 0 ]; if ($this->gameState['hosting_level'] > 0) { $effects['capacity'] = 100 * $this->gameState['hosting_level']; } elseif ($this->gameState['dedicated_server'] > 0) { $effects['capacity'] = 1000 * $this->gameState['dedicated_server']; } else { $effects['capacity'] = 100; } foreach ($activeUpgrades as $upgrade) { $upgradeEffects = $upgrade->getEffects(); foreach ($upgradeEffects as $key => $value) { switch ($key) { case 'capacity': if ($upgrade->getType() !== 'hosting' && $upgrade->getType() !== 'dedicated_server') { $effects['capacity'] += $value; } break; case 'visitors': $effects['base_visitors'] += $value; break; case 'satisfaction': $effects['satisfaction'] += $value; break; case 'attention_reduction': $effects['attention_reduction'] += $value; break; case 'attention_reset': $effects['attention_reset'] = $value; break; case 'daily_attention_reduction': $effects['daily_attention_reduction'] += $value; break; } } } return $effects; } } 