Snek/src/js/leaderboards.js

110 lines
2.6 KiB
JavaScript

const Popup=require('popup');
const levels=require('levels');
const config=require('config');
const upload=async (mode, win, snek) => {
if(!win && !snek.rules.uploadOnDeath) return;
if(window.serverless) return;
const username=config.getS('player.name');
const score=snek.score;
const length=snek.length;
const time=snek.endPlayTime;
const speed=snek.speed;
const rst=await fetch('api/leaderboards/'+mode, {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({
username,
score, length,
time, speed
})
});
const dat=await rst.json();
if(!dat.ok) console.error(rst.err);
};
const show=async (mode='speedrun/1', page=1) => {
let popup=new Popup("Leaderboards: "+mode);
const [category, id]=mode.split('/');
let modes=[];
(() => {
Object.keys(window.levelList).forEach(cat => {
window.levelList[cat].levels.forEach(lvl => {
modes.push(cat+'/'+lvl);
});
});
})();
const prevMode=() => {
let idx=modes.indexOf(mode);
return modes[idx-1]||modes[modes.length-1];
};
const nextMode=() => {
let idx=modes.indexOf(mode);
return modes[idx+1]||modes[0];
};
const rules=await levels.getRules(category, id);
const sort=rules.leaderboardsSort;
const rst=await fetch('api/leaderboards/'+mode+'?sort='+sort+'&page='+page+'&results=10');
const {ok, data, err}=await rst.json();
popup.buttons.close="Close";
popup.buttons.modeP="Previous mode";
popup.buttons.modeN="Next mode";
popup.large=true;
popup.animation=false;
if(ok) {
popup.addStrong("Page "+page);
if(data.length==10) popup.buttons.next="Next page";
if(page>1) popup.buttons.prev="Previous page";
if(data.length==0) {
popup.addEm("No data");
} else {
const rpad=(n, digits=2, pad=' ') =>
((''+n).length>=digits)?(''+n):(rpad(pad+n, digits, pad));
popup.addTable(data.map(({username, score, length, speed, time}, i) => {
return {
rank: '#'+(i+(page-1)*10+1),
username,
score: score+'pts',
length,
speed: speed+'tps',
time: rpad(Math.floor(time/60000), 2, '0')+
':'+rpad(Math.floor(time/1000)%60, 2, '0')+
':'+rpad(time%1000, 3, '0')
};
}), [
'rank',
'username',
'score',
'length',
'speed',
'time'
]);
}
} else {
popup.addStrong("Error loading leaderboards");
popup.addEm(err);
}
Popup.dismiss();
const verb=await popup.display();
if(verb=='next') return show(mode, page+1);
else if(verb=='prev') return show(mode, page-1);
else if(verb=='modeP') return show(prevMode());
else if(verb=='modeN') return show(nextMode());
location.hash='';
};
return module.exports={
upload, show
};