add leaderboard

This commit is contained in:
08draven 2024-10-08 20:48:38 -04:00
parent 5f31ceb7f2
commit 4437dad879
No known key found for this signature in database
GPG key ID: 33AC87E9ACE66954
9 changed files with 1575 additions and 8 deletions

View file

@ -105,6 +105,8 @@ class Player {
let oldHealth = target.health
let dmg = Math.floor( (dp-0.001) * 10);
target.health += Math.floor( (dp-0.001) * 10);
target.vel.x += (target.pos.x - ent.pos.x) * 0.1;
@ -112,6 +114,8 @@ class Player {
if (target.health <= 0 && oldHealth > 0) {
console.log(`Player ${target.you} died to a player ${ent.you}`);
ent.health -= dmg;
if (ent.health > 100) ent.health = 100;
ent.headCount++;
}
}

19
db.js Normal file
View file

@ -0,0 +1,19 @@
import sqlite3 from 'sqlite3'
import { open } from 'sqlite'
let db;
async function initDb() {
if (db) return db;
db = await open({
filename: `${process.cwd()}/db/main.db`,
driver: sqlite3.Database
});
await db.run(`CREATE TABLE IF NOT EXISTS stats (username TEXT, ip TEXT, ko TEXT);`);
return db;
}
export default initDb;

25
game.js
View file

@ -1,12 +1,18 @@
import GameBasic from "./common/game_basic.js";
import NPC from "./common/npc.js";
import initDb from './db.js';
import { createHash } from "crypto";
let db = await initDb();
class Game extends GameBasic {
constructor() {
super();
this.ws = [];
}
sync(full = false) {
async sync(full = false) {
let onScreen = this.entities.filter(x => x && x.health > 0).length;
onScreen += 4;
@ -31,11 +37,24 @@ class Game extends GameBasic {
if (entList.length == 0) return;
for (let client of this.ws) {
if (!client.active) continue;
let wsEnt = client.ent;
if (!wsEnt) continue;
if (full && wsEnt.health < 1 && !wsEnt.picked) {
wsEnt.picked = true;
const hash = createHash('sha256');
hash.update(client.ip || '');
await db.run('INSERT INTO stats (username, ip, ko) VALUES (?,?,?)', [
wsEnt.you,
hash.digest('hex'),
wsEnt.headCount
]);
}
if (!client.active) continue;
wsEnt.isYou = true;

View file

@ -4,6 +4,10 @@ import Game from "./game.js";
import NPC from "./common/npc.js";
import Player from "./common/player.js";
import initDb from "./db.js";
let db = await initDb();
var app = express();
expressW(app);
@ -15,6 +19,10 @@ app.use('/crypto.js', express.static('./common/crypto.js'));
app.use('/js', express.static('./common'));
app.use(express.static('./static'));
app.get('/leaderboard', async function(ws,req) {
req.send(JSON.stringify(await db.all('SELECT * from stats')));
})
app.ws('/', function (ws, req) {
game.ws.push(ws);
let player = new Player(false, true, game);
@ -23,9 +31,10 @@ app.ws('/', function (ws, req) {
ws.active = true;
ws.ent = player;
ws.ip = req.headers["x-real-ip"];
// This will only work under NGINX.
console.log(`Player ${player.you} joined under IP ${req.headers["x-real-ip"]}`)
console.log(`Player ${player.you} joined under IP ${ws.ip}`)
ws.on('message', function message(msg) {
let data = {};

1498
package-lock.json generated

File diff suppressed because it is too large Load diff

View file

@ -2,7 +2,9 @@
"dependencies": {
"crypto": "^1.0.1",
"express": "^4.21.0",
"express-ws": "^5.0.2"
"express-ws": "^5.0.2",
"sqlite": "^5.1.1",
"sqlite3": "^5.1.7"
},
"type": "module"
}

View file

@ -8,6 +8,7 @@ section {
width: 800px;
margin-left: auto;
margin-right: auto;
margin-bottom: 10px;
background: rgb(255, 255, 255);
border: solid rgb(200, 200, 200) 2px;
border-radius: 10px;
@ -27,7 +28,7 @@ h6 {
line-height: 40px;
}
p {
p, pre, s {
margin: 10px;
}

View file

@ -17,6 +17,10 @@
<canvas id='canvas'></canvas>
</div>
</section>
<section id='main'>
<h1>Leaderboard</h1>
<pre class='lb'></pre>
</section>
<script src='js/index.js' type="module"></script>
</body>

View file

@ -212,7 +212,7 @@ class Game extends GameBasic {
if (this.entities.length == 0) this.entities = [this.player];
}
init() {
async init() {
super.init();
let that = this;
@ -229,6 +229,19 @@ class Game extends GameBasic {
setInterval(function () { that.render() }, 1000 / 60);
game.canvas.onclick = () => that.click();
let jason = await (fetch('/leaderboard').then(x => x.json()))
let scores = {};
for (let e of jason) {
scores[e.ip] = scores[e.ip] || 0;
scores[e.ip] += e.ko ** 2;
}
scores = Object.entries(scores).sort((a,b) => b.ko - a.ko);
document.querySelector('.lb').textContent = scores.map(x => `${x[0]}: ${x[1]}`).join('\n');
}
}