diff --git a/src/templates/kill.ts b/src/templates/kill.ts new file mode 100644 index 0000000..9756ddd --- /dev/null +++ b/src/templates/kill.ts @@ -0,0 +1,118 @@ +import { Router, Request, Response } from "express"; +import { validateErrors } from "../common"; +import { + checkOrCreateLoadout, + checkOrCreateWeapon, + checkUpdateOrCreatePlayer, + } from "../utils"; +import { KillData, validateBody, RequestBody } from "../types"; +import db from "../db"; +import typia from "typia"; + +const router = Router(); + +router.post( + "/kill", + validateBody(typia.createValidate()), + (req: RequestBody, res: Response) => { + void (async () => { + const host_id = res.locals.host_id; + const startTime = Date.now() + const { + game_time, + distance, + match_id, + attacker: attackerData, + victim: victimData, + cause_of_death, + } = req.body; + const attacker_id = Number(attackerData.id); + const victim_id = Number(victimData.id); + if (isNaN(attacker_id) || isNaN(victim_id)) { + res + .status(400) + .send({ errors: [{ msg: "attacker_id or victim_id is NaN" }] }); + return; + } + const match = await db + .selectFrom("ToneAPI_v3.match") + .select(["ToneAPI_v3.match.ongoing", "ToneAPI_v3.match.match_id"]) + .where("ToneAPI_v3.match.host_id", "=", host_id) + .where("ToneAPI_v3.match.match_id", "=", match_id) + .executeTakeFirst(); + if (!match) { + res.status(403).send({ + errors: [ + { + msg: "Match does not exists", + param: "match_id", + location: "body", + }, + ], + }); + return; + } + + if (!match.ongoing) { + res.status(409).send({ + errors: [ + { + msg: "Match is already closed", + param: "match_id", + location: "body", + }, + ], + }); + return; + } + let attacker_loadout: number | undefined; + let victim_loadout: number | undefined; + + await checkUpdateOrCreatePlayer( + { id: attacker_id, name: attackerData.name }); + await checkUpdateOrCreatePlayer( + { id: victim_id, name: victimData.name } + ); + await checkOrCreateWeapon(cause_of_death); + await checkOrCreateWeapon(attackerData.current_weapon.id); + await checkOrCreateWeapon(victimData.current_weapon.id); + await checkOrCreateLoadout(attackerData.loadout).then( + (e) => (attacker_loadout = e) + ); + await checkOrCreateLoadout(victimData.loadout).then( + (e) => (victim_loadout = e) + ); + if (attacker_loadout === undefined) { + throw new Error("attacker_loadout is undefined"); + } + if (victim_loadout === undefined) { + throw new Error("victim_loadout is undefined"); + } + const insertResult = await db + .insertInto("ToneAPI_v3.kill") + .values({ + attacker_id, + victim_id, + match_id, + attacker_loadout_id: attacker_loadout, + victim_loadout_id: victim_loadout, + attacker_speed: attackerData.velocity, + victim_speed: victimData.velocity, + attacker_movementstate: attackerData.state, + victim_movementstate: victimData.state, + distance, + game_time, + cause_of_death, + attacker_held_weapon: attackerData.current_weapon.id, + victim_held_weapon: victimData.current_weapon.id, + }) + .returning("kill_id") + .executeTakeFirstOrThrow(); + + res.status(201).send({ id: insertResult.kill_id }); + console.log(Date.now()-startTime) + })(); + } + ); + +export default router \ No newline at end of file diff --git a/src/templates/match.ts b/src/templates/match.ts new file mode 100644 index 0000000..7e2b36c --- /dev/null +++ b/src/templates/match.ts @@ -0,0 +1,103 @@ +import { Router, Response } from "express"; +import { param } from "express-validator"; +import { validateErrors } from "../common"; +import { MatchData, validateBody, RequestBody } from "../types"; +import db from "../db"; +import typia from "typia"; + +const router = Router(); + +router.post( + "/match", + validateBody(typia.createValidate()), + (req: RequestBody, res: Response) => { + void (async () => { + const host_id = res.locals.host_id; + const { air_accel, server_name, game_map, gamemode } = req.body; + const server = await db + .selectFrom("ToneAPI_v3.server") + .selectAll() + .where("ToneAPI_v3.server.host_id", "=", host_id) + .where("ToneAPI_v3.server.server_name", "=", server_name) + .executeTakeFirst(); + if (!server) { + await db + .insertInto("ToneAPI_v3.server") + .values({ host_id, server_name }) + .execute(); + } + + await db + .updateTable("ToneAPI_v3.match") + .set({ ongoing: false }) + .where("ToneAPI_v3.match.server_name", "=", server_name) + .execute(); + + const match = await db + .insertInto("ToneAPI_v3.match") + .values({ + air_accel, + server_name, + game_map, + gamemode, + host_id, + ongoing: true, + }) + .returning("ToneAPI_v3.match.match_id") + .executeTakeFirstOrThrow(); + + res.status(201).send({ match: match?.match_id }); + })(); + } + ); + + + router.post( + "/match/:matchId(\d+)/close", + param('matchId').exists().withMessage("Missing Match ID").bail().isNumeric().withMessage("Match ID is not numeric"), + validateErrors, + validateBody(typia.createValidate()), + (req: RequestBody, res: Response) => { + void (async () => { + const host_id = res.locals.host_id; + const { air_accel, server_name, game_map, gamemode } = req.body; + const server = await db + .selectFrom("ToneAPI_v3.server") + .selectAll() + .where("ToneAPI_v3.server.host_id", "=", host_id) + .where("ToneAPI_v3.server.server_name", "=", server_name) + .executeTakeFirst(); + if (!server) { + await db + .insertInto("ToneAPI_v3.server") + .values({ host_id, server_name }) + .execute(); + } + + await db + .updateTable("ToneAPI_v3.match") + .set({ ongoing: false }) + .where("ToneAPI_v3.match.server_name", "=", server_name) + .execute(); + + const match = await db + .insertInto("ToneAPI_v3.match") + .values({ + air_accel, + server_name, + game_map, + gamemode, + host_id, + ongoing: true, + }) + .returning("ToneAPI_v3.match.match_id") + .executeTakeFirstOrThrow(); + + res.status(201).send({ match: match?.match_id }); + })(); + } + ); + + + +export default router; \ No newline at end of file diff --git a/src/templates/server.ts b/src/templates/server.ts index beabbe7..09271cd 100644 --- a/src/templates/server.ts +++ b/src/templates/server.ts @@ -1,15 +1,12 @@ /* eslint-disable @typescript-eslint/naming-convention */ -import { Router, Request, Response } from "express"; +import { Router } from "express"; import { header } from "express-validator"; -import { - checkOrCreateLoadout, - checkOrCreateWeapon, - checkUpdateOrCreatePlayer, -} from "../utils"; -import db, { /* createKillRecord, */ checkServerToken } from "../db"; + +import { /* createKillRecord, */ checkServerToken } from "../db"; import { validateErrors } from "../common"; -import { KillData, MatchData, validateBody } from "../types"; -import typia from "typia"; + +import match from './match' +import kill from './kill' const router = Router(); @@ -82,154 +79,7 @@ router.post("/", (req, res) => { next() }) */ -type RequestBody = Request<{}, {}, T>; - -router.post( - "/kill", - // validateBody(typia.createValidate()), - (req: RequestBody, res: Response) => { - void (async () => { - const host_id = res.locals.host_id; - const startTime = Date.now() - const { - game_time, - distance, - match_id, - attacker: attackerData, - victim: victimData, - cause_of_death, - } = req.body; - const attacker_id = Number(attackerData.id); - const victim_id = Number(victimData.id); - if (isNaN(attacker_id) || isNaN(victim_id)) { - res - .status(400) - .send({ errors: [{ msg: "attacker_id or victim_id is NaN" }] }); - return; - } - const match = await db - .selectFrom("ToneAPI_v3.match") - .select(["ToneAPI_v3.match.ongoing", "ToneAPI_v3.match.match_id"]) - .where("ToneAPI_v3.match.host_id", "=", host_id) - .where("ToneAPI_v3.match.match_id", "=", match_id) - .executeTakeFirst(); - if (!match) { - res.status(403).send({ - errors: [ - { - msg: "Match does not exists", - param: "match_id", - location: "body", - }, - ], - }); - return; - } - - if (!match.ongoing) { - res.status(409).send({ - errors: [ - { - msg: "Match is already closed", - param: "match_id", - location: "body", - }, - ], - }); - return; - } - let attacker_loadout: number | undefined; - let victim_loadout: number | undefined; - - await checkUpdateOrCreatePlayer( - { id: attacker_id, name: attackerData.name }); - await checkUpdateOrCreatePlayer( - { id: victim_id, name: victimData.name } - ); - await checkOrCreateWeapon(cause_of_death); - await checkOrCreateWeapon(attackerData.current_weapon.id); - await checkOrCreateWeapon(victimData.current_weapon.id); - await checkOrCreateLoadout(attackerData.loadout).then( - (e) => (attacker_loadout = e) - ); - await checkOrCreateLoadout(victimData.loadout).then( - (e) => (victim_loadout = e) - ); - if (attacker_loadout === undefined) { - throw new Error("attacker_loadout is undefined"); - } - if (victim_loadout === undefined) { - throw new Error("victim_loadout is undefined"); - } - const insertResult = await db - .insertInto("ToneAPI_v3.kill") - .values({ - attacker_id, - victim_id, - match_id, - attacker_loadout_id: attacker_loadout, - victim_loadout_id: victim_loadout, - attacker_speed: attackerData.velocity, - victim_speed: victimData.velocity, - attacker_movementstate: attackerData.state, - victim_movementstate: victimData.state, - distance, - game_time, - cause_of_death, - attacker_held_weapon: attackerData.current_weapon.id, - victim_held_weapon: victimData.current_weapon.id, - }) - .returning("kill_id") - .executeTakeFirstOrThrow(); - - res.status(201).send({ id: insertResult.kill_id }); - console.log(Date.now()-startTime) - })(); - } -); - -router.post( - "/match", - // validateBody(typia.createValidate()), - (req: RequestBody, res: Response) => { - void (async () => { - const host_id = res.locals.host_id; - const { air_accel, server_name, game_map, gamemode } = req.body; - const server = await db - .selectFrom("ToneAPI_v3.server") - .selectAll() - .where("ToneAPI_v3.server.host_id", "=", host_id) - .where("ToneAPI_v3.server.server_name", "=", server_name) - .executeTakeFirst(); - if (!server) { - await db - .insertInto("ToneAPI_v3.server") - .values({ host_id, server_name }) - .execute(); - } - - await db - .updateTable("ToneAPI_v3.match") - .set({ ongoing: false }) - .where("ToneAPI_v3.match.server_name", "=", server_name) - .execute(); - - const match = await db - .insertInto("ToneAPI_v3.match") - .values({ - air_accel, - server_name, - game_map, - gamemode, - host_id, - ongoing: true, - }) - .returning("ToneAPI_v3.match.match_id") - .executeTakeFirstOrThrow(); - - res.status(201).send({ match: match?.match_id }); - })(); - } -); +router.use("/kill", kill) +router.use("/match", match) export default router;