Вход Регистрация
Файл: pages/account/save.php
Строк: 156
<?php
// 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']='/save.php'$_SERVER['SCRIPT_NAME']='/save.php'; }

/* Сохранение героя / подтверждение данных: by Метриум (Стэлп) */
foreach(['common.php','functions.php','user.php'] as $i) require_once './system/'.$i;
$unic_code=(string)($_GET['unic_code']??'');
if(!
$unic_code || !security_flow_valid($unic_code,'save')){header('Location:/user/');exit;}
if(!
$user){header('Location:/');exit;} if((int)$user['save']===1){header('Location:/');exit;}
$title='Сохранение'; include './system/h.php'; echo '<div class="main">';
$errors=[]; $step=(string)($_POST['step']??'form');
if(
$_SERVER['REQUEST_METHOD']==='POST'security_require_csrf();
if(
$step==='prepare'){
 
$login=trim((string)($_POST['login']??''));$password=(string)($_POST['password']??'');
 if(!
preg_match('/^[a-z0-9а-яё _-]{2,20}$/iu',$login))$errors[]='Имя персонажа введено неверно';
 if(
strlen($password)<|| strlen($password)>72)$errors[]='Пароль должен содержать от 4 до 72 символов';
 if((int)(
db_result(db_query("SELECT COUNT(*) FROM `users` WHERE `login`='".db_real_escape_string($login)."' AND `id`<>".(int)$user['id']),0)?:0)>0)$errors[]='Выбранное имя персонажа уже занято';
 if(!
$errors){$_SESSION['_save_confirm']=['login'=>$login,'hash'=>security_password_hash($password),'sex'=>(int)($_POST['sex']??0),'r'=>(int)($_POST['r']??0),'at'=>time()];$step='confirm';}
}
if(
$step==='change'){unset($_SESSION['_save_confirm']);$step='form';}
if(
$step==='confirm' && isset($_SESSION['_save_confirm']) && ($_POST['confirm']??'')==='1'){
 
$p=$_SESSION['_save_confirm'];
 if(
time()-(int)$p['at']>1800){
   unset(
$_SESSION['_save_confirm']);
   
$errors[]='Сессия подтверждения истекла';
   
$step='form';
 } else {
   
$uid=(int)$user['id'];
   try {
     
// Сохраняем только гарантированно существующие поля users. Без транзакции вокруг legacy-таблиц:
     // это исключает конфликт уже открытой транзакции на production. by Метриум (Стэлп)
     
$stmt=db_prepare('UPDATE `users` SET `login`=:login,`r`=:race,`sex`=:sex,`password`=:pass,`save`='1',`g`=`g`+100 WHERE `id`=:uid AND `save`='0' LIMIT 1',[
       
'login'=>(string)$p['login'],
       
'race'=>max(0,min(2,(int)$p['r'])),
       
'sex'=>max(0,min(1,(int)$p['sex'])),
       
'pass'=>(string)$p['hash'],
       
'uid'=>$uid,
     ]);

     
$check=db_fetch_one('SELECT `id`,`save`,`login`,`password` FROM `users` WHERE `id`=:uid LIMIT 1',['uid'=>$uid]);
     if(!
$check || (int)($check['save']??0)!==1){
       throw new 
RuntimeException('save flag was not persisted');
     }

     
// Необязательные поля старых/новых схем не имеют права ломать сохранение героя.
     
try {
       
$cols=[]; $qr=db_query('SHOW COLUMNS FROM `users`');
       while(
$cr=db_fetch_assoc($qr)){ $f=(string)($cr['Field']??''); if($f!=='')$cols[$f]=true; }
       
$extra=[];
       if(isset(
$cols['new'])) $extra[]='`new`=1';
       if(isset(
$cols['hunt_battles'])) $extra[]='`hunt_battles`=15';
       if(isset(
$cols['hunt_battles_max'])) $extra[]='`hunt_battles_max`=15';
       if(
$extradb_query('UPDATE `users` SET '.implode(',',$extra).' WHERE `id`='.$uid.' LIMIT 1');
     } catch(
Throwable $optionalError){ error_log('[SAVE_OPTIONAL] '.$optionalError->getMessage()); }

     try { 
game_bonus_offer_ensure($uid); } catch(Throwable $bonusError) { error_log('[SAVE_BONUS] '.$bonusError->getMessage()); }

     
security_auth_login($uid);
     
$_COOKIE['id']=(string)$uid;
     if(
function_exists('tutorial_clear_progress')) tutorial_clear_progress();
     unset(
$_SESSION['_save_confirm'],$_SESSION['_flow']['save'],$_SESSION['_tutorial_progress']);
     
$_SESSION['just_saved']=1;
     
$_SESSION['ok']='Персонаж сохранён. Полный доступ к игре открыт.';
     
header('Location:/bonus-kit/?saved=1'); exit;
   } catch(
Throwable $e) {
     
error_log('[SAVE_CHARACTER] uid='.$uid.' '.get_class($e).': '.$e->getMessage());
     
$errors[]='Не удалось завершить сохранение персонажа. Попробуйте ещё раз.';
     
$step='form';
   }
 }
}
foreach(
$errors as $e) echo '<div class="block center red">'.htmlspecialchars($e,ENT_QUOTES,'UTF-8').'</div>';
if(
$step==='confirm' && isset($_SESSION['_save_confirm'])){$p=$_SESSION['_save_confirm'];?>
<div class="save-ref"><div class="save-ref__title">Проверьте данные</div><div class="save-ref__line"></div><b>Имя персонажа:</b> <?=htmlspecialchars($p['login'],ENT_QUOTES,'UTF-8')?><br><b>Ваш пароль:</b> ••••••••<form method="post" action="/save?unic_code=<?=urlencode($unic_code)?>"><?=security_csrf_field()?><input type="hidden" name="step" value="confirm"><input type="hidden" name="confirm" value="1"><button class="old-btn" type="submit">Всё верно</button></form><form method="post" action="/save?unic_code=<?=urlencode($unic_code)?>"><?=security_csrf_field()?><input type="hidden" name="step" value="change"><button class="save-link" type="submit">Изменить данные</button></form></div>
<?php } else { ?>
<div class="title">Сохранение</div><div class="save-ref"><div class="save-ref__bonus">За регистрацию вы получите <img src="/images/icon/gold.png" alt=""> <b>100 золота!</b><br>Откроете акцию на <span class="blue">Редкий комплект</span><br><span class="green">+1600 к параметрам!</span></div><form method="post" action="/save?unic_code=<?=urlencode($unic_code)?>"><?=security_csrf_field()?><input type="hidden" name="step" value="prepare"><b>Имя персонажа:</b><br><input class="text" name="login" maxlength="20" required><br><b>Введите пароль:</b><br><input class="text" type="password" name="password" maxlength="72" required><input type="hidden" name="sex" value="<?= (int)($user['sex']??0?>"><input type="hidden" name="r" value="<?= (int)($user['r']??0?>"><br><button class="old-btn" type="submit">Сохранить</button></form></div>
<?php } echo '</div>'; include './system/f.php'?>
Онлайн: 2
Реклама