Файл: system/activity.php
Строк: 125
<?php
declare(strict_types=1);
/**
* Единые индикаторы (+) v50.6.
* Важно: базовые флаги собираются одним SQL-запросом, чтобы индикаторы сами
* не создавали лишнюю нагрузку на каждую страницу.
*/
function game_activity_badges(array $user,?array $clan=null,?array $clanMemb=null): array {
static $cache=[];
$uid=(int)($user['id']??0); $cid=(int)($clan['id']??0); $key=$uid.':'.$cid;
if(isset($cache[$key])) return $cache[$key];
$out=[
'hero'=>0,'inventory'=>0,'quests'=>0,'clan'=>0,'clan_quests'=>0,'clan_applications'=>0,
'clan_chat'=>0,'feed'=>0,'cave'=>0,'undying'=>0,'altars'=>0,'hall'=>0,'daily'=>0,'mail'=>0,'chat'=>0,'forum_news'=>0,
];
if($uid<=0) return $cache[$key]=$out;
$now=time();
$questDay=db_real_escape_string(function_exists('game_daily_quest_day_key')?game_daily_quest_day_key():date('Y-m-d'));
// Один round-trip вместо серии COUNT/SELECT. Все значения ниже только счётчики/EXISTS.
$sql='SELECT '
.'(SELECT COUNT(*) FROM `inv` i WHERE i.`user`='.$uid.' AND i.`equip`=0 AND i.`place`=0 AND i.`new`=0) AS inventory,'
.'(SELECT COUNT(*) FROM `daily_quest_assignment` dqa JOIN `user_q` uq ON uq.`user`=dqa.`user` AND uq.`q`=dqa.`quest_id` JOIN `quest` q ON q.`id`=uq.`q` WHERE dqa.`user`='.$uid.' AND dqa.`day_key`=''.$questDay.'' AND uq.`complete`=0 AND uq.`c`>=q.`c`) AS quests,'
.'(SELECT COUNT(*) FROM `feed` f WHERE f.`user`='.$uid.') AS feed,'
.'(SELECT COUNT(*) FROM `mail` mm LEFT JOIN `users` mu ON mu.`id`=mm.`from` WHERE mm.`to`='.$uid.' AND mm.`read`=0 AND (mm.`from` IN (0,2) OR mu.`id` IS NOT NULL)) AS mail,'
.'(SELECT COUNT(*) FROM `chat` ch WHERE ch.`clan`=0 AND ch.`to`='.$uid.' AND ch.`read`=0) AS chat,'
.'(CASE WHEN COALESCE((SELECT MAX(ft.`id`) FROM `forum_topic` ft WHERE ft.`sub`=1),0)>'.(int)($user['nread']??0).' THEN 1 ELSE 0 END) AS forum_news,'
.'(CASE WHEN EXISTS(SELECT 1 FROM `cave_v512_state` cv WHERE cv.`user_id`='.$uid.' AND (cv.`stage`='found' OR (cv.`stage` IN ('searching','gathering') AND cv.`ends_at`<='.$now.'))) THEN 1 ELSE 0 END) AS cave,'
.'(SELECT COUNT(*) FROM `undying_v512_event` ue WHERE ue.`state` IN ('waiting','running')) AS undying,'
.'(SELECT COUNT(*) FROM `altar_v512_event` ae WHERE ae.`state` IN ('waiting','running')) AS altars,'
.'(CASE WHEN NOT EXISTS(SELECT 1 FROM `user_podarok` up WHERE up.`user_id`='.$uid.') OR COALESCE((SELECT MAX(up2.`last_auth`) FROM `user_podarok` up2 WHERE up2.`user_id`='.$uid.'),0)+86400<='.$now.' THEN 1 ELSE 0 END) AS daily';
if($cid>0){
$sql.=',(SELECT COUNT(*) FROM `chat` cc WHERE cc.`clan`='.$cid.' AND cc.`to`='.$uid.' AND cc.`read`=0) AS clan_chat';
if((int)($clanMemb['rank']??0)>=4) $sql.=',(SELECT COUNT(*) FROM `clan_z` cz WHERE cz.`clan`='.$cid.') AS clan_applications';
}
try{
$r=db_fetch_assoc(db_query($sql)) ?: [];
foreach(['inventory','quests','feed','mail','chat','forum_news','cave','undying','altars','daily','clan_chat','clan_applications'] as $k){ if(isset($r[$k])) $out[$k]=(int)$r[$k]; }
}catch(Throwable $e){ if(function_exists('app_log_write')) app_log_write('ACTIVITY','Badge query failed',['type'=>get_class($e)]); }
if($cid>0 && function_exists('game_clan_quest_completed_count')) $out['clan_quests']=game_clan_quest_completed_count($cid);
// Зал славы: (+) только когда активная попытка уже достигла цели и её нужно зафиксировать.
if($cid>0 && function_exists('game_hall_active_progress_for_user')){
$hp=game_hall_active_progress_for_user($user);
if($hp && (int)$hp['progress']>=(int)$hp['target']) $out['hall']=1;
}
$out['clan']=$out['clan_quests']+$out['clan_chat']+$out['clan_applications']+$out['hall'];
$out['hero']=$out['inventory']+$out['quests'];
return $cache[$key]=$out;
}
function game_badge_plus(int|bool $value): string { return $value?'<span class="green">(+)</span>':''; }
/** Помечает событие готовым уже в текущем запросе, даже если хедер успел собрать кэш до боевого действия. */
function game_activity_mark(string $key,int $amount=1): void {
if($amount<=0) return;
if(!isset($GLOBALS['game_badges']) || !is_array($GLOBALS['game_badges'])) $GLOBALS['game_badges']=[];
$GLOBALS['game_badges'][$key]=max((int)($GLOBALS['game_badges'][$key]??0),$amount);
if(in_array($key,['clan_quests','clan_applications','clan_chat','hall'],true)){
$GLOBALS['game_badges']['clan']=max(1,(int)($GLOBALS['game_badges']['clan']??0));
}
if(in_array($key,['inventory','quests'],true)){
$GLOBALS['game_badges']['hero']=max(1,(int)($GLOBALS['game_badges']['hero']??0));
}
}