mirror of
https://github.com/shiroikitsu8/Bayshore_6r_legacy.git
synced 2024-09-24 01:28:19 +02:00
6R
This commit is contained in:
parent
16232c0083
commit
b0b8bec0d6
19
README.md
19
README.md
@ -1,5 +1,20 @@
|
||||
# Bayshore
|
||||
Wangan Midnight Maximum Tune 6 server reimplementation written in TypeScript
|
||||
### THIS PROJECT IS CURRENTLY UNSUPPORTED. DO NOT MESSAGE ANYONE FOR HELP
|
||||
|
||||
# Bayshore 6R
|
||||
Wangan Midnight Maximum Tune 6R server reimplementation written in TypeScript
|
||||
|
||||
this repo is based on the original repo (https://github.com/ProjectAsakura/Bayshore)
|
||||
|
||||
## What is working
|
||||
- Same like 6
|
||||
- VSORG [Expedition] (some of them maybe... expedition saving works)
|
||||
- Highway [New Mode] (some of them maybe... highway saving works)
|
||||
- Ghost Trophies Saving
|
||||
|
||||
## What is not working
|
||||
- Transfer from 6
|
||||
|
||||
- Wanted Info for each area (game will crash... idk why)
|
||||
|
||||
## Credits
|
||||
This software is part of [Project Asakura](https://github.com/ProjectAsakura).
|
||||
|
@ -10,9 +10,8 @@
|
||||
"grantFullTuneTicketToNewUsers": 5,
|
||||
"giftCarsFullyTuned": 0,
|
||||
"scratchEnabled": 1,
|
||||
"scratchType": 1,
|
||||
"scratchType": 0,
|
||||
"giveMeterReward": 0,
|
||||
"newCardsBanned": 0,
|
||||
"enableScreenshot": 0
|
||||
"newCardsBanned": 0
|
||||
}
|
||||
}
|
@ -20,18 +20,11 @@
|
||||
"typescript": "^4.7.4"
|
||||
},
|
||||
"dependencies": {
|
||||
"@opentelemetry/api": "^1.3.0",
|
||||
"@opentelemetry/auto-instrumentations-node": "^0.35.0",
|
||||
"@opentelemetry/exporter-metrics-otlp-grpc": "^0.34.0",
|
||||
"@opentelemetry/exporter-trace-otlp-grpc": "^0.34.0",
|
||||
"@opentelemetry/sdk-metrics": "^1.8.0",
|
||||
"@opentelemetry/sdk-node": "^0.34.0",
|
||||
"@opentelemetry/semantic-conventions": "^1.8.0",
|
||||
"@prisma/client": "^4.0.0",
|
||||
"@sentry/node": "^7.7.0",
|
||||
"@sentry/tracing": "^7.7.0",
|
||||
"@types/pem": "^1.9.6",
|
||||
"body-parser": "^1.20.1",
|
||||
"body-parser": "^1.20.0",
|
||||
"dotenv": "^16.0.1",
|
||||
"express": "^4.18.1",
|
||||
"form-urlencoded": "^6.0.6",
|
||||
|
@ -1,150 +0,0 @@
|
||||
-- CreateTable
|
||||
CREATE TABLE "User" (
|
||||
"id" SERIAL NOT NULL,
|
||||
"chipId" TEXT NOT NULL,
|
||||
"accessCode" TEXT NOT NULL,
|
||||
"tutorials" BOOLEAN[],
|
||||
"userBanned" BOOLEAN NOT NULL DEFAULT false,
|
||||
|
||||
CONSTRAINT "User_pkey" PRIMARY KEY ("id")
|
||||
);
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE "UserItem" (
|
||||
"dbId" SERIAL NOT NULL,
|
||||
"category" INTEGER NOT NULL,
|
||||
"itemId" INTEGER NOT NULL,
|
||||
"userId" INTEGER NOT NULL,
|
||||
|
||||
CONSTRAINT "UserItem_pkey" PRIMARY KEY ("dbId")
|
||||
);
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE "Car" (
|
||||
"userId" INTEGER NOT NULL,
|
||||
"carId" SERIAL NOT NULL,
|
||||
"name" TEXT NOT NULL,
|
||||
"manufacturer" INTEGER NOT NULL,
|
||||
"model" INTEGER NOT NULL,
|
||||
"visualModel" INTEGER NOT NULL,
|
||||
"customColor" INTEGER NOT NULL DEFAULT 0,
|
||||
"defaultColor" INTEGER NOT NULL,
|
||||
"wheel" INTEGER NOT NULL DEFAULT 0,
|
||||
"wheelColor" INTEGER NOT NULL DEFAULT 0,
|
||||
"aero" INTEGER NOT NULL DEFAULT 0,
|
||||
"bonnet" INTEGER NOT NULL DEFAULT 0,
|
||||
"wing" INTEGER NOT NULL DEFAULT 0,
|
||||
"mirror" INTEGER NOT NULL DEFAULT 0,
|
||||
"neon" INTEGER NOT NULL DEFAULT 0,
|
||||
"trunk" INTEGER NOT NULL DEFAULT 0,
|
||||
"plate" INTEGER NOT NULL DEFAULT 0,
|
||||
"plateColor" INTEGER NOT NULL DEFAULT 0,
|
||||
"plateNumber" INTEGER NOT NULL DEFAULT 0,
|
||||
"tunePower" INTEGER NOT NULL DEFAULT 0,
|
||||
"tuneHandling" INTEGER NOT NULL DEFAULT 0,
|
||||
"title" TEXT NOT NULL DEFAULT 'New Car',
|
||||
"level" INTEGER NOT NULL DEFAULT 0,
|
||||
"windowSticker" BOOLEAN NOT NULL DEFAULT false,
|
||||
"windowStickerString" TEXT NOT NULL DEFAULT 'WANGAN',
|
||||
"windowStickerFont" INTEGER NOT NULL DEFAULT 0,
|
||||
"rivalMarker" INTEGER NOT NULL DEFAULT 0,
|
||||
"aura" INTEGER NOT NULL DEFAULT 0,
|
||||
"auraMotif" INTEGER NOT NULL DEFAULT 0,
|
||||
"ghostLevel" INTEGER NOT NULL DEFAULT 1,
|
||||
"tuningPoints" INTEGER NOT NULL DEFAULT 0,
|
||||
"odometer" INTEGER NOT NULL DEFAULT 0,
|
||||
"playCount" INTEGER NOT NULL DEFAULT 0,
|
||||
"earnedCustomColor" BOOLEAN NOT NULL DEFAULT false,
|
||||
"carSettingsDbId" INTEGER NOT NULL,
|
||||
"vsPlayCount" INTEGER NOT NULL DEFAULT 0,
|
||||
"vsBurstCount" INTEGER NOT NULL DEFAULT 0,
|
||||
"vsStarCount" INTEGER NOT NULL DEFAULT 0,
|
||||
"vsCoolOrWild" INTEGER NOT NULL DEFAULT 0,
|
||||
"vsSmoothOrRough" INTEGER NOT NULL DEFAULT 0,
|
||||
"vsTripleStarMedals" INTEGER NOT NULL DEFAULT 0,
|
||||
"vsDoubleStarMedals" INTEGER NOT NULL DEFAULT 0,
|
||||
"vsSingleStarMedals" INTEGER NOT NULL DEFAULT 0,
|
||||
"vsPlainMedals" INTEGER NOT NULL DEFAULT 0,
|
||||
"rgPlayCount" INTEGER NOT NULL DEFAULT 0,
|
||||
"rgWinCount" INTEGER NOT NULL DEFAULT 0,
|
||||
"rgTrophy" INTEGER NOT NULL DEFAULT 0,
|
||||
"rgScore" INTEGER NOT NULL DEFAULT 0,
|
||||
"rgStamp" INTEGER NOT NULL DEFAULT 0,
|
||||
"rgAcquireAllCrowns" BOOLEAN NOT NULL DEFAULT false,
|
||||
"dressupLevel" INTEGER NOT NULL DEFAULT 0,
|
||||
"dressupPoint" INTEGER NOT NULL DEFAULT 0,
|
||||
"stPlayCount" INTEGER NOT NULL DEFAULT 0,
|
||||
"stClearBits" INTEGER NOT NULL DEFAULT 0,
|
||||
"stClearDivCount" INTEGER NOT NULL DEFAULT 0,
|
||||
"stClearCount" INTEGER NOT NULL DEFAULT 0,
|
||||
"stLoseBits" INTEGER NOT NULL DEFAULT 0,
|
||||
"stConsecutiveWins" INTEGER NOT NULL DEFAULT 0,
|
||||
"stConsecutiveWinsMax" INTEGER NOT NULL DEFAULT 0,
|
||||
"stCompleted100Episodes" BOOLEAN NOT NULL DEFAULT false,
|
||||
"carStateDbId" INTEGER NOT NULL,
|
||||
|
||||
CONSTRAINT "Car_pkey" PRIMARY KEY ("carId")
|
||||
);
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE "CarItem" (
|
||||
"carId" INTEGER NOT NULL,
|
||||
"category" INTEGER NOT NULL,
|
||||
"itemId" INTEGER NOT NULL,
|
||||
"amount" INTEGER NOT NULL
|
||||
);
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE "CarSettings" (
|
||||
"dbId" SERIAL NOT NULL,
|
||||
"view" BOOLEAN NOT NULL DEFAULT true,
|
||||
"transmission" BOOLEAN NOT NULL DEFAULT false,
|
||||
"retire" BOOLEAN NOT NULL DEFAULT false,
|
||||
"meter" INTEGER NOT NULL DEFAULT 0,
|
||||
"navigationMap" BOOLEAN NOT NULL DEFAULT true,
|
||||
"volume" INTEGER NOT NULL DEFAULT 1,
|
||||
"bgm" INTEGER NOT NULL DEFAULT 0,
|
||||
"nameplate" INTEGER NOT NULL DEFAULT 0,
|
||||
"nameplateColor" INTEGER NOT NULL DEFAULT 0,
|
||||
"terminalBackground" INTEGER NOT NULL DEFAULT 0,
|
||||
|
||||
CONSTRAINT "CarSettings_pkey" PRIMARY KEY ("dbId")
|
||||
);
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE "CarState" (
|
||||
"dbId" SERIAL NOT NULL,
|
||||
"hasOpponentGhost" BOOLEAN NOT NULL DEFAULT false,
|
||||
"eventJoined" BOOLEAN NOT NULL DEFAULT false,
|
||||
"transferred" BOOLEAN NOT NULL DEFAULT false,
|
||||
"toBeDeleted" BOOLEAN NOT NULL DEFAULT false,
|
||||
|
||||
CONSTRAINT "CarState_pkey" PRIMARY KEY ("dbId")
|
||||
);
|
||||
|
||||
-- CreateIndex
|
||||
CREATE UNIQUE INDEX "User_chipId_key" ON "User"("chipId");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE UNIQUE INDEX "Car_carSettingsDbId_key" ON "Car"("carSettingsDbId");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE UNIQUE INDEX "Car_carStateDbId_key" ON "Car"("carStateDbId");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE UNIQUE INDEX "CarItem_carId_key" ON "CarItem"("carId");
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "UserItem" ADD CONSTRAINT "UserItem_userId_fkey" FOREIGN KEY ("userId") REFERENCES "User"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "Car" ADD CONSTRAINT "Car_userId_fkey" FOREIGN KEY ("userId") REFERENCES "User"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "Car" ADD CONSTRAINT "Car_carSettingsDbId_fkey" FOREIGN KEY ("carSettingsDbId") REFERENCES "CarSettings"("dbId") ON DELETE RESTRICT ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "Car" ADD CONSTRAINT "Car_carStateDbId_fkey" FOREIGN KEY ("carStateDbId") REFERENCES "CarState"("dbId") ON DELETE RESTRICT ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "CarItem" ADD CONSTRAINT "CarItem_carId_fkey" FOREIGN KEY ("carId") REFERENCES "Car"("carId") ON DELETE RESTRICT ON UPDATE CASCADE;
|
@ -1,20 +0,0 @@
|
||||
-- CreateTable
|
||||
CREATE TABLE "TimeAttackRecord" (
|
||||
"dbId" SERIAL NOT NULL,
|
||||
"userId" INTEGER NOT NULL,
|
||||
"model" INTEGER NOT NULL,
|
||||
"time" INTEGER NOT NULL,
|
||||
"course" INTEGER NOT NULL,
|
||||
"section1Time" INTEGER NOT NULL,
|
||||
"section2Time" INTEGER NOT NULL,
|
||||
"section3Time" INTEGER NOT NULL,
|
||||
"section4Time" INTEGER NOT NULL,
|
||||
"section5Time" INTEGER,
|
||||
"section6Time" INTEGER,
|
||||
"section7Time" INTEGER,
|
||||
|
||||
CONSTRAINT "TimeAttackRecord_pkey" PRIMARY KEY ("dbId")
|
||||
);
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "TimeAttackRecord" ADD CONSTRAINT "TimeAttackRecord_userId_fkey" FOREIGN KEY ("userId") REFERENCES "User"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
|
@ -1,8 +0,0 @@
|
||||
/*
|
||||
Warnings:
|
||||
|
||||
- Added the required column `isMorning` to the `TimeAttackRecord` table without a default value. This is not possible if the table is not empty.
|
||||
|
||||
*/
|
||||
-- AlterTable
|
||||
ALTER TABLE "TimeAttackRecord" ADD COLUMN "isMorning" BOOLEAN NOT NULL;
|
@ -1,16 +0,0 @@
|
||||
/*
|
||||
Warnings:
|
||||
|
||||
- You are about to drop the column `userId` on the `TimeAttackRecord` table. All the data in the column will be lost.
|
||||
- Added the required column `carId` to the `TimeAttackRecord` table without a default value. This is not possible if the table is not empty.
|
||||
|
||||
*/
|
||||
-- DropForeignKey
|
||||
ALTER TABLE "TimeAttackRecord" DROP CONSTRAINT "TimeAttackRecord_userId_fkey";
|
||||
|
||||
-- AlterTable
|
||||
ALTER TABLE "TimeAttackRecord" DROP COLUMN "userId",
|
||||
ADD COLUMN "carId" INTEGER NOT NULL;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "TimeAttackRecord" ADD CONSTRAINT "TimeAttackRecord_carId_fkey" FOREIGN KEY ("carId") REFERENCES "Car"("carId") ON DELETE RESTRICT ON UPDATE CASCADE;
|
@ -1,2 +0,0 @@
|
||||
-- AlterTable
|
||||
ALTER TABLE "Car" ADD COLUMN "regionId" INTEGER NOT NULL DEFAULT 0;
|
@ -1,3 +0,0 @@
|
||||
-- AlterTable
|
||||
ALTER TABLE "Car" ALTER COLUMN "stLoseBits" SET DEFAULT 0,
|
||||
ALTER COLUMN "stLoseBits" SET DATA TYPE BIGINT;
|
@ -1,9 +0,0 @@
|
||||
-- DropIndex
|
||||
DROP INDEX "CarItem_carId_key";
|
||||
|
||||
-- AlterTable
|
||||
ALTER TABLE "Car" ALTER COLUMN "stLoseBits" SET DEFAULT 0;
|
||||
|
||||
-- AlterTable
|
||||
ALTER TABLE "CarItem" ADD COLUMN "dbId" SERIAL NOT NULL,
|
||||
ADD CONSTRAINT "CarItem_pkey" PRIMARY KEY ("dbId");
|
@ -1,12 +0,0 @@
|
||||
-- AlterTable
|
||||
ALTER TABLE "Car" ALTER COLUMN "stLoseBits" SET DEFAULT 0;
|
||||
|
||||
-- AlterTable
|
||||
ALTER TABLE "TimeAttackRecord" ADD COLUMN "tuneHandling" INTEGER NOT NULL DEFAULT 0,
|
||||
ADD COLUMN "tunePower" INTEGER NOT NULL DEFAULT 0;
|
||||
|
||||
-- AlterTable
|
||||
ALTER TABLE "User" ADD COLUMN "bookmarks" INTEGER[],
|
||||
ADD COLUMN "carOrder" INTEGER[],
|
||||
ADD COLUMN "currentSheet" INTEGER NOT NULL DEFAULT 0,
|
||||
ADD COLUMN "lastSheet" INTEGER NOT NULL DEFAULT 0;
|
@ -1,3 +0,0 @@
|
||||
-- AlterTable
|
||||
ALTER TABLE "Car" ADD COLUMN "rgRegionMapScore" INTEGER[],
|
||||
ALTER COLUMN "stLoseBits" SET DEFAULT 0;
|
@ -1,2 +0,0 @@
|
||||
-- AlterTable
|
||||
ALTER TABLE "Car" ALTER COLUMN "stLoseBits" SET DEFAULT 0;
|
@ -1,50 +0,0 @@
|
||||
/*
|
||||
Warnings:
|
||||
|
||||
- You are about to drop the column `lastSheet` on the `User` table. All the data in the column will be lost.
|
||||
- The primary key for the `UserItem` table will be changed. If it partially fails, the table could be left without primary key constraint.
|
||||
- You are about to drop the column `dbId` on the `UserItem` table. All the data in the column will be lost.
|
||||
|
||||
*/
|
||||
-- AlterTable
|
||||
ALTER TABLE "Car" ADD COLUMN "lastPlayedAt" INTEGER NOT NULL DEFAULT 0,
|
||||
ALTER COLUMN "stLoseBits" SET DEFAULT 0;
|
||||
|
||||
-- AlterTable
|
||||
ALTER TABLE "User" DROP COLUMN "lastSheet",
|
||||
ADD COLUMN "lastScratched" INTEGER NOT NULL DEFAULT 0,
|
||||
ALTER COLUMN "currentSheet" SET DEFAULT 1;
|
||||
|
||||
-- AlterTable
|
||||
ALTER TABLE "UserItem" DROP CONSTRAINT "UserItem_pkey",
|
||||
DROP COLUMN "dbId",
|
||||
ADD COLUMN "earnedAt" INTEGER NOT NULL DEFAULT 0,
|
||||
ADD COLUMN "type" INTEGER NOT NULL DEFAULT 0,
|
||||
ADD COLUMN "userItemId" SERIAL NOT NULL,
|
||||
ADD CONSTRAINT "UserItem_pkey" PRIMARY KEY ("userItemId");
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE "ScratchSheet" (
|
||||
"id" SERIAL NOT NULL,
|
||||
"userId" INTEGER NOT NULL,
|
||||
"sheetNo" INTEGER NOT NULL,
|
||||
|
||||
CONSTRAINT "ScratchSheet_pkey" PRIMARY KEY ("id")
|
||||
);
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE "ScratchSquare" (
|
||||
"id" SERIAL NOT NULL,
|
||||
"sheetId" INTEGER NOT NULL,
|
||||
"category" INTEGER NOT NULL,
|
||||
"itemId" INTEGER NOT NULL,
|
||||
"earned" BOOLEAN NOT NULL,
|
||||
|
||||
CONSTRAINT "ScratchSquare_pkey" PRIMARY KEY ("id")
|
||||
);
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "ScratchSheet" ADD CONSTRAINT "ScratchSheet_userId_fkey" FOREIGN KEY ("userId") REFERENCES "User"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "ScratchSquare" ADD CONSTRAINT "ScratchSquare_sheetId_fkey" FOREIGN KEY ("sheetId") REFERENCES "ScratchSheet"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
|
@ -1,22 +0,0 @@
|
||||
-- AlterTable
|
||||
ALTER TABLE "Car" ALTER COLUMN "stLoseBits" SET DEFAULT 0;
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE "CarGTWing" (
|
||||
"dbId" SERIAL NOT NULL,
|
||||
"carId" INTEGER NOT NULL,
|
||||
"pillar" INTEGER NOT NULL DEFAULT 0,
|
||||
"pillarMaterial" INTEGER NOT NULL DEFAULT 0,
|
||||
"mainWing" INTEGER NOT NULL DEFAULT 0,
|
||||
"mainWingColor" INTEGER NOT NULL DEFAULT 0,
|
||||
"wingTip" INTEGER NOT NULL DEFAULT 0,
|
||||
"material" INTEGER NOT NULL DEFAULT 0,
|
||||
|
||||
CONSTRAINT "CarGTWing_pkey" PRIMARY KEY ("dbId")
|
||||
);
|
||||
|
||||
-- CreateIndex
|
||||
CREATE UNIQUE INDEX "CarGTWing_carId_key" ON "CarGTWing"("carId");
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "CarGTWing" ADD CONSTRAINT "CarGTWing_carId_fkey" FOREIGN KEY ("carId") REFERENCES "Car"("carId") ON DELETE RESTRICT ON UPDATE CASCADE;
|
@ -1,3 +0,0 @@
|
||||
-- AlterTable
|
||||
ALTER TABLE "Car" ADD COLUMN "windowDecoration" INTEGER NOT NULL DEFAULT 0,
|
||||
ALTER COLUMN "stLoseBits" SET DEFAULT 0;
|
@ -1,26 +0,0 @@
|
||||
/*
|
||||
Warnings:
|
||||
|
||||
- You are about to drop the column `carId` on the `CarGTWing` table. All the data in the column will be lost.
|
||||
- A unique constraint covering the columns `[carGTWingDbId]` on the table `Car` will be added. If there are existing duplicate values, this will fail.
|
||||
- Added the required column `carGTWingDbId` to the `Car` table without a default value. This is not possible if the table is not empty.
|
||||
|
||||
*/
|
||||
-- DropForeignKey
|
||||
ALTER TABLE "CarGTWing" DROP CONSTRAINT "CarGTWing_carId_fkey";
|
||||
|
||||
-- DropIndex
|
||||
DROP INDEX "CarGTWing_carId_key";
|
||||
|
||||
-- AlterTable
|
||||
ALTER TABLE "Car" ADD COLUMN "carGTWingDbId" INTEGER NOT NULL,
|
||||
ALTER COLUMN "stLoseBits" SET DEFAULT 0;
|
||||
|
||||
-- AlterTable
|
||||
ALTER TABLE "CarGTWing" DROP COLUMN "carId";
|
||||
|
||||
-- CreateIndex
|
||||
CREATE UNIQUE INDEX "Car_carGTWingDbId_key" ON "Car"("carGTWingDbId");
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "Car" ADD CONSTRAINT "Car_carGTWingDbId_fkey" FOREIGN KEY ("carGTWingDbId") REFERENCES "CarGTWing"("dbId") ON DELETE RESTRICT ON UPDATE CASCADE;
|
@ -1,17 +0,0 @@
|
||||
-- AlterTable
|
||||
ALTER TABLE "Car" ALTER COLUMN "stLoseBits" SET DEFAULT 0;
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE "CarCrown" (
|
||||
"dbId" SERIAL NOT NULL,
|
||||
"carId" INTEGER NOT NULL,
|
||||
"area" INTEGER NOT NULL,
|
||||
"ramp" INTEGER NOT NULL,
|
||||
"path" INTEGER NOT NULL,
|
||||
"trail" BIGINT NOT NULL DEFAULT 0,
|
||||
|
||||
CONSTRAINT "CarCrown_pkey" PRIMARY KEY ("dbId")
|
||||
);
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "CarCrown" ADD CONSTRAINT "CarCrown_carId_fkey" FOREIGN KEY ("carId") REFERENCES "Car"("carId") ON DELETE RESTRICT ON UPDATE CASCADE;
|
@ -1,14 +0,0 @@
|
||||
/*
|
||||
Warnings:
|
||||
|
||||
- A unique constraint covering the columns `[area]` on the table `CarCrown` will be added. If there are existing duplicate values, this will fail.
|
||||
|
||||
*/
|
||||
-- AlterTable
|
||||
ALTER TABLE "Car" ALTER COLUMN "stLoseBits" SET DEFAULT 0;
|
||||
|
||||
-- AlterTable
|
||||
ALTER TABLE "CarCrown" ALTER COLUMN "trail" SET DEFAULT 0;
|
||||
|
||||
-- CreateIndex
|
||||
CREATE UNIQUE INDEX "CarCrown_area_key" ON "CarCrown"("area");
|
@ -1,6 +0,0 @@
|
||||
-- AlterTable
|
||||
ALTER TABLE "Car" ALTER COLUMN "stLoseBits" SET DEFAULT 0;
|
||||
|
||||
-- AlterTable
|
||||
ALTER TABLE "CarCrown" ADD COLUMN "playedAt" INTEGER NOT NULL DEFAULT 0,
|
||||
ALTER COLUMN "trail" SET DEFAULT 0;
|
@ -1,14 +0,0 @@
|
||||
/*
|
||||
Warnings:
|
||||
|
||||
- Added the required column `tuneHandling` to the `CarCrown` table without a default value. This is not possible if the table is not empty.
|
||||
- Added the required column `tunePower` to the `CarCrown` 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 "CarCrown" ADD COLUMN "tuneHandling" INTEGER NOT NULL,
|
||||
ADD COLUMN "tunePower" INTEGER NOT NULL,
|
||||
ALTER COLUMN "trail" SET DEFAULT 0;
|
@ -1,26 +0,0 @@
|
||||
-- AlterTable
|
||||
ALTER TABLE "Car" ALTER COLUMN "stLoseBits" SET DEFAULT 0;
|
||||
|
||||
-- AlterTable
|
||||
ALTER TABLE "CarCrown" ALTER COLUMN "trail" DROP DEFAULT;
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE "GhostTrail" (
|
||||
"dbId" SERIAL NOT NULL,
|
||||
"carId" INTEGER NOT NULL,
|
||||
"area" INTEGER NOT NULL,
|
||||
"ramp" INTEGER NOT NULL,
|
||||
"path" INTEGER NOT NULL,
|
||||
"trail" BYTEA NOT NULL,
|
||||
"time" INTEGER,
|
||||
"driveData" BYTEA,
|
||||
"trendBinaryByArea" BYTEA,
|
||||
"tunePower" INTEGER NOT NULL,
|
||||
"tuneHandling" INTEGER NOT NULL,
|
||||
"playedAt" INTEGER NOT NULL,
|
||||
|
||||
CONSTRAINT "GhostTrail_pkey" PRIMARY KEY ("dbId")
|
||||
);
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "GhostTrail" ADD CONSTRAINT "GhostTrail_carId_fkey" FOREIGN KEY ("carId") REFERENCES "Car"("carId") ON DELETE RESTRICT ON UPDATE CASCADE;
|
@ -1,11 +0,0 @@
|
||||
/*
|
||||
Warnings:
|
||||
|
||||
- Added the required column `crownBattle` to the `GhostTrail` 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 "GhostTrail" ADD COLUMN "crownBattle" BOOLEAN NOT NULL;
|
@ -1,13 +0,0 @@
|
||||
/*
|
||||
Warnings:
|
||||
|
||||
- You are about to drop the column `tuneHandling` on the `GhostTrail` table. All the data in the column will be lost.
|
||||
- You are about to drop the column `tunePower` on the `GhostTrail` table. All the data in the column will be lost.
|
||||
|
||||
*/
|
||||
-- AlterTable
|
||||
ALTER TABLE "Car" ALTER COLUMN "stLoseBits" SET DEFAULT 0;
|
||||
|
||||
-- AlterTable
|
||||
ALTER TABLE "GhostTrail" DROP COLUMN "tuneHandling",
|
||||
DROP COLUMN "tunePower";
|
@ -1,11 +0,0 @@
|
||||
/*
|
||||
Warnings:
|
||||
|
||||
- You are about to drop the column `trail` on the `CarCrown` table. All the data in the column will be lost.
|
||||
|
||||
*/
|
||||
-- AlterTable
|
||||
ALTER TABLE "Car" ALTER COLUMN "stLoseBits" SET DEFAULT 0;
|
||||
|
||||
-- AlterTable
|
||||
ALTER TABLE "CarCrown" DROP COLUMN "trail";
|
@ -1,9 +0,0 @@
|
||||
-- AlterTable
|
||||
ALTER TABLE "Car" ALTER COLUMN "stLoseBits" SET DEFAULT 0;
|
||||
|
||||
-- AlterTable
|
||||
ALTER TABLE "GhostTrail" ADD COLUMN "byAreaMergeSerial" INTEGER,
|
||||
ADD COLUMN "byCarMergeSerial" INTEGER,
|
||||
ADD COLUMN "byUserMergeSerial" INTEGER,
|
||||
ADD COLUMN "trendBinaryByCar" BYTEA,
|
||||
ADD COLUMN "trendBinaryByUser" BYTEA;
|
@ -1,5 +0,0 @@
|
||||
-- AlterTable
|
||||
ALTER TABLE "Car" ALTER COLUMN "stLoseBits" SET DEFAULT 0;
|
||||
|
||||
-- AlterTable
|
||||
ALTER TABLE "GhostTrail" ADD COLUMN "driveDMergeSerial" INTEGER;
|
@ -1,8 +0,0 @@
|
||||
-- AlterTable
|
||||
ALTER TABLE "Car" ALTER COLUMN "stLoseBits" SET DEFAULT 0;
|
||||
|
||||
-- AlterTable
|
||||
ALTER TABLE "GhostTrail" ADD COLUMN "tuneHandling" INTEGER NOT NULL DEFAULT 0,
|
||||
ADD COLUMN "tunePower" INTEGER NOT NULL DEFAULT 0,
|
||||
ALTER COLUMN "playedAt" SET DEFAULT 0,
|
||||
ALTER COLUMN "crownBattle" SET DEFAULT false;
|
@ -1,30 +0,0 @@
|
||||
-- AlterTable
|
||||
ALTER TABLE "Car" ALTER COLUMN "stLoseBits" SET DEFAULT 0;
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE "GhostBattleRecord" (
|
||||
"dbId" SERIAL NOT NULL,
|
||||
"carId" INTEGER NOT NULL,
|
||||
"tunePower" INTEGER NOT NULL DEFAULT 0,
|
||||
"tuneHandling" INTEGER NOT NULL DEFAULT 0,
|
||||
"opponent1CarId" INTEGER NOT NULL,
|
||||
"opponent1Result" INTEGER NOT NULL,
|
||||
"opponent1TunePower" INTEGER NOT NULL,
|
||||
"opponent1TuneHandling" INTEGER NOT NULL,
|
||||
"opponent2CarId" INTEGER,
|
||||
"opponent2Result" INTEGER,
|
||||
"opponent2TunePower" INTEGER,
|
||||
"opponent2TuneHandling" INTEGER,
|
||||
"opponent3CarId" INTEGER,
|
||||
"opponent3Result" INTEGER,
|
||||
"opponent3TunePower" INTEGER,
|
||||
"opponent3TuneHandling" INTEGER,
|
||||
"area" INTEGER NOT NULL DEFAULT 0,
|
||||
"playedAt" INTEGER NOT NULL DEFAULT 0,
|
||||
"playedShopName" TEXT NOT NULL DEFAULT 'Bayshore',
|
||||
|
||||
CONSTRAINT "GhostBattleRecord_pkey" PRIMARY KEY ("dbId")
|
||||
);
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "GhostBattleRecord" ADD CONSTRAINT "GhostBattleRecord_carId_fkey" FOREIGN KEY ("carId") REFERENCES "Car"("carId") ON DELETE RESTRICT ON UPDATE CASCADE;
|
@ -1,18 +0,0 @@
|
||||
-- AlterTable
|
||||
ALTER TABLE "Car" ALTER COLUMN "stLoseBits" SET DEFAULT 0;
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE "CarPathandTuning" (
|
||||
"dbId" SERIAL NOT NULL,
|
||||
"carId" INTEGER NOT NULL,
|
||||
"area" INTEGER NOT NULL DEFAULT 0,
|
||||
"ramp" INTEGER NOT NULL DEFAULT 0,
|
||||
"path" INTEGER NOT NULL DEFAULT 0,
|
||||
"tunePower" INTEGER NOT NULL DEFAULT 17,
|
||||
"tuneHandling" INTEGER NOT NULL DEFAULT 17,
|
||||
|
||||
CONSTRAINT "CarPathandTuning_pkey" PRIMARY KEY ("dbId")
|
||||
);
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "CarPathandTuning" ADD CONSTRAINT "CarPathandTuning_carId_fkey" FOREIGN KEY ("carId") REFERENCES "Car"("carId") ON DELETE RESTRICT ON UPDATE CASCADE;
|
@ -1,119 +0,0 @@
|
||||
-- AlterTable
|
||||
ALTER TABLE "Car" ALTER COLUMN "stLoseBits" SET DEFAULT 0;
|
||||
|
||||
-- AlterTable
|
||||
ALTER TABLE "CarState" ADD COLUMN "competitionState" INTEGER NOT NULL DEFAULT 0;
|
||||
|
||||
-- AlterTable
|
||||
ALTER TABLE "GhostBattleRecord" ADD COLUMN "ocmBattle" BOOLEAN NOT NULL DEFAULT false,
|
||||
ADD COLUMN "ocmMainDay" BOOLEAN NOT NULL DEFAULT false;
|
||||
|
||||
-- AlterTable
|
||||
ALTER TABLE "GhostTrail" ADD COLUMN "ocmBattle" BOOLEAN NOT NULL DEFAULT false,
|
||||
ADD COLUMN "ocmMainDay" BOOLEAN NOT NULL DEFAULT false;
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE "OCMEvent" (
|
||||
"dbId" SERIAL NOT NULL,
|
||||
"competitionId" INTEGER NOT NULL,
|
||||
"qualifyingPeriodStartAt" INTEGER NOT NULL,
|
||||
"qualifyingPeriodCloseAt" INTEGER NOT NULL,
|
||||
"competitionStartAt" INTEGER NOT NULL,
|
||||
"competitionCloseAt" INTEGER NOT NULL,
|
||||
"competitionEndAt" INTEGER NOT NULL,
|
||||
"lengthOfPeriod" INTEGER NOT NULL,
|
||||
"lengthOfInterval" INTEGER NOT NULL,
|
||||
"area" INTEGER NOT NULL DEFAULT 0,
|
||||
"minigamePatternId" INTEGER NOT NULL DEFAULT 0,
|
||||
|
||||
CONSTRAINT "OCMEvent_pkey" PRIMARY KEY ("dbId")
|
||||
);
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE "OCMPlayRecord" (
|
||||
"dbId" SERIAL NOT NULL,
|
||||
"carId" INTEGER NOT NULL,
|
||||
"competitionId" INTEGER NOT NULL,
|
||||
"periodId" INTEGER NOT NULL,
|
||||
"brakingPoint" INTEGER,
|
||||
"playedAt" INTEGER NOT NULL DEFAULT 0,
|
||||
|
||||
CONSTRAINT "OCMPlayRecord_pkey" PRIMARY KEY ("dbId")
|
||||
);
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE "OCMTop1Ghost" (
|
||||
"dbId" SERIAL NOT NULL,
|
||||
"carId" INTEGER NOT NULL,
|
||||
"competitionId" INTEGER NOT NULL,
|
||||
"periodId" INTEGER NOT NULL,
|
||||
"result" INTEGER NOT NULL,
|
||||
"tunePower" INTEGER NOT NULL DEFAULT 0,
|
||||
"tuneHandling" INTEGER NOT NULL DEFAULT 0,
|
||||
|
||||
CONSTRAINT "OCMTop1Ghost_pkey" PRIMARY KEY ("dbId")
|
||||
);
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE "OCMTally" (
|
||||
"dbId" SERIAL NOT NULL,
|
||||
"carId" INTEGER NOT NULL,
|
||||
"competitionId" INTEGER NOT NULL,
|
||||
"periodId" INTEGER NOT NULL,
|
||||
"result" INTEGER NOT NULL,
|
||||
"tunePower" INTEGER NOT NULL DEFAULT 0,
|
||||
"tuneHandling" INTEGER NOT NULL DEFAULT 0,
|
||||
|
||||
CONSTRAINT "OCMTally_pkey" PRIMARY KEY ("dbId")
|
||||
);
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE "OCMGhostBattleRecord" (
|
||||
"dbId" SERIAL NOT NULL,
|
||||
"carId" INTEGER NOT NULL,
|
||||
"tunePower" INTEGER NOT NULL DEFAULT 0,
|
||||
"tuneHandling" INTEGER NOT NULL DEFAULT 0,
|
||||
"competitionId" INTEGER NOT NULL,
|
||||
"periodId" INTEGER NOT NULL,
|
||||
"result" INTEGER NOT NULL,
|
||||
"area" INTEGER NOT NULL DEFAULT 0,
|
||||
"playedAt" INTEGER NOT NULL DEFAULT 0,
|
||||
"playedShopName" TEXT NOT NULL DEFAULT 'Bayshore',
|
||||
"ocmMainDraw" BOOLEAN NOT NULL DEFAULT false,
|
||||
|
||||
CONSTRAINT "OCMGhostBattleRecord_pkey" PRIMARY KEY ("dbId")
|
||||
);
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE "OCMGhostTrail" (
|
||||
"dbId" SERIAL NOT NULL,
|
||||
"carId" INTEGER NOT NULL,
|
||||
"area" INTEGER NOT NULL,
|
||||
"ramp" INTEGER NOT NULL,
|
||||
"path" INTEGER NOT NULL,
|
||||
"trail" BYTEA NOT NULL,
|
||||
"competitionId" INTEGER NOT NULL,
|
||||
"periodId" INTEGER NOT NULL,
|
||||
"playedAt" INTEGER NOT NULL DEFAULT 0,
|
||||
"tunePower" INTEGER NOT NULL DEFAULT 0,
|
||||
"tuneHandling" INTEGER NOT NULL DEFAULT 0,
|
||||
"ocmBattle" BOOLEAN NOT NULL DEFAULT false,
|
||||
"ocmMainDraw" BOOLEAN NOT NULL DEFAULT false,
|
||||
|
||||
CONSTRAINT "OCMGhostTrail_pkey" PRIMARY KEY ("dbId")
|
||||
);
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "OCMPlayRecord" ADD CONSTRAINT "OCMPlayRecord_carId_fkey" FOREIGN KEY ("carId") REFERENCES "Car"("carId") ON DELETE RESTRICT ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "OCMTop1Ghost" ADD CONSTRAINT "OCMTop1Ghost_carId_fkey" FOREIGN KEY ("carId") REFERENCES "Car"("carId") ON DELETE RESTRICT ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "OCMTally" ADD CONSTRAINT "OCMTally_carId_fkey" FOREIGN KEY ("carId") REFERENCES "Car"("carId") ON DELETE RESTRICT ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "OCMGhostBattleRecord" ADD CONSTRAINT "OCMGhostBattleRecord_carId_fkey" FOREIGN KEY ("carId") REFERENCES "Car"("carId") ON DELETE RESTRICT ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "OCMGhostTrail" ADD CONSTRAINT "OCMGhostTrail_carId_fkey" FOREIGN KEY ("carId") REFERENCES "Car"("carId") ON DELETE RESTRICT ON UPDATE CASCADE;
|
@ -1,17 +0,0 @@
|
||||
-- AlterTable
|
||||
ALTER TABLE "Car" ALTER COLUMN "stLoseBits" SET DEFAULT 0;
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE "OCMPeriod" (
|
||||
"dbId" SERIAL NOT NULL,
|
||||
"competitionDbId" INTEGER NOT NULL,
|
||||
"competitionId" INTEGER NOT NULL,
|
||||
"periodId" INTEGER NOT NULL,
|
||||
"startAt" INTEGER NOT NULL,
|
||||
"closeAt" INTEGER NOT NULL,
|
||||
|
||||
CONSTRAINT "OCMPeriod_pkey" PRIMARY KEY ("dbId")
|
||||
);
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "OCMPeriod" ADD CONSTRAINT "OCMPeriod_competitionDbId_fkey" FOREIGN KEY ("competitionDbId") REFERENCES "OCMEvent"("dbId") ON DELETE RESTRICT ON UPDATE CASCADE;
|
@ -1,17 +0,0 @@
|
||||
/*
|
||||
Warnings:
|
||||
|
||||
- You are about to drop the column `ocmBattle` on the `GhostTrail` table. All the data in the column will be lost.
|
||||
- You are about to drop the column `ocmMainDay` on the `GhostTrail` table. All the data in the column will be lost.
|
||||
- You are about to drop the column `ocmBattle` on the `OCMGhostTrail` table. All the data in the column will be lost.
|
||||
|
||||
*/
|
||||
-- AlterTable
|
||||
ALTER TABLE "Car" ALTER COLUMN "stLoseBits" SET DEFAULT 0;
|
||||
|
||||
-- AlterTable
|
||||
ALTER TABLE "GhostTrail" DROP COLUMN "ocmBattle",
|
||||
DROP COLUMN "ocmMainDay";
|
||||
|
||||
-- AlterTable
|
||||
ALTER TABLE "OCMGhostTrail" DROP COLUMN "ocmBattle";
|
@ -1,13 +0,0 @@
|
||||
/*
|
||||
Warnings:
|
||||
|
||||
- You are about to drop the column `ocmBattle` on the `GhostBattleRecord` table. All the data in the column will be lost.
|
||||
- You are about to drop the column `ocmMainDay` on the `GhostBattleRecord` table. All the data in the column will be lost.
|
||||
|
||||
*/
|
||||
-- AlterTable
|
||||
ALTER TABLE "Car" ALTER COLUMN "stLoseBits" SET DEFAULT 0;
|
||||
|
||||
-- AlterTable
|
||||
ALTER TABLE "GhostBattleRecord" DROP COLUMN "ocmBattle",
|
||||
DROP COLUMN "ocmMainDay";
|
@ -1,3 +0,0 @@
|
||||
-- AlterTable
|
||||
ALTER TABLE "Car" ADD COLUMN "country" TEXT NOT NULL DEFAULT 'JPN',
|
||||
ALTER COLUMN "stLoseBits" SET DEFAULT 0;
|
@ -1,15 +0,0 @@
|
||||
-- AlterTable
|
||||
ALTER TABLE "Car" ALTER COLUMN "stLoseBits" SET DEFAULT 0;
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE "GhostRegisteredFromTerminal" (
|
||||
"dbId" SERIAL NOT NULL,
|
||||
"carId" INTEGER NOT NULL,
|
||||
"competitionId" INTEGER,
|
||||
"opponentCarId" INTEGER NOT NULL,
|
||||
|
||||
CONSTRAINT "GhostRegisteredFromTerminal_pkey" PRIMARY KEY ("dbId")
|
||||
);
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "GhostRegisteredFromTerminal" ADD CONSTRAINT "GhostRegisteredFromTerminal_carId_fkey" FOREIGN KEY ("carId") REFERENCES "Car"("carId") ON DELETE RESTRICT ON UPDATE CASCADE;
|
@ -1,35 +0,0 @@
|
||||
-- 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;
|
@ -1,5 +0,0 @@
|
||||
-- AlterTable
|
||||
ALTER TABLE "Car" ALTER COLUMN "stLoseBits" SET DEFAULT 0;
|
||||
|
||||
-- AlterTable
|
||||
ALTER TABLE "CarSettings" ALTER COLUMN "volume" SET DEFAULT 2;
|
@ -1,17 +0,0 @@
|
||||
-- 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;
|
@ -1,17 +0,0 @@
|
||||
/*
|
||||
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;
|
545
prisma/migrations/20220827074507_init/migration.sql
Normal file
545
prisma/migrations/20220827074507_init/migration.sql
Normal file
@ -0,0 +1,545 @@
|
||||
-- CreateTable
|
||||
CREATE TABLE "User" (
|
||||
"id" SERIAL NOT NULL,
|
||||
"chipId" TEXT NOT NULL,
|
||||
"accessCode" TEXT NOT NULL,
|
||||
"carOrder" INTEGER[],
|
||||
"tutorials" BOOLEAN[],
|
||||
"userBanned" BOOLEAN NOT NULL DEFAULT false,
|
||||
"bookmarks" INTEGER[],
|
||||
"currentSheet" INTEGER NOT NULL DEFAULT 1,
|
||||
"lastScratched" INTEGER NOT NULL DEFAULT 0,
|
||||
|
||||
CONSTRAINT "User_pkey" PRIMARY KEY ("id")
|
||||
);
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE "ScratchSheet" (
|
||||
"id" SERIAL NOT NULL,
|
||||
"userId" INTEGER NOT NULL,
|
||||
"sheetNo" INTEGER NOT NULL,
|
||||
|
||||
CONSTRAINT "ScratchSheet_pkey" PRIMARY KEY ("id")
|
||||
);
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE "ScratchSquare" (
|
||||
"id" SERIAL NOT NULL,
|
||||
"sheetId" INTEGER NOT NULL,
|
||||
"category" INTEGER NOT NULL,
|
||||
"itemId" INTEGER NOT NULL,
|
||||
"earned" BOOLEAN NOT NULL,
|
||||
|
||||
CONSTRAINT "ScratchSquare_pkey" PRIMARY KEY ("id")
|
||||
);
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE "UserItem" (
|
||||
"userItemId" SERIAL NOT NULL,
|
||||
"category" INTEGER NOT NULL,
|
||||
"itemId" INTEGER NOT NULL,
|
||||
"userId" INTEGER NOT NULL,
|
||||
"type" INTEGER NOT NULL DEFAULT 0,
|
||||
"earnedAt" INTEGER NOT NULL DEFAULT 0,
|
||||
|
||||
CONSTRAINT "UserItem_pkey" PRIMARY KEY ("userItemId")
|
||||
);
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE "Car" (
|
||||
"userId" INTEGER NOT NULL,
|
||||
"carId" SERIAL NOT NULL,
|
||||
"name" TEXT NOT NULL,
|
||||
"manufacturer" INTEGER NOT NULL,
|
||||
"model" INTEGER NOT NULL,
|
||||
"visualModel" INTEGER NOT NULL,
|
||||
"customColor" INTEGER NOT NULL DEFAULT 0,
|
||||
"defaultColor" INTEGER NOT NULL,
|
||||
"wheel" INTEGER NOT NULL DEFAULT 0,
|
||||
"wheelColor" INTEGER NOT NULL DEFAULT 0,
|
||||
"aero" INTEGER NOT NULL DEFAULT 0,
|
||||
"bonnet" INTEGER NOT NULL DEFAULT 0,
|
||||
"wing" INTEGER NOT NULL DEFAULT 0,
|
||||
"mirror" INTEGER NOT NULL DEFAULT 0,
|
||||
"neon" INTEGER NOT NULL DEFAULT 0,
|
||||
"trunk" INTEGER NOT NULL DEFAULT 0,
|
||||
"plate" INTEGER NOT NULL DEFAULT 0,
|
||||
"plateColor" INTEGER NOT NULL DEFAULT 0,
|
||||
"plateNumber" INTEGER NOT NULL DEFAULT 0,
|
||||
"tunePower" INTEGER NOT NULL DEFAULT 0,
|
||||
"tuneHandling" INTEGER NOT NULL DEFAULT 0,
|
||||
"title" TEXT NOT NULL DEFAULT 'New Car',
|
||||
"level" INTEGER NOT NULL DEFAULT 0,
|
||||
"windowSticker" BOOLEAN NOT NULL DEFAULT false,
|
||||
"windowStickerString" TEXT NOT NULL DEFAULT 'WANGAN',
|
||||
"windowStickerFont" INTEGER NOT NULL DEFAULT 0,
|
||||
"windowDecoration" INTEGER NOT NULL DEFAULT 0,
|
||||
"rivalMarker" INTEGER NOT NULL DEFAULT 0,
|
||||
"lastPlayedAt" INTEGER NOT NULL DEFAULT 0,
|
||||
"aura" INTEGER NOT NULL DEFAULT 0,
|
||||
"regionId" INTEGER NOT NULL DEFAULT 0,
|
||||
"country" TEXT NOT NULL DEFAULT 'JPN',
|
||||
"tuningPoints" INTEGER NOT NULL DEFAULT 0,
|
||||
"odometer" INTEGER NOT NULL DEFAULT 0,
|
||||
"playCount" INTEGER NOT NULL DEFAULT 0,
|
||||
"earnedCustomColor" BOOLEAN NOT NULL DEFAULT false,
|
||||
"carSettingsDbId" INTEGER NOT NULL,
|
||||
"auraMotif" INTEGER NOT NULL DEFAULT 0,
|
||||
"vsPlayCount" INTEGER NOT NULL DEFAULT 0,
|
||||
"vsBurstCount" INTEGER NOT NULL DEFAULT 0,
|
||||
"vsStarCount" INTEGER NOT NULL DEFAULT 0,
|
||||
"vsStarCountMax" INTEGER NOT NULL DEFAULT 0,
|
||||
"vsCoolOrWild" INTEGER NOT NULL DEFAULT 0,
|
||||
"vsSmoothOrRough" INTEGER NOT NULL DEFAULT 0,
|
||||
"vsTripleStarMedals" INTEGER NOT NULL DEFAULT 0,
|
||||
"vsDoubleStarMedals" INTEGER NOT NULL DEFAULT 0,
|
||||
"vsSingleStarMedals" INTEGER NOT NULL DEFAULT 0,
|
||||
"vsPlainMedals" INTEGER NOT NULL DEFAULT 0,
|
||||
"ghostLevel" INTEGER NOT NULL DEFAULT 1,
|
||||
"rgPlayCount" INTEGER NOT NULL DEFAULT 0,
|
||||
"rgWinCount" INTEGER NOT NULL DEFAULT 0,
|
||||
"rgTrophy" INTEGER NOT NULL DEFAULT 0,
|
||||
"rgScore" INTEGER NOT NULL DEFAULT 0,
|
||||
"rgStamp" INTEGER NOT NULL DEFAULT 0,
|
||||
"rgAcquireAllCrowns" BOOLEAN NOT NULL DEFAULT false,
|
||||
"rgRegionMapScore" INTEGER[],
|
||||
"stampSheetCount" INTEGER NOT NULL DEFAULT 0,
|
||||
"stampSheet" INTEGER[],
|
||||
"dressupLevel" INTEGER NOT NULL DEFAULT 0,
|
||||
"dressupPoint" INTEGER NOT NULL DEFAULT 0,
|
||||
"stPlayCount" INTEGER NOT NULL DEFAULT 0,
|
||||
"stClearBits" INTEGER NOT NULL DEFAULT 0,
|
||||
"stClearDivCount" INTEGER NOT NULL DEFAULT 0,
|
||||
"stClearCount" INTEGER NOT NULL DEFAULT 0,
|
||||
"stLoseBits" BIGINT NOT NULL DEFAULT 0,
|
||||
"stConsecutiveWins" INTEGER NOT NULL DEFAULT 0,
|
||||
"stConsecutiveWinsMax" INTEGER NOT NULL DEFAULT 0,
|
||||
"stCompleted100Episodes" BOOLEAN NOT NULL DEFAULT false,
|
||||
"rgScoreVs_2" INTEGER NOT NULL DEFAULT 0,
|
||||
"rgHighwayClearCount" INTEGER NOT NULL DEFAULT 0,
|
||||
"rgHighwayPoint" INTEGER NOT NULL DEFAULT 0,
|
||||
"rgHighwayStationClearBits" INTEGER NOT NULL DEFAULT 0,
|
||||
"rgHighwayPreviousDice" INTEGER NOT NULL DEFAULT 0,
|
||||
"lastPlayedPlaceId" INTEGER,
|
||||
"carGTWingDbId" INTEGER NOT NULL,
|
||||
"carStateDbId" INTEGER NOT NULL,
|
||||
|
||||
CONSTRAINT "Car_pkey" PRIMARY KEY ("carId")
|
||||
);
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE "CarGTWing" (
|
||||
"dbId" SERIAL NOT NULL,
|
||||
"pillar" INTEGER NOT NULL DEFAULT 0,
|
||||
"pillarMaterial" INTEGER NOT NULL DEFAULT 0,
|
||||
"mainWing" INTEGER NOT NULL DEFAULT 0,
|
||||
"mainWingColor" INTEGER NOT NULL DEFAULT 0,
|
||||
"wingTip" INTEGER NOT NULL DEFAULT 0,
|
||||
"material" INTEGER NOT NULL DEFAULT 0,
|
||||
|
||||
CONSTRAINT "CarGTWing_pkey" PRIMARY KEY ("dbId")
|
||||
);
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE "CarItem" (
|
||||
"dbId" SERIAL NOT NULL,
|
||||
"carId" INTEGER NOT NULL,
|
||||
"category" INTEGER NOT NULL,
|
||||
"itemId" INTEGER NOT NULL,
|
||||
"amount" INTEGER NOT NULL,
|
||||
|
||||
CONSTRAINT "CarItem_pkey" PRIMARY KEY ("dbId")
|
||||
);
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE "CarSettings" (
|
||||
"dbId" SERIAL NOT NULL,
|
||||
"view" BOOLEAN NOT NULL DEFAULT true,
|
||||
"transmission" BOOLEAN NOT NULL DEFAULT false,
|
||||
"retire" BOOLEAN NOT NULL DEFAULT false,
|
||||
"meter" INTEGER NOT NULL DEFAULT 0,
|
||||
"navigationMap" BOOLEAN NOT NULL DEFAULT true,
|
||||
"volume" INTEGER NOT NULL DEFAULT 2,
|
||||
"bgm" INTEGER NOT NULL DEFAULT 0,
|
||||
"nameplate" INTEGER NOT NULL DEFAULT 0,
|
||||
"nameplateColor" INTEGER NOT NULL DEFAULT 0,
|
||||
"terminalBackground" INTEGER NOT NULL DEFAULT 0,
|
||||
|
||||
CONSTRAINT "CarSettings_pkey" PRIMARY KEY ("dbId")
|
||||
);
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE "CarState" (
|
||||
"dbId" SERIAL NOT NULL,
|
||||
"hasOpponentGhost" BOOLEAN NOT NULL DEFAULT false,
|
||||
"eventJoined" BOOLEAN NOT NULL DEFAULT false,
|
||||
"transferred" BOOLEAN NOT NULL DEFAULT false,
|
||||
"toBeDeleted" BOOLEAN NOT NULL DEFAULT false,
|
||||
"competitionState" INTEGER NOT NULL DEFAULT 0,
|
||||
|
||||
CONSTRAINT "CarState_pkey" PRIMARY KEY ("dbId")
|
||||
);
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE "CarPathandTuning" (
|
||||
"dbId" SERIAL NOT NULL,
|
||||
"carId" INTEGER NOT NULL,
|
||||
"area" INTEGER NOT NULL DEFAULT 0,
|
||||
"ramp" INTEGER NOT NULL DEFAULT 0,
|
||||
"path" INTEGER NOT NULL DEFAULT 0,
|
||||
"tunePower" INTEGER NOT NULL DEFAULT 17,
|
||||
"tuneHandling" INTEGER NOT NULL DEFAULT 17,
|
||||
"lastPlayedAt" INTEGER NOT NULL DEFAULT 0,
|
||||
|
||||
CONSTRAINT "CarPathandTuning_pkey" PRIMARY KEY ("dbId")
|
||||
);
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE "CarCrown" (
|
||||
"dbId" SERIAL NOT NULL,
|
||||
"carId" INTEGER NOT NULL,
|
||||
"area" INTEGER NOT NULL,
|
||||
"ramp" INTEGER NOT NULL,
|
||||
"path" INTEGER NOT NULL,
|
||||
"playedAt" INTEGER NOT NULL DEFAULT 0,
|
||||
"tunePower" INTEGER NOT NULL,
|
||||
"tuneHandling" INTEGER NOT NULL,
|
||||
|
||||
CONSTRAINT "CarCrown_pkey" PRIMARY KEY ("dbId")
|
||||
);
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE "TimeAttackRecord" (
|
||||
"dbId" SERIAL NOT NULL,
|
||||
"carId" INTEGER NOT NULL,
|
||||
"model" INTEGER NOT NULL,
|
||||
"time" INTEGER NOT NULL,
|
||||
"course" INTEGER NOT NULL,
|
||||
"isMorning" BOOLEAN NOT NULL,
|
||||
"section1Time" INTEGER NOT NULL,
|
||||
"section2Time" INTEGER NOT NULL,
|
||||
"section3Time" INTEGER NOT NULL,
|
||||
"section4Time" INTEGER NOT NULL,
|
||||
"section5Time" INTEGER,
|
||||
"section6Time" INTEGER,
|
||||
"section7Time" INTEGER,
|
||||
"tunePower" INTEGER NOT NULL DEFAULT 0,
|
||||
"tuneHandling" INTEGER NOT NULL DEFAULT 0,
|
||||
|
||||
CONSTRAINT "TimeAttackRecord_pkey" PRIMARY KEY ("dbId")
|
||||
);
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE "GhostTrail" (
|
||||
"dbId" SERIAL NOT NULL,
|
||||
"carId" INTEGER NOT NULL,
|
||||
"area" INTEGER NOT NULL,
|
||||
"ramp" INTEGER NOT NULL,
|
||||
"path" INTEGER NOT NULL,
|
||||
"trail" BYTEA NOT NULL,
|
||||
"time" INTEGER,
|
||||
"driveData" BYTEA,
|
||||
"driveDMergeSerial" INTEGER,
|
||||
"trendBinaryByUser" BYTEA,
|
||||
"byUserMergeSerial" INTEGER,
|
||||
"trendBinaryByArea" BYTEA,
|
||||
"byAreaMergeSerial" INTEGER,
|
||||
"trendBinaryByCar" BYTEA,
|
||||
"byCarMergeSerial" INTEGER,
|
||||
"playedAt" INTEGER NOT NULL DEFAULT 0,
|
||||
"tunePower" INTEGER NOT NULL DEFAULT 0,
|
||||
"tuneHandling" INTEGER NOT NULL DEFAULT 0,
|
||||
"crownBattle" BOOLEAN NOT NULL DEFAULT false,
|
||||
|
||||
CONSTRAINT "GhostTrail_pkey" PRIMARY KEY ("dbId")
|
||||
);
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE "GhostBattleRecord" (
|
||||
"dbId" SERIAL NOT NULL,
|
||||
"carId" INTEGER NOT NULL,
|
||||
"tunePower" INTEGER NOT NULL DEFAULT 0,
|
||||
"tuneHandling" INTEGER NOT NULL DEFAULT 0,
|
||||
"opponent1CarId" INTEGER NOT NULL,
|
||||
"opponent1Result" INTEGER NOT NULL,
|
||||
"opponent1TunePower" INTEGER NOT NULL,
|
||||
"opponent1TuneHandling" INTEGER NOT NULL,
|
||||
"opponent2CarId" INTEGER,
|
||||
"opponent2Result" INTEGER,
|
||||
"opponent2TunePower" INTEGER,
|
||||
"opponent2TuneHandling" INTEGER,
|
||||
"opponent3CarId" INTEGER,
|
||||
"opponent3Result" INTEGER,
|
||||
"opponent3TunePower" INTEGER,
|
||||
"opponent3TuneHandling" INTEGER,
|
||||
"area" INTEGER NOT NULL DEFAULT 0,
|
||||
"playedAt" INTEGER NOT NULL DEFAULT 0,
|
||||
"playedShopName" TEXT NOT NULL DEFAULT 'Bayshore',
|
||||
|
||||
CONSTRAINT "GhostBattleRecord_pkey" PRIMARY KEY ("dbId")
|
||||
);
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE "OCMEvent" (
|
||||
"dbId" SERIAL NOT NULL,
|
||||
"competitionId" INTEGER NOT NULL,
|
||||
"qualifyingPeriodStartAt" INTEGER NOT NULL,
|
||||
"qualifyingPeriodCloseAt" INTEGER NOT NULL,
|
||||
"competitionStartAt" INTEGER NOT NULL,
|
||||
"competitionCloseAt" INTEGER NOT NULL,
|
||||
"competitionEndAt" INTEGER NOT NULL,
|
||||
"lengthOfPeriod" INTEGER NOT NULL,
|
||||
"lengthOfInterval" INTEGER NOT NULL,
|
||||
"area" INTEGER NOT NULL DEFAULT 0,
|
||||
"minigamePatternId" INTEGER NOT NULL DEFAULT 0,
|
||||
|
||||
CONSTRAINT "OCMEvent_pkey" PRIMARY KEY ("dbId")
|
||||
);
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE "OCMPlayRecord" (
|
||||
"dbId" SERIAL NOT NULL,
|
||||
"carId" INTEGER NOT NULL,
|
||||
"competitionId" INTEGER NOT NULL,
|
||||
"periodId" INTEGER NOT NULL,
|
||||
"brakingPoint" INTEGER,
|
||||
"playedAt" INTEGER NOT NULL DEFAULT 0,
|
||||
|
||||
CONSTRAINT "OCMPlayRecord_pkey" PRIMARY KEY ("dbId")
|
||||
);
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE "OCMTop1Ghost" (
|
||||
"dbId" SERIAL NOT NULL,
|
||||
"carId" INTEGER NOT NULL,
|
||||
"competitionId" INTEGER NOT NULL,
|
||||
"periodId" INTEGER NOT NULL,
|
||||
"result" INTEGER NOT NULL,
|
||||
"tunePower" INTEGER NOT NULL DEFAULT 0,
|
||||
"tuneHandling" INTEGER NOT NULL DEFAULT 0,
|
||||
|
||||
CONSTRAINT "OCMTop1Ghost_pkey" PRIMARY KEY ("dbId")
|
||||
);
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE "OCMTop1GhostTrail" (
|
||||
"dbId" SERIAL NOT NULL,
|
||||
"carId" INTEGER NOT NULL,
|
||||
"area" INTEGER NOT NULL,
|
||||
"ramp" INTEGER NOT NULL,
|
||||
"path" INTEGER NOT NULL,
|
||||
"trail" BYTEA NOT NULL,
|
||||
"competitionId" INTEGER NOT NULL,
|
||||
"periodId" INTEGER NOT NULL,
|
||||
"playedAt" INTEGER NOT NULL DEFAULT 0,
|
||||
"tunePower" INTEGER NOT NULL DEFAULT 0,
|
||||
"tuneHandling" INTEGER NOT NULL DEFAULT 0,
|
||||
"ocmMainDraw" BOOLEAN NOT NULL DEFAULT false,
|
||||
|
||||
CONSTRAINT "OCMTop1GhostTrail_pkey" PRIMARY KEY ("dbId")
|
||||
);
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE "OCMTally" (
|
||||
"dbId" SERIAL NOT NULL,
|
||||
"carId" INTEGER NOT NULL,
|
||||
"competitionId" INTEGER NOT NULL,
|
||||
"periodId" INTEGER NOT NULL,
|
||||
"result" INTEGER NOT NULL,
|
||||
"tunePower" INTEGER NOT NULL DEFAULT 0,
|
||||
"tuneHandling" INTEGER NOT NULL DEFAULT 0,
|
||||
|
||||
CONSTRAINT "OCMTally_pkey" PRIMARY KEY ("dbId")
|
||||
);
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE "OCMGhostBattleRecord" (
|
||||
"dbId" SERIAL NOT NULL,
|
||||
"carId" INTEGER NOT NULL,
|
||||
"tunePower" INTEGER NOT NULL DEFAULT 0,
|
||||
"tuneHandling" INTEGER NOT NULL DEFAULT 0,
|
||||
"competitionId" INTEGER NOT NULL,
|
||||
"periodId" INTEGER NOT NULL,
|
||||
"result" INTEGER NOT NULL,
|
||||
"area" INTEGER NOT NULL DEFAULT 0,
|
||||
"playedAt" INTEGER NOT NULL DEFAULT 0,
|
||||
"playedShopName" TEXT NOT NULL DEFAULT 'Bayshore',
|
||||
"ocmMainDraw" BOOLEAN NOT NULL DEFAULT false,
|
||||
|
||||
CONSTRAINT "OCMGhostBattleRecord_pkey" PRIMARY KEY ("dbId")
|
||||
);
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE "OCMGhostTrail" (
|
||||
"dbId" SERIAL NOT NULL,
|
||||
"carId" INTEGER NOT NULL,
|
||||
"area" INTEGER NOT NULL,
|
||||
"ramp" INTEGER NOT NULL,
|
||||
"path" INTEGER NOT NULL,
|
||||
"trail" BYTEA NOT NULL,
|
||||
"competitionId" INTEGER NOT NULL,
|
||||
"periodId" INTEGER NOT NULL,
|
||||
"playedAt" INTEGER NOT NULL DEFAULT 0,
|
||||
"tunePower" INTEGER NOT NULL DEFAULT 0,
|
||||
"tuneHandling" INTEGER NOT NULL DEFAULT 0,
|
||||
"ocmMainDraw" BOOLEAN NOT NULL DEFAULT false,
|
||||
|
||||
CONSTRAINT "OCMGhostTrail_pkey" PRIMARY KEY ("dbId")
|
||||
);
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE "OCMPeriod" (
|
||||
"dbId" SERIAL NOT NULL,
|
||||
"competitionDbId" INTEGER NOT NULL,
|
||||
"competitionId" INTEGER NOT NULL,
|
||||
"periodId" INTEGER NOT NULL,
|
||||
"startAt" INTEGER NOT NULL,
|
||||
"closeAt" INTEGER NOT NULL,
|
||||
|
||||
CONSTRAINT "OCMPeriod_pkey" PRIMARY KEY ("dbId")
|
||||
);
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE "GhostRegisteredFromTerminal" (
|
||||
"dbId" SERIAL NOT NULL,
|
||||
"carId" INTEGER NOT NULL,
|
||||
"competitionId" INTEGER,
|
||||
"opponentCarId" INTEGER NOT NULL,
|
||||
|
||||
CONSTRAINT "GhostRegisteredFromTerminal_pkey" PRIMARY KEY ("dbId")
|
||||
);
|
||||
|
||||
-- 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,
|
||||
"lastPlayedAt" INTEGER NOT NULL DEFAULT 0,
|
||||
|
||||
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")
|
||||
);
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE "PlaceList" (
|
||||
"id" SERIAL NOT NULL,
|
||||
"placeId" TEXT NOT NULL,
|
||||
"regionId" INTEGER NOT NULL,
|
||||
"shopName" TEXT NOT NULL,
|
||||
"country" TEXT NOT NULL,
|
||||
|
||||
CONSTRAINT "PlaceList_pkey" PRIMARY KEY ("id")
|
||||
);
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE "GhostExpedition" (
|
||||
"dbId" SERIAL NOT NULL,
|
||||
"carId" INTEGER NOT NULL,
|
||||
"ghostExpeditionId" INTEGER NOT NULL,
|
||||
"sugorokuPoint" INTEGER NOT NULL DEFAULT 0,
|
||||
"earnedScore" INTEGER NOT NULL DEFAULT 0,
|
||||
"score" INTEGER NOT NULL DEFAULT 0,
|
||||
|
||||
CONSTRAINT "GhostExpedition_pkey" PRIMARY KEY ("dbId")
|
||||
);
|
||||
|
||||
-- CreateIndex
|
||||
CREATE UNIQUE INDEX "User_chipId_key" ON "User"("chipId");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE UNIQUE INDEX "Car_carSettingsDbId_key" ON "Car"("carSettingsDbId");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE UNIQUE INDEX "Car_carGTWingDbId_key" ON "Car"("carGTWingDbId");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE UNIQUE INDEX "Car_carStateDbId_key" ON "Car"("carStateDbId");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE UNIQUE INDEX "CarCrown_area_key" ON "CarCrown"("area");
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "ScratchSheet" ADD CONSTRAINT "ScratchSheet_userId_fkey" FOREIGN KEY ("userId") REFERENCES "User"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "ScratchSquare" ADD CONSTRAINT "ScratchSquare_sheetId_fkey" FOREIGN KEY ("sheetId") REFERENCES "ScratchSheet"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "UserItem" ADD CONSTRAINT "UserItem_userId_fkey" FOREIGN KEY ("userId") REFERENCES "User"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "Car" ADD CONSTRAINT "Car_userId_fkey" FOREIGN KEY ("userId") REFERENCES "User"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "Car" ADD CONSTRAINT "Car_carGTWingDbId_fkey" FOREIGN KEY ("carGTWingDbId") REFERENCES "CarGTWing"("dbId") ON DELETE RESTRICT ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "Car" ADD CONSTRAINT "Car_carSettingsDbId_fkey" FOREIGN KEY ("carSettingsDbId") REFERENCES "CarSettings"("dbId") ON DELETE RESTRICT ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "Car" ADD CONSTRAINT "Car_carStateDbId_fkey" FOREIGN KEY ("carStateDbId") REFERENCES "CarState"("dbId") ON DELETE RESTRICT ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "Car" ADD CONSTRAINT "Car_lastPlayedPlaceId_fkey" FOREIGN KEY ("lastPlayedPlaceId") REFERENCES "PlaceList"("id") ON DELETE SET NULL ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "CarItem" ADD CONSTRAINT "CarItem_carId_fkey" FOREIGN KEY ("carId") REFERENCES "Car"("carId") ON DELETE RESTRICT ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "CarPathandTuning" ADD CONSTRAINT "CarPathandTuning_carId_fkey" FOREIGN KEY ("carId") REFERENCES "Car"("carId") ON DELETE RESTRICT ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "CarCrown" ADD CONSTRAINT "CarCrown_carId_fkey" FOREIGN KEY ("carId") REFERENCES "Car"("carId") ON DELETE RESTRICT ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "TimeAttackRecord" ADD CONSTRAINT "TimeAttackRecord_carId_fkey" FOREIGN KEY ("carId") REFERENCES "Car"("carId") ON DELETE RESTRICT ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "GhostTrail" ADD CONSTRAINT "GhostTrail_carId_fkey" FOREIGN KEY ("carId") REFERENCES "Car"("carId") ON DELETE RESTRICT ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "GhostBattleRecord" ADD CONSTRAINT "GhostBattleRecord_carId_fkey" FOREIGN KEY ("carId") REFERENCES "Car"("carId") ON DELETE RESTRICT ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "OCMPlayRecord" ADD CONSTRAINT "OCMPlayRecord_carId_fkey" FOREIGN KEY ("carId") REFERENCES "Car"("carId") ON DELETE RESTRICT ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "OCMTop1Ghost" ADD CONSTRAINT "OCMTop1Ghost_carId_fkey" FOREIGN KEY ("carId") REFERENCES "Car"("carId") ON DELETE RESTRICT ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "OCMTally" ADD CONSTRAINT "OCMTally_carId_fkey" FOREIGN KEY ("carId") REFERENCES "Car"("carId") ON DELETE RESTRICT ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "OCMGhostBattleRecord" ADD CONSTRAINT "OCMGhostBattleRecord_carId_fkey" FOREIGN KEY ("carId") REFERENCES "Car"("carId") ON DELETE RESTRICT ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "OCMGhostTrail" ADD CONSTRAINT "OCMGhostTrail_carId_fkey" FOREIGN KEY ("carId") REFERENCES "Car"("carId") ON DELETE RESTRICT ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "OCMPeriod" ADD CONSTRAINT "OCMPeriod_competitionDbId_fkey" FOREIGN KEY ("competitionDbId") REFERENCES "OCMEvent"("dbId") ON DELETE RESTRICT ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "GhostRegisteredFromTerminal" ADD CONSTRAINT "GhostRegisteredFromTerminal_carId_fkey" FOREIGN KEY ("carId") REFERENCES "Car"("carId") ON DELETE RESTRICT ON UPDATE CASCADE;
|
||||
|
||||
-- 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;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "GhostExpedition" ADD CONSTRAINT "GhostExpedition_carId_fkey" FOREIGN KEY ("carId") REFERENCES "Car"("carId") ON DELETE RESTRICT ON UPDATE CASCADE;
|
File diff suppressed because one or more lines are too long
@ -0,0 +1,5 @@
|
||||
-- AlterTable
|
||||
ALTER TABLE "Car" ALTER COLUMN "stLoseBits" SET DEFAULT 0;
|
||||
|
||||
-- AlterTable
|
||||
ALTER TABLE "GhostExpeditionWantedCar" ADD COLUMN "ghostExpeditionId" INTEGER NOT NULL DEFAULT 1;
|
@ -2,4 +2,4 @@
|
||||
ALTER TABLE "Car" ALTER COLUMN "stLoseBits" SET DEFAULT 0;
|
||||
|
||||
-- AlterTable
|
||||
ALTER TABLE "CarPathandTuning" ADD COLUMN "lastPlayedAt" INTEGER NOT NULL DEFAULT 0;
|
||||
ALTER TABLE "GhostExpeditionWantedCar" ADD COLUMN "area" INTEGER NOT NULL DEFAULT 0;
|
@ -0,0 +1,8 @@
|
||||
-- AlterTable
|
||||
ALTER TABLE "Car" ALTER COLUMN "stLoseBits" SET DEFAULT 0;
|
||||
|
||||
-- AlterTable
|
||||
ALTER TABLE "GhostExpeditionWantedCar" ADD COLUMN "challengerCarId" INTEGER,
|
||||
ADD COLUMN "locked" BOOLEAN NOT NULL DEFAULT false,
|
||||
ALTER COLUMN "numOfHostages" SET DEFAULT 1,
|
||||
ALTER COLUMN "defeatedMeCount" SET DEFAULT 1;
|
@ -0,0 +1,14 @@
|
||||
-- AlterTable
|
||||
ALTER TABLE "Car" ALTER COLUMN "stLoseBits" SET DEFAULT 0;
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE "GhostExpeditionEvent" (
|
||||
"dbId" SERIAL NOT NULL,
|
||||
"ghostExpeditionId" INTEGER NOT NULL,
|
||||
"startAt" INTEGER NOT NULL,
|
||||
"endAt" INTEGER NOT NULL,
|
||||
"aftereventEndAt" INTEGER NOT NULL,
|
||||
"opponentCountry" INTEGER NOT NULL,
|
||||
|
||||
CONSTRAINT "GhostExpeditionEvent_pkey" PRIMARY KEY ("dbId")
|
||||
);
|
@ -2,4 +2,4 @@
|
||||
ALTER TABLE "Car" ALTER COLUMN "stLoseBits" SET DEFAULT 0;
|
||||
|
||||
-- AlterTable
|
||||
ALTER TABLE "CarChallenger" ADD COLUMN "lastPlayedAt" INTEGER NOT NULL DEFAULT 0;
|
||||
ALTER TABLE "GhostExpeditionEvent" ALTER COLUMN "opponentCountry" SET DATA TYPE TEXT;
|
@ -1,3 +0,0 @@
|
||||
-- AlterTable
|
||||
ALTER TABLE "Car" ALTER COLUMN "stLoseBits" SET DEFAULT 0,
|
||||
ALTER COLUMN "regionId" SET DEFAULT 1;
|
@ -0,0 +1,5 @@
|
||||
-- AlterTable
|
||||
ALTER TABLE "Car" ALTER COLUMN "stLoseBits" SET DEFAULT 0;
|
||||
|
||||
-- AlterTable
|
||||
ALTER TABLE "GhostExpeditionWantedCar" ADD COLUMN "lockTime" INTEGER NOT NULL DEFAULT 0;
|
@ -1,5 +0,0 @@
|
||||
-- AlterTable
|
||||
ALTER TABLE "Car" ALTER COLUMN "stLoseBits" SET DEFAULT 0;
|
||||
|
||||
-- AlterTable
|
||||
ALTER TABLE "FileList" ADD COLUMN "filePath" TEXT NOT NULL DEFAULT '';
|
@ -1,6 +1,5 @@
|
||||
-- AlterTable
|
||||
ALTER TABLE "Car" ALTER COLUMN "stLoseBits" SET DEFAULT 0,
|
||||
ALTER COLUMN "regionId" SET DEFAULT 18;
|
||||
ALTER TABLE "Car" ALTER COLUMN "stLoseBits" SET DEFAULT 0;
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE "FileList" (
|
||||
@ -11,6 +10,7 @@ CREATE TABLE "FileList" (
|
||||
"sha1sum" TEXT NOT NULL,
|
||||
"notBefore" INTEGER NOT NULL,
|
||||
"notAfter" INTEGER NOT NULL,
|
||||
"filePath" TEXT NOT NULL,
|
||||
|
||||
CONSTRAINT "FileList_pkey" PRIMARY KEY ("fileId")
|
||||
);
|
@ -86,7 +86,7 @@ model Car {
|
||||
rivalMarker Int @default(0)
|
||||
lastPlayedAt Int @default(0)
|
||||
aura Int @default(0)
|
||||
regionId Int @default(18)
|
||||
regionId Int @default(0)
|
||||
country String @default("JPN")
|
||||
|
||||
// This is more data about the car
|
||||
@ -97,6 +97,7 @@ model Car {
|
||||
carSettingsDbId Int @unique
|
||||
settings CarSettings @relation(fields: [carSettingsDbId], references: [dbId])
|
||||
|
||||
// VS
|
||||
auraMotif Int @default(0)
|
||||
vsPlayCount Int @default(0)
|
||||
vsBurstCount Int @default(0)
|
||||
@ -109,6 +110,7 @@ model Car {
|
||||
vsSingleStarMedals Int @default(0)
|
||||
vsPlainMedals Int @default(0)
|
||||
|
||||
// Ghost
|
||||
ghostLevel Int @default(1)
|
||||
rgPlayCount Int @default(0)
|
||||
rgWinCount Int @default(0)
|
||||
@ -120,9 +122,11 @@ model Car {
|
||||
stampSheetCount Int @default(0)
|
||||
stampSheet Int[]
|
||||
|
||||
// Dress Up
|
||||
dressupLevel Int @default(0)
|
||||
dressupPoint Int @default(0)
|
||||
|
||||
// Story
|
||||
stPlayCount Int @default(0)
|
||||
stClearBits Int @default(0)
|
||||
stClearDivCount Int @default(0)
|
||||
@ -132,6 +136,14 @@ model Car {
|
||||
stConsecutiveWinsMax Int @default(0)
|
||||
stCompleted100Episodes Boolean @default(false)
|
||||
|
||||
// Highway Ghost
|
||||
rgScoreVs_2 Int @default(0)
|
||||
rgHighwayClearCount Int @default(0)
|
||||
rgHighwayPoint Int @default(0)
|
||||
rgHighwayStationClearBits Int @default(0)
|
||||
rgHighwayPreviousDice Int @default(0)
|
||||
|
||||
// Last Played
|
||||
lastPlayedPlaceId Int?
|
||||
lastPlayedPlace PlaceList? @relation(fields: [lastPlayedPlaceId], references: [id])
|
||||
|
||||
@ -153,6 +165,8 @@ model Car {
|
||||
GhostRegisteredFromTerminal GhostRegisteredFromTerminal[]
|
||||
CarStampTarget CarStampTarget[]
|
||||
CarChallenger CarChallenger[]
|
||||
GhostExpedition GhostExpedition[]
|
||||
GhostExpeditionWantedCar GhostExpeditionWantedCar[]
|
||||
}
|
||||
|
||||
model CarGTWing {
|
||||
@ -438,6 +452,40 @@ model PlaceList {
|
||||
country String
|
||||
}
|
||||
|
||||
model GhostExpedition {
|
||||
dbId Int @id @default(autoincrement())
|
||||
car Car @relation(fields: [carId], references: [carId])
|
||||
carId Int
|
||||
ghostExpeditionId Int
|
||||
sugorokuPoint Int @default(0)
|
||||
earnedScore Int @default(0)
|
||||
score Int @default(0)
|
||||
}
|
||||
|
||||
model GhostExpeditionWantedCar {
|
||||
dbId Int @id @default(autoincrement())
|
||||
car Car @relation(fields: [carId], references: [carId])
|
||||
carId Int
|
||||
bonus Int @default(0)
|
||||
numOfHostages Int @default(1)
|
||||
defeatedMeCount Int @default(1)
|
||||
hostage Int?
|
||||
ghostExpeditionId Int @default(1)
|
||||
area Int @default(0)
|
||||
locked Boolean @default(false)
|
||||
lockTime Int @default(0)
|
||||
challengerCarId Int?
|
||||
}
|
||||
|
||||
model GhostExpeditionEvent {
|
||||
dbId Int @id @default(autoincrement())
|
||||
ghostExpeditionId Int
|
||||
startAt Int
|
||||
endAt Int
|
||||
aftereventEndAt Int
|
||||
opponentCountry String
|
||||
}
|
||||
|
||||
model FileList {
|
||||
fileId Int @id @default(autoincrement())
|
||||
fileType Int
|
||||
@ -446,5 +494,5 @@ model FileList {
|
||||
sha1sum String
|
||||
notBefore Int
|
||||
notAfter Int
|
||||
filePath String @default("")
|
||||
filePath String
|
||||
}
|
@ -4,7 +4,6 @@ import { unzipSync } from "zlib";
|
||||
import { Module } from "./module";
|
||||
import iconv from "iconv-lite";
|
||||
import { Config } from "./config";
|
||||
import * as common from "./modules/util/common";
|
||||
|
||||
// TODO: Move this into the config
|
||||
const STARTUP_URI = `https://${Config.getConfig().serverIp || "localhost"}:9002`;
|
||||
@ -72,11 +71,11 @@ export default class AllnetModule extends Module {
|
||||
const adjusted = now;
|
||||
|
||||
let shopName = Config.getConfig().shopName;
|
||||
let shopNick = 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 = common.sanitizeInputNotZero(Number(Config.getConfig().regionId)) || 1;
|
||||
let regionId = Config.getConfig().regionId;
|
||||
|
||||
// TODO: Implement board authentication here.
|
||||
|
||||
|
@ -47,16 +47,12 @@ export interface GameOptions {
|
||||
grantFullTuneTicketToNewUsers: number;
|
||||
|
||||
// Give meter reward every n*100 play
|
||||
giveMeterReward: number; // 1 is on, 0 is off
|
||||
giveMeterReward: number; //1 is on, 0 is off
|
||||
|
||||
// if the new card is not in the User databese
|
||||
// set this option to 1 will not create a new card
|
||||
// and prevent new card registration
|
||||
newCardsBanned: number; // 1 is on, 0 is off
|
||||
|
||||
// revision check
|
||||
// set this option to 1 to enable screenshot feature
|
||||
enableScreenshot: number; // 1 is on, 0 is off
|
||||
newCardsBanned: number;//1 is on, 0 is off
|
||||
}
|
||||
|
||||
export class Config {
|
||||
|
48
src/index.ts
48
src/index.ts
@ -1,18 +1,6 @@
|
||||
// Bayshore - a Wangan Midnight Maximum Tune 6 private server.
|
||||
// Made with love by Luna, and part of Project Asakura.
|
||||
|
||||
import process from 'process';
|
||||
import * as dotenv from "dotenv";
|
||||
dotenv.config({path: __dirname + '/.env'});
|
||||
|
||||
let tracing: any = {};
|
||||
|
||||
if (process.env.OPENTELEMETRY_ENABLED === "true") {
|
||||
console.log('Enabling OpenTelemetry-compatible tracing...');
|
||||
tracing = require('./tracing');
|
||||
tracing.startTracing();
|
||||
}
|
||||
|
||||
import express, { Router } from 'express';
|
||||
import {PrismaClient} from '@prisma/client';
|
||||
import https, {globalAgent} from 'https';
|
||||
@ -22,9 +10,13 @@ import bodyParser from 'body-parser';
|
||||
import AllnetModule from './allnet';
|
||||
import MuchaModule from './mucha';
|
||||
import { Config } from './config';
|
||||
import process from 'process';
|
||||
import * as Sentry from '@sentry/node';
|
||||
import * as Tracing from '@sentry/tracing';
|
||||
import * as common from './modules/util/common';
|
||||
import * as common from './util/common';
|
||||
|
||||
import * as dotenv from "dotenv";
|
||||
dotenv.config({path: __dirname + '/.env'});
|
||||
|
||||
globalAgent.options.keepAlive = true;
|
||||
|
||||
@ -35,10 +27,9 @@ export const prisma = new PrismaClient();
|
||||
|
||||
const appRouter = Router();
|
||||
|
||||
const PORT_ALLNET = process.env.ALLNET_PORT !== undefined ? parseInt(process.env.ALLNET_PORT) : 80;
|
||||
const PORT_MUCHA = process.env.MUCHA_PORT !== undefined ? parseInt(process.env.MUCHA_PORT) : 10082;
|
||||
const PORT_BNGI = process.env.SERVICE_PORT !== undefined ? parseInt(process.env.SERVICE_PORT) : 9002;
|
||||
const PORT_API = process.env.API_PORT !== undefined ? parseInt(process.env.API_PORT) : 9003;
|
||||
const PORT_ALLNET = 80;
|
||||
const PORT_MUCHA = 10082;
|
||||
const PORT_BNGI = 9002;
|
||||
|
||||
const app = express();
|
||||
const muchaApp = express();
|
||||
@ -64,29 +55,6 @@ if (useSentry) {
|
||||
});
|
||||
}
|
||||
|
||||
if (process.env.OPENTELEMETRY_ENABLED === "true") {
|
||||
tracing.startHttpMetrics([
|
||||
{
|
||||
app,
|
||||
options: {
|
||||
appName: 'service'
|
||||
}
|
||||
},
|
||||
{
|
||||
app: muchaApp,
|
||||
options: {
|
||||
appName: 'mucha'
|
||||
}
|
||||
},
|
||||
{
|
||||
app: allnetApp,
|
||||
options: {
|
||||
appName: 'allnet'
|
||||
}
|
||||
}
|
||||
]);
|
||||
}
|
||||
|
||||
// Get the current timestamp
|
||||
let timestamp: string = common.getTimeStamp();
|
||||
|
||||
|
@ -2,13 +2,16 @@ import { Application } from "express";
|
||||
import { Config } from "../config";
|
||||
import { Module } from "module";
|
||||
import { prisma } from "..";
|
||||
import { User } from "@prisma/client";
|
||||
import Long from "long";
|
||||
|
||||
// Import Proto
|
||||
import * as wm from "../wmmt/wm.proto";
|
||||
|
||||
// Import Util
|
||||
import * as common from "./util/common";
|
||||
import * as carFunctions from "./cars/functions";
|
||||
import * as common from "../util/common";
|
||||
import * as scratch from "../util/scratch";
|
||||
import * as terminal from "../util/terminal/check_car";
|
||||
|
||||
|
||||
export default class CarModule extends Module {
|
||||
@ -21,60 +24,223 @@ export default class CarModule extends Module {
|
||||
let body = wm.wm.protobuf.LoadCarRequest.decode(req.body);
|
||||
|
||||
// Get the car (required data only) with the given id
|
||||
let car = await carFunctions.getCar(body.carId);
|
||||
|
||||
// Get Registered HoF Data
|
||||
let registeredTarget = await carFunctions.getRegisteredTarget(body.carId);
|
||||
|
||||
// Get Challenger Data
|
||||
let opponentsTarget = await carFunctions.getOpponentsTarget(body.carId, registeredTarget.registeredargetAvailable);
|
||||
|
||||
// Set Screenshot Count
|
||||
let screenshotCount = 0;
|
||||
|
||||
// Check if screenshot feature enabled or not
|
||||
let enableScreenshot = Config.getConfig().gameOptions.enableScreenshot || 0;
|
||||
|
||||
// Screenshot feature enabled
|
||||
if(enableScreenshot === 1)
|
||||
{
|
||||
// Set the screnshot chance count
|
||||
screenshotCount = 99;
|
||||
let car = await prisma.car.findFirst({
|
||||
where: {
|
||||
carId: body.carId
|
||||
},
|
||||
include: {
|
||||
settings: true,
|
||||
items: true,
|
||||
gtWing: true,
|
||||
lastPlayedPlace: true,
|
||||
}
|
||||
});
|
||||
|
||||
// Error handling if ghostLevel accidentally set to 0 or more than 10
|
||||
if(car!.ghostLevel < 1)
|
||||
{
|
||||
car!.ghostLevel = 1;
|
||||
}
|
||||
if(car!.ghostLevel > 11)
|
||||
{
|
||||
car!.ghostLevel = 10;
|
||||
}
|
||||
|
||||
// Convert the database lose bits to a Long
|
||||
let longLoseBits = Long.fromString(car!.stLoseBits.toString());
|
||||
|
||||
// Get Registered Target
|
||||
let getTarget = await prisma.ghostRegisteredFromTerminal.findFirst({
|
||||
where:{
|
||||
carId: body.carId
|
||||
}
|
||||
});
|
||||
let opponentGhost;
|
||||
let opponentTrailId;
|
||||
let opponentCompetitionId;
|
||||
let registeredTarget: boolean = false;
|
||||
|
||||
if(getTarget)
|
||||
{
|
||||
console.log('Registered Opponents Available');
|
||||
|
||||
let getTargetTrail = await prisma.oCMTop1GhostTrail.findFirst({
|
||||
where:{
|
||||
carId: getTarget.opponentCarId,
|
||||
competitionId: Number(getTarget.competitionId)
|
||||
},
|
||||
orderBy:{
|
||||
periodId: 'desc'
|
||||
}
|
||||
});
|
||||
|
||||
if(getTargetTrail)
|
||||
{
|
||||
let getTargetCar = await prisma.car.findFirst({
|
||||
where:{
|
||||
carId: getTarget.opponentCarId
|
||||
},
|
||||
include:{
|
||||
gtWing: true,
|
||||
lastPlayedPlace: true
|
||||
}
|
||||
});
|
||||
|
||||
opponentGhost = wm.wm.protobuf.GhostCar.create({
|
||||
car: {
|
||||
...getTargetCar!,
|
||||
tunePower: getTargetTrail!.tunePower,
|
||||
tuneHandling: getTargetTrail!.tuneHandling,
|
||||
},
|
||||
area: getTargetTrail!.area,
|
||||
ramp: getTargetTrail!.ramp,
|
||||
path: getTargetTrail!.path,
|
||||
nonhuman: false,
|
||||
type: wm.wm.protobuf.GhostType.GHOST_NORMAL,
|
||||
trailId: getTargetTrail!.dbId
|
||||
});
|
||||
opponentTrailId = Number(getTargetTrail!.dbId);
|
||||
opponentCompetitionId = Number(getTarget.competitionId);
|
||||
}
|
||||
|
||||
registeredTarget = true;
|
||||
}
|
||||
|
||||
// Check opponents stamp target
|
||||
// Will skip this if user's have Hall of Fame ghost registered
|
||||
let carsChallengers;
|
||||
let returnCount = 1;
|
||||
let opponentTargetCount = 0;
|
||||
if(registeredTarget === false)
|
||||
{
|
||||
opponentTargetCount = await prisma.carStampTarget.count({
|
||||
where:{
|
||||
stampTargetCarId: body.carId,
|
||||
recommended: true,
|
||||
},
|
||||
orderBy:{
|
||||
locked: 'desc'
|
||||
}
|
||||
});
|
||||
|
||||
if(opponentTargetCount > 0)
|
||||
{
|
||||
console.log('Challengers Available');
|
||||
|
||||
// Randomize pick
|
||||
let random: number = 1;
|
||||
|
||||
// Randomize it 5 times
|
||||
for(let i=0; i<5; i++)
|
||||
{
|
||||
random = Math.floor(Math.random() * opponentTargetCount);
|
||||
}
|
||||
|
||||
// Try randomize it again if it's 1
|
||||
if(random === 1)
|
||||
{
|
||||
random = Math.floor(Math.random() * opponentTargetCount);
|
||||
}
|
||||
|
||||
// Check opponents target
|
||||
let opponentTarget = await prisma.carStampTarget.findMany({
|
||||
where:{
|
||||
stampTargetCarId: body.carId,
|
||||
recommended: true,
|
||||
},
|
||||
orderBy:{
|
||||
locked: 'desc'
|
||||
},
|
||||
skip: random,
|
||||
take: 1,
|
||||
});
|
||||
|
||||
// Get all of the friend cars for the carId provided
|
||||
let challengers = await prisma.carChallenger.findFirst({
|
||||
where: {
|
||||
challengerCarId: opponentTarget[0].carId,
|
||||
carId: body.carId
|
||||
},
|
||||
orderBy:{
|
||||
id: 'desc'
|
||||
}
|
||||
});
|
||||
|
||||
if(challengers)
|
||||
{
|
||||
returnCount = opponentTarget[0].returnCount;
|
||||
|
||||
let carTarget = await prisma.car.findFirst({
|
||||
where:{
|
||||
carId: challengers.challengerCarId
|
||||
},
|
||||
include:{
|
||||
gtWing: true,
|
||||
lastPlayedPlace: true
|
||||
}
|
||||
})
|
||||
|
||||
let result = 0;
|
||||
if(challengers.result > 0)
|
||||
{
|
||||
result = -Math.abs(challengers.result);
|
||||
}
|
||||
else{
|
||||
result = Math.abs(challengers.result);
|
||||
}
|
||||
|
||||
carsChallengers = wm.wm.protobuf.ChallengerCar.create({
|
||||
car: carTarget!,
|
||||
stamp: challengers.stamp,
|
||||
result: result,
|
||||
area: challengers.area
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// VS ORG
|
||||
let getVSORGData = await prisma.ghostExpedition.findFirst({
|
||||
where:{
|
||||
carId: body.carId
|
||||
},
|
||||
orderBy:{
|
||||
dbId: 'desc'
|
||||
}
|
||||
})
|
||||
|
||||
// Response data
|
||||
let msg = {
|
||||
error: wm.wm.protobuf.ErrorCode.ERR_SUCCESS,
|
||||
|
||||
// wm.protobuf.Car;
|
||||
car: car,
|
||||
|
||||
// Other Car Data (tuningPoint, odometer, playCount, etc)
|
||||
...car,
|
||||
stLoseBits: car.longLoseBits,
|
||||
car: {
|
||||
...car!,
|
||||
},
|
||||
tuningPoint: car!.tuningPoints,
|
||||
setting: car!.settings,
|
||||
rgPreviousVersionPlayCount: 0,
|
||||
stCompleted_100Episodes: car!.stCompleted100Episodes,
|
||||
auraMotifAutoChange: false,
|
||||
screenshotCount: screenshotCount,
|
||||
screenshotCount: 0,
|
||||
transferred: false,
|
||||
...car!,
|
||||
stLoseBits: longLoseBits,
|
||||
ownedItems: car!.items,
|
||||
lastPlayedAt: car!.lastPlayedAt,
|
||||
announceEventModePrize: true,
|
||||
|
||||
// Stamp or Challenger
|
||||
challenger: opponentsTarget.challenger,
|
||||
challengerReturnCount: opponentsTarget.challengerReturnCount,
|
||||
numOfChallengers: opponentsTarget.numOfChallengers,
|
||||
challenger: carsChallengers || null,
|
||||
challengerReturnCount: returnCount || null,
|
||||
numOfStampTargetCars: opponentTargetCount + 1 || null,
|
||||
|
||||
// OCM Challenge Top 1
|
||||
opponentGhost: registeredTarget.opponentGhost,
|
||||
opponentTrailId: registeredTarget.opponentTrailId,
|
||||
opponentCompetitionId: registeredTarget.opponentCompetitionId,
|
||||
opponentGhost: opponentGhost || null,
|
||||
opponentTrailId: opponentTrailId || null,
|
||||
opponentCompetitionId: opponentCompetitionId || null,
|
||||
|
||||
// Owned Item
|
||||
ownedItems: car.items,
|
||||
|
||||
// Announce Event Mode Prize
|
||||
announceEventModePrize: true
|
||||
// VS ORG
|
||||
rgExpeditionScore: getVSORGData?.score || 0,
|
||||
ghostExpeditionState: wm.wm.protobuf.GhostExpeditionParticipantState.EXPEDITION_NOT_PARTICIPATED,
|
||||
};
|
||||
|
||||
// Generate the load car response message
|
||||
@ -91,18 +257,283 @@ export default class CarModule extends Module {
|
||||
// Get the request body for the create car request
|
||||
let body = wm.wm.protobuf.CreateCarRequest.decode(req.body);
|
||||
|
||||
// Create the Car
|
||||
let createCar = await carFunctions.createCar(body);
|
||||
let tune = createCar.tune;
|
||||
let carInsert = createCar.carInsert;
|
||||
// Trim Mojibake
|
||||
body.cardChipId = body.cardChipId.replace('<27><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>0000', '');
|
||||
|
||||
// Check if user's other car have unique window sticker
|
||||
let windowSticker = await carFunctions.getWindowSticker(body.userId);
|
||||
let additionalWindowStickerInsert = windowSticker.additionalWindowStickerInsert
|
||||
// Get the current date/time (unix epoch)
|
||||
let date = Math.floor(new Date().getTime() / 1000)
|
||||
|
||||
/// Switch on tune status
|
||||
let getCarTune = await carFunctions.getCarTune(tune, carInsert);
|
||||
let additionalInsert = getCarTune.additionalInsert;
|
||||
// Retrieve user from card chip / user id
|
||||
let user: User | null;
|
||||
|
||||
// User ID provided, use that
|
||||
if (body.userId) {
|
||||
user = await prisma.user.findFirst({
|
||||
where: {
|
||||
id: body.userId
|
||||
},
|
||||
});
|
||||
} else { // No user id, use card chip
|
||||
user = await prisma.user.findFirst({
|
||||
where: {
|
||||
chipId: body.cardChipId,
|
||||
accessCode: body.accessCode
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
// User not found, terminate
|
||||
if (!user) throw new Error();
|
||||
|
||||
// Generate blank car settings object
|
||||
let settings = await prisma.carSettings.create({
|
||||
data: {}
|
||||
});
|
||||
|
||||
// Generate blank car state object
|
||||
let state = await prisma.carState.create({
|
||||
data: {}
|
||||
})
|
||||
|
||||
let gtWing = await prisma.carGTWing.create({
|
||||
data: {}
|
||||
})
|
||||
|
||||
// Sets if full tune is used or not
|
||||
// let fullyTuned = false;
|
||||
|
||||
// 0: Stock Tune
|
||||
// 1: Basic Tune (600 HP)
|
||||
// 2: Fully Tuned (840 HP)
|
||||
let tune = 0;
|
||||
|
||||
// If a user item has been used
|
||||
if (body.userItemId)
|
||||
{
|
||||
console.log(`Item used - ID ${body.userItemId}`);
|
||||
|
||||
// Remove the user item from the database
|
||||
let item = await prisma.userItem.delete({
|
||||
where: {
|
||||
userItemId: body.userItemId
|
||||
}
|
||||
});
|
||||
|
||||
console.log('Item deleted!');
|
||||
|
||||
switch(item.category)
|
||||
{
|
||||
case 203: // Car Tune Ticket
|
||||
|
||||
// Switch on item id
|
||||
switch(item.itemId)
|
||||
{
|
||||
// Discarded Vehicle Card
|
||||
case 1: tune = 1; break;
|
||||
case 2: tune = 1; break;
|
||||
case 3: tune = 1; break;
|
||||
|
||||
// Fully Tuned Ticket
|
||||
case 5: tune = 2; break;
|
||||
|
||||
default: // Unknown item type, throw unsupported error
|
||||
throw Error("Unsupported itemId: " + item.itemId);
|
||||
}
|
||||
break;
|
||||
|
||||
case 201: // Special Car Ticket
|
||||
|
||||
// Fully tuned special cars
|
||||
if (scratch.fullyTunedCars.includes(item.itemId))
|
||||
{
|
||||
// Car is fully tuned
|
||||
tune = 2;
|
||||
}
|
||||
// Basic tuned special cars
|
||||
if (scratch.basicTunedCars.includes(item.itemId))
|
||||
{
|
||||
// If gift cars fully tuned is set
|
||||
if (Config.getConfig().gameOptions.giftCarsFullyTuned)
|
||||
{
|
||||
// Car is fully tuned
|
||||
tune = 2;
|
||||
}
|
||||
else // Gift cars fully tuned not set
|
||||
{
|
||||
// Car is basic tuned
|
||||
tune = 1;
|
||||
}
|
||||
}
|
||||
// Stock tuned special cars
|
||||
if (scratch.stockTunedCars.includes(item.itemId))
|
||||
{
|
||||
// If gift cars fully tuned is set
|
||||
if (Config.getConfig().gameOptions.giftCarsFullyTuned)
|
||||
{
|
||||
// Car is fully tuned
|
||||
tune = 2;
|
||||
}
|
||||
else // Gift cars fully tuned not set
|
||||
{
|
||||
// Car is stock
|
||||
tune = 0;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
console.log(`Item category was ${item.category} and item game ID was ${item.itemId}`);
|
||||
}
|
||||
|
||||
// Other cases, may occur if item is not detected as 'used'
|
||||
|
||||
// User item not used, but car has 740 HP by default
|
||||
else if (body.car &&
|
||||
(body.car.tunePower == 17) && (body.car.tuneHandling == 17))
|
||||
{
|
||||
// Car is fully tuned
|
||||
tune = 2;
|
||||
|
||||
// Check if created car is from terminal scratch car
|
||||
await terminal.checkScratchCar(body.userId, body.car.visualModel!)
|
||||
}
|
||||
// User item not used, but car has 600 HP by default
|
||||
else if (body.car &&
|
||||
(body.car.tunePower == 10) && (body.car.tuneHandling == 10))
|
||||
{
|
||||
// Car is basic tuned
|
||||
tune = 1;
|
||||
}
|
||||
// User item not used, but gift cars fully tuned switch is set
|
||||
else if (Config.getConfig().gameOptions.giftCarsFullyTuned)
|
||||
{
|
||||
// List of event / exclusive car IDs
|
||||
let event_cars = [
|
||||
0x7A, // Mini
|
||||
0x82, // S660
|
||||
0x83, // S2000
|
||||
0x89, // NDERC
|
||||
0x8B, // GS130 (Starts at 20 Stories by default)
|
||||
];
|
||||
|
||||
// If the car visual model is not null and is in the list of event cars
|
||||
if (body.car.visualModel && event_cars.includes(body.car.visualModel))
|
||||
{
|
||||
// Set full tune used to be true
|
||||
tune = 2;
|
||||
}
|
||||
}
|
||||
|
||||
// Randomize regionId
|
||||
let regionId: number = 18;
|
||||
|
||||
// Randomize it 5 times
|
||||
for(let i=0; i<5; i++)
|
||||
{
|
||||
regionId = Math.floor(Math.random() * 47) + 1;
|
||||
}
|
||||
|
||||
// Try randomize it again if it's 1
|
||||
if(regionId === 1)
|
||||
{
|
||||
regionId = Math.floor(Math.random() * 47) + 1;
|
||||
}
|
||||
|
||||
// Error handling if regionId is below 1 or above 47
|
||||
if(regionId < 1 || regionId > 47)
|
||||
{
|
||||
regionId = Math.floor(Math.random() * 10) + 10;
|
||||
}
|
||||
|
||||
// Default car values
|
||||
let carInsert = {
|
||||
userId: user.id,
|
||||
manufacturer: body.car.manufacturer!,
|
||||
defaultColor: body.car.defaultColor!,
|
||||
model: body.car.model!,
|
||||
visualModel: body.car.visualModel!,
|
||||
name: body.car.name!,
|
||||
title: body.car.title!,
|
||||
level: body.car.level!,
|
||||
tunePower: body.car.tunePower!,
|
||||
tuneHandling: body.car.tuneHandling!,
|
||||
carSettingsDbId: settings.dbId,
|
||||
carStateDbId: state.dbId,
|
||||
carGTWingDbId: gtWing.dbId,
|
||||
regionId: regionId,
|
||||
lastPlayedAt: date,
|
||||
lastPlayedPlaceId: 1, // Server Default
|
||||
};
|
||||
|
||||
// Check if user have more than one cars
|
||||
let checkWindowSticker = await prisma.car.findFirst({
|
||||
where: {
|
||||
userId: body.userId
|
||||
},
|
||||
select: {
|
||||
windowStickerString: true,
|
||||
windowStickerFont: true
|
||||
}
|
||||
});
|
||||
let additionalWindowStickerInsert = {
|
||||
|
||||
}
|
||||
|
||||
// If more than one cars, get the window sticker string
|
||||
if(checkWindowSticker)
|
||||
{
|
||||
additionalWindowStickerInsert = {
|
||||
windowStickerString: checkWindowSticker.windowStickerString,
|
||||
windowStickerFont: checkWindowSticker.windowStickerFont,
|
||||
}
|
||||
}
|
||||
|
||||
// Additional car values (for basic / full tune)
|
||||
let additionalInsert = {
|
||||
|
||||
}
|
||||
|
||||
// Switch on tune status
|
||||
switch(tune)
|
||||
{
|
||||
// 0: Stock, nothing extra
|
||||
|
||||
case 1: // Basic Tune
|
||||
|
||||
// Updated default values
|
||||
carInsert.level = 2; // C8
|
||||
carInsert.tunePower = 10; // 600 HP
|
||||
carInsert.tuneHandling = 10; // 600 HP
|
||||
|
||||
// Additional basic tune values
|
||||
additionalInsert = {
|
||||
ghostLevel: 4,
|
||||
stClearBits: 0,
|
||||
stLoseBits: 0,
|
||||
stClearCount: 20,
|
||||
stClearDivCount: 1,
|
||||
stConsecutiveWins: 20,
|
||||
stConsecutiveWinsMax: 20
|
||||
};
|
||||
break;
|
||||
|
||||
case 2: // Fully Tuned
|
||||
|
||||
// Updated default values
|
||||
carInsert.level = 8; // C3
|
||||
carInsert.tunePower = 17; // 740 HP
|
||||
carInsert.tuneHandling = 17; // 740 HP
|
||||
|
||||
// Additional full tune values
|
||||
additionalInsert = {
|
||||
ghostLevel: 10,
|
||||
stClearBits: 0,
|
||||
stLoseBits: 0,
|
||||
stClearCount: 80,
|
||||
stClearDivCount: 4,
|
||||
stConsecutiveWins: 80,
|
||||
stConsecutiveWinsMax: 80
|
||||
};
|
||||
}
|
||||
|
||||
// Insert the car into the database
|
||||
let car = await prisma.car.create({
|
||||
@ -114,26 +545,30 @@ export default class CarModule extends Module {
|
||||
});
|
||||
|
||||
// Get the user's current car order
|
||||
let carOrder = createCar.user.carOrder;
|
||||
await carFunctions.carOrder(carOrder, car, createCar.user.id);
|
||||
let carOrder = user.carOrder;
|
||||
|
||||
// Add the new car to the front of the id
|
||||
carOrder.unshift(car.carId);
|
||||
|
||||
// Add the car to the front of the order
|
||||
await prisma.user.update({
|
||||
where: {
|
||||
id: user.id
|
||||
},
|
||||
data: {
|
||||
carOrder: carOrder
|
||||
}
|
||||
});
|
||||
|
||||
console.log(`Created new car ${car.name} with ID ${car.carId}`);
|
||||
|
||||
// Response data
|
||||
let msg = {
|
||||
error: wm.wm.protobuf.ErrorCode.ERR_SUCCESS,
|
||||
|
||||
// User ID
|
||||
accessCode: body.accessCode,
|
||||
banapassportAmId: body.banapassportAmId,
|
||||
//mbid: number|null,
|
||||
|
||||
// Car Data
|
||||
carId: car.carId,
|
||||
car,
|
||||
...carInsert,
|
||||
...additionalInsert,
|
||||
|
||||
// Expiring Full Tuned Ticket
|
||||
//fullTunedCarCouponUnreceivableAt: number|null
|
||||
...additionalInsert
|
||||
}
|
||||
|
||||
// Generate the load car response message
|
||||
@ -150,24 +585,105 @@ export default class CarModule extends Module {
|
||||
// Get the request body for the update car request
|
||||
let body = wm.wm.protobuf.UpdateCarRequest.decode(req.body);
|
||||
|
||||
// Not deleting car
|
||||
if(body.toBeDeleted === false || body.toBeDeleted === undefined || body.toBeDeleted === null)
|
||||
// Get the ghost result for the car
|
||||
let cars = body?.car;
|
||||
|
||||
// Declare data
|
||||
let data : any;
|
||||
|
||||
// Car is set
|
||||
if (cars)
|
||||
{
|
||||
// Update the car
|
||||
await carFunctions.updateCar(body);
|
||||
// Get current date
|
||||
let date = Math.floor(new Date().getTime() / 1000);
|
||||
|
||||
// Update the car setting
|
||||
await carFunctions.updateCarSetting(body);
|
||||
// Car update data
|
||||
data = {
|
||||
customColor: common.sanitizeInput(cars.customColor),
|
||||
wheel: common.sanitizeInput(cars.wheel),
|
||||
wheelColor: common.sanitizeInput(cars.wheelColor),
|
||||
aero: common.sanitizeInput(cars.aero),
|
||||
bonnet: common.sanitizeInput(cars.bonnet),
|
||||
wing: common.sanitizeInput(cars.wing),
|
||||
mirror: common.sanitizeInput(cars.mirror),
|
||||
neon: common.sanitizeInput(cars.neon),
|
||||
trunk: common.sanitizeInput(cars.trunk),
|
||||
plate: common.sanitizeInput(cars.plate),
|
||||
plateColor: common.sanitizeInput(cars.plateColor),
|
||||
plateNumber: common.sanitizeInput(cars.plateNumber),
|
||||
windowSticker: common.sanitizeInput(cars.windowSticker),
|
||||
windowDecoration: common.sanitizeInput(cars.windowDecoration),
|
||||
rivalMarker: common.sanitizeInput(cars.rivalMarker),
|
||||
aura: common.sanitizeInput(cars.aura),
|
||||
auraMotif: common.sanitizeInput(cars.auraMotif),
|
||||
rgStamp: common.sanitizeInputNotZero(body.rgStamp),
|
||||
lastPlayedAt: date
|
||||
}
|
||||
|
||||
// Update the car window Sticker
|
||||
await carFunctions.updateCarWindowSticker(body);
|
||||
// Update the car info
|
||||
await prisma.car.update({
|
||||
where: {
|
||||
carId: body.carId
|
||||
},
|
||||
data: data
|
||||
})
|
||||
}
|
||||
|
||||
// Update the car Custom Wing
|
||||
await carFunctions.updateCarCustomWing(body);
|
||||
// Get the car with the given id
|
||||
let car = await prisma.car.findFirst({
|
||||
where: {
|
||||
carId: body.carId
|
||||
},
|
||||
include: {
|
||||
settings: true,
|
||||
gtWing: true,
|
||||
lastPlayedPlace: true
|
||||
}
|
||||
});
|
||||
|
||||
// Update the car settings
|
||||
await prisma.carSettings.update({
|
||||
where: {
|
||||
dbId: car?.carSettingsDbId,
|
||||
},
|
||||
data: {
|
||||
...body.setting
|
||||
}
|
||||
});
|
||||
|
||||
// Update the user data
|
||||
let userData = await prisma.car.findFirst({
|
||||
where:{
|
||||
carId: body.carId
|
||||
},
|
||||
select:{
|
||||
userId: true,
|
||||
windowStickerString: true
|
||||
}
|
||||
})
|
||||
|
||||
// Newer window sticker string is different from the older one
|
||||
// Check if window sticker string is not null
|
||||
// (windowStickerString value when changing custom color in driver unit is undefined)
|
||||
if(body.car?.windowStickerString)
|
||||
{
|
||||
if(userData!.windowStickerString !== body.car.windowStickerString){
|
||||
console.log('Updating Window Sticker');
|
||||
|
||||
await prisma.car.updateMany({
|
||||
where: {
|
||||
userId: userData!.userId
|
||||
},
|
||||
data: {
|
||||
windowStickerString: body.car.windowStickerString,
|
||||
windowStickerFont: body.car.windowStickerFont!
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// Get car item (custom color or discarded card)
|
||||
if(body.earnedItems.length !== 0)
|
||||
{
|
||||
if(body.earnedItems.length !== 0){
|
||||
console.log('Car Item reward available, continuing ...');
|
||||
for(let i=0; i<body.earnedItems.length; i++){
|
||||
await prisma.carItem.create({
|
||||
@ -180,22 +696,54 @@ export default class CarModule extends Module {
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
// Deleting car
|
||||
else
|
||||
{
|
||||
console.log('Deleting Car ID : ' + body.carId);
|
||||
|
||||
// Mark Deleted Car
|
||||
await prisma.carState.update({
|
||||
where:{
|
||||
// Update the GT Wing (custom wing) info
|
||||
// Get the GT Wing data for the car
|
||||
let gtWing = body.car?.gtWing;
|
||||
let dataGTWing: any;
|
||||
|
||||
// GT Wing is set
|
||||
if (gtWing)
|
||||
{
|
||||
dataGTWing = {
|
||||
pillar: common.sanitizeInput(gtWing.pillar),
|
||||
pillarMaterial: common.sanitizeInput(gtWing.pillarMaterial),
|
||||
mainWing: common.sanitizeInput(gtWing.mainWing),
|
||||
mainWingColor: common.sanitizeInput(gtWing.mainWingColor),
|
||||
wingTip: common.sanitizeInput(gtWing.wingTip),
|
||||
material: common.sanitizeInput(gtWing.material),
|
||||
}
|
||||
|
||||
await prisma.carGTWing.update({
|
||||
where: {
|
||||
dbId: body.carId
|
||||
},
|
||||
data:{
|
||||
toBeDeleted: body.toBeDeleted
|
||||
}
|
||||
data: dataGTWing
|
||||
})
|
||||
}
|
||||
// Check if this is in getting new custom color screen or not
|
||||
else if(body.car?.carId !== null && body.car?.carId !== undefined)
|
||||
{
|
||||
// GT Wing not set
|
||||
if(gtWing === undefined || gtWing === null)
|
||||
{
|
||||
dataGTWing = {
|
||||
pillar: 0,
|
||||
pillarMaterial: 0,
|
||||
mainWing: 0,
|
||||
mainWingColor: 0,
|
||||
wingTip: 0,
|
||||
material: 0,
|
||||
}
|
||||
|
||||
await prisma.carGTWing.update({
|
||||
where: {
|
||||
dbId: body.carId
|
||||
},
|
||||
data: dataGTWing
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// Response data
|
||||
let msg = {
|
||||
|
@ -1,86 +0,0 @@
|
||||
import { Config } from "../../config";
|
||||
import { prisma } from "../..";
|
||||
|
||||
// Import Util
|
||||
import * as scratch from "../terminal/scratch";
|
||||
|
||||
|
||||
// Create Car With Item
|
||||
export async function createCarWithItem(userItemId: number)
|
||||
{
|
||||
console.log(`Item used - ID ${userItemId}`);
|
||||
|
||||
// Remove the user item from the database
|
||||
let item = await prisma.userItem.delete({
|
||||
where: {
|
||||
userItemId: userItemId
|
||||
}
|
||||
});
|
||||
let tune = 0;
|
||||
|
||||
console.log('Item deleted!');
|
||||
|
||||
switch(item.category)
|
||||
{
|
||||
case 203: // Car Tune Ticket
|
||||
|
||||
// Switch on item id
|
||||
switch(item.itemId)
|
||||
{
|
||||
// Discarded Vehicle Card
|
||||
case 1: tune = 1; break;
|
||||
case 2: tune = 1; break;
|
||||
case 3: tune = 1; break;
|
||||
|
||||
// Fully Tuned Ticket
|
||||
case 5: tune = 2; break;
|
||||
|
||||
default: // Unknown item type, throw unsupported error
|
||||
throw Error("Unsupported itemId: " + item.itemId);
|
||||
}
|
||||
break;
|
||||
|
||||
case 201: // Special Car Ticket
|
||||
|
||||
// Fully tuned special cars
|
||||
if (scratch.fullyTunedCars.includes(item.itemId))
|
||||
{
|
||||
// Car is fully tuned
|
||||
tune = 2;
|
||||
}
|
||||
// Basic tuned special cars
|
||||
if (scratch.basicTunedCars.includes(item.itemId))
|
||||
{
|
||||
// If gift cars fully tuned is set
|
||||
if (Config.getConfig().gameOptions.giftCarsFullyTuned)
|
||||
{
|
||||
// Car is fully tuned
|
||||
tune = 2;
|
||||
}
|
||||
else // Gift cars fully tuned not set
|
||||
{
|
||||
// Car is basic tuned
|
||||
tune = 1;
|
||||
}
|
||||
}
|
||||
// Stock tuned special cars
|
||||
if (scratch.stockTunedCars.includes(item.itemId))
|
||||
{
|
||||
// If gift cars fully tuned is set
|
||||
if (Config.getConfig().gameOptions.giftCarsFullyTuned)
|
||||
{
|
||||
// Car is fully tuned
|
||||
tune = 2;
|
||||
}
|
||||
else // Gift cars fully tuned not set
|
||||
{
|
||||
// Car is stock
|
||||
tune = 0;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
console.log(`Item category was ${item.category} and item game ID was ${item.itemId}`);
|
||||
|
||||
return { tune }
|
||||
}
|
@ -1,669 +0,0 @@
|
||||
import { prisma } from "../..";
|
||||
import { User } from "@prisma/client";
|
||||
import { Config } from "../../config";
|
||||
import Long from "long";
|
||||
|
||||
// Import Proto
|
||||
import { wm } from "../../wmmt/wm.proto";
|
||||
import * as wmproto from "../../wmmt/wm.proto";
|
||||
|
||||
// Import Util
|
||||
import * as common from "../util/common";
|
||||
import * as car_tune from "./car_tune";
|
||||
import * as terminal from "../terminal/check_car";
|
||||
|
||||
|
||||
// Get Car Data
|
||||
export async function getCar(carId: number)
|
||||
{
|
||||
// Get the car (required data only) with the given id
|
||||
let car = await prisma.car.findFirst({
|
||||
where: {
|
||||
carId: carId
|
||||
},
|
||||
include: {
|
||||
settings: true,
|
||||
items: true,
|
||||
gtWing: true,
|
||||
lastPlayedPlace: true,
|
||||
}
|
||||
});
|
||||
|
||||
// Error handling if ghostLevel accidentally set to 0 or more than 10
|
||||
if(car!.ghostLevel < 1)
|
||||
{
|
||||
car!.ghostLevel = 1;
|
||||
}
|
||||
if(car!.ghostLevel > 11)
|
||||
{
|
||||
car!.ghostLevel = 10;
|
||||
}
|
||||
|
||||
// Convert the database lose bits to a Long
|
||||
let longLoseBits = Long.fromString(car!.stLoseBits.toString());
|
||||
|
||||
return { ...car!, longLoseBits }
|
||||
}
|
||||
|
||||
|
||||
// Get Opponents Target
|
||||
export async function getRegisteredTarget(carId: number)
|
||||
{
|
||||
// Get Registered Target
|
||||
let getTarget = await prisma.ghostRegisteredFromTerminal.findFirst({
|
||||
where:{
|
||||
carId: carId
|
||||
}
|
||||
});
|
||||
let opponentGhost;
|
||||
let opponentTrailId;
|
||||
let opponentCompetitionId;
|
||||
let registeredargetAvailable: boolean = false;
|
||||
|
||||
if(getTarget)
|
||||
{
|
||||
console.log('Registered Opponents Available');
|
||||
|
||||
let getTargetTrail = await prisma.oCMTop1GhostTrail.findFirst({
|
||||
where:{
|
||||
carId: getTarget.opponentCarId,
|
||||
competitionId: Number(getTarget.competitionId)
|
||||
},
|
||||
orderBy:{
|
||||
periodId: 'desc'
|
||||
}
|
||||
});
|
||||
|
||||
if(getTargetTrail)
|
||||
{
|
||||
let getTargetCar = await prisma.car.findFirst({
|
||||
where:{
|
||||
carId: getTarget.opponentCarId
|
||||
},
|
||||
include:{
|
||||
gtWing: true,
|
||||
lastPlayedPlace: true
|
||||
}
|
||||
});
|
||||
|
||||
opponentGhost = wmproto.wm.protobuf.GhostCar.create({
|
||||
car: {
|
||||
...getTargetCar!,
|
||||
tunePower: getTargetTrail!.tunePower,
|
||||
tuneHandling: getTargetTrail!.tuneHandling,
|
||||
},
|
||||
area: getTargetTrail!.area,
|
||||
ramp: getTargetTrail!.ramp,
|
||||
path: getTargetTrail!.path,
|
||||
nonhuman: false,
|
||||
type: wmproto.wm.protobuf.GhostType.GHOST_NORMAL,
|
||||
trailId: getTargetTrail!.dbId
|
||||
});
|
||||
opponentTrailId = Number(getTargetTrail!.dbId);
|
||||
opponentCompetitionId = Number(getTarget.competitionId);
|
||||
}
|
||||
|
||||
registeredargetAvailable = true;
|
||||
}
|
||||
|
||||
return { opponentGhost, opponentTrailId, opponentCompetitionId, registeredargetAvailable }
|
||||
}
|
||||
|
||||
|
||||
// Get Opponents Target
|
||||
export async function getOpponentsTarget(carId: number, registeredargetAvailable: boolean)
|
||||
{
|
||||
// Check opponents stamp target
|
||||
// Will skip this if user's have Hall of Fame ghost registered
|
||||
let challenger;
|
||||
let challengerReturnCount = 1;
|
||||
let opponentTargetCount = 0;
|
||||
let numOfChallengers: number = 0;
|
||||
if(registeredargetAvailable === false)
|
||||
{
|
||||
// Check opponents target
|
||||
opponentTargetCount = await prisma.carStampTarget.count({
|
||||
where:{
|
||||
stampTargetCarId: carId,
|
||||
recommended: true,
|
||||
},
|
||||
orderBy:{
|
||||
locked: 'desc'
|
||||
}
|
||||
});
|
||||
|
||||
if(opponentTargetCount > 0)
|
||||
{
|
||||
console.log('Challengers Available');
|
||||
|
||||
// Randomize pick
|
||||
let random: number = 1;
|
||||
let randomArray: number[] = [];
|
||||
let maxNumber = 5;
|
||||
|
||||
if(opponentTargetCount < 5)
|
||||
{
|
||||
maxNumber = opponentTargetCount;
|
||||
}
|
||||
|
||||
// Randomize it 5 times
|
||||
while(randomArray.length < maxNumber)
|
||||
{
|
||||
// Pick random car Id
|
||||
random = Math.floor(Math.random() * opponentTargetCount);
|
||||
|
||||
// Try randomize it again if it's 0, and fix if more than car length
|
||||
if(random < 1 || random >= opponentTargetCount)
|
||||
{
|
||||
random = Math.floor(Math.random() * opponentTargetCount);
|
||||
}
|
||||
|
||||
// Random Number not yet selected
|
||||
if(randomArray.indexOf(random) === -1)
|
||||
{
|
||||
// Push current number to array
|
||||
randomArray.push(random);
|
||||
}
|
||||
}
|
||||
|
||||
// Pick the array number
|
||||
let pickRandom = Math.floor(Math.random() * randomArray.length);
|
||||
random = randomArray[pickRandom];
|
||||
|
||||
// Check opponents target
|
||||
let opponentTarget = await prisma.carStampTarget.findMany({
|
||||
where:{
|
||||
stampTargetCarId: carId,
|
||||
recommended: true,
|
||||
},
|
||||
orderBy: [
|
||||
{
|
||||
id: 'asc'
|
||||
},
|
||||
{
|
||||
recommended: 'desc'
|
||||
}
|
||||
],
|
||||
skip: random,
|
||||
take: 1,
|
||||
});
|
||||
|
||||
// Get Opponents Challengers
|
||||
let carChallengers = await prisma.carChallenger.findFirst({
|
||||
where: {
|
||||
challengerCarId: opponentTarget[0].carId,
|
||||
carId: carId
|
||||
},
|
||||
orderBy:{
|
||||
id: 'desc'
|
||||
}
|
||||
});
|
||||
|
||||
// Challengers Available
|
||||
if(carChallengers)
|
||||
{
|
||||
// Get Shuttle
|
||||
challengerReturnCount = opponentTarget[0].returnCount;
|
||||
|
||||
// Get Car Target
|
||||
let carTarget = await prisma.car.findFirst({
|
||||
where:{
|
||||
carId: carChallengers.challengerCarId
|
||||
},
|
||||
include:{
|
||||
gtWing: true,
|
||||
lastPlayedPlace: true
|
||||
}
|
||||
});
|
||||
|
||||
// Car Target Available
|
||||
if(carTarget)
|
||||
{
|
||||
// Get Advantage
|
||||
let result = 0;
|
||||
if(carChallengers.result > 0)
|
||||
{
|
||||
result = -Math.abs(carChallengers.result);
|
||||
}
|
||||
else{
|
||||
result = Math.abs(carChallengers.result);
|
||||
}
|
||||
|
||||
// Error handling if regionId is below 1 or above 47
|
||||
if(carTarget!.regionId < 1 || carTarget!.regionId > 47)
|
||||
{
|
||||
carTarget!.regionId = Math.floor(Math.random() * 10) + 10;
|
||||
}
|
||||
|
||||
// Push the data
|
||||
challenger = wmproto.wm.protobuf.ChallengerCar.create({
|
||||
car: carTarget,
|
||||
stamp: carChallengers.stamp,
|
||||
result: result,
|
||||
area: carChallengers.area
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// Get Number of Challengers
|
||||
numOfChallengers = opponentTargetCount + 1;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return { challenger, challengerReturnCount, numOfChallengers }
|
||||
}
|
||||
|
||||
|
||||
// Create Car
|
||||
export async function createCar(body: wm.protobuf.CreateCarRequest)
|
||||
{
|
||||
// Get the current date/time (unix epoch)
|
||||
let date = Math.floor(new Date().getTime() / 1000);
|
||||
|
||||
// Retrieve user from card chip / user id
|
||||
let user: User | null;
|
||||
|
||||
// User ID provided, use that
|
||||
if (body.userId)
|
||||
{
|
||||
user = await prisma.user.findFirst({
|
||||
where: {
|
||||
id: body.userId
|
||||
},
|
||||
});
|
||||
}
|
||||
// No user id, use card chip
|
||||
else
|
||||
{
|
||||
user = await prisma.user.findFirst({
|
||||
where: {
|
||||
chipId: body.cardChipId,
|
||||
accessCode: body.accessCode
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
// User not found, terminate
|
||||
if (!user) throw new Error();
|
||||
|
||||
// Generate blank car settings object
|
||||
let settings = await prisma.carSettings.create({
|
||||
data: {}
|
||||
});
|
||||
|
||||
// Generate blank car state object
|
||||
let state = await prisma.carState.create({
|
||||
data: {}
|
||||
});
|
||||
|
||||
let gtWing = await prisma.carGTWing.create({
|
||||
data: {}
|
||||
});
|
||||
|
||||
// Sets if full tune is used or not
|
||||
// let fullyTuned = false;
|
||||
|
||||
// 0: Stock Tune
|
||||
// 1: Basic Tune (600 HP)
|
||||
// 2: Fully Tuned (840 HP)
|
||||
let tune = 0;
|
||||
|
||||
// If a user item has been used
|
||||
if (body.userItemId)
|
||||
{
|
||||
let carUtilFunctions = await car_tune.createCarWithItem(body.userItemId);
|
||||
|
||||
tune = carUtilFunctions.tune;
|
||||
}
|
||||
// Other cases, may occur if item is not detected as 'used'
|
||||
// User item not used, but car has 740 HP by default
|
||||
else if (body.car && body.car.tunePower == 17 && body.car.tuneHandling == 17)
|
||||
{
|
||||
// Car is fully tuned
|
||||
tune = 2;
|
||||
|
||||
// Check if created car is from terminal scratch car
|
||||
await terminal.checkScratchCar(body.userId, body.car.visualModel!)
|
||||
}
|
||||
// User item not used, but car has 600 HP by default
|
||||
else if (body.car && body.car.tunePower == 10 && body.car.tuneHandling == 10)
|
||||
{
|
||||
// Car is basic tuned
|
||||
tune = 1;
|
||||
}
|
||||
// User item not used, but gift cars fully tuned switch is set
|
||||
else if (Config.getConfig().gameOptions.giftCarsFullyTuned)
|
||||
{
|
||||
// List of event / exclusive car IDs
|
||||
let event_cars = [
|
||||
0x7A, // Mini
|
||||
0x82, // S660
|
||||
0x83, // S2000
|
||||
0x89, // NDERC
|
||||
0x8B, // GS130 (Starts at 20 Stories by default)
|
||||
];
|
||||
|
||||
// If the car visual model is not null and is in the list of event cars
|
||||
if (body.car.visualModel && event_cars.includes(body.car.visualModel))
|
||||
{
|
||||
// Set full tune used to be true
|
||||
tune = 2;
|
||||
}
|
||||
}
|
||||
|
||||
// Randomize pick
|
||||
let random: number = 1;
|
||||
let randomArray: number[] = [];
|
||||
|
||||
// Randomize it 5 times
|
||||
while(randomArray.length < 5)
|
||||
{
|
||||
// Pick random car Id
|
||||
random = Math.floor(Math.random() * 47) + 1;
|
||||
|
||||
// Try randomize it again if it's 0, and fix if more than car length
|
||||
if(random < 1 || random > 47)
|
||||
{
|
||||
random = Math.floor(Math.random() * 47) + 1;
|
||||
}
|
||||
|
||||
// Random Number not yet selected
|
||||
if(randomArray.indexOf(random) === -1)
|
||||
{
|
||||
// Push current number to array
|
||||
randomArray.push(random);
|
||||
}
|
||||
}
|
||||
|
||||
// Pick the array number
|
||||
let pickRandom = Math.floor(Math.random() * randomArray.length);
|
||||
random = randomArray[pickRandom];
|
||||
|
||||
// Default car values
|
||||
let carInsert = {
|
||||
userId: user.id,
|
||||
manufacturer: body.car.manufacturer!,
|
||||
defaultColor: body.car.defaultColor!,
|
||||
model: body.car.model!,
|
||||
visualModel: body.car.visualModel!,
|
||||
name: body.car.name!,
|
||||
title: body.car.title!,
|
||||
level: body.car.level!,
|
||||
tunePower: body.car.tunePower!,
|
||||
tuneHandling: body.car.tuneHandling!,
|
||||
carSettingsDbId: settings.dbId,
|
||||
carStateDbId: state.dbId,
|
||||
carGTWingDbId: gtWing.dbId,
|
||||
regionId: random,
|
||||
lastPlayedAt: date,
|
||||
lastPlayedPlaceId: 1, // Server Default
|
||||
};
|
||||
|
||||
return { carInsert, tune, user }
|
||||
}
|
||||
|
||||
|
||||
// Get Window Sticker
|
||||
export async function getWindowSticker(userId: number)
|
||||
{
|
||||
// Check if user have more than one cars
|
||||
let checkWindowSticker = await prisma.car.findFirst({
|
||||
where: {
|
||||
userId: userId
|
||||
},
|
||||
select: {
|
||||
windowStickerString: true,
|
||||
windowStickerFont: true
|
||||
}
|
||||
});
|
||||
let additionalWindowStickerInsert = {};
|
||||
|
||||
// If more than one cars, get the window sticker string
|
||||
if(checkWindowSticker)
|
||||
{
|
||||
additionalWindowStickerInsert = {
|
||||
windowStickerString: checkWindowSticker.windowStickerString,
|
||||
windowStickerFont: checkWindowSticker.windowStickerFont,
|
||||
}
|
||||
}
|
||||
|
||||
return { additionalWindowStickerInsert }
|
||||
}
|
||||
|
||||
|
||||
// Get Car Tune
|
||||
export async function getCarTune(tune: number, carInsert: any)
|
||||
{
|
||||
// Additional car values (for basic / full tune)
|
||||
let additionalInsert = {};
|
||||
|
||||
switch(tune)
|
||||
{
|
||||
// 0: Stock, nothing extra
|
||||
|
||||
case 1: // Basic Tune
|
||||
|
||||
// Updated default values
|
||||
carInsert.level = 2; // C8
|
||||
carInsert.tunePower = 10; // 600 HP
|
||||
carInsert.tuneHandling = 10; // 600 HP
|
||||
|
||||
// Additional basic tune values
|
||||
additionalInsert = {
|
||||
ghostLevel: 4,
|
||||
stClearBits: 0,
|
||||
stLoseBits: 0,
|
||||
stClearCount: 20,
|
||||
stClearDivCount: 1,
|
||||
stConsecutiveWins: 20,
|
||||
stConsecutiveWinsMax: 20
|
||||
};
|
||||
break;
|
||||
|
||||
case 2: // Fully Tuned
|
||||
|
||||
// Updated default values
|
||||
carInsert.level = 8; // C3
|
||||
carInsert.tunePower = 17; // 740 HP
|
||||
carInsert.tuneHandling = 17; // 740 HP
|
||||
|
||||
// Additional full tune values
|
||||
additionalInsert = {
|
||||
ghostLevel: 10,
|
||||
stClearBits: 0,
|
||||
stLoseBits: 0,
|
||||
stClearCount: 80,
|
||||
stClearDivCount: 4,
|
||||
stConsecutiveWins: 80,
|
||||
stConsecutiveWinsMax: 80
|
||||
};
|
||||
}
|
||||
|
||||
return { additionalInsert }
|
||||
}
|
||||
|
||||
|
||||
// Car Order
|
||||
export async function carOrder(carOrder: any, car: any, userId: number)
|
||||
{
|
||||
// Add the new car to the front of the id
|
||||
carOrder.unshift(car.carId);
|
||||
|
||||
// Add the car to the front of the order
|
||||
await prisma.user.update({
|
||||
where: {
|
||||
id: userId
|
||||
},
|
||||
data: {
|
||||
carOrder: carOrder
|
||||
}
|
||||
});
|
||||
|
||||
console.log(`Created new car ${car.name} with ID ${car.carId}`);
|
||||
}
|
||||
|
||||
|
||||
// Update Car
|
||||
export async function updateCar(body: wm.protobuf.UpdateCarRequest)
|
||||
{
|
||||
// Get the ghost result for the car
|
||||
let cars = body?.car;
|
||||
|
||||
// Declare data
|
||||
let data: any;
|
||||
|
||||
// Get the current date/time (unix epoch)
|
||||
let date = Math.floor(new Date().getTime() / 1000);
|
||||
|
||||
// Car is set
|
||||
if (cars)
|
||||
{
|
||||
// Car update data
|
||||
data = {
|
||||
customColor: common.sanitizeInput(cars.customColor),
|
||||
wheel: common.sanitizeInput(cars.wheel),
|
||||
wheelColor: common.sanitizeInput(cars.wheelColor),
|
||||
aero: common.sanitizeInput(cars.aero),
|
||||
bonnet: common.sanitizeInput(cars.bonnet),
|
||||
wing: common.sanitizeInput(cars.wing),
|
||||
mirror: common.sanitizeInput(cars.mirror),
|
||||
neon: common.sanitizeInput(cars.neon),
|
||||
trunk: common.sanitizeInput(cars.trunk),
|
||||
plate: common.sanitizeInput(cars.plate),
|
||||
plateColor: common.sanitizeInput(cars.plateColor),
|
||||
plateNumber: common.sanitizeInput(cars.plateNumber),
|
||||
windowSticker: common.sanitizeInput(cars.windowSticker),
|
||||
windowDecoration: common.sanitizeInput(cars.windowDecoration),
|
||||
rivalMarker: common.sanitizeInput(cars.rivalMarker),
|
||||
aura: common.sanitizeInput(cars.aura),
|
||||
auraMotif: common.sanitizeInput(cars.auraMotif),
|
||||
rgStamp: common.sanitizeInputNotZero(body.rgStamp),
|
||||
lastPlayedAt: date
|
||||
};
|
||||
|
||||
// Update the car info
|
||||
await prisma.car.update({
|
||||
where: {
|
||||
carId: body.carId
|
||||
},
|
||||
data: data
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Update Car Setting
|
||||
export async function updateCarSetting(body: wm.protobuf.UpdateCarRequest)
|
||||
{
|
||||
// Get the car with the given id
|
||||
let car = await prisma.car.findFirst({
|
||||
where: {
|
||||
carId: body.carId
|
||||
},
|
||||
include: {
|
||||
settings: true,
|
||||
gtWing: true,
|
||||
lastPlayedPlace: true
|
||||
}
|
||||
});
|
||||
|
||||
// Update the car settings
|
||||
await prisma.carSettings.update({
|
||||
where: {
|
||||
dbId: car?.carSettingsDbId,
|
||||
},
|
||||
data: {
|
||||
...body.setting
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
// Update car Window Sticker
|
||||
export async function updateCarWindowSticker(body: wm.protobuf.UpdateCarRequest)
|
||||
{
|
||||
// Update the user data
|
||||
let userData = await prisma.car.findFirst({
|
||||
where:{
|
||||
carId: body.carId
|
||||
},
|
||||
select:{
|
||||
userId: true,
|
||||
windowStickerString: true
|
||||
}
|
||||
});
|
||||
|
||||
// Newer window sticker string is different from the older one
|
||||
// Check if window sticker string is not null
|
||||
// (windowStickerString value when changing custom color in driver unit is undefined)
|
||||
if(body.car?.windowStickerString)
|
||||
{
|
||||
if(userData!.windowStickerString !== body.car.windowStickerString){
|
||||
console.log('Updating Window Sticker');
|
||||
|
||||
await prisma.car.updateMany({
|
||||
where: {
|
||||
userId: userData!.userId
|
||||
},
|
||||
data: {
|
||||
windowStickerString: body.car.windowStickerString,
|
||||
windowStickerFont: body.car.windowStickerFont!
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Update Car Custom Wing
|
||||
export async function updateCarCustomWing(body: wm.protobuf.UpdateCarRequest)
|
||||
{
|
||||
// Update the GT Wing (custom wing) info
|
||||
// Get the GT Wing data for the car
|
||||
let gtWing = body.car?.gtWing;
|
||||
let dataGTWing: any;
|
||||
|
||||
// GT Wing is set
|
||||
if (gtWing)
|
||||
{
|
||||
dataGTWing = {
|
||||
pillar: common.sanitizeInput(gtWing.pillar),
|
||||
pillarMaterial: common.sanitizeInput(gtWing.pillarMaterial),
|
||||
mainWing: common.sanitizeInput(gtWing.mainWing),
|
||||
mainWingColor: common.sanitizeInput(gtWing.mainWingColor),
|
||||
wingTip: common.sanitizeInput(gtWing.wingTip),
|
||||
material: common.sanitizeInput(gtWing.material),
|
||||
};
|
||||
|
||||
await prisma.carGTWing.update({
|
||||
where: {
|
||||
dbId: body.carId
|
||||
},
|
||||
data: dataGTWing
|
||||
});
|
||||
}
|
||||
// Check if this is in getting new custom color screen or not
|
||||
else if(body.car?.carId !== null && body.car?.carId !== undefined)
|
||||
{
|
||||
// GT Wing not set
|
||||
if(gtWing === undefined || gtWing === null)
|
||||
{
|
||||
dataGTWing = {
|
||||
pillar: 0,
|
||||
pillarMaterial: 0,
|
||||
mainWing: 0,
|
||||
mainWingColor: 0,
|
||||
wingTip: 0,
|
||||
material: 0,
|
||||
};
|
||||
|
||||
await prisma.carGTWing.update({
|
||||
where: {
|
||||
dbId: body.carId
|
||||
},
|
||||
data: dataGTWing
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
@ -7,13 +7,12 @@ import { Config } from "../config";
|
||||
import * as wm from "../wmmt/wm.proto";
|
||||
|
||||
// Import Util
|
||||
import * as common from "./util/common";
|
||||
import * as gameFunction from "./game/functions";
|
||||
import * as meter_reward from "./util/meter_reward";
|
||||
import * as story from "./game/story";
|
||||
import * as time_attack from "./game/time_attack";
|
||||
import * as ghost from "./game/ghost";
|
||||
import * as versus from "./game/versus";
|
||||
import * as common from "../util/common";
|
||||
import * as meter_reward from "../util/games/meter_reward";
|
||||
import * as story from "../util/games/story";
|
||||
import * as time_attack from "../util/games/time_attack";
|
||||
import * as ghost from "../util/games/ghost";
|
||||
import * as versus from "../util/games/versus";
|
||||
|
||||
|
||||
export default class GameModule extends Module {
|
||||
@ -36,10 +35,15 @@ export default class GameModule extends Module {
|
||||
}
|
||||
});
|
||||
|
||||
// Declare some variable for message response
|
||||
let ghostModePlay:boolean = false;
|
||||
let updateNewTrail:boolean = true;
|
||||
let OCMModePlay:boolean = false;
|
||||
// Declare some variable
|
||||
// Default value is 'false', inside 'BASE_PATH/src/util/games/ghost.ts' file
|
||||
let ghostModePlay;
|
||||
|
||||
// Default value is 'true', inside 'BASE_PATH/src/util/games/ghost.ts' file
|
||||
let updateNewTrail;
|
||||
|
||||
// Default value is 'false', inside 'BASE_PATH/src/util/games/ghost.ts' file
|
||||
let OCMModePlay;
|
||||
|
||||
// Switch on the gamemode
|
||||
switch (body.gameMode)
|
||||
@ -96,15 +100,96 @@ export default class GameModule extends Module {
|
||||
}
|
||||
}
|
||||
|
||||
// Get car item
|
||||
// Car item reward from the game is available
|
||||
if(body.earnedItems.length !== 0)
|
||||
{
|
||||
console.log('Car Item reward available, continuing ...');
|
||||
for(let i=0; i<body.earnedItems.length; i++){
|
||||
await prisma.carItem.create({
|
||||
data: {
|
||||
carId: body.carId,
|
||||
category: body.earnedItems[i].category,
|
||||
itemId: body.earnedItems[i].itemId,
|
||||
amount: 1
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// Check if earned some items
|
||||
await gameFunction.getItem(body);
|
||||
// Get user item
|
||||
// User item reward from the game is available
|
||||
if(body.earnedUserItems.length !== 0)
|
||||
{
|
||||
console.log('User Item reward available, continuing ...');
|
||||
for(let i=0; i<body.earnedUserItems.length; i++){
|
||||
await prisma.userItem.create({
|
||||
data: {
|
||||
category: body.earnedUserItems[i].category,
|
||||
itemId: body.earnedUserItems[i].itemId,
|
||||
userId: body.car!.userId!,
|
||||
earnedAt: 0,
|
||||
type: 0
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// Update Car Data
|
||||
await gameFunction.updateCar(body, car);
|
||||
// Check playet at timestamp
|
||||
let timestamps = 0;
|
||||
if(body.car?.lastPlayedAt !== undefined && body.car?.lastPlayedAt !== null)
|
||||
{
|
||||
if(body.car.lastPlayedAt !== 0)
|
||||
{
|
||||
timestamps = body.car.lastPlayedAt;
|
||||
}
|
||||
else
|
||||
{
|
||||
timestamps = Math.floor(new Date().getTime() / 1000);
|
||||
}
|
||||
}
|
||||
|
||||
// Update Car Order and Save Tutorial
|
||||
await gameFunction.updateOrderTutorial(body);
|
||||
// Check P & H must not more than 34 (fully tuned value)
|
||||
let tunePower = 0;
|
||||
let tuneHandling = 0;
|
||||
let totalTune = body.car!.tunePower + body.car!.tuneHandling;
|
||||
if(totalTune <= 34)
|
||||
{
|
||||
tunePower = body.car!.tunePower;
|
||||
tuneHandling = body.car!.tuneHandling;
|
||||
}
|
||||
|
||||
// Update car
|
||||
await prisma.car.update({
|
||||
where: {
|
||||
carId: body.carId,
|
||||
},
|
||||
data: {
|
||||
aura: body.car!.aura!,
|
||||
auraMotif: body.car!.auraMotif!,
|
||||
odometer: body.odometer,
|
||||
playCount: body.playCount,
|
||||
level: body.car!.level!,
|
||||
title: body.car!.title!,
|
||||
tunePower: tunePower,
|
||||
tuneHandling: tuneHandling,
|
||||
windowSticker: body.car!.windowSticker!,
|
||||
lastPlayedAt: timestamps,
|
||||
regionId: body.car!.regionId!,
|
||||
rgStamp: common.sanitizeInputNotZero(body.rgResult?.rgStamp),
|
||||
stampSheetCount: common.sanitizeInputNotZero(body.rgResult?.stampSheetCount)
|
||||
}
|
||||
})
|
||||
|
||||
// Update car settings
|
||||
await prisma.carSettings.update({
|
||||
where: {
|
||||
dbId: car!.carSettingsDbId
|
||||
},
|
||||
data: {
|
||||
...body.setting
|
||||
}
|
||||
});
|
||||
|
||||
// Every n*100 play give reward
|
||||
// Check this feature config
|
||||
@ -117,15 +202,61 @@ export default class GameModule extends Module {
|
||||
await meter_reward.giveMeterRewards(body);
|
||||
}
|
||||
|
||||
// Update user
|
||||
let user = await prisma.user.findFirst({
|
||||
where: {
|
||||
id: body.car!.userId!
|
||||
}
|
||||
});
|
||||
|
||||
// -----------------------------------------------------------------------------------------------
|
||||
// Additional Message for Response Data
|
||||
let additionalSesionIdMsg = {};
|
||||
// User object exists
|
||||
if (user)
|
||||
{
|
||||
// Get user tutorials
|
||||
let storedTutorials = user!.tutorials;
|
||||
|
||||
// Update any seen tutorials
|
||||
body.confirmedTutorials.forEach(
|
||||
(idx) => storedTutorials[idx] = true
|
||||
);
|
||||
|
||||
// Get the order of the user's cars
|
||||
let carOrder = user?.carOrder;
|
||||
|
||||
// Get the index of the selected car
|
||||
let index = carOrder.indexOf(body.carId);
|
||||
|
||||
// Only splice array when item is found
|
||||
if (index > -1)
|
||||
{
|
||||
carOrder.splice(index, 1); // 2nd parameter means remove one item only
|
||||
}
|
||||
|
||||
// Add it back to the front
|
||||
carOrder.unshift(body.carId);
|
||||
|
||||
// Otherwise, just ignore it
|
||||
|
||||
// Update the values
|
||||
await prisma.user.update({
|
||||
where: {
|
||||
id: body.car!.userId!
|
||||
},
|
||||
data: {
|
||||
tutorials: storedTutorials,
|
||||
carOrder: carOrder
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// Response data
|
||||
let msg;
|
||||
|
||||
// Ghost Battle mode or Crown Ghost Battle game mode is completed
|
||||
if(ghostModePlay === true && OCMModePlay === false && updateNewTrail === true)
|
||||
{
|
||||
additionalSesionIdMsg = {
|
||||
msg = {
|
||||
error: wm.wm.protobuf.ErrorCode.ERR_SUCCESS,
|
||||
|
||||
// Set session for saving ghost trail Ghost Battle Mode or Crown Ghost Battle Mode
|
||||
ghostSessionId: Math.floor(Math.random() * 100) + 1
|
||||
@ -134,24 +265,21 @@ export default class GameModule extends Module {
|
||||
// OCM Battle game mode is completed
|
||||
else if(ghostModePlay === true && OCMModePlay === true && updateNewTrail === true)
|
||||
{
|
||||
additionalSesionIdMsg = {
|
||||
msg = {
|
||||
error: wm.wm.protobuf.ErrorCode.ERR_SUCCESS,
|
||||
|
||||
// Set session for saving ghost trail Competition (OCM) Ghost Battle Mode
|
||||
// Set session for saving ghost trail OCM Ghost Battle Mode
|
||||
ghostSessionId: Math.floor(Math.random() * 100) + 101
|
||||
}
|
||||
}
|
||||
// -----------------------------------------------------------------------------------------------
|
||||
// Story mode or TA mode is completed
|
||||
else
|
||||
{
|
||||
msg = {
|
||||
error: wm.wm.protobuf.ErrorCode.ERR_SUCCESS
|
||||
|
||||
|
||||
// Response data
|
||||
let msg = {
|
||||
error: wm.wm.protobuf.ErrorCode.ERR_SUCCESS,
|
||||
|
||||
// Ghost Session ID
|
||||
...additionalSesionIdMsg,
|
||||
|
||||
// Available Tickets (maybe for VS)
|
||||
//availableTickets: wm.protobuf.UserItem[]
|
||||
// No session for saving ghost trail (not playing Ghost Battle Mode / Retiring)
|
||||
}
|
||||
}
|
||||
|
||||
// Encode the response
|
||||
@ -168,6 +296,9 @@ export default class GameModule extends Module {
|
||||
// Get the request content
|
||||
let body = wm.wm.protobuf.LoadGameHistoryRequest.decode(req.body);
|
||||
|
||||
// Empty list of time attack records for the player's car
|
||||
let ta_records : wm.wm.protobuf.LoadGameHistoryResponse.TimeAttackRecord[] = [];
|
||||
|
||||
// Get the car info
|
||||
let car = await prisma.car.findFirst({
|
||||
where: {
|
||||
@ -179,26 +310,242 @@ export default class GameModule extends Module {
|
||||
}
|
||||
});
|
||||
|
||||
// Get Time Attack Record
|
||||
let taRecords = await gameFunction.getTimeAttackRecord(body);
|
||||
// Get the car's time attack records
|
||||
let records = await prisma.timeAttackRecord.findMany({
|
||||
where: {
|
||||
carId: body.carId
|
||||
}
|
||||
});
|
||||
|
||||
// Get Ghost Battle Record
|
||||
let ghostBattleRecord = await gameFunction.getGhostBattleRecord(body);
|
||||
// Loop over all of the records
|
||||
for(let record of records)
|
||||
{
|
||||
// This code could probably be done with less DB calls in the future
|
||||
|
||||
// Calculate the total rank, total participants for the record
|
||||
let wholeData = await prisma.timeAttackRecord.findMany({
|
||||
where: {
|
||||
course: record.course
|
||||
},
|
||||
orderBy: {
|
||||
time: 'asc'
|
||||
}
|
||||
});
|
||||
|
||||
// Get the overall number of participants
|
||||
let wholeParticipants = wholeData.length;
|
||||
|
||||
// Whole rank (default: 1)
|
||||
let wholeRank = 1;
|
||||
|
||||
// Loop over all of the participants
|
||||
for(let row of wholeData)
|
||||
{
|
||||
// If the car ID does not match
|
||||
if (row.carId !== body.carId)
|
||||
{
|
||||
// Increment whole rank
|
||||
wholeRank++;
|
||||
}
|
||||
else // Model ID matches
|
||||
{
|
||||
// Break the loop
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Calculate the model rank, model participants for the record
|
||||
let modelData = await prisma.timeAttackRecord.findMany({
|
||||
where: {
|
||||
course: record.course,
|
||||
model: record.model
|
||||
},
|
||||
orderBy: {
|
||||
time: 'asc'
|
||||
}
|
||||
});
|
||||
|
||||
// Get the overall number of participants (with the same car model)
|
||||
let modelParticipants = modelData.length;
|
||||
|
||||
// Model rank (default: 1)
|
||||
let modelRank = 1;
|
||||
|
||||
// Loop over all of the participants
|
||||
for(let row of modelData)
|
||||
{
|
||||
// If the car ID does not match
|
||||
if (row.carId !== body.carId)
|
||||
{
|
||||
// Increment whole rank
|
||||
modelRank++;
|
||||
}
|
||||
else // Model ID matches
|
||||
{
|
||||
// Break the loop
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Generate the time attack record object and add it to the list
|
||||
ta_records.push(wm.wm.protobuf.LoadGameHistoryResponse.TimeAttackRecord.create({
|
||||
course: record.course,
|
||||
time: record.time,
|
||||
tunePower: record.tunePower,
|
||||
tuneHandling: record.tuneHandling,
|
||||
wholeParticipants: wholeParticipants,
|
||||
wholeRank: wholeRank,
|
||||
modelParticipants: modelParticipants,
|
||||
modelRank: modelRank
|
||||
}));
|
||||
}
|
||||
|
||||
// Get user ghost battle mode history data
|
||||
let ghostHistoryData = await prisma.ghostBattleRecord.findMany({
|
||||
where: {
|
||||
carId: body.carId,
|
||||
},
|
||||
orderBy: {
|
||||
playedAt: 'desc'
|
||||
},
|
||||
take: 3
|
||||
});
|
||||
|
||||
// Empty list of ghost battle history records for the player's car
|
||||
let list_ghostHistoryData: wm.wm.protobuf.LoadGameHistoryResponse.GhostBattleRecord[] = [];
|
||||
for(let i=0; i<ghostHistoryData.length; i++){
|
||||
|
||||
// User car setting
|
||||
let carSetings = wm.wm.protobuf.LoadGameHistoryResponse.GhostBattleRecord.GhostCarSetting.create({
|
||||
tunePower: ghostHistoryData![i].tunePower,
|
||||
tuneHandling: ghostHistoryData![i].tuneHandling,
|
||||
});
|
||||
|
||||
// ----Ghost Opponent 1----
|
||||
let ghostOpponentCar = await prisma.car.findFirst({
|
||||
where: {
|
||||
carId: ghostHistoryData![i].opponent1CarId!
|
||||
}
|
||||
});
|
||||
|
||||
// If opponent is default ghost or random ghost
|
||||
if(!(ghostOpponentCar)){
|
||||
ghostOpponentCar = await prisma.car.findFirst({});
|
||||
ghostOpponentCar!.name = 'S660';
|
||||
ghostOpponentCar!.manufacturer = 12;
|
||||
ghostOpponentCar!.model = 105;
|
||||
ghostOpponentCar!.visualModel = 130;
|
||||
ghostOpponentCar!.regionId = 18;
|
||||
ghostOpponentCar!.country = 'GLB';
|
||||
}
|
||||
|
||||
// Get Opponent 1 tune
|
||||
ghostOpponentCar!.tunePower = ghostHistoryData![i].opponent1TunePower!;
|
||||
ghostOpponentCar!.tuneHandling = ghostHistoryData![i].opponent1TuneHandling!;
|
||||
|
||||
// Get the Data
|
||||
let ghostOpponent = wm.wm.protobuf.LoadGameHistoryResponse.GhostBattleRecord.GhostBattleRecordCar.create({
|
||||
car: {
|
||||
...ghostOpponentCar!
|
||||
},
|
||||
result: ghostHistoryData![i].opponent1Result!
|
||||
});
|
||||
// ------------------------
|
||||
|
||||
// ----Ghost Opponent 2 & 3----
|
||||
// Empty list of ghost battle records for the player's car
|
||||
let ghostMob: wm.wm.protobuf.LoadGameHistoryResponse.GhostBattleRecord.GhostBattleRecordCar[] = [];
|
||||
|
||||
// ----Ghost Opponent 2----
|
||||
if(ghostHistoryData[i]?.opponent2CarId !== null && ghostHistoryData[i]?.opponent2CarId !== undefined)
|
||||
{
|
||||
let ghostOpponentCar2 = await prisma.car.findFirst({
|
||||
where: {
|
||||
carId: ghostHistoryData![i].opponent2CarId!
|
||||
}
|
||||
});
|
||||
|
||||
// If opponent is default ghost or random ghost
|
||||
if(!(ghostOpponentCar2)){
|
||||
ghostOpponentCar2 = await prisma.car.findFirst({});
|
||||
ghostOpponentCar2!.name = 'S660';
|
||||
ghostOpponentCar2!.manufacturer = 12;
|
||||
ghostOpponentCar2!.model = 105;
|
||||
ghostOpponentCar2!.visualModel = 130;
|
||||
ghostOpponentCar2!.regionId = 18;
|
||||
ghostOpponentCar2!.country = 'GLB';
|
||||
}
|
||||
|
||||
// Get Opponent 2 tune
|
||||
ghostOpponentCar2!.tunePower = ghostHistoryData![i].opponent2TunePower!;
|
||||
ghostOpponentCar2!.tuneHandling = ghostHistoryData![i].opponent2TuneHandling!;
|
||||
|
||||
// Get the Data
|
||||
ghostMob.push(wm.wm.protobuf.LoadGameHistoryResponse.GhostBattleRecord.GhostBattleRecordCar.create({
|
||||
car: {
|
||||
...ghostOpponentCar2!
|
||||
},
|
||||
result: ghostHistoryData![i].opponent2Result!
|
||||
}));
|
||||
}
|
||||
// ------------------------
|
||||
|
||||
// ----Ghost Opponent 3----
|
||||
if(ghostHistoryData[i]?.opponent3CarId !== null && ghostHistoryData[i]?.opponent3CarId !== undefined)
|
||||
{
|
||||
let ghostOpponentCar3 = await prisma.car.findFirst({
|
||||
where: {
|
||||
carId: ghostHistoryData![i].opponent3CarId!
|
||||
}
|
||||
});
|
||||
|
||||
// If opponent is default ghost or random ghost
|
||||
if(!(ghostOpponentCar3)){
|
||||
ghostOpponentCar3 = await prisma.car.findFirst({});
|
||||
ghostOpponentCar3!.name = 'S660';
|
||||
ghostOpponentCar3!.manufacturer = 12;
|
||||
ghostOpponentCar3!.model = 105;
|
||||
ghostOpponentCar3!.visualModel = 130;
|
||||
ghostOpponentCar3!.regionId = 18;
|
||||
ghostOpponentCar3!.country = 'GLB';
|
||||
}
|
||||
|
||||
// Get Opponent 3 tune
|
||||
ghostOpponentCar3!.tunePower = ghostHistoryData![i].opponent3TunePower!;
|
||||
ghostOpponentCar3!.tuneHandling = ghostHistoryData![i].opponent3TuneHandling!;
|
||||
|
||||
// Get the Data
|
||||
ghostMob.push(wm.wm.protobuf.LoadGameHistoryResponse.GhostBattleRecord.GhostBattleRecordCar.create({
|
||||
car: {
|
||||
...ghostOpponentCar3!
|
||||
},
|
||||
result: ghostHistoryData![i].opponent3Result!
|
||||
}));
|
||||
}
|
||||
// ----------------------------
|
||||
|
||||
// Push the ghost battle history data
|
||||
list_ghostHistoryData.push(wm.wm.protobuf.LoadGameHistoryResponse.GhostBattleRecord.create({
|
||||
carSetting: carSetings,
|
||||
opponent: ghostOpponent,
|
||||
mobs: ghostMob || null,
|
||||
area: ghostHistoryData![i].area,
|
||||
playedAt: ghostHistoryData![i].playedAt,
|
||||
playedShopName: ghostHistoryData![i].playedShopName
|
||||
}));
|
||||
}
|
||||
|
||||
// Get current date
|
||||
let date = Math.floor(new Date().getTime() / 1000);
|
||||
|
||||
// Response data
|
||||
let msg = {
|
||||
error: wm.wm.protobuf.ErrorCode.ERR_SUCCESS,
|
||||
|
||||
// Time Attack Record
|
||||
taRecords: taRecords.ta_records,
|
||||
taRankingUpdatedAt: taRecords.date,
|
||||
|
||||
// Ghost Battle Record
|
||||
ghostHistory: ghostBattleRecord.ghostBattle_records,
|
||||
taRecords: ta_records,
|
||||
taRankingUpdatedAt: date,
|
||||
ghostHistory: list_ghostHistoryData,
|
||||
ghostBattleCount: car!.rgPlayCount,
|
||||
ghostBattleWinCount: car!.rgWinCount,
|
||||
|
||||
// Stamp Sheet
|
||||
stampSheetCount: car!.stampSheetCount,
|
||||
stampSheet: car!.stampSheet
|
||||
}
|
||||
@ -225,27 +572,5 @@ export default class GameModule extends Module {
|
||||
// Send the response to the client
|
||||
common.sendResponse(message, res);
|
||||
})
|
||||
|
||||
|
||||
// Save Screenshot
|
||||
app.post('/method/save_screenshot', async (req, res) => {
|
||||
|
||||
// Get the request body
|
||||
let body = wm.wm.protobuf.SaveScreenshotRequest.decode(req.body);
|
||||
|
||||
// Perform the save screenshot request for the car
|
||||
await gameFunction.saveScreenshot(body);
|
||||
|
||||
// Response data
|
||||
let msg = {
|
||||
error: wm.wm.protobuf.ErrorCode.ERR_SUCCESS,
|
||||
};
|
||||
|
||||
// Encode the response
|
||||
let message = wm.wm.protobuf.SaveScreenshotResponse.encode(msg);
|
||||
|
||||
// Send the response to the client
|
||||
common.sendResponse(message, res);
|
||||
})
|
||||
}
|
||||
}
|
||||
|
@ -1,450 +0,0 @@
|
||||
import { prisma } from "../..";
|
||||
import { Config } from "../../config";
|
||||
import path from "path";
|
||||
import fs from "fs";
|
||||
|
||||
// Import Proto
|
||||
import { wm } from "../../wmmt/wm.proto";
|
||||
import * as wmproto from "../../wmmt/wm.proto";
|
||||
|
||||
// Import Util
|
||||
import * as common from "../util/common";
|
||||
|
||||
|
||||
// Get some item
|
||||
export async function getItem(body: wm.protobuf.SaveGameResultRequest)
|
||||
{
|
||||
// Get car item
|
||||
// Car item reward from the game is available
|
||||
if(body.earnedItems.length !== 0)
|
||||
{
|
||||
console.log('Car Item reward available, continuing ...');
|
||||
|
||||
for(let i=0; i<body.earnedItems.length; i++){
|
||||
await prisma.carItem.create({
|
||||
data: {
|
||||
carId: body.carId,
|
||||
category: body.earnedItems[i].category,
|
||||
itemId: body.earnedItems[i].itemId,
|
||||
amount: 1
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// Get user item
|
||||
// User item reward from the game is available
|
||||
if(body.earnedUserItems.length !== 0)
|
||||
{
|
||||
console.log('User Item reward available, continuing ...');
|
||||
|
||||
for(let i=0; i<body.earnedUserItems.length; i++){
|
||||
await prisma.userItem.create({
|
||||
data: {
|
||||
category: body.earnedUserItems[i].category,
|
||||
itemId: body.earnedUserItems[i].itemId,
|
||||
userId: body.car!.userId!,
|
||||
earnedAt: 0,
|
||||
type: 0
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Update the Car
|
||||
export async function updateCar(body: wm.protobuf.SaveGameResultRequest, car: any)
|
||||
{
|
||||
// Check playet at timestamp
|
||||
let timestamps = 0;
|
||||
if(body.car?.lastPlayedAt !== undefined && body.car?.lastPlayedAt !== null)
|
||||
{
|
||||
if(body.car.lastPlayedAt !== 0)
|
||||
{
|
||||
timestamps = body.car.lastPlayedAt;
|
||||
}
|
||||
else
|
||||
{
|
||||
timestamps = Math.floor(new Date().getTime() / 1000);
|
||||
}
|
||||
}
|
||||
|
||||
// Check P & H must not more than 34 (fully tuned value)
|
||||
let tunePower = 0;
|
||||
let tuneHandling = 0;
|
||||
let totalTune = body.car!.tunePower + body.car!.tuneHandling;
|
||||
if(totalTune <= 34)
|
||||
{
|
||||
tunePower = body.car!.tunePower;
|
||||
tuneHandling = body.car!.tuneHandling;
|
||||
}
|
||||
|
||||
// Update car
|
||||
await prisma.car.update({
|
||||
where: {
|
||||
carId: body.carId,
|
||||
},
|
||||
data: {
|
||||
aura: body.car!.aura!,
|
||||
auraMotif: body.car!.auraMotif!,
|
||||
odometer: body.odometer,
|
||||
playCount: body.playCount,
|
||||
level: body.car!.level!,
|
||||
title: body.car!.title!,
|
||||
tunePower: tunePower,
|
||||
tuneHandling: tuneHandling,
|
||||
windowSticker: body.car!.windowSticker!,
|
||||
lastPlayedAt: timestamps,
|
||||
rgStamp: common.sanitizeInputNotZero(body.rgResult?.rgStamp),
|
||||
stampSheetCount: common.sanitizeInputNotZero(body.rgResult?.stampSheetCount)
|
||||
}
|
||||
})
|
||||
|
||||
// Update car settings
|
||||
await prisma.carSettings.update({
|
||||
where: {
|
||||
dbId: car!.carSettingsDbId
|
||||
},
|
||||
data: {
|
||||
...body.setting
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
// Update Car Order and Saving Tutorial
|
||||
export async function updateOrderTutorial(body: wm.protobuf.SaveGameResultRequest)
|
||||
{
|
||||
// Get User
|
||||
let user = await prisma.user.findFirst({
|
||||
where: {
|
||||
id: body.car!.userId!
|
||||
}
|
||||
});
|
||||
|
||||
// User Available
|
||||
if (user)
|
||||
{
|
||||
// Get user tutorials
|
||||
let storedTutorials = user!.tutorials;
|
||||
|
||||
// Update any seen tutorials
|
||||
body.confirmedTutorials.forEach(
|
||||
(idx) => storedTutorials[idx] = true
|
||||
);
|
||||
|
||||
// Get the order of the user's cars
|
||||
let carOrder = user?.carOrder;
|
||||
|
||||
// Get the index of the selected car
|
||||
let index = carOrder.indexOf(body.carId);
|
||||
|
||||
// Only splice array when item is found
|
||||
if (index > -1)
|
||||
{
|
||||
carOrder.splice(index, 1); // 2nd parameter means remove one item only
|
||||
}
|
||||
|
||||
// Add it back to the front
|
||||
carOrder.unshift(body.carId);
|
||||
|
||||
// Otherwise, just ignore it
|
||||
|
||||
// Update the values
|
||||
await prisma.user.update({
|
||||
where: {
|
||||
id: body.car!.userId!
|
||||
},
|
||||
data: {
|
||||
tutorials: storedTutorials,
|
||||
carOrder: carOrder
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Get User's Time Attack Record
|
||||
export async function getTimeAttackRecord(body: wm.protobuf.LoadGameHistoryRequest)
|
||||
{
|
||||
// Empty list of time attack records for the player's car
|
||||
let ta_records : wmproto.wm.protobuf.LoadGameHistoryResponse.TimeAttackRecord[] = [];
|
||||
|
||||
// Get the car's time attack records
|
||||
let records = await prisma.timeAttackRecord.findMany({
|
||||
where: {
|
||||
carId: body.carId
|
||||
}
|
||||
});
|
||||
|
||||
// Loop over all of the records
|
||||
for(let record of records)
|
||||
{
|
||||
// This code could probably be done with less DB calls in the future
|
||||
|
||||
// Calculate the total rank, total participants for the record
|
||||
let wholeData = await prisma.timeAttackRecord.findMany({
|
||||
where: {
|
||||
course: record.course
|
||||
},
|
||||
orderBy: {
|
||||
time: 'asc'
|
||||
}
|
||||
});
|
||||
|
||||
// Get the overall number of participants
|
||||
let wholeParticipants = wholeData.length;
|
||||
|
||||
// Whole rank (default: 1)
|
||||
let wholeRank = 1;
|
||||
|
||||
// Loop over all of the participants
|
||||
for(let row of wholeData)
|
||||
{
|
||||
// If the car ID does not match
|
||||
if (row.carId !== body.carId)
|
||||
{
|
||||
// Increment whole rank
|
||||
wholeRank++;
|
||||
}
|
||||
else // Model ID matches
|
||||
{
|
||||
// Break the loop
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Calculate the model rank, model participants for the record
|
||||
let modelData = await prisma.timeAttackRecord.findMany({
|
||||
where: {
|
||||
course: record.course,
|
||||
model: record.model
|
||||
},
|
||||
orderBy: {
|
||||
time: 'asc'
|
||||
}
|
||||
});
|
||||
|
||||
// Get the overall number of participants (with the same car model)
|
||||
let modelParticipants = modelData.length;
|
||||
|
||||
// Model rank (default: 1)
|
||||
let modelRank = 1;
|
||||
|
||||
// Loop over all of the participants
|
||||
for(let row of modelData)
|
||||
{
|
||||
// If the car ID does not match
|
||||
if (row.carId !== body.carId)
|
||||
{
|
||||
// Increment whole rank
|
||||
modelRank++;
|
||||
}
|
||||
else // Model ID matches
|
||||
{
|
||||
// Break the loop
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Generate the time attack record object and add it to the list
|
||||
ta_records.push(wmproto.wm.protobuf.LoadGameHistoryResponse.TimeAttackRecord.create({
|
||||
course: record.course,
|
||||
time: record.time,
|
||||
tunePower: record.tunePower,
|
||||
tuneHandling: record.tuneHandling,
|
||||
wholeParticipants: wholeParticipants,
|
||||
wholeRank: wholeRank,
|
||||
modelParticipants: modelParticipants,
|
||||
modelRank: modelRank
|
||||
}));
|
||||
}
|
||||
|
||||
// Get the current date/time (unix epoch)
|
||||
let date = Math.floor(new Date().getTime() / 1000);
|
||||
|
||||
return { ta_records, date }
|
||||
}
|
||||
|
||||
|
||||
// Get User's Ghost Battle Record
|
||||
export async function getGhostBattleRecord(body: wm.protobuf.LoadGameHistoryRequest)
|
||||
{
|
||||
// Get user ghost battle mode history data
|
||||
let ghostHistoryData = await prisma.ghostBattleRecord.findMany({
|
||||
where: {
|
||||
carId: body.carId,
|
||||
},
|
||||
orderBy: {
|
||||
playedAt: 'desc'
|
||||
},
|
||||
take: 3
|
||||
});
|
||||
|
||||
// Empty list of ghost battle history records for the player's car
|
||||
let ghostBattle_records: wmproto.wm.protobuf.LoadGameHistoryResponse.GhostBattleRecord[] = [];
|
||||
for(let i=0; i<ghostHistoryData.length; i++)
|
||||
{
|
||||
// User car setting
|
||||
let carSetings = wmproto.wm.protobuf.LoadGameHistoryResponse.GhostBattleRecord.GhostCarSetting.create({
|
||||
tunePower: ghostHistoryData![i].tunePower,
|
||||
tuneHandling: ghostHistoryData![i].tuneHandling,
|
||||
});
|
||||
|
||||
// ----Ghost Opponent 1----
|
||||
let ghostOpponentCar = await prisma.car.findFirst({
|
||||
where: {
|
||||
carId: ghostHistoryData![i].opponent1CarId!
|
||||
}
|
||||
});
|
||||
|
||||
// If opponent is default ghost or random ghost
|
||||
if(!(ghostOpponentCar))
|
||||
{
|
||||
ghostOpponentCar = await prisma.car.findFirst({});
|
||||
ghostOpponentCar!.name = 'S660';
|
||||
ghostOpponentCar!.manufacturer = 12;
|
||||
ghostOpponentCar!.model = 105;
|
||||
ghostOpponentCar!.visualModel = 130;
|
||||
ghostOpponentCar!.regionId = 18;
|
||||
ghostOpponentCar!.country = 'IDN';
|
||||
}
|
||||
|
||||
// Get Opponent 1 tune
|
||||
ghostOpponentCar!.tunePower = ghostHistoryData![i].opponent1TunePower!;
|
||||
ghostOpponentCar!.tuneHandling = ghostHistoryData![i].opponent1TuneHandling!;
|
||||
|
||||
// Get the Data
|
||||
let ghostOpponent = wmproto.wm.protobuf.LoadGameHistoryResponse.GhostBattleRecord.GhostBattleRecordCar.create({
|
||||
car: {
|
||||
...ghostOpponentCar!
|
||||
},
|
||||
result: ghostHistoryData![i].opponent1Result!
|
||||
});
|
||||
// ------------------------
|
||||
|
||||
// ----Ghost Opponent 2 & 3----
|
||||
// Empty list of ghost battle records for the player's car
|
||||
let ghostMob: wmproto.wm.protobuf.LoadGameHistoryResponse.GhostBattleRecord.GhostBattleRecordCar[] = [];
|
||||
|
||||
// ----Ghost Opponent 2----
|
||||
if(ghostHistoryData[i]?.opponent2CarId !== null && ghostHistoryData[i]?.opponent2CarId !== undefined)
|
||||
{
|
||||
let ghostOpponentCar2 = await prisma.car.findFirst({
|
||||
where: {
|
||||
carId: ghostHistoryData![i].opponent2CarId!
|
||||
}
|
||||
});
|
||||
|
||||
// If opponent is default ghost or random ghost
|
||||
if(!(ghostOpponentCar2))
|
||||
{
|
||||
ghostOpponentCar2 = await prisma.car.findFirst({});
|
||||
ghostOpponentCar2!.name = 'S660';
|
||||
ghostOpponentCar2!.manufacturer = 12;
|
||||
ghostOpponentCar2!.model = 105;
|
||||
ghostOpponentCar2!.visualModel = 130;
|
||||
ghostOpponentCar2!.regionId = 18;
|
||||
ghostOpponentCar2!.country = 'IDN';
|
||||
}
|
||||
|
||||
// Get Opponent 2 tune
|
||||
ghostOpponentCar2!.tunePower = ghostHistoryData![i].opponent2TunePower!;
|
||||
ghostOpponentCar2!.tuneHandling = ghostHistoryData![i].opponent2TuneHandling!;
|
||||
|
||||
// Get the Data
|
||||
ghostMob.push(wmproto.wm.protobuf.LoadGameHistoryResponse.GhostBattleRecord.GhostBattleRecordCar.create({
|
||||
car: {
|
||||
...ghostOpponentCar2!
|
||||
},
|
||||
result: ghostHistoryData![i].opponent2Result!
|
||||
}));
|
||||
}
|
||||
// ------------------------
|
||||
|
||||
// ----Ghost Opponent 3----
|
||||
if(ghostHistoryData[i]?.opponent3CarId !== null && ghostHistoryData[i]?.opponent3CarId !== undefined)
|
||||
{
|
||||
let ghostOpponentCar3 = await prisma.car.findFirst({
|
||||
where: {
|
||||
carId: ghostHistoryData![i].opponent3CarId!
|
||||
}
|
||||
});
|
||||
|
||||
// If opponent is default ghost or random ghost
|
||||
if(!(ghostOpponentCar3))
|
||||
{
|
||||
ghostOpponentCar3 = await prisma.car.findFirst({});
|
||||
ghostOpponentCar3!.name = 'S660';
|
||||
ghostOpponentCar3!.manufacturer = 12;
|
||||
ghostOpponentCar3!.model = 105;
|
||||
ghostOpponentCar3!.visualModel = 130;
|
||||
ghostOpponentCar3!.regionId = 18;
|
||||
ghostOpponentCar3!.country = 'IDN';
|
||||
}
|
||||
|
||||
// Get Opponent 3 tune
|
||||
ghostOpponentCar3!.tunePower = ghostHistoryData![i].opponent3TunePower!;
|
||||
ghostOpponentCar3!.tuneHandling = ghostHistoryData![i].opponent3TuneHandling!;
|
||||
|
||||
// Get the Data
|
||||
ghostMob.push(wmproto.wm.protobuf.LoadGameHistoryResponse.GhostBattleRecord.GhostBattleRecordCar.create({
|
||||
car: {
|
||||
...ghostOpponentCar3!
|
||||
},
|
||||
result: ghostHistoryData![i].opponent3Result!
|
||||
}));
|
||||
}
|
||||
// ----------------------------
|
||||
|
||||
// Push the ghost battle history data
|
||||
ghostBattle_records.push(wmproto.wm.protobuf.LoadGameHistoryResponse.GhostBattleRecord.create({
|
||||
carSetting: carSetings,
|
||||
opponent: ghostOpponent,
|
||||
mobs: ghostMob || null,
|
||||
area: ghostHistoryData![i].area,
|
||||
playedAt: ghostHistoryData![i].playedAt,
|
||||
playedShopName: ghostHistoryData![i].playedShopName
|
||||
}));
|
||||
}
|
||||
|
||||
return { ghostBattle_records }
|
||||
}
|
||||
|
||||
|
||||
// Save Screenshot
|
||||
export async function saveScreenshot(body: wm.protobuf.SaveScreenshotRequest)
|
||||
{
|
||||
// Check if screenshot feature enabled or not
|
||||
let enableScreenshot = Config.getConfig().gameOptions.enableScreenshot || 0;
|
||||
|
||||
// Screenshot feature enabled
|
||||
if(enableScreenshot === 1)
|
||||
{
|
||||
let filename: string | undefined = undefined;
|
||||
|
||||
filename = `${body.timestamp}_${body.carId}_${body.imageType}.png`;
|
||||
|
||||
let dir = path.join('screenshot');
|
||||
|
||||
if (!fs.existsSync(dir)){
|
||||
fs.mkdirSync(dir);
|
||||
}
|
||||
|
||||
// Combine the filename with the save location
|
||||
let fullname = path.join('screenshot', filename);
|
||||
|
||||
// Attempt to write to the file
|
||||
fs.writeFile(fullname, body.image, (err) => {
|
||||
if (err)
|
||||
{
|
||||
console.log(err);
|
||||
}
|
||||
else
|
||||
{
|
||||
console.log(`Screenshot saved successfully as '${filename}'`)
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
@ -3,17 +3,18 @@ import { Module } from "module";
|
||||
import { prisma } from "..";
|
||||
import { CarPathandTuning } from "@prisma/client";
|
||||
import Long from "long";
|
||||
import { Config } from "../config";
|
||||
|
||||
// Import Proto
|
||||
import * as wm from "../wmmt/wm.proto";
|
||||
import * as wmsrv from "../wmmt/service.proto";
|
||||
|
||||
// Import Util
|
||||
import * as common from "./util/common";
|
||||
import * as ghostFunctions from "./ghost/functions";
|
||||
import * as ghost_save_trail from "./ghost/ghost_save_trail";
|
||||
import * as ghost_trail from "./ghost/ghost_util/ghost_trail";
|
||||
import * as ghost_area from "./ghost/ghost_util/ghost_area";
|
||||
import * as common from "../util/common";
|
||||
import * as ghost_save_trail from "../util/ghost/ghost_save_trail";
|
||||
import * as ghost_trail from "../util/ghost/ghost_trail";
|
||||
import * as ghost_area from "../util/ghost/ghost_area";
|
||||
import * as ghost_default_car from "../util/ghost/ghost_default_car";
|
||||
|
||||
|
||||
export default class GhostModule extends Module {
|
||||
@ -33,35 +34,152 @@ export default class GhostModule extends Module {
|
||||
gtWing: true,
|
||||
lastPlayedPlace: true
|
||||
}
|
||||
})
|
||||
|
||||
// Car History
|
||||
let findChallenger = await prisma.carChallenger.findMany({
|
||||
where: {
|
||||
challengerCarId: body.carId
|
||||
},
|
||||
orderBy:{
|
||||
lastPlayedAt: 'desc'
|
||||
},
|
||||
take: 10
|
||||
})
|
||||
|
||||
let carsHistory: wm.wm.protobuf.Car[] = [];
|
||||
if(findChallenger.length > 0)
|
||||
{
|
||||
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
|
||||
});
|
||||
|
||||
// Get Challenged Opponent History
|
||||
let getStampTargets = await ghostFunctions.getOpponentHistory(body.carId);
|
||||
let opponentHistory = getStampTargets.opponentHistory;
|
||||
carsHistory.push(wm.wm.protobuf.Car.create({
|
||||
...car!
|
||||
}))
|
||||
}
|
||||
}
|
||||
|
||||
// Get Stamp Target
|
||||
let getStampTarget = await ghostFunctions.getStampTarget(body.carId);
|
||||
let stampTarget = getStampTarget.stampTarget;
|
||||
let carsStamp: wm.wm.protobuf.StampTargetCar[] = [];
|
||||
let carsChallenger: wm.wm.protobuf.ChallengerCar[] = [];
|
||||
|
||||
// Get Challengers
|
||||
let getChallengers = await ghostFunctions.getChallengers(body.carId);
|
||||
let challengers = getChallengers.challengers;
|
||||
// Get all of the friend cars for the carId provided
|
||||
let stampTargets = await prisma.carStampTarget.findMany({
|
||||
where: {
|
||||
stampTargetCarId: body.carId,
|
||||
recommended: true
|
||||
},
|
||||
orderBy:{
|
||||
locked: 'desc'
|
||||
}
|
||||
});
|
||||
|
||||
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,
|
||||
})
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
// Get all of the challenger car for the carId provided except beated car
|
||||
let checkBeatedCar = await prisma.carStampTarget.findMany({
|
||||
where: {
|
||||
stampTargetCarId: body.carId,
|
||||
recommended: false
|
||||
},
|
||||
orderBy:{
|
||||
carId: 'asc'
|
||||
}
|
||||
});
|
||||
|
||||
let arrChallengerCarId = [];
|
||||
for(let i=0; i<checkBeatedCar.length; i++)
|
||||
{
|
||||
arrChallengerCarId.push(checkBeatedCar[i].carId);
|
||||
}
|
||||
|
||||
let challengers = await prisma.carChallenger.findMany({
|
||||
where: {
|
||||
carId: body.carId,
|
||||
NOT: {
|
||||
challengerCarId: { in: arrChallengerCarId }, // Except beated challenger id
|
||||
},
|
||||
}
|
||||
});
|
||||
|
||||
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
|
||||
}
|
||||
})
|
||||
|
||||
let result = 0;
|
||||
if(challengers[i].result > 0)
|
||||
{
|
||||
result = -Math.abs(challengers[i].result);
|
||||
}
|
||||
else{
|
||||
result = Math.abs(challengers[i].result);
|
||||
}
|
||||
|
||||
carsChallenger.push(
|
||||
wm.wm.protobuf.ChallengerCar.create({
|
||||
car: carTarget!,
|
||||
stamp: challengers[i].stamp,
|
||||
result: result,
|
||||
area: challengers[i].area
|
||||
})
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
// Response data
|
||||
let msg = {
|
||||
error: wm.wm.protobuf.ErrorCode.ERR_SUCCESS,
|
||||
|
||||
// Challengers
|
||||
challengers: challengers || null,
|
||||
stampTargetCars: stampTarget || null,
|
||||
|
||||
// History
|
||||
history: opponentHistory || null,
|
||||
|
||||
// Stamp
|
||||
stampSheetCount: car?.stampSheetCount || 0,
|
||||
stampTargetCars: carsStamp || null,
|
||||
challengers: carsChallenger || null,
|
||||
stampSheetCount: car!.stampSheetCount,
|
||||
stampSheet: car?.stampSheet || null,
|
||||
stampReturnStats: car?.stampSheet || null,
|
||||
history: carsHistory || null,
|
||||
promotedToBuddy: false
|
||||
};
|
||||
|
||||
// Encode the response
|
||||
@ -78,19 +196,90 @@ export default class GhostModule extends Module {
|
||||
// Get the request body for the load stamp target request
|
||||
let body = wm.wm.protobuf.LoadStampTargetRequest.decode(req.body);
|
||||
|
||||
// Get Stamp Target
|
||||
let getStampTarget = await ghostFunctions.getStampTarget(body.carId);
|
||||
let stampTarget = getStampTarget.stampTarget;
|
||||
let carsStamp: wm.wm.protobuf.StampTargetCar[] = [];
|
||||
let carsChallenger: wm.wm.protobuf.ChallengerCar[] = [];
|
||||
|
||||
// Get Challengers
|
||||
let getChallengers = await ghostFunctions.getChallengers(body.carId);
|
||||
let challengers = getChallengers.challengers;
|
||||
// Get all of the friend cars for the carId provided
|
||||
let stampTargets = await prisma.carStampTarget.findMany({
|
||||
where: {
|
||||
stampTargetCarId: body.carId,
|
||||
recommended: true
|
||||
},
|
||||
orderBy:{
|
||||
locked: 'asc'
|
||||
}
|
||||
});
|
||||
|
||||
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,
|
||||
})
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
// 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
|
||||
}
|
||||
})
|
||||
|
||||
let result = 0;
|
||||
if(challengers[i].result > 0)
|
||||
{
|
||||
result = -Math.abs(challengers[i].result);
|
||||
}
|
||||
else{
|
||||
result = Math.abs(challengers[i].result);
|
||||
}
|
||||
|
||||
carsChallenger.push(
|
||||
wm.wm.protobuf.ChallengerCar.create({
|
||||
car: carTarget!,
|
||||
stamp: challengers[i].stamp,
|
||||
result: result,
|
||||
area: challengers[i].area
|
||||
})
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
// Response data
|
||||
let msg = {
|
||||
error: wm.wm.protobuf.ErrorCode.ERR_SUCCESS,
|
||||
cars: stampTarget,
|
||||
challengers: challengers
|
||||
cars: carsStamp,
|
||||
challengers: carsChallenger
|
||||
};
|
||||
|
||||
// Encode the response
|
||||
@ -101,7 +290,7 @@ export default class GhostModule extends Module {
|
||||
})
|
||||
|
||||
|
||||
// Search Cars 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
|
||||
@ -137,36 +326,189 @@ export default class GhostModule extends Module {
|
||||
});
|
||||
}
|
||||
|
||||
// Randomizing the starting ramp and path based on selected area
|
||||
let rampVal = 0;
|
||||
let pathVal = 0;
|
||||
|
||||
// Get the ramp and path id
|
||||
let ghost_areas = await ghost_area.GhostArea(body.area);
|
||||
|
||||
// Set the value
|
||||
let rampVal = ghost_areas.rampVal;
|
||||
let pathVal = ghost_areas.pathVal;
|
||||
rampVal = ghost_areas.rampVal;
|
||||
pathVal = ghost_areas.pathVal;
|
||||
|
||||
// Get Ghost Car
|
||||
let getGhostCar = await ghostFunctions.getGhostCar(car, body.area, rampVal, pathVal);
|
||||
let lists_ghostcar = getGhostCar.lists_ghostcar;
|
||||
// Empty list of ghost car records
|
||||
let lists_ghostcar: wm.wm.protobuf.GhostCar[] = [];
|
||||
let arr = [];
|
||||
let maxNumber = 0;
|
||||
|
||||
// If all user car data available is more than 10 for certain level
|
||||
if(car.length > 10)
|
||||
{
|
||||
maxNumber = 10 // Limit to 10 (game default)
|
||||
}
|
||||
// If no more than 10
|
||||
else
|
||||
{
|
||||
maxNumber = car.length;
|
||||
}
|
||||
|
||||
// Choose the user's car data randomly to appear
|
||||
while(arr.length < maxNumber)
|
||||
{
|
||||
// Pick random car Id
|
||||
let randomNumber: number = Math.floor(Math.random() * car.length);
|
||||
if(arr.indexOf(randomNumber) === -1){
|
||||
|
||||
// Push current number to array
|
||||
arr.push(randomNumber);
|
||||
|
||||
// Check if ghost trail for certain car is available
|
||||
let ghost_trails = await prisma.ghostTrail.findFirst({
|
||||
where: {
|
||||
carId: car[randomNumber].carId,
|
||||
area: body.area,
|
||||
crownBattle: false
|
||||
},
|
||||
orderBy: {
|
||||
playedAt: 'desc'
|
||||
}
|
||||
});
|
||||
|
||||
// If regionId is 0 or not set, game will crash after defeating the ghost
|
||||
if(car[randomNumber]!.regionId === 0)
|
||||
{
|
||||
let randomRegionId = Math.floor(Math.random() * 47) + 1;
|
||||
car[randomNumber].regionId = randomRegionId;
|
||||
}
|
||||
|
||||
// Push user's car data without ghost trail
|
||||
if(!(ghost_trails))
|
||||
{
|
||||
lists_ghostcar.push(wm.wm.protobuf.GhostCar.create({
|
||||
car: car[randomNumber]
|
||||
}));
|
||||
}
|
||||
// Push user's car data with ghost trail
|
||||
else
|
||||
{
|
||||
// Set the tunePower used when playing certain area
|
||||
car[randomNumber].tunePower = ghost_trails!.tunePower;
|
||||
|
||||
// Set the tuneHandling used when playing certain area
|
||||
car[randomNumber].tuneHandling = ghost_trails!.tuneHandling;
|
||||
|
||||
// Push data to Ghost car proto
|
||||
lists_ghostcar.push(wm.wm.protobuf.GhostCar.create({
|
||||
car: car[randomNumber],
|
||||
nonhuman: false,
|
||||
type: wm.wm.protobuf.GhostType.GHOST_NORMAL,
|
||||
trailId: ghost_trails!.dbId!
|
||||
}));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Check again if car list for that selected region is available of not
|
||||
if(body.regionId !== null && body.regionId !== undefined && body.regionId !== 0 && car.length < 1)
|
||||
if(body.regionId !== null && body.regionId !== undefined && body.regionId !== 0)
|
||||
{
|
||||
let checkGhostSearchByRegion = await ghostFunctions.checkGhostSearchByRegion(body.ghostLevel, body.regionId);
|
||||
lists_ghostcar = checkGhostSearchByRegion.lists_ghostcar;
|
||||
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
|
||||
let ghost_default_cars = await ghost_default_car.DefaultGhostCarHonda();
|
||||
|
||||
// Push data to Ghost car proto
|
||||
lists_ghostcar.push(wm.wm.protobuf.GhostCar.create({
|
||||
car: {
|
||||
...ghost_default_cars.cars,
|
||||
regionId: body.regionId,
|
||||
tunePower: tunePowerDefault,
|
||||
tuneHandling: tuneHandlingDefault,
|
||||
lastPlayedAt: date,
|
||||
lastPlayedPlace: playedPlace
|
||||
},
|
||||
nonhuman: true,
|
||||
type: wm.wm.protobuf.GhostType.GHOST_DEFAULT,
|
||||
}))
|
||||
}
|
||||
|
||||
// else{} have car list
|
||||
}
|
||||
|
||||
// Response data
|
||||
let msg = {
|
||||
error: wm.wm.protobuf.ErrorCode.ERR_SUCCESS,
|
||||
|
||||
// Area Value
|
||||
ramp: rampVal,
|
||||
path: pathVal,
|
||||
|
||||
// Ghost Car List
|
||||
ghosts: lists_ghostcar,
|
||||
|
||||
// Ghost Selection Method
|
||||
selectionMethod: Number(wm.wm.protobuf.GhostSelectionMethod.GHOST_SELECT_BY_LEVEL)
|
||||
};
|
||||
|
||||
@ -178,6 +520,298 @@ export default class GhostModule extends Module {
|
||||
})
|
||||
|
||||
|
||||
app.post('/method/search_cars', async (req, res) => {
|
||||
|
||||
// Get the request body for the load ghost drive data request
|
||||
let body = wm.wm.protobuf.SearchCarsRequest.decode(req.body);
|
||||
|
||||
// Find ghost car
|
||||
let car;
|
||||
switch(body.selectionMethod)
|
||||
{
|
||||
// GHOST_SELECT_BY_MANUFACTURER = 16
|
||||
case wm.wm.protobuf.GhostSelectionMethod.GHOST_SELECT_BY_MANUFACTURER:
|
||||
{
|
||||
let selectManufacturer = body.selectManufacturer;
|
||||
|
||||
car = await prisma.car.findMany({
|
||||
where:{
|
||||
manufacturer: selectManufacturer
|
||||
},
|
||||
include:{
|
||||
gtWing: true,
|
||||
lastPlayedPlace: true
|
||||
}
|
||||
});
|
||||
|
||||
break;
|
||||
}
|
||||
// GHOST_SELECT_BY_OTHER_MANUFACTURER = 17
|
||||
case wm.wm.protobuf.GhostSelectionMethod.GHOST_SELECT_BY_OTHER_MANUFACTURER:
|
||||
{
|
||||
let selectManufacturer = body.selectManufacturer;
|
||||
|
||||
car = await prisma.car.findMany({
|
||||
where:{
|
||||
manufacturer: selectManufacturer
|
||||
},
|
||||
include:{
|
||||
gtWing: true,
|
||||
lastPlayedPlace: true
|
||||
}
|
||||
});
|
||||
|
||||
break;
|
||||
}
|
||||
// GHOST_SELECT_BY_REGION_MANUFACTURER = 20
|
||||
case wm.wm.protobuf.GhostSelectionMethod.GHOST_SELECT_BY_REGION_MANUFACTURER:
|
||||
{
|
||||
let selectManufacturer = body.selectManufacturer;
|
||||
|
||||
car = await prisma.car.findMany({
|
||||
where:{
|
||||
manufacturer: selectManufacturer
|
||||
},
|
||||
include:{
|
||||
gtWing: true,
|
||||
lastPlayedPlace: true
|
||||
}
|
||||
});
|
||||
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
car = await prisma.car.findMany({
|
||||
include:{
|
||||
gtWing: true,
|
||||
lastPlayedPlace: true
|
||||
}
|
||||
});
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
// Randomizing the starting ramp and path based on selected area
|
||||
let rampVal = 0;
|
||||
let pathVal = 0;
|
||||
|
||||
// Get the ramp and path id
|
||||
let ghost_areas = await ghost_area.GhostArea(body.area);
|
||||
|
||||
// Set the value
|
||||
rampVal = ghost_areas.rampVal;
|
||||
pathVal = ghost_areas.pathVal;
|
||||
|
||||
// Empty list of ghost car records
|
||||
let lists_ghostcar: wm.wm.protobuf.GhostCar[] = [];
|
||||
let arr = [];
|
||||
let maxNumber = 0;
|
||||
|
||||
if(car.length === 0)
|
||||
{
|
||||
if(body.selectionMethod === wm.wm.protobuf.GhostSelectionMethod.GHOST_SELECT_BY_MANUFACTURER ||
|
||||
body.selectionMethod === wm.wm.protobuf.GhostSelectionMethod.GHOST_SELECT_BY_OTHER_MANUFACTURER ||
|
||||
body.selectionMethod === wm.wm.protobuf.GhostSelectionMethod.GHOST_SELECT_BY_REGION_MANUFACTURER)
|
||||
{
|
||||
// Default car here
|
||||
let ghost_default_cars: any;
|
||||
|
||||
if(body.selectManufacturer === 0) // BMW (Blood, Memory, Wonichan Moe)
|
||||
{
|
||||
ghost_default_cars = await ghost_default_car.DefaultGhostCarBMW();
|
||||
}
|
||||
else if(body.selectManufacturer === 1) // CHEVROLET
|
||||
{
|
||||
ghost_default_cars = await ghost_default_car.DefaultGhostCarChevrolet();
|
||||
}
|
||||
else if(body.selectManufacturer === 2) // MAZDA
|
||||
{
|
||||
ghost_default_cars = await ghost_default_car.DefaultGhostCarMazda();
|
||||
}
|
||||
else if(body.selectManufacturer === 3) // MERCEDES BENZ
|
||||
{
|
||||
// TODO: default car here
|
||||
ghost_default_cars = await ghost_default_car.DefaultGhostCarMercedes();
|
||||
}
|
||||
else if(body.selectManufacturer === 4) // MITSUBISHI
|
||||
{
|
||||
// TODO: default car here
|
||||
ghost_default_cars = await ghost_default_car.DefaultGhostCarMitsubishi();
|
||||
}
|
||||
else if(body.selectManufacturer === 5) // NISSAN
|
||||
{
|
||||
ghost_default_cars = await ghost_default_car.DefaultGhostCarNissan();
|
||||
}
|
||||
/*else if(body.selectManufacturer === 6) // ???
|
||||
{
|
||||
// TODO: default car here
|
||||
ghost_default_cars = await ghost_default_car.DefaultGhostCar???();
|
||||
}*/
|
||||
else if(body.selectManufacturer === 7) // SUBARU
|
||||
{
|
||||
// TODO: default car here
|
||||
ghost_default_cars = await ghost_default_car.DefaultGhostCarSubaru();
|
||||
}
|
||||
else if(body.selectManufacturer === 8) // TOYOTA
|
||||
{
|
||||
ghost_default_cars = await ghost_default_car.DefaultGhostCarToyota();
|
||||
}
|
||||
else if(body.selectManufacturer === 9) // AUDI
|
||||
{
|
||||
// TODO: default car here
|
||||
ghost_default_cars = await ghost_default_car.DefaultGhostCarAudi();
|
||||
}
|
||||
else if(body.selectManufacturer === 10) // DODGE
|
||||
{
|
||||
// TODO: default car here
|
||||
ghost_default_cars = await ghost_default_car.DefaultGhostCarDodge();
|
||||
}
|
||||
else if(body.selectManufacturer === 11) // LAMBORGHINI
|
||||
{
|
||||
ghost_default_cars = await ghost_default_car.DefaultGhostCarLamborghini();
|
||||
}
|
||||
else if(body.selectManufacturer === 12) // HONDA
|
||||
{
|
||||
ghost_default_cars = await ghost_default_car.DefaultGhostCarHonda();
|
||||
}
|
||||
else if(body.selectManufacturer === 13) // ACURA
|
||||
{
|
||||
ghost_default_cars = await ghost_default_car.DefaultGhostCarAcura();
|
||||
}
|
||||
else if(body.selectManufacturer === 14) // PORSCHE
|
||||
{
|
||||
ghost_default_cars = await ghost_default_car.DefaultGhostCarPorsche();
|
||||
}
|
||||
else // OTHER MAYBE?
|
||||
{
|
||||
ghost_default_cars = await ghost_default_car.DefaultGhostCarHonda();
|
||||
}
|
||||
|
||||
// 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
|
||||
});
|
||||
|
||||
for(let i=0; i<3; i++)
|
||||
{
|
||||
|
||||
lists_ghostcar.push(wm.wm.protobuf.GhostCar.create({
|
||||
car: {
|
||||
...ghost_default_cars.cars,
|
||||
carId: 999999999-i, // prevent dupilcate id
|
||||
lastPlayedAt: date,
|
||||
lastPlayedPlace: playedPlace
|
||||
|
||||
},
|
||||
area: body.area,
|
||||
ramp: rampVal,
|
||||
path: pathVal,
|
||||
nonhuman: true,
|
||||
}))
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// If all user car data available is more than 10 for certain level
|
||||
if(car.length > 10)
|
||||
{
|
||||
maxNumber = 10 // Limit to 10 (game default)
|
||||
}
|
||||
// If no more than 10
|
||||
else
|
||||
{
|
||||
maxNumber = car.length;
|
||||
}
|
||||
|
||||
// Choose the user's car data randomly to appear
|
||||
while(arr.length < maxNumber)
|
||||
{
|
||||
// Pick random car Id
|
||||
let randomNumber: number = Math.floor(Math.random() * car.length);
|
||||
if(arr.indexOf(randomNumber) === -1)
|
||||
{
|
||||
// Push current number to array
|
||||
arr.push(randomNumber);
|
||||
|
||||
// Check if ghost trail for certain car is available
|
||||
let ghost_trails = await prisma.ghostTrail.findFirst({
|
||||
where: {
|
||||
carId: car[randomNumber].carId,
|
||||
area: body.area,
|
||||
crownBattle: false
|
||||
},
|
||||
orderBy: {
|
||||
playedAt: 'desc'
|
||||
}
|
||||
});
|
||||
|
||||
// If regionId is 0 or not set, game will crash after defeating the ghost
|
||||
if(car[randomNumber]!.regionId === 0)
|
||||
{
|
||||
let randomRegionId = Math.floor(Math.random() * 47) + 1;
|
||||
car[randomNumber].regionId = randomRegionId;
|
||||
}
|
||||
|
||||
// Push user's car data without ghost trail
|
||||
if(!(ghost_trails))
|
||||
{
|
||||
lists_ghostcar.push(wm.wm.protobuf.GhostCar.create({
|
||||
car: car[randomNumber],
|
||||
area: body.area,
|
||||
ramp: rampVal,
|
||||
path: pathVal,
|
||||
nonhuman: true,
|
||||
type: wm.wm.protobuf.GhostType.GHOST_DEFAULT,
|
||||
}));
|
||||
}
|
||||
// Push user's car data with ghost trail
|
||||
else
|
||||
{
|
||||
// Set the tunePower used when playing certain area
|
||||
car[randomNumber].tunePower = ghost_trails!.tunePower;
|
||||
|
||||
// Set the tuneHandling used when playing certain area
|
||||
car[randomNumber].tuneHandling = ghost_trails!.tuneHandling;
|
||||
|
||||
// Push data to Ghost car proto
|
||||
lists_ghostcar.push(wm.wm.protobuf.GhostCar.create({
|
||||
car: car[randomNumber],
|
||||
area: body.area,
|
||||
ramp: rampVal,
|
||||
path: pathVal,
|
||||
nonhuman: false,
|
||||
type: wm.wm.protobuf.GhostType.GHOST_NORMAL,
|
||||
trailId: ghost_trails!.dbId!
|
||||
}));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Response data
|
||||
let msg = {
|
||||
error: wm.wm.protobuf.ErrorCode.ERR_SUCCESS,
|
||||
ramp: rampVal,
|
||||
path: pathVal,
|
||||
ghosts: lists_ghostcar,
|
||||
selectionMethod: wm.wm.protobuf.PathSelectionMethod.PATH_NORMAL
|
||||
};
|
||||
|
||||
// Encode the response
|
||||
let message = wm.wm.protobuf.SearchCarsResponse.encode(msg);
|
||||
|
||||
// Send the response to the client
|
||||
common.sendResponse(message, res);
|
||||
})
|
||||
|
||||
|
||||
// Load Normal Ghost Trail data
|
||||
app.post('/method/load_ghost_drive_data', async (req, res) => {
|
||||
|
||||
@ -197,7 +831,7 @@ export default class GhostModule extends Module {
|
||||
let ghost_trails = await prisma.ghostTrail.findFirst({
|
||||
where: {
|
||||
carId: body.carTunings[i].carId!,
|
||||
path: body.path,
|
||||
path: path,
|
||||
},
|
||||
orderBy: {
|
||||
playedAt: 'desc'
|
||||
@ -207,8 +841,7 @@ export default class GhostModule extends Module {
|
||||
// ---Get the user and opponent ghost trail data---
|
||||
let ghostType: number = wm.wm.protobuf.GhostType.GHOST_NORMAL;
|
||||
let lists_binarydriveData;
|
||||
if(ghost_trails?.driveData !== null && ghost_trails?.driveData !== undefined)
|
||||
{
|
||||
if(ghost_trails?.driveData !== null && ghost_trails?.driveData !== undefined){
|
||||
lists_binarydriveData = wm.wm.protobuf.BinaryData.create({
|
||||
data: ghost_trails!.driveData!,
|
||||
mergeSerial: ghost_trails!.driveDMergeSerial!
|
||||
@ -216,8 +849,7 @@ export default class GhostModule extends Module {
|
||||
}
|
||||
|
||||
let lists_binaryByArea
|
||||
if(ghost_trails?.trendBinaryByArea !== null && ghost_trails?.trendBinaryByArea !== undefined)
|
||||
{
|
||||
if(ghost_trails?.trendBinaryByArea !== null && ghost_trails?.trendBinaryByArea !== undefined){
|
||||
lists_binaryByArea = wm.wm.protobuf.BinaryData.create({
|
||||
data: ghost_trails!.trendBinaryByArea!,
|
||||
mergeSerial: ghost_trails!.byAreaMergeSerial!
|
||||
@ -225,8 +857,7 @@ export default class GhostModule extends Module {
|
||||
}
|
||||
|
||||
let lists_binaryByCar
|
||||
if(ghost_trails?.trendBinaryByCar !== null && ghost_trails?.trendBinaryByCar !== undefined)
|
||||
{
|
||||
if(ghost_trails?.trendBinaryByCar !== null && ghost_trails?.trendBinaryByCar !== undefined){
|
||||
lists_binaryByCar = wm.wm.protobuf.BinaryData.create({
|
||||
data: ghost_trails!.trendBinaryByCar!,
|
||||
mergeSerial: ghost_trails!.byCarMergeSerial!
|
||||
@ -234,8 +865,7 @@ export default class GhostModule extends Module {
|
||||
}
|
||||
|
||||
let lists_binaryByUser
|
||||
if(ghost_trails?.trendBinaryByUser !== null && ghost_trails?.trendBinaryByUser !== undefined)
|
||||
{
|
||||
if(ghost_trails?.trendBinaryByUser !== null && ghost_trails?.trendBinaryByUser !== undefined){
|
||||
lists_binaryByUser = wm.wm.protobuf.BinaryData.create({
|
||||
data: ghost_trails!.trendBinaryByUser!,
|
||||
mergeSerial: ghost_trails!.byUserMergeSerial!
|
||||
@ -258,7 +888,6 @@ export default class GhostModule extends Module {
|
||||
// Response data
|
||||
let msg = {
|
||||
error: wm.wm.protobuf.ErrorCode.ERR_SUCCESS,
|
||||
path: path,
|
||||
data: lists_ghostcar
|
||||
};
|
||||
|
||||
@ -286,7 +915,6 @@ export default class GhostModule extends Module {
|
||||
actualSessionId = common.getBigIntFromLong(body.ghostSessionId);
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------------------
|
||||
// OCM game mode session id
|
||||
if(actualSessionId > 100 && actualSessionId < 201)
|
||||
{
|
||||
@ -317,7 +945,6 @@ export default class GhostModule extends Module {
|
||||
await ghost_save_trail.savePathAndTuning(body);
|
||||
}
|
||||
}
|
||||
// -----------------------------------------------------------------------------------------
|
||||
|
||||
// Response data
|
||||
let msg = {
|
||||
@ -351,8 +978,6 @@ export default class GhostModule extends Module {
|
||||
// Query parameter from OCM Battle available
|
||||
if(pTrailId)
|
||||
{
|
||||
console.log('Requesting OCM Ghost Trail');
|
||||
|
||||
// Get the trail data
|
||||
let ghost_trails = await ghost_trail.getOCMGhostTrail(pCarId, pTrailId);
|
||||
|
||||
@ -365,8 +990,6 @@ export default class GhostModule extends Module {
|
||||
// Query parameter from Crown Ghost Battle available
|
||||
else
|
||||
{
|
||||
console.log('Requesting Crown Ghost Trail');
|
||||
|
||||
// Get the crown trail data
|
||||
let ghost_trails = await ghost_trail.getCrownGhostTrail(pCarId, pArea);
|
||||
|
||||
|
@ -1,398 +0,0 @@
|
||||
import { Config } from "../../config";
|
||||
import { prisma } from "../..";
|
||||
|
||||
// Import Proto
|
||||
import * as wmproto from "../../wmmt/wm.proto";
|
||||
|
||||
// Get Challenged Opponent History
|
||||
export async function getOpponentHistory(carId: number)
|
||||
{
|
||||
// Car History
|
||||
let findChallenger = await prisma.carChallenger.findMany({
|
||||
where: {
|
||||
challengerCarId: carId
|
||||
},
|
||||
orderBy:{
|
||||
lastPlayedAt: 'desc'
|
||||
},
|
||||
take: 20
|
||||
});
|
||||
let opponentHistory: wmproto.wm.protobuf.Car[] = [];
|
||||
let inserted = 0;
|
||||
|
||||
if(findChallenger.length > 0)
|
||||
{
|
||||
for(let i=0; i<findChallenger.length; i++)
|
||||
{
|
||||
let car = await prisma.car.findFirst({
|
||||
where: {
|
||||
carId: findChallenger[i].carId
|
||||
},
|
||||
include:{
|
||||
gtWing: true,
|
||||
lastPlayedPlace: true
|
||||
}
|
||||
});
|
||||
|
||||
if(car)
|
||||
{
|
||||
// Error handling if regionId is below 1 or above 47
|
||||
if(car!.regionId < 1 || car!.regionId > 47)
|
||||
{
|
||||
car!.regionId = Math.floor(Math.random() * 10) + 10;
|
||||
}
|
||||
|
||||
opponentHistory.push(wmproto.wm.protobuf.Car.create({
|
||||
...car!
|
||||
}));
|
||||
|
||||
inserted++;
|
||||
}
|
||||
|
||||
if(inserted > 10)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return { opponentHistory }
|
||||
}
|
||||
|
||||
|
||||
// Get Stamp Target
|
||||
export async function getStampTarget(carId: number)
|
||||
{
|
||||
// Get all of the friend cars for the carId provided
|
||||
let getStampTargets = await prisma.carStampTarget.findMany({
|
||||
where: {
|
||||
stampTargetCarId: carId,
|
||||
recommended: true
|
||||
},
|
||||
orderBy:{
|
||||
locked: 'desc'
|
||||
},
|
||||
take: 10
|
||||
});
|
||||
let stampTarget: wmproto.wm.protobuf.StampTargetCar[] = [];
|
||||
|
||||
if(getStampTargets)
|
||||
{
|
||||
for(let i=0; i<getStampTargets.length; i++)
|
||||
{
|
||||
let carTarget = await prisma.car.findFirst({
|
||||
where:{
|
||||
carId: getStampTargets[i].carId
|
||||
},
|
||||
include:{
|
||||
gtWing: true,
|
||||
lastPlayedPlace: true
|
||||
}
|
||||
});
|
||||
|
||||
// Error handling if regionId is below 1 or above 47
|
||||
if(carTarget!.regionId < 1 || carTarget!.regionId > 47)
|
||||
{
|
||||
carTarget!.regionId = Math.floor(Math.random() * 10) + 10;
|
||||
}
|
||||
|
||||
stampTarget.push(
|
||||
wmproto.wm.protobuf.StampTargetCar.create({
|
||||
car: carTarget!,
|
||||
returnCount: getStampTargets[i].returnCount,
|
||||
locked: getStampTargets[i].locked,
|
||||
recommended: getStampTargets[i].recommended
|
||||
})
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
return { stampTarget }
|
||||
}
|
||||
|
||||
|
||||
// Get Challengers
|
||||
export async function getChallengers(carId: number)
|
||||
{
|
||||
// Get all of the challenger car for the carId provided except beated car
|
||||
let checkBeatedCar = await prisma.carStampTarget.findMany({
|
||||
where: {
|
||||
stampTargetCarId: carId,
|
||||
recommended: false
|
||||
},
|
||||
orderBy:{
|
||||
carId: 'asc'
|
||||
}
|
||||
});
|
||||
let challengers: wmproto.wm.protobuf.ChallengerCar[] = [];
|
||||
let arrChallengerCarId = [];
|
||||
|
||||
// Push beated carId to array
|
||||
for(let i=0; i<checkBeatedCar.length; i++)
|
||||
{
|
||||
arrChallengerCarId.push(checkBeatedCar[i].carId);
|
||||
}
|
||||
|
||||
// Find Opponent Challengers except beated car
|
||||
let getChallengers = await prisma.carChallenger.findMany({
|
||||
where: {
|
||||
carId: carId,
|
||||
NOT: {
|
||||
challengerCarId: { in: arrChallengerCarId }, // Except beated challenger id
|
||||
}
|
||||
},
|
||||
take: 10
|
||||
});
|
||||
|
||||
if(getChallengers)
|
||||
{
|
||||
for(let i=0; i<getChallengers.length; i++)
|
||||
{
|
||||
let carTarget = await prisma.car.findFirst({
|
||||
where:{
|
||||
carId: getChallengers[i].challengerCarId
|
||||
},
|
||||
include:{
|
||||
gtWing: true,
|
||||
lastPlayedPlace: true
|
||||
}
|
||||
})
|
||||
|
||||
let result = 0;
|
||||
if(getChallengers[i].result > 0)
|
||||
{
|
||||
result = -Math.abs(getChallengers[i].result);
|
||||
}
|
||||
else{
|
||||
result = Math.abs(getChallengers[i].result);
|
||||
}
|
||||
|
||||
// Error handling if regionId is below 1 or above 47
|
||||
if(carTarget!.regionId < 1 || carTarget!.regionId > 47)
|
||||
{
|
||||
carTarget!.regionId = Math.floor(Math.random() * 10) + 10;
|
||||
}
|
||||
|
||||
challengers.push(
|
||||
wmproto.wm.protobuf.ChallengerCar.create({
|
||||
car: carTarget!,
|
||||
stamp: getChallengers[i].stamp,
|
||||
result: result,
|
||||
area: getChallengers[i].area
|
||||
})
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
return { challengers }
|
||||
}
|
||||
|
||||
|
||||
// Get Ghost Car
|
||||
export async function getGhostCar(car: any, area: number, ramp: number, path: number)
|
||||
{
|
||||
// Empty list of ghost car records
|
||||
let lists_ghostcar: wmproto.wm.protobuf.GhostCar[] = [];
|
||||
let arr = [];
|
||||
let maxNumber = 0;
|
||||
|
||||
// If all user car data available is more than 10 for certain level
|
||||
if(car.length > 10)
|
||||
{
|
||||
maxNumber = 10 // Limit to 10 (game default)
|
||||
}
|
||||
// If no more than 10
|
||||
else
|
||||
{
|
||||
maxNumber = car.length;
|
||||
}
|
||||
|
||||
// Choose the user's car data randomly to appear
|
||||
while(arr.length < maxNumber)
|
||||
{
|
||||
// Randomize pick
|
||||
let random: number = 1;
|
||||
|
||||
// Randomize it 5 times
|
||||
for(let i=0; i<5; i++)
|
||||
{
|
||||
random = Math.floor(Math.random() * car.length);
|
||||
}
|
||||
|
||||
// Try randomize it again if it's 1
|
||||
if(random === 1)
|
||||
{
|
||||
random = Math.floor(Math.random() * car.length);
|
||||
}
|
||||
|
||||
|
||||
if(arr.indexOf(random) === -1)
|
||||
{
|
||||
// Push current number to array
|
||||
arr.push(random);
|
||||
|
||||
// Check if ghost trail for certain car is available
|
||||
let ghost_trails = await prisma.ghostTrail.findFirst({
|
||||
where: {
|
||||
carId: car[random].carId,
|
||||
area: area,
|
||||
crownBattle: false
|
||||
},
|
||||
orderBy: {
|
||||
playedAt: 'desc'
|
||||
}
|
||||
});
|
||||
|
||||
// Error handling if regionId is below 1 or above 47
|
||||
if(car!.regionId < 1 || car!.regionId > 47)
|
||||
{
|
||||
car!.regionId = Math.floor(Math.random() * 10) + 10;
|
||||
}
|
||||
|
||||
// Push user's car data without ghost trail
|
||||
if(!(ghost_trails))
|
||||
{
|
||||
lists_ghostcar.push(wmproto.wm.protobuf.GhostCar.create({
|
||||
car: car[random]
|
||||
}));
|
||||
}
|
||||
// Push user's car data with ghost trail
|
||||
else
|
||||
{
|
||||
// Set the tunePower used when playing certain area
|
||||
car[random].tunePower = ghost_trails!.tunePower;
|
||||
|
||||
// Set the tuneHandling used when playing certain area
|
||||
car[random].tuneHandling = ghost_trails!.tuneHandling;
|
||||
|
||||
// Push data to Ghost car proto
|
||||
lists_ghostcar.push(wmproto.wm.protobuf.GhostCar.create({
|
||||
car: car[random],
|
||||
nonhuman: false,
|
||||
type: wmproto.wm.protobuf.GhostType.GHOST_NORMAL,
|
||||
trailId: ghost_trails!.dbId!
|
||||
}));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return { lists_ghostcar }
|
||||
}
|
||||
|
||||
|
||||
// Check Ghost Car when using Search by Region
|
||||
export async function checkGhostSearchByRegion(ghostLevel: number, regionId: number)
|
||||
{
|
||||
// Get current date
|
||||
let date = Math.floor(new Date().getTime() / 1000);
|
||||
|
||||
let playedPlace = wmproto.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(ghostLevel === 1)
|
||||
{
|
||||
tunePowerDefault = 1;
|
||||
tuneHandlingDefault = 4;
|
||||
}
|
||||
else if(ghostLevel === 2)
|
||||
{
|
||||
tunePowerDefault = 5;
|
||||
tuneHandlingDefault = 5;
|
||||
}
|
||||
else if(ghostLevel === 3)
|
||||
{
|
||||
tunePowerDefault = 8;
|
||||
tuneHandlingDefault = 7;
|
||||
}
|
||||
else if(ghostLevel === 4)
|
||||
{
|
||||
tunePowerDefault = 10;
|
||||
tuneHandlingDefault = 10;
|
||||
}
|
||||
else if(ghostLevel === 5)
|
||||
{
|
||||
tunePowerDefault = 15;
|
||||
tuneHandlingDefault = 10;
|
||||
}
|
||||
else if(ghostLevel === 6)
|
||||
{
|
||||
tunePowerDefault = 18;
|
||||
tuneHandlingDefault = 10;
|
||||
}
|
||||
else if(ghostLevel === 7)
|
||||
{
|
||||
tunePowerDefault = 20;
|
||||
tuneHandlingDefault = 10;
|
||||
}
|
||||
else if(ghostLevel === 8)
|
||||
{
|
||||
tunePowerDefault = 21;
|
||||
tuneHandlingDefault = 10;
|
||||
}
|
||||
else if(ghostLevel === 9)
|
||||
{
|
||||
tunePowerDefault = 22;
|
||||
tuneHandlingDefault = 10;
|
||||
}
|
||||
else if(ghostLevel === 10)
|
||||
{
|
||||
tunePowerDefault = 24;
|
||||
tuneHandlingDefault = 10;
|
||||
}
|
||||
else if(ghostLevel === 11)
|
||||
{
|
||||
tunePowerDefault = 24;
|
||||
tuneHandlingDefault = 24;
|
||||
}
|
||||
|
||||
// Generate default S660 car data
|
||||
let car = wmproto.wm.protobuf.Car.create({
|
||||
carId: 999999999, // Don't change this
|
||||
name: 'S660',
|
||||
regionId: 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: 'BAYSHORE',
|
||||
windowStickerFont: 0,
|
||||
title: 'No Ghost for this Region',
|
||||
level: 65, // SSSSS
|
||||
lastPlayedAt: date,
|
||||
country: 'JPN',
|
||||
lastPlayedPlace: playedPlace
|
||||
});
|
||||
|
||||
// Push data to Ghost car proto
|
||||
let lists_ghostcar: wmproto.wm.protobuf.GhostCar[] = [];
|
||||
lists_ghostcar.push(wmproto.wm.protobuf.GhostCar.create({
|
||||
car: car,
|
||||
nonhuman: true,
|
||||
type: wmproto.wm.protobuf.GhostType.GHOST_DEFAULT,
|
||||
}));
|
||||
|
||||
return { lists_ghostcar }
|
||||
}
|
@ -1,391 +0,0 @@
|
||||
// Import 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_stamp";
|
||||
import * as ghost_get_area_from_path from "./ghost_util/ghost_get_area_from_path";
|
||||
|
||||
|
||||
// Save ghost history battle
|
||||
export async function saveGhostHistory(body: wm.protobuf.SaveGameResultRequest)
|
||||
{
|
||||
console.log('Saving Ghost Battle History');
|
||||
|
||||
let updateNewTrail: boolean = true;
|
||||
let saveExGhostHistory: any = {};
|
||||
|
||||
// Get the car result for the car
|
||||
let car = body?.car;
|
||||
|
||||
if(car)
|
||||
{
|
||||
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 }
|
||||
}
|
||||
|
||||
|
||||
export async function saveOCMGhostHistory(body: wm.protobuf.SaveGameResultRequest)
|
||||
{
|
||||
let updateNewTrail: boolean = true;
|
||||
let saveExGhostHistory: any = {};
|
||||
|
||||
// Get the car result for the car
|
||||
let car = body?.car;
|
||||
|
||||
if(car)
|
||||
{
|
||||
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 the advantage distance between first opponent and user
|
||||
saveExGhostHistory.result = rgResult.opponents[0].result;
|
||||
}
|
||||
|
||||
// Get area
|
||||
if(common.sanitizeInput(rgResult.path))
|
||||
{
|
||||
let getArea = await ghost_get_area_from_path.getArea(rgResult.path);
|
||||
|
||||
saveExGhostHistory.area = getArea.area
|
||||
}
|
||||
}
|
||||
|
||||
// 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:{
|
||||
competitionId: 'desc'
|
||||
}
|
||||
});
|
||||
|
||||
// ----------Get available OCM Record (Qualifying or Main Draw)----------
|
||||
// Current date is OCM main draw
|
||||
let countGBR;
|
||||
if(ocmEventDate!.competitionStartAt < date && ocmEventDate!.competitionCloseAt > date)
|
||||
{
|
||||
// Set OCM Main draw value to true
|
||||
saveExGhostHistory.ocmMainDraw = true
|
||||
|
||||
// Get the user's available OCM Battle Record data
|
||||
countGBR = await prisma.oCMTally.findFirst({
|
||||
where:{
|
||||
carId: saveExGhostHistory.carId,
|
||||
competitionId: ocmEventDate!.competitionId,
|
||||
}
|
||||
});
|
||||
}
|
||||
// Current date is OCM qualifying day
|
||||
else
|
||||
{
|
||||
// Set OCM Main draw value to false
|
||||
saveExGhostHistory.ocmMainDraw = false
|
||||
|
||||
// Get the user's available OCM Battle Record data
|
||||
countGBR = await prisma.oCMGhostBattleRecord.findFirst({
|
||||
where:{
|
||||
carId: saveExGhostHistory.carId,
|
||||
ocmMainDraw: saveExGhostHistory.ocmMainDraw,
|
||||
competitionId: ocmEventDate!.competitionId,
|
||||
periodId: 0
|
||||
}
|
||||
});
|
||||
}
|
||||
// ----------------------------------------------------------------
|
||||
|
||||
// User have OCM Battle Record data available
|
||||
if(countGBR)
|
||||
{
|
||||
// Check if the newest advantage distance is bigger than the older advantage distance
|
||||
if(countGBR.result < saveExGhostHistory.result)
|
||||
{
|
||||
console.log('OCM Ghost Tally found');
|
||||
|
||||
// Current date is OCM Main Draw
|
||||
if(ocmEventDate!.competitionStartAt < date && ocmEventDate!.competitionCloseAt > date)
|
||||
{
|
||||
// Get OCM Period ID
|
||||
let OCM_periodId = await prisma.oCMPeriod.findFirst({
|
||||
where:{
|
||||
competitionId: ocmEventDate!.competitionId,
|
||||
startAt:
|
||||
{
|
||||
lte: date, // competitionStartAt is less than current date
|
||||
},
|
||||
closeAt:
|
||||
{
|
||||
gte: date, // competitionCloseAt is greater than current date
|
||||
}
|
||||
},
|
||||
select:{
|
||||
periodId: true
|
||||
}
|
||||
});
|
||||
|
||||
let checkGhost = await prisma.oCMGhostBattleRecord.findFirst({
|
||||
where:{
|
||||
carId: saveExGhostHistory.carId,
|
||||
competitionId: ocmEventDate!.competitionId,
|
||||
}
|
||||
});
|
||||
|
||||
if(checkGhost)
|
||||
{
|
||||
console.log('Updating OCM Ghost Battle Record entry');
|
||||
|
||||
// Get the user's available OCM Battle Record data
|
||||
let getGBR = await prisma.oCMGhostBattleRecord.findFirst({
|
||||
where:{
|
||||
carId: saveExGhostHistory.carId,
|
||||
competitionId: ocmEventDate!.competitionId,
|
||||
}
|
||||
});
|
||||
|
||||
// Update ghost battle record
|
||||
await prisma.oCMGhostBattleRecord.update({
|
||||
where:{
|
||||
dbId: getGBR!.dbId
|
||||
},
|
||||
data: {
|
||||
...saveExGhostHistory,
|
||||
competitionId: ocmEventDate!.competitionId,
|
||||
periodId: OCM_periodId!.periodId
|
||||
}
|
||||
});
|
||||
}
|
||||
else
|
||||
{
|
||||
console.log('Creating new OCM Ghost Battle Record entry');
|
||||
|
||||
// Create new ghost battle record
|
||||
await prisma.oCMGhostBattleRecord.create({
|
||||
data: {
|
||||
...saveExGhostHistory,
|
||||
competitionId: ocmEventDate!.competitionId,
|
||||
periodId: OCM_periodId!.periodId
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
console.log('Updating OCM Tally Record');
|
||||
|
||||
// Update the OCM Tally Record
|
||||
await prisma.oCMTally.update({
|
||||
where:{
|
||||
dbId: countGBR.dbId
|
||||
},
|
||||
data: {
|
||||
periodId: OCM_periodId!.periodId,
|
||||
result: body.rgResult!.opponents![0].result,
|
||||
tunePower: body.car?.tunePower!,
|
||||
tuneHandling: body.car?.tuneHandling!
|
||||
}
|
||||
});
|
||||
}
|
||||
// Current date is OCM Qualifying
|
||||
else
|
||||
{
|
||||
// Update ghost battle record
|
||||
await prisma.oCMGhostBattleRecord.update({
|
||||
where:{
|
||||
dbId: countGBR.dbId
|
||||
},
|
||||
data: {
|
||||
...saveExGhostHistory,
|
||||
competitionId: ocmEventDate!.competitionId,
|
||||
periodId: 0
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
// Newest advantage distance is smaller than the older advantage distance
|
||||
else
|
||||
{
|
||||
console.log('Result record is lower than previous record');
|
||||
|
||||
// Don't update the User's OCM ghost trail
|
||||
updateNewTrail = false;
|
||||
}
|
||||
}
|
||||
// User don't have OCM Battle Record data available
|
||||
else
|
||||
{
|
||||
console.log('OCM Ghost Battle Record not found');
|
||||
console.log('Creating new OCM Ghost Battle Record entry');
|
||||
|
||||
// Current date is OCM Main Draw
|
||||
if(ocmEventDate!.competitionStartAt < date && ocmEventDate!.competitionCloseAt > date)
|
||||
{
|
||||
// Get OCM Period ID
|
||||
let OCM_periodId = await prisma.oCMPeriod.findFirst({
|
||||
where:{
|
||||
competitionId: ocmEventDate!.competitionId,
|
||||
},
|
||||
orderBy:{
|
||||
periodId: 'desc'
|
||||
},
|
||||
select:{
|
||||
periodId: true
|
||||
}
|
||||
});
|
||||
|
||||
// Update ghost battle record
|
||||
await prisma.oCMGhostBattleRecord.create({
|
||||
data: {
|
||||
...saveExGhostHistory,
|
||||
competitionId: ocmEventDate!.competitionId,
|
||||
periodId: OCM_periodId!.periodId
|
||||
}
|
||||
});
|
||||
|
||||
let ocmTallyfind = await prisma.oCMTally.findFirst({
|
||||
where:{
|
||||
carId: saveExGhostHistory.carId,
|
||||
competitionId: ocmEventDate!.competitionId,
|
||||
},
|
||||
});
|
||||
|
||||
if(ocmTallyfind)
|
||||
{
|
||||
console.log('Updating OCM Tally Record');
|
||||
|
||||
// Update the OCM Tally Record
|
||||
await prisma.oCMTally.update({
|
||||
where:{
|
||||
dbId: ocmTallyfind.dbId
|
||||
},
|
||||
data: {
|
||||
periodId: OCM_periodId!.periodId,
|
||||
result: body.rgResult!.opponents![0].result,
|
||||
tunePower: body.car?.tunePower!,
|
||||
tuneHandling: body.car?.tuneHandling!
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
// Current date is OCM Qualifying
|
||||
else
|
||||
{
|
||||
// Update ghost battle record
|
||||
await prisma.oCMGhostBattleRecord.create({
|
||||
data: {
|
||||
...saveExGhostHistory,
|
||||
competitionId: ocmEventDate!.competitionId,
|
||||
periodId: 0
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// Return the value to 'BASE_PATH/src/util/games/ghost.ts'
|
||||
return { updateNewTrail }
|
||||
}
|
@ -7,9 +7,9 @@ import { Config } from "../config";
|
||||
import * as wm from "../wmmt/wm.proto";
|
||||
|
||||
// Import Util
|
||||
import * as common from "./util/common";
|
||||
import * as ghost_ocm from "./ghost/ghost_ocm";
|
||||
import * as ghost_ocm_area from "./ghost/ghost_util/ghost_ocm_area";
|
||||
import * as common from "../util/common";
|
||||
import * as ghost_ocm from "../util/ghost/ghost_ocm";
|
||||
import * as ghost_ocm_area from "../util/ghost/ghost_ocm_area";
|
||||
|
||||
|
||||
export default class GhostModule extends Module {
|
||||
@ -181,6 +181,7 @@ export default class GhostModule extends Module {
|
||||
// Get Current OCM Period
|
||||
let OCMCurrentPeriod = await prisma.oCMPeriod.findFirst({
|
||||
where: {
|
||||
competitionDbId: ocmEventDate!.dbId,
|
||||
competitionId: ocmEventDate!.competitionId
|
||||
},
|
||||
orderBy: {
|
||||
@ -419,9 +420,11 @@ export default class GhostModule extends Module {
|
||||
if(!(ocmEventDate))
|
||||
{
|
||||
ocmEventDate = await prisma.oCMEvent.findFirst({
|
||||
orderBy:{
|
||||
competitionId: 'desc'
|
||||
orderBy: [
|
||||
{
|
||||
dbId: 'desc'
|
||||
},
|
||||
],
|
||||
});
|
||||
}
|
||||
|
||||
@ -462,6 +465,9 @@ export default class GhostModule extends Module {
|
||||
carId: ocmTallyRecord!.carId,
|
||||
competitionId: ocmEventDate!.competitionId,
|
||||
periodId: period_id,
|
||||
area: areaVal,
|
||||
ramp: rampVal,
|
||||
path: pathVal,
|
||||
},
|
||||
orderBy:{
|
||||
playedAt: 'desc'
|
||||
@ -491,9 +497,6 @@ export default class GhostModule extends Module {
|
||||
// Set Ghost stuff Value
|
||||
cars!.lastPlayedAt = checkGhostTrail.playedAt
|
||||
ghostTrailId = checkGhostTrail.dbId!;
|
||||
areaVal = Number(checkGhostTrail.area);
|
||||
rampVal = Number(checkGhostTrail.ramp);
|
||||
pathVal = Number(checkGhostTrail.path);
|
||||
ghostTypes = wm.wm.protobuf.GhostType.GHOST_NORMAL;
|
||||
}
|
||||
}
|
||||
@ -508,6 +511,9 @@ export default class GhostModule extends Module {
|
||||
carId: 999999999,
|
||||
competitionId: ocmEventDate!.competitionId,
|
||||
periodId: 0,
|
||||
area: areaVal,
|
||||
ramp: rampVal,
|
||||
path: pathVal
|
||||
},
|
||||
orderBy:{
|
||||
playedAt: 'desc'
|
||||
@ -550,10 +556,7 @@ export default class GhostModule extends Module {
|
||||
});
|
||||
|
||||
// Set Ghost stuff Value
|
||||
ghostTrailId = checkGhostTrail!.dbId;
|
||||
areaVal = Number(checkGhostTrail!.area);
|
||||
rampVal = Number(checkGhostTrail!.ramp);
|
||||
pathVal = Number(checkGhostTrail!.path);
|
||||
ghostTrailId = checkGhostTrail!.dbId!;
|
||||
ghostTypes = wm.wm.protobuf.GhostType.GHOST_NORMAL;
|
||||
}
|
||||
else if(ocmEventDate!.competitionCloseAt < date && ocmEventDate!.competitionEndAt > date)
|
||||
|
620
src/modules/ghost_vsorg.ts
Normal file
620
src/modules/ghost_vsorg.ts
Normal file
@ -0,0 +1,620 @@
|
||||
import { Application } from "express";
|
||||
import { Module } from "module";
|
||||
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 GhostModule extends Module {
|
||||
register(app: Application): void {
|
||||
|
||||
app.post('/method/load_ghost_expedition_info', async (req, res) => {
|
||||
|
||||
// Get the request body for the load stamp target request
|
||||
let body = wm.wm.protobuf.LoadGhostExpeditionInfoRequest.decode(req.body);
|
||||
|
||||
// Get User data
|
||||
let userScores = await prisma.ghostExpedition.findFirst({
|
||||
where:{
|
||||
carId: body.carId,
|
||||
ghostExpeditionId: body.ghostExpeditionId
|
||||
}
|
||||
})
|
||||
|
||||
// Get local store score
|
||||
let localScores = await prisma.ghostExpedition.findMany({
|
||||
where:{
|
||||
ghostExpeditionId: body.ghostExpeditionId
|
||||
},
|
||||
orderBy:{
|
||||
score: 'desc'
|
||||
}
|
||||
})
|
||||
|
||||
// Totaling local store score
|
||||
let sumLocalScore = 0;
|
||||
for(let i=0; i<localScores.length; i++)
|
||||
{
|
||||
sumLocalScore += localScores[i].score;
|
||||
}
|
||||
|
||||
// Response data
|
||||
let msg = {
|
||||
error: wm.wm.protobuf.ErrorCode.ERR_SUCCESS,
|
||||
sugorokuPoint: userScores?.sugorokuPoint || 0,
|
||||
score: userScores?.score || 0,
|
||||
localScore: sumLocalScore,
|
||||
};
|
||||
|
||||
// Encode the response
|
||||
let message = wm.wm.protobuf.LoadGhostExpeditionInfoResponse.encode(msg);
|
||||
|
||||
// Send the response to the client
|
||||
common.sendResponse(message, res);
|
||||
})
|
||||
|
||||
|
||||
app.post('/method/load_ghost_expedition_target_by_path', async (req, res) => {
|
||||
|
||||
// Get the request body for the load stamp target request
|
||||
let body = wm.wm.protobuf.LoadGhostExpeditionTargetByPathRequest.decode(req.body);
|
||||
|
||||
let areaExpedition: wm.wm.protobuf.LoadGhostExpeditionTargetByPathResponse.AreaStats[] = [];
|
||||
|
||||
for(let j=0; j<19; j++)
|
||||
{
|
||||
// 14 - 16 are dummy area, 17 is C1 Closed
|
||||
if(j >= 14){
|
||||
j = 18; // GID_RUNAREA_HIROSHIMA
|
||||
}
|
||||
let areaVal = 0;
|
||||
let pathVal = 0;
|
||||
if(j === 0){ // GID_RUNAREA_C1
|
||||
areaVal = 0;
|
||||
pathVal = 0;
|
||||
}
|
||||
else if(j === 1){ // GID_RUNAREA_RING
|
||||
areaVal = 1;
|
||||
pathVal = 10;
|
||||
}
|
||||
else if(j === 2){ // GID_RUNAREA_SUBTOKYO_3_4
|
||||
areaVal = 2;
|
||||
pathVal = 16;
|
||||
}
|
||||
else if(j === 3){ // GID_RUNAREA_SUBTOKYO_5
|
||||
areaVal = 3;
|
||||
pathVal = 18;
|
||||
}
|
||||
else if(j === 4){ // GID_RUNAREA_WANGAN
|
||||
areaVal = 4;
|
||||
pathVal = 20;
|
||||
}
|
||||
else if(j === 5){ // GID_RUNAREA_K1
|
||||
areaVal = 5;
|
||||
pathVal = 27;
|
||||
}
|
||||
else if(j === 6){ // GID_RUNAREA_YAESU
|
||||
areaVal = 6;
|
||||
pathVal = 34;
|
||||
}
|
||||
else if(j === 7){ // GID_RUNAREA_YOKOHAMA
|
||||
areaVal = 7;
|
||||
pathVal = 38;
|
||||
}
|
||||
else if(j === 8){ // GID_RUNAREA_NAGOYA
|
||||
areaVal = 8;
|
||||
pathVal = 49;
|
||||
}
|
||||
else if(j === 9){ // GID_RUNAREA_OSAKA
|
||||
areaVal = 9;
|
||||
pathVal = 50;
|
||||
}
|
||||
else if(j === 10){ // GID_RUNAREA_KOBE
|
||||
areaVal = 10;
|
||||
pathVal = 54;
|
||||
}
|
||||
else if(j === 11){ // GID_RUNAREA_FUKUOKA
|
||||
areaVal = 11;
|
||||
pathVal = 58;
|
||||
}
|
||||
else if(j === 12){ // GID_RUNAREA_HAKONE
|
||||
areaVal = 12;
|
||||
pathVal = 62;
|
||||
}
|
||||
else if(j === 13){ // GID_RUNAREA_TURNPIKE
|
||||
areaVal = 13;
|
||||
pathVal = 64;
|
||||
}
|
||||
//14 - 16 are dummy area, 17 is GID_RUNAREA_C1_CLOSED
|
||||
else if(j === 18){ // GID_RUNAREA_HIROSHIMA
|
||||
areaVal = 18;
|
||||
pathVal = 56;
|
||||
}
|
||||
|
||||
// Get Wanted List
|
||||
let wantedInfo: wm.wm.protobuf.LoadGhostExpeditionTargetByPathResponse.AreaStats.WantedInfo[] = [];
|
||||
|
||||
let checkWantedList = await prisma.ghostExpeditionWantedCar.findMany({
|
||||
where:{
|
||||
ghostExpeditionId: body.ghostExpeditionId,
|
||||
area: j
|
||||
},
|
||||
orderBy:{
|
||||
bonus: 'desc'
|
||||
},
|
||||
take: 10
|
||||
})
|
||||
|
||||
// TODO: FIX THIS STUFF
|
||||
/* GAME SOMETIMES BUT MOSTLY WILL CRASH IF I ADDED WANTED INFO... HUH?!?!?!??!?!?! WTF GAME?!?!?
|
||||
if(checkWantedList.length > 0)
|
||||
{
|
||||
wantedInfo.push(wm.wm.protobuf.LoadGhostExpeditionTargetByPathResponse.AreaStats.WantedInfo.create({
|
||||
wantedLevel: checkWantedList[0].bonus,
|
||||
numOfWantedCars: checkWantedList.length
|
||||
}))
|
||||
|
||||
areaExpedition.push(wm.wm.protobuf.LoadGhostExpeditionTargetByPathResponse.AreaStats.create({
|
||||
area: areaVal,
|
||||
path: pathVal,
|
||||
wantedInfo: wantedInfo
|
||||
}));
|
||||
}
|
||||
else
|
||||
{
|
||||
areaExpedition.push(wm.wm.protobuf.LoadGhostExpeditionTargetByPathResponse.AreaStats.create({
|
||||
area: areaVal,
|
||||
path: pathVal,
|
||||
wantedInfo: null
|
||||
}));
|
||||
}*/
|
||||
|
||||
// Push the path per area (if not set.. all will become kandabashi ramp)
|
||||
areaExpedition.push(wm.wm.protobuf.LoadGhostExpeditionTargetByPathResponse.AreaStats.create({
|
||||
area: areaVal,
|
||||
path: pathVal,
|
||||
wantedInfo: null
|
||||
}));
|
||||
}
|
||||
|
||||
let msg = {
|
||||
error: wm.wm.protobuf.ErrorCode.ERR_SUCCESS,
|
||||
areas: areaExpedition,
|
||||
selectionMethod: wm.wm.protobuf.PathSelectionMethod.PATH_NORMAL // idk what this is
|
||||
};
|
||||
|
||||
// Encode the response
|
||||
let message = wm.wm.protobuf.LoadGhostExpeditionTargetByPathResponse.encode(msg);
|
||||
|
||||
// Send the response to the client
|
||||
common.sendResponse(message, res);
|
||||
})
|
||||
|
||||
app.post('/method/load_ghost_expedition_targets', async (req, res) => {
|
||||
|
||||
// Get the request body for the load stamp target request
|
||||
let body = wm.wm.protobuf.LoadGhostExpeditionTargetsRequest.decode(req.body);
|
||||
|
||||
// Get the area id and ramp id
|
||||
let area = 0;
|
||||
let ramp = 0; // this is important to set, if not.. the path shown when selecting car tune and loading screen will get randomized
|
||||
let path = 0;
|
||||
if(body.path)
|
||||
{
|
||||
if(body.path >= 0 && body.path <= 9){ // GID_PATH_C1
|
||||
area = Number(0);
|
||||
ramp = 0;
|
||||
}
|
||||
else if(body.path >= 10 && body.path <= 15){ // GID_PATH_N9
|
||||
area = Number(1);
|
||||
ramp = 4;
|
||||
}
|
||||
else if(body.path >= 16 && body.path <= 17){ // GID_PATH_WTEAST
|
||||
area = Number(2);
|
||||
ramp = 6;
|
||||
}
|
||||
else if(body.path >= 18 && body.path <= 19){ // GID_PATH_WT_UP_DOWN
|
||||
area = Number(3);
|
||||
ramp = 8;
|
||||
}
|
||||
else if(body.path >= 20 && body.path <= 26){ // GID_PATH_WG
|
||||
area = Number(4);
|
||||
ramp = 10;
|
||||
}
|
||||
else if(body.path >= 27 && body.path <= 33){ // GID_PATH_KG
|
||||
area = Number(5);
|
||||
ramp = 14;
|
||||
}
|
||||
else if(body.path >= 34 && body.path <= 37){ // GID_PATH_YS
|
||||
area = Number(6);
|
||||
ramp = 18;
|
||||
}
|
||||
else if(body.path >= 38 && body.path <= 48){ // GID_PATH_KG_SHINYAMASHITA_MINATOMIRAI
|
||||
area = Number(7);
|
||||
ramp = 21;
|
||||
}
|
||||
else if(body.path === 49){ // GID_PATH_NGR
|
||||
area = Number(8);
|
||||
ramp = 25;
|
||||
}
|
||||
else if(body.path >= 50 && body.path <= 53){ // GID_PATH_OS
|
||||
area = Number(9);
|
||||
ramp = 26;
|
||||
}
|
||||
else if(body.path >= 54 && body.path <= 55){ // GID_PATH_KB
|
||||
area = Number(10);
|
||||
ramp = 27;
|
||||
}
|
||||
else if(body.path >= 58 && body.path <= 61){ // GID_PATH_FK
|
||||
area = Number(11);
|
||||
ramp = 29;
|
||||
}
|
||||
else if(body.path >= 62 && body.path <= 63){ // GID_PATH_HK
|
||||
area = Number(12);
|
||||
ramp = 33;
|
||||
}
|
||||
else if(body.path >= 64 && body.path <= 65){ // GID_PATH_TP
|
||||
area = Number(13);
|
||||
ramp = 35;
|
||||
}
|
||||
else if(body.path >= 56 && body.path <= 57){ // GID_PATH_HS
|
||||
area = Number(18);
|
||||
ramp = 37;
|
||||
}
|
||||
|
||||
path = Number(body.path);
|
||||
}
|
||||
|
||||
let lists_candidates: wm.wm.protobuf.GhostCar[] = [];
|
||||
let lists_wanted: wm.wm.protobuf.WantedCar[] = [];
|
||||
|
||||
// Check wanted car
|
||||
let wantedCarList = await prisma.ghostExpeditionWantedCar.findMany({
|
||||
where:{
|
||||
ghostExpeditionId: body.ghostExpeditionId,
|
||||
area: area
|
||||
},
|
||||
take: 10
|
||||
})
|
||||
|
||||
// Make array for excluding wanted car from non wanted car
|
||||
let arrayWantedCarId = [];
|
||||
for(let i=0; i<wantedCarList.length; i++)
|
||||
{
|
||||
arrayWantedCarId.push(wantedCarList[i].carId);
|
||||
}
|
||||
|
||||
// Get Expedition (VSORG) VS Ghost Region
|
||||
let ghostExpeditionRegion = await prisma.ghostExpeditionEvent.findFirst({
|
||||
where: {
|
||||
ghostExpeditionId: body.ghostExpeditionId
|
||||
},
|
||||
});
|
||||
|
||||
let country = 'JPN';
|
||||
let regionId: number = 20;
|
||||
if(ghostExpeditionRegion!.opponentCountry === 'IDN')
|
||||
{
|
||||
country = 'IDN';
|
||||
regionId = 18;
|
||||
}
|
||||
else if(ghostExpeditionRegion!.opponentCountry === 'AUS')
|
||||
{
|
||||
country = 'AUS';
|
||||
regionId = 2;
|
||||
}
|
||||
else if(ghostExpeditionRegion!.opponentCountry === 'CHN')
|
||||
{
|
||||
country = 'CHN';
|
||||
regionId = 10;
|
||||
}
|
||||
else if(ghostExpeditionRegion!.opponentCountry === 'HKG')
|
||||
{
|
||||
country = 'HKG';
|
||||
regionId = 15;
|
||||
}
|
||||
else if(ghostExpeditionRegion!.opponentCountry === 'PHL')
|
||||
{
|
||||
country = 'PHL';
|
||||
regionId = 30;
|
||||
}
|
||||
|
||||
// Get Canditate list
|
||||
let car = await prisma.car.findMany({
|
||||
where:{
|
||||
NOT: {
|
||||
carId: { in: arrayWantedCarId }, // except wanted car
|
||||
}
|
||||
},
|
||||
include:{
|
||||
gtWing: true,
|
||||
lastPlayedPlace: true
|
||||
}
|
||||
});
|
||||
|
||||
let arr = [];
|
||||
let maxNumber = 0;
|
||||
|
||||
// If all user car data available is more than 10 for certain level
|
||||
if(car.length > 10)
|
||||
{
|
||||
maxNumber = 10 // Limit to 10 (game default)
|
||||
}
|
||||
// If no more than 10
|
||||
else
|
||||
{
|
||||
maxNumber = car.length;
|
||||
}
|
||||
|
||||
while(arr.length < maxNumber)
|
||||
{
|
||||
// Pick random car Id
|
||||
let randomNumber: number = Math.floor(Math.random() * car.length);
|
||||
|
||||
if(arr.indexOf(randomNumber) === -1)
|
||||
{
|
||||
// Push current number to array
|
||||
arr.push(randomNumber);
|
||||
|
||||
// Push data to Ghost car proto
|
||||
lists_candidates.push(wm.wm.protobuf.GhostCar.create({
|
||||
car: {
|
||||
...car[randomNumber],
|
||||
country: country,
|
||||
regionId: regionId
|
||||
},
|
||||
area: area,
|
||||
ramp: ramp,
|
||||
path: path,
|
||||
nonhuman: false,
|
||||
type: wm.wm.protobuf.GhostType.GHOST_REGION,
|
||||
}));
|
||||
}
|
||||
}
|
||||
|
||||
// Get store result performance
|
||||
let localScores = await prisma.ghostExpedition.findMany({
|
||||
where:{
|
||||
ghostExpeditionId: body.ghostExpeditionId
|
||||
}
|
||||
})
|
||||
let sumLocalScore = 0;
|
||||
let recentWinners: wm.wm.protobuf.CarEntry[] = []
|
||||
|
||||
for(let i=0; i<localScores.length; i++)
|
||||
{
|
||||
// total the local store score
|
||||
sumLocalScore += localScores[i].score;
|
||||
|
||||
if(localScores[i].carId !== body.carId)
|
||||
{
|
||||
let car = await prisma.car.findFirst({
|
||||
where:{
|
||||
carId: localScores[i].carId
|
||||
}
|
||||
});
|
||||
|
||||
// Push to recent store winner
|
||||
recentWinners.push(wm.wm.protobuf.CarEntry.create({
|
||||
name: car!.name,
|
||||
level: car!.level,
|
||||
title: car!.title,
|
||||
model: car!.model,
|
||||
visualModel: car!.visualModel,
|
||||
defaultColor: car!.defaultColor,
|
||||
score: localScores[i].score,
|
||||
}))
|
||||
}
|
||||
}
|
||||
|
||||
// Get Wanted List
|
||||
for(let i=0; i<wantedCarList.length; i++)
|
||||
{
|
||||
let wantedCar = await prisma.car.findFirst({
|
||||
where:{
|
||||
carId: wantedCarList[i].carId
|
||||
},
|
||||
include:{
|
||||
gtWing: true,
|
||||
lastPlayedPlace: true
|
||||
}
|
||||
});
|
||||
|
||||
if(wantedCar)
|
||||
{
|
||||
let ghostcar = wm.wm.protobuf.GhostCar.create({
|
||||
car: {
|
||||
...wantedCar,
|
||||
country: country,
|
||||
regionId: regionId
|
||||
},
|
||||
area: area,
|
||||
ramp: ramp,
|
||||
path: path,
|
||||
nonhuman: false,
|
||||
type: wm.wm.protobuf.GhostType.GHOST_REGION,
|
||||
});
|
||||
|
||||
let car = await prisma.car.findFirst({
|
||||
where:{
|
||||
carId: body.carId
|
||||
}
|
||||
})
|
||||
|
||||
// idk what hostages for
|
||||
let hostages = wm.wm.protobuf.CarEntry.create({
|
||||
name: car!.name,
|
||||
level: car!.level,
|
||||
title: car!.title,
|
||||
model: car!.model,
|
||||
visualModel: car!.visualModel,
|
||||
defaultColor: car!.defaultColor,
|
||||
score: wantedCarList[i].bonus, // idk what this is
|
||||
})
|
||||
|
||||
lists_wanted.push(wm.wm.protobuf.WantedCar.create({
|
||||
ghost: ghostcar,
|
||||
wantedId: wantedCar.carId, // id?
|
||||
bonus: wantedCarList[i].bonus, // for bonus store win
|
||||
numOfHostages: 1, // idk what this is for
|
||||
defeatedMeCount: wantedCarList[i].defeatedMeCount, // for bonus movements
|
||||
hostage: hostages // idk what this is for
|
||||
}))
|
||||
}
|
||||
}
|
||||
|
||||
// Response data
|
||||
let msg = {
|
||||
error: wm.wm.protobuf.ErrorCode.ERR_SUCCESS,
|
||||
candidates: lists_candidates,
|
||||
localScore: sumLocalScore,
|
||||
wantedCars: lists_wanted,
|
||||
recentWinners: recentWinners // store result performance
|
||||
};
|
||||
|
||||
// Encode the response
|
||||
let message = wm.wm.protobuf.LoadGhostExpeditionTargetsResponse.encode(msg);
|
||||
|
||||
// Send the response to the client
|
||||
common.sendResponse(message, res);
|
||||
})
|
||||
|
||||
|
||||
// Lock Wanted
|
||||
app.post('/method/lock_wanted', async (req, res) => {
|
||||
|
||||
// Get the request body for the load stamp target request
|
||||
let body = wmsrv.wm.protobuf.LockWantedRequest.decode(req.body);
|
||||
|
||||
// Get the current date/time (unix epoch)
|
||||
let date = Math.floor(new Date().getTime() / 1000);
|
||||
|
||||
// Wanted Lock Variable
|
||||
let locked: boolean = false;
|
||||
let lockTime: number = 0;
|
||||
|
||||
// Handling to auto unlock the Wanted Ghost
|
||||
await prisma.ghostExpeditionWantedCar.updateMany({
|
||||
where:{
|
||||
lockTime: {
|
||||
lt: date
|
||||
}
|
||||
},
|
||||
data:{
|
||||
locked: locked,
|
||||
lockTime: lockTime
|
||||
}
|
||||
});
|
||||
|
||||
// Lock the Wanted Ghost
|
||||
if(body.lockTime > 0)
|
||||
{
|
||||
locked = true;
|
||||
lockTime = date + 600;
|
||||
}
|
||||
|
||||
// Change the Wanted Ghost Lock Status
|
||||
await prisma.ghostExpeditionWantedCar.updateMany({
|
||||
where:{
|
||||
carId: body.wantedId
|
||||
},
|
||||
data:{
|
||||
locked: locked,
|
||||
lockTime: lockTime
|
||||
}
|
||||
});
|
||||
|
||||
// Response data
|
||||
let msg = {
|
||||
error: wm.wm.protobuf.ErrorCode.ERR_SUCCESS,
|
||||
};
|
||||
|
||||
// Encode the response
|
||||
let message = wmsrv.wm.protobuf.LockWantedResponse.encode(msg);
|
||||
|
||||
// Send the response to the client
|
||||
common.sendResponse(message, res);
|
||||
})
|
||||
|
||||
|
||||
// Load Ghost Expedition Result
|
||||
app.post('/method/load_ghost_expedition_result', async (req, res) => {
|
||||
|
||||
// Get the request body for the load stamp target request
|
||||
let body = wmsrv.wm.protobuf.LoadGhostExpeditionResultRequest.decode(req.body);
|
||||
|
||||
// Get User data
|
||||
let userScores = await prisma.ghostExpedition.findFirst({
|
||||
where:{
|
||||
carId: body.carId,
|
||||
ghostExpeditionId: body.ghostExpeditionId
|
||||
}
|
||||
})
|
||||
|
||||
// Get local store score
|
||||
let localScores = await prisma.ghostExpedition.findMany({
|
||||
where:{
|
||||
ghostExpeditionId: body.ghostExpeditionId
|
||||
},
|
||||
orderBy:{
|
||||
score: 'desc'
|
||||
}
|
||||
})
|
||||
|
||||
// Totaling local store score
|
||||
let sumLocalScore = 0;
|
||||
let ghostExpeditionRankings: wm.wm.protobuf.GhostExpeditionRankingEntry[] = []
|
||||
|
||||
for(let i=0; i<localScores.length; i++)
|
||||
{
|
||||
sumLocalScore += localScores[i].score;
|
||||
}
|
||||
|
||||
// Get car score
|
||||
for(let i=0; i<localScores.length; i++)
|
||||
{
|
||||
let car = await prisma.car.findFirst({
|
||||
where:{
|
||||
carId: localScores[i].carId
|
||||
},
|
||||
orderBy:{
|
||||
carId: 'asc'
|
||||
},
|
||||
include:{
|
||||
gtWing: true,
|
||||
lastPlayedPlace: true
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
if(car)
|
||||
{
|
||||
ghostExpeditionRankings.push(wm.wm.protobuf.GhostExpeditionRankingEntry.create({
|
||||
rank: i+1,
|
||||
score: localScores[i].score,
|
||||
car: car!
|
||||
}));
|
||||
}
|
||||
}
|
||||
|
||||
// Response data
|
||||
let msg = {
|
||||
error: wm.wm.protobuf.ErrorCode.ERR_SUCCESS,
|
||||
score: userScores?.score || 0,
|
||||
localScore: sumLocalScore,
|
||||
localRanking: ghostExpeditionRankings
|
||||
}
|
||||
|
||||
// Encode the response
|
||||
let message = wmsrv.wm.protobuf.LoadGhostExpeditionResultResponse.encode(msg);
|
||||
|
||||
// Send the response to the client
|
||||
common.sendResponse(message, res);
|
||||
})
|
||||
}
|
||||
}
|
@ -1,4 +1,4 @@
|
||||
import { Application } from "express";
|
||||
import e, { Application } from "express";
|
||||
import { Module } from "module";
|
||||
import { Config } from "../config";
|
||||
import { prisma } from "..";
|
||||
@ -9,9 +9,7 @@ import * as wm from "../wmmt/wm.proto";
|
||||
import * as wmsrv from "../wmmt/service.proto";
|
||||
|
||||
// Import Util
|
||||
import * as common from "./util/common";
|
||||
import * as crown_list from "./resource/crown_list";
|
||||
import * as ranking from "./resource/ranking";
|
||||
import * as common from "../util/common";
|
||||
|
||||
|
||||
export default class ResourceModule extends Module {
|
||||
@ -25,13 +23,10 @@ export default class ResourceModule extends Module {
|
||||
// Empty list of place records
|
||||
let places: wm.wm.protobuf.Place[] = [];
|
||||
|
||||
// Region ID must not 0
|
||||
let regionId = common.sanitizeInputNotZero(Number(Config.getConfig().regionId)) || 1;
|
||||
|
||||
// Response data
|
||||
places.push(new wm.wm.protobuf.Place({
|
||||
placeId: Config.getConfig().placeId || 'JPN0123',
|
||||
regionId: regionId,
|
||||
regionId: Number(Config.getConfig().regionId) || 1,
|
||||
shopName: Config.getConfig().shopName || 'Bayshore',
|
||||
country: Config.getConfig().country || 'JPN'
|
||||
}));
|
||||
@ -49,28 +44,12 @@ export default class ResourceModule extends Module {
|
||||
await prisma.placeList.create({
|
||||
data:{
|
||||
placeId: Config.getConfig().placeId || 'JPN0123',
|
||||
regionId: regionId,
|
||||
regionId: Number(Config.getConfig().regionId) || 1,
|
||||
shopName: Config.getConfig().shopName || 'Bayshore',
|
||||
country: Config.getConfig().country || 'JPN'
|
||||
}
|
||||
})
|
||||
}
|
||||
else
|
||||
{
|
||||
if(checkPlaceList.shopName !== Config.getConfig().shopName)
|
||||
{
|
||||
await prisma.placeList.update({
|
||||
where:{
|
||||
id: checkPlaceList.id
|
||||
},
|
||||
data:{
|
||||
regionId: regionId,
|
||||
shopName: Config.getConfig().shopName,
|
||||
country: Config.getConfig().country
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// Encode the response
|
||||
let message = wm.wm.protobuf.PlaceList.encode({places});
|
||||
@ -79,6 +58,7 @@ export default class ResourceModule extends Module {
|
||||
common.sendResponse(message, res);
|
||||
})
|
||||
|
||||
|
||||
// Get Ranking data for attract screen (TA, Ghost, VS)
|
||||
app.get('/resource/ranking', async (req, res) => {
|
||||
|
||||
@ -88,16 +68,252 @@ export default class ResourceModule extends Module {
|
||||
let lists: wmsrv.wm.protobuf.Ranking.List[] = [];
|
||||
|
||||
// Get TA Ranking
|
||||
let rankingTA = await ranking.getTimeAttackRanking();
|
||||
lists.push( ...rankingTA.lists );
|
||||
for(let i=0; i<25; i++){ // GID_TACOURSE ID
|
||||
|
||||
// Get VS Outrun Ranking
|
||||
let rankingVSOutrun = await ranking.getVSOutrunRanking();
|
||||
lists.push( ...rankingVSOutrun.lists );
|
||||
// Get the TA time per course
|
||||
let ta_time = await prisma.timeAttackRecord.findMany({
|
||||
where: {
|
||||
course: i
|
||||
},
|
||||
orderBy: {
|
||||
time: 'asc'
|
||||
},
|
||||
take: 10, // Take top 10
|
||||
});
|
||||
|
||||
// Get Ghost Trophies Ranking
|
||||
let rankingGhostTrophies = await ranking.getTGhostTrophiesRanking();
|
||||
lists.push( ...rankingGhostTrophies.lists );
|
||||
// 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: 'GUEST',
|
||||
regionId: 1, // Hokkaido
|
||||
model: Math.floor(Math.random() * 50), // Randomizing GUEST Car data
|
||||
visualModel: Math.floor(Math.random() * 100), // Randomizing GUEST 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 GUEST time attack
|
||||
let list_ta: wmsrv.wm.protobuf.Ranking.Entry[] = [];
|
||||
|
||||
// Generate the top 10 GUEST 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 GUEST data to the ranking data
|
||||
list_ta.push(wmsrv.wm.protobuf.Ranking.Entry.create({
|
||||
carId: 0,
|
||||
rank: 0,
|
||||
result: resulttime,
|
||||
name: 'GUEST',
|
||||
regionId: 1, // Hokkaido
|
||||
model: Math.floor(Math.random() * 50), // Randomizing GUEST Car data
|
||||
visualModel: Math.floor(Math.random() * 100), // Randomizing GUEST 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 GUEST data to the ranking data
|
||||
list_vs.push(wmsrv.wm.protobuf.Ranking.Entry.create({
|
||||
carId: 0,
|
||||
rank: 0,
|
||||
result: 0,
|
||||
name: 'GUEST',
|
||||
regionId: 1, // Hokkaido
|
||||
model: Math.floor(Math.random() * 50), // Randomizing GUEST Car data
|
||||
visualModel: Math.floor(Math.random() * 100), // Randomizing GUEST 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 GUEST data to the ranking data
|
||||
list_ghost.push(wmsrv.wm.protobuf.Ranking.Entry.create({
|
||||
carId: 0,
|
||||
rank: 0,
|
||||
result: 0,
|
||||
name: 'GUEST',
|
||||
regionId: 1, // Hokkaido
|
||||
model: Math.floor(Math.random() * 50), // Randomizing GUEST Car data
|
||||
visualModel: Math.floor(Math.random() * 100), // Randomizing GUEST 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});
|
||||
@ -113,14 +329,168 @@ export default class ResourceModule extends Module {
|
||||
console.log('crown_list');
|
||||
|
||||
// Empty list of crown records
|
||||
let crowns: wmsrv.wm.protobuf.Crown[] = [];
|
||||
let list_crown: wmsrv.wm.protobuf.Crown[] = [];
|
||||
|
||||
// Get Crown List
|
||||
let crown_lists = await crown_list.getCrownList();
|
||||
crowns.push( ...crown_lists.list_crown );
|
||||
// Get the crown holder data
|
||||
let car_crown = await prisma.carCrown.findMany({
|
||||
orderBy: {
|
||||
area: 'asc'
|
||||
},
|
||||
distinct: ['area']
|
||||
});
|
||||
|
||||
// Crown holder data available
|
||||
if(car_crown.length !== 0)
|
||||
{
|
||||
let counter = 0;
|
||||
|
||||
// Loop GID_RUNAREA
|
||||
for(let i=0; i<19; i++)
|
||||
{
|
||||
// After Kobe is Hiroshima then Fukuoka and the rest
|
||||
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
|
||||
}
|
||||
});
|
||||
|
||||
// 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
|
||||
// GID_RUNAREA_HIROSHIMA
|
||||
if(car_crown[counter].area === 18)
|
||||
{
|
||||
let listCrown = wmsrv.wm.protobuf.Crown.create({
|
||||
carId: car_crown[counter].carId,
|
||||
area: car_crown[counter].area,
|
||||
unlockAt: car_crown[counter].playedAt,
|
||||
car: car!
|
||||
});
|
||||
|
||||
list_crown.splice(11, 0, listCrown);
|
||||
}
|
||||
// GID_RUNAREA_C1 - GID_RUNAREA_TURNPIKE
|
||||
else
|
||||
{
|
||||
list_crown.push(wmsrv.wm.protobuf.Crown.create({
|
||||
carId: car_crown[counter].carId,
|
||||
area: car_crown[counter].area,
|
||||
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
|
||||
// GID_RUNAREA_HIROSHIMA
|
||||
if(i === 18)
|
||||
{
|
||||
let listCrown = wmsrv.wm.protobuf.Crown.create({
|
||||
carId: 999999999-i,
|
||||
area: i,
|
||||
unlockAt: 0,
|
||||
});
|
||||
|
||||
list_crown.splice(11, 0, listCrown);
|
||||
}
|
||||
// GID_RUNAREA_C1 - GID_RUNAREA_TURNPIKE
|
||||
else
|
||||
{
|
||||
list_crown.push(wmsrv.wm.protobuf.Crown.create({
|
||||
carId: 999999999-i,
|
||||
area: i,
|
||||
unlockAt: 0,
|
||||
}));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// There is no user's crown holder data available
|
||||
else
|
||||
{
|
||||
// Loop GID_RUNAREA
|
||||
for(let i=0; i<19; i++)
|
||||
{
|
||||
// After Kobe is Hiroshima then Fukuoka and the rest
|
||||
if(i > 14)
|
||||
{
|
||||
i = 18; // GID_RUNAREA_HIROSHIMA
|
||||
}
|
||||
|
||||
// Push the default data by the game to the crown holder data
|
||||
// GID_RUNAREA_HIROSHIMA
|
||||
if(i === 18)
|
||||
{
|
||||
let listCrown = wmsrv.wm.protobuf.Crown.create({
|
||||
carId: 999999999-i,
|
||||
area: i,
|
||||
unlockAt: 0,
|
||||
});
|
||||
|
||||
// Push it after Kobe
|
||||
list_crown.splice(11, 0, listCrown);
|
||||
}
|
||||
// GID_RUNAREA_C1 - GID_RUNAREA_TURNPIKE
|
||||
else
|
||||
{
|
||||
list_crown.push(wmsrv.wm.protobuf.Crown.create({
|
||||
carId: 999999999-i,
|
||||
area: i,
|
||||
unlockAt: 0,
|
||||
}));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Response data
|
||||
let msg = {
|
||||
crowns: list_crown
|
||||
};
|
||||
|
||||
// Encode the response
|
||||
let message = wmsrv.wm.protobuf.CrownList.encode( {crowns} );
|
||||
let message = wmsrv.wm.protobuf.CrownList.encode(msg);
|
||||
|
||||
// Send the response to the client
|
||||
common.sendResponse(message, res);
|
||||
@ -140,6 +510,7 @@ export default class ResourceModule extends Module {
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
res.sendFile(path.resolve(paths!.filePath, req.params.filename), { cacheControl: false });
|
||||
});
|
||||
|
||||
@ -208,5 +579,186 @@ export default class ResourceModule extends Module {
|
||||
// Send the response to the client
|
||||
common.sendResponse(message, res);
|
||||
})
|
||||
|
||||
|
||||
// Ghost Expedition (VSORG) Ranking
|
||||
app.get('/resource/ghost_expedition_ranking', async (req, res) => {
|
||||
|
||||
console.log('ghost_expedition_ranking');
|
||||
|
||||
let ghostExpeditionRankings: wm.wm.protobuf.GhostExpeditionRankingEntry[] = [];
|
||||
|
||||
// Get VSORG / Expedition Participant Ranking
|
||||
let localScores = await prisma.ghostExpedition.findMany({
|
||||
where:{
|
||||
ghostExpeditionId: Number(req.query.ghost_expedition_id)
|
||||
},
|
||||
orderBy:{
|
||||
score: 'desc'
|
||||
}
|
||||
})
|
||||
|
||||
// Get car score
|
||||
let car;
|
||||
let todaysMvps;
|
||||
for(let i=0; i<localScores.length; i++)
|
||||
{
|
||||
car = await prisma.car.findFirst({
|
||||
where:{
|
||||
carId: localScores[i].carId
|
||||
},
|
||||
orderBy:{
|
||||
carId: 'asc'
|
||||
},
|
||||
include:{
|
||||
gtWing: true,
|
||||
lastPlayedPlace: true
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
if(car)
|
||||
{
|
||||
ghostExpeditionRankings.push(wm.wm.protobuf.GhostExpeditionRankingEntry.create({
|
||||
rank: i+1,
|
||||
score: localScores[i].score,
|
||||
car: car!
|
||||
}));
|
||||
|
||||
if(i === 0)
|
||||
{
|
||||
todaysMvps = wm.wm.protobuf.GhostExpeditionRankingEntry.create({
|
||||
rank: i+1,
|
||||
score: localScores[i].score,
|
||||
car: car!
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Totaling score for store score
|
||||
let sum = 0;
|
||||
for(let i=0; i<localScores.length; i++)
|
||||
{
|
||||
sum += localScores[i].score;
|
||||
}
|
||||
|
||||
// Response data
|
||||
let msg = {
|
||||
localScore: sum,
|
||||
todaysMvp: todaysMvps || null,
|
||||
localRanking: ghostExpeditionRankings || null
|
||||
};
|
||||
|
||||
// Encode the response
|
||||
let message = wm.wm.protobuf.GhostExpeditionRanking.encode(msg);
|
||||
|
||||
// Send the response to the client
|
||||
common.sendResponse(message, res);
|
||||
})
|
||||
|
||||
|
||||
// Lock Wanted List
|
||||
app.get('/resource/lock_wanted_list', async (req, res) => {
|
||||
|
||||
console.log('lock_wanted_list');
|
||||
|
||||
let wanteds: wmsrv.wm.protobuf.WantedCar[] = [];
|
||||
|
||||
// TODO: Actual stuff here
|
||||
// This is literally just bare-bones so the shit boots
|
||||
|
||||
// Get the current date/time (unix epoch)
|
||||
let date = Math.floor(new Date().getTime() / 1000);
|
||||
|
||||
// Get VSORG Event Date
|
||||
let ghostExpeditionDate = await prisma.ghostExpeditionEvent.findFirst({
|
||||
where: {
|
||||
// qualifyingPeriodStartAt is less than equal current date
|
||||
startAt: { lte: date },
|
||||
|
||||
// competitionEndAt is greater than equal current date
|
||||
aftereventEndAt: { gte: date },
|
||||
},
|
||||
});
|
||||
|
||||
// Check Wanted Car
|
||||
let wantedCarList = await prisma.ghostExpeditionWantedCar.findMany({
|
||||
where:{
|
||||
ghostExpeditionId: ghostExpeditionDate?.ghostExpeditionId,
|
||||
locked: true
|
||||
}
|
||||
});
|
||||
|
||||
// Wanted Car Exists
|
||||
if(wantedCarList.length > 0)
|
||||
{
|
||||
for(let i=0; i<wantedCarList.length; i++)
|
||||
{
|
||||
let wantedCar = await prisma.car.findFirst({
|
||||
where:{
|
||||
carId: wantedCarList[i].carId
|
||||
}
|
||||
});
|
||||
|
||||
let ghostcar = wm.wm.protobuf.GhostCar.create({
|
||||
car: wantedCar!,
|
||||
area: wantedCarList[i].area,
|
||||
});
|
||||
|
||||
wanteds.push(wm.wm.protobuf.WantedCar.create({
|
||||
ghost: ghostcar,
|
||||
wantedId: wantedCarList[i].carId,
|
||||
bonus: wantedCarList[i].bonus,
|
||||
numOfHostages: wantedCarList[i].numOfHostages
|
||||
}))
|
||||
}
|
||||
}
|
||||
|
||||
// Encode the response
|
||||
let message = wmsrv.wm.protobuf.LockWantedList.encode({wanteds});
|
||||
|
||||
// Send the response to the client
|
||||
common.sendResponse(message, res);
|
||||
})
|
||||
|
||||
|
||||
// Ghost Expedition Participants
|
||||
app.get('/resource/ghost_expedition_participants', async (req, res) => {
|
||||
|
||||
console.log('ghost_expedition_participants');
|
||||
|
||||
// Get url query
|
||||
let ghost_expedition_id = Number(req.query.ghost_expedition_id);
|
||||
let place_id = String(req.query.place_id);
|
||||
|
||||
// Get local store participant
|
||||
let localParticipant = await prisma.ghostExpedition.findMany({
|
||||
where:{
|
||||
ghostExpeditionId: ghost_expedition_id
|
||||
},
|
||||
orderBy:{
|
||||
score: 'desc'
|
||||
}
|
||||
})
|
||||
|
||||
let arrayParticipant = [];
|
||||
for(let i=0; i<localParticipant.length; i++)
|
||||
{
|
||||
arrayParticipant.push(localParticipant[i].carId);
|
||||
}
|
||||
|
||||
// Response data
|
||||
let msg = {
|
||||
placeId: place_id,
|
||||
participantCars: arrayParticipant
|
||||
};
|
||||
|
||||
// Encode the response
|
||||
let message = wm.wm.protobuf.GhostExpeditionParticipants.encode(msg);
|
||||
|
||||
// Send the response to the client
|
||||
common.sendResponse(message, res);
|
||||
})
|
||||
}
|
||||
}
|
@ -1,175 +0,0 @@
|
||||
import { prisma } from "../..";
|
||||
|
||||
//Import Proto
|
||||
import wmsrv from "../../wmmt/service.proto";
|
||||
|
||||
|
||||
// Get Crown List
|
||||
export async function getCrownList()
|
||||
{
|
||||
// Empty list of crown records
|
||||
let list_crown: wmsrv.wm.protobuf.Crown[] = [];
|
||||
|
||||
// Get the current date/time (unix epoch)
|
||||
let date = Math.floor(new Date().getTime() / 1000);
|
||||
|
||||
// Get the crown holder data
|
||||
let car_crown = await prisma.carCrown.findMany({
|
||||
orderBy: {
|
||||
area: 'asc'
|
||||
},
|
||||
distinct: ['area']
|
||||
});
|
||||
|
||||
// Crown holder data available
|
||||
if(car_crown.length !== 0)
|
||||
{
|
||||
let counter = 0;
|
||||
|
||||
// Loop GID_RUNAREA
|
||||
for(let i=0; i<19; i++)
|
||||
{
|
||||
// After Kobe is Hiroshima then Fukuoka and the rest
|
||||
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
|
||||
}
|
||||
});
|
||||
|
||||
// Set the tunePower and tuneHandling used when capturing ghost crown
|
||||
car!.tunePower = car_crown[counter].tunePower;
|
||||
car!.tuneHandling = car_crown[counter].tuneHandling;
|
||||
|
||||
// Acquired crown timestamp - 1 day (prevent locking)
|
||||
car!.lastPlayedAt = car_crown[counter].playedAt - 172800;
|
||||
|
||||
// Acquired crown timestamp - 1 day (prevent locking)
|
||||
car_crown[counter].playedAt = car_crown[counter].playedAt - 172800;
|
||||
|
||||
// PlayedAt still bigger than current date (prevent locking)
|
||||
if(car_crown[counter].playedAt > date)
|
||||
{
|
||||
car_crown[counter].playedAt = date;
|
||||
}
|
||||
// PlayedAt still smaller than 1674579600
|
||||
else if(car_crown[counter].playedAt < 1674579600)
|
||||
{
|
||||
car_crown[counter].playedAt = 1674579600;
|
||||
}
|
||||
|
||||
// Error handling if regionId is below 1 or above 47
|
||||
if(car!.regionId < 1 || car!.regionId > 47)
|
||||
{
|
||||
car!.regionId = Math.floor(Math.random() * 10) + 10;
|
||||
}
|
||||
|
||||
// Push the car data to the crown holder data
|
||||
// GID_RUNAREA_HIROSHIMA
|
||||
if(car_crown[counter].area === 18)
|
||||
{
|
||||
let listCrown = wmsrv.wm.protobuf.Crown.create({
|
||||
carId: car_crown[counter].carId,
|
||||
area: car_crown[counter].area,
|
||||
unlockAt: car_crown[counter].playedAt,
|
||||
car: car!
|
||||
});
|
||||
|
||||
// Push it after Kobe
|
||||
list_crown.splice(11, 0, listCrown);
|
||||
}
|
||||
// GID_RUNAREA_C1 - GID_RUNAREA_TURNPIKE
|
||||
else
|
||||
{
|
||||
list_crown.push(wmsrv.wm.protobuf.Crown.create({
|
||||
carId: car_crown[counter].carId,
|
||||
area: car_crown[counter].area,
|
||||
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
|
||||
// GID_RUNAREA_HIROSHIMA
|
||||
if(i === 18)
|
||||
{
|
||||
let listCrown = wmsrv.wm.protobuf.Crown.create({
|
||||
carId: 999999999-i,
|
||||
area: i,
|
||||
unlockAt: date - 1000,
|
||||
});
|
||||
|
||||
// Push it after Kobe
|
||||
list_crown.splice(11, 0, listCrown);
|
||||
}
|
||||
// GID_RUNAREA_C1 - GID_RUNAREA_TURNPIKE
|
||||
else
|
||||
{
|
||||
list_crown.push(wmsrv.wm.protobuf.Crown.create({
|
||||
carId: 999999999-i,
|
||||
area: i,
|
||||
unlockAt: date - 1000,
|
||||
}));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// There is no user's crown holder data available
|
||||
else
|
||||
{
|
||||
// Loop GID_RUNAREA
|
||||
for(let i=0; i<19; i++)
|
||||
{
|
||||
// After Kobe is Hiroshima then Fukuoka and the rest
|
||||
if(i > 14)
|
||||
{
|
||||
i = 18; // GID_RUNAREA_HIROSHIMA
|
||||
}
|
||||
|
||||
// Push the default data by the game to the crown holder data
|
||||
// GID_RUNAREA_HIROSHIMA
|
||||
if(i === 18)
|
||||
{
|
||||
let listCrown = wmsrv.wm.protobuf.Crown.create({
|
||||
carId: 999999999-i,
|
||||
area: i,
|
||||
unlockAt: date - 1000,
|
||||
});
|
||||
|
||||
// Push it after Kobe
|
||||
list_crown.splice(11, 0, listCrown);
|
||||
}
|
||||
// GID_RUNAREA_C1 - GID_RUNAREA_TURNPIKE
|
||||
else
|
||||
{
|
||||
list_crown.push(wmsrv.wm.protobuf.Crown.create({
|
||||
carId: 999999999-i,
|
||||
area: i,
|
||||
unlockAt: date - 1000,
|
||||
}));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return { list_crown }
|
||||
}
|
@ -1,279 +0,0 @@
|
||||
import { prisma } from "../..";
|
||||
|
||||
//Import Proto
|
||||
import * as wmsrv from "../../wmmt/service.proto";
|
||||
|
||||
|
||||
// Get TA Ranking
|
||||
export async function getTimeAttackRanking()
|
||||
{
|
||||
// Empty list ranking records
|
||||
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: 'GUEST',
|
||||
regionId: 1, // Hokkaido
|
||||
model: Math.floor(Math.random() * 50), // Randomizing GUEST Car data
|
||||
visualModel: Math.floor(Math.random() * 100), // Randomizing GUEST 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 GUEST time attack
|
||||
let list_ta: wmsrv.wm.protobuf.Ranking.Entry[] = [];
|
||||
|
||||
// Generate the top 10 GUEST 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 GUEST data to the ranking data
|
||||
list_ta.push(wmsrv.wm.protobuf.Ranking.Entry.create({
|
||||
carId: 0,
|
||||
rank: 0,
|
||||
result: resulttime,
|
||||
name: 'GUEST',
|
||||
regionId: 1, // Hokkaido
|
||||
model: Math.floor(Math.random() * 50), // Randomizing GUEST Car data
|
||||
visualModel: Math.floor(Math.random() * 100), // Randomizing GUEST 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
|
||||
}));
|
||||
}
|
||||
}
|
||||
|
||||
return { lists }
|
||||
}
|
||||
|
||||
// Get VS Outrun Ranking
|
||||
export async function getVSOutrunRanking()
|
||||
{
|
||||
// Empty list ranking records
|
||||
let lists: wmsrv.wm.protobuf.Ranking.List[] = [];
|
||||
|
||||
// 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 GUEST data to the ranking data
|
||||
list_vs.push(wmsrv.wm.protobuf.Ranking.Entry.create({
|
||||
carId: 0,
|
||||
rank: 0,
|
||||
result: 0,
|
||||
name: 'GUEST',
|
||||
regionId: 1, // Hokkaido
|
||||
model: Math.floor(Math.random() * 50), // Randomizing GUEST Car data
|
||||
visualModel: Math.floor(Math.random() * 100), // Randomizing GUEST 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
|
||||
}));
|
||||
|
||||
return { lists }
|
||||
}
|
||||
|
||||
// Get Ghost Trophies Ranking
|
||||
export async function getTGhostTrophiesRanking()
|
||||
{
|
||||
// Empty list ranking records
|
||||
let lists: wmsrv.wm.protobuf.Ranking.List[] = [];
|
||||
|
||||
// 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 GUEST data to the ranking data
|
||||
list_ghost.push(wmsrv.wm.protobuf.Ranking.Entry.create({
|
||||
carId: 0,
|
||||
rank: 0,
|
||||
result: 0,
|
||||
name: 'GUEST',
|
||||
regionId: 1, // Hokkaido
|
||||
model: Math.floor(Math.random() * 50), // Randomizing GUEST Car data
|
||||
visualModel: Math.floor(Math.random() * 100), // Randomizing GUEST 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
|
||||
}));
|
||||
|
||||
return { lists }
|
||||
}
|
@ -1,12 +1,12 @@
|
||||
import { Application } from "express";
|
||||
import { Module } from "module";
|
||||
import { prisma } from "..";
|
||||
|
||||
// Import Proto
|
||||
import * as wm from "../wmmt/wm.proto";
|
||||
|
||||
// Import Util
|
||||
import * as common from "./util/common";
|
||||
import * as startupFunctions from "./startup/functions";
|
||||
import * as common from "../util/common";
|
||||
|
||||
|
||||
export default class StartupModule extends Module {
|
||||
@ -21,9 +21,108 @@ export default class StartupModule extends Module {
|
||||
// Get current date
|
||||
let date = Math.floor(new Date().getTime() / 1000);
|
||||
|
||||
// Get Competition (OCM) Event Date
|
||||
let getCompetitionSchedule = await startupFunctions.competitionSchedule(date, null);
|
||||
let additionalCompetitionMsg = getCompetitionSchedule.additionalCompetitionMsg;
|
||||
// Get current / previous active OCM Event
|
||||
let ocmEventDate = await prisma.oCMEvent.findFirst({
|
||||
where: {
|
||||
// qualifyingPeriodStartAt is less than current date
|
||||
qualifyingPeriodStartAt: { lte: date },
|
||||
|
||||
// competitionEndAt is greater than current date
|
||||
competitionEndAt: { gte: date },
|
||||
},
|
||||
orderBy: {
|
||||
competitionEndAt: 'desc',
|
||||
}
|
||||
});
|
||||
|
||||
let pastEvent = 0;
|
||||
if(!(ocmEventDate))
|
||||
{
|
||||
ocmEventDate = await prisma.oCMEvent.findFirst({
|
||||
orderBy:{
|
||||
competitionId: 'desc'
|
||||
}
|
||||
});
|
||||
|
||||
pastEvent = 1;
|
||||
}
|
||||
|
||||
// Declare GhostCompetitionSchedule
|
||||
let competitionSchedule;
|
||||
let lastCompetitionId: number = 0;
|
||||
if(ocmEventDate)
|
||||
{
|
||||
let pastDay = date - ocmEventDate.competitionEndAt
|
||||
|
||||
if(pastDay < 604800)
|
||||
{
|
||||
console.log("OCM Event Available");
|
||||
|
||||
// Creating GhostCompetitionSchedule
|
||||
competitionSchedule = wm.wm.protobuf.GhostCompetitionSchedule.create({
|
||||
|
||||
// OCM Competition ID (1 = C1 (Round 16), 4 = Nagoya (Round 19), 8 = Hiroshima (Round 21))
|
||||
competitionId: ocmEventDate.competitionId,
|
||||
|
||||
// OCM Qualifying Start Timestamp
|
||||
qualifyingPeriodStartAt: ocmEventDate.qualifyingPeriodStartAt,
|
||||
|
||||
// OCM Qualifying Close Timestamp
|
||||
qualifyingPeriodCloseAt: ocmEventDate.qualifyingPeriodCloseAt,
|
||||
|
||||
// OCM Competition (Main Draw) Start Timestamp
|
||||
competitionStartAt: ocmEventDate.competitionStartAt,
|
||||
|
||||
// OCM Competition (Main Draw) Close Timestamp
|
||||
competitionCloseAt: ocmEventDate.competitionCloseAt,
|
||||
|
||||
// OCM Competition (Main Draw) End Timestamp
|
||||
competitionEndAt: ocmEventDate.competitionEndAt,
|
||||
|
||||
// idk what this is
|
||||
lengthOfPeriod: ocmEventDate.lengthOfPeriod,
|
||||
|
||||
// idk what this is
|
||||
lengthOfInterval: ocmEventDate.lengthOfInterval,
|
||||
|
||||
// Area for the event (GID_RUNAREA_*, 8 is GID_RUNAREA_NAGOYA)
|
||||
area: ocmEventDate.area,
|
||||
|
||||
// idk what this is
|
||||
minigamePatternId: ocmEventDate.minigamePatternId
|
||||
});
|
||||
}
|
||||
|
||||
if(pastEvent === 1)
|
||||
{
|
||||
console.log("Previous OCM Event Available");
|
||||
|
||||
lastCompetitionId = ocmEventDate.competitionId
|
||||
}
|
||||
}
|
||||
|
||||
// Get VSORG Event Date
|
||||
let ghostExpeditionDate = await prisma.ghostExpeditionEvent.findFirst({
|
||||
where: {
|
||||
// qualifyingPeriodStartAt is less than equal current date
|
||||
startAt: { lte: date },
|
||||
|
||||
// competitionEndAt is greater than equal current date
|
||||
aftereventEndAt: { gte: date },
|
||||
},
|
||||
})
|
||||
let vsOrgEventDate;
|
||||
|
||||
if(ghostExpeditionDate)
|
||||
{
|
||||
vsOrgEventDate = wm.wm.protobuf.GhostExpeditionSchedule.create({
|
||||
ghostExpeditionId: ghostExpeditionDate.ghostExpeditionId,
|
||||
startAt: ghostExpeditionDate.startAt,
|
||||
endAt: ghostExpeditionDate.endAt,
|
||||
aftereventEndAt: ghostExpeditionDate.aftereventEndAt,
|
||||
opponentCountry: ghostExpeditionDate.opponentCountry // not sure if this connected to ghostExpeditionId or not
|
||||
});
|
||||
}
|
||||
|
||||
// Response data
|
||||
let msg = {
|
||||
@ -41,8 +140,13 @@ export default class StartupModule extends Module {
|
||||
releaseAt: 0 // idk what this is
|
||||
},
|
||||
|
||||
// Competition (OCM)
|
||||
...additionalCompetitionMsg
|
||||
// OCM
|
||||
latestCompetitionId: lastCompetitionId || null,
|
||||
competitionSchedule: competitionSchedule || null, // OCM Event Available or not
|
||||
|
||||
// VSORG
|
||||
expeditionSchedule: vsOrgEventDate || null,
|
||||
expeditionEventWasHeld: true
|
||||
}
|
||||
|
||||
// Encode the response
|
||||
@ -73,7 +177,6 @@ export default class StartupModule extends Module {
|
||||
common.sendResponse(message, res);
|
||||
});
|
||||
|
||||
|
||||
// Ping
|
||||
app.post('/method/ping', (req, res) => {
|
||||
|
||||
@ -93,7 +196,6 @@ export default class StartupModule extends Module {
|
||||
})
|
||||
|
||||
|
||||
// Register System Stats
|
||||
app.post('/method/register_system_stats', async (req, res) => {
|
||||
|
||||
let body = wm.wm.protobuf.RegisterSystemStatsRequest.decode(req.body);
|
||||
@ -114,7 +216,6 @@ export default class StartupModule extends Module {
|
||||
})
|
||||
|
||||
|
||||
// Update Event Mode Serial
|
||||
app.post('/method/update_event_mode_serial', async (req, res) => {
|
||||
|
||||
let body = wm.wm.protobuf.UpdateEventModeSerialRequest.decode(req.body);
|
||||
@ -125,10 +226,7 @@ export default class StartupModule extends Module {
|
||||
// Response data
|
||||
let msg = {
|
||||
error: wm.wm.protobuf.ErrorCode.ERR_SUCCESS,
|
||||
serialError: wm.wm.protobuf.EventModeSerialErrorCode.SERIAL_SUCCESS,
|
||||
eventModeSerial: body.eventModeSerial || '285013990002',
|
||||
startAt: 0,
|
||||
endAt: 2147483647
|
||||
serialError: wm.wm.protobuf.EventModeSerialErrorCode.SERIAL_NO_INPUT
|
||||
}
|
||||
|
||||
// Encode the response
|
||||
@ -139,7 +237,6 @@ export default class StartupModule extends Module {
|
||||
})
|
||||
|
||||
|
||||
// Submit Client Log
|
||||
app.post('/method/submit_client_log', async (req, res) => {
|
||||
|
||||
let body = wm.wm.protobuf.SubmitClientLogRequest.decode(req.body);
|
||||
|
@ -1,128 +0,0 @@
|
||||
import { prisma } from "../..";
|
||||
|
||||
// Import Proto
|
||||
import * as wm from "../../wmmt/wm.proto";
|
||||
|
||||
|
||||
// Get Competition (OCM) Schedule
|
||||
export async function competitionSchedule(date: any, competitionId: any)
|
||||
{
|
||||
// Get the Competition (OCM) schedule
|
||||
let ghostCompetitionSchedule;
|
||||
|
||||
// Request by compedtitionId
|
||||
if(competitionId)
|
||||
{
|
||||
ghostCompetitionSchedule = await prisma.oCMEvent.findFirst({
|
||||
where: {
|
||||
competitionId: competitionId
|
||||
},
|
||||
orderBy: {
|
||||
competitionId: 'desc'
|
||||
}
|
||||
});
|
||||
}
|
||||
// Request by date
|
||||
else
|
||||
{
|
||||
ghostCompetitionSchedule = await prisma.oCMEvent.findFirst({
|
||||
where: {
|
||||
// qualifyingPeriodStartAt is less than current date
|
||||
qualifyingPeriodStartAt: { lte: Number(date) },
|
||||
|
||||
// competitionEndAt is greater than current date
|
||||
competitionEndAt: { gte: Number(date) },
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// Other variable
|
||||
let competitionSchedule;
|
||||
let lastCompetitionId: number = 0;
|
||||
let additionalCompetitionMsg = {};
|
||||
|
||||
// Currently no Active Competition (OCM) Event.. Getting Previous Competition (OCM) Event
|
||||
let pastEvent = 0;
|
||||
if(!(ghostCompetitionSchedule))
|
||||
{
|
||||
ghostCompetitionSchedule = await prisma.oCMEvent.findFirst({
|
||||
orderBy:{
|
||||
competitionId: 'desc'
|
||||
}
|
||||
});
|
||||
|
||||
pastEvent = 1;
|
||||
}
|
||||
|
||||
// Previous / Current Competition (OCM) available
|
||||
if(ghostCompetitionSchedule)
|
||||
{
|
||||
console.log('Ghost Competition (OCM) Available');
|
||||
|
||||
let pastDay = date - ghostCompetitionSchedule.competitionEndAt;
|
||||
|
||||
if(pastDay < 604800)
|
||||
{
|
||||
// Creating GhostCompetitionSchedule
|
||||
competitionSchedule = wm.wm.protobuf.GhostCompetitionSchedule.create({
|
||||
|
||||
// Competition ID
|
||||
competitionId: ghostCompetitionSchedule.competitionId,
|
||||
|
||||
// Competition Qualifying Start Timestamp
|
||||
qualifyingPeriodStartAt: ghostCompetitionSchedule.qualifyingPeriodStartAt,
|
||||
|
||||
// Competition Qualifying Close Timestamp
|
||||
qualifyingPeriodCloseAt: ghostCompetitionSchedule.qualifyingPeriodCloseAt,
|
||||
|
||||
// Competition (Main Draw) Start Timestamp
|
||||
competitionStartAt: ghostCompetitionSchedule.competitionStartAt,
|
||||
|
||||
// Competition (Main Draw) Close Timestamp
|
||||
competitionCloseAt: ghostCompetitionSchedule.competitionCloseAt,
|
||||
|
||||
// Competition (Main Draw) End Timestamp
|
||||
competitionEndAt: ghostCompetitionSchedule.competitionEndAt,
|
||||
|
||||
// Competition (Main Draw) length per periods
|
||||
lengthOfPeriod: ghostCompetitionSchedule.lengthOfPeriod,
|
||||
|
||||
// Competition (Main Draw) interval (for tallying) per periods
|
||||
lengthOfInterval: ghostCompetitionSchedule.lengthOfInterval,
|
||||
|
||||
// Area for the Competition Event (GID_RUNAREA_*)
|
||||
area: ghostCompetitionSchedule.area,
|
||||
|
||||
// idk what this is
|
||||
minigamePatternId: ghostCompetitionSchedule.minigamePatternId
|
||||
});
|
||||
}
|
||||
|
||||
// It's previous Competition (OCM) event
|
||||
if(pastEvent === 1)
|
||||
{
|
||||
// Get current date
|
||||
let dates = Math.floor(new Date().getTime() / 1000);
|
||||
|
||||
let lastScheduleCompetitionId = await prisma.oCMEvent.findFirst({
|
||||
where: {
|
||||
competitionCloseAt: { lte: dates }
|
||||
},
|
||||
orderBy:{
|
||||
competitionId: 'desc'
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
lastCompetitionId = lastScheduleCompetitionId?.competitionId || 0;
|
||||
}
|
||||
|
||||
// Competition (OCM) Response Message
|
||||
additionalCompetitionMsg = {
|
||||
latestCompetitionId: lastCompetitionId,
|
||||
competitionSchedule: competitionSchedule,
|
||||
}
|
||||
}
|
||||
|
||||
return { additionalCompetitionMsg, competitionSchedule }
|
||||
}
|
@ -8,8 +8,8 @@ import { Car } from "@prisma/client";
|
||||
import * as wm from "../wmmt/wm.proto";
|
||||
|
||||
// Import Util
|
||||
import * as scratch from "./terminal/scratch";
|
||||
import * as common from "./util/common";
|
||||
import * as scratch from "../util/scratch";
|
||||
import * as common from "../util/common";
|
||||
|
||||
|
||||
export default class TerminalModule extends Module {
|
||||
@ -186,9 +186,7 @@ export default class TerminalModule extends Module {
|
||||
|
||||
// Get the query from the request
|
||||
let query = req.query;
|
||||
let cars: wm.wm.protobuf.Car[] = [];
|
||||
let car;
|
||||
let arr = [];
|
||||
let cars;
|
||||
|
||||
// Check the query limit
|
||||
let queryLimit = 10
|
||||
@ -212,23 +210,22 @@ export default class TerminalModule extends Module {
|
||||
queryLastPlayedPlaceId = getLastPlayedPlaceId.id;
|
||||
}
|
||||
|
||||
car = await prisma.car.findMany({
|
||||
cars = await prisma.car.findMany({
|
||||
take: queryLimit,
|
||||
where: {
|
||||
lastPlayedPlaceId: queryLastPlayedPlaceId
|
||||
},
|
||||
include:{
|
||||
gtWing: true,
|
||||
lastPlayedPlace: true
|
||||
},
|
||||
orderBy: {
|
||||
carId: "asc"
|
||||
}
|
||||
});
|
||||
}
|
||||
else
|
||||
{
|
||||
// Get all of the cars matching the query
|
||||
car = await prisma.car.findMany({
|
||||
cars = await prisma.car.findMany({
|
||||
take: queryLimit,
|
||||
where: {
|
||||
OR:[
|
||||
{
|
||||
@ -247,50 +244,10 @@ export default class TerminalModule extends Module {
|
||||
include:{
|
||||
gtWing: true,
|
||||
lastPlayedPlace: true
|
||||
},
|
||||
orderBy: {
|
||||
carId: "asc"
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
if(car.length > 0)
|
||||
{
|
||||
if(car.length < queryLimit)
|
||||
{
|
||||
queryLimit = car.length;
|
||||
}
|
||||
|
||||
// Choose the user's car data randomly to appear
|
||||
while(arr.length < queryLimit)
|
||||
{
|
||||
// Randomize pick
|
||||
let random: number = 1;
|
||||
|
||||
// Randomize it 5 times
|
||||
for(let i=0; i<5; i++)
|
||||
{
|
||||
random = Math.floor(Math.random() * car.length);
|
||||
}
|
||||
|
||||
// Try randomize it again if it's 1
|
||||
if(random === 1)
|
||||
{
|
||||
random = Math.floor(Math.random() * car.length);
|
||||
}
|
||||
|
||||
if(arr.indexOf(random) === -1)
|
||||
{
|
||||
// Push current number to array
|
||||
arr.push(random);
|
||||
|
||||
cars.push(wm.wm.protobuf.Car.create({
|
||||
...car[random]
|
||||
}));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
let msg = {
|
||||
hitCount: cars.length,
|
||||
cars: cars
|
||||
@ -678,31 +635,32 @@ export default class TerminalModule extends Module {
|
||||
periodId: 'desc'
|
||||
}
|
||||
],
|
||||
include:{
|
||||
car: true
|
||||
},
|
||||
distinct: ["carId"],
|
||||
take: 50
|
||||
})
|
||||
|
||||
numOfParticipants = ocmParticipant.length;
|
||||
periodId = 0;
|
||||
let ranking = 0;
|
||||
|
||||
if(numOfParticipants > 0)
|
||||
if(ocmParticipant)
|
||||
{
|
||||
periodId = ocmParticipant[0].periodId;
|
||||
|
||||
for(let i=0; i<ocmParticipant.length; i++)
|
||||
{
|
||||
let cars = await prisma.car.findFirst({
|
||||
where:{
|
||||
carId: ocmParticipant[i].carId
|
||||
},
|
||||
include:{
|
||||
gtWing: true,
|
||||
lastPlayedPlace: true
|
||||
}
|
||||
});
|
||||
|
||||
let ocmGhostrecord = await prisma.oCMGhostBattleRecord.findFirst({
|
||||
where:{
|
||||
carId: ocmParticipant[0].carId,
|
||||
competitionId: ocmEventDate!.competitionId,
|
||||
},
|
||||
select:{
|
||||
playedShopName: true,
|
||||
playedAt: true
|
||||
}
|
||||
});
|
||||
|
||||
@ -718,14 +676,14 @@ export default class TerminalModule extends Module {
|
||||
rank: i + 1,
|
||||
result: ocmParticipant[i].result,
|
||||
carId: ocmParticipant[i].carId,
|
||||
name: ocmParticipant[i].car.name,
|
||||
regionId: ocmParticipant[i].car.regionId,
|
||||
model: ocmParticipant[i].car.model,
|
||||
visualModel: ocmParticipant[i].car.visualModel,
|
||||
defaultColor: ocmParticipant[i].car.defaultColor,
|
||||
title: ocmParticipant[i].car.title,
|
||||
level: ocmParticipant[i].car.level,
|
||||
windowStickerString: ocmParticipant[i].car.windowStickerString,
|
||||
name: cars!.name,
|
||||
regionId: cars!.regionId,
|
||||
model: cars!.model,
|
||||
visualModel: cars!.visualModel,
|
||||
defaultColor: cars!.defaultColor,
|
||||
title: cars!.title,
|
||||
level: cars!.level,
|
||||
windowStickerString: cars!.windowStickerString,
|
||||
playedShopName: playedShopName,
|
||||
playedAt: ocmGhostrecord!.playedAt
|
||||
});
|
||||
@ -738,66 +696,18 @@ export default class TerminalModule extends Module {
|
||||
rank: i + 1,
|
||||
result: ocmParticipant[i].result,
|
||||
carId: ocmParticipant[i].carId,
|
||||
name: ocmParticipant[i].car.name,
|
||||
regionId: ocmParticipant[i].car.regionId,
|
||||
model: ocmParticipant[i].car.model,
|
||||
visualModel: ocmParticipant[i].car.visualModel,
|
||||
defaultColor: ocmParticipant[i].car.defaultColor,
|
||||
title: ocmParticipant[i].car.title,
|
||||
level: ocmParticipant[i].car.level,
|
||||
windowStickerString: ocmParticipant[i].car.windowStickerString,
|
||||
name: cars!.name,
|
||||
regionId: cars!.regionId,
|
||||
model: cars!.model,
|
||||
visualModel: cars!.visualModel,
|
||||
defaultColor: cars!.defaultColor,
|
||||
title: cars!.title,
|
||||
level: cars!.level,
|
||||
windowStickerString: cars!.windowStickerString,
|
||||
playedShopName: playedShopName,
|
||||
playedAt: ocmGhostrecord!.playedAt
|
||||
}));
|
||||
}
|
||||
|
||||
if(!(ownRecords))
|
||||
{
|
||||
let ocmPersonalRank = [{ result: 0, position: 0 }];
|
||||
|
||||
ocmPersonalRank = await prisma.$queryRaw`
|
||||
select "result", "position" from
|
||||
(select *, row_number() over(order by "result" DESC) as "position" from "OCMTally"
|
||||
where "competitionId" = ${body.competitionId}) "OCMTally" where "carId" = ${body.carId}`;
|
||||
|
||||
if(ocmPersonalRank.length > 0)
|
||||
{
|
||||
let userCar = await prisma.car.findFirst({
|
||||
where:{
|
||||
carId: body.carId
|
||||
}
|
||||
});
|
||||
|
||||
let userPlayedAt = await prisma.oCMGhostBattleRecord.findFirst({
|
||||
where:{
|
||||
carId: body.carId,
|
||||
competitionId: body.competitionId
|
||||
},
|
||||
select:{
|
||||
playedAt: true
|
||||
}
|
||||
});
|
||||
|
||||
let myRank = Number(ocmPersonalRank[0].position);
|
||||
let myResult = Number(ocmPersonalRank[0].result);
|
||||
|
||||
ownRecords = wm.wm.protobuf.LoadGhostCompetitionRankingResponse.Entry.create({
|
||||
rank: myRank,
|
||||
result: myResult,
|
||||
carId: userCar!.carId,
|
||||
name: userCar!.name,
|
||||
regionId: userCar!.regionId,
|
||||
model: userCar!.model,
|
||||
visualModel: userCar!.visualModel,
|
||||
defaultColor: userCar!.defaultColor,
|
||||
title: userCar!.title,
|
||||
level: userCar!.level,
|
||||
windowStickerString: userCar!.windowStickerString,
|
||||
playedShopName: playedShopName,
|
||||
playedAt: userPlayedAt?.playedAt || 0
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// Current date is OCM qualifying day
|
||||
@ -811,21 +721,27 @@ export default class TerminalModule extends Module {
|
||||
},
|
||||
orderBy: {
|
||||
result: 'desc'
|
||||
},
|
||||
include:{
|
||||
car: true
|
||||
},
|
||||
distinct: ["carId"],
|
||||
}
|
||||
})
|
||||
|
||||
numOfParticipants = ocmParticipant.length;
|
||||
periodId = 0;
|
||||
let ranking = 0;
|
||||
|
||||
if(numOfParticipants > 0)
|
||||
if(ocmParticipant)
|
||||
{
|
||||
for(let i=0; i<numOfParticipants; i++)
|
||||
for(let i=0; i<ocmParticipant.length; i++)
|
||||
{
|
||||
let cars = await prisma.car.findFirst({
|
||||
where:{
|
||||
carId: ocmParticipant[i].carId
|
||||
},
|
||||
include:{
|
||||
gtWing: true,
|
||||
lastPlayedPlace: true
|
||||
}
|
||||
})
|
||||
|
||||
if(ocmParticipant[i].carId === body.carId && ranking === 0)
|
||||
{
|
||||
// User car setting
|
||||
@ -833,21 +749,37 @@ export default class TerminalModule extends Module {
|
||||
rank: i + 1,
|
||||
result: ocmParticipant[i].result,
|
||||
carId: ocmParticipant[i].carId,
|
||||
name: ocmParticipant[i].car.name,
|
||||
regionId: ocmParticipant[i].car.regionId,
|
||||
model: ocmParticipant[i].car.model,
|
||||
visualModel: ocmParticipant[i].car.visualModel,
|
||||
defaultColor: ocmParticipant[i].car.defaultColor,
|
||||
title: ocmParticipant[i].car.title,
|
||||
level: ocmParticipant[i].car.level,
|
||||
windowStickerString: ocmParticipant[i].car.windowStickerString,
|
||||
playedShopName: playedShopName,
|
||||
name: cars!.name,
|
||||
regionId: cars!.regionId,
|
||||
model: cars!.model,
|
||||
visualModel: cars!.visualModel,
|
||||
defaultColor: cars!.defaultColor,
|
||||
title: cars!.title,
|
||||
level: cars!.level,
|
||||
windowStickerString: cars!.windowStickerString,
|
||||
playedShopName: ocmParticipant[i].playedShopName,
|
||||
playedAt: ocmParticipant[i].playedAt
|
||||
});
|
||||
|
||||
ranking++;
|
||||
break;
|
||||
}
|
||||
|
||||
// Generate OCM Top Records
|
||||
topRecords.push(wm.wm.protobuf.LoadGhostCompetitionRankingResponse.Entry.create({
|
||||
rank: i + 1,
|
||||
result: ocmParticipant[i].result,
|
||||
carId: ocmParticipant[i].carId,
|
||||
name: cars!.name,
|
||||
regionId: cars!.regionId,
|
||||
model: cars!.model,
|
||||
visualModel: cars!.visualModel,
|
||||
defaultColor: cars!.defaultColor,
|
||||
title: cars!.title,
|
||||
level: cars!.level,
|
||||
windowStickerString: cars!.windowStickerString,
|
||||
playedShopName: ocmParticipant[i].playedShopName,
|
||||
playedAt: ocmParticipant[i].playedAt
|
||||
}));
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -856,52 +788,41 @@ export default class TerminalModule extends Module {
|
||||
{
|
||||
console.log('Current / Previous OCM Day : OCM has Ended');
|
||||
|
||||
// Get Current OCM Period and All User's Record
|
||||
let ocmParticipant = await prisma.oCMTally.findMany({
|
||||
where:{
|
||||
competitionId: ocmEventDate!.competitionId,
|
||||
periodId: 999999999
|
||||
},
|
||||
orderBy: [
|
||||
{
|
||||
orderBy: {
|
||||
result: 'desc'
|
||||
},
|
||||
{
|
||||
periodId: 'desc'
|
||||
}
|
||||
],
|
||||
include:{
|
||||
car: true
|
||||
},
|
||||
distinct: ["carId"],
|
||||
take: 10
|
||||
})
|
||||
|
||||
numOfParticipants = ocmParticipant.length;
|
||||
periodId = 0;
|
||||
let ranking = 0;
|
||||
|
||||
if(numOfParticipants > 0)
|
||||
if(ocmParticipant)
|
||||
{
|
||||
periodId = ocmParticipant[0].periodId;
|
||||
|
||||
for(let i=0; i<ocmParticipant.length; i++)
|
||||
{
|
||||
let cars = await prisma.car.findFirst({
|
||||
where:{
|
||||
carId: ocmParticipant[i].carId
|
||||
},
|
||||
include:{
|
||||
gtWing: true,
|
||||
lastPlayedPlace: true
|
||||
}
|
||||
});
|
||||
|
||||
let ocmGhostrecord = await prisma.oCMGhostBattleRecord.findFirst({
|
||||
where:{
|
||||
carId: ocmParticipant[0].carId,
|
||||
competitionId: ocmEventDate!.competitionId,
|
||||
},
|
||||
select:{
|
||||
playedShopName: true,
|
||||
playedAt: true
|
||||
}
|
||||
});
|
||||
|
||||
if(ocmGhostrecord?.playedShopName !== null && ocmGhostrecord?.playedShopName !== undefined)
|
||||
{
|
||||
playedShopName = ocmGhostrecord.playedShopName;
|
||||
}
|
||||
|
||||
if(ocmParticipant[i].carId === body.carId && ranking === 0)
|
||||
{
|
||||
// User car setting
|
||||
@ -909,15 +830,15 @@ export default class TerminalModule extends Module {
|
||||
rank: i + 1,
|
||||
result: ocmParticipant[i].result,
|
||||
carId: ocmParticipant[i].carId,
|
||||
name: ocmParticipant[i].car.name,
|
||||
regionId: ocmParticipant[i].car.regionId,
|
||||
model: ocmParticipant[i].car.model,
|
||||
visualModel: ocmParticipant[i].car.visualModel,
|
||||
defaultColor: ocmParticipant[i].car.defaultColor,
|
||||
title: ocmParticipant[i].car.title,
|
||||
level: ocmParticipant[i].car.level,
|
||||
windowStickerString: ocmParticipant[i].car.windowStickerString,
|
||||
playedShopName: playedShopName,
|
||||
name: cars!.name,
|
||||
regionId: cars!.regionId,
|
||||
model: cars!.model,
|
||||
visualModel: cars!.visualModel,
|
||||
defaultColor: cars!.defaultColor,
|
||||
title: cars!.title,
|
||||
level: cars!.level,
|
||||
windowStickerString: cars!.windowStickerString,
|
||||
playedShopName: ocmGhostrecord!.playedShopName,
|
||||
playedAt: ocmGhostrecord!.playedAt
|
||||
});
|
||||
|
||||
@ -929,66 +850,18 @@ export default class TerminalModule extends Module {
|
||||
rank: i + 1,
|
||||
result: ocmParticipant[i].result,
|
||||
carId: ocmParticipant[i].carId,
|
||||
name: ocmParticipant[i].car.name,
|
||||
regionId: ocmParticipant[i].car.regionId,
|
||||
model: ocmParticipant[i].car.model,
|
||||
visualModel: ocmParticipant[i].car.visualModel,
|
||||
defaultColor: ocmParticipant[i].car.defaultColor,
|
||||
title: ocmParticipant[i].car.title,
|
||||
level: ocmParticipant[i].car.level,
|
||||
windowStickerString: ocmParticipant[i].car.windowStickerString,
|
||||
playedShopName: playedShopName,
|
||||
name: cars!.name,
|
||||
regionId: cars!.regionId,
|
||||
model: cars!.model,
|
||||
visualModel: cars!.visualModel,
|
||||
defaultColor: cars!.defaultColor,
|
||||
title: cars!.title,
|
||||
level: cars!.level,
|
||||
windowStickerString: cars!.windowStickerString,
|
||||
playedShopName: ocmGhostrecord!.playedShopName,
|
||||
playedAt: ocmGhostrecord!.playedAt
|
||||
}));
|
||||
}
|
||||
|
||||
if(!(ownRecords))
|
||||
{
|
||||
let ocmPersonalRank = [{ result: 0, position: 0 }];
|
||||
|
||||
ocmPersonalRank = await prisma.$queryRaw`
|
||||
select "result", "position" from
|
||||
(select *, row_number() over(order by "result" DESC) as "position" from "OCMTally"
|
||||
where "competitionId" = ${body.competitionId}) "OCMTally" where "carId" = ${body.carId}`;
|
||||
|
||||
if(ocmPersonalRank.length > 0)
|
||||
{
|
||||
let userCar = await prisma.car.findFirst({
|
||||
where:{
|
||||
carId: body.carId
|
||||
}
|
||||
});
|
||||
|
||||
let userPlayedAt = await prisma.oCMGhostBattleRecord.findFirst({
|
||||
where:{
|
||||
carId: body.carId,
|
||||
competitionId: body.competitionId
|
||||
},
|
||||
select:{
|
||||
playedAt: true
|
||||
}
|
||||
});
|
||||
|
||||
let myRank = Number(ocmPersonalRank[0].position);
|
||||
let myResult = Number(ocmPersonalRank[0].result);
|
||||
|
||||
ownRecords = wm.wm.protobuf.LoadGhostCompetitionRankingResponse.Entry.create({
|
||||
rank: myRank,
|
||||
result: myResult,
|
||||
carId: userCar!.carId,
|
||||
name: userCar!.name,
|
||||
regionId: userCar!.regionId,
|
||||
model: userCar!.model,
|
||||
visualModel: userCar!.visualModel,
|
||||
defaultColor: userCar!.defaultColor,
|
||||
title: userCar!.title,
|
||||
level: userCar!.level,
|
||||
windowStickerString: userCar!.windowStickerString,
|
||||
playedShopName: playedShopName,
|
||||
playedAt: userPlayedAt?.playedAt || 0
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -1130,6 +1003,24 @@ export default class TerminalModule extends Module {
|
||||
});
|
||||
|
||||
|
||||
app.post('/method/save_screenshot', async (req, res) => {
|
||||
|
||||
// Get the information from the request
|
||||
let body = wm.wm.protobuf.SaveScreenshotRequest.decode(req.body);
|
||||
|
||||
// Response data
|
||||
let msg = {
|
||||
error: wm.wm.protobuf.ErrorCode.ERR_SUCCESS,
|
||||
};
|
||||
|
||||
// Encode the response
|
||||
let message = wm.wm.protobuf.SaveScreenshotResponse.encode(msg);
|
||||
|
||||
// Send the response to the client
|
||||
common.sendResponse(message, res);
|
||||
});
|
||||
|
||||
|
||||
/*
|
||||
app.post('/method/load_unreceived_user_items', async (req, res) => {
|
||||
|
||||
|
@ -6,7 +6,7 @@ import { prisma } from "..";
|
||||
import * as wm from "../wmmt/wm.proto";
|
||||
|
||||
// Import Util
|
||||
import * as common from "./util/common";
|
||||
import * as common from "../util/common";
|
||||
|
||||
|
||||
export default class TimeAttackModule extends Module {
|
||||
|
@ -7,8 +7,8 @@ import { prisma } from "..";
|
||||
import * as wm from "../wmmt/wm.proto";
|
||||
|
||||
// Import Util
|
||||
import * as scratch from "./terminal/scratch";
|
||||
import * as common from "./util/common";
|
||||
import * as scratch from "../util/scratch";
|
||||
import * as common from "../util/common";
|
||||
|
||||
|
||||
export default class UserModule extends Module {
|
||||
@ -20,6 +20,9 @@ export default class UserModule extends Module {
|
||||
// Get the request body for the load user request
|
||||
let body = wm.wm.protobuf.LoadUserRequest.decode(req.body);
|
||||
|
||||
// Trim Mojibake (happens if user using release version of bngrw)
|
||||
body.cardChipId = body.cardChipId.replace('<27><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>0000', '');
|
||||
|
||||
// Block blank card.ini data and vanilla TP blank card data
|
||||
if(body.cardChipId.match(/7F5C9744F11111114326.*/) || body.cardChipId.match(/0000000000.*/))
|
||||
{
|
||||
@ -39,9 +42,6 @@ export default class UserModule extends Module {
|
||||
state: true,
|
||||
gtWing: true,
|
||||
lastPlayedPlace: true
|
||||
},
|
||||
where:{
|
||||
state: { toBeDeleted: false } // except deleted car
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -58,6 +58,10 @@ export default class UserModule extends Module {
|
||||
cars: [],
|
||||
spappState: wm.wm.protobuf.SmartphoneAppState.SPAPP_UNREGISTERED,
|
||||
transferState: wm.wm.protobuf.TransferState.NOT_REGISTERED,
|
||||
fullTunedCarTicket: false, // TODO: Maybe... idk
|
||||
ghostVs_2Locked: false, // TODO: Maybe... idk
|
||||
ghostVs_3Locked: false, // TODO: Maybe... idk
|
||||
ghostHighwayLocked: false, // TODO: Maybe... idk
|
||||
};
|
||||
|
||||
if (!body.cardChipId || !body.accessCode)
|
||||
@ -74,30 +78,11 @@ export default class UserModule extends Module {
|
||||
}
|
||||
|
||||
// Check if new card registration is allowed or not
|
||||
let newCardsBanned = Config.getConfig().gameOptions.newCardsBanned || 0;
|
||||
let newCardsBanned = Config.getConfig().gameOptions.newCardsBanned;
|
||||
|
||||
// New card registration is allowed
|
||||
if (newCardsBanned === 0)
|
||||
{
|
||||
let checkUser = await prisma.user.findFirst({
|
||||
where:{
|
||||
chipId: body.cardChipId
|
||||
}
|
||||
});
|
||||
|
||||
if(checkUser)
|
||||
{
|
||||
msg.error = wm.wm.protobuf.ErrorCode.ERR_USER_LOCKED;
|
||||
|
||||
// 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,
|
||||
@ -236,8 +221,8 @@ export default class UserModule extends Module {
|
||||
if (user.carOrder.length > 0)
|
||||
{
|
||||
// Sort the player's car list using the car order property
|
||||
user.cars = user.cars.sort(function(a, b)
|
||||
{
|
||||
user.cars = user.cars.sort(function(a, b){
|
||||
|
||||
// User, and both car IDs exist
|
||||
if (user)
|
||||
{
|
||||
@ -349,6 +334,22 @@ export default class UserModule extends Module {
|
||||
})
|
||||
}
|
||||
|
||||
// Check ghost trophy count if more than 50 or not
|
||||
let ghostExpeditionLocked: boolean = true;
|
||||
let checkRgTrophy = await prisma.car.findFirst({
|
||||
where:{
|
||||
userId: user.id,
|
||||
rgTrophy:{
|
||||
gte: 50 // greater than equal 50
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
if(checkRgTrophy)
|
||||
{
|
||||
ghostExpeditionLocked = false;
|
||||
}
|
||||
|
||||
|
||||
// Response data
|
||||
let msg = {
|
||||
@ -388,7 +389,13 @@ export default class UserModule extends Module {
|
||||
wasCreatedToday: false,
|
||||
|
||||
// Invite Friend Campaign Event
|
||||
participatedInInviteFriendCampaign: false
|
||||
participatedInInviteFriendCampaign: false,
|
||||
|
||||
// TODO: Make saving about this
|
||||
ghostExpeditionLocked: ghostExpeditionLocked, // must more than 50 rgTrophy
|
||||
ghostVs_2Locked: false,
|
||||
ghostVs_3Locked: false,
|
||||
ghostHighwayLocked: false,
|
||||
}
|
||||
|
||||
|
||||
@ -606,6 +613,9 @@ export default class UserModule extends Module {
|
||||
// Get the request body for the create user request
|
||||
let body = wm.wm.protobuf.CreateUserRequest.decode(req.body);
|
||||
|
||||
// Trim Mojibake (happens if user using release version of bngrw)
|
||||
body.cardChipId = body.cardChipId.replace('<27><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>0000', '');
|
||||
|
||||
// Get the user info via the card chip id
|
||||
let user = await prisma.user.findFirst({
|
||||
where: {
|
||||
|
@ -1,85 +0,0 @@
|
||||
// OpenTelemetry tracing module
|
||||
|
||||
import * as opentelemetry from '@opentelemetry/sdk-node';
|
||||
import { getNodeAutoInstrumentations } from '@opentelemetry/auto-instrumentations-node';
|
||||
import { diag, DiagConsoleLogger, DiagLogLevel } from '@opentelemetry/api';
|
||||
import { OTLPTraceExporter } from '@opentelemetry/exporter-trace-otlp-grpc';
|
||||
import { Resource } from '@opentelemetry/resources';
|
||||
import { SemanticResourceAttributes } from '@opentelemetry/semantic-conventions';
|
||||
import process from 'process';
|
||||
import {Request, Response, Application} from 'express';
|
||||
import { AggregationTemporality, MeterProvider, PeriodicExportingMetricReader } from '@opentelemetry/sdk-metrics';
|
||||
import { OTLPMetricExporter } from '@opentelemetry/exporter-metrics-otlp-http';
|
||||
|
||||
export function startTracing() {
|
||||
diag.setLogger(new DiagConsoleLogger(), DiagLogLevel.INFO);
|
||||
|
||||
const sdk = new opentelemetry.NodeSDK({
|
||||
traceExporter: new OTLPTraceExporter({
|
||||
url: process.env.OPENTELEMETRY_OTLP_URI,
|
||||
headers: {}
|
||||
}),
|
||||
resource: new Resource({
|
||||
[SemanticResourceAttributes.SERVICE_NAME]: 'bayshore',
|
||||
[SemanticResourceAttributes.DEPLOYMENT_ENVIRONMENT]:
|
||||
process.env.NODE_ENV !== undefined ? process.env.NODE_ENV : 'development',
|
||||
}),
|
||||
instrumentations: [getNodeAutoInstrumentations()]
|
||||
});
|
||||
|
||||
sdk.start();
|
||||
}
|
||||
|
||||
interface MiddlewareOpts {
|
||||
appName: string,
|
||||
}
|
||||
|
||||
interface HttpMetricsParameter {
|
||||
app: Application,
|
||||
options: MiddlewareOpts
|
||||
}
|
||||
|
||||
// TODO: Implement stuff in such a way to make it be possible to view data like
|
||||
// time attack clears per hour, story stuff etc etc. Not now tho, later
|
||||
export function startHttpMetrics(apps: HttpMetricsParameter[]) {
|
||||
const provider = new MeterProvider({
|
||||
resource: new Resource({
|
||||
[SemanticResourceAttributes.SERVICE_NAME]: 'bayshore',
|
||||
[SemanticResourceAttributes.DEPLOYMENT_ENVIRONMENT]:
|
||||
process.env.NODE_ENV !== undefined ? process.env.NODE_ENV : 'development',
|
||||
}),
|
||||
});
|
||||
|
||||
function configureMiddleware(opts: MiddlewareOpts) {
|
||||
let meter = provider.getMeter(opts.appName);
|
||||
var counter = meter.createCounter('requests_made', {
|
||||
description: 'Number of requests registered to application'
|
||||
});
|
||||
|
||||
return function(req: Request, res: Response, next: CallableFunction) {
|
||||
counter.add(1, {
|
||||
url: req.url
|
||||
});
|
||||
next();
|
||||
}
|
||||
}
|
||||
|
||||
console.log('Registering middleware metrics');
|
||||
|
||||
for (let appObj of apps) {
|
||||
console.log(`Registered metrics application for ${appObj.options.appName}`);
|
||||
appObj.app.use(configureMiddleware(appObj.options));
|
||||
}
|
||||
|
||||
const exporter = new OTLPMetricExporter({
|
||||
url: process.env.OPENTELEMETRY_OTLP_HTTP_URI,
|
||||
});
|
||||
|
||||
provider.addMetricReader(new PeriodicExportingMetricReader({
|
||||
exporter,
|
||||
exportIntervalMillis: 15000,
|
||||
exportTimeoutMillis: 1000,
|
||||
}));
|
||||
|
||||
console.log('Metrics started');
|
||||
}
|
@ -44,21 +44,18 @@ export function getBigIntFromLong(n: Long)
|
||||
}
|
||||
|
||||
|
||||
// Undefined Input Sanitization
|
||||
export function sanitizeInput(value: any)
|
||||
{
|
||||
return (value == null || value == undefined) ? undefined : value;
|
||||
}
|
||||
|
||||
|
||||
// Undefined and Zero Input Sanitization
|
||||
export function sanitizeInputNotZero(value: any)
|
||||
{
|
||||
return (value !== null && value !== undefined && value !== 0) ? value : undefined;
|
||||
}
|
||||
|
||||
|
||||
// Get Time Stamp
|
||||
export function getTimeStamp(date: Date = new Date())
|
||||
{
|
||||
// Return a timestamp string for the current / provided time
|
@ -5,9 +5,10 @@ import { wm } from "../../wmmt/wm.proto";
|
||||
import wmproto from "../../wmmt/wm.proto";
|
||||
|
||||
// Import Util
|
||||
import * as common from "../util/common";
|
||||
import * as common from "../../util/common";
|
||||
import * as ghost_history from "../ghost/ghost_history";
|
||||
import * as ghost_stamp from "../ghost/ghost_stamp";
|
||||
import * as ghost_crown from "../ghost/ghost_crown";
|
||||
|
||||
// Save ghost battle result
|
||||
export async function saveGhostBattleResult(body: wm.protobuf.SaveGameResultRequest, car: any)
|
||||
@ -29,6 +30,7 @@ export async function saveGhostBattleResult(body: wm.protobuf.SaveGameResultRequ
|
||||
let dataGhost : any;
|
||||
let dataCar : any;
|
||||
let dataCarGTWing: any;
|
||||
let dataHighway : any;
|
||||
|
||||
// Get the ghost result for the car
|
||||
let cars = body?.car;
|
||||
@ -106,6 +108,7 @@ export async function saveGhostBattleResult(body: wm.protobuf.SaveGameResultRequ
|
||||
dressupPoint: common.sanitizeInput(ghostResult.dressupPoint),
|
||||
stampSheet: stampSheet,
|
||||
stampSheetCount: common.sanitizeInputNotZero(ghostResult.stampSheetCount),
|
||||
rgTrophy: common.sanitizeInputNotZero(ghostResult.rgTrophy),
|
||||
}
|
||||
|
||||
// Count total win based on region map score
|
||||
@ -122,7 +125,21 @@ export async function saveGhostBattleResult(body: wm.protobuf.SaveGameResultRequ
|
||||
// Set the data
|
||||
dataGhost.rgWinCount = winCounter;
|
||||
dataGhost.rgScore = winCounter;
|
||||
dataGhost.rgTrophy = winCounter;
|
||||
}
|
||||
}
|
||||
|
||||
// Get the ghost result for the car
|
||||
let highwayResult = body.rgResult?.highwayResult;
|
||||
|
||||
// ghostResult is set
|
||||
if (highwayResult)
|
||||
{
|
||||
// Highway Ghost update data
|
||||
dataHighway = {
|
||||
rgHighwayClearCount: common.sanitizeInput(highwayResult.rgHighwayClearCount),
|
||||
rgHighwayPoint: common.sanitizeInput(highwayResult.rgHighwayPoint),
|
||||
rgHighwayStationClearBits: common.sanitizeInput(highwayResult.rgHighwayStationClearBits),
|
||||
rgHighwayPreviousDice: common.sanitizeInput(highwayResult.rgHighwayPreviousDice),
|
||||
}
|
||||
}
|
||||
|
||||
@ -134,6 +151,7 @@ export async function saveGhostBattleResult(body: wm.protobuf.SaveGameResultRequ
|
||||
data: {
|
||||
...dataGhost,
|
||||
...dataCar,
|
||||
...dataHighway
|
||||
}
|
||||
});
|
||||
|
||||
@ -195,136 +213,7 @@ export async function saveGhostBattleResult(body: wm.protobuf.SaveGameResultRequ
|
||||
{
|
||||
console.log('Win the Crown Ghost Battle');
|
||||
|
||||
// Get the ghost crown result
|
||||
let ghostResultCrown = body?.rgResult;
|
||||
|
||||
// Declare data
|
||||
let dataCrown : any;
|
||||
|
||||
// ghostResultCrown is set
|
||||
if (ghostResultCrown)
|
||||
{
|
||||
let carId: number = 0;
|
||||
if(body.carId)
|
||||
{
|
||||
carId = Number(body.carId);
|
||||
}
|
||||
|
||||
// Ghost Crown update data
|
||||
dataCrown = {
|
||||
carId: carId,
|
||||
playedAt: common.sanitizeInput(body.playedAt),
|
||||
tunePower: common.sanitizeInput(body.car?.tunePower),
|
||||
tuneHandling: common.sanitizeInput(body.car?.tuneHandling),
|
||||
}
|
||||
|
||||
// Get the area id and ramp id
|
||||
let area = 0;
|
||||
let ramp = 0;
|
||||
let path = 0;
|
||||
if(body.rgResult?.path)
|
||||
{
|
||||
if(body.rgResult?.path >= 0 && body.rgResult?.path <= 9){ // GID_PATH_C1
|
||||
area = Number(0);
|
||||
ramp = Number(Math.floor(Math.random() * 4));
|
||||
}
|
||||
else if(body.rgResult?.path >= 10 && body.rgResult?.path <= 15){ // GID_PATH_N9
|
||||
area = Number(1);
|
||||
ramp = Number(Math.floor(Math.random() * 2) + 4);
|
||||
}
|
||||
else if(body.rgResult?.path >= 16 && body.rgResult?.path <= 17){ // GID_PATH_WTEAST
|
||||
area = Number(2);
|
||||
ramp = Number(Math.floor(Math.random() * 2) + 6);
|
||||
}
|
||||
else if(body.rgResult?.path >= 18 && body.rgResult?.path <= 19){ // GID_PATH_WT_UP_DOWN
|
||||
area = Number(3);
|
||||
ramp = Number(Math.floor(Math.random() * 2) + 8);
|
||||
}
|
||||
else if(body.rgResult?.path >= 20 && body.rgResult?.path <= 26){ // GID_PATH_WG
|
||||
area = Number(4);
|
||||
ramp = Number(Math.floor(Math.random() * 4) + 10);
|
||||
}
|
||||
else if(body.rgResult?.path >= 27 && body.rgResult?.path <= 33){ // GID_PATH_KG
|
||||
area = Number(5);
|
||||
ramp = Number(Math.floor(Math.random() * 4) + 14);
|
||||
}
|
||||
else if(body.rgResult?.path >= 34 && body.rgResult?.path <= 37){ // GID_PATH_YS
|
||||
area = Number(6);
|
||||
ramp = Number(Math.floor(Math.random() * 3) + 18);
|
||||
}
|
||||
else if(body.rgResult?.path >= 38 && body.rgResult?.path <= 48){ // GID_PATH_KG_SHINYAMASHITA_MINATOMIRAI
|
||||
area = Number(7);
|
||||
ramp = Number(Math.floor(Math.random() * 4) + 21);
|
||||
}
|
||||
else if(body.rgResult?.path === 49){ // GID_PATH_NGR
|
||||
area = Number(8);
|
||||
ramp = Number(25);
|
||||
}
|
||||
else if(body.rgResult?.path >= 50 && body.rgResult?.path <= 53){ // GID_PATH_OS
|
||||
area = Number(9);
|
||||
ramp = Number(26);
|
||||
}
|
||||
else if(body.rgResult?.path >= 54 && body.rgResult?.path <= 55){ // GID_PATH_KB
|
||||
area = Number(10);
|
||||
ramp = Number(Math.floor(Math.random() * 2) + 27);
|
||||
}
|
||||
else if(body.rgResult?.path >= 58 && body.rgResult?.path <= 61){ // GID_PATH_FK
|
||||
area = Number(11);
|
||||
ramp = Number(Math.floor(Math.random() * 4) + 29);
|
||||
}
|
||||
else if(body.rgResult?.path >= 62 && body.rgResult?.path <= 63){ // GID_PATH_HK
|
||||
area = Number(12);
|
||||
ramp = Number(Math.floor(Math.random() * 2) + 33);
|
||||
}
|
||||
else if(body.rgResult?.path >= 64 && body.rgResult?.path <= 65){ // GID_PATH_TP
|
||||
area = Number(13);
|
||||
ramp = Number(Math.floor(Math.random() * 2) + 35);
|
||||
}
|
||||
else if(body.rgResult?.path >= 56 && body.rgResult?.path <= 57){ // GID_PATH_HS
|
||||
area = Number(18);
|
||||
ramp = Number(Math.floor(Math.random() * 2) + 27);
|
||||
}
|
||||
|
||||
path = Number(body.rgResult.path);
|
||||
}
|
||||
|
||||
// Get the available crown holder data
|
||||
let carCrowns = await prisma.carCrown.count({
|
||||
where: {
|
||||
area: area
|
||||
}
|
||||
});
|
||||
|
||||
// Crown holder data available
|
||||
if(carCrowns !== 0)
|
||||
{
|
||||
// Update it to the new one
|
||||
let areaVal = Number(area);
|
||||
await prisma.carCrown.update({
|
||||
where: {
|
||||
area: areaVal
|
||||
},
|
||||
data: {
|
||||
...dataCrown,
|
||||
area: area,
|
||||
ramp: ramp,
|
||||
path: path
|
||||
}
|
||||
});
|
||||
}
|
||||
// Crown holder data not available or still default crown holder data
|
||||
else
|
||||
{
|
||||
await prisma.carCrown.create({
|
||||
data: {
|
||||
...dataCrown,
|
||||
area: area,
|
||||
ramp: ramp,
|
||||
path: path
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
await ghost_crown.saveCrownData(body);
|
||||
|
||||
updateNewTrail = true;
|
||||
}
|
||||
@ -516,10 +405,10 @@ export async function saveGhostBattleResult(body: wm.protobuf.SaveGameResultRequ
|
||||
break;
|
||||
}
|
||||
|
||||
// Ghost Battle Select from Bookmarks (12)
|
||||
// Ghost Battle Select from Bookmars (12)
|
||||
case wmproto.wm.protobuf.GhostSelectionMethod.GHOST_SELECT_FROM_BOOKMARKS:
|
||||
{
|
||||
console.log('Normal Ghost Mode Found - Select from Bookmarks');
|
||||
console.log('Normal Ghost Mode Found - Select from Bookmars');
|
||||
|
||||
ghost_historys = await ghost_history.saveGhostHistory(body);
|
||||
|
||||
@ -531,6 +420,192 @@ export async function saveGhostBattleResult(body: wm.protobuf.SaveGameResultRequ
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
// Ghost Battle Expedition (13)
|
||||
case wmproto.wm.protobuf.GhostSelectionMethod.GHOST_EXPEDITION:
|
||||
{
|
||||
console.log('Normal Ghost Mode Found - VS Other Region (Expedition)');
|
||||
|
||||
ghost_historys = await ghost_history.saveVSORGGhostHistory(body);
|
||||
|
||||
// Return Stamp (Shuttle Match)
|
||||
await ghost_stamp.shuttleReturnStamp(body);
|
||||
|
||||
// Update the updateNewTrail value
|
||||
updateNewTrail = ghost_historys.updateNewTrail;
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
// Ghost Battle Select by Place (14)
|
||||
case wmproto.wm.protobuf.GhostSelectionMethod.GHOST_SELECT_BY_PLACE:
|
||||
{
|
||||
console.log('Normal Ghost Mode Found - Select by Place');
|
||||
|
||||
// TODO: Make saving
|
||||
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 by Other Place (15)
|
||||
case wmproto.wm.protobuf.GhostSelectionMethod.GHOST_SELECT_BY_OTHER_PLACE:
|
||||
{
|
||||
console.log('Normal Ghost Mode Found - Select by Other Place');
|
||||
|
||||
// TODO: Make saving
|
||||
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 by Manufacturer (16)
|
||||
case wmproto.wm.protobuf.GhostSelectionMethod.GHOST_SELECT_BY_MANUFACTURER:
|
||||
{
|
||||
console.log('Normal Ghost Mode Found - Select by Manufacturer');
|
||||
|
||||
// TODO: Make saving
|
||||
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 by Other Manufacturer (17)
|
||||
case wmproto.wm.protobuf.GhostSelectionMethod.GHOST_SELECT_BY_OTHER_MANUFACTURER:
|
||||
{
|
||||
console.log('Normal Ghost Mode Found - Select by Other Manufacturer');
|
||||
|
||||
// TODO: Make saving
|
||||
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 by Played (18)
|
||||
case wmproto.wm.protobuf.GhostSelectionMethod.GHOST_SELECT_BY_PLAYED:
|
||||
{
|
||||
console.log('Normal Ghost Mode Found - Select by Played');
|
||||
|
||||
// TODO: Make saving
|
||||
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 by Region Manufacturer (20)
|
||||
case wmproto.wm.protobuf.GhostSelectionMethod.GHOST_SELECT_BY_REGION_MANUFACTURER:
|
||||
{
|
||||
console.log('Normal Ghost Mode Found - Select by Region Manufacturer');
|
||||
|
||||
// TODO: Make saving
|
||||
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 by Region Played (22)
|
||||
case wmproto.wm.protobuf.GhostSelectionMethod.GHOST_SELECT_BY_REGION_PLAYED:
|
||||
{
|
||||
console.log('Normal Ghost Mode Found - Select by Region Played');
|
||||
|
||||
// TODO: Make saving
|
||||
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 by Region Station (23)
|
||||
case wmproto.wm.protobuf.GhostSelectionMethod.GHOST_SELECT_BY_REGION_STATION:
|
||||
{
|
||||
console.log('Normal Ghost Mode Found - Select by Region Station');
|
||||
|
||||
// TODO: Make saving
|
||||
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 by Region Boss (24)
|
||||
case wmproto.wm.protobuf.GhostSelectionMethod.GHOST_SELECT_BY_REGION_BOSS:
|
||||
{
|
||||
console.log('Normal Ghost Mode Found - Select by Region Boss');
|
||||
|
||||
// TODO: Make saving
|
||||
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 by Region Place (25)
|
||||
case wmproto.wm.protobuf.GhostSelectionMethod.GHOST_SELECT_BY_REGION_PLACE:
|
||||
{
|
||||
console.log('Normal Ghost Mode Found - Select by Region Place');
|
||||
|
||||
// TODO: Make saving
|
||||
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
|
||||
@ -549,14 +624,11 @@ export async function saveGhostBattleResult(body: wm.protobuf.SaveGameResultRequ
|
||||
// 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 = {
|
||||
let dataGhost = {
|
||||
rgPlayCount: common.sanitizeInput(ghostResult.rgPlayCount),
|
||||
}
|
||||
|
||||
@ -571,6 +643,7 @@ export async function saveGhostBattleResult(body: wm.protobuf.SaveGameResultRequ
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// Retiring OCM for mini games
|
||||
else if(body.rgResult!.selectionMethod === wmproto.wm.protobuf.GhostSelectionMethod.GHOST_COMPETITION)
|
||||
{
|
||||
@ -660,6 +733,15 @@ export async function saveGhostBattleResult(body: wm.protobuf.SaveGameResultRequ
|
||||
});
|
||||
}
|
||||
|
||||
// Retiring VS ORG
|
||||
else if(body.rgResult!.selectionMethod === wmproto.wm.protobuf.GhostSelectionMethod.GHOST_EXPEDITION)
|
||||
{
|
||||
console.log('VSORG (Expedition) Ghost Mode Found but Retiring');
|
||||
|
||||
await ghost_history.saveVSORGGhostRetireHistory(body);
|
||||
}
|
||||
// TODO: Highway Ghost Mode Retiring Saving
|
||||
|
||||
// Return the value to 'BASE_PATH/src/modules/game.ts'
|
||||
return { ghostModePlay, updateNewTrail, OCMModePlay }
|
||||
}
|
@ -5,8 +5,8 @@ import { prisma } from "../..";
|
||||
import { wm } from "../../wmmt/wm.proto";
|
||||
|
||||
// Import Util
|
||||
import * as common from "../util/common";
|
||||
import * as check_step from "./games_util/check_step";
|
||||
import * as common from "../common";
|
||||
import * as check_step from "../games/games_util/check_step";
|
||||
|
||||
|
||||
// Save story result
|
||||
@ -35,7 +35,7 @@ export async function saveStoryResult(body: wm.protobuf.SaveGameResultRequest, c
|
||||
}
|
||||
|
||||
// If the current consecutive wins is greater than the previous max
|
||||
if (storyResult.stConsecutiveWins! > car!.stConsecutiveWinsMax)
|
||||
if (storyResult.stConsecutiveWins! > car.stConsecutiveWinsMax)
|
||||
{
|
||||
// Update the maximum consecutive wins;
|
||||
data.stConsecutiveWinsMax = storyResult.stConsecutiveWins;
|
||||
@ -46,7 +46,10 @@ export async function saveStoryResult(body: wm.protobuf.SaveGameResultRequest, c
|
||||
{
|
||||
// Convert them to BigInt and add to the data
|
||||
data.stLoseBits = common.getBigIntFromLong(storyResult.stLoseBits);
|
||||
if(data.stLoseBits > 0)
|
||||
{
|
||||
stLoseBits = data.stLoseBits
|
||||
}
|
||||
|
||||
// If a loss has been recorded
|
||||
if (stLoseBits > 0)
|
||||
@ -55,6 +58,10 @@ export async function saveStoryResult(body: wm.protobuf.SaveGameResultRequest, c
|
||||
data.stConsecutiveWins = 0;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
stLoseBits = 0;
|
||||
}
|
||||
|
||||
// Calling check step function (BASE_PATH/src/util/games/games_util/check_step.ts)
|
||||
let check_steps = await check_step.checkCurrentStep(body);
|
@ -52,20 +52,14 @@ export async function saveTimeAttackResult(body: wm.protobuf.SaveGameResultReque
|
||||
cheatedTime = true;
|
||||
}
|
||||
|
||||
// Check the time again
|
||||
if (body.taResult!.time <= 0 || body.taResult!.time >= 1200000 || body.taResult!.time.toString() == "-2147483648")
|
||||
{
|
||||
cheatedTime = true;
|
||||
}
|
||||
|
||||
// Not Cheated Time
|
||||
if(cheatedTime === false)
|
||||
{
|
||||
// Record already exists
|
||||
if (currentRecord)
|
||||
{
|
||||
// Current time record is faster than previous time record and time record is below 20 minutes
|
||||
if (body.taResult!.time < currentRecord.time && body.taResult!.time < 1200000)
|
||||
// If the existing record is faster, do not continue
|
||||
if (body.taResult!.time < currentRecord.time)
|
||||
{
|
||||
console.log('Updating time attack record...');
|
||||
|
||||
@ -90,10 +84,7 @@ export async function saveTimeAttackResult(body: wm.protobuf.SaveGameResultReque
|
||||
});
|
||||
}
|
||||
}
|
||||
// Creating a new record
|
||||
else
|
||||
{
|
||||
if (body.taResult!.time < 1200000)
|
||||
else // Creating a new record
|
||||
{
|
||||
console.log('Creating new time attack record');
|
||||
|
||||
@ -117,7 +108,6 @@ export async function saveTimeAttackResult(body: wm.protobuf.SaveGameResultReque
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
// else {} cheated time, ignore it
|
||||
}
|
||||
}
|
@ -4,7 +4,7 @@ import { prisma } from "../..";
|
||||
import { wm } from "../../wmmt/wm.proto";
|
||||
|
||||
// Import Util
|
||||
import * as common from "../util/common";
|
||||
import * as common from "../common";
|
||||
|
||||
|
||||
// Save versus battle result
|
143
src/util/ghost/ghost_crown.ts
Normal file
143
src/util/ghost/ghost_crown.ts
Normal file
@ -0,0 +1,143 @@
|
||||
import { prisma } from "../..";
|
||||
|
||||
// Import Proto
|
||||
import { wm } from "../../wmmt/wm.proto";
|
||||
|
||||
// Import Util
|
||||
import * as common from "../../util/common";
|
||||
|
||||
|
||||
// Saving Crown Data
|
||||
export async function saveCrownData(body: wm.protobuf.SaveGameResultRequest)
|
||||
{
|
||||
// Get the ghost crown result
|
||||
let ghostResultCrown = body?.rgResult;
|
||||
|
||||
// Declare data
|
||||
let dataCrown : any;
|
||||
|
||||
// ghostResultCrown is set
|
||||
if (ghostResultCrown)
|
||||
{
|
||||
let carId: number = 0;
|
||||
if(body.carId)
|
||||
{
|
||||
carId = Number(body.carId);
|
||||
}
|
||||
|
||||
// Ghost Crown update data
|
||||
dataCrown = {
|
||||
carId: carId,
|
||||
playedAt: common.sanitizeInput(body.playedAt),
|
||||
tunePower: common.sanitizeInput(body.car?.tunePower),
|
||||
tuneHandling: common.sanitizeInput(body.car?.tuneHandling),
|
||||
}
|
||||
|
||||
// Get the area id and ramp id
|
||||
let area = 0;
|
||||
let ramp = 0;
|
||||
let path = 0;
|
||||
if(body.rgResult?.path)
|
||||
{
|
||||
if(body.rgResult?.path >= 0 && body.rgResult?.path <= 9){ // GID_PATH_C1
|
||||
area = Number(0);
|
||||
ramp = Number(Math.floor(Math.random() * 4));
|
||||
}
|
||||
else if(body.rgResult?.path >= 10 && body.rgResult?.path <= 15){ // GID_PATH_N9
|
||||
area = Number(1);
|
||||
ramp = Number(Math.floor(Math.random() * 2) + 4);
|
||||
}
|
||||
else if(body.rgResult?.path >= 16 && body.rgResult?.path <= 17){ // GID_PATH_WTEAST
|
||||
area = Number(2);
|
||||
ramp = Number(Math.floor(Math.random() * 2) + 6);
|
||||
}
|
||||
else if(body.rgResult?.path >= 18 && body.rgResult?.path <= 19){ // GID_PATH_WT_UP_DOWN
|
||||
area = Number(3);
|
||||
ramp = Number(Math.floor(Math.random() * 2) + 8);
|
||||
}
|
||||
else if(body.rgResult?.path >= 20 && body.rgResult?.path <= 26){ // GID_PATH_WG
|
||||
area = Number(4);
|
||||
ramp = Number(Math.floor(Math.random() * 4) + 10);
|
||||
}
|
||||
else if(body.rgResult?.path >= 27 && body.rgResult?.path <= 33){ // GID_PATH_KG
|
||||
area = Number(5);
|
||||
ramp = Number(Math.floor(Math.random() * 4) + 14);
|
||||
}
|
||||
else if(body.rgResult?.path >= 34 && body.rgResult?.path <= 37){ // GID_PATH_YS
|
||||
area = Number(6);
|
||||
ramp = Number(Math.floor(Math.random() * 3) + 18);
|
||||
}
|
||||
else if(body.rgResult?.path >= 38 && body.rgResult?.path <= 48){ // GID_PATH_KG_SHINYAMASHITA_MINATOMIRAI
|
||||
area = Number(7);
|
||||
ramp = Number(Math.floor(Math.random() * 4) + 21);
|
||||
}
|
||||
else if(body.rgResult?.path === 49){ // GID_PATH_NGR
|
||||
area = Number(8);
|
||||
ramp = Number(25);
|
||||
}
|
||||
else if(body.rgResult?.path >= 50 && body.rgResult?.path <= 53){ // GID_PATH_OS
|
||||
area = Number(9);
|
||||
ramp = Number(26);
|
||||
}
|
||||
else if(body.rgResult?.path >= 54 && body.rgResult?.path <= 55){ // GID_PATH_KB
|
||||
area = Number(10);
|
||||
ramp = Number(Math.floor(Math.random() * 2) + 27);
|
||||
}
|
||||
else if(body.rgResult?.path >= 58 && body.rgResult?.path <= 61){ // GID_PATH_FK
|
||||
area = Number(11);
|
||||
ramp = Number(Math.floor(Math.random() * 4) + 29);
|
||||
}
|
||||
else if(body.rgResult?.path >= 62 && body.rgResult?.path <= 63){ // GID_PATH_HK
|
||||
area = Number(12);
|
||||
ramp = Number(Math.floor(Math.random() * 2) + 33);
|
||||
}
|
||||
else if(body.rgResult?.path >= 64 && body.rgResult?.path <= 65){ // GID_PATH_TP
|
||||
area = Number(13);
|
||||
ramp = Number(Math.floor(Math.random() * 2) + 35);
|
||||
}
|
||||
else if(body.rgResult?.path >= 56 && body.rgResult?.path <= 57){ // GID_PATH_HS
|
||||
area = Number(18);
|
||||
ramp = Number(Math.floor(Math.random() * 2) + 27);
|
||||
}
|
||||
|
||||
path = Number(body.rgResult.path);
|
||||
}
|
||||
|
||||
// Get the available crown holder data
|
||||
let carCrowns = await prisma.carCrown.count({
|
||||
where: {
|
||||
area: area
|
||||
}
|
||||
});
|
||||
|
||||
// Crown holder data available
|
||||
if(carCrowns !== 0)
|
||||
{
|
||||
// Update it to the new one
|
||||
let areaVal = Number(area);
|
||||
await prisma.carCrown.update({
|
||||
where: {
|
||||
area: areaVal
|
||||
},
|
||||
data: {
|
||||
...dataCrown,
|
||||
area: area,
|
||||
ramp: ramp,
|
||||
path: path
|
||||
}
|
||||
});
|
||||
}
|
||||
// Crown holder data not available or still default crown holder data
|
||||
else
|
||||
{
|
||||
await prisma.carCrown.create({
|
||||
data: {
|
||||
...dataCrown,
|
||||
area: area,
|
||||
ramp: ramp,
|
||||
path: path
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
573
src/util/ghost/ghost_default_car.ts
Normal file
573
src/util/ghost/ghost_default_car.ts
Normal file
@ -0,0 +1,573 @@
|
||||
import { Config } from "../../config";
|
||||
|
||||
// Import Proto
|
||||
import * as wm from "../../wmmt/wm.proto";
|
||||
|
||||
// Global Variable
|
||||
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
|
||||
});
|
||||
|
||||
|
||||
export async function DefaultGhostCarBMW()
|
||||
{
|
||||
let cars = wm.wm.protobuf.Car.create({
|
||||
carId: 999999999, // Don't change this
|
||||
name: 'SAFTY',
|
||||
regionId: 18, // IDN (福井)
|
||||
manufacturer: 0,
|
||||
model: 71, // Z4 Safty (yes.. safty)
|
||||
visualModel: 100, // Z4 Safty (yes.. safty)
|
||||
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: 18,
|
||||
tuneHandling: 16,
|
||||
rivalMarker: 32,
|
||||
aura: 551,
|
||||
windowSticker: true,
|
||||
windowStickerString: 'BAYSHORE',
|
||||
windowStickerFont: 0,
|
||||
title: 'Wangan Beginner',
|
||||
level: 65, // SSSSS
|
||||
lastPlayedAt: date,
|
||||
country: 'JPN',
|
||||
lastPlayedPlace: playedPlace
|
||||
});
|
||||
|
||||
return { cars };
|
||||
}
|
||||
|
||||
|
||||
export async function DefaultGhostCarChevrolet()
|
||||
{
|
||||
let cars = wm.wm.protobuf.Car.create({
|
||||
carId: 999999999, // Don't change this
|
||||
name: 'TAXI',
|
||||
regionId: 18, // IDN (福井)
|
||||
manufacturer: 1,
|
||||
model: 66, // Corvette C6 Taxi
|
||||
visualModel: 1, // Corvette C6 Taxi
|
||||
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: 18,
|
||||
tuneHandling: 16,
|
||||
rivalMarker: 32,
|
||||
aura: 551,
|
||||
windowSticker: true,
|
||||
windowStickerString: 'BAYSHORE',
|
||||
windowStickerFont: 0,
|
||||
title: 'Wangan Beginner',
|
||||
level: 65, // SSSSS
|
||||
lastPlayedAt: date,
|
||||
country: 'JPN',
|
||||
lastPlayedPlace: playedPlace
|
||||
});
|
||||
|
||||
return { cars };
|
||||
}
|
||||
|
||||
|
||||
export async function DefaultGhostCarMazda()
|
||||
{
|
||||
let cars = wm.wm.protobuf.Car.create({
|
||||
carId: 999999999, // Don't change this
|
||||
name: 'EREK7',
|
||||
regionId: 18, // IDN (福井)
|
||||
manufacturer: 2,
|
||||
model: 9, // RX-7
|
||||
visualModel: 6, // RX-7
|
||||
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: 18,
|
||||
tuneHandling: 16,
|
||||
rivalMarker: 32,
|
||||
aura: 551,
|
||||
windowSticker: true,
|
||||
windowStickerString: 'BAYSHORE',
|
||||
windowStickerFont: 0,
|
||||
title: 'Wangan Beginner',
|
||||
level: 65, // SSSSS
|
||||
lastPlayedAt: date,
|
||||
country: 'JPN',
|
||||
lastPlayedPlace: playedPlace
|
||||
});
|
||||
|
||||
return { cars };
|
||||
}
|
||||
|
||||
|
||||
export async function DefaultGhostCarMercedes()
|
||||
{
|
||||
let cars = wm.wm.protobuf.Car.create({
|
||||
carId: 999999999, // Don't change this
|
||||
name: 'SLS',
|
||||
regionId: 18, // IDN (福井)
|
||||
manufacturer: 3,
|
||||
model: 87, // SLS AMG
|
||||
visualModel: 107, // SLS AMG
|
||||
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: 18,
|
||||
tuneHandling: 16,
|
||||
rivalMarker: 32,
|
||||
aura: 551,
|
||||
windowSticker: true,
|
||||
windowStickerString: 'BAYSHORE',
|
||||
windowStickerFont: 0,
|
||||
title: 'Wangan Beginner',
|
||||
level: 65, // SSSSS
|
||||
lastPlayedAt: date,
|
||||
country: 'JPN',
|
||||
lastPlayedPlace: playedPlace
|
||||
});
|
||||
|
||||
return { cars };
|
||||
}
|
||||
|
||||
|
||||
export async function DefaultGhostCarMitsubishi()
|
||||
{
|
||||
let cars = wm.wm.protobuf.Car.create({
|
||||
carId: 999999999, // Don't change this
|
||||
name: 'EVO 9',
|
||||
regionId: 18, // IDN (福井)
|
||||
manufacturer: 4,
|
||||
model: 22, // EVO IX
|
||||
visualModel: 15, // EVO IX
|
||||
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: 18,
|
||||
tuneHandling: 16,
|
||||
rivalMarker: 32,
|
||||
aura: 551,
|
||||
windowSticker: true,
|
||||
windowStickerString: 'BAYSHORE',
|
||||
windowStickerFont: 0,
|
||||
title: 'Wangan Beginner',
|
||||
level: 65, // SSSSS
|
||||
lastPlayedAt: date,
|
||||
country: 'JPN',
|
||||
lastPlayedPlace: playedPlace
|
||||
});
|
||||
|
||||
return { cars };
|
||||
}
|
||||
|
||||
|
||||
export async function DefaultGhostCarNissan()
|
||||
{
|
||||
let cars = wm.wm.protobuf.Car.create({
|
||||
carId: 999999999, // Don't change this
|
||||
name: 'DEBUG',
|
||||
regionId: 18, // IDN (福井)
|
||||
manufacturer: 5,
|
||||
model: 27, // R34 nur
|
||||
visualModel: 30, // R34 nur
|
||||
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: 18,
|
||||
tuneHandling: 16,
|
||||
rivalMarker: 32,
|
||||
aura: 551,
|
||||
windowSticker: true,
|
||||
windowStickerString: 'BAYSHORE',
|
||||
windowStickerFont: 0,
|
||||
title: 'Wangan Beginner',
|
||||
level: 65, // SSSSS
|
||||
lastPlayedAt: date,
|
||||
country: 'JPN',
|
||||
lastPlayedPlace: playedPlace
|
||||
});
|
||||
|
||||
return { cars };
|
||||
}
|
||||
|
||||
|
||||
export async function DefaultGhostCarSubaru()
|
||||
{
|
||||
let cars = wm.wm.protobuf.Car.create({
|
||||
carId: 999999999, // Don't change this
|
||||
name: 'SVX',
|
||||
regionId: 18, // IDN (福井)
|
||||
manufacturer: 7,
|
||||
model: 47, // ALCYONE SVX
|
||||
visualModel: 54, // ALCYONE SVX
|
||||
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: 18,
|
||||
tuneHandling: 16,
|
||||
rivalMarker: 32,
|
||||
aura: 551,
|
||||
windowSticker: true,
|
||||
windowStickerString: 'BAYSHORE',
|
||||
windowStickerFont: 0,
|
||||
title: 'Wangan Beginner',
|
||||
level: 65, // SSSSS
|
||||
lastPlayedAt: date,
|
||||
country: 'JPN',
|
||||
lastPlayedPlace: playedPlace
|
||||
});
|
||||
|
||||
return { cars };
|
||||
}
|
||||
|
||||
|
||||
export async function DefaultGhostCarToyota()
|
||||
{
|
||||
let cars = wm.wm.protobuf.Car.create({
|
||||
carId: 999999999, // Don't change this
|
||||
name: 'A90',
|
||||
regionId: 18, // IDN (福井)
|
||||
manufacturer: 8,
|
||||
model: 122, // GR Supra (not honda supra motorbike)
|
||||
visualModel: 145, // GR Supra (not honda supra motorbike)
|
||||
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: 18,
|
||||
tuneHandling: 16,
|
||||
rivalMarker: 32,
|
||||
aura: 551,
|
||||
windowSticker: true,
|
||||
windowStickerString: 'BAYSHORE',
|
||||
windowStickerFont: 0,
|
||||
title: 'Wangan Beginner',
|
||||
level: 65, // SSSSS
|
||||
lastPlayedAt: date,
|
||||
country: 'JPN',
|
||||
lastPlayedPlace: playedPlace
|
||||
});
|
||||
|
||||
return { cars };
|
||||
}
|
||||
|
||||
|
||||
export async function DefaultGhostCarAudi()
|
||||
{
|
||||
let cars = wm.wm.protobuf.Car.create({
|
||||
carId: 999999999, // Don't change this
|
||||
name: 'R8',
|
||||
regionId: 18, // IDN (福井)
|
||||
manufacturer: 9,
|
||||
model: 89, // R8
|
||||
visualModel: 109, // R8
|
||||
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: 18,
|
||||
tuneHandling: 16,
|
||||
rivalMarker: 32,
|
||||
aura: 551,
|
||||
windowSticker: true,
|
||||
windowStickerString: 'BAYSHORE',
|
||||
windowStickerFont: 0,
|
||||
title: 'Wangan Beginner',
|
||||
level: 65, // SSSSS
|
||||
lastPlayedAt: date,
|
||||
country: 'JPN',
|
||||
lastPlayedPlace: playedPlace
|
||||
});
|
||||
|
||||
return { cars };
|
||||
}
|
||||
|
||||
|
||||
export async function DefaultGhostCarDodge()
|
||||
{
|
||||
let cars = wm.wm.protobuf.Car.create({
|
||||
carId: 999999999, // Don't change this
|
||||
name: 'VIPER',
|
||||
regionId: 18, // IDN (福井)
|
||||
manufacturer: 10,
|
||||
model: 91, // Viper SRT10
|
||||
visualModel: 111, // Viper SRT10
|
||||
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: 18,
|
||||
tuneHandling: 16,
|
||||
rivalMarker: 32,
|
||||
aura: 551,
|
||||
windowSticker: true,
|
||||
windowStickerString: 'BAYSHORE',
|
||||
windowStickerFont: 0,
|
||||
title: 'Wangan Beginner',
|
||||
level: 65, // SSSSS
|
||||
lastPlayedAt: date,
|
||||
country: 'JPN',
|
||||
lastPlayedPlace: playedPlace
|
||||
});
|
||||
|
||||
return { cars };
|
||||
}
|
||||
|
||||
|
||||
export async function DefaultGhostCarLamborghini()
|
||||
{
|
||||
let cars = wm.wm.protobuf.Car.create({
|
||||
carId: 999999999, // Don't change this
|
||||
name: 'MIURA',
|
||||
regionId: 18, // IDN (福井)
|
||||
manufacturer: 11,
|
||||
model: 103, // MIURA
|
||||
visualModel: 125, // MIURA
|
||||
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: 18,
|
||||
tuneHandling: 16,
|
||||
rivalMarker: 32,
|
||||
aura: 551,
|
||||
windowSticker: true,
|
||||
windowStickerString: 'BAYSHORE',
|
||||
windowStickerFont: 0,
|
||||
title: 'Wangan Beginner',
|
||||
level: 65, // SSSSS
|
||||
lastPlayedAt: date,
|
||||
country: 'JPN',
|
||||
lastPlayedPlace: playedPlace
|
||||
});
|
||||
|
||||
return { cars };
|
||||
}
|
||||
|
||||
|
||||
export async function DefaultGhostCarHonda()
|
||||
{
|
||||
let cars = wm.wm.protobuf.Car.create({
|
||||
carId: 999999999, // Don't change this
|
||||
name: 'S660',
|
||||
regionId: 18, // IDN (福井)
|
||||
manufacturer: 12,
|
||||
model: 105, // S660
|
||||
visualModel: 130, // S660
|
||||
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: 18,
|
||||
tuneHandling: 16,
|
||||
rivalMarker: 32,
|
||||
aura: 551,
|
||||
windowSticker: true,
|
||||
windowStickerString: 'BAYSHORE',
|
||||
windowStickerFont: 0,
|
||||
title: 'Wangan Beginner',
|
||||
level: 65, // SSSSS
|
||||
lastPlayedAt: date,
|
||||
country: 'JPN',
|
||||
lastPlayedPlace: playedPlace
|
||||
});
|
||||
|
||||
return { cars };
|
||||
}
|
||||
|
||||
|
||||
export async function DefaultGhostCarAcura()
|
||||
{
|
||||
let cars = wm.wm.protobuf.Car.create({
|
||||
carId: 999999999, // Don't change this
|
||||
name: 'ACURA',
|
||||
regionId: 18, // IDN (福井)
|
||||
manufacturer: 12, // Not Acura... Acura is ID 13
|
||||
model: 107, // Honda NSX
|
||||
visualModel: 128, // Honda NSX
|
||||
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: 18,
|
||||
tuneHandling: 16,
|
||||
rivalMarker: 32,
|
||||
aura: 551,
|
||||
windowSticker: true,
|
||||
windowStickerString: 'BAYSHORE',
|
||||
windowStickerFont: 0,
|
||||
title: 'Wangan Beginner',
|
||||
level: 65, // SSSSS
|
||||
lastPlayedAt: date,
|
||||
country: 'JPN',
|
||||
lastPlayedPlace: playedPlace
|
||||
});
|
||||
|
||||
return { cars };
|
||||
}
|
||||
|
||||
|
||||
export async function DefaultGhostCarPorsche()
|
||||
{
|
||||
let cars = wm.wm.protobuf.Car.create({
|
||||
carId: 999999999, // Don't change this
|
||||
name: '718',
|
||||
regionId: 18, // IDN (福井)
|
||||
manufacturer: 14,
|
||||
model: 121, // 718 CAYMAN S
|
||||
visualModel: 144, // 718 CAYMAN S
|
||||
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: 18,
|
||||
tuneHandling: 16,
|
||||
rivalMarker: 32,
|
||||
aura: 551,
|
||||
windowSticker: true,
|
||||
windowStickerString: 'BAYSHORE',
|
||||
windowStickerFont: 0,
|
||||
title: 'Wangan Beginner',
|
||||
level: 65, // SSSSS
|
||||
lastPlayedAt: date,
|
||||
country: 'JPN',
|
||||
lastPlayedPlace: playedPlace
|
||||
});
|
||||
|
||||
return { cars };
|
||||
}
|
832
src/util/ghost/ghost_history.ts
Normal file
832
src/util/ghost/ghost_history.ts
Normal file
@ -0,0 +1,832 @@
|
||||
import { prisma } from "../..";
|
||||
import { Config } from "../../config";
|
||||
|
||||
// Import Proto
|
||||
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
|
||||
export async function saveGhostHistory(body: wm.protobuf.SaveGameResultRequest)
|
||||
{
|
||||
console.log('Saving Ghost Battle History');
|
||||
|
||||
let updateNewTrail: boolean = true;
|
||||
let saveExGhostHistory: any = {};
|
||||
|
||||
// Get the car result for the car
|
||||
let car = body?.car;
|
||||
|
||||
if(car)
|
||||
{
|
||||
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 }
|
||||
}
|
||||
|
||||
|
||||
// Save OCM ghost history battle
|
||||
export async function saveOCMGhostHistory(body: wm.protobuf.SaveGameResultRequest)
|
||||
{
|
||||
let updateNewTrail: boolean = true;
|
||||
let saveExGhostHistory: any = {};
|
||||
|
||||
// Get the car result for the car
|
||||
let car = body?.car;
|
||||
|
||||
if(car)
|
||||
{
|
||||
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 the advantage distance between first opponent and user
|
||||
saveExGhostHistory.result = rgResult.opponents[0].result;
|
||||
}
|
||||
|
||||
// Get played Area
|
||||
if(common.sanitizeInput(rgResult.path))
|
||||
{
|
||||
let getArea = await ghost_get_area_from_path.getArea(rgResult.path);
|
||||
|
||||
saveExGhostHistory.area = getArea.area
|
||||
}
|
||||
}
|
||||
|
||||
// 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 equal current date
|
||||
qualifyingPeriodStartAt: { lte: date },
|
||||
|
||||
// competitionEndAt is greater than equal current date
|
||||
competitionEndAt: { gte: date },
|
||||
},
|
||||
orderBy:{
|
||||
dbId: 'desc'
|
||||
}
|
||||
});
|
||||
|
||||
// ----------Get available OCM Record (Qualifying or Main Draw)----------
|
||||
// Current date is OCM main draw
|
||||
let countGBR;
|
||||
if(ocmEventDate!.competitionStartAt < date && ocmEventDate!.competitionCloseAt > date)
|
||||
{
|
||||
// Set OCM Main draw value to true
|
||||
saveExGhostHistory.ocmMainDraw = true
|
||||
|
||||
// Get the user's available OCM Battle Record data
|
||||
countGBR = await prisma.oCMTally.findFirst({
|
||||
where:{
|
||||
carId: saveExGhostHistory.carId,
|
||||
competitionId: ocmEventDate!.competitionId,
|
||||
}
|
||||
});
|
||||
}
|
||||
// Current date is OCM qualifying day
|
||||
else
|
||||
{
|
||||
// Set OCM Main draw value to false
|
||||
saveExGhostHistory.ocmMainDraw = false
|
||||
|
||||
// Get the user's available OCM Battle Record data
|
||||
countGBR = await prisma.oCMGhostBattleRecord.findFirst({
|
||||
where:{
|
||||
carId: saveExGhostHistory.carId,
|
||||
ocmMainDraw: saveExGhostHistory.ocmMainDraw,
|
||||
area: saveExGhostHistory.area,
|
||||
competitionId: ocmEventDate!.competitionId,
|
||||
periodId: 0
|
||||
}
|
||||
});
|
||||
}
|
||||
// ----------------------------------------------------------------
|
||||
|
||||
// User have OCM Battle Record data available
|
||||
if(countGBR)
|
||||
{
|
||||
// Check if the newest advantage distance is bigger than the older advantage distance
|
||||
if(countGBR!.result < saveExGhostHistory.result)
|
||||
{
|
||||
console.log('OCM Ghost Tally found');
|
||||
|
||||
// Current date is OCM Main Draw
|
||||
if(ocmEventDate!.competitionStartAt < date && ocmEventDate!.competitionCloseAt > date)
|
||||
{
|
||||
// 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 equal current date
|
||||
},
|
||||
closeAt:
|
||||
{
|
||||
gte: date, // competitionCloseAt is greater than equal current date
|
||||
}
|
||||
},
|
||||
select:{
|
||||
periodId: true
|
||||
}
|
||||
});
|
||||
|
||||
let checkGhost = await prisma.oCMGhostBattleRecord.findFirst({
|
||||
where:{
|
||||
carId: saveExGhostHistory.carId,
|
||||
competitionId: ocmEventDate!.competitionId,
|
||||
}
|
||||
});
|
||||
|
||||
if(checkGhost)
|
||||
{
|
||||
console.log('Updating OCM Ghost Battle Record entry');
|
||||
|
||||
// Get the user's available OCM Battle Record data
|
||||
let getGBR = await prisma.oCMGhostBattleRecord.findFirst({
|
||||
where:{
|
||||
carId: saveExGhostHistory.carId,
|
||||
area: saveExGhostHistory.area,
|
||||
competitionId: ocmEventDate!.competitionId,
|
||||
}
|
||||
});
|
||||
|
||||
// Update ghost battle record
|
||||
await prisma.oCMGhostBattleRecord.update({
|
||||
where:{
|
||||
dbId: getGBR!.dbId
|
||||
},
|
||||
data: {
|
||||
...saveExGhostHistory,
|
||||
competitionId: ocmEventDate!.competitionId,
|
||||
periodId: OCM_periodId!.periodId
|
||||
}
|
||||
});
|
||||
}
|
||||
else
|
||||
{
|
||||
console.log('Creating new OCM Ghost Battle Record entry');
|
||||
|
||||
// Create new ghost battle record
|
||||
await prisma.oCMGhostBattleRecord.create({
|
||||
data: {
|
||||
...saveExGhostHistory,
|
||||
competitionId: ocmEventDate!.competitionId,
|
||||
periodId: OCM_periodId!.periodId
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
console.log('Updating OCM Tally Record');
|
||||
|
||||
// Update the OCM Tally Record
|
||||
await prisma.oCMTally.update({
|
||||
where:{
|
||||
dbId: countGBR.dbId
|
||||
},
|
||||
data: {
|
||||
periodId: OCM_periodId!.periodId,
|
||||
result: body.rgResult!.opponents![0].result,
|
||||
tunePower: body.car?.tunePower!,
|
||||
tuneHandling: body.car?.tuneHandling!
|
||||
}
|
||||
});
|
||||
}
|
||||
// Current date is OCM Qualifying
|
||||
else
|
||||
{
|
||||
// Update ghost battle record
|
||||
await prisma.oCMGhostBattleRecord.update({
|
||||
where:{
|
||||
dbId: countGBR.dbId
|
||||
},
|
||||
data: {
|
||||
...saveExGhostHistory,
|
||||
competitionId: ocmEventDate!.competitionId,
|
||||
periodId: 0
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
// Newest advantage distance is smaller than the older advantage distance
|
||||
else
|
||||
{
|
||||
console.log('Result record is lower than previous record');
|
||||
|
||||
// Don't update the User's OCM ghost trail
|
||||
updateNewTrail = false;
|
||||
}
|
||||
}
|
||||
// User don't have OCM Battle Record data available
|
||||
else
|
||||
{
|
||||
console.log('OCM Ghost Battle Record not found');
|
||||
console.log('Creating new OOCM Ghost Battle Record entry');
|
||||
|
||||
// Current date is OCM Main Draw
|
||||
if(ocmEventDate!.competitionStartAt < date && ocmEventDate!.competitionCloseAt > date)
|
||||
{
|
||||
// Get OCM Period ID
|
||||
let OCM_periodId = await prisma.oCMPeriod.findFirst({
|
||||
where:{
|
||||
competitionDbId: ocmEventDate!.dbId,
|
||||
competitionId: ocmEventDate!.competitionId
|
||||
},
|
||||
orderBy:{
|
||||
periodId: 'desc'
|
||||
},
|
||||
select:{
|
||||
periodId: true
|
||||
}
|
||||
});
|
||||
|
||||
// Update ghost battle record
|
||||
await prisma.oCMGhostBattleRecord.create({
|
||||
data: {
|
||||
...saveExGhostHistory,
|
||||
competitionId: ocmEventDate!.competitionId,
|
||||
periodId: OCM_periodId!.periodId
|
||||
}
|
||||
});
|
||||
|
||||
let ocmTallyfind = await prisma.oCMTally.findFirst({
|
||||
where:{
|
||||
carId: saveExGhostHistory.carId,
|
||||
competitionId: ocmEventDate!.competitionId,
|
||||
},
|
||||
});
|
||||
|
||||
if(ocmTallyfind)
|
||||
{
|
||||
console.log('Updating OCM Tally Record');
|
||||
|
||||
// Update the OCM Tally Record
|
||||
await prisma.oCMTally.update({
|
||||
where:{
|
||||
dbId: ocmTallyfind.dbId
|
||||
},
|
||||
data: {
|
||||
periodId: OCM_periodId!.periodId,
|
||||
result: body.rgResult!.opponents![0].result,
|
||||
tunePower: body.car?.tunePower!,
|
||||
tuneHandling: body.car?.tuneHandling!
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
// Current date is OCM Qualifying
|
||||
else
|
||||
{
|
||||
// Update ghost battle record
|
||||
await prisma.oCMGhostBattleRecord.create({
|
||||
data: {
|
||||
...saveExGhostHistory,
|
||||
competitionId: ocmEventDate!.competitionId,
|
||||
periodId: 0
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// Return the value to 'BASE_PATH/src/util/games/ghost.ts'
|
||||
return { updateNewTrail }
|
||||
}
|
||||
|
||||
|
||||
// Save VSORG ghost history battle
|
||||
export async function saveVSORGGhostHistory(body: wm.protobuf.SaveGameResultRequest)
|
||||
{
|
||||
console.log('Saving VSORG Ghost Battle History');
|
||||
|
||||
// Get the ghost expedition result for the car
|
||||
let expeditionResult = body.rgResult?.expeditionResult;
|
||||
|
||||
// Get current date
|
||||
let date = Math.floor(new Date().getTime() / 1000);
|
||||
|
||||
// expeditionResult is set
|
||||
if (expeditionResult)
|
||||
{
|
||||
// Expedition update data
|
||||
let dataExpedition = {
|
||||
ghostExpeditionId: common.sanitizeInput(expeditionResult.ghostExpeditionId),
|
||||
sugorokuPoint: common.sanitizeInput(expeditionResult.sugorokuPoint),
|
||||
earnedScore: common.sanitizeInput(expeditionResult.earnedScore),
|
||||
score: common.sanitizeInput(expeditionResult.score),
|
||||
}
|
||||
|
||||
let checkExpeditionData = await prisma.ghostExpedition.findFirst({
|
||||
where:{
|
||||
carId: body.carId
|
||||
}
|
||||
});
|
||||
|
||||
// Update the expedition data
|
||||
if(checkExpeditionData)
|
||||
{
|
||||
await prisma.ghostExpedition.update({
|
||||
where:{
|
||||
dbId: checkExpeditionData.dbId
|
||||
},
|
||||
data: {
|
||||
...dataExpedition
|
||||
}
|
||||
});
|
||||
}
|
||||
// Create the expedition data
|
||||
else
|
||||
{
|
||||
await prisma.ghostExpedition.create({
|
||||
data: {
|
||||
carId: body.carId,
|
||||
...dataExpedition
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
if(expeditionResult.earnedItems!.length !== 0)
|
||||
{
|
||||
console.log('User Item reward from VSORG available, continuing ...');
|
||||
|
||||
// Get current date
|
||||
let date = Math.floor(new Date().getTime() / 1000);
|
||||
|
||||
for(let i=0; i<expeditionResult.earnedItems!.length; i++)
|
||||
{
|
||||
await prisma.userItem.create({
|
||||
data: {
|
||||
category: expeditionResult.earnedItems![i].category,
|
||||
itemId: expeditionResult.earnedItems![i].itemId,
|
||||
userId: body.car!.userId!,
|
||||
earnedAt: date,
|
||||
type: 0
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
if(expeditionResult.aftereventBonus!.length !== 0)
|
||||
{
|
||||
console.log('User Item after event reward from VSORG available, continuing ...');
|
||||
|
||||
// Get current date
|
||||
let date = Math.floor(new Date().getTime() / 1000);
|
||||
|
||||
for(let i=0; i<expeditionResult.aftereventBonus!.length; i++)
|
||||
{
|
||||
/*
|
||||
await prisma.userItem.create({
|
||||
data: {
|
||||
category: expeditionResult.earnedItems![i].category,
|
||||
itemId: expeditionResult.earnedItems![i].itemId,
|
||||
userId: body.car!.userId!,
|
||||
earnedAt: date,
|
||||
type: 0
|
||||
}
|
||||
});*/
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
let updateNewTrail: boolean = true;
|
||||
let saveExGhostHistory: any = {};
|
||||
|
||||
// Get the car result for the car
|
||||
let car = body?.car;
|
||||
|
||||
if(car)
|
||||
{
|
||||
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 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;
|
||||
}
|
||||
|
||||
// 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
|
||||
});
|
||||
|
||||
let getArea = await ghost_get_area_from_path.getArea(rgResult!.path);
|
||||
|
||||
// Check if defeating Wanted car
|
||||
let checkWantedCar = await prisma.ghostExpeditionWantedCar.findFirst({
|
||||
where:{
|
||||
carId: rgResult!.opponents![0].carId,
|
||||
area: getArea.area
|
||||
}
|
||||
})
|
||||
|
||||
// Wanted car available
|
||||
if(checkWantedCar)
|
||||
{
|
||||
if(rgResult!.opponents![0].result > 0)
|
||||
{
|
||||
console.log('Wanted Car Defeated');
|
||||
|
||||
await prisma.ghostExpeditionWantedCar.delete({
|
||||
where:{
|
||||
dbId: checkWantedCar.dbId
|
||||
}
|
||||
})
|
||||
}
|
||||
else
|
||||
{
|
||||
console.log('Lose from Wanted Car');
|
||||
|
||||
// Making wanted car
|
||||
let dataWantedGhost = {
|
||||
carId: common.sanitizeInput(rgResult!.opponents![0].carId),
|
||||
bonus: checkWantedCar.bonus + 1,
|
||||
defeatedMeCount: checkWantedCar.defeatedMeCount + 1
|
||||
}
|
||||
|
||||
await prisma.ghostExpeditionWantedCar.update({
|
||||
where:{
|
||||
dbId: checkWantedCar.dbId
|
||||
},
|
||||
data: dataWantedGhost
|
||||
})
|
||||
}
|
||||
}
|
||||
// If lose the race maybe
|
||||
else
|
||||
{
|
||||
if(rgResult!.opponents![0].result < 0)
|
||||
{
|
||||
// Making wanted car
|
||||
let dataWantedGhost = {
|
||||
carId: common.sanitizeInput(rgResult!.opponents![0].carId),
|
||||
bonus: 0,
|
||||
numOfHostages: 1,
|
||||
defeatedMeCount: 1,
|
||||
area: getArea.area
|
||||
}
|
||||
|
||||
console.log('Creating Wanted Car');
|
||||
|
||||
await prisma.ghostExpeditionWantedCar.create({
|
||||
data: dataWantedGhost
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// Check full tune ticket piece
|
||||
let checkFTTicketPiece = await prisma.userItem.findMany({
|
||||
where:{
|
||||
userId: body.car!.userId!,
|
||||
category: 202,
|
||||
itemId: 2
|
||||
}
|
||||
});
|
||||
|
||||
if(checkFTTicketPiece.length >= 6)
|
||||
{
|
||||
// Give full tune ticket :)
|
||||
await prisma.userItem.create({
|
||||
data:{
|
||||
userId: body.car!.userId!,
|
||||
category: 203,
|
||||
itemId: 5,
|
||||
type: 0,
|
||||
earnedAt: date
|
||||
}
|
||||
});
|
||||
|
||||
// Remove full tune ticket piece :(
|
||||
await prisma.userItem.deleteMany({
|
||||
where:{
|
||||
userId: body.car!.userId!,
|
||||
category: 202,
|
||||
itemId: 2,
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// Sending stamp to opponents
|
||||
await ghost_stamp.sendStamp(body);
|
||||
|
||||
// Return the value to 'BASE_PATH/src/util/games/ghost.ts'
|
||||
return { updateNewTrail }
|
||||
}
|
||||
|
||||
|
||||
// Save VSORG ghost history battle but retiring
|
||||
export async function saveVSORGGhostRetireHistory(body: wm.protobuf.SaveGameResultRequest)
|
||||
{
|
||||
console.log('Saving VSORG Retiring Ghost Battle History');
|
||||
|
||||
// Get the ghost result for the car
|
||||
let ghostResult = body?.rgResult;
|
||||
|
||||
// Get current date
|
||||
let date = Math.floor(new Date().getTime() / 1000);
|
||||
|
||||
// ghostResult is set
|
||||
let dataGhost: any;
|
||||
if (ghostResult)
|
||||
{
|
||||
dataGhost = {
|
||||
rgPlayCount: common.sanitizeInput(ghostResult.rgPlayCount),
|
||||
}
|
||||
|
||||
// Update the car properties
|
||||
await prisma.car.update({
|
||||
where: {
|
||||
carId: body.carId
|
||||
},
|
||||
data: {
|
||||
...dataGhost
|
||||
}
|
||||
});
|
||||
|
||||
let getArea = await ghost_get_area_from_path.getArea(ghostResult.path);
|
||||
|
||||
// Making wanted car
|
||||
let dataWantedGhost = {
|
||||
carId: common.sanitizeInput(ghostResult.opponents![0].carId),
|
||||
bonus: 0,
|
||||
numOfHostages: 1,
|
||||
defeatedMeCount: 1,
|
||||
area: getArea.area
|
||||
}
|
||||
|
||||
let checkWantedCar = await prisma.ghostExpeditionWantedCar.findFirst({
|
||||
where:{
|
||||
carId: dataWantedGhost.carId
|
||||
}
|
||||
})
|
||||
|
||||
if(checkWantedCar)
|
||||
{
|
||||
console.log('Updating Wanted Car');
|
||||
|
||||
dataWantedGhost.bonus = checkWantedCar.bonus + 1;
|
||||
dataWantedGhost.defeatedMeCount = checkWantedCar.defeatedMeCount + 1;
|
||||
|
||||
await prisma.ghostExpeditionWantedCar.update({
|
||||
where:{
|
||||
dbId: checkWantedCar.dbId
|
||||
},
|
||||
data: dataWantedGhost
|
||||
})
|
||||
}
|
||||
else
|
||||
{
|
||||
console.log('Creating Wanted Car');
|
||||
|
||||
await prisma.ghostExpeditionWantedCar.create({
|
||||
data: dataWantedGhost
|
||||
})
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// Get the ghost expedition result for the car
|
||||
let expeditionResult = body.rgResult?.expeditionResult;
|
||||
|
||||
// expeditionResult is set
|
||||
if (expeditionResult)
|
||||
{
|
||||
// Expedition update data
|
||||
let dataExpedition = {
|
||||
ghostExpeditionId: common.sanitizeInput(expeditionResult.ghostExpeditionId),
|
||||
sugorokuPoint: common.sanitizeInput(expeditionResult.sugorokuPoint),
|
||||
earnedScore: common.sanitizeInput(expeditionResult.earnedScore),
|
||||
score: common.sanitizeInput(expeditionResult.score),
|
||||
}
|
||||
|
||||
let checkExpeditionData = await prisma.ghostExpedition.findFirst({
|
||||
where:{
|
||||
carId: body.carId
|
||||
}
|
||||
});
|
||||
|
||||
// Update the expedition data
|
||||
if(checkExpeditionData)
|
||||
{
|
||||
await prisma.ghostExpedition.update({
|
||||
where:{
|
||||
dbId: checkExpeditionData.dbId
|
||||
},
|
||||
data: {
|
||||
...dataExpedition
|
||||
}
|
||||
});
|
||||
}
|
||||
// Create the expedition data
|
||||
else
|
||||
{
|
||||
await prisma.ghostExpedition.create({
|
||||
data: {
|
||||
carId: body.carId,
|
||||
...dataExpedition
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
if(expeditionResult.earnedItems!.length !== 0)
|
||||
{
|
||||
console.log('User Item reward from VSORG available, continuing ...');
|
||||
|
||||
for(let i=0; i<expeditionResult.earnedItems!.length; i++)
|
||||
{
|
||||
await prisma.userItem.create({
|
||||
data: {
|
||||
category: expeditionResult.earnedItems![i].category,
|
||||
itemId: expeditionResult.earnedItems![i].itemId,
|
||||
userId: body.car!.userId!,
|
||||
earnedAt: date,
|
||||
type: 0
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
if(expeditionResult.aftereventBonus!.length !== 0)
|
||||
{
|
||||
console.log('User Item after event reward from VSORG available, continuing ...');
|
||||
|
||||
for(let i=0; i<expeditionResult.aftereventBonus!.length; i++)
|
||||
{
|
||||
/*
|
||||
await prisma.userItem.create({
|
||||
data: {
|
||||
category: expeditionResult.earnedItems![i].category,
|
||||
itemId: expeditionResult.earnedItems![i].itemId,
|
||||
userId: body.car!.userId!,
|
||||
earnedAt: date,
|
||||
type: 0
|
||||
}
|
||||
});*/
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Check full tune ticket piece
|
||||
let checkFTTicketPiece = await prisma.userItem.findMany({
|
||||
where:{
|
||||
userId: body.car!.userId!,
|
||||
category: 202,
|
||||
itemId: 2
|
||||
}
|
||||
});
|
||||
|
||||
if(checkFTTicketPiece.length >= 6)
|
||||
{
|
||||
// Give full tune ticket :)
|
||||
await prisma.userItem.create({
|
||||
data:{
|
||||
userId: body.car!.userId!,
|
||||
category: 203,
|
||||
itemId: 5,
|
||||
type: 0,
|
||||
earnedAt: date
|
||||
}
|
||||
});
|
||||
|
||||
// Remove full tune ticket piece :(
|
||||
await prisma.userItem.deleteMany({
|
||||
where:{
|
||||
userId: body.car!.userId!,
|
||||
category: 202,
|
||||
itemId: 2,
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
@ -381,8 +381,7 @@ export async function ocmTallying(body: wm.protobuf.LoadGhostCompetitionInfoRequ
|
||||
}
|
||||
|
||||
|
||||
if(i === 0)
|
||||
{
|
||||
if(i === 0){
|
||||
console.log('Making OCM Top 1 Ghost Data');
|
||||
|
||||
// Create Top 1 ghost data
|
||||
@ -588,10 +587,10 @@ export async function ocmGiveNamePlateReward(competitionId: number)
|
||||
|
||||
let participantLength = getCarParticipant.length;
|
||||
|
||||
// Participant is more than certain number (100 is default)
|
||||
if(participantLength > 25)
|
||||
// Participant is more than 100
|
||||
if(participantLength > 100)
|
||||
{
|
||||
participantLength = 25;
|
||||
participantLength = 100
|
||||
}
|
||||
|
||||
// 16th - C1
|
||||
@ -739,37 +738,8 @@ export async function ocmGiveNamePlateReward(competitionId: number)
|
||||
})
|
||||
}
|
||||
}
|
||||
// 20th - Kobe
|
||||
else if(competitionId === 6)
|
||||
{
|
||||
// Participation Award (Gemstone)
|
||||
for(let i=0; i<getCarParticipant.length; i++)
|
||||
{
|
||||
await prisma.carItem.create({
|
||||
data:{
|
||||
carId: getCarParticipant[i].carId,
|
||||
category: 17,
|
||||
itemId: 228,
|
||||
amount: 1
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// Ranking within the top 100 (Minotaur GP)
|
||||
for(let i=0; i<participantLength; i++)
|
||||
{
|
||||
await prisma.carItem.create({
|
||||
data:{
|
||||
carId: getCarParticipant[i].carId,
|
||||
category: 17,
|
||||
itemId: 229,
|
||||
amount: 1
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
// 7th - Fukutoshin
|
||||
else if(competitionId === 7)
|
||||
else if(competitionId === 6)
|
||||
{
|
||||
// Participation Award (Koi)
|
||||
for(let i=0; i<getCarParticipant.length; i++)
|
||||
@ -797,37 +767,8 @@ export async function ocmGiveNamePlateReward(competitionId: number)
|
||||
})
|
||||
}
|
||||
}
|
||||
// 21st - Hiroshima
|
||||
else if(competitionId === 8)
|
||||
{
|
||||
// Participation Award (Ukiyo-e)
|
||||
for(let i=0; i<getCarParticipant.length; i++)
|
||||
{
|
||||
await prisma.carItem.create({
|
||||
data:{
|
||||
carId: getCarParticipant[i].carId,
|
||||
category: 17,
|
||||
itemId: 234,
|
||||
amount: 1
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// Ranking within the top 100 (Cerberus GP)
|
||||
for(let i=0; i<participantLength; i++)
|
||||
{
|
||||
await prisma.carItem.create({
|
||||
data:{
|
||||
carId: getCarParticipant[i].carId,
|
||||
category: 17,
|
||||
itemId: 235,
|
||||
amount: 1
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
// 8th - Hakone
|
||||
else if(competitionId === 9)
|
||||
else if(competitionId === 7)
|
||||
{
|
||||
// Participation Award (Studs)
|
||||
for(let i=0; i<getCarParticipant.length; i++)
|
||||
@ -855,6 +796,64 @@ export async function ocmGiveNamePlateReward(competitionId: number)
|
||||
})
|
||||
}
|
||||
}
|
||||
// 20th - Kobe
|
||||
else if(competitionId === 8)
|
||||
{
|
||||
// Participation Award (Gemstone)
|
||||
for(let i=0; i<getCarParticipant.length; i++)
|
||||
{
|
||||
await prisma.carItem.create({
|
||||
data:{
|
||||
carId: getCarParticipant[i].carId,
|
||||
category: 17,
|
||||
itemId: 228,
|
||||
amount: 1
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// Ranking within the top 100 (Minotaur GP)
|
||||
for(let i=0; i<participantLength; i++)
|
||||
{
|
||||
await prisma.carItem.create({
|
||||
data:{
|
||||
carId: getCarParticipant[i].carId,
|
||||
category: 17,
|
||||
itemId: 229,
|
||||
amount: 1
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
// 21st - Hiroshima
|
||||
else if(competitionId === 9)
|
||||
{
|
||||
// Participation Award (Ukiyo-e)
|
||||
for(let i=0; i<getCarParticipant.length; i++)
|
||||
{
|
||||
await prisma.carItem.create({
|
||||
data:{
|
||||
carId: getCarParticipant[i].carId,
|
||||
category: 17,
|
||||
itemId: 234,
|
||||
amount: 1
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// Ranking within the top 100 (Cerberus GP)
|
||||
for(let i=0; i<participantLength; i++)
|
||||
{
|
||||
await prisma.carItem.create({
|
||||
data:{
|
||||
carId: getCarParticipant[i].carId,
|
||||
category: 17,
|
||||
itemId: 235,
|
||||
amount: 1
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
// 1st - C1
|
||||
else if(competitionId === 10)
|
||||
{
|
@ -5,7 +5,7 @@ export async function OCMArea(competition_id: number)
|
||||
let rampVal = 0;
|
||||
let pathVal = 0;
|
||||
|
||||
// 16th - C1 Outbound
|
||||
// 16th - C1
|
||||
if(competition_id === 1)
|
||||
{
|
||||
// GID_RUNAREA_C1
|
||||
@ -53,7 +53,7 @@ export async function OCMArea(competition_id: number)
|
||||
// GID_PATH_NGR_MARUNOUCHI
|
||||
pathVal = 49;
|
||||
}
|
||||
// 6th - C1 Inbound
|
||||
// 6th - C1
|
||||
else if(competition_id === 5)
|
||||
{
|
||||
// GID_RUNAREA_C1
|
||||
@ -65,20 +65,8 @@ export async function OCMArea(competition_id: number)
|
||||
// GID_PATH_C1IN_KANDABASHI02
|
||||
pathVal = 1;
|
||||
}
|
||||
// 20th - Kobe
|
||||
else if(competition_id === 6)
|
||||
{
|
||||
// GID_RUNAREA_KOBE
|
||||
areaVal = 10;
|
||||
|
||||
// GID_RAMP_KOBE_NADAOOHASHI
|
||||
rampVal = 28;
|
||||
|
||||
// GID_PATH_KB_NADA
|
||||
pathVal = 55;
|
||||
}
|
||||
// 7th - Fukutoshin
|
||||
else if(competition_id === 7)
|
||||
else if(competition_id === 6)
|
||||
{
|
||||
// GID_RUNAREA_SUBTOKYO_3_4
|
||||
areaVal = 2;
|
||||
@ -89,20 +77,8 @@ export async function OCMArea(competition_id: number)
|
||||
// GID_PATH_WTWEST_GAIEN
|
||||
pathVal = 17;
|
||||
}
|
||||
// 21st - Hiroshima
|
||||
else if(competition_id === 8)
|
||||
{
|
||||
// GID_RUNAREA_HIROSHIMA
|
||||
areaVal = 18;
|
||||
|
||||
// GID_RAMP_HIROSHIMA_SHINONOME
|
||||
rampVal = 37;
|
||||
|
||||
// GID_PATH_HS_SHINONOME
|
||||
pathVal = 56;
|
||||
}
|
||||
// 8th - Hakone
|
||||
else if(competition_id === 9)
|
||||
else if(competition_id === 7)
|
||||
{
|
||||
// GID_RUNAREA_HAKONE
|
||||
areaVal = 12;
|
||||
@ -113,6 +89,30 @@ export async function OCMArea(competition_id: number)
|
||||
// GID_PATH_HKFOR
|
||||
pathVal = 62;
|
||||
}
|
||||
// 20th - Kobe
|
||||
else if(competition_id === 8)
|
||||
{
|
||||
// GID_RUNAREA_KOBE
|
||||
areaVal = 10;
|
||||
|
||||
// GID_RAMP_KOBE_NADAOOHASHI
|
||||
rampVal = 28;
|
||||
|
||||
// GID_PATH_KB_NADA
|
||||
pathVal = 55;
|
||||
}
|
||||
// 21st - Hiroshima
|
||||
else if(competition_id === 9)
|
||||
{
|
||||
// GID_RUNAREA_HIROSHIMA
|
||||
areaVal = 18;
|
||||
|
||||
// GID_RAMP_HIROSHIMA_SHINONOME
|
||||
rampVal = 37;
|
||||
|
||||
// GID_PATH_HS_SHINONOME
|
||||
pathVal = 56;
|
||||
}
|
||||
// 1st - C1 Outbound
|
||||
else if(competition_id === 10)
|
||||
{
|
@ -4,7 +4,7 @@ import { prisma } from "../..";
|
||||
import { wm } from "../../wmmt/wm.proto";
|
||||
|
||||
// Import Util
|
||||
import * as ghost_get_area_from_path from "./ghost_util/ghost_get_area_from_path";
|
||||
import * as ghost_get_area_from_path from "../ghost/ghost_util/ghost_get_area_from_path";
|
||||
|
||||
|
||||
export async function sendStamp(body: wm.protobuf.SaveGameResultRequest)
|
@ -1,4 +1,4 @@
|
||||
import { prisma } from "../../..";
|
||||
import { prisma } from "../..";
|
||||
|
||||
// Import Proto
|
||||
import * as ghost_ocm_area from "./ghost_ocm_area";
|
@ -1,8 +1,8 @@
|
||||
import { prisma } from "../..";
|
||||
import { Config } from "../../config";
|
||||
import { prisma } from "..";
|
||||
import { Config } from "../config";
|
||||
|
||||
//Import Proto
|
||||
import * as wm from "../../wmmt/wm.proto";
|
||||
import * as wm from "../wmmt/wm.proto";
|
||||
|
||||
// *** CONSTANTS ***
|
||||
|
@ -1,6 +1,5 @@
|
||||
import { prisma } from "../..";
|
||||
|
||||
|
||||
// Sends the server response to the client
|
||||
export async function checkScratchCar(userId: number, visualModel: number)
|
||||
{
|
3310
src/wmmt/message.proto.d.ts
vendored
3310
src/wmmt/message.proto.d.ts
vendored
File diff suppressed because it is too large
Load Diff
9629
src/wmmt/message.proto.js
vendored
9629
src/wmmt/message.proto.js
vendored
File diff suppressed because it is too large
Load Diff
4096
src/wmmt/service.proto.d.ts
vendored
4096
src/wmmt/service.proto.d.ts
vendored
File diff suppressed because it is too large
Load Diff
11217
src/wmmt/service.proto.js
vendored
11217
src/wmmt/service.proto.js
vendored
File diff suppressed because it is too large
Load Diff
3181
src/wmmt/system.proto.d.ts
vendored
3181
src/wmmt/system.proto.d.ts
vendored
File diff suppressed because it is too large
Load Diff
9270
src/wmmt/system.proto.js
vendored
9270
src/wmmt/system.proto.js
vendored
File diff suppressed because it is too large
Load Diff
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user