diff --git a/src/index.ts b/src/index.ts index 5a8ebea..afa1cc9 100644 --- a/src/index.ts +++ b/src/index.ts @@ -24,7 +24,7 @@ import MuchaModule from './mucha'; import { Config } from './config'; import * as Sentry from '@sentry/node'; import * as Tracing from '@sentry/tracing'; -import * as common from './util/common'; +import * as common from './modules/util/common'; globalAgent.options.keepAlive = true; diff --git a/src/modules/cars.ts b/src/modules/cars.ts index 7b0a3d8..d164244 100644 --- a/src/modules/cars.ts +++ b/src/modules/cars.ts @@ -1,17 +1,13 @@ import { Application } from "express"; -import { Config } from "../config"; import { Module } from "module"; import { prisma } from ".."; -import { User } from "@prisma/client"; -import Long from "long"; // Import Proto import * as wm from "../wmmt/wm.proto"; // Import Util -import * as common from "../util/common"; -import * as scratch from "../util/scratch"; -import * as terminal from "../util/terminal/check_car"; +import * as common from "./util/common"; +import * as carFunctions from "./cars/functions"; export default class CarModule extends Module { @@ -24,189 +20,24 @@ export default class CarModule extends Module { let body = wm.wm.protobuf.LoadCarRequest.decode(req.body); // Get the car (required data only) with the given id - let car = await prisma.car.findFirst({ - where: { - carId: body.carId - }, - include: { - settings: true, - items: true, - gtWing: true, - lastPlayedPlace: true, - } - }); + let car = await carFunctions.getCar(body.carId); - // Error handling if ghostLevel accidentally set to 0 or more than 10 - if(car!.ghostLevel < 1) - { - car!.ghostLevel = 1; - } - if(car!.ghostLevel > 11) - { - car!.ghostLevel = 10; - } + // Get Challenger Data + let registeredTarget = await carFunctions.getRegisteredTarget(body.carId); - // Convert the database lose bits to a Long - let longLoseBits = Long.fromString(car!.stLoseBits.toString()); - - // Get Registered Target - let getTarget = await prisma.ghostRegisteredFromTerminal.findFirst({ - where:{ - carId: body.carId - } - }); - let opponentGhost; - let opponentTrailId; - let opponentCompetitionId; - let registeredTarget: boolean = false; - - if(getTarget) - { - console.log('Registered Opponents Available'); - - let getTargetTrail = await prisma.oCMTop1GhostTrail.findFirst({ - where:{ - carId: getTarget.opponentCarId, - competitionId: Number(getTarget.competitionId) - }, - orderBy:{ - periodId: 'desc' - } - }); - - if(getTargetTrail) - { - let getTargetCar = await prisma.car.findFirst({ - where:{ - carId: getTarget.opponentCarId - }, - include:{ - gtWing: true, - lastPlayedPlace: true - } - }); - - opponentGhost = wm.wm.protobuf.GhostCar.create({ - car: { - ...getTargetCar!, - tunePower: getTargetTrail!.tunePower, - tuneHandling: getTargetTrail!.tuneHandling, - }, - area: getTargetTrail!.area, - ramp: getTargetTrail!.ramp, - path: getTargetTrail!.path, - nonhuman: false, - type: wm.wm.protobuf.GhostType.GHOST_NORMAL, - trailId: getTargetTrail!.dbId - }); - opponentTrailId = Number(getTargetTrail!.dbId); - opponentCompetitionId = Number(getTarget.competitionId); - } - - registeredTarget = true; - } - - // Check opponents stamp target - // Will skip this if user's have Hall of Fame ghost registered - let carsChallengers; - let returnCount = 1; - let opponentTargetCount = 0; - if(registeredTarget === false) - { - opponentTargetCount = await prisma.carStampTarget.count({ - where:{ - stampTargetCarId: body.carId, - recommended: true, - }, - orderBy:{ - locked: 'desc' - } - }) - - if(opponentTargetCount > 0) - { - console.log('Challengers Available'); - - // Randomize pick - let random: number = 1; - - // Randomize it 5 times - for(let i=0; i<5; i++) - { - random = Math.floor(Math.random() * opponentTargetCount); - } - - // Try randomize it again if it's 1 - if(random === 1) - { - random = Math.floor(Math.random() * opponentTargetCount); - } - - // Check opponents target - let opponentTarget = await prisma.carStampTarget.findMany({ - where:{ - stampTargetCarId: body.carId, - recommended: true, - }, - orderBy:{ - locked: 'desc' - }, - skip: random, - take: 1, - }); - - // Get all of the friend cars for the carId provided - let challengers = await prisma.carChallenger.findFirst({ - where: { - challengerCarId: opponentTarget[0].carId, - carId: body.carId - }, - orderBy:{ - id: 'desc' - } - }); - - if(challengers) - { - returnCount = opponentTarget[0].returnCount; - - let carTarget = await prisma.car.findFirst({ - where:{ - carId: challengers.challengerCarId - }, - include:{ - gtWing: true, - lastPlayedPlace: true - } - }) - - let result = 0; - if(challengers.result > 0) - { - result = -Math.abs(challengers.result); - } - else{ - result = Math.abs(challengers.result); - } - - carsChallengers = wm.wm.protobuf.ChallengerCar.create({ - car: carTarget!, - stamp: challengers.stamp, - result: result, - area: challengers.area - }); - } - } - } - - + // Get Challenger Data + let opponentsTarget = await carFunctions.getOpponentsTarget(body.carId, registeredTarget.registeredargetAvailable); // Response data let msg = { error: wm.wm.protobuf.ErrorCode.ERR_SUCCESS, - car: { - ...car!, - }, + + // wm.protobuf.Car; + car: car, + + // Other Car Data (tuningPoint, odometer, playCount, etc) + ...car, + stLoseBits: car.longLoseBits, tuningPoint: car!.tuningPoints, setting: car!.settings, rgPreviousVersionPlayCount: 0, @@ -214,21 +45,22 @@ export default class CarModule extends Module { auraMotifAutoChange: false, screenshotCount: 0, transferred: false, - ...car!, - stLoseBits: longLoseBits, - ownedItems: car!.items, - lastPlayedAt: car!.lastPlayedAt, - announceEventModePrize: true, // Stamp or Challenger - challenger: carsChallengers || null, - challengerReturnCount: returnCount || null, - numOfChallengers: opponentTargetCount + 1 || null, + challenger: opponentsTarget.challenger, + challengerReturnCount: opponentsTarget.challengerReturnCount, + numOfChallengers: opponentsTarget.numOfChallengers, // OCM Challenge Top 1 - opponentGhost: opponentGhost || null, - opponentTrailId: opponentTrailId || null, - opponentCompetitionId: opponentCompetitionId || null + opponentGhost: registeredTarget.opponentGhost, + opponentTrailId: registeredTarget.opponentTrailId, + opponentCompetitionId: registeredTarget.opponentCompetitionId, + + // Owned Item + ownedItems: car.items, + + // Announce Event Mode Prize + announceEventModePrize: true }; // Generate the load car response message @@ -245,274 +77,18 @@ export default class CarModule extends Module { // Get the request body for the create car request let body = wm.wm.protobuf.CreateCarRequest.decode(req.body); - // Get the current date/time (unix epoch) - let date = Math.floor(new Date().getTime() / 1000) + // Create the Car + let createCar = await carFunctions.createCar(body); + let tune = createCar.tune; + let carInsert = createCar.carInsert; - // Retrieve user from card chip / user id - let user: User | null; - - // User ID provided, use that - if (body.userId) { - user = await prisma.user.findFirst({ - where: { - id: body.userId - }, - }); - } else { // No user id, use card chip - user = await prisma.user.findFirst({ - where: { - chipId: body.cardChipId, - accessCode: body.accessCode - }, - }) - } - - // User not found, terminate - if (!user) throw new Error(); - - // Generate blank car settings object - let settings = await prisma.carSettings.create({ - data: {} - }); - - // Generate blank car state object - let state = await prisma.carState.create({ - data: {} - }) - - let gtWing = await prisma.carGTWing.create({ - data: {} - }) - - // Sets if full tune is used or not - // let fullyTuned = false; - - // 0: Stock Tune - // 1: Basic Tune (600 HP) - // 2: Fully Tuned (840 HP) - let tune = 0; - - // If a user item has been used - if (body.userItemId) - { - console.log(`Item used - ID ${body.userItemId}`); - - // Remove the user item from the database - let item = await prisma.userItem.delete({ - where: { - userItemId: body.userItemId - } - }); - - console.log('Item deleted!'); - - switch(item.category) - { - case 203: // Car Tune Ticket - - // Switch on item id - switch(item.itemId) - { - // Discarded Vehicle Card - case 1: tune = 1; break; - case 2: tune = 1; break; - case 3: tune = 1; break; - - // Fully Tuned Ticket - case 5: tune = 2; break; - - default: // Unknown item type, throw unsupported error - throw Error("Unsupported itemId: " + item.itemId); - } - break; - - case 201: // Special Car Ticket - - // Fully tuned special cars - if (scratch.fullyTunedCars.includes(item.itemId)) - { - // Car is fully tuned - tune = 2; - } - // Basic tuned special cars - if (scratch.basicTunedCars.includes(item.itemId)) - { - // If gift cars fully tuned is set - if (Config.getConfig().gameOptions.giftCarsFullyTuned) - { - // Car is fully tuned - tune = 2; - } - else // Gift cars fully tuned not set - { - // Car is basic tuned - tune = 1; - } - } - // Stock tuned special cars - if (scratch.stockTunedCars.includes(item.itemId)) - { - // If gift cars fully tuned is set - if (Config.getConfig().gameOptions.giftCarsFullyTuned) - { - // Car is fully tuned - tune = 2; - } - else // Gift cars fully tuned not set - { - // Car is stock - tune = 0; - } - } - break; - } - console.log(`Item category was ${item.category} and item game ID was ${item.itemId}`); - } - - // Other cases, may occur if item is not detected as 'used' - - // User item not used, but car has 740 HP by default - else if (body.car && - (body.car.tunePower == 17) && (body.car.tuneHandling == 17)) - { - // Car is fully tuned - tune = 2; - - // Check if created car is from terminal scratch car - await terminal.checkScratchCar(body.userId, body.car.visualModel!) - } - // User item not used, but car has 600 HP by default - else if (body.car && - (body.car.tunePower == 10) && (body.car.tuneHandling == 10)) - { - // Car is basic tuned - tune = 1; - } - // User item not used, but gift cars fully tuned switch is set - else if (Config.getConfig().gameOptions.giftCarsFullyTuned) - { - // List of event / exclusive car IDs - let event_cars = [ - 0x7A, // Mini - 0x82, // S660 - 0x83, // S2000 - 0x89, // NDERC - 0x8B, // GS130 (Starts at 20 Stories by default) - ]; - - // If the car visual model is not null and is in the list of event cars - if (body.car.visualModel && event_cars.includes(body.car.visualModel)) - { - // Set full tune used to be true - tune = 2; - } - } - - // Randomize regionId - let regionId: number = 18; - - // Randomize it 5 times - for(let i=0; i<5; i++) - { - regionId = Math.floor(Math.random() * 47) + 1; - } - - // Try randomize it again if it's 1 - if(regionId === 1) - { - regionId = Math.floor(Math.random() * 47) + 1; - } + // Check if user's other car have unique window sticker + let windowSticker = await carFunctions.getWindowSticker(body.userId); + let additionalWindowStickerInsert = windowSticker.additionalWindowStickerInsert - // Default car values - let carInsert = { - userId: user.id, - manufacturer: body.car.manufacturer!, - defaultColor: body.car.defaultColor!, - model: body.car.model!, - visualModel: body.car.visualModel!, - name: body.car.name!, - title: body.car.title!, - level: body.car.level!, - tunePower: body.car.tunePower!, - tuneHandling: body.car.tuneHandling!, - carSettingsDbId: settings.dbId, - carStateDbId: state.dbId, - carGTWingDbId: gtWing.dbId, - regionId: regionId, - lastPlayedAt: date, - lastPlayedPlaceId: 1, // Server Default - }; - - // Check if user have more than one cars - let checkWindowSticker = await prisma.car.findFirst({ - where: { - userId: body.userId - }, - select: { - windowStickerString: true, - windowStickerFont: true - } - }); - let additionalWindowStickerInsert = { - - } - - // If more than one cars, get the window sticker string - if(checkWindowSticker) - { - additionalWindowStickerInsert = { - windowStickerString: checkWindowSticker.windowStickerString, - windowStickerFont: checkWindowSticker.windowStickerFont, - } - } - - // Additional car values (for basic / full tune) - let additionalInsert = { - - } - - // Switch on tune status - switch(tune) - { - // 0: Stock, nothing extra - - case 1: // Basic Tune - - // Updated default values - carInsert.level = 2; // C8 - carInsert.tunePower = 10; // 600 HP - carInsert.tuneHandling = 10; // 600 HP - - // Additional basic tune values - additionalInsert = { - ghostLevel: 4, - stClearBits: 0, - stLoseBits: 0, - stClearCount: 20, - stClearDivCount: 1, - stConsecutiveWins: 20, - stConsecutiveWinsMax: 20 - }; - break; - - case 2: // Fully Tuned - - // Updated default values - carInsert.level = 8; // C3 - carInsert.tunePower = 17; // 740 HP - carInsert.tuneHandling = 17; // 740 HP - - // Additional full tune values - additionalInsert = { - ghostLevel: 10, - stClearBits: 0, - stLoseBits: 0, - stClearCount: 80, - stClearDivCount: 4, - stConsecutiveWins: 80, - stConsecutiveWinsMax: 80 - }; - } + /// Switch on tune status + let getCarTune = await carFunctions.getCarTune(tune, carInsert); + let additionalInsert = getCarTune.additionalInsert; // Insert the car into the database let car = await prisma.car.create({ @@ -524,30 +100,26 @@ export default class CarModule extends Module { }); // Get the user's current car order - let carOrder = user.carOrder; - - // Add the new car to the front of the id - carOrder.unshift(car.carId); - - // Add the car to the front of the order - await prisma.user.update({ - where: { - id: user.id - }, - data: { - carOrder: carOrder - } - }); - - console.log(`Created new car ${car.name} with ID ${car.carId}`); + let carOrder = createCar.user.carOrder; + await carFunctions.carOrder(carOrder, car, createCar.user.id); // Response data let msg = { error: wm.wm.protobuf.ErrorCode.ERR_SUCCESS, + + // User ID + accessCode: body.accessCode, + banapassportAmId: body.banapassportAmId, + //mbid: number|null, + + // Car Data carId: car.carId, car, ...carInsert, - ...additionalInsert + ...additionalInsert, + + // Expiring Full Tuned Ticket + //fullTunedCarCouponUnreceivableAt: number|null } // Generate the load car response message @@ -564,105 +136,21 @@ export default class CarModule extends Module { // Get the request body for the update car request let body = wm.wm.protobuf.UpdateCarRequest.decode(req.body); - // Get the ghost result for the car - let cars = body?.car; + // Update the car + await carFunctions.updateCar(body); - // Declare data - let data : any; + // Update the car setting + await carFunctions.updateCarSetting(body); - // Car is set - if (cars) - { - // Get current date - let date = Math.floor(new Date().getTime() / 1000); + // Update the car window Sticker + await carFunctions.updateCarWindowSticker(body); - // Car update data - data = { - customColor: common.sanitizeInput(cars.customColor), - wheel: common.sanitizeInput(cars.wheel), - wheelColor: common.sanitizeInput(cars.wheelColor), - aero: common.sanitizeInput(cars.aero), - bonnet: common.sanitizeInput(cars.bonnet), - wing: common.sanitizeInput(cars.wing), - mirror: common.sanitizeInput(cars.mirror), - neon: common.sanitizeInput(cars.neon), - trunk: common.sanitizeInput(cars.trunk), - plate: common.sanitizeInput(cars.plate), - plateColor: common.sanitizeInput(cars.plateColor), - plateNumber: common.sanitizeInput(cars.plateNumber), - windowSticker: common.sanitizeInput(cars.windowSticker), - windowDecoration: common.sanitizeInput(cars.windowDecoration), - rivalMarker: common.sanitizeInput(cars.rivalMarker), - aura: common.sanitizeInput(cars.aura), - auraMotif: common.sanitizeInput(cars.auraMotif), - rgStamp: common.sanitizeInputNotZero(body.rgStamp), - lastPlayedAt: date - } - - // Update the car info - await prisma.car.update({ - where: { - carId: body.carId - }, - data: data - }) - } - - // Get the car with the given id - let car = await prisma.car.findFirst({ - where: { - carId: body.carId - }, - include: { - settings: true, - gtWing: true, - lastPlayedPlace: true - } - }); - - // Update the car settings - await prisma.carSettings.update({ - where: { - dbId: car?.carSettingsDbId, - }, - data: { - ...body.setting - } - }); - - // Update the user data - let userData = await prisma.car.findFirst({ - where:{ - carId: body.carId - }, - select:{ - userId: true, - windowStickerString: true - } - }) - - // Newer window sticker string is different from the older one - // Check if window sticker string is not null - // (windowStickerString value when changing custom color in driver unit is undefined) - if(body.car?.windowStickerString) - { - if(userData!.windowStickerString !== body.car.windowStickerString){ - console.log('Updating Window Sticker'); - - await prisma.car.updateMany({ - where: { - userId: userData!.userId - }, - data: { - windowStickerString: body.car.windowStickerString, - windowStickerFont: body.car.windowStickerFont! - } - }) - } - } + // Update the car Custom Wing + await carFunctions.updateCarCustomWing(body); // Get car item (custom color or discarded card) - if(body.earnedItems.length !== 0){ + if(body.earnedItems.length !== 0) + { console.log('Car Item reward available, continuing ...'); for(let i=0; i 11) + { + car!.ghostLevel = 10; + } + + // Convert the database lose bits to a Long + let longLoseBits = Long.fromString(car!.stLoseBits.toString()); + + return { ...car!, longLoseBits } +} + + +// Get Opponents Target +export async function getRegisteredTarget(carId: number) +{ + // Get Registered Target + let getTarget = await prisma.ghostRegisteredFromTerminal.findFirst({ + where:{ + carId: carId + } + }); + let opponentGhost; + let opponentTrailId; + let opponentCompetitionId; + let registeredargetAvailable: boolean = false; + + if(getTarget) + { + console.log('Registered Opponents Available'); + + let getTargetTrail = await prisma.oCMTop1GhostTrail.findFirst({ + where:{ + carId: getTarget.opponentCarId, + competitionId: Number(getTarget.competitionId) + }, + orderBy:{ + periodId: 'desc' + } + }); + + if(getTargetTrail) + { + let getTargetCar = await prisma.car.findFirst({ + where:{ + carId: getTarget.opponentCarId + }, + include:{ + gtWing: true, + lastPlayedPlace: true + } + }); + + opponentGhost = wmproto.wm.protobuf.GhostCar.create({ + car: { + ...getTargetCar!, + tunePower: getTargetTrail!.tunePower, + tuneHandling: getTargetTrail!.tuneHandling, + }, + area: getTargetTrail!.area, + ramp: getTargetTrail!.ramp, + path: getTargetTrail!.path, + nonhuman: false, + type: wmproto.wm.protobuf.GhostType.GHOST_NORMAL, + trailId: getTargetTrail!.dbId + }); + opponentTrailId = Number(getTargetTrail!.dbId); + opponentCompetitionId = Number(getTarget.competitionId); + } + + registeredargetAvailable = true; + } + + return { opponentGhost, opponentTrailId, opponentCompetitionId, registeredargetAvailable } +} + + +// Get Opponents Target +export async function getOpponentsTarget(carId: number, registeredargetAvailable: boolean) +{ + // Check opponents stamp target + // Will skip this if user's have Hall of Fame ghost registered + let challenger; + let challengerReturnCount = 1; + let opponentTargetCount = 0; + let numOfChallengers: number = 0; + if(registeredargetAvailable === false) + { + // Check opponents target + opponentTargetCount = await prisma.carStampTarget.count({ + where:{ + stampTargetCarId: carId, + recommended: true, + }, + orderBy:{ + locked: 'desc' + } + }); + + if(opponentTargetCount > 0) + { + console.log('Challengers Available'); + + // Randomize pick + let random: number = 1; + + // Randomize it 5 times + for(let i=0; i<5; i++) + { + random = Math.floor(Math.random() * opponentTargetCount); + } + + // Try randomize it again if it's 1 + if(random === 1) + { + random = Math.floor(Math.random() * opponentTargetCount); + } + + // Check opponents target + let opponentTarget = await prisma.carStampTarget.findMany({ + where:{ + stampTargetCarId: carId, + recommended: true, + }, + orderBy:{ + locked: 'desc' + }, + skip: random, + take: 1, + }); + + // Get Opponents Challengers + let carChallengers = await prisma.carChallenger.findFirst({ + where: { + challengerCarId: opponentTarget[0].carId, + carId: carId + }, + orderBy:{ + id: 'desc' + } + }); + + // Challengers Available + if(carChallengers) + { + // Get Shuttle + challengerReturnCount = opponentTarget[0].returnCount; + + // Get Car Target + let carTarget = await prisma.car.findFirst({ + where:{ + carId: carChallengers.challengerCarId + }, + include:{ + gtWing: true, + lastPlayedPlace: true + } + }); + + // Car Target Available + if(carTarget) + { + // Get Advantage + let result = 0; + if(carChallengers.result > 0) + { + result = -Math.abs(carChallengers.result); + } + else{ + result = Math.abs(carChallengers.result); + } + + // Push the data + challenger = wmproto.wm.protobuf.ChallengerCar.create({ + car: carTarget, + stamp: carChallengers.stamp, + result: result, + area: carChallengers.area + }); + } + } + + // Get Number of Challengers + numOfChallengers = opponentTarget.length + 1; + } + } + + + return { challenger, challengerReturnCount, numOfChallengers } +} + + +// Create Car +export async function createCar(body: wm.protobuf.CreateCarRequest) +{ + // Get the current date/time (unix epoch) + let date = Math.floor(new Date().getTime() / 1000); + + // Retrieve user from card chip / user id + let user: User | null; + + // User ID provided, use that + if (body.userId) + { + user = await prisma.user.findFirst({ + where: { + id: body.userId + }, + }); + } + // No user id, use card chip + else + { + user = await prisma.user.findFirst({ + where: { + chipId: body.cardChipId, + accessCode: body.accessCode + }, + }); + } + + // User not found, terminate + if (!user) throw new Error(); + + // Generate blank car settings object + let settings = await prisma.carSettings.create({ + data: {} + }); + + // Generate blank car state object + let state = await prisma.carState.create({ + data: {} + }); + + let gtWing = await prisma.carGTWing.create({ + data: {} + }); + + // Sets if full tune is used or not + // let fullyTuned = false; + + // 0: Stock Tune + // 1: Basic Tune (600 HP) + // 2: Fully Tuned (840 HP) + let tune = 0; + + // If a user item has been used + if (body.userItemId) + { + let carUtilFunctions = await car_tune.createCarWithItem(body.userItemId); + + tune = carUtilFunctions.tune; + } + // Other cases, may occur if item is not detected as 'used' + // User item not used, but car has 740 HP by default + else if (body.car && body.car.tunePower == 17 && body.car.tuneHandling == 17) + { + // Car is fully tuned + tune = 2; + + // Check if created car is from terminal scratch car + await terminal.checkScratchCar(body.userId, body.car.visualModel!) + } + // User item not used, but car has 600 HP by default + else if (body.car && body.car.tunePower == 10 && body.car.tuneHandling == 10) + { + // Car is basic tuned + tune = 1; + } + // User item not used, but gift cars fully tuned switch is set + else if (Config.getConfig().gameOptions.giftCarsFullyTuned) + { + // List of event / exclusive car IDs + let event_cars = [ + 0x7A, // Mini + 0x82, // S660 + 0x83, // S2000 + 0x89, // NDERC + 0x8B, // GS130 (Starts at 20 Stories by default) + ]; + + // If the car visual model is not null and is in the list of event cars + if (body.car.visualModel && event_cars.includes(body.car.visualModel)) + { + // Set full tune used to be true + tune = 2; + } + } + + // Randomize regionId + let regionId: number = 18; + + // Randomize it 5 times + for(let i=0; i<5; i++) + { + regionId = Math.floor(Math.random() * 47) + 1; + } + + // Try randomize it again if it's 1 + if(regionId === 1) + { + regionId = Math.floor(Math.random() * 47) + 1; + } + + // Error handling if regionId is above 47 + if(regionId > 47) + { + regionId = 47 + } + + // Default car values + let carInsert = { + userId: user.id, + manufacturer: body.car.manufacturer!, + defaultColor: body.car.defaultColor!, + model: body.car.model!, + visualModel: body.car.visualModel!, + name: body.car.name!, + title: body.car.title!, + level: body.car.level!, + tunePower: body.car.tunePower!, + tuneHandling: body.car.tuneHandling!, + carSettingsDbId: settings.dbId, + carStateDbId: state.dbId, + carGTWingDbId: gtWing.dbId, + regionId: regionId, + lastPlayedAt: date, + lastPlayedPlaceId: 1, // Server Default + }; + + return { carInsert, tune, user } +} + + +// Get Window Sticker +export async function getWindowSticker(userId: number) +{ + // Check if user have more than one cars + let checkWindowSticker = await prisma.car.findFirst({ + where: { + userId: userId + }, + select: { + windowStickerString: true, + windowStickerFont: true + } + }); + let additionalWindowStickerInsert = {}; + + // If more than one cars, get the window sticker string + if(checkWindowSticker) + { + additionalWindowStickerInsert = { + windowStickerString: checkWindowSticker.windowStickerString, + windowStickerFont: checkWindowSticker.windowStickerFont, + } + } + + return { additionalWindowStickerInsert } +} + + +// Get Car Tune +export async function getCarTune(tune: number, carInsert: any) +{ + // Additional car values (for basic / full tune) + let additionalInsert = {}; + + switch(tune) + { + // 0: Stock, nothing extra + + case 1: // Basic Tune + + // Updated default values + carInsert.level = 2; // C8 + carInsert.tunePower = 10; // 600 HP + carInsert.tuneHandling = 10; // 600 HP + + // Additional basic tune values + additionalInsert = { + ghostLevel: 4, + stClearBits: 0, + stLoseBits: 0, + stClearCount: 20, + stClearDivCount: 1, + stConsecutiveWins: 20, + stConsecutiveWinsMax: 20 + }; + break; + + case 2: // Fully Tuned + + // Updated default values + carInsert.level = 8; // C3 + carInsert.tunePower = 17; // 740 HP + carInsert.tuneHandling = 17; // 740 HP + + // Additional full tune values + additionalInsert = { + ghostLevel: 10, + stClearBits: 0, + stLoseBits: 0, + stClearCount: 80, + stClearDivCount: 4, + stConsecutiveWins: 80, + stConsecutiveWinsMax: 80 + }; + } + + return { additionalInsert } +} + + +// Car Order +export async function carOrder(carOrder: any, car: any, userId: number) +{ + // Add the new car to the front of the id + carOrder.unshift(car.carId); + + // Add the car to the front of the order + await prisma.user.update({ + where: { + id: userId + }, + data: { + carOrder: carOrder + } + }); + + console.log(`Created new car ${car.name} with ID ${car.carId}`); +} + + +// Update Car +export async function updateCar(body: wm.protobuf.UpdateCarRequest) +{ + // Get the ghost result for the car + let cars = body?.car; + + // Declare data + let data: any; + + // Get the current date/time (unix epoch) + let date = Math.floor(new Date().getTime() / 1000); + + // Car is set + if (cars) + { + // Car update data + data = { + customColor: common.sanitizeInput(cars.customColor), + wheel: common.sanitizeInput(cars.wheel), + wheelColor: common.sanitizeInput(cars.wheelColor), + aero: common.sanitizeInput(cars.aero), + bonnet: common.sanitizeInput(cars.bonnet), + wing: common.sanitizeInput(cars.wing), + mirror: common.sanitizeInput(cars.mirror), + neon: common.sanitizeInput(cars.neon), + trunk: common.sanitizeInput(cars.trunk), + plate: common.sanitizeInput(cars.plate), + plateColor: common.sanitizeInput(cars.plateColor), + plateNumber: common.sanitizeInput(cars.plateNumber), + windowSticker: common.sanitizeInput(cars.windowSticker), + windowDecoration: common.sanitizeInput(cars.windowDecoration), + rivalMarker: common.sanitizeInput(cars.rivalMarker), + aura: common.sanitizeInput(cars.aura), + auraMotif: common.sanitizeInput(cars.auraMotif), + rgStamp: common.sanitizeInputNotZero(body.rgStamp), + lastPlayedAt: date + }; + + // Update the car info + await prisma.car.update({ + where: { + carId: body.carId + }, + data: data + }); + } +} + + +// Update Car Setting +export async function updateCarSetting(body: wm.protobuf.UpdateCarRequest) +{ + // Get the car with the given id + let car = await prisma.car.findFirst({ + where: { + carId: body.carId + }, + include: { + settings: true, + gtWing: true, + lastPlayedPlace: true + } + }); + + // Update the car settings + await prisma.carSettings.update({ + where: { + dbId: car?.carSettingsDbId, + }, + data: { + ...body.setting + } + }); +} + + +// Update car Window Sticker +export async function updateCarWindowSticker(body: wm.protobuf.UpdateCarRequest) +{ + // Update the user data + let userData = await prisma.car.findFirst({ + where:{ + carId: body.carId + }, + select:{ + userId: true, + windowStickerString: true + } + }); + + // Newer window sticker string is different from the older one + // Check if window sticker string is not null + // (windowStickerString value when changing custom color in driver unit is undefined) + if(body.car?.windowStickerString) + { + if(userData!.windowStickerString !== body.car.windowStickerString){ + console.log('Updating Window Sticker'); + + await prisma.car.updateMany({ + where: { + userId: userData!.userId + }, + data: { + windowStickerString: body.car.windowStickerString, + windowStickerFont: body.car.windowStickerFont! + } + }); + } + } +} + + +// Update Car Custom Wing +export async function updateCarCustomWing(body: wm.protobuf.UpdateCarRequest) +{ + // Update the GT Wing (custom wing) info + // Get the GT Wing data for the car + let gtWing = body.car?.gtWing; + let dataGTWing: any; + + // GT Wing is set + if (gtWing) + { + dataGTWing = { + pillar: common.sanitizeInput(gtWing.pillar), + pillarMaterial: common.sanitizeInput(gtWing.pillarMaterial), + mainWing: common.sanitizeInput(gtWing.mainWing), + mainWingColor: common.sanitizeInput(gtWing.mainWingColor), + wingTip: common.sanitizeInput(gtWing.wingTip), + material: common.sanitizeInput(gtWing.material), + }; + + await prisma.carGTWing.update({ + where: { + dbId: body.carId + }, + data: dataGTWing + }); + } + // Check if this is in getting new custom color screen or not + else if(body.car?.carId !== null && body.car?.carId !== undefined) + { + // GT Wing not set + if(gtWing === undefined || gtWing === null) + { + dataGTWing = { + pillar: 0, + pillarMaterial: 0, + mainWing: 0, + mainWingColor: 0, + wingTip: 0, + material: 0, + }; + + await prisma.carGTWing.update({ + where: { + dbId: body.carId + }, + data: dataGTWing + }); + } + } +} \ No newline at end of file diff --git a/src/modules/game.ts b/src/modules/game.ts index 0a07151..7188485 100644 --- a/src/modules/game.ts +++ b/src/modules/game.ts @@ -7,12 +7,13 @@ import { Config } from "../config"; import * as wm from "../wmmt/wm.proto"; // Import Util -import * as common from "../util/common"; -import * as meter_reward from "../util/games/meter_reward"; -import * as story from "../util/games/story"; -import * as time_attack from "../util/games/time_attack"; -import * as ghost from "../util/games/ghost"; -import * as versus from "../util/games/versus"; +import * as common from "./util/common"; +import * as gameFunction from "./game/functions"; +import * as meter_reward from "./util/meter_reward"; +import * as story from "./game/story"; +import * as time_attack from "./game/time_attack"; +import * as ghost from "./game/ghost"; +import * as versus from "./game/versus"; export default class GameModule extends Module { @@ -35,15 +36,10 @@ export default class GameModule extends Module { } }); - // Declare some variable - // Default value is 'false', inside 'BASE_PATH/src/util/games/ghost.ts' file - let ghostModePlay; - - // Default value is 'true', inside 'BASE_PATH/src/util/games/ghost.ts' file - let updateNewTrail; - - // Default value is 'false', inside 'BASE_PATH/src/util/games/ghost.ts' file - let OCMModePlay; + // Declare some variable for message response + let ghostModePlay:boolean = false; + let updateNewTrail:boolean = true; + let OCMModePlay:boolean = false; // Switch on the gamemode switch (body.gameMode) @@ -100,96 +96,15 @@ export default class GameModule extends Module { } } - // Get car item - // Car item reward from the game is available - if(body.earnedItems.length !== 0) - { - console.log('Car Item reward available, continuing ...'); - for(let i=0; i storedTutorials[idx] = true - ); - - // Get the order of the user's cars - let carOrder = user?.carOrder; - - // Get the index of the selected car - let index = carOrder.indexOf(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 - await prisma.user.update({ - where: { - id: body.car!.userId! - }, - data: { - tutorials: storedTutorials, - carOrder: carOrder - } - }); - } - - // Response data - let msg; + // ----------------------------------------------------------------------------------------------- + // Additional Message for Response Data + let additionalSesionIdMsg = {}; // Ghost Battle mode or Crown Ghost Battle game mode is completed if(ghostModePlay === true && OCMModePlay === false && updateNewTrail === true) { - msg = { - error: wm.wm.protobuf.ErrorCode.ERR_SUCCESS, + additionalSesionIdMsg = { // Set session for saving ghost trail Ghost Battle Mode or Crown Ghost Battle Mode ghostSessionId: Math.floor(Math.random() * 100) + 1 @@ -265,21 +134,24 @@ export default class GameModule extends Module { // OCM Battle game mode is completed else if(ghostModePlay === true && OCMModePlay === true && updateNewTrail === true) { - msg = { - error: wm.wm.protobuf.ErrorCode.ERR_SUCCESS, + additionalSesionIdMsg = { - // Set session for saving ghost trail OCM Ghost Battle Mode + // Set session for saving ghost trail Competition (OCM) Ghost Battle Mode ghostSessionId: Math.floor(Math.random() * 100) + 101 } } - // Story mode or TA mode is completed - else - { - msg = { - error: wm.wm.protobuf.ErrorCode.ERR_SUCCESS + // ----------------------------------------------------------------------------------------------- - // No session for saving ghost trail (not playing Ghost Battle Mode / Retiring) - } + + // Response data + let msg = { + error: wm.wm.protobuf.ErrorCode.ERR_SUCCESS, + + // Ghost Session ID + ...additionalSesionIdMsg, + + // Available Tickets (maybe for VS) + //availableTickets: wm.protobuf.UserItem[] } // Encode the response @@ -296,9 +168,6 @@ export default class GameModule extends Module { // Get the request content let body = wm.wm.protobuf.LoadGameHistoryRequest.decode(req.body); - // Empty list of time attack records for the player's car - let ta_records : wm.wm.protobuf.LoadGameHistoryResponse.TimeAttackRecord[] = []; - // Get the car info let car = await prisma.car.findFirst({ where: { @@ -310,242 +179,26 @@ export default class GameModule extends Module { } }); - // Get the car's time attack records - let records = await prisma.timeAttackRecord.findMany({ - where: { - carId: body.carId - } - }); + // Get Time Attack Record + let taRecords = await gameFunction.getTimeAttackRecord(body); - // Loop over all of the records - for(let record of records) - { - // This code could probably be done with less DB calls in the future - - // Calculate the total rank, total participants for the record - let wholeData = await prisma.timeAttackRecord.findMany({ - where: { - course: record.course - }, - orderBy: { - time: 'asc' - } - }); - - // Get the overall number of participants - let wholeParticipants = wholeData.length; - - // Whole rank (default: 1) - let wholeRank = 1; - - // Loop over all of the participants - for(let row of wholeData) - { - // If the car ID does not match - if (row.carId !== body.carId) - { - // Increment whole rank - wholeRank++; - } - else // Model ID matches - { - // Break the loop - break; - } - } - - // Calculate the model rank, model participants for the record - let modelData = await prisma.timeAttackRecord.findMany({ - where: { - course: record.course, - model: record.model - }, - orderBy: { - time: 'asc' - } - }); - - // Get the overall number of participants (with the same car model) - let modelParticipants = modelData.length; - - // Model rank (default: 1) - let modelRank = 1; - - // Loop over all of the participants - for(let row of modelData) - { - // If the car ID does not match - if (row.carId !== body.carId) - { - // Increment whole rank - modelRank++; - } - else // Model ID matches - { - // Break the loop - break; - } - } - - // Generate the time attack record object and add it to the list - ta_records.push(wm.wm.protobuf.LoadGameHistoryResponse.TimeAttackRecord.create({ - course: record.course, - time: record.time, - tunePower: record.tunePower, - tuneHandling: record.tuneHandling, - wholeParticipants: wholeParticipants, - wholeRank: wholeRank, - modelParticipants: modelParticipants, - modelRank: modelRank - })); - } - - // Get user ghost battle mode history data - let ghostHistoryData = await prisma.ghostBattleRecord.findMany({ - where: { - carId: body.carId, - }, - orderBy: { - playedAt: 'desc' - }, - take: 3 - }); - - // Empty list of ghost battle history records for the player's car - let list_ghostHistoryData: wm.wm.protobuf.LoadGameHistoryResponse.GhostBattleRecord[] = []; - for(let i=0; i { + + // Get the information from the request + let body = wm.wm.protobuf.SaveScreenshotRequest.decode(req.body); + + // TODO: Actual stuff here + // This is literally just bare-bones so the shit boots + + // Response data + let msg = { + error: wm.wm.protobuf.ErrorCode.ERR_SUCCESS, + }; + + // Encode the response + let message = wm.wm.protobuf.SaveScreenshotResponse.encode(msg); + + // Send the response to the client + common.sendResponse(message, res); + }); } } diff --git a/src/modules/game/functions.ts b/src/modules/game/functions.ts new file mode 100644 index 0000000..460a08b --- /dev/null +++ b/src/modules/game/functions.ts @@ -0,0 +1,411 @@ +import { prisma } from "../.."; + +// Import Proto +import { wm } from "../../wmmt/wm.proto"; +import * as wmproto from "../../wmmt/wm.proto"; + +// Import Util +import * as common from "../util/common"; + + +// Get some item +export async function getItem(body: wm.protobuf.SaveGameResultRequest) +{ + // Get car item + // Car item reward from the game is available + if(body.earnedItems.length !== 0) + { + console.log('Car Item reward available, continuing ...'); + + for(let i=0; i storedTutorials[idx] = true + ); + + // Get the order of the user's cars + let carOrder = user?.carOrder; + + // Get the index of the selected car + let index = carOrder.indexOf(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 + await prisma.user.update({ + where: { + id: body.car!.userId! + }, + data: { + tutorials: storedTutorials, + carOrder: carOrder + } + }); + } +} + + +// Get User's Time Attack Record +export async function getTimeAttackRecord(body: wm.protobuf.LoadGameHistoryRequest) +{ + // Empty list of time attack records for the player's car + let ta_records : wmproto.wm.protobuf.LoadGameHistoryResponse.TimeAttackRecord[] = []; + + // Get the car's time attack records + let records = await prisma.timeAttackRecord.findMany({ + where: { + carId: body.carId + } + }); + + // Loop over all of the records + for(let record of records) + { + // This code could probably be done with less DB calls in the future + + // Calculate the total rank, total participants for the record + let wholeData = await prisma.timeAttackRecord.findMany({ + where: { + course: record.course + }, + orderBy: { + time: 'asc' + } + }); + + // Get the overall number of participants + let wholeParticipants = wholeData.length; + + // Whole rank (default: 1) + let wholeRank = 1; + + // Loop over all of the participants + for(let row of wholeData) + { + // If the car ID does not match + if (row.carId !== body.carId) + { + // Increment whole rank + wholeRank++; + } + else // Model ID matches + { + // Break the loop + break; + } + } + + // Calculate the model rank, model participants for the record + let modelData = await prisma.timeAttackRecord.findMany({ + where: { + course: record.course, + model: record.model + }, + orderBy: { + time: 'asc' + } + }); + + // Get the overall number of participants (with the same car model) + let modelParticipants = modelData.length; + + // Model rank (default: 1) + let modelRank = 1; + + // Loop over all of the participants + for(let row of modelData) + { + // If the car ID does not match + if (row.carId !== body.carId) + { + // Increment whole rank + modelRank++; + } + else // Model ID matches + { + // Break the loop + break; + } + } + + // Generate the time attack record object and add it to the list + ta_records.push(wmproto.wm.protobuf.LoadGameHistoryResponse.TimeAttackRecord.create({ + course: record.course, + time: record.time, + tunePower: record.tunePower, + tuneHandling: record.tuneHandling, + wholeParticipants: wholeParticipants, + wholeRank: wholeRank, + modelParticipants: modelParticipants, + modelRank: modelRank + })); + } + + // Get the current date/time (unix epoch) + let date = Math.floor(new Date().getTime() / 1000); + + return { ta_records, date } +} + + +// Get User's Ghost Battle Record +export async function getGhostBattleRecord(body: wm.protobuf.LoadGameHistoryRequest) +{ + // Get user ghost battle mode history data + let ghostHistoryData = await prisma.ghostBattleRecord.findMany({ + where: { + carId: body.carId, + }, + orderBy: { + playedAt: 'desc' + }, + take: 3 + }); + + // Empty list of ghost battle history records for the player's car + let ghostBattle_records: wmproto.wm.protobuf.LoadGameHistoryResponse.GhostBattleRecord[] = []; + for(let i=0; i date) diff --git a/src/modules/resource.ts b/src/modules/resource.ts index dc84b75..da77cdb 100644 --- a/src/modules/resource.ts +++ b/src/modules/resource.ts @@ -9,7 +9,7 @@ import * as wm from "../wmmt/wm.proto"; import * as wmsrv from "../wmmt/service.proto"; // Import Util -import * as common from "../util/common"; +import * as common from "./util/common"; export default class ResourceModule extends Module { diff --git a/src/modules/startup.ts b/src/modules/startup.ts index c76c46d..46e0b8a 100644 --- a/src/modules/startup.ts +++ b/src/modules/startup.ts @@ -1,12 +1,12 @@ import { Application } from "express"; import { Module } from "module"; -import { prisma } from ".."; // Import Proto import * as wm from "../wmmt/wm.proto"; // Import Util -import * as common from "../util/common"; +import * as common from "./util/common"; +import * as startupFunctions from "./startup/functions"; export default class StartupModule extends Module { @@ -21,85 +21,9 @@ export default class StartupModule extends Module { // Get current date let date = Math.floor(new Date().getTime() / 1000); - // 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: { - competitionEndAt: 'desc', - } - }); - - let pastEvent = 0; - if(!(ocmEventDate)) - { - ocmEventDate = await prisma.oCMEvent.findFirst({ - orderBy:{ - competitionId: 'desc' - } - }); - - pastEvent = 1; - } - - // Declare GhostCompetitionSchedule - let competitionSchedule; - let lastCompetitionId: number = 0; - if(ocmEventDate) - { - let pastDay = date - ocmEventDate.competitionEndAt - - if(pastDay < 604800) - { - console.log("OCM Event Available"); - - // Creating GhostCompetitionSchedule - competitionSchedule = 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 - }); - } - - if(pastEvent === 1) - { - console.log("Previous OCM Event Available"); - - lastCompetitionId = ocmEventDate.competitionId - } - } + // Get Competition (OCM) Event Date + let getCompetitionSchedule = await startupFunctions.competitionSchedule(date, null); + let additionalCompetitionMsg = getCompetitionSchedule.additionalCompetitionMsg; // Response data let msg = { @@ -116,8 +40,9 @@ export default class StartupModule extends Module { pluses: 0, releaseAt: 0 // idk what this is }, - latestCompetitionId: lastCompetitionId || null, - competitionSchedule: competitionSchedule || null // OCM Event Available or not + + // Competition (OCM) + ...additionalCompetitionMsg } // Encode the response @@ -148,6 +73,7 @@ export default class StartupModule extends Module { common.sendResponse(message, res); }); + // Ping app.post('/method/ping', (req, res) => { @@ -167,6 +93,7 @@ export default class StartupModule extends Module { }) + // Register System Stats app.post('/method/register_system_stats', async (req, res) => { let body = wm.wm.protobuf.RegisterSystemStatsRequest.decode(req.body); @@ -187,6 +114,7 @@ export default class StartupModule extends Module { }) + // Update Event Mode Serial app.post('/method/update_event_mode_serial', async (req, res) => { let body = wm.wm.protobuf.UpdateEventModeSerialRequest.decode(req.body); @@ -197,7 +125,10 @@ export default class StartupModule extends Module { // Response data let msg = { error: wm.wm.protobuf.ErrorCode.ERR_SUCCESS, - serialError: wm.wm.protobuf.EventModeSerialErrorCode.SERIAL_NO_INPUT + serialError: wm.wm.protobuf.EventModeSerialErrorCode.SERIAL_SUCCESS, + eventModeSerial: body.eventModeSerial || '285013990002', + startAt: 0, + endAt: 2147483647 } // Encode the response @@ -208,6 +139,7 @@ export default class StartupModule extends Module { }) + // Submit Client Log app.post('/method/submit_client_log', async (req, res) => { let body = wm.wm.protobuf.SubmitClientLogRequest.decode(req.body); diff --git a/src/modules/startup/functions.ts b/src/modules/startup/functions.ts new file mode 100644 index 0000000..3eb11c7 --- /dev/null +++ b/src/modules/startup/functions.ts @@ -0,0 +1,115 @@ +import { prisma } from "../.."; + +// Import Proto +import * as wm from "../../wmmt/wm.proto"; + + +// Get Competition (OCM) Schedule +export async function competitionSchedule(date: any, competitionId: any) +{ + // Get the Competition (OCM) schedule + let ghostCompetitionSchedule; + + // Request by compedtitionId + if(competitionId) + { + ghostCompetitionSchedule = await prisma.oCMEvent.findFirst({ + where: { + competitionId: competitionId + }, + orderBy: { + competitionId: 'desc' + } + }); + } + // Request by date + else + { + ghostCompetitionSchedule = await prisma.oCMEvent.findFirst({ + where: { + // qualifyingPeriodStartAt is less than current date + qualifyingPeriodStartAt: { lte: Number(date) }, + + // competitionEndAt is greater than current date + competitionEndAt: { gte: Number(date) }, + } + }); + } + + // Other variable + let competitionSchedule; + let lastCompetitionId: number = 0; + let additionalCompetitionMsg = {}; + + // Currently no Active Competition (OCM) Event.. Getting Previous Competition (OCM) Event + let pastEvent = 0; + if(!(ghostCompetitionSchedule)) + { + ghostCompetitionSchedule = await prisma.oCMEvent.findFirst({ + orderBy:{ + competitionId: 'desc' + } + }); + + pastEvent = 1; + } + + // Previous / Current Competition (OCM) available + if(ghostCompetitionSchedule) + { + console.log('Ghost Competition (OCM) Available'); + + let pastDay = date - ghostCompetitionSchedule.competitionEndAt; + + if(pastDay < 604800) + { + // Creating GhostCompetitionSchedule + competitionSchedule = wm.wm.protobuf.GhostCompetitionSchedule.create({ + + // Competition ID + competitionId: ghostCompetitionSchedule.competitionId, + + // Competition Qualifying Start Timestamp + qualifyingPeriodStartAt: ghostCompetitionSchedule.qualifyingPeriodStartAt, + + // Competition Qualifying Close Timestamp + qualifyingPeriodCloseAt: ghostCompetitionSchedule.qualifyingPeriodCloseAt, + + // Competition (Main Draw) Start Timestamp + competitionStartAt: ghostCompetitionSchedule.competitionStartAt, + + // Competition (Main Draw) Close Timestamp + competitionCloseAt: ghostCompetitionSchedule.competitionCloseAt, + + // Competition (Main Draw) End Timestamp + competitionEndAt: ghostCompetitionSchedule.competitionEndAt, + + // Competition (Main Draw) length per periods + lengthOfPeriod: ghostCompetitionSchedule.lengthOfPeriod, + + // Competition (Main Draw) interval (for tallying) per periods + lengthOfInterval: ghostCompetitionSchedule.lengthOfInterval, + + // Area for the Competition Event (GID_RUNAREA_*) + area: ghostCompetitionSchedule.area, + + // idk what this is + minigamePatternId: ghostCompetitionSchedule.minigamePatternId + }); + } + + // It's previous Competition (OCM) event + if(pastEvent === 1) + { + lastCompetitionId = ghostCompetitionSchedule.competitionId; + } + + // Competition (OCM) Response Message + additionalCompetitionMsg = { + latestCompetitionId: lastCompetitionId, + competitionSchedule: competitionSchedule, + } + } + + return { additionalCompetitionMsg, competitionSchedule } +} \ No newline at end of file diff --git a/src/modules/terminal.ts b/src/modules/terminal.ts index 128fb99..f0e0777 100644 --- a/src/modules/terminal.ts +++ b/src/modules/terminal.ts @@ -8,8 +8,8 @@ import { Car } from "@prisma/client"; import * as wm from "../wmmt/wm.proto"; // Import Util -import * as scratch from "../util/scratch"; -import * as common from "../util/common"; +import * as scratch from "./terminal/scratch"; +import * as common from "./util/common"; export default class TerminalModule extends Module { @@ -1003,24 +1003,6 @@ export default class TerminalModule extends Module { }); - app.post('/method/save_screenshot', async (req, res) => { - - // Get the information from the request - let body = wm.wm.protobuf.SaveScreenshotRequest.decode(req.body); - - // Response data - let msg = { - error: wm.wm.protobuf.ErrorCode.ERR_SUCCESS, - }; - - // Encode the response - let message = wm.wm.protobuf.SaveScreenshotResponse.encode(msg); - - // Send the response to the client - common.sendResponse(message, res); - }); - - /* app.post('/method/load_unreceived_user_items', async (req, res) => { diff --git a/src/util/terminal/check_car.ts b/src/modules/terminal/check_car.ts similarity index 99% rename from src/util/terminal/check_car.ts rename to src/modules/terminal/check_car.ts index 2493c1b..d719db1 100644 --- a/src/util/terminal/check_car.ts +++ b/src/modules/terminal/check_car.ts @@ -1,5 +1,6 @@ import { prisma } from "../.."; + // Sends the server response to the client export async function checkScratchCar(userId: number, visualModel: number) { diff --git a/src/util/scratch.ts b/src/modules/terminal/scratch.ts similarity index 99% rename from src/util/scratch.ts rename to src/modules/terminal/scratch.ts index 775d1d6..884f0b4 100644 --- a/src/util/scratch.ts +++ b/src/modules/terminal/scratch.ts @@ -1,8 +1,8 @@ -import { prisma } from ".."; -import { Config } from "../config"; +import { prisma } from "../.."; +import { Config } from "../../config"; //Import Proto -import * as wm from "../wmmt/wm.proto"; +import * as wm from "../../wmmt/wm.proto"; // *** CONSTANTS *** diff --git a/src/modules/time_attack.ts b/src/modules/time_attack.ts index 6f6ceae..a36ffe1 100644 --- a/src/modules/time_attack.ts +++ b/src/modules/time_attack.ts @@ -6,7 +6,7 @@ import { prisma } from ".."; import * as wm from "../wmmt/wm.proto"; // Import Util -import * as common from "../util/common"; +import * as common from "./util/common"; export default class TimeAttackModule extends Module { diff --git a/src/modules/users.ts b/src/modules/users.ts index 03c2aa2..0a1333a 100644 --- a/src/modules/users.ts +++ b/src/modules/users.ts @@ -7,8 +7,8 @@ import { prisma } from ".."; import * as wm from "../wmmt/wm.proto"; // Import Util -import * as scratch from "../util/scratch"; -import * as common from "../util/common"; +import * as scratch from "./terminal/scratch"; +import * as common from "./util/common"; export default class UserModule extends Module { @@ -19,6 +19,13 @@ export default class UserModule extends Module { // Get the request body for the load user request let body = wm.wm.protobuf.LoadUserRequest.decode(req.body); + + // Block blank card.ini data + if(body.cardChipId.match(/7F5C9744F11111114326.*/)) + { + body.cardChipId = ''; + body.accessCode = ''; + } // Get the user from the database let user = await prisma.user.findFirst({ @@ -69,7 +76,7 @@ export default class UserModule extends Module { } // Check if new card registration is allowed or not - let newCardsBanned = Config.getConfig().gameOptions.newCardsBanned; + let newCardsBanned = Config.getConfig().gameOptions.newCardsBanned || 0; // New card registration is allowed if (newCardsBanned === 0) diff --git a/src/util/common.ts b/src/modules/util/common.ts similarity index 100% rename from src/util/common.ts rename to src/modules/util/common.ts diff --git a/src/util/games/meter_reward.ts b/src/modules/util/meter_reward.ts similarity index 100% rename from src/util/games/meter_reward.ts rename to src/modules/util/meter_reward.ts diff --git a/src/util/ghost/ghost_history.ts b/src/util/ghost/ghost_history.ts index 0a24652..b738d8d 100644 --- a/src/util/ghost/ghost_history.ts +++ b/src/util/ghost/ghost_history.ts @@ -4,7 +4,7 @@ import { Config } from "../../config"; import { wm } from "../../wmmt/wm.proto"; // Import Util -import * as common from "../../util/common"; +import * as common from "../../modules/util/common"; import * as ghost_stamp from "../ghost/ghost_stamp"; import * as ghost_get_area_from_path from "../ghost/ghost_util/ghost_get_area_from_path";