Файл: pages/economy/sunduk.php
Строк: 190
<?php
/* Безопасная система сундуков + звездная пыль. by Метриум (Стэлп) */
declare(strict_types=1);
// Physical module map v50.6: public URL stays clean while code lives in /pages.
if (!defined('GAME_ROOT')) define('GAME_ROOT', dirname(__DIR__, 2));
chdir(GAME_ROOT);
if (PHP_SAPI !== 'cli') { $_SERVER['PHP_SELF']='/sunduk.php'; $_SERVER['SCRIPT_NAME']='/sunduk.php'; }
require_once './system/common.php';
require_once './system/functions.php';
require_once './system/user.php';
if(!$user){ header('Location: /'); exit; }
$title='Сундуки';
$uid=(int)$user['id'];
$row=db_fetch_assoc(db_query("SELECT * FROM `sunduk` WHERE `id_user`=$uid LIMIT 1"));
if(!$row){
db_execute('INSERT INTO `sunduk` (`id_user`) VALUES (:u)',['u'=>$uid]);
$row=['id_user'=>$uid,'1'=>0,'2'=>0,'3'=>0,'4'=>0,'5'=>0,'inv'=>0,'inv_user'=>0,'g'=>0];
}
if(($_SERVER['REQUEST_METHOD']??'GET')==='POST'){
security_require_csrf();
$action=(string)($_POST['action']??'');
if($action==='buy_key'){
$price=20;
$fresh=db_fetch_assoc(db_query("SELECT `g` FROM `users` WHERE `id`=$uid LIMIT 1"));
$gold=(int)($fresh['g']??0);
if($gold<$price) $_SESSION['err']='Недостаточно золота для покупки ключа.';
else {
db_execute('UPDATE `users` SET `g`=`g`-:p1,`klu`=`klu`+1 WHERE `id`=:u AND `g`>=:p2',['p1'=>$price,'p2'=>$price,'u'=>$uid]);
$_SESSION['ok']='Ключ куплен.';
}
header('Location: /sunduk/'); exit;
}
if($action==='reset'){
$price=75;
$all=true; for($i=1;$i<=5;$i++) if((int)($row[(string)$i]??0)!==1)$all=false;
if(!$all) $_SESSION['err']='Сначала откройте все пять сундуков.';
else {
$fresh=db_fetch_assoc(db_query("SELECT `g` FROM `users` WHERE `id`=$uid LIMIT 1"));
if((int)($fresh['g']??0)<$price) $_SESSION['err']='Недостаточно золота для обновления сундуков.';
else {
db_execute('UPDATE `users` SET `g`=`g`-:p1 WHERE `id`=:u AND `g`>=:p2',['p1'=>$price,'p2'=>$price,'u'=>$uid]);
db_execute('UPDATE `sunduk` SET `1`=0,`2`=0,`3`=0,`4`=0,`5`=0 WHERE `id_user`=:u',['u'=>$uid]);
$_SESSION['ok']='Сундуки обновлены.';
}
}
header('Location: /sunduk/'); exit;
}
if($action==='open'){
$slot=(int)($_POST['slot']??0);
if($slot<1||$slot>5){ $_SESSION['err']='Некорректный сундук.'; header('Location: /sunduk/'); exit; }
$col=(string)$slot; // whitelisted above
$state=db_fetch_assoc(db_query("SELECT * FROM `sunduk` WHERE `id_user`=$uid LIMIT 1"));
$fresh=db_fetch_assoc(db_query("SELECT `klu` FROM `users` WHERE `id`=$uid LIMIT 1"));
if((int)($state[$col]??0)===1) $_SESSION['err']='Этот сундук уже открыт.';
elseif((int)($fresh['klu']??0)<=0) $_SESSION['err']='У вас нет ключей.';
else {
// Ключ списывается атомарно, повторное открытие блокируется условием по слоту.
$stmt=db_pdo()->prepare("UPDATE `sunduk` s JOIN `users` u ON u.`id`=:u SET s.`$col`=1,u.`klu`=u.`klu`-1 WHERE s.`id_user`=:u2 AND s.`$col`=0 AND u.`klu`>0");
$stmt->execute(['u'=>$uid,'u2'=>$uid]);
if($stmt->rowCount()===0){ $_SESSION['err']='Сундук уже открыт или ключ закончился.'; header('Location: /sunduk/'); exit; }
$roll=random_int(1,100);
$msg='';
if($roll<=22){
$amount=game_economy_award_gold($uid,random_int(1,5),'chest',150);
$msg="Получено <img src='/images/icon/gold.png' alt='*'> ".n_f($amount).' золота.';
} elseif($roll<=45){
$amount=random_int(150,1200); db_execute('UPDATE `users` SET `s`=`s`+:v WHERE `id`=:u',['v'=>$amount,'u'=>$uid]);
$msg="Получено <img src='/images/icon/silver.png' alt='*'> ".n_f($amount).' серебра.';
} elseif($roll<=65){
$amount=random_int(500,2500); db_execute('UPDATE `users` SET `exp`=`exp`+:v WHERE `id`=:u',['v'=>$amount,'u'=>$uid]);
$msg="Получено <img src='/images/icon/exp.png' alt='*'> ".n_f($amount).' опыта.';
} elseif($roll<=80){
$dust=random_int(1,4); game_star_chest_state($uid); db_execute('UPDATE `stars_dust_users` SET `dust`=`dust`+:d WHERE `user`=:u',['d'=>$dust,'u'=>$uid]);
$msg='Сундук сияет: получено '.n_f($dust).' звездной пыли!';
} elseif($roll<=91){
$res=random_int(1,5); $amount=random_int(5,20);
$field=(string)$res; // 1..5 whitelist
db_query("UPDATE `sack` SET `$field`=`$field`+$amount WHERE `user`=$uid");
$msg='Получены ресурсы: '.n_f($amount).' шт.';
} elseif($roll<=97){
$keys=random_int(1,2); db_execute('UPDATE `users` SET `klu`=`klu`+:v WHERE `id`=:u',['v'=>$keys,'u'=>$uid]);
$msg='Получено ключей: '.$keys.'.';
} else {
$item=db_fetch_assoc(db_query("SELECT * FROM `items` WHERE `quality`>=5 ORDER BY RAND() LIMIT 1"));
if($item){
$bonus=min(25,max(5,(int)($item['bonus']??10)));
$base=max(50,120*$bonus);
db_execute('INSERT INTO `inv` (`user`,`item`,`bonus`,`_str`,`_vit`,`_agi`,`quality`,`_def`) VALUES (:u,:i,:b,:s,:v,:a,:q,:d)',[
'u'=>$uid,'i'=>(int)$item['id'],'b'=>$bonus,'s'=>$base,'v'=>$base,'a'=>$base,'q'=>(int)$item['quality'],'d'=>$base
]);
db_execute('UPDATE `sunduk` SET `inv_user`=:u,`inv`=:i WHERE `id_user`=:u2',['u'=>$uid,'i'=>(int)$item['id'],'u2'=>$uid]);
$msg='Редкая находка: '.security_html((string)$item['name']).'!';
} else {
$amount=game_economy_award_gold($uid,10,'chest_fallback',150); $msg='Получено '.n_f($amount).' золота.';
}
}
$_SESSION['ok']=$msg;
}
header('Location: /sunduk/'); exit;
}
}
include './system/h.php';
$row=db_fetch_assoc(db_query("SELECT * FROM `sunduk` WHERE `id_user`=$uid LIMIT 1")) ?: $row;
$fresh=db_fetch_assoc(db_query("SELECT `klu`,`g` FROM `users` WHERE `id`=$uid LIMIT 1")) ?: $user;
$dustState=game_star_chest_state($uid);
?>
<div class="title">Сундуки</div>
<div class="block center">
Открывай сундуки ключами. Внутри есть золото, серебро, опыт, ресурсы, экипировка и <b>звездная пыль</b>.<br>
<span class="blue">Ключей: <?=n_f((int)($fresh['klu']??0))?> · Звездная пыль: <?=n_f((int)($dustState['dust']??0))?></span>
</div>
<div class="block center">
<form method="post" action="/sunduk/" class="inline-form"><?=security_csrf_field()?>
<input type="hidden" name="action" value="buy_key">
<button class="btn" type="submit"><span class="end"><span class="label">Купить ключ за <img src="/images/icon/gold.png" alt="*"> 20</span></span></button>
</form>
</div>
<div class="chest-grid center">
<?php for($i=1;$i<=5;$i++): $opened=(int)($row[(string)$i]??0)===1; ?>
<div class="game-chest <?=$opened?'is-open':'is-closed'?>">
<?php if(!$opened): ?>
<form method="post" action="/sunduk/" class="inline-form">
<?=security_csrf_field()?>
<input type="hidden" name="action" value="open"><input type="hidden" name="slot" value="<?=$i?>">
<button type="submit" class="chest-button" aria-label="Открыть сундук <?=$i?>"><img src="/images/stash/closed.png" alt="Закрытый сундук"></button>
</form>
<?php else: ?>
<img src="/images/stash/opened_dust.png" alt="Открытый сундук со звездной пылью">
<?php endif; ?>
<div class="medium">Сундук <?=$i?> · <?=$opened?'открыт':'закрыт'?></div>
</div>
<?php endfor; ?>
</div>
<?php $all=true; for($i=1;$i<=5;$i++) if((int)($row[(string)$i]??0)!==1)$all=false; if($all): ?>
<div class="block center">
<form method="post" action="/sunduk/" class="inline-form"><?=security_csrf_field()?>
<input type="hidden" name="action" value="reset">
<button class="btn" type="submit"><span class="end"><span class="label">Обновить сундуки за 75 золота</span></span></button>
</form>
</div>
<?php endif; ?>
<div class="resours center"><span class="orange">Ключи можно получать в сражениях и других игровых активностях.</span></div>
<?php include './system/f.php'; ?>