Вход Регистрация
Файл: assets/js/game-live.js
Строк: 265
<?php
/* Единые живые таймеры v50.10.4 — общий ход игрового времени. */
(()=>{
  
'use strict';
  const 
pad=n=>String(Math.max(0,n)).padStart(2,'0');
  const 
rawNow=()=>Math.floor(Date.now()/1000);
  
let worldOffset=0;
  const 
meta=document.querySelector('meta[name="game-world-unix"]');
  if(
meta){const s=Number(meta.content||0);if(Number.isFinite(s)&&s>0)worldOffset=s-rawNow();}
  const 
now=()=>rawNow()+worldOffset;
  const 
calibrate=s=>{s=Number(s||0);if(Number.isFinite(s)&&s>0)worldOffset=s-rawNow();};
  const 
fmt=s=>{s=Math.max(0,Math.floor(s));const d=Math.floor(s/86400),h=Math.floor(s%86400/3600),m=Math.floor(s%3600/60),q=s%60;return (d?d+'д ':'')+pad(h)+':'+pad(m)+':'+pad(q)};
  const 
shortFmt=s=>{s=Math.max(0,Math.floor(s));const h=Math.floor(s/3600),m=Math.floor(s%3600/60),q=s%60;return h>0?`${h} ч ${m} мин`:m>0?`${m} мин ${q} сек`:`${q} сек`};
  
let reloadQueued=false;
  const 
syncBusy=new WeakSet();
  const 
lastSync=new WeakMap();
  const 
nextSync=new WeakMap();
  const 
queueReload=()=>{if(reloadQueued)return;reloadQueued=true;setTimeout(()=>location.reload(),180)};

  
async function liveSync(el,force=false){
    const 
url=el.dataset.liveSyncUrl||'';
    if(!
url||syncBusy.has(el)||reloadQueued)return;
    const 
t=Date.now(), interval=Math.max(5000,Number(el.dataset.liveSyncInterval||5000));
    const 
prev=Number(lastSync.get(el)||0), next=Number(nextSync.get(el)||0);
    if(
t<next || t-prev<interval)return;
    
lastSync.set(el,t);syncBusy.add(el);
    try{
      const 
sep=url.includes('?')?'&':'?';
      const 
r=await fetch(url+sep+'_ts='+t,{credentials:'same-origin',cache:'no-store',headers:{'X-Requested-With':'XMLHttpRequest','Accept':'application/json'}});
      const 
data=await r.json().catch(()=>null);
      if(
data&&data.world_now)calibrate(data.world_now);
      if(!
r.ok||!data||data.ok!==true)throw new Error((data&&data.error)||('HTTP '+r.status));

      const 
expected=String(el.dataset.livePhase||'');
      const 
expectedEvent=Number(el.dataset.liveEventId||0);
      const 
expectedJoined=el.dataset.liveJoined===''||typeof el.dataset.liveJoined==='undefined'?null:Number(el.dataset.liveJoined||0);
      const 
phase=String(data.phase||'');
      const 
eventId=Number(data.event_id||0);
      const 
joined=Number(data.joined||0);
      if((
expected&&phase!==expected)||(expectedEvent>0&&eventId!==expectedEvent)||(expectedJoined!==null&&joined!==expectedJoined)){queueReload();return;}

      const 
worldUntil=Number(data.until||0);
      if(
worldUntil>0)el.dataset.liveUntil=String(worldUntil);
      const 
left=Math.max(0,worldUntil-now());
      
el.textContent=el.dataset.liveFormat==='short'?shortFmt(left):fmt(left);
      
nextSync.set(el,t+interval);
      
el.classList.remove('live-sync-error');
      
el.removeAttribute('title');
    }catch(
e){
      
nextSync.set(el,t+15000);
      if(
Number(el.dataset.liveUntil||0)<=now()){
        
el.textContent='Событие временно недоступно';
        
el.classList.add('live-sync-error');
        
el.title='Не удалось обновить ход события. Обновите страницу.';
      }
    }finally{
syncBusy.delete(el);}
  }

  function 
tickLiveUntil(){
    
document.querySelectorAll('[data-live-until]').forEach(el=>{
      const 
end=Number(el.dataset.liveUntil||0), left=Math.max(0,end-now());
      if(
left>0)el.textContent=el.dataset.liveFormat==='short'?shortFmt(left):fmt(left);
      if(
el.dataset.liveSyncUrl){
        if(
left<=0){el.textContent='Завершение…';liveSync(el,true);}
        else if(
el.dataset.liveSyncInterval)liveSync(el,false);
      }else if(
left<=&& el.dataset.liveReload==='1'queueReload();
    });
  }
  function 
tickSeconds(){document.querySelectorAll('[data-live-seconds]').forEach(el=>{let s=Math.max(0,Number(el.dataset.liveSeconds||0));el.textContent=fmt(s);if(s>0)el.dataset.liveSeconds=String(s-1)})}
  function 
tickMessages(){document.querySelectorAll('[data-message-time]').forEach(el=>{const sec=Math.max(0,now()-Number(el.dataset.messageTime||0));el.textContent=sec<60?'только что':sec<3600?Math.floor(sec/60)+' мин. назад':sec<86400?Math.floor(sec/3600)+' ч. назад':Math.floor(sec/86400)+' дн. назад'})}
  function 
tickHide(){document.querySelectorAll('[data-live-hide-at]').forEach(el=>{const end=Number(el.dataset.liveHideAt||0);if(end>0&&now()>=end)el.style.display='none'})}
  function 
tickCooldownLabels(){document.querySelectorAll('[data-live-cooldown]').forEach(el=>{const end=Number(el.dataset.liveCooldown||0),left=Math.max(0,end-now());el.textContent=left>0?left+' сек.':'готово'})}
  function 
tickCooldownButtons(){document.querySelectorAll('[data-cooldown-until]').forEach(btn=>{const end=Number(btn.dataset.cooldownUntil||0),left=Math.max(0,end-now());if(!btn.dataset.readyHtml)btn.dataset.readyHtml=btn.innerHTML;const hasChild=!!btn.querySelector('[data-live-cooldown]');if(left>0){btn.disabled=true;btn.classList.add('is-cooldown');if(!hasChild)btn.textContent='До удара: '+left+' сек.';}else{btn.disabled=false;btn.classList.remove('is-cooldown');if(!hasChild&&btn.dataset.readyHtml)btn.innerHTML=btn.dataset.readyHtml;}})}
  function 
initLegacyTimers(){document.querySelectorAll('[id^="time_"]').forEach(el=>{if(el.dataset.legacyEnd)return;const raw=(el.id||'').slice(5),ms=Number(raw);if(Number.isFinite(ms)&&ms>0)el.dataset.legacyEnd=String(now()+Math.ceil(ms/1000));})}
  function 
tickLegacyTimers(){document.querySelectorAll('[data-legacy-end]').forEach(el=>{const left=Math.max(0,Number(el.dataset.legacyEnd)-now());el.textContent=fmt(left)})}
  function 
tickHall(){document.querySelectorAll('[data-hall-until]').forEach(el=>{const s=Math.max(0,Number(el.dataset.hallUntil)-now());if(s>=82800){const d=Math.max(1,Math.ceil(s/86400));el.textContent=d+' '+(d%10===1&&d%100!==11?'день':d%10>=2&&d%10<=4&&(d%100<10||d%100>=20)?'дня':'дней')}else el.textContent=shortFmt(s)})}
  function 
tick(){tickLiveUntil();tickSeconds();tickMessages();tickHide();tickCooldownLabels();tickCooldownButtons();tickLegacyTimers();tickHall()}
  
initLegacyTimers();tick();setInterval(tick,1000);
})();
?>
Онлайн: 1
Реклама