1
0
mirror of synced 2024-12-05 03:27:57 +01:00

Merge pull request #35 from ghkkk090/master

ghost stamp, ghost search by region, ghost search by store, ghost history, config.json, etc (i forgot)
This commit is contained in:
Luna 2022-08-25 09:38:25 +01:00 committed by GitHub
commit fff0e3e083
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
27 changed files with 2096 additions and 1255 deletions

View File

@ -1,6 +1,9 @@
{
"placeId": "JPN0123",
"shopName": "Bayshore",
"shopNickname": "Bayshore",
"regionId": "1",
"country": "JPN",
"regionName": "JPN0123",
"serverIp": "127.0.0.1",
"gameOptions": {

View File

@ -0,0 +1,35 @@
-- AlterTable
ALTER TABLE "Car" ADD COLUMN "stampSheet" INTEGER[],
ADD COLUMN "stampSheetCount" INTEGER NOT NULL DEFAULT 0,
ADD COLUMN "vsStarCountMax" INTEGER NOT NULL DEFAULT 0,
ALTER COLUMN "stLoseBits" SET DEFAULT 0;
-- CreateTable
CREATE TABLE "CarChallenger" (
"id" SERIAL NOT NULL,
"carId" INTEGER NOT NULL,
"challengerCarId" INTEGER NOT NULL,
"stamp" INTEGER NOT NULL,
"result" INTEGER NOT NULL,
"area" INTEGER NOT NULL,
CONSTRAINT "CarChallenger_pkey" PRIMARY KEY ("id")
);
-- CreateTable
CREATE TABLE "CarStampTarget" (
"id" SERIAL NOT NULL,
"carId" INTEGER NOT NULL,
"stampTargetCarId" INTEGER NOT NULL,
"returnCount" INTEGER NOT NULL,
"locked" BOOLEAN NOT NULL,
"recommended" BOOLEAN NOT NULL,
CONSTRAINT "CarStampTarget_pkey" PRIMARY KEY ("id")
);
-- AddForeignKey
ALTER TABLE "CarChallenger" ADD CONSTRAINT "CarChallenger_challengerCarId_fkey" FOREIGN KEY ("challengerCarId") REFERENCES "Car"("carId") ON DELETE RESTRICT ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE "CarStampTarget" ADD CONSTRAINT "CarStampTarget_stampTargetCarId_fkey" FOREIGN KEY ("stampTargetCarId") REFERENCES "Car"("carId") ON DELETE RESTRICT ON UPDATE CASCADE;

View File

@ -0,0 +1,5 @@
-- AlterTable
ALTER TABLE "Car" ALTER COLUMN "stLoseBits" SET DEFAULT 0;
-- AlterTable
ALTER TABLE "CarSettings" ALTER COLUMN "volume" SET DEFAULT 2;

View File

@ -0,0 +1,17 @@
-- AlterTable
ALTER TABLE "Car" ADD COLUMN "lastPlayedPlaceId" INTEGER,
ALTER COLUMN "stLoseBits" SET DEFAULT 0;
-- CreateTable
CREATE TABLE "PlaceList" (
"id" SERIAL NOT NULL,
"placeId" TEXT NOT NULL,
"regionId" INTEGER NOT NULL,
"locked" BOOLEAN NOT NULL,
"recommended" BOOLEAN NOT NULL,
CONSTRAINT "PlaceList_pkey" PRIMARY KEY ("id")
);
-- AddForeignKey
ALTER TABLE "Car" ADD CONSTRAINT "Car_lastPlayedPlaceId_fkey" FOREIGN KEY ("lastPlayedPlaceId") REFERENCES "PlaceList"("id") ON DELETE SET NULL ON UPDATE CASCADE;

View File

@ -0,0 +1,17 @@
/*
Warnings:
- You are about to drop the column `locked` on the `PlaceList` table. All the data in the column will be lost.
- You are about to drop the column `recommended` on the `PlaceList` table. All the data in the column will be lost.
- Added the required column `country` to the `PlaceList` table without a default value. This is not possible if the table is not empty.
- Added the required column `shopName` to the `PlaceList` table without a default value. This is not possible if the table is not empty.
*/
-- AlterTable
ALTER TABLE "Car" ALTER COLUMN "stLoseBits" SET DEFAULT 0;
-- AlterTable
ALTER TABLE "PlaceList" DROP COLUMN "locked",
DROP COLUMN "recommended",
ADD COLUMN "country" TEXT NOT NULL,
ADD COLUMN "shopName" TEXT NOT NULL;

View File

@ -0,0 +1,5 @@
-- AlterTable
ALTER TABLE "Car" ALTER COLUMN "stLoseBits" SET DEFAULT 0;
-- AlterTable
ALTER TABLE "CarChallenger" ADD COLUMN "lastPlayedAt" INTEGER NOT NULL DEFAULT 0;

View File

@ -88,8 +88,6 @@ model Car {
rivalMarker Int @default(0)
lastPlayedAt Int @default(0)
aura Int @default(0)
auraMotif Int @default(0)
ghostLevel Int @default(1)
// This is more data about the car
tuningPoints Int @default(0)
@ -98,15 +96,20 @@ model Car {
earnedCustomColor Boolean @default(false)
carSettingsDbId Int @unique
settings CarSettings @relation(fields: [carSettingsDbId], references: [dbId])
auraMotif Int @default(0)
vsPlayCount Int @default(0)
vsBurstCount Int @default(0)
vsStarCount Int @default(0)
vsStarCountMax Int @default(0)
vsCoolOrWild Int @default(0)
vsSmoothOrRough Int @default(0)
vsTripleStarMedals Int @default(0)
vsDoubleStarMedals Int @default(0)
vsSingleStarMedals Int @default(0)
vsPlainMedals Int @default(0)
ghostLevel Int @default(1)
rgPlayCount Int @default(0)
rgWinCount Int @default(0)
rgTrophy Int @default(0)
@ -114,8 +117,12 @@ model Car {
rgStamp Int @default(0)
rgAcquireAllCrowns Boolean @default(false)
rgRegionMapScore Int[]
stampSheetCount Int @default(0)
stampSheet Int[]
dressupLevel Int @default(0)
dressupPoint Int @default(0)
stPlayCount Int @default(0)
stClearBits Int @default(0)
stClearDivCount Int @default(0)
@ -125,24 +132,27 @@ model Car {
stConsecutiveWinsMax Int @default(0)
stCompleted100Episodes Boolean @default(false)
items CarItem[]
carGTWingDbId Int @unique
gtWing CarGTWing @relation(fields: [carGTWingDbId], references: [dbId])
carStateDbId Int @unique
state CarState @relation(fields: [carStateDbId], references: [dbId])
TimeAttackRecord TimeAttackRecord[]
CarCrown CarCrown[]
GhostTrail GhostTrail[]
GhostBattleRecord GhostBattleRecord[]
CarPathandTuning CarPathandTuning[]
lastPlayedPlaceId Int?
lastPlayedPlace PlaceList? @relation(fields: [lastPlayedPlaceId], references: [id])
items CarItem[]
carGTWingDbId Int @unique
gtWing CarGTWing @relation(fields: [carGTWingDbId], references: [dbId])
carStateDbId Int @unique
state CarState @relation(fields: [carStateDbId], references: [dbId])
TimeAttackRecord TimeAttackRecord[]
CarCrown CarCrown[]
GhostTrail GhostTrail[]
GhostBattleRecord GhostBattleRecord[]
CarPathandTuning CarPathandTuning[]
OCMGhostBattleRecord OCMGhostBattleRecord[]
OCMTally OCMTally[]
OCMTop1Ghost OCMTop1Ghost[]
OCMGhostTrail OCMGhostTrail[]
OCMPlayRecord OCMPlayRecord[]
GhostRegisteredFromTerminal GhostRegisteredFromTerminal[]
CarStampTarget CarStampTarget[]
CarChallenger CarChallenger[]
}
model CarGTWing {
@ -175,7 +185,7 @@ model CarSettings {
retire Boolean @default(false)
meter Int @default(0)
navigationMap Boolean @default(true)
volume Int @default(1)
volume Int @default(2)
bgm Int @default(0)
nameplate Int @default(0)
nameplateColor Int @default(0)
@ -394,4 +404,36 @@ model GhostRegisteredFromTerminal {
carId Int
competitionId Int?
opponentCarId Int
}
model CarChallenger {
id Int @id @default(autoincrement())
challengerCar Car @relation(fields: [challengerCarId], references: [carId])
carId Int
challengerCarId Int
stamp Int
result Int
area Int
lastPlayedAt Int @default(0)
}
model CarStampTarget {
id Int @id @default(autoincrement())
stampTargetCar Car @relation(fields: [stampTargetCarId], references: [carId])
carId Int
stampTargetCarId Int
returnCount Int
locked Boolean
recommended Boolean
}
model PlaceList {
id Int @id @default(autoincrement())
car Car[]
placeId String
regionId Int
shopName String
country String
}

View File

@ -72,6 +72,9 @@ export default class AllnetModule extends Module {
let shopName = Config.getConfig().shopName;
let shopNick = Config.getConfig().shopNickname;
let regionName = Config.getConfig().regionName;
let placeId = Config.getConfig().placeId;
let country = Config.getConfig().country;
let regionId = Config.getConfig().regionId;
// TODO: Implement board authentication here.
@ -79,15 +82,15 @@ export default class AllnetModule extends Module {
stat: 1,
uri: STARTUP_URI,
host: STARTUP_HOST,
place_id: "JPN0123",
place_id: placeId,
name: shopName,
nickname: shopNick,
region0: "1",
region0: regionId,
region_name0: regionName,
region_name1: "X",
region_name2: "Y",
region_name3: "Z",
country: "JPN",
country: country,
allnet_id: "456",
timezone: "002:00",
setting: "",

View File

@ -1,8 +1,11 @@
import fs from 'fs';
export interface ConfigFile {
placeId: string;
shopName: string;
shopNickname: string;
regionId: number;
country: string;
regionName: string;
serverIp?: string;
gameOptions: GameOptions;

View File

@ -30,7 +30,8 @@ export default class CarModule extends Module {
include: {
settings: true,
items: true,
gtWing: true
gtWing: true,
lastPlayedPlace: true,
}
});
@ -51,30 +52,12 @@ export default class CarModule extends Module {
// Get current / previous active OCM Event
let ocmEventDate = await prisma.oCMEvent.findFirst({
where: {
OR: [
{
// qualifyingPeriodStartAt is less than current date
qualifyingPeriodStartAt: { lte: date },
// qualifyingPeriodCloseAt is greater than current date
qualifyingPeriodCloseAt: { gte: date },
},
{
// competitionStartAt is less than current date
competitionStartAt: { lte: date },
// competitionCloseAt is greater than current date
competitionCloseAt: { gte: date },
},
{
// competitionCloseAt is less than current date
competitionCloseAt: { lte: date },
// competitionEndAt is greater than current date
competitionEndAt: {gte: date },
}
],
},
// qualifyingPeriodStartAt is less than current date
qualifyingPeriodStartAt: { lte: date },
// competitionEndAt is greater than current date
competitionEndAt: { gte: date },
},
orderBy: [
{
dbId: 'desc'
@ -140,18 +123,11 @@ export default class CarModule extends Module {
carId: carId
},
include:{
gtWing: true
gtWing: true,
lastPlayedPlace: true
}
});
// Get Place
let playedPlace = wm.wm.protobuf.Place.create({
placeId: 'JPN0123',
shopName: Config.getConfig().shopName,
regionId: 18,
country: 'JPN'
});
// Get Ghost Trail
let ghostTrailNo1 = await prisma.oCMTop1GhostTrail.findFirst({
where:{
@ -166,7 +142,6 @@ export default class CarModule extends Module {
ghostCarsNo1 = wm.wm.protobuf.GhostCar.create({
car: {
...cars!,
lastPlayedPlace: playedPlace
},
area: ghostTrailNo1!.area,
ramp: ghostTrailNo1!.ramp,
@ -180,15 +155,70 @@ export default class CarModule extends Module {
}
}
// Check opponents target
let opponentTarget = await prisma.carStampTarget.findMany({
where:{
stampTargetCarId: body.carId,
locked: false,
recommended: true,
}
})
let carsChallengers: wm.wm.protobuf.ChallengerCar[] = [];
let returnCount = 1;
if(opponentTarget.length > 0)
{
console.log('Challengers Available');
for(let i=0; i<opponentTarget.length; i++)
{
// 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
}
})
carsChallengers.push(
wm.wm.protobuf.ChallengerCar.create({
car: carTarget!,
stamp: challengers.stamp,
result: challengers.result,
area: challengers.area
})
);
}
}
}
// Response data
let msg = {
error: wm.wm.protobuf.ErrorCode.ERR_SUCCESS,
car: {
...car!
...car!,
},
tuningPoint: car!.tuningPoints,
setting: car!.settings,
vsStarCountMax: car!.vsStarCount,
rgPreviousVersionPlayCount: 0,
stCompleted_100Episodes: car!.stCompleted100Episodes,
auraMotifAutoChange: false,
@ -199,6 +229,13 @@ export default class CarModule extends Module {
ownedItems: car!.items,
lastPlayedAt: car!.lastPlayedAt,
announceEventModePrize: true,
// Stamp or Challenger
challenger: carsChallengers[0] || null,
challengerReturnCount: returnCount || null,
numOfChallengers: carsChallengers.length || null,
// OCM Challenge Top 1
opponentGhost: ghostCarsNo1 || null,
opponentTrailId: trailIdNo1 || null,
opponentCompetitionId: ocmEventDate?.competitionId || null
@ -396,6 +433,7 @@ export default class CarModule extends Module {
carGTWingDbId: gtWing.dbId,
regionId: randomRegionId,
lastPlayedAt: date,
lastPlayedPlaceId: 1, // Server Default
};
// Check if user have more than one cars
@ -528,6 +566,9 @@ export default class CarModule extends Module {
// Car is set
if (cars)
{
// Get current date
let date = Math.floor(new Date().getTime() / 1000);
// Car update data
data = {
customColor: common.sanitizeInput(cars.customColor),
@ -548,6 +589,7 @@ export default class CarModule extends Module {
aura: common.sanitizeInput(cars.aura),
auraMotif: common.sanitizeInput(cars.auraMotif),
rgStamp: common.sanitizeInput(body.rgStamp),
lastPlayed: date
}
// Update the car info
@ -566,7 +608,8 @@ export default class CarModule extends Module {
},
include: {
settings: true,
gtWing: true
gtWing: true,
lastPlayedPlace: true
}
});

View File

@ -8,7 +8,7 @@ import * as wm from "../wmmt/wm.proto";
// Import Util
import * as common from "../util/common";
import * as meter_reward from "../util/meter_reward";
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";
@ -28,6 +28,10 @@ export default class GameModule extends Module {
let car = await prisma.car.findFirst({
where: {
carId: body.carId
},
include:{
gtWing: true,
lastPlayedPlace: true
}
});
@ -68,13 +72,14 @@ export default class GameModule extends Module {
case wm.wm.protobuf.GameMode.MODE_GHOST_BATTLE:
{
// Calling save ghost battle result function (BASE_PATH/src/util/games/ghost.ts)
let ghostReturn = await ghost.saveGhostBattleResult(body, car);
let ghostReturn = await ghost.saveGhostBattleResult(body, car);
// Set this to tell the server if user is playing ghost battle mode
ghostModePlay = ghostReturn.ghostModePlay;
// For OCM Ghost Batle Mode
// Disable update trail if current advantage distance record is not better than previous advantage distance record
// For OCM : Disable update trail if current advantage distance record is not better than previous advantage distance record
// For Crown : Disable update trail if lose
// Ghost Battle will return true
updateNewTrail = ghostReturn.updateNewTrail;
// Check if user playing OCM Ghost Battle Mode
@ -88,7 +93,7 @@ export default class GameModule extends Module {
case wm.wm.protobuf.GameMode.MODE_VS_BATTLE:
{
// Calling save vs battle result function (BASE_PATH/src/util/games/versus.ts)
await versus.saveVersusBattleResult(body);
await versus.saveVersusBattleResult(body, car);
// Break the switch case
break;
@ -167,7 +172,9 @@ export default class GameModule extends Module {
tuneHandling: body.car!.tuneHandling!,
windowSticker: body.car!.windowSticker!,
lastPlayedAt: timestamps,
regionId: body.car!.regionId!
regionId: body.car!.regionId!,
rgStamp: common.sanitizeInputNotZero(body.rgResult?.rgStamp),
stampSheetCount: common.sanitizeInputNotZero(body.rgResult?.stampSheetCount)
}
})
@ -269,7 +276,7 @@ export default class GameModule extends Module {
msg = {
error: wm.wm.protobuf.ErrorCode.ERR_SUCCESS
// No session for saving ghost trail (not playing Ghost Battle Mode)
// No session for saving ghost trail (not playing Ghost Battle Mode / Retiring)
}
}
@ -294,6 +301,10 @@ export default class GameModule extends Module {
let car = await prisma.car.findFirst({
where: {
carId: body.carId
},
include:{
gtWing: true,
lastPlayedPlace: true
}
});
@ -539,16 +550,20 @@ export default class GameModule extends Module {
playedShopName: ghostHistoryData![i].playedShopName
}));
}
// Get current date
let date = Math.floor(new Date().getTime() / 1000);
// Response data
let msg = {
error: wm.wm.protobuf.ErrorCode.ERR_SUCCESS,
taRecords: ta_records,
taRankingUpdatedAt: 1,
taRankingUpdatedAt: date,
ghostHistory: list_ghostHistoryData,
ghostBattleCount: car!.rgPlayCount,
ghostBattleWinCount: car!.rgWinCount,
stampSheetCount: 0,
stampSheetCount: car!.stampSheetCount,
stampSheet: car!.stampSheet
}
// Encode the response

View File

@ -1,8 +1,9 @@
import { Application } from "express";
import { Module } from "module";
import { prisma } from "..";
import { CarPathandTuning, GhostTrail } from "@prisma/client";
import { CarPathandTuning } from "@prisma/client";
import Long from "long";
import { Config } from "../config";
// Import Proto
import * as wm from "../wmmt/wm.proto";
@ -10,8 +11,8 @@ import * as wmsrv from "../wmmt/service.proto";
// Import Util
import * as common from "../util/common";
import * as ghost_save_trail from "../util/games/ghost_save_trail";
import * as ghost_trail from "../util/games/ghost_trail";
import * as ghost_save_trail from "../util/ghost/ghost_save_trail";
import * as ghost_trail from "../util/ghost/ghost_trail";
export default class GhostModule extends Module {
@ -20,43 +21,131 @@ export default class GhostModule extends Module {
// Load Ghost Battle Info
app.post('/method/load_ghost_battle_info', async (req, res) => {
// ---For testing only---
let cars = await prisma.car.findMany({
where: {
OR: [
{
name: { startsWith: '' }
},
{
name: { startsWith: 'きつ' }
},
],
},
include:{
gtWing: true
// Get the request body for the load stamp target request
let body = wm.wm.protobuf.LoadGhostBattleInfoRequest.decode(req.body);
let car = await prisma.car.findFirst({
where:{
carId: body.carId
},
orderBy: {
carId: 'asc'
include:{
gtWing: true,
lastPlayedPlace: true
}
})
// Car History
let findChallenger = await prisma.carChallenger.findMany({
where: {
challengerCarId: body.carId
},
orderBy:{
lastPlayedAt: 'desc'
},
take: 10
});
})
for(let i=0; i<cars.length; i++)
let carsHistory: wm.wm.protobuf.Car[] = [];
if(findChallenger.length > 0)
{
// If regionId is 0 or not set, game will crash after defeating the ghost
if(cars[i].regionId === 0)
{
let randomRegionId = Math.floor(Math.random() * 47) + 1;
cars[i].regionId = randomRegionId;
for(let i=0; i<findChallenger.length; i++)
{
let car = await prisma.car.findFirst({
where: {
carId: findChallenger[i].carId
},
include:{
gtWing: true,
lastPlayedPlace: true
},
orderBy: {
carId: 'asc'
},
take: 10
});
carsHistory.push(wm.wm.protobuf.Car.create({
...car!
}))
}
}
let carsStamp: wm.wm.protobuf.StampTargetCar[] = [];
let carsChallenger: wm.wm.protobuf.ChallengerCar[] = [];
// Get all of the friend cars for the carId provided
let stampTargets = await prisma.carStampTarget.findMany({
where: {
stampTargetCarId: body.carId
}
});
if(stampTargets)
{
for(let i=0; i<stampTargets.length; i++)
{
let carTarget = await prisma.car.findFirst({
where:{
carId: stampTargets[i].carId
},
include:{
gtWing: true,
lastPlayedPlace: true
}
})
carsStamp.push(
wm.wm.protobuf.StampTargetCar.create({
car: carTarget!,
returnCount: stampTargets[i].returnCount,
locked: stampTargets[i].locked,
recommended: stampTargets[i].recommended
})
);
}
}
// Get all of the friend cars for the carId provided
let challengers = await prisma.carChallenger.findMany({
where: {
carId: body.carId
}
});
if(challengers)
{
for(let i=0; i<challengers.length; i++)
{
let carTarget = await prisma.car.findFirst({
where:{
carId: challengers[i].challengerCarId
},
include:{
gtWing: true,
lastPlayedPlace: true
}
})
carsChallenger.push(
wm.wm.protobuf.ChallengerCar.create({
car: carTarget!,
stamp: challengers[i].stamp,
result: challengers[i].result,
area: challengers[i].area
})
);
}
}
// ----------------------
// Response data
let msg = {
error: wm.wm.protobuf.ErrorCode.ERR_SUCCESS,
stampSheetCount: 100,
history: cars || null,
stampTargetCars: carsStamp || null,
challengers: carsChallenger || null,
stampSheetCount: car!.stampSheetCount,
stampSheet: car?.stampSheet || null,
stampReturnStats: car?.stampSheet || null,
history: carsHistory || null,
};
// Encode the response
@ -67,18 +156,84 @@ export default class GhostModule extends Module {
})
// Load Stamp Target (Still not working)
// Load Stamp Target
app.post('/method/load_stamp_target', async (req, res) => {
// Get the request body for the load stamp target request
let body = wm.wm.protobuf.LoadStampTargetRequest.encode(req.body);
let body = wm.wm.protobuf.LoadStampTargetRequest.decode(req.body);
// TODO: Actual stamp stuff here
// This is literally just bare-bones
let carsStamp: wm.wm.protobuf.StampTargetCar[] = [];
let carsChallenger: wm.wm.protobuf.ChallengerCar[] = [];
// Get all of the friend cars for the carId provided
let stampTargets = await prisma.carStampTarget.findMany({
where: {
carId: body.carId
}
});
if(stampTargets)
{
for(let i=0; i<stampTargets.length; i++)
{
let carTarget = await prisma.car.findFirst({
where:{
carId: stampTargets[i].stampTargetCarId
},
include:{
gtWing: true,
lastPlayedPlace: true
}
})
carsStamp.push(
wm.wm.protobuf.StampTargetCar.create({
car: carTarget!,
returnCount: stampTargets[i].returnCount,
locked: stampTargets[i].locked,
recommended: stampTargets[i].recommended
})
);
}
}
// Get all of the friend cars for the carId provided
let challengers = await prisma.carChallenger.findMany({
where: {
carId: body.carId
}
});
if(stampTargets)
{
for(let i=0; i<challengers.length; i++)
{
let carTarget = await prisma.car.findFirst({
where:{
carId: challengers[i].challengerCarId
},
include:{
gtWing: true,
lastPlayedPlace: true
}
})
carsChallenger.push(
wm.wm.protobuf.ChallengerCar.create({
car: carTarget!,
stamp: challengers[i].stamp,
result: challengers[i].result,
area: challengers[i].area
})
);
}
}
// Response data
let msg = {
error: wm.wm.protobuf.ErrorCode.ERR_SUCCESS,
cars: carsStamp,
challengers: carsChallenger
};
// Encode the response
@ -89,21 +244,41 @@ export default class GhostModule extends Module {
})
// Ghost Mode - Search ghost car by level
// Ghost Mode
app.post('/method/search_cars_by_level', async (req, res) => {
// Get the request body for the search cars by level request
let body = wm.wm.protobuf.SearchCarsByLevelRequest.decode(req.body);
// Find ghost car by selected level
let car = await prisma.car.findMany({
where: {
ghostLevel: body.ghostLevel
},
include:{
gtWing: true
}
});
let car;
if(body.regionId !== null && body.regionId !== undefined && body.regionId !== 0)
{
// Find ghost car by selected level and region ID
car = await prisma.car.findMany({
where: {
ghostLevel: body.ghostLevel,
regionId: body.regionId
},
include:{
gtWing: true,
lastPlayedPlace: true,
}
});
}
else
{
// Find ghost car by selected level
car = await prisma.car.findMany({
where: {
ghostLevel: body.ghostLevel,
},
include:{
gtWing: true,
lastPlayedPlace: true,
}
});
}
// Randomizing the starting ramp and path based on selected area
let rampVal = 0;
@ -176,17 +351,19 @@ export default class GhostModule extends Module {
let maxNumber = 0;
// If all user car data available is more than 10 for certain level
if(car.length > 10){
if(car.length > 10)
{
maxNumber = 10 // Limit to 10 (game default)
}
// If no more than 10
else{
else
{
maxNumber = car.length;
}
// Choose the user's car data randomly to appear
while(arr.length < maxNumber){
while(arr.length < maxNumber)
{
// Pick random car Id
let randomNumber: number = Math.floor(Math.random() * car.length);
if(arr.indexOf(randomNumber) === -1){
@ -214,14 +391,15 @@ export default class GhostModule extends Module {
}
// Push user's car data without ghost trail
if(!(ghost_trails)){
if(!(ghost_trails))
{
lists_ghostcar.push(wm.wm.protobuf.GhostCar.create({
car: car[randomNumber]
}));
}
// Push user's car data with ghost trail
else{
else
{
// Set the tunePower used when playing certain area
car[randomNumber].tunePower = ghost_trails!.tunePower;
@ -239,6 +417,124 @@ export default class GhostModule extends Module {
}
}
// Check again if car list for that selected region is available of not
if(body.regionId !== null && body.regionId !== undefined && body.regionId !== 0)
{
if(car.length < 1)
{
// Get current date
let date = Math.floor(new Date().getTime() / 1000);
let playedPlace = wm.wm.protobuf.Place.create({
placeId: Config.getConfig().placeId,
regionId: Config.getConfig().regionId,
shopName: Config.getConfig().shopName,
country: Config.getConfig().country
});
let tunePowerDefault = 0
let tuneHandlingDefault = 0;
if(body.ghostLevel === 1)
{
tunePowerDefault = 1;
tuneHandlingDefault = 4;
}
else if(body.ghostLevel === 2)
{
tunePowerDefault = 5;
tuneHandlingDefault = 5;
}
else if(body.ghostLevel === 3)
{
tunePowerDefault = 8;
tuneHandlingDefault = 7;
}
else if(body.ghostLevel === 4)
{
tunePowerDefault = 10;
tuneHandlingDefault = 10;
}
else if(body.ghostLevel === 5)
{
tunePowerDefault = 15;
tuneHandlingDefault = 10;
}
else if(body.ghostLevel === 6)
{
tunePowerDefault = 18;
tuneHandlingDefault = 10;
}
else if(body.ghostLevel === 7)
{
tunePowerDefault = 20;
tuneHandlingDefault = 10;
}
else if(body.ghostLevel === 8)
{
tunePowerDefault = 21;
tuneHandlingDefault = 10;
}
else if(body.ghostLevel === 9)
{
tunePowerDefault = 22;
tuneHandlingDefault = 10;
}
else if(body.ghostLevel === 10)
{
tunePowerDefault = 24;
tuneHandlingDefault = 10;
}
else if(body.ghostLevel === 11)
{
tunePowerDefault = 24;
tuneHandlingDefault = 24;
}
// Generate default S660 car data
car = wm.wm.protobuf.Car.create({
carId: 999999999, // Don't change this
name: '',
regionId: body.regionId, // IDN (福井)
manufacturer: 12, // HONDA
model: 105, // S660 [JW5]
visualModel: 130, // S660 [JW5]
defaultColor: 0,
customColor: 0,
wheel: 20,
wheelColor: 0,
aero: 0,
bonnet: 0,
wing: 0,
mirror: 0,
neon: 0,
trunk: 0,
plate: 0,
plateColor: 0,
plateNumber: 0,
tunePower: tunePowerDefault,
tuneHandling: tuneHandlingDefault,
rivalMarker: 32,
aura: 551,
windowSticker: true,
windowStickerString: '',
windowStickerFont: 0,
title: 'No Ghost for this Region',
level: 65, // SSSSS
lastPlayedAt: date,
country: 'JPN',
lastPlayedPlace: playedPlace
});
// Push data to Ghost car proto
lists_ghostcar.push(wm.wm.protobuf.GhostCar.create({
car: car,
nonhuman: true,
type: wm.wm.protobuf.GhostType.GHOST_DEFAULT,
}));
}
// else{} have car list
}
// Response data
let msg = {
error: wm.wm.protobuf.ErrorCode.ERR_SUCCESS,
@ -269,8 +565,8 @@ export default class GhostModule extends Module {
let lists_ghostcar: wm.wm.protobuf.LoadGhostDriveDataResponse.GhostDriveData[] = [];
// Check how many opponent ghost data available (including user data)
for(let i=0; i<body.carTunings.length; i++){
for(let i=0; i<body.carTunings.length; i++)
{
// Check if opponent ghost have trail
let ghost_trails = await prisma.ghostTrail.findFirst({
where: {
@ -568,7 +864,7 @@ export default class GhostModule extends Module {
carId: body.selectedCars[i],
tunePower: pathAndTuning!.tunePower,
tuneHandling: pathAndTuning!.tuneHandling,
lastPlayedAt: pathAndTuning!.lastPlayedAt
lastPlayedAt: pathAndTuning!.lastPlayedAt,
}));
}
// Opponent ghost doesn't have path and tuning record for certain area
@ -577,7 +873,7 @@ export default class GhostModule extends Module {
// Get user's car last used tunePower and tuneHandling
let car = await prisma.car.findFirst({
where: {
carId: body.carId
carId: body.selectedCars[i]
},
select:{
tunePower: true,
@ -636,37 +932,5 @@ export default class GhostModule extends Module {
// Send the response to the client
common.sendResponse(message, res);
})
/*
app.post('/method/lock_stamp_target', async (req, res) => {
// Response data
let msg = {
error: wmsrv.wm.protobuf.ErrorCode.ERR_SUCCESS,
};
// Encode the response
let message = wmsrv.wm.protobuf.LockStampTargetResponse.encode(msg);
// Send the response to the client
common.sendResponse(message, res);
})
app.get('/resource/ghost_list', async (req, res) => {
// Response data
let msg = {
error: wmsrv.wm.protobuf.ErrorCode.ERR_SUCCESS,
};
// Encode the response
let message = wmsrv.wm.protobuf.GhostList.encode(msg);
// Send the response to the client
common.sendResponse(message, res);
})
*/
}
}

View File

@ -9,8 +9,8 @@ import * as wm from "../wmmt/wm.proto";
// Import Util
import * as common from "../util/common";
import * as ghost_ocm from "../util/games/ghost_ocm";
import * as ghost_ocm_area from "../util/games/games_util/ghost_ocm_area";
import * as ghost_ocm from "../util/ghost/ghost_ocm";
import * as ghost_ocm_area from "../util/ghost/ghost_ocm_area";
export default class GhostModule extends Module {
@ -28,30 +28,12 @@ export default class GhostModule extends Module {
// Get currently active OCM event (query still not complete)
let ocmEventDate = await prisma.oCMEvent.findFirst({
where: {
OR: [
{
// qualifyingPeriodStartAt is less than current date
qualifyingPeriodStartAt: { lte: date },
// qualifyingPeriodCloseAt is greater than current date
qualifyingPeriodCloseAt: { gte: date },
},
{
// competitionStartAt is less than current date
competitionStartAt: { lte: date },
// competitionCloseAt is greater than current date
competitionCloseAt: { gte: date },
},
{
// competitionCloseAt is less than current date
competitionCloseAt: { lte: date },
// competitionEndAt is greater than current date
competitionEndAt: {gte: date },
}
],
},
// qualifyingPeriodStartAt is less than current date
qualifyingPeriodStartAt: { lte: date },
// competitionEndAt is greater than current date
competitionEndAt: { gte: date },
},
orderBy:{
dbId: 'desc'
}
@ -417,36 +399,14 @@ export default class GhostModule extends Module {
// Get currently active OCM event
let ocmEventDate = await prisma.oCMEvent.findFirst({
where: {
OR: [
{
competitionId: competition_id,
// qualifyingPeriodStartAt is less than current date
qualifyingPeriodStartAt: { lte: date },
// qualifyingPeriodCloseAt is greater than current date
qualifyingPeriodCloseAt: { gte: date },
},
{
competitionId: competition_id,
// competitionStartAt is less than current date
competitionStartAt: { lte: date },
// competitionCloseAt is greater than current date
competitionCloseAt: { gte: date },
},
{
competitionId: competition_id,
// competitionCloseAt is less than current date
competitionCloseAt: { lte: date },
// competitionEndAt is greater than current date
competitionEndAt: {gte: date },
}
],
},
competitionId: competition_id,
// qualifyingPeriodStartAt is less than current date
qualifyingPeriodStartAt: { lte: date },
// competitionEndAt is greater than current date
competitionEndAt: { gte: date },
},
orderBy:{
dbId: 'desc'
}
@ -471,10 +431,10 @@ export default class GhostModule extends Module {
let ghostTypes;
let cars: wm.wm.protobuf.ICar | (Car & { gtWing: CarGTWing; }) | null;
let playedPlace = wm.wm.protobuf.Place.create({
placeId: 'JPN0123',
shopName: Config.getConfig().shopName,
regionId: 18,
country: 'JPN'
placeId: Config.getConfig().placeId,
regionId: Config.getConfig().regionId,
shopName: Config.getConfig().shopName,
country: Config.getConfig().country
});
// Get default trail id
@ -520,7 +480,8 @@ export default class GhostModule extends Module {
carId: checkGhostTrail!.carId
},
include:{
gtWing: true
gtWing: true,
lastPlayedPlace: true
}
});
@ -594,7 +555,8 @@ export default class GhostModule extends Module {
title: 'Don\'t have S660?',
level: 65, // SSSSS
lastPlayedAt: checkGhostTrail!.playedAt,
country: 'GLB'
country: 'IDN',
lastPlayedPlace: playedPlace
});
// Set Ghost stuff Value
@ -603,7 +565,8 @@ export default class GhostModule extends Module {
}
else if(ocmEventDate!.competitionCloseAt < date && ocmEventDate!.competitionEndAt > date)
{
// TODO: IDK
// TODO: Actual stuff here
// This is literally just bare-bones so the shit boots
}
else
{
@ -644,7 +607,8 @@ export default class GhostModule extends Module {
carId: checkGhostTrail!.carId
},
include:{
gtWing: true
gtWing: true,
lastPlayedPlace: true
}
});
@ -670,10 +634,7 @@ export default class GhostModule extends Module {
// Push the Top 1 OCM ghost car data
ghostCars = wm.wm.protobuf.GhostCar.create({
car: {
...cars!,
lastPlayedPlace: playedPlace
},
car: cars!,
area: areaVal,
ramp: rampVal,
path: pathVal,

495
src/modules/resource.ts Normal file
View File

@ -0,0 +1,495 @@
import { Application } from "express";
import {Module} from "module";
import { Config } from "../config";
import { prisma } from "..";
// Import Proto
import * as wm from "../wmmt/wm.proto";
import * as wmsrv from "../wmmt/service.proto";
// Import Util
import * as common from "../util/common";
export default class ResourceModule extends Module {
register(app: Application): void {
// Place List
app.get('/resource/place_list', async (req, res) => {
console.log('place list');
// Empty list of place records
let places: wm.wm.protobuf.Place[] = [];
// Response data
places.push(new wm.wm.protobuf.Place({
placeId: Config.getConfig().placeId,
regionId: Config.getConfig().regionId,
shopName: Config.getConfig().shopName,
country: Config.getConfig().country
}));
let checkPlaceList = await prisma.placeList.findFirst({
where:{
placeId: Config.getConfig().placeId,
}
})
if(!(checkPlaceList))
{
console.log('Creating new Place List entry')
await prisma.placeList.create({
data:{
placeId: Config.getConfig().placeId,
regionId: Number(Config.getConfig().regionId),
shopName: Config.getConfig().shopName,
country: Config.getConfig().country
}
})
}
// Encode the response
let message = wm.wm.protobuf.PlaceList.encode({places});
// Send the response to the client
common.sendResponse(message, res);
})
// Get Ranking data for attract screen (TA, Ghost, VS)
app.get('/resource/ranking', async (req, res) => {
console.log('ranking');
// Empty list of all ranking records (Combination of TA, VS Stars, and Ghost Battle Win)
let lists: wmsrv.wm.protobuf.Ranking.List[] = [];
// Get TA Ranking
for(let i=0; i<25; i++){ // GID_TACOURSE ID
// Get the TA time per course
let ta_time = await prisma.timeAttackRecord.findMany({
where: {
course: i
},
orderBy: {
time: 'asc'
},
take: 10, // Take top 10
});
// TA time record by user is available for certain course
if(ta_time.length > 0){
// Empty list of ranking records for user time attack
let list_ta: wmsrv.wm.protobuf.Ranking.Entry[] = [];
// Get the TA time data
for(let j=0; j<ta_time.length; j++){
// Get the car data
let car_ta = await prisma.car.findFirst({
where: {
carId: ta_time[j].carId
}
});
// Push the data to the ranking data
list_ta.push(wmsrv.wm.protobuf.Ranking.Entry.create({
carId: ta_time[j].carId,
rank: car_ta!.level,
result: ta_time[j].time,
name: car_ta!.name,
regionId: car_ta!.regionId,
model: car_ta!.model,
visualModel: car_ta!.visualModel,
defaultColor: car_ta!.defaultColor,
tunePower: ta_time[j].tunePower, // Set the tunePower used when playing TA
tuneHandling: ta_time[j].tuneHandling, // Set the tuneHandling used when playing TA
title: car_ta!.title,
level: car_ta!.level
}));
}
// If the TA time record by user is less than 10 user
if(ta_time.length < 11){
// Take the remaining unfilled
for(let j=ta_time.length; j<11; j++){
let resultTime = 599999; // 9:59:999 time
// GID_TACOURSE_TOKYOALL & GID_TACOURSE_KANAGAWAALL area
if(i === 22 || i === 23){
resultTime = 1199999; // 19:59:999 time
}
// Push the data to the ranking data
list_ta.push(wmsrv.wm.protobuf.Ranking.Entry.create({
carId: 0,
rank: 0,
result: resultTime,
name: '',
regionId: 1, // Hokkaido
model: Math.floor(Math.random() * 50), // Randomizing Car data
visualModel: Math.floor(Math.random() * 100), // Randomizing Car data
defaultColor: 0,
tunePower: 0,
tuneHandling: 0,
title: 'Wangan Beginner', // 湾岸の新人
level: 0 // N
}));
}
}
lists.push(new wmsrv.wm.protobuf.Ranking.List({
rankingType: i, // RANKING_TA_*AREA*
topRecords: list_ta
}));
}
// There is no user's TA record for certain area
else{
// Empty list of ranking records for time attack
let list_ta: wmsrv.wm.protobuf.Ranking.Entry[] = [];
// Generate the top 10 TA time data
for(let j=0; j<11; j++){
let resulttime = 599999; // 9:59:999 time
// GID_TACOURSE_TOKYOALL & GID_TACOURSE_KANAGAWAALL area
if(i === 22 || i === 23){
resulttime = 1199999 // 19:59:999 time
}
// Push the data to the ranking data
list_ta.push(wmsrv.wm.protobuf.Ranking.Entry.create({
carId: 0,
rank: 0,
result: resulttime,
name: '',
regionId: 1, // Hokkaido
model: Math.floor(Math.random() * 50), // Randomizing Car data
visualModel: Math.floor(Math.random() * 100), // Randomizing Car data
defaultColor: 0,
tunePower: 0,
tuneHandling: 0,
title: 'Wangan Beginner', // 湾岸の新人
level: 0 // N
}));
}
// Push the certain area ranking data to the list
lists.push(new wmsrv.wm.protobuf.Ranking.List({
rankingType: i, // RANKING_TA_*AREA*
topRecords: list_ta // Top 10 TA time record data
}));
}
}
// Get VS Star Ranking
// Get the user's VS Stars data
let car_vs = await prisma.car.findMany({
orderBy: {
vsStarCount: 'desc'
},
take: 20, // Take top 20
});
// Empty list of ranking records for VS Stars
let list_vs: wmsrv.wm.protobuf.Ranking.Entry[] = [];
// Get the VS stars data
for(let i=0; i<car_vs.length; i++){
// Push the car data to the ranking data
list_vs.push(wmsrv.wm.protobuf.Ranking.Entry.create({
carId: car_vs[i].carId,
rank: car_vs[i].level,
result: car_vs[i].vsStarCount,
name: car_vs[i].name,
regionId: car_vs[i].regionId,
model: car_vs[i].model,
visualModel: car_vs[i].visualModel,
defaultColor: car_vs[i].defaultColor,
tunePower: car_vs[i].tunePower,
tuneHandling: car_vs[i].tuneHandling,
title: car_vs[i].title,
level: car_vs[i].level
}));
}
// If the VS stars record by user is less than 20 user
if(car_vs.length < 20){
// Take the remaining unfilled
for(let j=car_vs.length; j<21; j++){
// Push the data to the ranking data
list_vs.push(wmsrv.wm.protobuf.Ranking.Entry.create({
carId: 0,
rank: 0,
result: 0,
name: '',
regionId: 1, // Hokkaido
model: Math.floor(Math.random() * 50), // Randomizing Car data
visualModel: Math.floor(Math.random() * 100), // Randomizing Car data
defaultColor: 0,
tunePower: 0,
tuneHandling: 0,
title: 'Wangan Beginner', // 湾岸の新人
level: 0 // N
}));
}
}
// Push the data
lists.push(new wmsrv.wm.protobuf.Ranking.List({
rankingType: 100, // RANKING_VS_STAR
topRecords: list_vs // Top 20 VS stars record data
}));
// Get Ghost Defeated Ranking
// Get the user's Ghost Win data
let car_ghost = await prisma.car.findMany({
orderBy: {
rgWinCount: 'desc'
},
take: 20, // Take top 20
});
// Empty list of ranking records for Ghost Battle Win
let list_ghost: wmsrv.wm.protobuf.Ranking.Entry[] = [];
// Get the Ghost Battle Win data
for(let i=0; i<car_ghost.length; i++){
// Push the car data to the ranking data
list_ghost.push(wmsrv.wm.protobuf.Ranking.Entry.create({
carId: car_ghost[i].carId,
rank: car_ghost[i].level,
result: car_ghost[i].rgWinCount,
name: car_ghost[i].name,
regionId: car_ghost[i].regionId,
model: car_ghost[i].model,
visualModel: car_ghost[i].visualModel,
defaultColor: car_ghost[i].defaultColor,
tunePower: car_ghost[i].tunePower,
tuneHandling: car_ghost[i].tuneHandling,
title: car_ghost[i].title,
level: car_ghost[i].level
}));
}
// If the Ghost Win record by user is less than 20 user
if(car_ghost.length < 20){
// Take the remaining unfilled
for(let j=car_ghost.length; j<21; j++){
// Push the data to the ranking data
list_ghost.push(wmsrv.wm.protobuf.Ranking.Entry.create({
carId: 0,
rank: 0,
result: 0,
name: '',
regionId: 1, // Hokkaido
model: Math.floor(Math.random() * 50), // Randomizing Car data
visualModel: Math.floor(Math.random() * 100), // Randomizing Car data
defaultColor: 0,
tunePower: 0,
tuneHandling: 0,
title: 'Wangan Beginner', // 湾岸の新人
level: 0 // N
}));
}
}
// Push the data
lists.push(new wmsrv.wm.protobuf.Ranking.List({
rankingType: 101, // RANKING_GHOST_DEFEATED_COUNT
topRecords: list_ghost // Top 20 Ghost Win record data
}));
// Encode the response
let message = wmsrv.wm.protobuf.Ranking.encode({lists});
// Send the response to the client
common.sendResponse(message, res);
})
// Crown List for attract screen and Crown Ghost Battle mode
app.get('/resource/crown_list', async (req, res) => {
console.log('crown_list');
// Empty list of crown records
let list_crown: wmsrv.wm.protobuf.Crown[] = [];
// Get the crown holder data
let car_crown = await prisma.carCrown.findMany({
orderBy: {
area: 'asc'
}
});
// Crown holder data available
if(car_crown.length !== 0)
{
let counter = 0;
// Loop GID_RUNAREA
for(let i=0; i<19; i++)
{
// 14 - 16 are dummy area, 17 is C1 Closed
if(i >= 14)
{
i = 18; // GID_RUNAREA_HIROSHIMA
}
// Crown holder for certain area available
if(car_crown[counter].area === i){
// Get user's data
let car = await prisma.car.findFirst({
where: {
carId: car_crown[counter].carId
},
include: {
gtWing: true,
lastPlayedPlace: true
}
});
// If regionId is 0 or not set, game will crash after defeating the ghost
if(car!.regionId === 0)
{
car!.regionId = i + 1; // Change car region id
}
// Set the tunePower and tuneHandling used when capturing ghost crown
car!.tunePower = car_crown[counter].tunePower;
car!.tuneHandling = car_crown[counter].tuneHandling;
// Error handling if played At timestamp value is current date and timestamp is bigger than 9 July 2022 (using GMT+7 timestamp)
if(car_crown[counter].playedAt !== 0 && car_crown[counter].playedAt >= 1657299600)
{
// Acquired crown timestamp - 1 day
car!.lastPlayedAt = car_crown[counter].playedAt - 172800;
// Acquired crown timestamp - 1 day
car_crown[counter].playedAt = car_crown[counter].playedAt - 172800;
}
// Error handling if played At timestamp value is 0 or timestamp is less than 9 July 2022 (using GMT+7 timestamp)
else if(car_crown[counter].playedAt === 0 || car_crown[counter].playedAt < 1657299600)
{
// Acquired crown timestamp become 9 July 2022 (using GMT+7 timestamp)
car!.lastPlayedAt = 1657299600;
// Acquired crown timestamp become 9 July 2022 (using GMT+7 timestamp)
car_crown[counter].playedAt = 1657299600;
}
// Push the car data to the crown holder data
list_crown.push(wmsrv.wm.protobuf.Crown.create({
carId: car_crown[counter].carId,
area: car_crown[counter].area, // GID_RUNAREA_C1 - GID_RUNAREA_TURNPIKE & GID_RUNAREA_HIROSHIMA
unlockAt: car_crown[counter].playedAt,
car: car!
}));
if(counter < car_crown.length-1){
counter++;
}
}
// Crown holder for certain area not available
else{
// Push the default data by the game to the crown holder data
list_crown.push(wmsrv.wm.protobuf.Crown.create({
carId: i,
area: i, // GID_RUNAREA_C1 - GID_RUNAREA_TURNPIKE & GID_RUNAREA_HIROSHIMA
unlockAt: 0,
}));
}
}
}
// There is no user's crown holder data available
else{
// Loop GID_RUNAREA
for(let i=0; i<19; i++)
{
// 14 - 16 are dummy area, 17 is C1 Closed
if(i >= 14)
{
i = 18; // GID_RUNAREA_HIROSHIMA
}
// Push the default data by the game to the crown holder data
list_crown.push(wmsrv.wm.protobuf.Crown.create({
carId: i,
area: i, // GID_RUNAREA_C1 - GID_RUNAREA_TURNPIKE & GID_RUNAREA_HIROSHIMA
unlockAt: 0,
}));
}
}
// Response data
let msg = {
crowns: list_crown
};
// Encode the response
let message = wmsrv.wm.protobuf.CrownList.encode(msg);
// Send the response to the client
common.sendResponse(message, res);
})
app.get('/resource/file_list', async (req, res) => {
console.log('file_list');
// 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,
files: null,
interval: null
}
// Encode the response
let message = wm.wm.protobuf.FileList.encode(msg);
// Send the response to the client
common.sendResponse(message, res);
})
app.get('/resource/ghost_list', async (req, res) => {
console.log('ghost_list');
// TODO: Actual stuff here
// This is literally just bare-bones so the shit boots
// Response data
let msg = {
error: wmsrv.wm.protobuf.ErrorCode.ERR_SUCCESS,
ghosts: null
};
// Encode the response
let message = wmsrv.wm.protobuf.GhostList.encode(msg);
// Send the response to the client
common.sendResponse(message, res);
})
}
}

View File

@ -1,11 +1,9 @@
import { Application } from "express";
import {Module} from "module";
import { Config } from "../config";
import { prisma } from "..";
// Import Proto
import * as wm from "../wmmt/wm.proto";
import * as wmsrv from "../wmmt/service.proto";
// Import Util
import * as common from "../util/common";
@ -26,30 +24,12 @@ export default class StartupModule extends Module {
// Get current / previous active OCM Event
let ocmEventDate = await prisma.oCMEvent.findFirst({
where: {
OR: [
{
// qualifyingPeriodStartAt is less than current date
qualifyingPeriodStartAt: { lte: date },
// qualifyingPeriodCloseAt is greater than current date
qualifyingPeriodCloseAt: { gte: date },
},
{
// competitionStartAt is less than current date
competitionStartAt: { lte: date },
// competitionCloseAt is greater than current date
competitionCloseAt: { gte: date },
},
{
// competitionCloseAt is less than current date
competitionCloseAt: { lte: date },
// competitionEndAt is greater than current date
competitionEndAt: {gte: date },
}
],
},
// qualifyingPeriodStartAt is less than current date
qualifyingPeriodStartAt: { lte: date },
// competitionEndAt is greater than current date
competitionEndAt: { gte: date },
},
orderBy: [
{
dbId: 'desc'
@ -154,295 +134,31 @@ export default class StartupModule extends Module {
})
// Place List
app.get('/resource/place_list', (req, res) => {
console.log('place list');
// Update Event Mode Serial
app.post('/method/update_user_session', (req, res) => {
// Empty list of place records
let places: wm.wm.protobuf.Place[] = [];
let body = wm.wm.protobuf.UpdateUserSessionRequest.decode(req.body);
// TODO: Actual stuff here
// This is literally just bare-bones so the shit boots
// Response data
places.push(new wm.wm.protobuf.Place({
placeId: "JPN0123",
regionId: 1,
shopName: Config.getConfig().shopName,
country: "JPN"
}));
let msg = {
error: wm.wm.protobuf.ErrorCode.ERR_SUCCESS,
}
// Encode the response
let message = wm.wm.protobuf.PlaceList.encode({places});
// Send the response to the client
common.sendResponse(message, res);
})
// Get Ranking data for attract screen (TA, Ghost, VS)
app.get('/resource/ranking', async (req, res) => {
console.log('ranking');
// Generate the response message
let message = wm.wm.protobuf.UpdateUserSessionResponse.encode(msg);
// Empty list of all ranking records (Combination of TA, VS Stars, and Ghost Battle Win)
let lists: wmsrv.wm.protobuf.Ranking.List[] = [];
// Get TA Ranking
for(let i=0; i<25; i++){ // GID_TACOURSE ID
// Get the TA time per course
let ta_time = await prisma.timeAttackRecord.findMany({
where: {
course: i
},
orderBy: {
time: 'asc'
},
take: 10, // Take top 10
});
// TA time record by user is available for certain course
if(ta_time.length > 0){
// Empty list of ranking records for user time attack
let list_ta: wmsrv.wm.protobuf.Ranking.Entry[] = [];
// Get the TA time data
for(let j=0; j<ta_time.length; j++){
// Get the car data
let car_ta = await prisma.car.findFirst({
where: {
carId: ta_time[j].carId
}
});
// Push the data to the ranking data
list_ta.push(wmsrv.wm.protobuf.Ranking.Entry.create({
carId: ta_time[j].carId,
rank: car_ta!.level,
result: ta_time[j].time,
name: car_ta!.name,
regionId: car_ta!.regionId,
model: car_ta!.model,
visualModel: car_ta!.visualModel,
defaultColor: car_ta!.defaultColor,
tunePower: ta_time[j].tunePower, // Set the tunePower used when playing TA
tuneHandling: ta_time[j].tuneHandling, // Set the tuneHandling used when playing TA
title: car_ta!.title,
level: car_ta!.level
}));
}
// If the TA time record by user is less than 10 user
if(ta_time.length < 11){
// Take the remaining unfilled
for(let j=ta_time.length; j<11; j++){
let resultTime = 599999; // 9:59:999 time
// GID_TACOURSE_TOKYOALL & GID_TACOURSE_KANAGAWAALL area
if(i === 22 || i === 23){
resultTime = 1199999; // 19:59:999 time
}
// Push the data to the ranking data
list_ta.push(wmsrv.wm.protobuf.Ranking.Entry.create({
carId: 0,
rank: 0,
result: resultTime,
name: '',
regionId: 1, // Hokkaido
model: Math.floor(Math.random() * 50), // Randomizing Car data
visualModel: Math.floor(Math.random() * 100), // Randomizing Car data
defaultColor: 0,
tunePower: 0,
tuneHandling: 0,
title: 'Wangan Beginner', // 湾岸の新人
level: 0 // N
}));
}
}
lists.push(new wmsrv.wm.protobuf.Ranking.List({
rankingType: i, // RANKING_TA_*AREA*
topRecords: list_ta
}));
}
// There is no user's TA record for certain area
else{
// Empty list of ranking records for time attack
let list_ta: wmsrv.wm.protobuf.Ranking.Entry[] = [];
// Generate the top 10 TA time data
for(let j=0; j<11; j++){
let resulttime = 599999; // 9:59:999 time
// GID_TACOURSE_TOKYOALL & GID_TACOURSE_KANAGAWAALL area
if(i === 22 || i === 23){
resulttime = 1199999 // 19:59:999 time
}
// Push the data to the ranking data
list_ta.push(wmsrv.wm.protobuf.Ranking.Entry.create({
carId: 0,
rank: 0,
result: resulttime,
name: '',
regionId: 1, // Hokkaido
model: Math.floor(Math.random() * 50), // Randomizing Car data
visualModel: Math.floor(Math.random() * 100), // Randomizing Car data
defaultColor: 0,
tunePower: 0,
tuneHandling: 0,
title: 'Wangan Beginner', // 湾岸の新人
level: 0 // N
}));
}
// Push the certain area ranking data to the list
lists.push(new wmsrv.wm.protobuf.Ranking.List({
rankingType: i, // RANKING_TA_*AREA*
topRecords: list_ta // Top 10 TA time record data
}));
}
}
// Get VS Star Ranking
// Get the user's VS Stars data
let car_vs = await prisma.car.findMany({
orderBy: {
vsStarCount: 'desc'
},
take: 20, // Take top 20
});
// Empty list of ranking records for VS Stars
let list_vs: wmsrv.wm.protobuf.Ranking.Entry[] = [];
// Get the VS stars data
for(let i=0; i<car_vs.length; i++){
// Push the car data to the ranking data
list_vs.push(wmsrv.wm.protobuf.Ranking.Entry.create({
carId: car_vs[i].carId,
rank: car_vs[i].level,
result: car_vs[i].vsStarCount,
name: car_vs[i].name,
regionId: car_vs[i].regionId,
model: car_vs[i].model,
visualModel: car_vs[i].visualModel,
defaultColor: car_vs[i].defaultColor,
tunePower: car_vs[i].tunePower,
tuneHandling: car_vs[i].tuneHandling,
title: car_vs[i].title,
level: car_vs[i].level
}));
}
// If the VS stars record by user is less than 20 user
if(car_vs.length < 20){
// Take the remaining unfilled
for(let j=car_vs.length; j<21; j++){
// Push the data to the ranking data
list_vs.push(wmsrv.wm.protobuf.Ranking.Entry.create({
carId: 0,
rank: 0,
result: 0,
name: '',
regionId: 1, // Hokkaido
model: Math.floor(Math.random() * 50), // Randomizing Car data
visualModel: Math.floor(Math.random() * 100), // Randomizing Car data
defaultColor: 0,
tunePower: 0,
tuneHandling: 0,
title: 'Wangan Beginner', // 湾岸の新人
level: 0 // N
}));
}
}
// Push the data
lists.push(new wmsrv.wm.protobuf.Ranking.List({
rankingType: 100, // RANKING_VS_STAR
topRecords: list_vs // Top 20 VS stars record data
}));
// Get Ghost Defeated Ranking
// Get the user's Ghost Win data
let car_ghost = await prisma.car.findMany({
orderBy: {
rgWinCount: 'desc'
},
take: 20, // Take top 20
});
// Empty list of ranking records for Ghost Battle Win
let list_ghost: wmsrv.wm.protobuf.Ranking.Entry[] = [];
// Get the Ghost Battle Win data
for(let i=0; i<car_ghost.length; i++){
// Push the car data to the ranking data
list_ghost.push(wmsrv.wm.protobuf.Ranking.Entry.create({
carId: car_ghost[i].carId,
rank: car_ghost[i].level,
result: car_ghost[i].rgWinCount,
name: car_ghost[i].name,
regionId: car_ghost[i].regionId,
model: car_ghost[i].model,
visualModel: car_ghost[i].visualModel,
defaultColor: car_ghost[i].defaultColor,
tunePower: car_ghost[i].tunePower,
tuneHandling: car_ghost[i].tuneHandling,
title: car_ghost[i].title,
level: car_ghost[i].level
}));
}
// If the Ghost Win record by user is less than 20 user
if(car_ghost.length < 20){
// Take the remaining unfilled
for(let j=car_ghost.length; j<21; j++){
// Push the data to the ranking data
list_ghost.push(wmsrv.wm.protobuf.Ranking.Entry.create({
carId: 0,
rank: 0,
result: 0,
name: '',
regionId: 1, // Hokkaido
model: Math.floor(Math.random() * 50), // Randomizing Car data
visualModel: Math.floor(Math.random() * 100), // Randomizing Car data
defaultColor: 0,
tunePower: 0,
tuneHandling: 0,
title: 'Wangan Beginner', // 湾岸の新人
level: 0 // N
}));
}
}
// Push the data
lists.push(new wmsrv.wm.protobuf.Ranking.List({
rankingType: 101, // RANKING_GHOST_DEFEATED_COUNT
topRecords: list_ghost // Top 20 Ghost Win record data
}));
// Encode the response
let message = wmsrv.wm.protobuf.Ranking.encode({lists});
// Send the response to the client
common.sendResponse(message, res);
})
});
// Ping
app.post('/method/ping', (req, res) => {
console.log('ping');
let body = wm.wm.protobuf.PingRequest.decode(req.body);
// Response data
@ -458,163 +174,14 @@ export default class StartupModule extends Module {
common.sendResponse(message, res);
})
// Crown List for attract screen and Crown Ghost Battle mode
app.get('/resource/crown_list', async (req, res) => {
console.log('crown_list');
// Empty list of crown records
let list_crown: wmsrv.wm.protobuf.Crown[] = [];
// Get the crown holder data
let car_crown = await prisma.carCrown.findMany({
orderBy: {
area: 'asc'
}
});
// Crown holder data available
if(car_crown.length !== 0){
let counter = 0;
// Loop GID_RUNAREA
for(let i=0; i<19; i++){
// 14 - 16 are dummy area, 17 is C1 Closed
if(i >= 14){
i = 18; // GID_RUNAREA_HIROSHIMA
}
// Crown holder for certain area available
if(car_crown[counter].area === i){
// Get user's data
let car = await prisma.car.findFirst({
where: {
carId: car_crown[counter].carId
},
include: {
gtWing: true
}
});
// If regionId is 0 or not set, game will crash after defeating the ghost
if(car!.regionId === 0)
{
/* Region Id
01 = Hokkaido
02 = Aomori
03 = Iwate
04 = Miyagi
05 = Akita
06 = Yamagata
07 = Fukushima
08 = Ibaraki
09 = Tochigi
10 = Gunma
11 = Saitama
12 = Chiba
13 = Tokyo
19 = Yamanashi
*/
car!.regionId = i + 1; // Change car region id
}
// Set the tunePower used when capturing ghost crown
car!.tunePower = car_crown[counter].tunePower;
// Set the tunePower used when capturing ghost crown
car!.tuneHandling = car_crown[counter].tuneHandling;
// Error handling if played At timestamp value is current date and timestamp is bigger than 9 July 2022 (using GMT+7 timestamp)
if(car_crown[counter].playedAt !== 0 && car_crown[counter].playedAt >= 1657299600)
{
// Acquired crown timestamp - 1 day
car!.lastPlayedAt = car_crown[counter].playedAt - 172800;
// Acquired crown timestamp - 1 day
car_crown[counter].playedAt = car_crown[counter].playedAt - 172800;
}
// Error handling if played At timestamp value is 0 or timestamp is less than 9 July 2022 (using GMT+7 timestamp)
else if(car_crown[counter].playedAt === 0 || car_crown[counter].playedAt < 1657299600)
{
// Acquired crown timestamp become 9 July 2022 (using GMT+7 timestamp)
car!.lastPlayedAt = 1657299600;
// Acquired crown timestamp become 9 July 2022 (using GMT+7 timestamp)
car_crown[counter].playedAt = 1657299600;
}
let playedPlace = wm.wm.protobuf.Place.create({
placeId: 'JPN0123',
shopName: Config.getConfig().shopName,
regionId: 18,
country: 'JPN'
});
// Push the car data to the crown holder data
list_crown.push(wmsrv.wm.protobuf.Crown.create({
carId: car_crown[counter].carId,
area: car_crown[counter].area, // GID_RUNAREA_C1 - GID_RUNAREA_TURNPIKE & GID_RUNAREA_HIROSHIMA
unlockAt: car_crown[counter].playedAt,
car: {
...car!,
lastPlayedPlace: playedPlace
}
}));
if(counter < car_crown.length-1){
counter++;
}
}
// Crown holder for certain area not available
else{
// Push the default data by the game to the crown holder data
list_crown.push(wmsrv.wm.protobuf.Crown.create({
carId: i,
area: i, // GID_RUNAREA_C1 - GID_RUNAREA_TURNPIKE & GID_RUNAREA_HIROSHIMA
unlockAt: 0,
}));
}
}
}
// There is no user's crown holder data available
else{
// Loop GID_RUNAREA
for(let i=0; i<19; i++){
// 14 - 16 are dummy area, 17 is C1 Closed
if(i >= 14){
i = 18; // GID_RUNAREA_HIROSHIMA
}
// Push the default data by the game to the crown holder data
list_crown.push(wmsrv.wm.protobuf.Crown.create({
carId: i,
area: i, // GID_RUNAREA_C1 - GID_RUNAREA_TURNPIKE & GID_RUNAREA_HIROSHIMA
unlockAt: 0,
}));
}
}
// Response data
let msg = {
crowns: list_crown
};
// Encode the response
let message = wmsrv.wm.protobuf.CrownList.encode(msg);
// Send the response to the client
common.sendResponse(message, res);
})
/*
app.post('/method/register_system_stats', async (req, res) => {
let body = wm.wm.protobuf.RegisterSystemStatsRequest.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,
@ -630,9 +197,15 @@ export default class StartupModule extends Module {
app.post('/method/update_event_mode_serial', async (req, res) => {
let body = wm.wm.protobuf.UpdateEventModeSerialRequest.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,
serialError: wm.wm.protobuf.EventModeSerialErrorCode.SERIAL_NO_INPUT
}
// Encode the response
@ -642,8 +215,14 @@ export default class StartupModule extends Module {
common.sendResponse(message, res);
})
app.post('/method/submit_client_log', async (req, res) => {
let body = wm.wm.protobuf.SubmitClientLogRequest.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,
@ -655,20 +234,5 @@ export default class StartupModule extends Module {
// Send the response to the client
common.sendResponse(message, res);
})
app.get('/resource/file_list', async (req, res) => {
// Response data
let msg = {
error: wm.wm.protobuf.ErrorCode.ERR_SUCCESS,
}
// Encode the response
let message = wm.wm.protobuf.FileList.encode(msg);
// Send the response to the client
common.sendResponse(message, res);
})
*/
}
}

View File

@ -121,6 +121,10 @@ export default class TerminalModule extends Module {
let car = await prisma.car.findFirst({
where: {
carId: carId
},
include:{
gtWing: true,
lastPlayedPlace: true
}
});
@ -185,16 +189,47 @@ export default class TerminalModule extends Module {
// Get the query from the request
let query = req.query;
// Check the query limit
let queryLimit = 10
if(query.limit)
{
queryLimit = Number(query.limit);
}
// Check the last played place id
let queryLastPlayedPlaceId = 1;
if(query.limit)
{
let getLastPlayedPlaceId = await prisma.placeList.findFirst({
where:{
placeId: String(query.last_played_place_id)
}
})
if(getLastPlayedPlaceId)
{
queryLastPlayedPlaceId = getLastPlayedPlaceId.id
}
}
// Get all of the cars matching the query
let cars = await prisma.car.findMany({
take: Number(query.limit),
take: queryLimit,
where: {
name: {
startsWith: String(query.name)
}
OR:[
{
name: {
startsWith: String(query.name)
}
},
{
lastPlayedPlaceId: queryLastPlayedPlaceId
}
]
},
include:{
gtWing: true
gtWing: true,
lastPlayedPlace: true
}
});
@ -532,36 +567,12 @@ export default class TerminalModule extends Module {
// Get current active OCM Event
let ocmEventDate = await prisma.oCMEvent.findFirst({
where: {
OR: [
{
competitionId: body.competitionId,
// qualifyingPeriodStartAt is less than current date
qualifyingPeriodStartAt: { lte: date },
// qualifyingPeriodCloseAt is greater than current date
qualifyingPeriodCloseAt: { gte: date },
},
{
competitionId: body.competitionId,
// competitionStartAt is less than current date
competitionStartAt: { lte: date },
// competitionCloseAt is greater than current date
competitionCloseAt: { gte: date },
},
{
competitionId: body.competitionId,
// competitionCloseAt is less than current date
competitionCloseAt: { lte: date },
// competitionEndAt is greater than current date
competitionEndAt: {gte: date },
}
],
},
// qualifyingPeriodStartAt is less than current date
qualifyingPeriodStartAt: { lte: date },
// competitionEndAt is greater than current date
competitionEndAt: { gte: date },
},
orderBy:{
dbId: 'desc'
}
@ -669,6 +680,10 @@ export default class TerminalModule extends Module {
let cars = await prisma.car.findFirst({
where:{
carId: ocmParticipant[i].carId
},
include:{
gtWing: true,
lastPlayedPlace: true
}
});
@ -745,6 +760,10 @@ export default class TerminalModule extends Module {
let cars = await prisma.car.findFirst({
where:{
carId: ocmParticipant[i].carId
},
include:{
gtWing: true,
lastPlayedPlace: true
}
})
@ -815,6 +834,10 @@ export default class TerminalModule extends Module {
let cars = await prisma.car.findFirst({
where:{
carId: ocmParticipant[i].carId
},
include:{
gtWing: true,
lastPlayedPlace: true
}
});

View File

@ -30,15 +30,18 @@ export default class UserModule extends Module {
cars: {
include: {
state: true,
gtWing: true
gtWing: true,
lastPlayedPlace: true
}
}
}
});
// No user returned
if (!user) {
if (!user)
{
console.log('no such user');
let msg = {
error: wm.wm.protobuf.ErrorCode.ERR_SUCCESS,
numOfOwnedCars: 0,
@ -46,75 +49,86 @@ export default class UserModule extends Module {
spappState: wm.wm.protobuf.SmartphoneAppState.SPAPP_UNREGISTERED,
transferState: wm.wm.protobuf.TransferState.NOT_REGISTERED,
};
if (!body.cardChipId || !body.accessCode) {
if (!body.cardChipId || !body.accessCode)
{
let msg = {
error: wm.wm.protobuf.ErrorCode.ERR_ID_BANNED,
numOfOwnedCars: 0,
spappState: wm.wm.protobuf.SmartphoneAppState.SPAPP_UNREGISTERED,
transferState: wm.wm.protobuf.TransferState.NOT_REGISTERED
}
let resp = wm.wm.protobuf.LoadUserResponse.encode(msg);
let end = resp.finish();
let r = res
.header('Server', 'v388 wangan')
.header('Content-Type', 'application/x-protobuf; revision=8053')
.header('Content-Length', end.length.toString())
.status(200);
r.send(Buffer.from(end));
// Encode the response
let message = wm.wm.protobuf.LoadUserResponse.encode(msg);
// Send the response to the client
common.sendResponse(message, res);
return;
}
let user = await prisma.user.create({
data: {
chipId: body.cardChipId,
accessCode: body.accessCode,
tutorials: [
false, //TUTORIAL_ID_STORY
false, //TUTORIAL_ID_TIME_ATTACK
false, //TUTORIAL_ID_GHOST
false, //TUTORIAL_ID_GHOST_CHALLENGE
false, //TUTORIAL_ID_GHOST_LEVEL
false, //TUTORIAL_ID_UNUSED_5
false, //TUTORIAL_ID_GHOST_SEARCH
false, //TUTORIAL_ID_GHOST_COMPETITION
false, //TUTORIAL_ID_HP600_CARD
false, //TUTORIAL_ID_UNUSED_9
false, //TUTORIAL_ID_COMPETITION_QUALIFIED
false, //TUTORIAL_ID_COMPETITION_TERMINAL
false, //TUTORIAL_ID_COMPETITION_NOTICE
false, //TUTORIAL_ID_COMPETITION_FINISHED
false, //TUTORIAL_ID_UNUSED_14
false, //TUTORIAL_ID_UNUSED_15
false, //TUTORIAL_ID_UNUSED_16
false, //TUTORIAL_ID_UNUSED_17
false, //TUTORIAL_ID_UNUSED_18
false, //TUTORIAL_ID_UNUSED_19
false, //TUTORIAL_ID_GHOST_STAMP
false, //TUTORIAL_ID_GHOST_STAMP_DECLINED
false, //TUTORIAL_ID_GHOST_STAMP_FRIENDS
true, //TUTORIAL_ID_TERMINAL_SCRATCH
true, //TUTORIAL_ID_TURN_SCRATCH_SHEET
false, //TUTORIAL_ID_INVITE_FRIEND_CAMPAIGN
false, //TUTORIAL_ID_CAR_COUPON_FULL_TUNED_RECEIVABLE
false, //TUTORIAL_ID_VS_CONTINUE_TICKET
false, //TUTORIAL_ID_UNUSED_28
false, //TUTORIAL_ID_UNUSED_29
false, //TUTORIAL_ID_UNUSED_30
false, //TUTORIAL_ID_DRESS_UP
true, //TUTORIAL_ID_MULTI_GHOST
true, //TUTORIAL_ID_STORY_NEW_FEATURE
true, //TUTORIAL_ID_GHOST_NEW_FEATURE
true, //TUTORIAL_ID_GHOST_REGION_MAP
false, //TUTORIAL_ID_STORY = 0,
false, //TUTORIAL_ID_TIME_ATTACK = 1,
false, //TUTORIAL_ID_GHOST = 2,
false, //TUTORIAL_ID_GHOST_CHALLENGE = 3,
false, //TUTORIAL_ID_GHOST_LEVEL = 4,
false, //TUTORIAL_ID_UNUSED_5 = 5,
false, //TUTORIAL_ID_GHOST_SEARCH = 6,
false, //TUTORIAL_ID_GHOST_COMPETITION = 7,
false, //TUTORIAL_ID_HP600_CARD = 8,
false, //TUTORIAL_ID_UNUSED_9 = 9,
false, //TUTORIAL_ID_COMPETITION_QUALIFIED = 10,
false, //TUTORIAL_ID_COMPETITION_TERMINAL = 11,
false, //TUTORIAL_ID_COMPETITION_NOTICE = 12,
false, //TUTORIAL_ID_COMPETITION_FINISHED = 13,
false, //TUTORIAL_ID_UNUSED_14 = 14,
false, //TUTORIAL_ID_UNUSED_15 = 15,
false, //TUTORIAL_ID_UNUSED_16 = 16,
false, //TUTORIAL_ID_UNUSED_17 = 17,
false, //TUTORIAL_ID_UNUSED_18 = 18,
false, //TUTORIAL_ID_UNUSED_19 = 19,
true, //TUTORIAL_ID_GHOST_STAMP = 20,
true, //TUTORIAL_ID_GHOST_STAMP_DECLINED = 21,
true, //TUTORIAL_ID_GHOST_STAMP_FRIENDS = 22,
true, //TUTORIAL_ID_TERMINAL_SCRATCH = 23,
true, //TUTORIAL_ID_TURN_SCRATCH_SHEET = 24,
false, //TUTORIAL_ID_INVITE_FRIEND_CAMPAIGN = 25,
false, //TUTORIAL_ID_CAR_COUPON_FULL_TUNED_RECEIVABLE = 26,
false, //TUTORIAL_ID_VS_CONTINUE_TICKET = 27,
false, //TUTORIAL_ID_UNUSED_28 = 28,
false, //TUTORIAL_ID_UNUSED_29 = 29,
false, //TUTORIAL_ID_UNUSED_30 = 30,
false, //TUTORIAL_ID_DRESS_UP = 31,
true, //TUTORIAL_ID_MULTI_GHOST = 32,
true, //TUTORIAL_ID_STORY_NEW_FEATURE = 33,
true, //TUTORIAL_ID_GHOST_NEW_FEATURE = 34,
true, //TUTORIAL_ID_GHOST_REGION_MAP = 35
],
}
});
console.log('user made')
if (!user) {
if (!user)
{
msg.error = wm.wm.protobuf.ErrorCode.ERR_REQUEST;
}
let ftTicketGrant = Config.getConfig().gameOptions.grantFullTuneTicketToNewUsers;
if (ftTicketGrant > 0) {
if (ftTicketGrant > 0)
{
console.log(`Granting Full-Tune Ticket x${ftTicketGrant} to new user...`);
for (let i=0; i<ftTicketGrant; i++) {
for (let i=0; i<ftTicketGrant; i++)
{
await prisma.userItem.create({
data: {
userId: user.id,
@ -124,16 +138,16 @@ export default class UserModule extends Module {
}
});
}
console.log('Done!');
}
let resp = wm.wm.protobuf.LoadUserResponse.encode(msg);
let end = resp.finish();
let r = res
.header('Server', 'v388 wangan')
.header('Content-Type', 'application/x-protobuf; revision=8053')
.header('Content-Length', end.length.toString())
.status(200);
r.send(Buffer.from(end));
// Encode the response
let message = wm.wm.protobuf.LoadUserResponse.encode(msg);
// Send the response to the client
common.sendResponse(message, res);
return;
}
@ -233,7 +247,7 @@ export default class UserModule extends Module {
let wsFont = 0;
// user.cars found
if(user.cars)
if(user.cars.length > 0)
{
// User atleast have 1 car
if(user.cars[0]?.windowStickerString !== null && user.cars[0]?.windowStickerString !== undefined &&
@ -243,8 +257,45 @@ export default class UserModule extends Module {
wsFont = user.cars[0].windowStickerFont;
}
// else{} User don't have a car... returning default windowStickerString and windowStickerFont value
if(user.cars[0].lastPlayedPlaceId === null || user.cars[0].lastPlayedPlaceId === undefined)
{
for(let i=0; i<user.cars.length; i++)
{
user.cars[0].lastPlayedPlaceId = 1;
}
await prisma.car.updateMany({
where:{
userId: user.id
},
data:{
lastPlayedPlaceId: 1
}
})
}
}
// Change Ghost Stamp tutorial to true
if(user.tutorials[20] === false)
{
console.log(`Change Ghost Stamp tutorial to true`)
for(let i=20; i<25; i++)
{
user.tutorials[i] = true
}
await prisma.user.update({
where:{
chipId: body.cardChipId
},
data:{
tutorials: user.tutorials
}
})
}
// Response data
let msg = {
error: wm.wm.protobuf.ErrorCode.ERR_SUCCESS,
@ -279,41 +330,24 @@ export default class UserModule extends Module {
// Get current date
let date = Math.floor(new Date().getTime() / 1000);
// Get current 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:{
dbId: 'desc'
}
});
// Check each car record
for(let i=0; i<msg.cars.length; i++)
{
// Get current active OCM Event
let ocmEventDate = await prisma.oCMEvent.findFirst({
where: {
OR: [
{
// qualifyingPeriodStartAt is less than current date
qualifyingPeriodStartAt: { lte: date },
// qualifyingPeriodCloseAt is greater than current date
qualifyingPeriodCloseAt: { gte: date },
},
{
// competitionStartAt is less than current date
competitionStartAt: { lte: date },
// competitionCloseAt is greater than current date
competitionCloseAt: { gte: date },
},
{
// competitionCloseAt is less than current date
competitionCloseAt: { lte: date },
// competitionEndAt is greater than current date
competitionEndAt: {gte: date },
}
],
},
orderBy:{
dbId: 'desc'
}
});
// Check Competition (OCM) Participation, and available OCM event
if(user.cars.length > 0 && ocmEventDate)
@ -333,31 +367,21 @@ export default class UserModule extends Module {
if(checkParticipation)
{
ParticipationMainDrawCounter++
}
// Check Car State
// Get OCM Data
let ocmTallyRecord = await prisma.oCMTally.findMany({
where:{
competitionId: ocmEventDate!.competitionId
},
orderBy: [
{
competitionId: 'desc',
},
{
periodId: 'desc',
},
{
result: 'desc',
},
],
});
// Check Car State
// Get OCM Data
let ocmTallyRecord = await prisma.oCMTally.findFirst({
where:{
carId: user.cars[i].carId,
competitionId: ocmEventDate!.competitionId
}
});
for(let j=0; j<ocmTallyRecord.length; j++)
{
carStates[i].eventJoined = true;
carStates[i].competitionState = wm.wm.protobuf.GhostCompetitionParticipantState.COMPETITION_QUALIFIED
if(ocmTallyRecord)
{
carStates[i].eventJoined = true;
carStates[i].competitionState = wm.wm.protobuf.GhostCompetitionParticipantState.COMPETITION_QUALIFIED
}
}
}
// Current date is OCM qualifying day
@ -375,30 +399,18 @@ export default class UserModule extends Module {
if(checkParticipation)
{
ParticipationQualifyingCounter++
}
// Check Car State
// Get OCM Data
let ocmRecord = await prisma.oCMPlayRecord.findMany({
where:{
competitionId: ocmEventDate!.competitionId
},
orderBy: [
{
dbId: 'asc',
// Check Car State
// Get OCM Data
let ocmRecord = await prisma.oCMPlayRecord.findFirst({
where:{
carId: user.cars[i].carId,
competitionId: ocmEventDate!.competitionId,
periodId: 0
},
{
competitionId: 'desc',
},
{
periodId: 'desc',
},
],
});
});
for(let j=0; j<ocmRecord.length; j++)
{
if(carStates[i].dbId === ocmRecord[j].carId)
if(ocmRecord)
{
carStates[i].eventJoined = true;
carStates[i].competitionState = wm.wm.protobuf.GhostCompetitionParticipantState.COMPETITION_PARTICIPATED
@ -407,7 +419,7 @@ export default class UserModule extends Module {
}
// Current date is OCM ended
else if(ocmEventDate!.competitionCloseAt < date && ocmEventDate!.competitionEndAt > date)
{
{
// Check ghost battle record
let checkParticipation = await prisma.oCMPlayRecord.findFirst({
where:{
@ -420,33 +432,22 @@ export default class UserModule extends Module {
if(checkParticipation)
{
ParticipationEndedCounter++
}
// Check Car State
// Get OCM Data
let ocmTallyRecord = await prisma.oCMTally.findMany({
where:{
competitionId: ocmEventDate!.competitionId,
periodId: 999999999
},
orderBy: [
{
result: 'desc',
// Check Car State
// Get OCM Data
let ocmTallyRecord = await prisma.oCMTally.findFirst({
where:{
carId: user.cars[i].carId,
competitionId: ocmEventDate!.competitionId,
periodId: 999999999
},
],
});
});
for(let j=0; j<ocmTallyRecord.length; j++)
{
if(carStates[i].dbId === ocmTallyRecord[j].carId)
if(ocmTallyRecord)
{
carStates[i].eventJoined = true;
carStates[i].competitionState = wm.wm.protobuf.GhostCompetitionParticipantState.COMPETITION_QUALIFIED
}
if(carStates[i].dbId === ocmTallyRecord[j].carId && j === 0)
{
carStates[i].competitionState = wm.wm.protobuf.GhostCompetitionParticipantState.COMPETITION_WON
}
}
}
}
@ -499,13 +500,20 @@ export default class UserModule extends Module {
else if(ParticipationEndedCounter > 0)
{
console.log('OCM Participation : '+ParticipationEndedCounter+' car(s) played OCM Event');
msg.competitionUserState = wm.wm.protobuf.GhostCompetitionParticipantState.COMPETITION_QUALIFIED;
}
else{
else if(ocmEventDate)
{
console.log('OCM Participation : Not Participated / Qualified');
}
else
{
console.log('No OCM Event Available');
}
// Response data if user is banned
if (user.userBanned) {
if (user.userBanned)
{
msg.error = wm.wm.protobuf.ErrorCode.ERR_ID_BANNED;
}

View File

@ -43,7 +43,8 @@ export function getBigIntFromLong(n: Long)
return Number(bigInt);
}
export function sanitizeInput(value: any){
export function sanitizeInput(value: any)
{
return (value == null || value == undefined) ? undefined : value;
}

View File

@ -6,7 +6,8 @@ import wmproto from "../../wmmt/wm.proto";
// Import Util
import * as common from "../../util/common";
import * as ghost_history from "../games/games_util/ghost_history";
import * as ghost_history from "../ghost/ghost_history";
import * as ghost_stamp from "../ghost/ghost_stamp";
// Save ghost battle result
export async function saveGhostBattleResult(body: wm.protobuf.SaveGameResultRequest, car: any)
@ -24,25 +25,10 @@ export async function saveGhostBattleResult(body: wm.protobuf.SaveGameResultRequ
// Set ghost mode play to true for saving the ghost trail later
ghostModePlay = true;
// Get the ghost result for the car
let ghostResult = body?.rgResult;
// Declare data
let dataGhost : any;
let dataCar : any;
// ghostResult is set
if (ghostResult)
{
// Ghost update data
dataGhost = {
rgRegionMapScore: common.sanitizeInput(ghostResult.rgRegionMapScore),
rgPlayCount: common.sanitizeInput(ghostResult.rgPlayCount),
dressupLevel: common.sanitizeInput(ghostResult.dressupLevel),
dressupPoint: common.sanitizeInput(ghostResult.dressupPoint),
}
}
// Get the ghost result for the car
let cars = body?.car;
@ -79,21 +65,38 @@ export async function saveGhostBattleResult(body: wm.protobuf.SaveGameResultRequ
}
}
// Count total win based on region map score
if(body.rgResult?.rgRegionMapScore && body.rgResult?.rgRegionMapScore.length !== 0)
{
let winCounter = 0;
// Get the ghost result for the car
let ghostResult = body?.rgResult;
// Count the total win
for(let i=0; i<body.rgResult.rgRegionMapScore.length; i++)
{
winCounter += body.rgResult.rgRegionMapScore[i];
// ghostResult is set
if (ghostResult)
{
// Ghost update data
dataGhost = {
rgRegionMapScore: common.sanitizeInput(ghostResult.rgRegionMapScore),
rgPlayCount: common.sanitizeInput(ghostResult.rgPlayCount),
dressupLevel: common.sanitizeInput(ghostResult.dressupLevel),
dressupPoint: common.sanitizeInput(ghostResult.dressupPoint),
stampSheet: common.sanitizeInput(ghostResult.stampSheet),
stampSheetCount: common.sanitizeInputNotZero(ghostResult.stampSheetCount),
}
// Count total win based on region map score
if(ghostResult.rgRegionMapScore && ghostResult.rgRegionMapScore.length !== 0)
{
let winCounter = 0;
// Count the total win
for(let i=0; i<ghostResult.rgRegionMapScore.length; i++)
{
winCounter += ghostResult.rgRegionMapScore[i];
}
// Set the data
dataGhost.rgWinCount = winCounter;
dataGhost.rgScore = winCounter;
dataGhost.rgTrophy = winCounter;
}
// Set the data
dataGhost.rgWinCount = winCounter;
dataGhost.rgScore = winCounter;
dataGhost.rgTrophy = winCounter;
}
// Update the car properties
@ -114,64 +117,31 @@ export async function saveGhostBattleResult(body: wm.protobuf.SaveGameResultRequ
switch (body.rgResult!.selectionMethod)
{
// Ghost Battle by Level
case wmproto.wm.protobuf.GhostSelectionMethod.GHOST_SELECT_BY_LEVEL:
{
console.log('Normal Ghost Mode Found - Select by Level');
ghost_historys = await ghost_history.saveGhostHistory(body);
// Update the updateNewTrail value
updateNewTrail = ghost_historys.updateNewTrail;
break;
}
// Ghost Battle by Name
case wmproto.wm.protobuf.GhostSelectionMethod.GHOST_SEARCH_BY_NAME:
{
console.log('Normal Ghost Mode Found - Search by Name');
ghost_historys = await ghost_history.saveGhostHistory(body);
// Update the updateNewTrail value
updateNewTrail = ghost_historys.updateNewTrail;
break;
}
// Ghost Battle by Region
// Ghost Battle Search by Region (1)
case wmproto.wm.protobuf.GhostSelectionMethod.GHOST_SEARCH_BY_REGION:
{
console.log('Normal Ghost Mode Found - Search by Region');
ghost_historys = await ghost_history.saveGhostHistory(body);
// Return Stamp (Shuttle Match)
await ghost_stamp.shuttleReturnStamp(body);
// Update the updateNewTrail value
updateNewTrail = ghost_historys.updateNewTrail;
break;
}
// Ghost Battle from History
case wmproto.wm.protobuf.GhostSelectionMethod.GHOST_SELECT_FROM_HISTORY:
// Ghost Battle Select by Level (2)
case wmproto.wm.protobuf.GhostSelectionMethod.GHOST_SELECT_BY_LEVEL:
{
console.log('Normal Ghost Mode Found - Select from History');
console.log('Normal Ghost Mode Found - Select by Level');
ghost_historys = await ghost_history.saveGhostHistory(body);
// Update the updateNewTrail value
updateNewTrail = ghost_historys.updateNewTrail;
break;
}
// Ghost Battle by Shop
case wmproto.wm.protobuf.GhostSelectionMethod.GHOST_SEARCH_BY_SHOP:
{
console.log('Normal Ghost Mode Found - Search by Shop');
ghost_historys = await ghost_history.saveGhostHistory(body);
// Return Stamp (Shuttle Match)
await ghost_stamp.shuttleReturnStamp(body);
// Update the updateNewTrail value
updateNewTrail = ghost_historys.updateNewTrail;
@ -179,7 +149,7 @@ export async function saveGhostBattleResult(body: wm.protobuf.SaveGameResultRequ
break;
}
// Crown Ghost Battle Mode
// Crown Ghost Battle Mode (3)
case wmproto.wm.protobuf.GhostSelectionMethod.GHOST_SELECT_CROWN_MATCH:
{
console.log('Crown Ghost Mode Found');
@ -335,51 +305,250 @@ export async function saveGhostBattleResult(body: wm.protobuf.SaveGameResultRequ
break;
}
// OCM Ghost Battle Mode
// Ghost Battle Select Stamp Match (4)
case wmproto.wm.protobuf.GhostSelectionMethod.GHOST_SELECT_STAMP_MATCH:
{
console.log('Normal Ghost Mode Found - Select Stamp Match');
ghost_historys = await ghost_history.saveGhostHistory(body);
// Return Stamp (Shuttle Match)
await ghost_stamp.shuttleReturnStamp(body);
// Update the updateNewTrail value
updateNewTrail = ghost_historys.updateNewTrail;
break;
}
// Ghost Battle Select from History (5)
case wmproto.wm.protobuf.GhostSelectionMethod.GHOST_SELECT_FROM_HISTORY:
{
console.log('Normal Ghost Mode Found - Select from History');
ghost_historys = await ghost_history.saveGhostHistory(body);
// Return Stamp (Shuttle Match)
await ghost_stamp.shuttleReturnStamp(body);
// Update the updateNewTrail value
updateNewTrail = ghost_historys.updateNewTrail;
break;
}
// Ghost Battle Search by Shop (6)
case wmproto.wm.protobuf.GhostSelectionMethod.GHOST_SEARCH_BY_SHOP:
{
console.log('Normal Ghost Mode Found - Search by Shop');
ghost_historys = await ghost_history.saveGhostHistory(body);
// Return Stamp (Shuttle Match)
await ghost_stamp.shuttleReturnStamp(body);
// Update the updateNewTrail value
updateNewTrail = ghost_historys.updateNewTrail;
break;
}
// Ghost Battle Search by Name (7)
case wmproto.wm.protobuf.GhostSelectionMethod.GHOST_SEARCH_BY_NAME:
{
console.log('Normal Ghost Mode Found - Search by Name');
ghost_historys = await ghost_history.saveGhostHistory(body);
// Return Stamp (Shuttle Match)
await ghost_stamp.shuttleReturnStamp(body);
// Update the updateNewTrail value
updateNewTrail = ghost_historys.updateNewTrail;
break;
}
// Ghost Battle Challenger (8)
case wmproto.wm.protobuf.GhostSelectionMethod.GHOST_ACCEPT_CHALLENGER:
{
console.log('Normal Ghost Mode Found - Challenger');
ghost_historys = await ghost_history.saveGhostHistory(body);
// Return Stamp (Shuttle Match)
await ghost_stamp.shuttleReturnStamp(body);
// Update the updateNewTrail value
updateNewTrail = ghost_historys.updateNewTrail;
break;
}
// OCM Ghost Battle Mode (11)
case wmproto.wm.protobuf.GhostSelectionMethod.GHOST_COMPETITION:
{
console.log('OCM Ghost Mode Found');
OCMModePlay = true;
let saveExOCM: any = {};
saveExOCM.carId = body.carId;
if(body.rgResult?.competitionId)
{
saveExOCM.competitionId = body.rgResult?.competitionId!;
}
// Get the rg result for the car
let rgResult = body?.rgResult;
if(body.rgResult?.periodId)
// rgResult is set
if (rgResult)
{
saveExOCM.periodId = body.rgResult?.periodId!;
}
else
{
saveExOCM.periodId = 0;
}
let data : any = {
carId: body.carId,
competitionId: common.sanitizeInput(rgResult.competitionId),
periodId: common.sanitizeInput(rgResult.periodId) || 0,
brakingPoint: common.sanitizeInput(rgResult.brakingPoint) || 0,
playedAt: common.sanitizeInput(body.playedAt),
}
if(body.rgResult?.brakingPoint)
{
saveExOCM.brakingPoint = body.rgResult?.brakingPoint!;
}
else
{
saveExOCM.brakingPoint = 0;
}
// Get the user's available OCM Battle data
let countOCM = await prisma.oCMPlayRecord.count({
where: {
competitionId: data.competitionId,
carId: body.carId
}
});
if(body?.playedAt)
{
saveExOCM.playedAt = body?.playedAt!;
// User's OCM Battle data available
if(countOCM !== 0)
{
console.log('OCM Play Record found');
console.log('Updaing OCM Play Record entry');
await prisma.oCMPlayRecord.updateMany({
where:{
carId: data.carId,
competitionId: data.competitionId,
},
data: data
});
}
// First time User playing OCM Battle
else
{
console.log('OCM Play Record not found');
console.log('Creating new OCM Play Record entry');
await prisma.oCMPlayRecord.create({
data: data
});
}
ghost_historys = await ghost_history.saveOCMGhostHistory(body);
// Update the updateNewTrail value
updateNewTrail = ghost_historys.updateNewTrail;
}
break;
}
// Ghost Battle Select from Bookmars (12)
case wmproto.wm.protobuf.GhostSelectionMethod.GHOST_SELECT_FROM_BOOKMARKS:
{
console.log('Normal Ghost Mode Found - Select from Bookmars');
ghost_historys = await ghost_history.saveGhostHistory(body);
// Return Stamp (Shuttle Match)
await ghost_stamp.shuttleReturnStamp(body);
// Update the updateNewTrail value
updateNewTrail = ghost_historys.updateNewTrail;
break;
}
}
}
// Retiring Ghost Battle
else if(body.rgResult!.selectionMethod === wmproto.wm.protobuf.GhostSelectionMethod.GHOST_SEARCH_BY_REGION ||
body.rgResult!.selectionMethod === wmproto.wm.protobuf.GhostSelectionMethod.GHOST_SELECT_BY_LEVEL ||
body.rgResult!.selectionMethod === wmproto.wm.protobuf.GhostSelectionMethod.GHOST_SELECT_CROWN_MATCH ||
body.rgResult!.selectionMethod === wmproto.wm.protobuf.GhostSelectionMethod.GHOST_SELECT_STAMP_MATCH ||
body.rgResult!.selectionMethod === wmproto.wm.protobuf.GhostSelectionMethod.GHOST_SELECT_FROM_HISTORY ||
body.rgResult!.selectionMethod === wmproto.wm.protobuf.GhostSelectionMethod.GHOST_SEARCH_BY_SHOP ||
body.rgResult!.selectionMethod === wmproto.wm.protobuf.GhostSelectionMethod.GHOST_SEARCH_BY_NAME ||
body.rgResult!.selectionMethod === wmproto.wm.protobuf.GhostSelectionMethod.GHOST_ACCEPT_CHALLENGER ||
body.rgResult!.selectionMethod === wmproto.wm.protobuf.GhostSelectionMethod.GHOST_SELECT_FROM_BOOKMARKS)
{
console.log('Normal Ghost Mode Found but Retiring');
// Get the ghost result for the car
let ghostResult = body?.rgResult;
// Declare data
let dataGhost : any;
// ghostResult is set
if (ghostResult)
{
// Ghost update data
dataGhost = {
rgPlayCount: common.sanitizeInput(ghostResult.rgPlayCount),
}
// Update the car properties
await prisma.car.update({
where: {
carId: body.carId
},
data: {
...dataGhost
}
});
}
}
// Retiring OCM for mini games
else if(body.rgResult!.selectionMethod === wmproto.wm.protobuf.GhostSelectionMethod.GHOST_COMPETITION)
{
// Get current date
let date = Math.floor(new Date().getTime() / 1000);
// Get currently 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:{
dbId: 'desc'
}
});
if(ocmEventDate!.qualifyingPeriodStartAt < date && ocmEventDate!.qualifyingPeriodCloseAt > date)
{
console.log('OCM Ghost Mode Found but Retiring');
// Get the rg result for the car
let rgResult = body?.rgResult;
// rgResult is set
if (rgResult)
{
let data : any = {
carId: body.carId,
competitionId: common.sanitizeInput(rgResult.competitionId),
periodId: common.sanitizeInput(rgResult.periodId) || 0,
brakingPoint: common.sanitizeInput(rgResult.brakingPoint) || 0,
playedAt: common.sanitizeInput(body.playedAt),
}
// Get the user's available OCM Battle data
let countOCM = await prisma.oCMPlayRecord.count({
where: {
competitionId: saveExOCM.competitionId,
competitionId: data.competitionId,
carId: body.carId
}
});
// User's OCM Battle data available
if(countOCM !== 0)
{
@ -388,10 +557,10 @@ export async function saveGhostBattleResult(body: wm.protobuf.SaveGameResultRequ
await prisma.oCMPlayRecord.updateMany({
where:{
carId: saveExOCM.carId,
competitionId: saveExOCM.competitionId,
carId: data.carId,
competitionId: data.competitionId,
},
data: saveExOCM
data: data
});
}
// First time User playing OCM Battle
@ -401,16 +570,9 @@ export async function saveGhostBattleResult(body: wm.protobuf.SaveGameResultRequ
console.log('Creating new OCM Play Record entry');
await prisma.oCMPlayRecord.create({
data: saveExOCM
data: data
});
}
ghost_historys = await ghost_history.saveOCMGhostHistory(body);
// Update the updateNewTrail value
updateNewTrail = ghost_historys.updateNewTrail;
break;
}
}
}

View File

@ -1,7 +1,7 @@
import { prisma } from "..";
import { prisma } from "../..";
// Import Proto
import { wm } from "../wmmt/wm.proto";
import { wm } from "../../wmmt/wm.proto";
// Save story result

View File

@ -1,7 +1,12 @@
// Import Proto
import { prisma } from "../../..";
import { Config } from "../../../config";
import { wm } from "../../../wmmt/wm.proto";
import { prisma } from "../..";
import { Config } from "../../config";
import { wm } from "../../wmmt/wm.proto";
// Import Util
import * as common from "../../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";
// Save ghost history battle
@ -11,129 +16,97 @@ export async function saveGhostHistory(body: wm.protobuf.SaveGameResultRequest)
let updateNewTrail: boolean = true;
let saveExGhostHistory: any = {};
if (body.car?.carId !== null && body.car?.carId !== undefined) {
saveExGhostHistory.carId = body.car?.carId!;
}
if (body.car?.tunePower !== null && body.car?.tunePower !== undefined) {
saveExGhostHistory.tunePower = body.car?.tunePower!;
}
if (body.car?.tuneHandling !== null && body.car?.tuneHandling !== undefined) {
saveExGhostHistory.tuneHandling = body.car?.tuneHandling!;
}
if (body.playedAt !== null && body.playedAt !== undefined){
saveExGhostHistory.playedAt = body.playedAt!;
}
// Get shop name
saveExGhostHistory.playedShopName = Config.getConfig().shopName;
// Get the car result for the car
let car = body?.car;
// Get how many opponents available
for(let i=0; i<body.rgResult!.opponents!.length; i++)
{
// First opponent data
if(i == 0)
{
// Get first opponent carId
saveExGhostHistory.opponent1CarId = body.rgResult!.opponents![0].carId;
// Get first opponent tunePower
saveExGhostHistory.opponent1TunePower = body.rgResult!.opponents![0].tunePower;
// Get first opponent tunePower
saveExGhostHistory.opponent1TuneHandling = body.rgResult!.opponents![0].tuneHandling;
// Get the advantage distance between first opponent and user
saveExGhostHistory.opponent1Result = body.rgResult!.opponents![0].result;
}
// Second opponent data
else if(i == 1)
{
// Get second opponent carId
saveExGhostHistory.opponent2CarId = body.rgResult!.opponents![1].carId;
// Get second opponent tunePower
saveExGhostHistory.opponent2TunePower = body.rgResult!.opponents![1].tunePower;
// Get second opponent tuneHandling
saveExGhostHistory.opponent2TuneHandling = body.rgResult!.opponents![1].tuneHandling;
// Get the advantage distance between second opponent and user
saveExGhostHistory.opponent2Result = body.rgResult!.opponents![1].result;
}
// Third opponent data
else if(i == 2)
{
// Get third opponent carId
saveExGhostHistory.opponent3CarId = body.rgResult!.opponents![2].carId;
// Get third opponent tunePower
saveExGhostHistory.opponent3TunePower = body.rgResult!.opponents![2].tunePower;
// Get third opponent tuneHandling
saveExGhostHistory.opponent3TuneHandling = body.rgResult!.opponents![2].tuneHandling;
// Get the advantage distance between third opponent and user
saveExGhostHistory.opponent3Result = body.rgResult!.opponents![2].result;
}
}
// Get played Area
if(body.rgResult?.path !== null && body.rgResult?.path !== undefined)
if(car)
{
if(body.rgResult?.path >= 0 && body.rgResult?.path <= 9){ // GID_PATH_C1
saveExGhostHistory.area = Number(0);
}
else if(body.rgResult?.path >= 10 && body.rgResult?.path <= 15){ // GID_PATH_N9
saveExGhostHistory.area = Number(1);
}
else if(body.rgResult?.path >= 16 && body.rgResult?.path <= 17){ // GID_PATH_WTEAST
saveExGhostHistory.area = Number(2);
}
else if(body.rgResult?.path >= 18 && body.rgResult?.path <= 19){ // GID_PATH_WT_UP_DOWN
saveExGhostHistory.area = Number(3);
}
else if(body.rgResult?.path >= 20 && body.rgResult?.path <= 26){ // GID_PATH_WG
saveExGhostHistory.area = Number(4);
}
else if(body.rgResult?.path >= 27 && body.rgResult?.path <= 33){ // GID_PATH_KG
saveExGhostHistory.area = Number(5);
}
else if(body.rgResult?.path >= 34 && body.rgResult?.path <= 37){ // GID_PATH_YS
saveExGhostHistory.area = Number(6);
}
else if(body.rgResult?.path >= 38 && body.rgResult?.path <= 48){ // GID_PATH_KG_SHINYAMASHITA_MINATOMIRAI
saveExGhostHistory.area = Number(7);
}
else if(body.rgResult?.path === 49){ // GID_PATH_NGR
saveExGhostHistory.area = Number(8);
}
else if(body.rgResult?.path >= 50 && body.rgResult?.path <= 53){ // GID_PATH_OS
saveExGhostHistory.area = Number(9);
}
else if(body.rgResult?.path >= 54 && body.rgResult?.path <= 55){ // GID_PATH_KB
saveExGhostHistory.area = Number(10);
}
else if(body.rgResult?.path >= 58 && body.rgResult?.path <= 61){ // GID_PATH_FK
saveExGhostHistory.area = Number(11);
}
else if(body.rgResult?.path >= 62 && body.rgResult?.path <= 63){ // GID_PATH_HK
saveExGhostHistory.area = Number(12);
}
else if(body.rgResult?.path >= 64 && body.rgResult?.path <= 65){ // GID_PATH_TP
saveExGhostHistory.area = Number(13);
}
else if(body.rgResult?.path >= 56 && body.rgResult?.path <= 57){ // GID_PATH_HS
saveExGhostHistory.area = Number(18);
saveExGhostHistory = {
carId: common.sanitizeInput(car.carId),
tunePower: common.sanitizeInput(car.tunePower),
tuneHandling: common.sanitizeInput(car.tuneHandling),
playedAt: common.sanitizeInputNotZero(body.playedAt),
playedShopName: Config.getConfig().shopName
}
}
// Get the rg result for the car
let rgResult = body?.rgResult;
if(rgResult)
{
if(rgResult.opponents)
{
// Get how many opponents available
for(let i=0; i<rgResult.opponents.length; i++)
{
// First opponent data
if(i == 0)
{
// Get first opponent carId
saveExGhostHistory.opponent1CarId = rgResult.opponents[0].carId;
// Get first opponent tunePower
saveExGhostHistory.opponent1TunePower = rgResult.opponents[0].tunePower;
// Get first opponent tunePower
saveExGhostHistory.opponent1TuneHandling = rgResult.opponents[0].tuneHandling;
// Get the advantage distance between first opponent and user
saveExGhostHistory.opponent1Result = rgResult.opponents[0].result;
}
// Second opponent data
else if(i == 1)
{
// Get second opponent carId
saveExGhostHistory.opponent2CarId = rgResult.opponents[1].carId;
// Get second opponent tunePower
saveExGhostHistory.opponent2TunePower = rgResult.opponents[1].tunePower;
// Get second opponent tuneHandling
saveExGhostHistory.opponent2TuneHandling = rgResult.opponents[1].tuneHandling;
// Get the advantage distance between second opponent and user
saveExGhostHistory.opponent2Result = rgResult.opponents[1].result;
}
// Third opponent data
else if(i == 2)
{
// Get third opponent carId
saveExGhostHistory.opponent3CarId = rgResult.opponents[2].carId;
// Get third opponent tunePower
saveExGhostHistory.opponent3TunePower = rgResult.opponents[2].tunePower;
// Get third opponent tuneHandling
saveExGhostHistory.opponent3TuneHandling = rgResult.opponents[2].tuneHandling;
// Get the advantage distance between third opponent and user
saveExGhostHistory.opponent3Result = rgResult.opponents[2].result;
}
}
}
// Get played Area
if(common.sanitizeInput(rgResult.path))
{
let getArea = await ghost_get_area_from_path.getArea(rgResult.path);
saveExGhostHistory.area = getArea.area
}
}
await prisma.ghostBattleRecord.create({
data: saveExGhostHistory
});
// Sending stamp to opponents
await ghost_stamp.sendStamp(body);
// Return the value to 'BASE_PATH/src/util/games/ghost.ts'
return { updateNewTrail }
}
@ -144,72 +117,37 @@ export async function saveOCMGhostHistory(body: wm.protobuf.SaveGameResultReques
let updateNewTrail: boolean = true;
let saveExGhostHistory: any = {};
if (body.car?.carId !== null && body.car?.carId !== undefined) {
saveExGhostHistory.carId = body.car?.carId!;
}
if (body.car?.tunePower !== null && body.car?.tunePower !== undefined) {
saveExGhostHistory.tunePower = body.car?.tunePower!;
}
if (body.car?.tuneHandling !== null && body.car?.tuneHandling !== undefined) {
saveExGhostHistory.tuneHandling = body.car?.tuneHandling!;
}
if (body.playedAt !== null && body.playedAt !== undefined){
saveExGhostHistory.playedAt = body.playedAt!;
}
// Get the car result for the car
let car = body?.car;
// Get shop name
saveExGhostHistory.playedShopName = Config.getConfig().shopName;
// Get the advantage distance between first opponent and user
saveExGhostHistory.result = body.rgResult!.opponents![0].result;
// Get played Area
if(body.rgResult?.path !== null && body.rgResult?.path !== undefined)
if(car)
{
if(body.rgResult?.path >= 0 && body.rgResult?.path <= 9){ // GID_PATH_C1
saveExGhostHistory.area = Number(0);
saveExGhostHistory = {
carId: common.sanitizeInput(car.carId),
tunePower: common.sanitizeInput(car.tunePower),
tuneHandling: common.sanitizeInput(car.tuneHandling),
playedAt: common.sanitizeInputNotZero(body.playedAt),
playedShopName: Config.getConfig().shopName
}
else if(body.rgResult?.path >= 10 && body.rgResult?.path <= 15){ // GID_PATH_N9
saveExGhostHistory.area = Number(1);
}
// Get the rg result for the car
let rgResult = body?.rgResult;
if(rgResult)
{
if(rgResult.opponents)
{
// Get the advantage distance between first opponent and user
saveExGhostHistory.result = rgResult.opponents[0].result;
}
else if(body.rgResult?.path >= 16 && body.rgResult?.path <= 17){ // GID_PATH_WTEAST
saveExGhostHistory.area = Number(2);
}
else if(body.rgResult?.path >= 18 && body.rgResult?.path <= 19){ // GID_PATH_WT_UP_DOWN
saveExGhostHistory.area = Number(3);
}
else if(body.rgResult?.path >= 20 && body.rgResult?.path <= 26){ // GID_PATH_WG
saveExGhostHistory.area = Number(4);
}
else if(body.rgResult?.path >= 27 && body.rgResult?.path <= 33){ // GID_PATH_KG
saveExGhostHistory.area = Number(5);
}
else if(body.rgResult?.path >= 34 && body.rgResult?.path <= 37){ // GID_PATH_YS
saveExGhostHistory.area = Number(6);
}
else if(body.rgResult?.path >= 38 && body.rgResult?.path <= 48){ // GID_PATH_KG_SHINYAMASHITA_MINATOMIRAI
saveExGhostHistory.area = Number(7);
}
else if(body.rgResult?.path === 49){ // GID_PATH_NGR
saveExGhostHistory.area = Number(8);
}
else if(body.rgResult?.path >= 50 && body.rgResult?.path <= 53){ // GID_PATH_OS
saveExGhostHistory.area = Number(9);
}
else if(body.rgResult?.path >= 54 && body.rgResult?.path <= 55){ // GID_PATH_KB
saveExGhostHistory.area = Number(10);
}
else if(body.rgResult?.path >= 58 && body.rgResult?.path <= 61){ // GID_PATH_FK
saveExGhostHistory.area = Number(11);
}
else if(body.rgResult?.path >= 62 && body.rgResult?.path <= 63){ // GID_PATH_HK
saveExGhostHistory.area = Number(12);
}
else if(body.rgResult?.path >= 64 && body.rgResult?.path <= 65){ // GID_PATH_TP
saveExGhostHistory.area = Number(13);
}
else if(body.rgResult?.path >= 56 && body.rgResult?.path <= 57){ // GID_PATH_HS
saveExGhostHistory.area = Number(18);
// Get played Area
if(common.sanitizeInput(rgResult.path))
{
let getArea = await ghost_get_area_from_path.getArea(rgResult.path);
saveExGhostHistory.area = getArea.area
}
}
@ -219,29 +157,11 @@ export async function saveOCMGhostHistory(body: wm.protobuf.SaveGameResultReques
// Get currently active OCM event
let ocmEventDate = await prisma.oCMEvent.findFirst({
where: {
OR: [
{
// qualifyingPeriodStartAt is less than current date
qualifyingPeriodStartAt: { lte: date },
// qualifyingPeriodStartAt is less than current date
qualifyingPeriodStartAt: { lte: date },
// qualifyingPeriodCloseAt is greater than current date
qualifyingPeriodCloseAt: { gte: date },
},
{
// competitionStartAt is less than current date
competitionStartAt: { lte: date },
// competitionCloseAt is greater than current date
competitionCloseAt: { gte: date },
},
{
// competitionCloseAt is less than current date
competitionCloseAt: { lte: date },
// competitionEndAt is greater than current date
competitionEndAt: {gte: date },
}
],
// competitionEndAt is greater than current date
competitionEndAt: { gte: date },
},
orderBy:{
dbId: 'desc'

View File

@ -1,5 +1,4 @@
// Save ghost battle result
// OCM Area
export async function OCMArea(competition_id: number)
{
let areaVal = 0;

View File

@ -15,29 +15,11 @@ export async function saveOCMGhostTrail(body: wm.protobuf.RegisterGhostTrailRequ
// Get current active OCM Event
let ocmEventDate = await prisma.oCMEvent.findFirst({
where: {
OR: [
{
// qualifyingPeriodStartAt is less than current date
qualifyingPeriodStartAt: { lte: date },
// qualifyingPeriodStartAt is less than current date
qualifyingPeriodStartAt: { lte: date },
// qualifyingPeriodCloseAt is greater than current date
qualifyingPeriodCloseAt: { gte: date },
},
{
// competitionStartAt is less than current date
competitionStartAt: { lte: date },
// competitionCloseAt is greater than current date
competitionCloseAt: { gte: date },
},
{
// competitionCloseAt is less than current date
competitionCloseAt: { lte: date },
// competitionEndAt is greater than current date
competitionEndAt: {gte: date },
}
],
// competitionEndAt is greater than current date
competitionEndAt: { gte: date },
},
orderBy:{
dbId: 'desc'
@ -49,21 +31,20 @@ export async function saveOCMGhostTrail(body: wm.protobuf.RegisterGhostTrailRequ
// Get OCM Period ID
let OCM_periodId = await prisma.oCMPeriod.findFirst({
where:{
competitionDbId: ocmEventDate!.dbId,
competitionId: ocmEventDate!.competitionId,
startAt:
{
lte: date, // competitionStartAt is less than current date
},
closeAt:
{
gte: date, // competitionCloseAt is greater than current date
}
competitionDbId: ocmEventDate.dbId,
competitionId: ocmEventDate.competitionId,
// StartAt is less than current date
startAt: { lte: date },
// CloseAt is greater than current date
closeAt: { gte: date }
},
select:{
periodId: true
}
});
let ocmMainDraws: boolean = false;
let periodId = 0;
@ -92,6 +73,7 @@ export async function saveOCMGhostTrail(body: wm.protobuf.RegisterGhostTrailRequ
let grArea: number = 0;
let grRamp: number = 0;
let grPath: number = 0;
if(ghostResult.area)
{
grArea = ghostResult.area;
@ -184,6 +166,7 @@ export async function saveCrownGhostTrail(body: wm.protobuf.RegisterGhostTrailRe
let grArea: number = 0;
let grRamp: number = 0;
let grPath: number = 0;
if(ghostResult.area)
{
grArea = ghostResult.area;

View File

@ -0,0 +1,239 @@
import { prisma } from "../..";
// Import Proto
import { wm } from "../../wmmt/wm.proto";
// Import Util
import * as ghost_get_area_from_path from "../ghost/ghost_util/ghost_get_area_from_path";
export async function sendStamp(body: wm.protobuf.SaveGameResultRequest)
{
let consoleLog = 0; // stupid stuff for console log notice
let rgResult = body.rgResult;
// Get current date
let date = Math.floor(new Date().getTime() / 1000);
if(rgResult)
{
// Stamp must bigger than 0
if(rgResult.rgStamp === 0)
{
rgResult.rgStamp = 1;
}
// Get the area
let area;
if(rgResult.path)
{
let getArea = await ghost_get_area_from_path.getArea(rgResult.path);
area = getArea.area;
}
// Check how many opponents available
for(let i=0; i<rgResult.opponents!.length; i++)
{
let checkCar = await prisma.car.findFirst({
where:{
carId: rgResult.opponents![i].carId,
NOT:{
userId: body.car!.userId!
}
},
include:{
gtWing: true,
lastPlayedPlace: true
}
})
if(checkCar)
{
if(consoleLog === 0)
{
console.log('Sending Stamp');
consoleLog = 1;
}
// Create Challenger data
let dataChallenger: any = {
carId: rgResult.opponents![i].carId,
challengerCarId: body.carId,
stamp: rgResult.rgStamp,
result: rgResult.opponents![i].result,
area: area,
lastPlayedAt: date
}
// Create Stamp Target data
let dataStampTarget: any = {
carId: body.carId,
stampTargetCarId: rgResult.opponents![i].carId,
returnCount: 1,
locked: false,
recommended: true
}
// Check available stamp
let stampTarget = await prisma.carStampTarget.findFirst({
where:{
carId: body.carId,
stampTargetCarId: rgResult.opponents![i].carId,
}
})
// No record found
if(!(stampTarget))
{
console.log('Creating new stamp entry');
await prisma.carChallenger.create({
data: dataChallenger
})
await prisma.carStampTarget.create({
data: dataStampTarget
})
}
}
}
}
}
export async function shuttleReturnStamp(body: wm.protobuf.SaveGameResultRequest)
{
let consoleLog = 0; // stupid stuff for console log notice
let rgResult = body.rgResult;
// Get current date
let date = Math.floor(new Date().getTime() / 1000);
if(rgResult)
{
// Stamp must bigger than 0
if(rgResult.rgStamp === 0)
{
rgResult.rgStamp = 1;
}
// Get the area
let area;
if(rgResult.path)
{
let getArea = await ghost_get_area_from_path.getArea(rgResult.path);
area = getArea.area;
}
// Check how many opponents available
for(let i=0; i<rgResult.opponents!.length; i++)
{
let checkCar = await prisma.car.findFirst({
where:{
carId: rgResult.opponents![i].carId,
NOT:{
userId: body.car!.userId!
}
},
include:{
gtWing: true,
lastPlayedPlace: true
}
})
if(checkCar)
{
if(consoleLog === 0)
{
console.log('Returning Stamp');
consoleLog = 1;
}
// Return the stamp
let stampTarget = await prisma.carStampTarget.findFirst({
where:{
carId: rgResult.opponents![i].carId,
stampTargetCarId: body.carId,
}
})
if(stampTarget)
{
let returnCount = stampTarget.returnCount + 1;
let dataStampTarget: any = {
carId: rgResult.opponents![i].carId,
stampTargetCarId: body.carId,
returnCount: returnCount,
locked: true,
recommended: false
}
console.log(`Updating car ${rgResult.opponents![i].carId} vs ${body.carId} stamp entry and locking it`);
await prisma.carStampTarget.update({
where:{
id: stampTarget.id
},
data: dataStampTarget
})
}
// Stamp Returned
let challengeReturned = await prisma.carChallenger.findFirst({
where:{
carId: rgResult.opponents![i].carId,
challengerCarId: body.carId,
}
})
if(challengeReturned)
{
let dataChallenger: any = {
carId: rgResult.opponents![i].carId,
challengerCarId: body.carId,
stamp: rgResult.rgStamp,
result: rgResult.opponents![i].result,
area: area,
lastPlayedAt: date
}
console.log('Updating challenger entry');
await prisma.carChallenger.update({
where:{
id: challengeReturned.id
},
data: dataChallenger
})
}
let stampReturned = await prisma.carStampTarget.findFirst({
where:{
carId: body.carId,
stampTargetCarId: rgResult.opponents![i].carId,
}
})
if(stampReturned)
{
console.log(`Stamp returned to ${rgResult.opponents![i].carId}, unlocking it so opponents can fight your ghost`);
await prisma.carStampTarget.update({
where:{
id: stampReturned.id
},
data: {
locked: false,
recommended: true
}
})
}
}
}
}
}

View File

@ -2,7 +2,7 @@ import { prisma } from "../..";
import { OCMTop1GhostTrail } from "@prisma/client";
// Import Proto
import * as ghost_ocm_area from "../games/games_util/ghost_ocm_area";
import * as ghost_ocm_area from "./ghost_ocm_area";
// Save ghost battle result
@ -14,29 +14,11 @@ export async function getOCMGhostTrail(carId: number, trailId: number)
// Get current / previous active OCM Event
let ocmEventDate = await prisma.oCMEvent.findFirst({
where: {
OR: [
{
// qualifyingPeriodStartAt is less than current date
qualifyingPeriodStartAt: { lte: date },
// qualifyingPeriodStartAt is less than current date
qualifyingPeriodStartAt: { lte: date },
// qualifyingPeriodCloseAt is greater than current date
qualifyingPeriodCloseAt: { gte: date },
},
{
// competitionStartAt is less than current date
competitionStartAt: { lte: date },
// competitionCloseAt is greater than current date
competitionCloseAt: { gte: date },
},
{
// competitionCloseAt is less than current date
competitionCloseAt: { lte: date },
// competitionEndAt is greater than current date
competitionEndAt: {gte: date },
}
],
// competitionEndAt is greater than current date
competitionEndAt: { gte: date },
},
orderBy: [
{

View File

@ -0,0 +1,52 @@
export async function getArea(path: number)
{
let area = 0;
if(path >= 0 && path <= 9){ // GID_PATH_C1
area = Number(0);
}
else if(path >= 10 && path <= 15){ // GID_PATH_N9
area = Number(1);
}
else if(path >= 16 && path <= 17){ // GID_PATH_WTEAST
area = Number(2);
}
else if(path >= 18 && path <= 19){ // GID_PATH_WT_UP_DOWN
area = Number(3);
}
else if(path >= 20 && path <= 26){ // GID_PATH_WG
area = Number(4);
}
else if(path >= 27 && path <= 33){ // GID_PATH_KG
area = Number(5);
}
else if(path >= 34 && path <= 37){ // GID_PATH_YS
area = Number(6);
}
else if(path >= 38 && path <= 48){ // GID_PATH_KG_SHINYAMASHITA_MINATOMIRAI
area = Number(7);
}
else if(path === 49){ // GID_PATH_NGR
area = Number(8);
}
else if(path >= 50 && path <= 53){ // GID_PATH_OS
area = Number(9);
}
else if(path >= 54 && path <= 55){ // GID_PATH_KB
area = Number(10);
}
else if(path >= 58 && path <= 61){ // GID_PATH_FK
area = Number(11);
}
else if(path >= 62 && path <= 63){ // GID_PATH_HK
area = Number(12);
}
else if(path >= 64 && path <= 65){ // GID_PATH_TP
area = Number(13);
}
else if(path >= 56 && path <= 57){ // GID_PATH_HS
area = Number(18);
}
return { area }
}