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";