add leaderboard
This commit is contained in:
parent
5f31ceb7f2
commit
4437dad879
9 changed files with 1575 additions and 8 deletions
|
@ -105,6 +105,8 @@ class Player {
|
||||||
|
|
||||||
let oldHealth = target.health
|
let oldHealth = target.health
|
||||||
|
|
||||||
|
let dmg = Math.floor( (dp-0.001) * 10);
|
||||||
|
|
||||||
target.health += 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;
|
target.vel.x += (target.pos.x - ent.pos.x) * 0.1;
|
||||||
|
@ -112,6 +114,8 @@ class Player {
|
||||||
|
|
||||||
if (target.health <= 0 && oldHealth > 0) {
|
if (target.health <= 0 && oldHealth > 0) {
|
||||||
console.log(`Player ${target.you} died to a player ${ent.you}`);
|
console.log(`Player ${target.you} died to a player ${ent.you}`);
|
||||||
|
ent.health -= dmg;
|
||||||
|
if (ent.health > 100) ent.health = 100;
|
||||||
ent.headCount++;
|
ent.headCount++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
19
db.js
Normal file
19
db.js
Normal 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
25
game.js
|
@ -1,12 +1,18 @@
|
||||||
import GameBasic from "./common/game_basic.js";
|
import GameBasic from "./common/game_basic.js";
|
||||||
import NPC from "./common/npc.js";
|
import NPC from "./common/npc.js";
|
||||||
|
|
||||||
|
import initDb from './db.js';
|
||||||
|
|
||||||
|
import { createHash } from "crypto";
|
||||||
|
|
||||||
|
let db = await initDb();
|
||||||
|
|
||||||
class Game extends GameBasic {
|
class Game extends GameBasic {
|
||||||
constructor() {
|
constructor() {
|
||||||
super();
|
super();
|
||||||
this.ws = [];
|
this.ws = [];
|
||||||
}
|
}
|
||||||
sync(full = false) {
|
async sync(full = false) {
|
||||||
let onScreen = this.entities.filter(x => x && x.health > 0).length;
|
let onScreen = this.entities.filter(x => x && x.health > 0).length;
|
||||||
|
|
||||||
onScreen += 4;
|
onScreen += 4;
|
||||||
|
@ -31,12 +37,25 @@ class Game extends GameBasic {
|
||||||
if (entList.length == 0) return;
|
if (entList.length == 0) return;
|
||||||
|
|
||||||
for (let client of this.ws) {
|
for (let client of this.ws) {
|
||||||
if (!client.active) continue;
|
|
||||||
|
|
||||||
let wsEnt = client.ent;
|
let wsEnt = client.ent;
|
||||||
|
|
||||||
if (!wsEnt) continue;
|
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;
|
wsEnt.isYou = true;
|
||||||
|
|
||||||
let filtered;
|
let filtered;
|
||||||
|
|
11
index.js
11
index.js
|
@ -4,6 +4,10 @@ import Game from "./game.js";
|
||||||
import NPC from "./common/npc.js";
|
import NPC from "./common/npc.js";
|
||||||
import Player from "./common/player.js";
|
import Player from "./common/player.js";
|
||||||
|
|
||||||
|
import initDb from "./db.js";
|
||||||
|
|
||||||
|
let db = await initDb();
|
||||||
|
|
||||||
var app = express();
|
var app = express();
|
||||||
expressW(app);
|
expressW(app);
|
||||||
|
|
||||||
|
@ -15,6 +19,10 @@ app.use('/crypto.js', express.static('./common/crypto.js'));
|
||||||
app.use('/js', express.static('./common'));
|
app.use('/js', express.static('./common'));
|
||||||
app.use(express.static('./static'));
|
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) {
|
app.ws('/', function (ws, req) {
|
||||||
game.ws.push(ws);
|
game.ws.push(ws);
|
||||||
let player = new Player(false, true, game);
|
let player = new Player(false, true, game);
|
||||||
|
@ -23,9 +31,10 @@ app.ws('/', function (ws, req) {
|
||||||
|
|
||||||
ws.active = true;
|
ws.active = true;
|
||||||
ws.ent = player;
|
ws.ent = player;
|
||||||
|
ws.ip = req.headers["x-real-ip"];
|
||||||
|
|
||||||
// This will only work under NGINX.
|
// 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) {
|
ws.on('message', function message(msg) {
|
||||||
let data = {};
|
let data = {};
|
||||||
|
|
1498
package-lock.json
generated
1498
package-lock.json
generated
File diff suppressed because it is too large
Load diff
|
@ -2,7 +2,9 @@
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"crypto": "^1.0.1",
|
"crypto": "^1.0.1",
|
||||||
"express": "^4.21.0",
|
"express": "^4.21.0",
|
||||||
"express-ws": "^5.0.2"
|
"express-ws": "^5.0.2",
|
||||||
|
"sqlite": "^5.1.1",
|
||||||
|
"sqlite3": "^5.1.7"
|
||||||
},
|
},
|
||||||
"type": "module"
|
"type": "module"
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,6 +8,7 @@ section {
|
||||||
width: 800px;
|
width: 800px;
|
||||||
margin-left: auto;
|
margin-left: auto;
|
||||||
margin-right: auto;
|
margin-right: auto;
|
||||||
|
margin-bottom: 10px;
|
||||||
background: rgb(255, 255, 255);
|
background: rgb(255, 255, 255);
|
||||||
border: solid rgb(200, 200, 200) 2px;
|
border: solid rgb(200, 200, 200) 2px;
|
||||||
border-radius: 10px;
|
border-radius: 10px;
|
||||||
|
@ -27,7 +28,7 @@ h6 {
|
||||||
line-height: 40px;
|
line-height: 40px;
|
||||||
}
|
}
|
||||||
|
|
||||||
p {
|
p, pre, s {
|
||||||
margin: 10px;
|
margin: 10px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -17,6 +17,10 @@
|
||||||
<canvas id='canvas'></canvas>
|
<canvas id='canvas'></canvas>
|
||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
|
<section id='main'>
|
||||||
|
<h1>Leaderboard</h1>
|
||||||
|
<pre class='lb'></pre>
|
||||||
|
</section>
|
||||||
<script src='js/index.js' type="module"></script>
|
<script src='js/index.js' type="module"></script>
|
||||||
</body>
|
</body>
|
||||||
|
|
||||||
|
|
|
@ -212,7 +212,7 @@ class Game extends GameBasic {
|
||||||
|
|
||||||
if (this.entities.length == 0) this.entities = [this.player];
|
if (this.entities.length == 0) this.entities = [this.player];
|
||||||
}
|
}
|
||||||
init() {
|
async init() {
|
||||||
super.init();
|
super.init();
|
||||||
|
|
||||||
let that = this;
|
let that = this;
|
||||||
|
@ -229,6 +229,19 @@ class Game extends GameBasic {
|
||||||
setInterval(function () { that.render() }, 1000 / 60);
|
setInterval(function () { that.render() }, 1000 / 60);
|
||||||
|
|
||||||
game.canvas.onclick = () => that.click();
|
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');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue