103 lines
2.8 KiB
JavaScript
103 lines
2.8 KiB
JavaScript
const DB=require('better-sqlite3');
|
|
const {Router}=require('express');
|
|
|
|
const db=new DB('db.sqlite');
|
|
const api=new Router();
|
|
|
|
const leaderboardSelect='SELECT username, score, length, time, speed FROM leaderboards';
|
|
const getLeaderboardsBy={
|
|
score: db.prepare(`${leaderboardSelect} WHERE mode=? ORDER BY score DESC LIMIT ? OFFSET ?`),
|
|
timeA: db.prepare(`${leaderboardSelect} WHERE mode=? ORDER BY time ASC LIMIT ? OFFSET ?`),
|
|
timeD: db.prepare(`${leaderboardSelect} WHERE mode=? ORDER BY time DESC LIMIT ? OFFSET ?`)
|
|
};
|
|
const addLeaderboard=db.prepare(`
|
|
INSERT
|
|
INTO leaderboards(mode, username, score, length, time, speed)
|
|
VALUES(@mode, @username, @score, @length, @time, @speed)
|
|
`);
|
|
|
|
const levelList=require('./assets/levelList.json');
|
|
const validMode=mode => {
|
|
try {
|
|
const [category, name]=mode.split('/');
|
|
return levelList[category].levels.map(l => ''+l).includes(name);
|
|
} catch(e) {
|
|
return false;
|
|
}
|
|
};
|
|
|
|
api.get('/leaderboards/:category/:id', (req, res) => {
|
|
const sort=req.query.sort || 'score';
|
|
if(!['score', 'timeA', 'timeD'].includes(sort)) return res.status(400).json({
|
|
ok: false,
|
|
err: 'Invalid sort'
|
|
});
|
|
const results=+req.query.results || 20;
|
|
if((typeof results)!='number' || results<1 || results >100) return res.status(400).json({
|
|
ok: false,
|
|
err: 'Invalid result count'
|
|
});
|
|
const page=+req.query.page || 1;
|
|
if((typeof page)!='number' || page<1) return res.status(400).json({
|
|
ok: false,
|
|
err: 'Invalid page'
|
|
});
|
|
|
|
const data=getLeaderboardsBy[sort]
|
|
.all(req.params.category+'/'+req.params.id, results, (page-1)*results);
|
|
return res.status(200).json({
|
|
ok: true,
|
|
data
|
|
});
|
|
});
|
|
|
|
api.post('/leaderboards/:category/:id', (req, res) => {
|
|
const mode=req.params.category+'/'+req.params.id;
|
|
if((typeof mode)!='string' || !validMode(mode)) return res.status(400).json({
|
|
ok: false,
|
|
err: 'Invalid mode'
|
|
});
|
|
const username=req.body.username;
|
|
if((typeof username)!='string' || username.length>100) return res.status(400).json({
|
|
ok: false,
|
|
err: 'Invalid username'
|
|
});
|
|
const score=req.body.score;
|
|
if((typeof score)!='number' || score%1 || score<0) return res.status(400).json({
|
|
ok: false,
|
|
err: 'Invalid score'
|
|
});
|
|
const length=req.body.length;
|
|
if((typeof length)!='number' || length%1 || length<1) return res.status(400).json({
|
|
ok: false,
|
|
err: 'Invalid length'
|
|
});
|
|
const time=req.body.time;
|
|
if((typeof time)!='number' || time%1 || time<0) return res.status(400).json({
|
|
ok: false,
|
|
err: 'Invalid time'
|
|
});
|
|
const speed=req.body.speed;
|
|
if((typeof speed)!='number' || speed%1 || speed<0) return res.status(400).json({
|
|
ok: false,
|
|
err: 'Invalid speed'
|
|
});
|
|
|
|
try {
|
|
addLeaderboard.run({
|
|
mode, username,
|
|
score, length,
|
|
time, speed
|
|
});
|
|
res.json({
|
|
ok: true
|
|
});
|
|
} catch(e) {
|
|
res.status(500).json({
|
|
ok: false,
|
|
err: 'Failed to add score'
|
|
});
|
|
}
|
|
});
|
|
|
|
return module.exports=exports=api;
|