clean up (still not complete), fix new card restration, block blank card.ini data
This commit is contained in:
parent
9c7c80df0e
commit
46e9ba9e5a
@ -24,7 +24,7 @@ import MuchaModule from './mucha';
|
|||||||
import { Config } from './config';
|
import { Config } from './config';
|
||||||
import * as Sentry from '@sentry/node';
|
import * as Sentry from '@sentry/node';
|
||||||
import * as Tracing from '@sentry/tracing';
|
import * as Tracing from '@sentry/tracing';
|
||||||
import * as common from './util/common';
|
import * as common from './modules/util/common';
|
||||||
|
|
||||||
globalAgent.options.keepAlive = true;
|
globalAgent.options.keepAlive = true;
|
||||||
|
|
||||||
|
@ -1,17 +1,13 @@
|
|||||||
import { Application } from "express";
|
import { Application } from "express";
|
||||||
import { Config } from "../config";
|
|
||||||
import { Module } from "module";
|
import { Module } from "module";
|
||||||
import { prisma } from "..";
|
import { prisma } from "..";
|
||||||
import { User } from "@prisma/client";
|
|
||||||
import Long from "long";
|
|
||||||
|
|
||||||
// Import Proto
|
// Import Proto
|
||||||
import * as wm from "../wmmt/wm.proto";
|
import * as wm from "../wmmt/wm.proto";
|
||||||
|
|
||||||
// Import Util
|
// Import Util
|
||||||
import * as common from "../util/common";
|
import * as common from "./util/common";
|
||||||
import * as scratch from "../util/scratch";
|
import * as carFunctions from "./cars/functions";
|
||||||
import * as terminal from "../util/terminal/check_car";
|
|
||||||
|
|
||||||
|
|
||||||
export default class CarModule extends Module {
|
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);
|
let body = wm.wm.protobuf.LoadCarRequest.decode(req.body);
|
||||||
|
|
||||||
// Get the car (required data only) with the given id
|
// Get the car (required data only) with the given id
|
||||||
let car = await prisma.car.findFirst({
|
let car = await carFunctions.getCar(body.carId);
|
||||||
where: {
|
|
||||||
carId: body.carId
|
|
||||||
},
|
|
||||||
include: {
|
|
||||||
settings: true,
|
|
||||||
items: true,
|
|
||||||
gtWing: true,
|
|
||||||
lastPlayedPlace: true,
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
// 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;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 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 registeredTarget = await carFunctions.getRegisteredTarget(body.carId);
|
||||||
|
|
||||||
|
// Get Challenger Data
|
||||||
|
let opponentsTarget = await carFunctions.getOpponentsTarget(body.carId, registeredTarget.registeredargetAvailable);
|
||||||
|
|
||||||
// Response data
|
// Response data
|
||||||
let msg = {
|
let msg = {
|
||||||
error: wm.wm.protobuf.ErrorCode.ERR_SUCCESS,
|
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,
|
tuningPoint: car!.tuningPoints,
|
||||||
setting: car!.settings,
|
setting: car!.settings,
|
||||||
rgPreviousVersionPlayCount: 0,
|
rgPreviousVersionPlayCount: 0,
|
||||||
@ -214,21 +45,22 @@ export default class CarModule extends Module {
|
|||||||
auraMotifAutoChange: false,
|
auraMotifAutoChange: false,
|
||||||
screenshotCount: 0,
|
screenshotCount: 0,
|
||||||
transferred: false,
|
transferred: false,
|
||||||
...car!,
|
|
||||||
stLoseBits: longLoseBits,
|
|
||||||
ownedItems: car!.items,
|
|
||||||
lastPlayedAt: car!.lastPlayedAt,
|
|
||||||
announceEventModePrize: true,
|
|
||||||
|
|
||||||
// Stamp or Challenger
|
// Stamp or Challenger
|
||||||
challenger: carsChallengers || null,
|
challenger: opponentsTarget.challenger,
|
||||||
challengerReturnCount: returnCount || null,
|
challengerReturnCount: opponentsTarget.challengerReturnCount,
|
||||||
numOfChallengers: opponentTargetCount + 1 || null,
|
numOfChallengers: opponentsTarget.numOfChallengers,
|
||||||
|
|
||||||
// OCM Challenge Top 1
|
// OCM Challenge Top 1
|
||||||
opponentGhost: opponentGhost || null,
|
opponentGhost: registeredTarget.opponentGhost,
|
||||||
opponentTrailId: opponentTrailId || null,
|
opponentTrailId: registeredTarget.opponentTrailId,
|
||||||
opponentCompetitionId: opponentCompetitionId || null
|
opponentCompetitionId: registeredTarget.opponentCompetitionId,
|
||||||
|
|
||||||
|
// Owned Item
|
||||||
|
ownedItems: car.items,
|
||||||
|
|
||||||
|
// Announce Event Mode Prize
|
||||||
|
announceEventModePrize: true
|
||||||
};
|
};
|
||||||
|
|
||||||
// Generate the load car response message
|
// 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
|
// Get the request body for the create car request
|
||||||
let body = wm.wm.protobuf.CreateCarRequest.decode(req.body);
|
let body = wm.wm.protobuf.CreateCarRequest.decode(req.body);
|
||||||
|
|
||||||
// Get the current date/time (unix epoch)
|
// Create the Car
|
||||||
let date = Math.floor(new Date().getTime() / 1000)
|
let createCar = await carFunctions.createCar(body);
|
||||||
|
let tune = createCar.tune;
|
||||||
|
let carInsert = createCar.carInsert;
|
||||||
|
|
||||||
// Retrieve user from card chip / user id
|
// Check if user's other car have unique window sticker
|
||||||
let user: User | null;
|
let windowSticker = await carFunctions.getWindowSticker(body.userId);
|
||||||
|
let additionalWindowStickerInsert = windowSticker.additionalWindowStickerInsert
|
||||||
|
|
||||||
// User ID provided, use that
|
/// Switch on tune status
|
||||||
if (body.userId) {
|
let getCarTune = await carFunctions.getCarTune(tune, carInsert);
|
||||||
user = await prisma.user.findFirst({
|
let additionalInsert = getCarTune.additionalInsert;
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 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
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
// Insert the car into the database
|
// Insert the car into the database
|
||||||
let car = await prisma.car.create({
|
let car = await prisma.car.create({
|
||||||
@ -524,30 +100,26 @@ export default class CarModule extends Module {
|
|||||||
});
|
});
|
||||||
|
|
||||||
// Get the user's current car order
|
// Get the user's current car order
|
||||||
let carOrder = user.carOrder;
|
let carOrder = createCar.user.carOrder;
|
||||||
|
await carFunctions.carOrder(carOrder, car, createCar.user.id);
|
||||||
// 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}`);
|
|
||||||
|
|
||||||
// Response data
|
// Response data
|
||||||
let msg = {
|
let msg = {
|
||||||
error: wm.wm.protobuf.ErrorCode.ERR_SUCCESS,
|
error: wm.wm.protobuf.ErrorCode.ERR_SUCCESS,
|
||||||
|
|
||||||
|
// User ID
|
||||||
|
accessCode: body.accessCode,
|
||||||
|
banapassportAmId: body.banapassportAmId,
|
||||||
|
//mbid: number|null,
|
||||||
|
|
||||||
|
// Car Data
|
||||||
carId: car.carId,
|
carId: car.carId,
|
||||||
car,
|
car,
|
||||||
...carInsert,
|
...carInsert,
|
||||||
...additionalInsert
|
...additionalInsert,
|
||||||
|
|
||||||
|
// Expiring Full Tuned Ticket
|
||||||
|
//fullTunedCarCouponUnreceivableAt: number|null
|
||||||
}
|
}
|
||||||
|
|
||||||
// Generate the load car response message
|
// 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
|
// Get the request body for the update car request
|
||||||
let body = wm.wm.protobuf.UpdateCarRequest.decode(req.body);
|
let body = wm.wm.protobuf.UpdateCarRequest.decode(req.body);
|
||||||
|
|
||||||
// Get the ghost result for the car
|
// Update the car
|
||||||
let cars = body?.car;
|
await carFunctions.updateCar(body);
|
||||||
|
|
||||||
// Declare data
|
// Update the car setting
|
||||||
let data : any;
|
await carFunctions.updateCarSetting(body);
|
||||||
|
|
||||||
// Car is set
|
// Update the car window Sticker
|
||||||
if (cars)
|
await carFunctions.updateCarWindowSticker(body);
|
||||||
{
|
|
||||||
// Get current date
|
|
||||||
let date = Math.floor(new Date().getTime() / 1000);
|
|
||||||
|
|
||||||
// Car update data
|
// Update the car Custom Wing
|
||||||
data = {
|
await carFunctions.updateCarCustomWing(body);
|
||||||
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!
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Get car item (custom color or discarded card)
|
// 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 ...');
|
console.log('Car Item reward available, continuing ...');
|
||||||
for(let i=0; i<body.earnedItems.length; i++){
|
for(let i=0; i<body.earnedItems.length; i++){
|
||||||
await prisma.carItem.create({
|
await prisma.carItem.create({
|
||||||
@ -676,54 +164,6 @@ export default class CarModule extends Module {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 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
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Response data
|
// Response data
|
||||||
let msg = {
|
let msg = {
|
||||||
error: wm.wm.protobuf.ErrorCode.ERR_SUCCESS,
|
error: wm.wm.protobuf.ErrorCode.ERR_SUCCESS,
|
||||||
|
86
src/modules/cars/car_tune.ts
Normal file
86
src/modules/cars/car_tune.ts
Normal file
@ -0,0 +1,86 @@
|
|||||||
|
import { Config } from "../../config";
|
||||||
|
import { prisma } from "../..";
|
||||||
|
|
||||||
|
// Import Util
|
||||||
|
import * as scratch from "../terminal/scratch";
|
||||||
|
|
||||||
|
|
||||||
|
// Create Car With Item
|
||||||
|
export async function createCarWithItem(userItemId: number)
|
||||||
|
{
|
||||||
|
console.log(`Item used - ID ${userItemId}`);
|
||||||
|
|
||||||
|
// Remove the user item from the database
|
||||||
|
let item = await prisma.userItem.delete({
|
||||||
|
where: {
|
||||||
|
userItemId: userItemId
|
||||||
|
}
|
||||||
|
});
|
||||||
|
let tune = 0;
|
||||||
|
|
||||||
|
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}`);
|
||||||
|
|
||||||
|
return { tune }
|
||||||
|
}
|
632
src/modules/cars/functions.ts
Normal file
632
src/modules/cars/functions.ts
Normal file
@ -0,0 +1,632 @@
|
|||||||
|
import { prisma } from "../..";
|
||||||
|
import { User } from "@prisma/client";
|
||||||
|
import { Config } from "../../config";
|
||||||
|
import Long from "long";
|
||||||
|
|
||||||
|
// Import Proto
|
||||||
|
import { wm } from "../../wmmt/wm.proto";
|
||||||
|
import * as wmproto from "../../wmmt/wm.proto";
|
||||||
|
|
||||||
|
// Import Util
|
||||||
|
import * as common from "../util/common";
|
||||||
|
import * as car_tune from "./car_tune";
|
||||||
|
import * as terminal from "../terminal/check_car";
|
||||||
|
|
||||||
|
|
||||||
|
// Get Car Data
|
||||||
|
export async function getCar(carId: number)
|
||||||
|
{
|
||||||
|
// Get the car (required data only) with the given id
|
||||||
|
let car = await prisma.car.findFirst({
|
||||||
|
where: {
|
||||||
|
carId: carId
|
||||||
|
},
|
||||||
|
include: {
|
||||||
|
settings: true,
|
||||||
|
items: true,
|
||||||
|
gtWing: true,
|
||||||
|
lastPlayedPlace: true,
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// 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;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 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
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -7,12 +7,13 @@ import { Config } from "../config";
|
|||||||
import * as wm from "../wmmt/wm.proto";
|
import * as wm from "../wmmt/wm.proto";
|
||||||
|
|
||||||
// Import Util
|
// Import Util
|
||||||
import * as common from "../util/common";
|
import * as common from "./util/common";
|
||||||
import * as meter_reward from "../util/games/meter_reward";
|
import * as gameFunction from "./game/functions";
|
||||||
import * as story from "../util/games/story";
|
import * as meter_reward from "./util/meter_reward";
|
||||||
import * as time_attack from "../util/games/time_attack";
|
import * as story from "./game/story";
|
||||||
import * as ghost from "../util/games/ghost";
|
import * as time_attack from "./game/time_attack";
|
||||||
import * as versus from "../util/games/versus";
|
import * as ghost from "./game/ghost";
|
||||||
|
import * as versus from "./game/versus";
|
||||||
|
|
||||||
|
|
||||||
export default class GameModule extends Module {
|
export default class GameModule extends Module {
|
||||||
@ -35,15 +36,10 @@ export default class GameModule extends Module {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
// Declare some variable
|
// Declare some variable for message response
|
||||||
// Default value is 'false', inside 'BASE_PATH/src/util/games/ghost.ts' file
|
let ghostModePlay:boolean = false;
|
||||||
let ghostModePlay;
|
let updateNewTrail:boolean = true;
|
||||||
|
let OCMModePlay:boolean = false;
|
||||||
// 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;
|
|
||||||
|
|
||||||
// Switch on the gamemode
|
// Switch on the gamemode
|
||||||
switch (body.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<body.earnedItems.length; i++){
|
|
||||||
await prisma.carItem.create({
|
|
||||||
data: {
|
|
||||||
carId: body.carId,
|
|
||||||
category: body.earnedItems[i].category,
|
|
||||||
itemId: body.earnedItems[i].itemId,
|
|
||||||
amount: 1
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Get user item
|
// Check if earned some items
|
||||||
// User item reward from the game is available
|
await gameFunction.getItem(body);
|
||||||
if(body.earnedUserItems.length !== 0)
|
|
||||||
{
|
|
||||||
console.log('User Item reward available, continuing ...');
|
|
||||||
for(let i=0; i<body.earnedUserItems.length; i++){
|
|
||||||
await prisma.userItem.create({
|
|
||||||
data: {
|
|
||||||
category: body.earnedUserItems[i].category,
|
|
||||||
itemId: body.earnedUserItems[i].itemId,
|
|
||||||
userId: body.car!.userId!,
|
|
||||||
earnedAt: 0,
|
|
||||||
type: 0
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check playet at timestamp
|
// Update Car Data
|
||||||
let timestamps = 0;
|
await gameFunction.updateCar(body, car);
|
||||||
if(body.car?.lastPlayedAt !== undefined && body.car?.lastPlayedAt !== null)
|
|
||||||
{
|
|
||||||
if(body.car.lastPlayedAt !== 0)
|
|
||||||
{
|
|
||||||
timestamps = body.car.lastPlayedAt;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
timestamps = Math.floor(new Date().getTime() / 1000);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check P & H must not more than 34 (fully tuned value)
|
// Update Car Order and Save Tutorial
|
||||||
let tunePower = 0;
|
await gameFunction.updateOrderTutorial(body);
|
||||||
let tuneHandling = 0;
|
|
||||||
let totalTune = body.car!.tunePower + body.car!.tuneHandling;
|
|
||||||
if(totalTune <= 34)
|
|
||||||
{
|
|
||||||
tunePower = body.car!.tunePower;
|
|
||||||
tuneHandling = body.car!.tuneHandling;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Update car
|
|
||||||
await prisma.car.update({
|
|
||||||
where: {
|
|
||||||
carId: body.carId,
|
|
||||||
},
|
|
||||||
data: {
|
|
||||||
aura: body.car!.aura!,
|
|
||||||
auraMotif: body.car!.auraMotif!,
|
|
||||||
odometer: body.odometer,
|
|
||||||
playCount: body.playCount,
|
|
||||||
level: body.car!.level!,
|
|
||||||
title: body.car!.title!,
|
|
||||||
tunePower: tunePower,
|
|
||||||
tuneHandling: tuneHandling,
|
|
||||||
windowSticker: body.car!.windowSticker!,
|
|
||||||
lastPlayedAt: timestamps,
|
|
||||||
regionId: body.car!.regionId!,
|
|
||||||
rgStamp: common.sanitizeInputNotZero(body.rgResult?.rgStamp),
|
|
||||||
stampSheetCount: common.sanitizeInputNotZero(body.rgResult?.stampSheetCount)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
// Update car settings
|
|
||||||
await prisma.carSettings.update({
|
|
||||||
where: {
|
|
||||||
dbId: car!.carSettingsDbId
|
|
||||||
},
|
|
||||||
data: {
|
|
||||||
...body.setting
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
// Every n*100 play give reward
|
// Every n*100 play give reward
|
||||||
// Check this feature config
|
// Check this feature config
|
||||||
@ -202,61 +117,15 @@ export default class GameModule extends Module {
|
|||||||
await meter_reward.giveMeterRewards(body);
|
await meter_reward.giveMeterRewards(body);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Update user
|
|
||||||
let user = await prisma.user.findFirst({
|
|
||||||
where: {
|
|
||||||
id: body.car!.userId!
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
// User object exists
|
// -----------------------------------------------------------------------------------------------
|
||||||
if (user)
|
// Additional Message for Response Data
|
||||||
{
|
let additionalSesionIdMsg = {};
|
||||||
// Get user tutorials
|
|
||||||
let storedTutorials = user!.tutorials;
|
|
||||||
|
|
||||||
// Update any seen tutorials
|
|
||||||
body.confirmedTutorials.forEach(
|
|
||||||
(idx) => 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;
|
|
||||||
|
|
||||||
// Ghost Battle mode or Crown Ghost Battle game mode is completed
|
// Ghost Battle mode or Crown Ghost Battle game mode is completed
|
||||||
if(ghostModePlay === true && OCMModePlay === false && updateNewTrail === true)
|
if(ghostModePlay === true && OCMModePlay === false && updateNewTrail === true)
|
||||||
{
|
{
|
||||||
msg = {
|
additionalSesionIdMsg = {
|
||||||
error: wm.wm.protobuf.ErrorCode.ERR_SUCCESS,
|
|
||||||
|
|
||||||
// Set session for saving ghost trail Ghost Battle Mode or Crown Ghost Battle Mode
|
// Set session for saving ghost trail Ghost Battle Mode or Crown Ghost Battle Mode
|
||||||
ghostSessionId: Math.floor(Math.random() * 100) + 1
|
ghostSessionId: Math.floor(Math.random() * 100) + 1
|
||||||
@ -265,21 +134,24 @@ export default class GameModule extends Module {
|
|||||||
// OCM Battle game mode is completed
|
// OCM Battle game mode is completed
|
||||||
else if(ghostModePlay === true && OCMModePlay === true && updateNewTrail === true)
|
else if(ghostModePlay === true && OCMModePlay === true && updateNewTrail === true)
|
||||||
{
|
{
|
||||||
msg = {
|
additionalSesionIdMsg = {
|
||||||
error: wm.wm.protobuf.ErrorCode.ERR_SUCCESS,
|
|
||||||
|
|
||||||
// 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
|
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
|
// Encode the response
|
||||||
@ -296,9 +168,6 @@ export default class GameModule extends Module {
|
|||||||
// Get the request content
|
// Get the request content
|
||||||
let body = wm.wm.protobuf.LoadGameHistoryRequest.decode(req.body);
|
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
|
// Get the car info
|
||||||
let car = await prisma.car.findFirst({
|
let car = await prisma.car.findFirst({
|
||||||
where: {
|
where: {
|
||||||
@ -310,242 +179,26 @@ export default class GameModule extends Module {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
// Get the car's time attack records
|
// Get Time Attack Record
|
||||||
let records = await prisma.timeAttackRecord.findMany({
|
let taRecords = await gameFunction.getTimeAttackRecord(body);
|
||||||
where: {
|
|
||||||
carId: body.carId
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
// Loop over all of the records
|
// Get Ghost Battle Record
|
||||||
for(let record of records)
|
let ghostBattleRecord = await gameFunction.getGhostBattleRecord(body);
|
||||||
{
|
|
||||||
// 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<ghostHistoryData.length; i++){
|
|
||||||
|
|
||||||
// User car setting
|
|
||||||
let carSetings = wm.wm.protobuf.LoadGameHistoryResponse.GhostBattleRecord.GhostCarSetting.create({
|
|
||||||
tunePower: ghostHistoryData![i].tunePower,
|
|
||||||
tuneHandling: ghostHistoryData![i].tuneHandling,
|
|
||||||
});
|
|
||||||
|
|
||||||
// ----Ghost Opponent 1----
|
|
||||||
let ghostOpponentCar = await prisma.car.findFirst({
|
|
||||||
where: {
|
|
||||||
carId: ghostHistoryData![i].opponent1CarId!
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
// If opponent is default ghost or random ghost
|
|
||||||
if(!(ghostOpponentCar)){
|
|
||||||
ghostOpponentCar = await prisma.car.findFirst({});
|
|
||||||
ghostOpponentCar!.name = 'S660';
|
|
||||||
ghostOpponentCar!.manufacturer = 12;
|
|
||||||
ghostOpponentCar!.model = 105;
|
|
||||||
ghostOpponentCar!.visualModel = 130;
|
|
||||||
ghostOpponentCar!.regionId = 18;
|
|
||||||
ghostOpponentCar!.country = 'GLB';
|
|
||||||
}
|
|
||||||
|
|
||||||
// Get Opponent 1 tune
|
|
||||||
ghostOpponentCar!.tunePower = ghostHistoryData![i].opponent1TunePower!;
|
|
||||||
ghostOpponentCar!.tuneHandling = ghostHistoryData![i].opponent1TuneHandling!;
|
|
||||||
|
|
||||||
// Get the Data
|
|
||||||
let ghostOpponent = wm.wm.protobuf.LoadGameHistoryResponse.GhostBattleRecord.GhostBattleRecordCar.create({
|
|
||||||
car: {
|
|
||||||
...ghostOpponentCar!
|
|
||||||
},
|
|
||||||
result: ghostHistoryData![i].opponent1Result!
|
|
||||||
});
|
|
||||||
// ------------------------
|
|
||||||
|
|
||||||
// ----Ghost Opponent 2 & 3----
|
|
||||||
// Empty list of ghost battle records for the player's car
|
|
||||||
let ghostMob: wm.wm.protobuf.LoadGameHistoryResponse.GhostBattleRecord.GhostBattleRecordCar[] = [];
|
|
||||||
|
|
||||||
// ----Ghost Opponent 2----
|
|
||||||
if(ghostHistoryData[i]?.opponent2CarId !== null && ghostHistoryData[i]?.opponent2CarId !== undefined)
|
|
||||||
{
|
|
||||||
let ghostOpponentCar2 = await prisma.car.findFirst({
|
|
||||||
where: {
|
|
||||||
carId: ghostHistoryData![i].opponent2CarId!
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
// If opponent is default ghost or random ghost
|
|
||||||
if(!(ghostOpponentCar2)){
|
|
||||||
ghostOpponentCar2 = await prisma.car.findFirst({});
|
|
||||||
ghostOpponentCar2!.name = 'S660';
|
|
||||||
ghostOpponentCar2!.manufacturer = 12;
|
|
||||||
ghostOpponentCar2!.model = 105;
|
|
||||||
ghostOpponentCar2!.visualModel = 130;
|
|
||||||
ghostOpponentCar2!.regionId = 18;
|
|
||||||
ghostOpponentCar2!.country = 'GLB';
|
|
||||||
}
|
|
||||||
|
|
||||||
// Get Opponent 2 tune
|
|
||||||
ghostOpponentCar2!.tunePower = ghostHistoryData![i].opponent2TunePower!;
|
|
||||||
ghostOpponentCar2!.tuneHandling = ghostHistoryData![i].opponent2TuneHandling!;
|
|
||||||
|
|
||||||
// Get the Data
|
|
||||||
ghostMob.push(wm.wm.protobuf.LoadGameHistoryResponse.GhostBattleRecord.GhostBattleRecordCar.create({
|
|
||||||
car: {
|
|
||||||
...ghostOpponentCar2!
|
|
||||||
},
|
|
||||||
result: ghostHistoryData![i].opponent2Result!
|
|
||||||
}));
|
|
||||||
}
|
|
||||||
// ------------------------
|
|
||||||
|
|
||||||
// ----Ghost Opponent 3----
|
|
||||||
if(ghostHistoryData[i]?.opponent3CarId !== null && ghostHistoryData[i]?.opponent3CarId !== undefined)
|
|
||||||
{
|
|
||||||
let ghostOpponentCar3 = await prisma.car.findFirst({
|
|
||||||
where: {
|
|
||||||
carId: ghostHistoryData![i].opponent3CarId!
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
// If opponent is default ghost or random ghost
|
|
||||||
if(!(ghostOpponentCar3)){
|
|
||||||
ghostOpponentCar3 = await prisma.car.findFirst({});
|
|
||||||
ghostOpponentCar3!.name = 'S660';
|
|
||||||
ghostOpponentCar3!.manufacturer = 12;
|
|
||||||
ghostOpponentCar3!.model = 105;
|
|
||||||
ghostOpponentCar3!.visualModel = 130;
|
|
||||||
ghostOpponentCar3!.regionId = 18;
|
|
||||||
ghostOpponentCar3!.country = 'GLB';
|
|
||||||
}
|
|
||||||
|
|
||||||
// Get Opponent 3 tune
|
|
||||||
ghostOpponentCar3!.tunePower = ghostHistoryData![i].opponent3TunePower!;
|
|
||||||
ghostOpponentCar3!.tuneHandling = ghostHistoryData![i].opponent3TuneHandling!;
|
|
||||||
|
|
||||||
// Get the Data
|
|
||||||
ghostMob.push(wm.wm.protobuf.LoadGameHistoryResponse.GhostBattleRecord.GhostBattleRecordCar.create({
|
|
||||||
car: {
|
|
||||||
...ghostOpponentCar3!
|
|
||||||
},
|
|
||||||
result: ghostHistoryData![i].opponent3Result!
|
|
||||||
}));
|
|
||||||
}
|
|
||||||
// ----------------------------
|
|
||||||
|
|
||||||
// Push the ghost battle history data
|
|
||||||
list_ghostHistoryData.push(wm.wm.protobuf.LoadGameHistoryResponse.GhostBattleRecord.create({
|
|
||||||
carSetting: carSetings,
|
|
||||||
opponent: ghostOpponent,
|
|
||||||
mobs: ghostMob || null,
|
|
||||||
area: ghostHistoryData![i].area,
|
|
||||||
playedAt: ghostHistoryData![i].playedAt,
|
|
||||||
playedShopName: ghostHistoryData![i].playedShopName
|
|
||||||
}));
|
|
||||||
}
|
|
||||||
|
|
||||||
// Get current date
|
|
||||||
let date = Math.floor(new Date().getTime() / 1000);
|
|
||||||
|
|
||||||
// Response data
|
// Response data
|
||||||
let msg = {
|
let msg = {
|
||||||
error: wm.wm.protobuf.ErrorCode.ERR_SUCCESS,
|
error: wm.wm.protobuf.ErrorCode.ERR_SUCCESS,
|
||||||
taRecords: ta_records,
|
|
||||||
taRankingUpdatedAt: date,
|
// Time Attack Record
|
||||||
ghostHistory: list_ghostHistoryData,
|
taRecords: taRecords.ta_records,
|
||||||
|
taRankingUpdatedAt: taRecords.date,
|
||||||
|
|
||||||
|
// Ghost Battle Record
|
||||||
|
ghostHistory: ghostBattleRecord.ghostBattle_records,
|
||||||
ghostBattleCount: car!.rgPlayCount,
|
ghostBattleCount: car!.rgPlayCount,
|
||||||
ghostBattleWinCount: car!.rgWinCount,
|
ghostBattleWinCount: car!.rgWinCount,
|
||||||
|
|
||||||
|
// Stamp Sheet
|
||||||
stampSheetCount: car!.stampSheetCount,
|
stampSheetCount: car!.stampSheetCount,
|
||||||
stampSheet: car!.stampSheet
|
stampSheet: car!.stampSheet
|
||||||
}
|
}
|
||||||
@ -572,5 +225,27 @@ export default class GameModule extends Module {
|
|||||||
// Send the response to the client
|
// Send the response to the client
|
||||||
common.sendResponse(message, res);
|
common.sendResponse(message, res);
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
||||||
|
// Save Screenshot
|
||||||
|
app.post('/method/save_screenshot', async (req, res) => {
|
||||||
|
|
||||||
|
// 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);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
411
src/modules/game/functions.ts
Normal file
411
src/modules/game/functions.ts
Normal file
@ -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<body.earnedItems.length; i++){
|
||||||
|
await prisma.carItem.create({
|
||||||
|
data: {
|
||||||
|
carId: body.carId,
|
||||||
|
category: body.earnedItems[i].category,
|
||||||
|
itemId: body.earnedItems[i].itemId,
|
||||||
|
amount: 1
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get user item
|
||||||
|
// User item reward from the game is available
|
||||||
|
if(body.earnedUserItems.length !== 0)
|
||||||
|
{
|
||||||
|
console.log('User Item reward available, continuing ...');
|
||||||
|
|
||||||
|
for(let i=0; i<body.earnedUserItems.length; i++){
|
||||||
|
await prisma.userItem.create({
|
||||||
|
data: {
|
||||||
|
category: body.earnedUserItems[i].category,
|
||||||
|
itemId: body.earnedUserItems[i].itemId,
|
||||||
|
userId: body.car!.userId!,
|
||||||
|
earnedAt: 0,
|
||||||
|
type: 0
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Update the Car
|
||||||
|
export async function updateCar(body: wm.protobuf.SaveGameResultRequest, car: any)
|
||||||
|
{
|
||||||
|
// Check playet at timestamp
|
||||||
|
let timestamps = 0;
|
||||||
|
if(body.car?.lastPlayedAt !== undefined && body.car?.lastPlayedAt !== null)
|
||||||
|
{
|
||||||
|
if(body.car.lastPlayedAt !== 0)
|
||||||
|
{
|
||||||
|
timestamps = body.car.lastPlayedAt;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
timestamps = Math.floor(new Date().getTime() / 1000);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check P & H must not more than 34 (fully tuned value)
|
||||||
|
let tunePower = 0;
|
||||||
|
let tuneHandling = 0;
|
||||||
|
let totalTune = body.car!.tunePower + body.car!.tuneHandling;
|
||||||
|
if(totalTune <= 34)
|
||||||
|
{
|
||||||
|
tunePower = body.car!.tunePower;
|
||||||
|
tuneHandling = body.car!.tuneHandling;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Update car
|
||||||
|
await prisma.car.update({
|
||||||
|
where: {
|
||||||
|
carId: body.carId,
|
||||||
|
},
|
||||||
|
data: {
|
||||||
|
aura: body.car!.aura!,
|
||||||
|
auraMotif: body.car!.auraMotif!,
|
||||||
|
odometer: body.odometer,
|
||||||
|
playCount: body.playCount,
|
||||||
|
level: body.car!.level!,
|
||||||
|
title: body.car!.title!,
|
||||||
|
tunePower: tunePower,
|
||||||
|
tuneHandling: tuneHandling,
|
||||||
|
windowSticker: body.car!.windowSticker!,
|
||||||
|
lastPlayedAt: timestamps,
|
||||||
|
regionId: body.car!.regionId!,
|
||||||
|
rgStamp: common.sanitizeInputNotZero(body.rgResult?.rgStamp),
|
||||||
|
stampSheetCount: common.sanitizeInputNotZero(body.rgResult?.stampSheetCount)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
// Update car settings
|
||||||
|
await prisma.carSettings.update({
|
||||||
|
where: {
|
||||||
|
dbId: car!.carSettingsDbId
|
||||||
|
},
|
||||||
|
data: {
|
||||||
|
...body.setting
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Update Car Order and Saving Tutorial
|
||||||
|
export async function updateOrderTutorial(body: wm.protobuf.SaveGameResultRequest)
|
||||||
|
{
|
||||||
|
// Get User
|
||||||
|
let user = await prisma.user.findFirst({
|
||||||
|
where: {
|
||||||
|
id: body.car!.userId!
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// User Available
|
||||||
|
if (user)
|
||||||
|
{
|
||||||
|
// Get user tutorials
|
||||||
|
let storedTutorials = user!.tutorials;
|
||||||
|
|
||||||
|
// Update any seen tutorials
|
||||||
|
body.confirmedTutorials.forEach(
|
||||||
|
(idx) => 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<ghostHistoryData.length; i++)
|
||||||
|
{
|
||||||
|
// User car setting
|
||||||
|
let carSetings = wmproto.wm.protobuf.LoadGameHistoryResponse.GhostBattleRecord.GhostCarSetting.create({
|
||||||
|
tunePower: ghostHistoryData![i].tunePower,
|
||||||
|
tuneHandling: ghostHistoryData![i].tuneHandling,
|
||||||
|
});
|
||||||
|
|
||||||
|
// ----Ghost Opponent 1----
|
||||||
|
let ghostOpponentCar = await prisma.car.findFirst({
|
||||||
|
where: {
|
||||||
|
carId: ghostHistoryData![i].opponent1CarId!
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// If opponent is default ghost or random ghost
|
||||||
|
if(!(ghostOpponentCar))
|
||||||
|
{
|
||||||
|
ghostOpponentCar = await prisma.car.findFirst({});
|
||||||
|
ghostOpponentCar!.name = 'S660';
|
||||||
|
ghostOpponentCar!.manufacturer = 12;
|
||||||
|
ghostOpponentCar!.model = 105;
|
||||||
|
ghostOpponentCar!.visualModel = 130;
|
||||||
|
ghostOpponentCar!.regionId = 18;
|
||||||
|
ghostOpponentCar!.country = 'IDN';
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get Opponent 1 tune
|
||||||
|
ghostOpponentCar!.tunePower = ghostHistoryData![i].opponent1TunePower!;
|
||||||
|
ghostOpponentCar!.tuneHandling = ghostHistoryData![i].opponent1TuneHandling!;
|
||||||
|
|
||||||
|
// Get the Data
|
||||||
|
let ghostOpponent = wmproto.wm.protobuf.LoadGameHistoryResponse.GhostBattleRecord.GhostBattleRecordCar.create({
|
||||||
|
car: {
|
||||||
|
...ghostOpponentCar!
|
||||||
|
},
|
||||||
|
result: ghostHistoryData![i].opponent1Result!
|
||||||
|
});
|
||||||
|
// ------------------------
|
||||||
|
|
||||||
|
// ----Ghost Opponent 2 & 3----
|
||||||
|
// Empty list of ghost battle records for the player's car
|
||||||
|
let ghostMob: wmproto.wm.protobuf.LoadGameHistoryResponse.GhostBattleRecord.GhostBattleRecordCar[] = [];
|
||||||
|
|
||||||
|
// ----Ghost Opponent 2----
|
||||||
|
if(ghostHistoryData[i]?.opponent2CarId !== null && ghostHistoryData[i]?.opponent2CarId !== undefined)
|
||||||
|
{
|
||||||
|
let ghostOpponentCar2 = await prisma.car.findFirst({
|
||||||
|
where: {
|
||||||
|
carId: ghostHistoryData![i].opponent2CarId!
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// If opponent is default ghost or random ghost
|
||||||
|
if(!(ghostOpponentCar2))
|
||||||
|
{
|
||||||
|
ghostOpponentCar2 = await prisma.car.findFirst({});
|
||||||
|
ghostOpponentCar2!.name = 'S660';
|
||||||
|
ghostOpponentCar2!.manufacturer = 12;
|
||||||
|
ghostOpponentCar2!.model = 105;
|
||||||
|
ghostOpponentCar2!.visualModel = 130;
|
||||||
|
ghostOpponentCar2!.regionId = 18;
|
||||||
|
ghostOpponentCar2!.country = 'IDN';
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get Opponent 2 tune
|
||||||
|
ghostOpponentCar2!.tunePower = ghostHistoryData![i].opponent2TunePower!;
|
||||||
|
ghostOpponentCar2!.tuneHandling = ghostHistoryData![i].opponent2TuneHandling!;
|
||||||
|
|
||||||
|
// Get the Data
|
||||||
|
ghostMob.push(wmproto.wm.protobuf.LoadGameHistoryResponse.GhostBattleRecord.GhostBattleRecordCar.create({
|
||||||
|
car: {
|
||||||
|
...ghostOpponentCar2!
|
||||||
|
},
|
||||||
|
result: ghostHistoryData![i].opponent2Result!
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
// ------------------------
|
||||||
|
|
||||||
|
// ----Ghost Opponent 3----
|
||||||
|
if(ghostHistoryData[i]?.opponent3CarId !== null && ghostHistoryData[i]?.opponent3CarId !== undefined)
|
||||||
|
{
|
||||||
|
let ghostOpponentCar3 = await prisma.car.findFirst({
|
||||||
|
where: {
|
||||||
|
carId: ghostHistoryData![i].opponent3CarId!
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// If opponent is default ghost or random ghost
|
||||||
|
if(!(ghostOpponentCar3))
|
||||||
|
{
|
||||||
|
ghostOpponentCar3 = await prisma.car.findFirst({});
|
||||||
|
ghostOpponentCar3!.name = 'S660';
|
||||||
|
ghostOpponentCar3!.manufacturer = 12;
|
||||||
|
ghostOpponentCar3!.model = 105;
|
||||||
|
ghostOpponentCar3!.visualModel = 130;
|
||||||
|
ghostOpponentCar3!.regionId = 18;
|
||||||
|
ghostOpponentCar3!.country = 'IDN';
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get Opponent 3 tune
|
||||||
|
ghostOpponentCar3!.tunePower = ghostHistoryData![i].opponent3TunePower!;
|
||||||
|
ghostOpponentCar3!.tuneHandling = ghostHistoryData![i].opponent3TuneHandling!;
|
||||||
|
|
||||||
|
// Get the Data
|
||||||
|
ghostMob.push(wmproto.wm.protobuf.LoadGameHistoryResponse.GhostBattleRecord.GhostBattleRecordCar.create({
|
||||||
|
car: {
|
||||||
|
...ghostOpponentCar3!
|
||||||
|
},
|
||||||
|
result: ghostHistoryData![i].opponent3Result!
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
// ----------------------------
|
||||||
|
|
||||||
|
// Push the ghost battle history data
|
||||||
|
ghostBattle_records.push(wmproto.wm.protobuf.LoadGameHistoryResponse.GhostBattleRecord.create({
|
||||||
|
carSetting: carSetings,
|
||||||
|
opponent: ghostOpponent,
|
||||||
|
mobs: ghostMob || null,
|
||||||
|
area: ghostHistoryData![i].area,
|
||||||
|
playedAt: ghostHistoryData![i].playedAt,
|
||||||
|
playedShopName: ghostHistoryData![i].playedShopName
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
|
||||||
|
return { ghostBattle_records }
|
||||||
|
}
|
@ -5,9 +5,9 @@ import { wm } from "../../wmmt/wm.proto";
|
|||||||
import wmproto from "../../wmmt/wm.proto";
|
import wmproto from "../../wmmt/wm.proto";
|
||||||
|
|
||||||
// Import Util
|
// Import Util
|
||||||
import * as common from "../../util/common";
|
import * as common from "../util/common";
|
||||||
import * as ghost_history from "../ghost/ghost_history";
|
import * as ghost_history from "../../util/ghost/ghost_history";
|
||||||
import * as ghost_stamp from "../ghost/ghost_stamp";
|
import * as ghost_stamp from "../../util/ghost/ghost_stamp";
|
||||||
|
|
||||||
// Save ghost battle result
|
// Save ghost battle result
|
||||||
export async function saveGhostBattleResult(body: wm.protobuf.SaveGameResultRequest, car: any)
|
export async function saveGhostBattleResult(body: wm.protobuf.SaveGameResultRequest, car: any)
|
@ -5,8 +5,8 @@ import { prisma } from "../..";
|
|||||||
import { wm } from "../../wmmt/wm.proto";
|
import { wm } from "../../wmmt/wm.proto";
|
||||||
|
|
||||||
// Import Util
|
// Import Util
|
||||||
import * as common from "../common";
|
import * as common from "../util/common";
|
||||||
import * as check_step from "../games/games_util/check_step";
|
import * as check_step from "./games_util/check_step";
|
||||||
|
|
||||||
|
|
||||||
// Save story result
|
// Save story result
|
@ -4,7 +4,7 @@ import { prisma } from "../..";
|
|||||||
import { wm } from "../../wmmt/wm.proto";
|
import { wm } from "../../wmmt/wm.proto";
|
||||||
|
|
||||||
// Import Util
|
// Import Util
|
||||||
import * as common from "../common";
|
import * as common from "../util/common";
|
||||||
|
|
||||||
|
|
||||||
// Save versus battle result
|
// Save versus battle result
|
@ -10,7 +10,7 @@ import * as wm from "../wmmt/wm.proto";
|
|||||||
import * as wmsrv from "../wmmt/service.proto";
|
import * as wmsrv from "../wmmt/service.proto";
|
||||||
|
|
||||||
// Import Util
|
// Import Util
|
||||||
import * as common from "../util/common";
|
import * as common from "./util/common";
|
||||||
import * as ghost_save_trail from "../util/ghost/ghost_save_trail";
|
import * as ghost_save_trail from "../util/ghost/ghost_save_trail";
|
||||||
import * as ghost_trail from "../util/ghost/ghost_trail";
|
import * as ghost_trail from "../util/ghost/ghost_trail";
|
||||||
import * as ghost_area from "../util/ghost/ghost_area";
|
import * as ghost_area from "../util/ghost/ghost_area";
|
||||||
@ -747,11 +747,11 @@ export default class GhostModule extends Module {
|
|||||||
// Response data
|
// Response data
|
||||||
let msg = {
|
let msg = {
|
||||||
carId: pCarId,
|
carId: pCarId,
|
||||||
area: pArea,
|
area: 18,
|
||||||
ramp: rampVal,
|
ramp: 37,
|
||||||
path: pathVal,
|
path: 56,
|
||||||
playedAt: playedAt,
|
playedAt: playedAt,
|
||||||
trail: ghostTrail
|
trail: new Uint8Array([1, 2, 3, 4])
|
||||||
};
|
};
|
||||||
|
|
||||||
// Encode the response
|
// Encode the response
|
||||||
|
0
src/modules/ghost/functions.ts
Normal file
0
src/modules/ghost/functions.ts
Normal file
@ -7,7 +7,7 @@ import { Config } from "../config";
|
|||||||
import * as wm from "../wmmt/wm.proto";
|
import * as wm from "../wmmt/wm.proto";
|
||||||
|
|
||||||
// Import Util
|
// Import Util
|
||||||
import * as common from "../util/common";
|
import * as common from "./util/common";
|
||||||
import * as ghost_ocm from "../util/ghost/ghost_ocm";
|
import * as ghost_ocm from "../util/ghost/ghost_ocm";
|
||||||
import * as ghost_ocm_area from "../util/ghost/ghost_ocm_area";
|
import * as ghost_ocm_area from "../util/ghost/ghost_ocm_area";
|
||||||
|
|
||||||
@ -462,9 +462,6 @@ export default class GhostModule extends Module {
|
|||||||
carId: ocmTallyRecord!.carId,
|
carId: ocmTallyRecord!.carId,
|
||||||
competitionId: ocmEventDate!.competitionId,
|
competitionId: ocmEventDate!.competitionId,
|
||||||
periodId: period_id,
|
periodId: period_id,
|
||||||
area: areaVal,
|
|
||||||
ramp: rampVal,
|
|
||||||
path: pathVal,
|
|
||||||
},
|
},
|
||||||
orderBy:{
|
orderBy:{
|
||||||
playedAt: 'desc'
|
playedAt: 'desc'
|
||||||
@ -494,6 +491,9 @@ export default class GhostModule extends Module {
|
|||||||
// Set Ghost stuff Value
|
// Set Ghost stuff Value
|
||||||
cars!.lastPlayedAt = checkGhostTrail.playedAt
|
cars!.lastPlayedAt = checkGhostTrail.playedAt
|
||||||
ghostTrailId = checkGhostTrail.dbId!;
|
ghostTrailId = checkGhostTrail.dbId!;
|
||||||
|
areaVal = Number(checkGhostTrail.area);
|
||||||
|
rampVal = Number(checkGhostTrail.ramp);
|
||||||
|
pathVal = Number(checkGhostTrail.path);
|
||||||
ghostTypes = wm.wm.protobuf.GhostType.GHOST_NORMAL;
|
ghostTypes = wm.wm.protobuf.GhostType.GHOST_NORMAL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -508,9 +508,6 @@ export default class GhostModule extends Module {
|
|||||||
carId: 999999999,
|
carId: 999999999,
|
||||||
competitionId: ocmEventDate!.competitionId,
|
competitionId: ocmEventDate!.competitionId,
|
||||||
periodId: 0,
|
periodId: 0,
|
||||||
area: areaVal,
|
|
||||||
ramp: rampVal,
|
|
||||||
path: pathVal
|
|
||||||
},
|
},
|
||||||
orderBy:{
|
orderBy:{
|
||||||
playedAt: 'desc'
|
playedAt: 'desc'
|
||||||
@ -553,7 +550,10 @@ export default class GhostModule extends Module {
|
|||||||
});
|
});
|
||||||
|
|
||||||
// Set Ghost stuff Value
|
// Set Ghost stuff Value
|
||||||
ghostTrailId = checkGhostTrail!.dbId!;
|
ghostTrailId = checkGhostTrail!.dbId;
|
||||||
|
areaVal = Number(checkGhostTrail!.area);
|
||||||
|
rampVal = Number(checkGhostTrail!.ramp);
|
||||||
|
pathVal = Number(checkGhostTrail!.path);
|
||||||
ghostTypes = wm.wm.protobuf.GhostType.GHOST_NORMAL;
|
ghostTypes = wm.wm.protobuf.GhostType.GHOST_NORMAL;
|
||||||
}
|
}
|
||||||
else if(ocmEventDate!.competitionCloseAt < date && ocmEventDate!.competitionEndAt > date)
|
else if(ocmEventDate!.competitionCloseAt < date && ocmEventDate!.competitionEndAt > date)
|
||||||
|
@ -9,7 +9,7 @@ import * as wm from "../wmmt/wm.proto";
|
|||||||
import * as wmsrv from "../wmmt/service.proto";
|
import * as wmsrv from "../wmmt/service.proto";
|
||||||
|
|
||||||
// Import Util
|
// Import Util
|
||||||
import * as common from "../util/common";
|
import * as common from "./util/common";
|
||||||
|
|
||||||
|
|
||||||
export default class ResourceModule extends Module {
|
export default class ResourceModule extends Module {
|
||||||
|
@ -1,12 +1,12 @@
|
|||||||
import { Application } from "express";
|
import { Application } from "express";
|
||||||
import { Module } from "module";
|
import { Module } from "module";
|
||||||
import { prisma } from "..";
|
|
||||||
|
|
||||||
// Import Proto
|
// Import Proto
|
||||||
import * as wm from "../wmmt/wm.proto";
|
import * as wm from "../wmmt/wm.proto";
|
||||||
|
|
||||||
// Import Util
|
// 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 {
|
export default class StartupModule extends Module {
|
||||||
@ -21,85 +21,9 @@ export default class StartupModule extends Module {
|
|||||||
// Get current date
|
// Get current date
|
||||||
let date = Math.floor(new Date().getTime() / 1000);
|
let date = Math.floor(new Date().getTime() / 1000);
|
||||||
|
|
||||||
// Get current / previous active OCM Event
|
// Get Competition (OCM) Event Date
|
||||||
let ocmEventDate = await prisma.oCMEvent.findFirst({
|
let getCompetitionSchedule = await startupFunctions.competitionSchedule(date, null);
|
||||||
where: {
|
let additionalCompetitionMsg = getCompetitionSchedule.additionalCompetitionMsg;
|
||||||
// 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
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Response data
|
// Response data
|
||||||
let msg = {
|
let msg = {
|
||||||
@ -116,8 +40,9 @@ export default class StartupModule extends Module {
|
|||||||
pluses: 0,
|
pluses: 0,
|
||||||
releaseAt: 0 // idk what this is
|
releaseAt: 0 // idk what this is
|
||||||
},
|
},
|
||||||
latestCompetitionId: lastCompetitionId || null,
|
|
||||||
competitionSchedule: competitionSchedule || null // OCM Event Available or not
|
// Competition (OCM)
|
||||||
|
...additionalCompetitionMsg
|
||||||
}
|
}
|
||||||
|
|
||||||
// Encode the response
|
// Encode the response
|
||||||
@ -148,6 +73,7 @@ export default class StartupModule extends Module {
|
|||||||
common.sendResponse(message, res);
|
common.sendResponse(message, res);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
// Ping
|
// Ping
|
||||||
app.post('/method/ping', (req, res) => {
|
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) => {
|
app.post('/method/register_system_stats', async (req, res) => {
|
||||||
|
|
||||||
let body = wm.wm.protobuf.RegisterSystemStatsRequest.decode(req.body);
|
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) => {
|
app.post('/method/update_event_mode_serial', async (req, res) => {
|
||||||
|
|
||||||
let body = wm.wm.protobuf.UpdateEventModeSerialRequest.decode(req.body);
|
let body = wm.wm.protobuf.UpdateEventModeSerialRequest.decode(req.body);
|
||||||
@ -197,7 +125,10 @@ export default class StartupModule extends Module {
|
|||||||
// Response data
|
// Response data
|
||||||
let msg = {
|
let msg = {
|
||||||
error: wm.wm.protobuf.ErrorCode.ERR_SUCCESS,
|
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
|
// 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) => {
|
app.post('/method/submit_client_log', async (req, res) => {
|
||||||
|
|
||||||
let body = wm.wm.protobuf.SubmitClientLogRequest.decode(req.body);
|
let body = wm.wm.protobuf.SubmitClientLogRequest.decode(req.body);
|
||||||
|
115
src/modules/startup/functions.ts
Normal file
115
src/modules/startup/functions.ts
Normal file
@ -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 }
|
||||||
|
}
|
@ -8,8 +8,8 @@ import { Car } from "@prisma/client";
|
|||||||
import * as wm from "../wmmt/wm.proto";
|
import * as wm from "../wmmt/wm.proto";
|
||||||
|
|
||||||
// Import Util
|
// Import Util
|
||||||
import * as scratch from "../util/scratch";
|
import * as scratch from "./terminal/scratch";
|
||||||
import * as common from "../util/common";
|
import * as common from "./util/common";
|
||||||
|
|
||||||
|
|
||||||
export default class TerminalModule extends Module {
|
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) => {
|
app.post('/method/load_unreceived_user_items', async (req, res) => {
|
||||||
|
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
import { prisma } from "../..";
|
import { prisma } from "../..";
|
||||||
|
|
||||||
|
|
||||||
// Sends the server response to the client
|
// Sends the server response to the client
|
||||||
export async function checkScratchCar(userId: number, visualModel: number)
|
export async function checkScratchCar(userId: number, visualModel: number)
|
||||||
{
|
{
|
@ -1,8 +1,8 @@
|
|||||||
import { prisma } from "..";
|
import { prisma } from "../..";
|
||||||
import { Config } from "../config";
|
import { Config } from "../../config";
|
||||||
|
|
||||||
//Import Proto
|
//Import Proto
|
||||||
import * as wm from "../wmmt/wm.proto";
|
import * as wm from "../../wmmt/wm.proto";
|
||||||
|
|
||||||
// *** CONSTANTS ***
|
// *** CONSTANTS ***
|
||||||
|
|
@ -6,7 +6,7 @@ import { prisma } from "..";
|
|||||||
import * as wm from "../wmmt/wm.proto";
|
import * as wm from "../wmmt/wm.proto";
|
||||||
|
|
||||||
// Import Util
|
// Import Util
|
||||||
import * as common from "../util/common";
|
import * as common from "./util/common";
|
||||||
|
|
||||||
|
|
||||||
export default class TimeAttackModule extends Module {
|
export default class TimeAttackModule extends Module {
|
||||||
|
@ -7,8 +7,8 @@ import { prisma } from "..";
|
|||||||
import * as wm from "../wmmt/wm.proto";
|
import * as wm from "../wmmt/wm.proto";
|
||||||
|
|
||||||
// Import Util
|
// Import Util
|
||||||
import * as scratch from "../util/scratch";
|
import * as scratch from "./terminal/scratch";
|
||||||
import * as common from "../util/common";
|
import * as common from "./util/common";
|
||||||
|
|
||||||
|
|
||||||
export default class UserModule extends Module {
|
export default class UserModule extends Module {
|
||||||
@ -20,6 +20,13 @@ export default class UserModule extends Module {
|
|||||||
// Get the request body for the load user request
|
// Get the request body for the load user request
|
||||||
let body = wm.wm.protobuf.LoadUserRequest.decode(req.body);
|
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
|
// Get the user from the database
|
||||||
let user = await prisma.user.findFirst({
|
let user = await prisma.user.findFirst({
|
||||||
where: {
|
where: {
|
||||||
@ -69,7 +76,7 @@ export default class UserModule extends Module {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Check if new card registration is allowed or not
|
// 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
|
// New card registration is allowed
|
||||||
if (newCardsBanned === 0)
|
if (newCardsBanned === 0)
|
||||||
|
@ -4,7 +4,7 @@ import { Config } from "../../config";
|
|||||||
import { wm } from "../../wmmt/wm.proto";
|
import { wm } from "../../wmmt/wm.proto";
|
||||||
|
|
||||||
// Import Util
|
// 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_stamp from "../ghost/ghost_stamp";
|
||||||
import * as ghost_get_area_from_path from "../ghost/ghost_util/ghost_get_area_from_path";
|
import * as ghost_get_area_from_path from "../ghost/ghost_util/ghost_get_area_from_path";
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user