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