Файл: pages/clan/clan_q.php
Строк: 270
<?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']='/clan_q.php'; $_SERVER['SCRIPT_NAME']='/clan_q.php'; }
/* Клановые задания v50.6 — единая логика, POST/CSRF и уведомления (+). by Метриум (Стэлп) */
include './system/common.php';
include './system/functions.php';
include './system/user.php';
include './system/menu.php';
if(!$user){ header('Location:/'); exit; }
if(!$clan || !$clan_memb){ $_SESSION['err']='Клановые задания доступны только участникам клана.'; header('Location:/clans/'); exit; }
$cid=(int)$clan['id']; $uid=(int)$user['id'];
// Чужие клановые задания не раскрываем: маршрут /clan/{id}/quest ведёт только в собственный клан.
$requested=(int)($_GET['id']??$cid);
if($requested>0 && $requested!==$cid){ $_SESSION['err']='Задания другого клана недоступны.'; header('Location:/clan/'.$requested.'/'); exit; }
$defs=game_clan_quest_defs();
$row=game_clan_quest_row($cid,true) ?: [];
game_clan_quest_expire($cid,$row);
if(($_SERVER['REQUEST_METHOD']??'GET')==='POST'){
security_require_csrf();
$qid=(int)($_POST['quest_id']??0); $action=(string)($_POST['quest_action']??'');
try{
[$ok,$message]=match($action){
'start'=>game_clan_quest_start($cid,$qid,$uid),
'help'=>game_clan_quest_help($cid,$qid,$uid),
'cancel'=>game_clan_quest_cancel($cid,$qid,$uid),
'claim'=>game_clan_quest_claim($cid,$qid,$uid),
default=>[false,'Неизвестное действие.'],
};
$_SESSION[$ok?'ok':'err']=$message;
}catch(Throwable $e){
app_log('ERROR','Clan quest action failed',['quest'=>$qid,'action'=>$action,'error'=>$e->getMessage()]);
$_SESSION['err']='Не удалось выполнить действие. Попробуйте ещё раз.';
}
header('Location:/clan/'.$cid.'/quest/'); exit;
}
$title='Клановые задания';
include './system/h.php';
if(isset($_SESSION['ok'])){ echo '<div class="ok center">'.security_system_text((string)$_SESSION['ok']).'</div>'; unset($_SESSION['ok']); }
if(isset($_SESSION['err'])){ echo '<div class="ok center">'.security_html((string)$_SESSION['err']).'</div>'; unset($_SESSION['err']); }
if(!game_clan_quest_is_week_open()){
$members=[]; $q=db_prepare('SELECT cm.`plat`,u.`id`,u.`login`,u.`r`,u.`online` FROM `clan_memb` cm INNER JOIN `users` u ON u.`id`=cm.`user` WHERE cm.`clan`=:c AND cm.`plat`>0 ORDER BY cm.`plat` DESC LIMIT 50',['c'=>$cid]);
while($r=$q->fetch())$members[]=$r;
$gold=max(0,(int)$clan['plat']*20); $silver=max(0,(int)$clan['plat']*200);
echo '<div class="block_zero center"><b>Клановые задания завершены до понедельника</b><br>За неделю добыто <img src="/images/icon/crys/diamond.png" alt="*"> '.n_f((int)$clan['plat']).'<br>Награда клана: <img src="/images/icon/gold.png" alt="*"> '.n_f($gold).' <img src="/images/icon/silver.png" alt="*"> '.n_f($silver).'</div>';
if($members){ echo '<div class="menuList">'; foreach($members as $n=>$m){ echo '<li>'.($n+1).'. <img src="/images/icon/race/'.(int)$m['r'].(((int)$m['online']>time()-300)?'':'-off').'.png" alt=""> <a href="/user/'.(int)$m['id'].'/">'.security_html((string)$m['login']).'</a> <span class="float-right"><img src="/images/icon/crys/diamond.png" alt=""> '.n_f((int)$m['plat']).'</span></li>'; } echo '</div>'; }
include './system/f.php'; exit;
}
$completed=game_clan_quest_completed_count($cid);
echo '<div class="block_zero center"><span class="blue">Выполняй задания и добывай кристаллы для клана!</span><br>Добыто кристаллов: <img src="/images/icon/crys/diamond.png" alt=""> '.n_f((int)$clan['plat']);
if($completed>0) echo '<br><span class="green"><b>(+) Выполнено заданий: '.$completed.'</b></span>';
echo '<br><a class="grey" href="/clantournament/">Подробнее о турнире</a></div>';
// Загружаем исполнителей одним запросом вместо 16 SELECT на страницу.
$ids=[]; foreach($defs as $qid=>$def){ foreach(['user_'.$qid,'user_'.$qid.'_p'] as $f){$x=(int)($row[$f]??0);if($x>0)$ids[$x]=$x;} }
$people=[]; if($ids){ $q=db_query('SELECT `id`,`login`,`r`,`online` FROM `users` WHERE `id` IN ('.implode(',',array_map('intval',$ids)).')'); while($r=db_fetch_assoc($q))$people[(int)$r['id']]=$r; }
foreach($defs as $qid=>$def){
$progress=max(0,min((int)$def['goal'],(int)($row['q_'.$qid]??0))); $goal=(int)$def['goal']; $pct=(int)floor($progress/max(1,$goal)*100);
$primary=(int)($row['user_'.$qid]??0); $helper=(int)($row['user_'.$qid.'_p']??0); $cool=(int)($row[$qid.'_time']??0); $done=$primary>0&&$progress>=$goal;
$deadline=0; if($primary>0){ $a=db_fetch_one('SELECT `time` FROM `clan_q_user` WHERE `clans`=:c AND `user`=:u ORDER BY `id` DESC LIMIT 1',['c'=>$cid,'u'=>$primary]); $deadline=(int)($a['time']??0); }
echo '<section class="clan-quest-card'.($done?' clan-quest-card--done':'').'">';
echo '<div class="clan-quest-title"><img src="/images/icon/quest.png" alt=""> <b class="dgreen">'.security_html((string)$def['title']).'</b>'.($done?' <span class="green">(+)</span>':'').'</div>';
echo '<div>'.security_html((string)$def['description']).'</div>';
echo game_progress_markup($progress,$goal);
echo '<div><span class="blue">Награда:</span> <img src="/images/icon/gold.png" alt=""> '.n_f((int)$def['gold']).' <img src="/images/icon/exp.png" alt=""> '.n_f((int)$def['exp']).' + <img src="/images/icon/crys/diamond.png" alt=""> 1–10</div>';
if($cool>time()){
echo '<div class="grey">Повторно будет доступно через <span data-live-until="'.$cool.'" data-live-format="short">'._time($cool-time()).'</span></div>';
}elseif($primary>0){
$p=$people[$primary]??null; $h=$people[$helper]??null;
echo '<div class="clan-quest-runners">Выполняет: '.($p?'<img src="/images/icon/race/'.(int)$p['r'].(((int)$p['online']>time()-300)?'':'-off').'.png" alt=""> <a href="/user/'.(int)$p['id'].'/">'.security_html((string)$p['login']).'</a>':'—');
if($h) echo ' + <img src="/images/icon/race/'.(int)$h['r'].(((int)$h['online']>time()-300)?'':'-off').'.png" alt=""> <a href="/user/'.(int)$h['id'].'/">'.security_html((string)$h['login']).'</a>';
if($deadline>time()) echo ' <span class="grey">(осталось: <span data-live-until="'.$deadline.'" data-live-format="short">'._time($deadline-time()).'</span>)</span>'; echo '</div>';
if($done && $primary===$uid){
echo '<form method="post" class="center">'.security_csrf_field().'<input type="hidden" name="quest_id" value="'.$qid.'"><button class="btn" name="quest_action" value="claim" type="submit"><span class="end"><span class="label">Завершить и получить награду</span></span></button></form>';
}elseif($primary===$uid || $helper===$uid){
echo '<div class="center"><a class="btn" href="'.security_html((string)$def['route']).'"><span class="end"><span class="label">Продолжить</span></span></a></div>';
echo '<form method="post" class="center clan-quest-cancel">'.security_csrf_field().'<input type="hidden" name="quest_id" value="'.$qid.'"><button class="link-button grey" name="quest_action" value="cancel" type="submit">Отменить</button></form>';
}elseif($helper<=0 && !$done){
echo '<form method="post" class="center">'.security_csrf_field().'<input type="hidden" name="quest_id" value="'.$qid.'"><button class="btn" name="quest_action" value="help" type="submit"><span class="end"><span class="label">Помочь</span></span></button></form>';
}elseif($done){ echo '<div class="center dgreen"><b>Задание выполнено — ожидается получение награды</b></div>'; }
}else{
echo '<form method="post" class="center">'.security_csrf_field().'<input type="hidden" name="quest_id" value="'.$qid.'"><button class="btn" name="quest_action" value="start" type="submit"><span class="end"><span class="label">Выполнить</span></span></button></form>';
}
echo '</section>';
}
include './system/f.php';