// ---------------- Stage 12: trust/legal pages, closed beta, economy stress tests and controlled payment tests ---------------- function legal_documents(): array { return [ 'terms' => ['title'=>'Terms of Service', 'file'=>'terms.php', 'version'=>setting('legal_document_version','stage12-alpha')], 'privacy' => ['title'=>'Privacy Policy', 'file'=>'privacy.php', 'version'=>setting('legal_document_version','stage12-alpha')], 'risk' => ['title'=>'Crypto Risk Notice', 'file'=>'risk.php', 'version'=>setting('legal_document_version','stage12-alpha')], 'withdrawal' => ['title'=>'Withdrawal Policy', 'file'=>'withdrawal_policy.php', 'version'=>setting('legal_document_version','stage12-alpha')], 'no_gambling' => ['title'=>'No Gambling Policy', 'file'=>'no_gambling.php', 'version'=>setting('legal_document_version','stage12-alpha')], ]; } function legal_acceptance_status(int $userId): array { $pdo=db(); $version=(string)setting('legal_document_version','stage12-alpha'); $out=[]; foreach(array_keys(legal_documents()) as $key){ $stmt=$pdo->prepare('SELECT accepted_at FROM legal_acceptances WHERE user_id=? AND document_key=? AND version=?'); $stmt->execute([$userId,$key,$version]); $out[$key]=(string)($stmt->fetchColumn() ?: ''); } return $out; } function accept_legal_documents(int $userId, array $keys): array { $pdo=db(); $version=(string)setting('legal_document_version','stage12-alpha'); $allowed=array_keys(legal_documents()); $ip=$_SERVER['REMOTE_ADDR'] ?? ''; $ua=substr($_SERVER['HTTP_USER_AGENT'] ?? '',0,255); $stmt=$pdo->prepare('INSERT OR IGNORE INTO legal_acceptances(user_id,document_key,version,ip,user_agent,accepted_at) VALUES(?,?,?,?,?,?)'); $n=0; foreach($keys as $k){ if(in_array($k,$allowed,true)){ $stmt->execute([$userId,$k,$version,$ip,$ua,now_str()]); $n++; } } return ['ok'=>true,'message'=>'Accepted '.$n.' legal documents.']; } function beta_invite_generate(int $adminId, int $count=1, int $maxUses=1, string $note='', ?string $expiresAt=null): array { $pdo=db(); $codes=[]; $count=max(1,min(200,$count)); $maxUses=max(1,min(1000,$maxUses)); $stmt=$pdo->prepare('INSERT INTO beta_invites(code,max_uses,used_count,created_by,status,note,expires_at,created_at) VALUES(?,?,?,?,?,?,?,?)'); for($i=0;$i<$count;$i++){ $code='BETA-'.strtoupper(bin2hex(random_bytes(4))).'-'.random_int(100,999); $stmt->execute([$code,$maxUses,0,$adminId,'active',$note,$expiresAt,now_str()]); $codes[]=$code; } return $codes; } function beta_invites_list(int $limit=200): array { $stmt=db()->prepare('SELECT bi.*, u.username AS created_by_name FROM beta_invites bi LEFT JOIN users u ON u.id=bi.created_by ORDER BY bi.id DESC LIMIT ?'); $stmt->bindValue(1,$limit,PDO::PARAM_INT); $stmt->execute(); return $stmt->fetchAll() ?: []; } function beta_invite_validate(string $code): array { if ((int)setting('beta_invite_required','0') !== 1) return ['ok'=>true,'invite'=>null,'message'=>'Invite not required.']; $code=strtoupper(trim($code)); if($code==='') return ['ok'=>false,'message'=>'Beta invite code is required.']; $stmt=db()->prepare('SELECT * FROM beta_invites WHERE code=?'); $stmt->execute([$code]); $inv=$stmt->fetch(); if(!$inv) return ['ok'=>false,'message'=>'Invalid beta invite code.']; if(($inv['status'] ?? '') !== 'active') return ['ok'=>false,'message'=>'This beta invite is not active.']; if(!empty($inv['expires_at']) && strtotime($inv['expires_at']) < time()) return ['ok'=>false,'message'=>'This beta invite has expired.']; if((int)$inv['used_count'] >= (int)$inv['max_uses']) return ['ok'=>false,'message'=>'This beta invite has reached its usage limit.']; return ['ok'=>true,'invite'=>$inv,'message'=>'Invite accepted.']; } function beta_invite_redeem_for_user(string $code, int $userId): void { if((int)setting('beta_invite_required','0') !== 1 || trim($code)==='') return; $valid=beta_invite_validate($code); if(!$valid['ok']) throw new RuntimeException($valid['message']); $inv=$valid['invite']; $pdo=db(); $pdo->prepare('INSERT OR IGNORE INTO beta_invite_redemptions(invite_id,user_id,ip,device_id,created_at) VALUES(?,?,?,?,?)')->execute([(int)$inv['id'],$userId,$_SERVER['REMOTE_ADDR'] ?? '',$_COOKIE['cel_device_id'] ?? '',now_str()]); $pdo->prepare('UPDATE beta_invites SET used_count=used_count+1, status=CASE WHEN used_count+1>=max_uses THEN "used" ELSE status END WHERE id=?')->execute([(int)$inv['id']]); } function beta_dashboard_stats(): array { $pdo=db(); $one=fn($sql)=>(int)$pdo->query($sql)->fetchColumn(); return ['players'=>$one("SELECT COUNT(*) FROM users WHERE role='player'"),'active_invites'=>$one("SELECT COUNT(*) FROM beta_invites WHERE status='active'"),'used_invites'=>$one("SELECT COUNT(*) FROM beta_invite_redemptions"),'max_users'=>(int)setting('closed_beta_max_users','100'),'invite_required'=>(int)setting('beta_invite_required','0')]; } function economy_current_snapshot(): array { $pdo=db(); return [ 'resources'=>$pdo->query('SELECT name, ROUND(SUM(amount),4) AS total, ROUND(AVG(rate),4) AS avg_rate, COUNT(*) AS holders FROM resources GROUP BY name ORDER BY total DESC')->fetchAll() ?: [], 'wallets'=>$pdo->query('SELECT currency, ROUND(SUM(balance),8) AS total, COUNT(*) AS holders FROM wallets GROUP BY currency ORDER BY total DESC')->fetchAll() ?: [], 'platform_fees'=>$pdo->query('SELECT currency, ROUND(balance,8) AS balance FROM platform_wallets ORDER BY currency')->fetchAll() ?: [], 'pending_withdrawals'=>$pdo->query("SELECT currency, ROUND(SUM(amount),8) AS pending FROM withdrawals WHERE status IN ('pending','waiting_period','hold','approved_pending_api') GROUP BY currency")->fetchAll() ?: [], 'trades24'=>$pdo->query("SELECT COUNT(*) AS c, COALESCE(ROUND(SUM(gross_amount),8),0) AS volume FROM trades WHERE created_at>=datetime('now','-24 hours')")->fetch() ?: ['c'=>0,'volume'=>0] ]; } function economy_stress_recommendations(string $risk): array { if($risk==='high') return ['Increase rare item scarcity','Reduce sponsor reward multipliers','Disable automatic withdrawals during beta','Lower daily rewards','Review provider chargebacks daily']; if($risk==='medium') return ['Tighten Gold drop chance','Review marketplace fees','Lower daily reward cap','Keep 7-day wait active']; return ['Keep current beta caps','Run 7-day closed beta','Monitor provider chargebacks']; } function economy_run_stress_test(int $adminId, string $scenario='baseline', int $days=14, int $usersSample=100): array { $days=max(1,min(90,$days)); $usersSample=max(1,min(10000,$usersSample)); $snap=economy_current_snapshot(); $dailyExposure=(float)setting('economy_stress_max_daily_platform_exposure','50'); $safeWithdrawRatio=(float)setting('economy_stress_safe_withdraw_ratio','0.35'); $totalWallet=0.0; foreach($snap['wallets'] as $w){ if(($w['currency'] ?? '')!=='GUILD') $totalWallet+=(float)$w['total']; } $platform=0.0; foreach($snap['platform_fees'] as $w){ if(($w['currency'] ?? '')!=='GUILD') $platform+=(float)$w['balance']; } $projected=$totalWallet * ($scenario==='aggressive' ? 1.8 : ($scenario==='scarcity' ? 0.75 : 1.15)); $availableSafe=max(0,$platform*$safeWithdrawRatio + $dailyExposure*$days); $risk='low'; $notes=[]; if($projected>$availableSafe*3){$risk='high';$notes[]='Projected user balances exceed safe coverage by more than 3x.';} elseif($projected>$availableSafe){$risk='medium';$notes[]='Projected balances exceed conservative coverage.';} else {$notes[]='Projection is within current conservative coverage assumptions.';} $rareTotal=0.0; foreach($snap['resources'] as $r){ if(in_array($r['name'],['Gold','Gems','Energy Core','Builder License','Trade Permit'],true)) $rareTotal+=(float)$r['total']; } if($rareTotal>1000){$risk=$risk==='low'?'medium':$risk; $notes[]='Rare resource supply is high; check bottlenecks.';} $result=['snapshot'=>$snap,'scenario'=>$scenario,'days'=>$days,'users_sample'=>$usersSample,'projected_wallet_pressure'=>$projected,'available_safe_coverage'=>$availableSafe,'risk'=>$risk,'notes'=>$notes,'recommendations'=>economy_stress_recommendations($risk)]; db()->prepare('INSERT INTO stress_test_runs(scenario_key,days,users_sample,result_json,risk_level,created_by,created_at) VALUES(?,?,?,?,?,?,?)')->execute([$scenario,$days,$usersSample,json_encode($result,JSON_UNESCAPED_UNICODE),$risk,$adminId,now_str()]); return $result; } function recent_stress_tests(int $limit=20): array { $stmt=db()->prepare('SELECT * FROM stress_test_runs ORDER BY id DESC LIMIT ?'); $stmt->bindValue(1,$limit,PDO::PARAM_INT); $stmt->execute(); return $stmt->fetchAll() ?: []; } function controlled_payment_test_create(int $adminId, string $type, string $currency, float $amount, string $mode='dry_run'): array { $enabled=(int)setting('controlled_live_tests_enabled','0'); $max=(float)setting('faucetpay_test_max_amount','0.05'); $type=in_array($type,['payout','deposit_callback'],true)?$type:'payout'; $currency=strtoupper($currency); $amount=max(0,$amount); $mode=$mode==='live'?'live':'dry_run'; if($mode==='live' && !$enabled) return ['ok'=>false,'message'=>'Controlled live tests are disabled in admin settings.']; if($mode==='live' && $amount>$max) return ['ok'=>false,'message'=>'Test amount exceeds faucetpay_test_max_amount.']; $req=['type'=>$type,'currency'=>$currency,'amount'=>$amount,'mode'=>$mode,'site_mode'=>setting('site_mode','demo'),'live_payouts'=>setting('faucetpay_live_payouts_enabled','0')]; $response=['note'=>$mode==='dry_run'?'Dry-run only; no payment sent.':'Live test queued; execute only after manual verification.']; db()->prepare('INSERT INTO controlled_payment_tests(test_type,currency,amount,mode,status,request_json,response_json,created_by,created_at) VALUES(?,?,?,?,?,?,?,?,?)')->execute([$type,$currency,$amount,$mode,'created',json_encode($req,JSON_UNESCAPED_UNICODE),json_encode($response,JSON_UNESCAPED_UNICODE),$adminId,now_str()]); return ['ok'=>true,'message'=>'Controlled '.$type.' test created in '.$mode.' mode.']; } function controlled_payment_tests_recent(int $limit=30): array { $stmt=db()->prepare('SELECT cpt.*, u.username AS created_by_name FROM controlled_payment_tests cpt LEFT JOIN users u ON u.id=cpt.created_by ORDER BY cpt.id DESC LIMIT ?'); $stmt->bindValue(1,$limit,PDO::PARAM_INT); $stmt->execute(); return $stmt->fetchAll() ?: []; } function stage12_checklist(): array { return [ ['Legal pages enabled',(int)setting('legal_pages_enabled','1')===1], ['Withdraw wait days >= 7',(int)setting('withdraw_wait_days','7')>=7], ['Automatic withdrawals guarded',(string)setting('withdraw_processing_mode','manual')==='manual' || (int)setting('withdraw_auto_process_ready','0')===0], ['Cron secret exists',ensure_cron_secret()!==''], ['Backup enabled',(int)setting('backup_enabled','1')===1], ['Controlled live tests disabled by default',(int)setting('controlled_live_tests_enabled','0')===0], ['FaucetPay API key present for live tests',trim((string)setting('faucetpay_api_key',''))!==''] ]; } Crypto Empire Life - Multiplayer Crypto Economy Game
Browser MMO • Isometric 2.5D • Crypto Economy

Crypto Empire Life

Multiplayer κόσμος τύπου Sims + Age of Empires, με αγορά αγαθών σε DOGE/TRX/USDT, fees πλατφόρμας, rare resources, guilds, chat, missions και admin economy control.

MarketplaceTrade resources με crypto
ScarcityGold, permits, licenses
MultiplayerChat, guild, trade activity
AdminFees, coins, economy, payouts
Stage 12Beta, legal, stress tests

Login

Admin demo: mixalis / 12345 — άλλαξέ το μετά το upload.

Νέος παίκτης