import { Application } from "express"; import {Module} from "module"; import { Config } from "../config"; import { prisma } from ".."; // Import Proto import * as wm from "../wmmt/wm.proto"; import * as wmsrv from "../wmmt/service.proto"; // Import Util import * as common from "../util/common"; export default class StartupModule extends Module { register(app: Application): void { // Register system info upon booting app.post('/method/register_system_info', async (req, res) => { // Get the request body for the load stamp target request let body = wm.wm.protobuf.RegisterSystemInfoRequest.decode(req.body); // Get current date let date = Math.floor(new Date().getTime() / 1000); // Get current / previous active OCM Event let ocmEventDate = await prisma.oCMEvent.findFirst({ orderBy: [ { dbId: 'desc' }, { competitionEndAt: 'desc', }, ], }); // Declare GhostCompetitionSchedule let compeSch; if(ocmEventDate) { let pastDay = date - ocmEventDate.competitionEndAt if(pastDay < 604800) { // Creating GhostCompetitionSchedule compeSch = wm.wm.protobuf.GhostCompetitionSchedule.create({ // OCM Competition ID (1 = C1 (Round 16), 4 = Nagoya (Round 19), 8 = Hiroshima (Round 21)) competitionId: ocmEventDate.competitionId, // OCM Qualifying Start Timestamp qualifyingPeriodStartAt: ocmEventDate.qualifyingPeriodStartAt, // OCM Qualifying Close Timestamp qualifyingPeriodCloseAt: ocmEventDate.qualifyingPeriodCloseAt, // OCM Competition (Main Draw) Start Timestamp competitionStartAt: ocmEventDate.competitionStartAt, // OCM Competition (Main Draw) Close Timestamp competitionCloseAt: ocmEventDate.competitionCloseAt, // OCM Competition (Main Draw) End Timestamp competitionEndAt: ocmEventDate.competitionEndAt, // idk what this is lengthOfPeriod: ocmEventDate.lengthOfPeriod, // idk what this is lengthOfInterval: ocmEventDate.lengthOfInterval, // Area for the event (GID_RUNAREA_*, 8 is GID_RUNAREA_NAGOYA) area: ocmEventDate.area, // idk what this is minigamePatternId: ocmEventDate.minigamePatternId }); } } // Response data let msg = { error: wm.wm.protobuf.ErrorCode.ERR_SUCCESS, regionId: body.allnetRegion0, placeId: body.regionName0, allowedClientLogTypes: [], ghostSelectionMinRedoWait: 30, ghostSelectionMaxRedoWait: 4000, featureVersion: { version: 9, year: 2022, month: 7, pluses: 0, releaseAt: 0 // idk what this is }, competitionSchedule: compeSch || null // OCM Event Available or not } // Encode the response let message = wm.wm.protobuf.RegisterSystemInfoResponse.encode(msg); // Send the response to the client common.sendResponse(message, res); }) // Place List app.get('/resource/place_list', (req, res) => { console.log('place list'); // Empty list of place records let places: wm.wm.protobuf.Place[] = []; // Response data places.push(new wm.wm.protobuf.Place({ placeId: "JPN0123", regionId: 1, shopName: Config.getConfig().shopName, country: "JPN" })); // Encode the response let message = wm.wm.protobuf.PlaceList.encode({places}); // Send the response to the client common.sendResponse(message, res); }) // Get Ranking data for attract screen (TA, Ghost, VS) app.get('/resource/ranking', async (req, res) => { console.log('ranking'); // Empty list of all ranking records (Combination of TA, VS Stars, and Ghost Battle Win) let lists: wmsrv.wm.protobuf.Ranking.List[] = []; // Get TA Ranking for(let i=0; i<25; i++){ // GID_TACOURSE ID // Get the TA time per course let ta_time = await prisma.timeAttackRecord.findMany({ where: { course: i }, orderBy: { time: 'asc' }, take: 10, // Take top 10 }); // TA time record by user is available for certain course if(ta_time.length > 0){ // Empty list of ranking records for user time attack let list_ta: wmsrv.wm.protobuf.Ranking.Entry[] = []; // Get the TA time data for(let j=0; j { console.log('ping'); let body = wm.wm.protobuf.PingRequest.decode(req.body); // Response data let ping = { error: wm.wm.protobuf.ErrorCode.ERR_SUCCESS, pong: body.ping || 1 }; // Encode the response let message = wm.wm.protobuf.PingResponse.encode(ping); // Send the response to the client common.sendResponse(message, res); }) // Crown List for attract screen and Crown Ghost Battle mode app.get('/resource/crown_list', async (req, res) => { console.log('crown_list'); // Empty list of crown records let list_crown: wmsrv.wm.protobuf.Crown[] = []; // Get the crown holder data let car_crown = await prisma.carCrown.findMany({ orderBy: { area: 'asc' } }); // Crown holder data available if(car_crown.length !== 0){ let counter = 0; // Loop GID_RUNAREA for(let i=0; i<19; i++){ // 14 - 16 are dummy area, 17 is C1 Closed if(i >= 14){ i = 18; // GID_RUNAREA_HIROSHIMA } // Crown holder for certain area available if(car_crown[counter].area === i){ // Get user's data let car = await prisma.car.findFirst({ where: { carId: car_crown[counter].carId }, include: { gtWing: true } }); // If regionId is 0 or not set, game will crash after defeating the ghost if(car!.regionId === 0) { /* Region Id 01 = Hokkaido 北海道 02 = Aomori 青森 03 = Iwate 岩手 04 = Miyagi 宮城 05 = Akita 秋田 06 = Yamagata 山形 07 = Fukushima 福島 08 = Ibaraki 茨城 09 = Tochigi 栃木 10 = Gunma 群馬 11 = Saitama 埼玉 12 = Chiba 千葉 13 = Tokyo 東京 19 = Yamanashi 山梨 */ car!.regionId = i + 1; // Change car region id } // Set the tunePower used when capturing ghost crown car!.tunePower = car_crown[counter].tunePower; // Set the tunePower used when capturing ghost crown car!.tuneHandling = car_crown[counter].tuneHandling; // Error handling if played At timestamp value is current date and timestamp is bigger than 9 July 2022 (using GMT+7 timestamp) if(car_crown[counter].playedAt !== 0 && car_crown[counter].playedAt >= 1657299600) { // Acquired crown timestamp - 1 day car!.lastPlayedAt = car_crown[counter].playedAt - 172800; // Acquired crown timestamp - 1 day car_crown[counter].playedAt = car_crown[counter].playedAt - 172800; } // Error handling if played At timestamp value is 0 or timestamp is less than 9 July 2022 (using GMT+7 timestamp) else if(car_crown[counter].playedAt === 0 || car_crown[counter].playedAt < 1657299600) { // Acquired crown timestamp become 9 July 2022 (using GMT+7 timestamp) car!.lastPlayedAt = 1657299600; // Acquired crown timestamp become 9 July 2022 (using GMT+7 timestamp) car_crown[counter].playedAt = 1657299600; } let playedPlace = wm.wm.protobuf.Place.create({ placeId: 'JPN0123', shopName: Config.getConfig().shopName, regionId: 18, country: 'JPN' }); // Push the car data to the crown holder data list_crown.push(wmsrv.wm.protobuf.Crown.create({ carId: car_crown[counter].carId, area: car_crown[counter].area, // GID_RUNAREA_C1 - GID_RUNAREA_TURNPIKE & GID_RUNAREA_HIROSHIMA unlockAt: car_crown[counter].playedAt, car: { ...car!, lastPlayedPlace: playedPlace } })); if(counter < car_crown.length-1){ counter++; } } // Crown holder for certain area not available else{ // Push the default data by the game to the crown holder data list_crown.push(wmsrv.wm.protobuf.Crown.create({ carId: i, area: i, // GID_RUNAREA_C1 - GID_RUNAREA_TURNPIKE & GID_RUNAREA_HIROSHIMA unlockAt: 0, })); } } } // There is no user's crown holder data available else{ // Loop GID_RUNAREA for(let i=0; i<19; i++){ // 14 - 16 are dummy area, 17 is C1 Closed if(i >= 14){ i = 18; // GID_RUNAREA_HIROSHIMA } // Push the default data by the game to the crown holder data list_crown.push(wmsrv.wm.protobuf.Crown.create({ carId: i, area: i, // GID_RUNAREA_C1 - GID_RUNAREA_TURNPIKE & GID_RUNAREA_HIROSHIMA unlockAt: 0, })); } } // Response data let msg = { crowns: list_crown }; // Encode the response let message = wmsrv.wm.protobuf.CrownList.encode(msg); // Send the response to the client common.sendResponse(message, res); }) } }