import GameBasic from "./common/game_basic.js"; import NPC from "./common/npc.js"; import Shooter from "./common/shooter.js"; import fetch from "node-fetch"; import initDb from './db.js'; import { createHash } from "crypto"; let db = await initDb(); class Game extends GameBasic { constructor() { super(); this.ws = []; } async sync(full = false) { let onScreen = this.entities.filter(x => x && x.health > 0).length; onScreen += 4; this.width = (this.width * 0.99) + (Math.sqrt(onScreen) * 16); this.height = (this.height * 0.99) + (Math.sqrt(onScreen) * 16); let { entities } = this; let entList = []; for (let entity of entities) { entity.pos = { x: Math.round(entity.pos.x), y: Math.round(entity.pos.y) }; entity.vel = { x: Math.round(entity.vel.x), y: Math.round(entity.vel.y) }; entity.camera = entity.camera ? { x: Math.round(entity.camera.x), y: Math.round(entity.camera.y) } : false; let props = entity.serverProps; let basic = props.map(prop => entity[prop]); let str = JSON.stringify(basic); entList.push({ entity, str, basic }); } if (entList.length == 0) return; for (let client of this.ws) { let wsEnt = client.ent; if (!wsEnt) continue; if (full && wsEnt.health < 1 && !wsEnt.picked) { wsEnt.picked = true; let hash = client.username; if (!hash) { hash = createHash('sha256'); hash.update((+new Date) + ''); //hash.update(client.ip || ''); hash = hash.digest('hex'); } await db.run('INSERT INTO stats (username, ip, ko) VALUES (?,?,?)', [ wsEnt.you, hash, wsEnt.headCount ]); } if (!client.active) continue; wsEnt.isYou = true; let filtered; if (!full) { filtered = entList.filter(({ entity: ent }) => { return Math.sqrt((ent.pos.x - wsEnt.pos.x) ** 2 + (ent.pos.y - wsEnt.pos.y) ** 2) < 777 } ); } else { filtered = entList; } let na = []; for (let i in filtered) { let fi = filtered[i] na.push(fi.str) if (fi.entity.isYou) { let narr = [...fi.basic]; narr[fi.entity.serverProps.indexOf('isYou')] = 'true'; na[na.length - 1] = JSON.stringify(narr); } } na.push(JSON.stringify([this.width, this.height])) client.send(`[${na.join(',')}]`); wsEnt.isYou = false; } for (let entity of entities) { entity.r = 1; } } init() { super.init(); let that = this; that.entities = []; for (let i = 0; i < 20; i++) { that.entities.push(new NPC(false, that)) } for (let i = 0; i < 18; i++) { that.entities.push(new Shooter(false, that)) } setInterval(function () { that.sync(false) }, 1000 / 10); setInterval(function () { that.sync(true) }, 1000); setInterval(function () { that.clean() }, 1000); } clean() { for (let ent in this.entities) { let x = this.entities[ent]; if ( x.health > 0 || x.type != 'Player') return; this.entites[ent] = false; } } async authUser(ws, data) { ws.token = data; let f = new FormData(); f.append('token', ws.token); let j = await fetch("https://bg.xuyezo.net/api/form/auth_api/", { "method": "post", "body": f } ); j = await j.json(); if (j.username == '!nobody' || !j.username) return; if (this.ws.findIndex(x => x.username == j.username && x.ent.health > 0) != -1) { console.log(`Player ${ws.ent.you} uses username ${j.username} illegally`) return; } ws.ent.username = ws.username = j.username; console.log(`Player ${ws.ent.you} uses username ${ws.username}`) } } export default Game;