diff --git a/src/api.ts b/src/api.ts new file mode 100644 index 0000000..279f0ce --- /dev/null +++ b/src/api.ts @@ -0,0 +1,236 @@ +import express, { Application } from "express"; +import { prisma } from "."; +import { Module } from "./module"; + + +export default class ApiModule extends Module { + register(app: Application): void { + + app.use(express.urlencoded({ + type: '*/*', + extended: true + })); + + + app.use(express.json({ + type: '*/*' + })); + + + // API Get Requests + // Get Current Bayshore Version + app.get('/api/bayshore_version', async (req, res) => { + let message: any = { + error: null, + version: null + }; + + let myJSON = '{'+ + '"version": "v1.0.0",'+ + '"log":'+ + '['+ + '"• Fix ghost play count when retiring ocm",'+ + '"• API for ocm ranking",'+ + '"• Fix unlimited ghost stamp return (hopefully no more of this)",'+ + '"• Fix give meter reward bug if playCount still 0",'+ + '"• Hopefully fix ocm HoF bug"'+ + '"• Fix duplicate id in carOrder"'+ + '"• Fix OCM HoF wrong shopName"'+ + ']'+ + '}'; + message.version = JSON.parse(myJSON); + + // Send the response to the client + res.send(message); + }) + + // Post Login + app.post('/api/login', async (req, res) => { + + // Get the request body + let query = req.query; + + // Message Response + let message: any = { + error: null, + user: null + }; + + // Get the user from the database + let user = await prisma.user.findFirst({ + where: { + chipId: { + startsWith: query.cardChipId?.toString() + }, + accessCode: query.accessCode?.toString() + }, + include: { + cars: { + select: { + state: true, + gtWing: true, + lastPlayedPlace: true, + carId: true, + name: true, + defaultColor: true, + visualModel: true, + level: true, + title: true, + regionId: true, + } + } + } + }); + + if(user) + { + message.user = user; + } + else + { + message.error = 404 + } + + // Send the response to the client + res.send(message); + }) + + + // Get Current Competition Id + app.get('/api/get_competition_id', async (req, res) => { + + // Get current date + let date = Math.floor(new Date().getTime() / 1000); + + // Message Response + let message: any = { + error: null, + competitionId: 1 // default + }; + + // Get current / previous active OCM Event + let ocmEventDate = await prisma.oCMEvent.findFirst({ + where: { + // qualifyingPeriodStartAt is less than current date + qualifyingPeriodStartAt: { lte: date }, + + // competitionEndAt is greater than current date + competitionEndAt: { gte: date }, + }, + orderBy: [ + { + dbId: 'desc' + }, + { + competitionEndAt: 'desc', + }, + ], + select:{ + competitionId: true + } + }); + + if(ocmEventDate) + { + message.competitionId = ocmEventDate.competitionId; + } + else{ + ocmEventDate = await prisma.oCMEvent.findFirst({ + orderBy: { + dbId: 'desc' + }, + select:{ + competitionId: true + } + }); + + message.competitionId = ocmEventDate!.competitionId; + } + + // Send the response to the client + res.send(message); + }); + + + // Get Current Competition Id + app.get('/api/get_hof_competition_id', async (req, res) => { + + // Message Response + let message: any = { + error: null, + competitionId: 1 // default + }; + + // Get current / previous active OCM Event + let ocmEventDate = await prisma.oCMTally.findFirst({ + where:{ + periodId: 999999999 + }, + orderBy: { + competitionId: 'desc' + }, + select:{ + competitionId: true + } + }); + + if(ocmEventDate) + { + message.competitionId = ocmEventDate.competitionId; + } + + // Send the response to the client + res.send(message); + }); + + + // Get Competition Ranking + app.get('/api/get_competition_ranking', async (req, res) => { + + // Get url query + let competitionId = Number(req.query.competitionId); + + // Message Response + let message: any = { + error: null, + cars: [], + lastPlayedPlace: 'Bayshore' + }; + + // Get all of the cars matching the query + message.cars = await prisma.oCMTally.findMany({ + where:{ + competitionId: competitionId + }, + orderBy: { + result: 'desc' + }, + include:{ + car: { + select:{ + carId: true, + name: true, + defaultColor: true, + visualModel: true, + level: true, + title: true, + regionId: true, + } + }, + } + }); + + let getLastPlayedPlace = await prisma.oCMGhostBattleRecord.findFirst({ + where:{ + carId: message.cars[0].carId, + competitionId: competitionId + } + }) + + message.lastPlayedPlace = getLastPlayedPlace?.playedShopName; + + // Send the response to the client + res.send(message); + }); + } +} \ No newline at end of file diff --git a/src/index.ts b/src/index.ts index df3baad..bb33a3a 100644 --- a/src/index.ts +++ b/src/index.ts @@ -9,6 +9,7 @@ import fs from 'fs'; import bodyParser from 'body-parser'; import AllnetModule from './allnet'; import MuchaModule from './mucha'; +import ApiModule from './api'; import { Config } from './config'; import process from 'process'; import * as Sentry from '@sentry/node'; @@ -30,8 +31,13 @@ const appRouter = Router(); const PORT_ALLNET = 80; const PORT_MUCHA = 10082; const PORT_BNGI = 9002; +const PORT_API = 9003; const app = express(); +const muchaApp = express(); +const allnetApp = express(); +const apiApp = express(); + app.use(bodyParser.raw({ type: '*/*' })); @@ -51,9 +57,6 @@ if (useSentry) { }); } -const muchaApp = express(); -const allnetApp = express(); - // Get the current timestamp let timestamp: string = common.getTimeStamp(); @@ -77,6 +80,11 @@ allnetApp.use((req, res, next) => { next() }); +/*apiApp.use((req, res, next) => { + console.log(timestamp+` [ API] ${req.method} ${req.url}`); + next() +});*/ + // Get all of the files in the modules directory let dirs = fs.readdirSync('dist/modules'); // Loop over the files @@ -108,11 +116,12 @@ app.all('*', (req, res) => { // Register the ALL.NET / Mucha Server new AllnetModule().register(allnetApp); new MuchaModule().register(muchaApp); +new ApiModule().register(apiApp); // Sentry is in use if (useSentry) { - // Use the sentry error handler + // Use the sentry error handler app.use(Sentry.Handlers.errorHandler()); } @@ -141,3 +150,8 @@ https.createServer({key, cert}, muchaApp).listen(PORT_MUCHA, '0.0.0.0', 511, () https.createServer({key, cert}, app).listen(PORT_BNGI, '0.0.0.0', 511, () => { console.log(`Game server listening on port ${PORT_BNGI}!`); }) + +// Create the API server +http.createServer(apiApp).listen(PORT_API, '0.0.0.0', 4369, () => { + console.log(`API server listening on port ${PORT_API}!`); +}) diff --git a/src/modules/cars.ts b/src/modules/cars.ts index 8eb9a02..3859d44 100644 --- a/src/modules/cars.ts +++ b/src/modules/cars.ts @@ -37,10 +37,12 @@ export default class CarModule extends Module { }); // Error handling if ghostLevel accidentally set to 0 or more than 10 - if(car!.ghostLevel < 1){ + if(car!.ghostLevel < 1) + { car!.ghostLevel = 1; } - if(car!.ghostLevel > 11){ + if(car!.ghostLevel > 11) + { car!.ghostLevel = 10; } @@ -160,7 +162,37 @@ export default class CarModule extends Module { trailId: trailIdNo1 }); } - + else + { + ghostTrailNo1 = await prisma.oCMGhostTrail.findFirst({ + where:{ + carId: getNo1OCM.carId, + competitionId: ocmEventDate.competitionId + }, + orderBy:{ + playedAt: 'desc' + } + }); + + if(ghostTrailNo1) + { + console.log('Getting registered ghost trail from other table'); + + trailIdNo1 = ghostTrailNo1.dbId; + + ghostCarsNo1 = wm.wm.protobuf.GhostCar.create({ + car: { + ...cars!, + }, + area: ghostTrailNo1.area, + ramp: ghostTrailNo1.ramp, + path: ghostTrailNo1.path, + nonhuman: false, + type: wm.wm.protobuf.GhostType.GHOST_NORMAL, + trailId: trailIdNo1 + }); + } + } } } } @@ -588,7 +620,6 @@ export default class CarModule extends Module { // Get the request body for the update car request let body = wm.wm.protobuf.UpdateCarRequest.decode(req.body); - console.log(body); // Get the ghost result for the car let cars = body?.car; diff --git a/src/modules/game.ts b/src/modules/game.ts index 805f924..00ce9de 100644 --- a/src/modules/game.ts +++ b/src/modules/game.ts @@ -193,7 +193,7 @@ export default class GameModule extends Module { let giveMeterReward = Config.getConfig().gameOptions.giveMeterReward; // Check if this feature activated and check if user's play count is n*100 play - if(giveMeterReward === 1 && body.playCount % 100 === 0) + if(giveMeterReward === 1 && body.playCount % 100 === 0 && body.playCount !== 0) { // Calling give meter reward function (BASE_PATH/src/util/meter_reward.ts) await meter_reward.giveMeterRewards(body); @@ -223,16 +223,15 @@ export default class GameModule extends Module { // Get the index of the selected car let index = carOrder.indexOf(body.carId); - // If the selected car is not first - if (index > 0) - { - // Remove that index from the array - carOrder.slice(index); - - // Add it back to the front - carOrder.unshift(body.carId); + // Only splice array when item is found + if (index > -1) + { + carOrder.splice(index, 1); // 2nd parameter means remove one item only } + // Add it back to the front + carOrder.unshift(body.carId); + // Otherwise, just ignore it // Update the values diff --git a/src/modules/ghost.ts b/src/modules/ghost.ts index fda1877..c3bb9b7 100644 --- a/src/modules/ghost.ts +++ b/src/modules/ghost.ts @@ -110,10 +110,29 @@ export default class GhostModule extends Module { } } - // Get all of the friend cars for the carId provided + // Get all of the challenger car for the carId provided except beated car + let checkBeatedCar = await prisma.carStampTarget.findMany({ + where: { + stampTargetCarId: body.carId, + recommended: false + }, + orderBy:{ + carId: 'asc' + } + }); + + let arrChallengerCarId = []; + for(let i=0; i