mirror of
https://github.com/shiroikitsu8/Bayshore_6r_legacy.git
synced 2025-01-19 17:08:44 +01:00
commit
a2460fcb5d
@ -4,6 +4,8 @@
|
||||
"regionName": "Bayshore",
|
||||
"serverIp": "127.0.0.1",
|
||||
"gameOptions": {
|
||||
"grantFullTuneTicketToNewUsers": 0
|
||||
"grantFullTuneTicketToNewUsers": 0,
|
||||
"grantAllScratchRewards": 0,
|
||||
"grantBonusScratchCars": 0
|
||||
}
|
||||
}
|
@ -2,158 +2,182 @@
|
||||
// learn more about it in the docs: https://pris.ly/d/prisma-schema
|
||||
|
||||
generator client {
|
||||
provider = "prisma-client-js"
|
||||
provider = "prisma-client-js"
|
||||
}
|
||||
|
||||
datasource db {
|
||||
provider = "postgresql"
|
||||
url = env("POSTGRES_URL")
|
||||
provider = "postgresql"
|
||||
url = env("POSTGRES_URL")
|
||||
}
|
||||
|
||||
model User {
|
||||
id Int @id @default(autoincrement())
|
||||
chipId String @unique
|
||||
accessCode String
|
||||
cars Car[]
|
||||
unusedTickets UserItem[]
|
||||
tutorials Boolean[]
|
||||
userBanned Boolean @default(false)
|
||||
id Int @id @default(autoincrement())
|
||||
chipId String @unique
|
||||
accessCode String
|
||||
cars Car[]
|
||||
carOrder Int[] // Order of cars
|
||||
unusedTickets UserItem[]
|
||||
tutorials Boolean[]
|
||||
userBanned Boolean @default(false)
|
||||
bookmarks Int[]
|
||||
// ScratchSheet ScratchSheet[]
|
||||
currentSheet Int @default(0)
|
||||
lastSheet Int @default(0)
|
||||
}
|
||||
|
||||
// Not working yet, removing from schema
|
||||
// model ScratchSheet {
|
||||
// id Int @id @default(autoincrement())
|
||||
// User User @relation(fields: [userId], references: [id])
|
||||
// userId Int @unique
|
||||
// squares ScratchSquare[]
|
||||
// }
|
||||
|
||||
// model ScratchSquare {
|
||||
// id Int @id @default(autoincrement())
|
||||
// Sheet ScratchSheet @relation(fields: [sheetId], references: [id])
|
||||
// sheetId Int
|
||||
// category Int
|
||||
// itemId Int
|
||||
// earned Boolean
|
||||
// }
|
||||
|
||||
model UserItem {
|
||||
dbId Int @id @default(autoincrement())
|
||||
category Int
|
||||
itemId Int
|
||||
User User @relation(fields: [userId], references: [id])
|
||||
userId Int
|
||||
dbId Int @id @default(autoincrement())
|
||||
category Int
|
||||
itemId Int
|
||||
User User @relation(fields: [userId], references: [id])
|
||||
userId Int
|
||||
}
|
||||
|
||||
model Car {
|
||||
user User @relation(fields: [userId], references: [id])
|
||||
userId Int
|
||||
user User @relation(fields: [userId], references: [id])
|
||||
userId Int
|
||||
|
||||
// This is the Car object itself
|
||||
carId Int @id @default(autoincrement())
|
||||
name String
|
||||
manufacturer Int
|
||||
regionId Int @default(0)
|
||||
model Int
|
||||
visualModel Int
|
||||
customColor Int @default(0)
|
||||
defaultColor Int
|
||||
wheel Int @default(0)
|
||||
wheelColor Int @default(0)
|
||||
aero Int @default(0)
|
||||
bonnet Int @default(0)
|
||||
wing Int @default(0)
|
||||
mirror Int @default(0)
|
||||
neon Int @default(0)
|
||||
trunk Int @default(0)
|
||||
plate Int @default(0)
|
||||
plateColor Int @default(0)
|
||||
plateNumber Int @default(0)
|
||||
tunePower Int @default(0)
|
||||
tuneHandling Int @default(0)
|
||||
title String @default("New Car")
|
||||
level Int @default(0)
|
||||
windowSticker Boolean @default(false)
|
||||
windowStickerString String @default("WANGAN")
|
||||
windowStickerFont Int @default(0)
|
||||
rivalMarker Int @default(0)
|
||||
aura Int @default(0)
|
||||
auraMotif Int @default(0)
|
||||
ghostLevel Int @default(1)
|
||||
// This is the Car object itself
|
||||
carId Int @id @default(autoincrement())
|
||||
name String
|
||||
manufacturer Int
|
||||
regionId Int @default(0)
|
||||
model Int
|
||||
visualModel Int
|
||||
customColor Int @default(0)
|
||||
defaultColor Int
|
||||
wheel Int @default(0)
|
||||
wheelColor Int @default(0)
|
||||
aero Int @default(0)
|
||||
bonnet Int @default(0)
|
||||
wing Int @default(0)
|
||||
mirror Int @default(0)
|
||||
neon Int @default(0)
|
||||
trunk Int @default(0)
|
||||
plate Int @default(0)
|
||||
plateColor Int @default(0)
|
||||
plateNumber Int @default(0)
|
||||
tunePower Int @default(0)
|
||||
tuneHandling Int @default(0)
|
||||
title String @default("New Car")
|
||||
level Int @default(0)
|
||||
windowSticker Boolean @default(false)
|
||||
windowStickerString String @default("WANGAN")
|
||||
windowStickerFont Int @default(0)
|
||||
rivalMarker Int @default(0)
|
||||
aura Int @default(0)
|
||||
auraMotif Int @default(0)
|
||||
ghostLevel Int @default(1)
|
||||
|
||||
// This is more data about the car
|
||||
tuningPoints Int @default(0)
|
||||
odometer Int @default(0)
|
||||
playCount Int @default(0)
|
||||
earnedCustomColor Boolean @default(false)
|
||||
carSettingsDbId Int @unique
|
||||
settings CarSettings @relation(fields: [carSettingsDbId], references: [dbId])
|
||||
vsPlayCount Int @default(0)
|
||||
vsBurstCount Int @default(0)
|
||||
vsStarCount Int @default(0)
|
||||
vsCoolOrWild Int @default(0)
|
||||
vsSmoothOrRough Int @default(0)
|
||||
vsTripleStarMedals Int @default(0)
|
||||
vsDoubleStarMedals Int @default(0)
|
||||
vsSingleStarMedals Int @default(0)
|
||||
vsPlainMedals Int @default(0)
|
||||
rgPlayCount Int @default(0)
|
||||
rgWinCount Int @default(0)
|
||||
rgTrophy Int @default(0)
|
||||
rgScore Int @default(0)
|
||||
rgStamp Int @default(0)
|
||||
rgAcquireAllCrowns Boolean @default(false)
|
||||
dressupLevel Int @default(0)
|
||||
dressupPoint Int @default(0)
|
||||
stPlayCount Int @default(0)
|
||||
stClearBits Int @default(0)
|
||||
stClearDivCount Int @default(0)
|
||||
stClearCount Int @default(0)
|
||||
stLoseBits BigInt @default(0)
|
||||
stConsecutiveWins Int @default(0)
|
||||
stConsecutiveWinsMax Int @default(0)
|
||||
stCompleted100Episodes Boolean @default(false)
|
||||
// This is more data about the car
|
||||
tuningPoints Int @default(0)
|
||||
odometer Int @default(0)
|
||||
playCount Int @default(0)
|
||||
earnedCustomColor Boolean @default(false)
|
||||
carSettingsDbId Int @unique
|
||||
settings CarSettings @relation(fields: [carSettingsDbId], references: [dbId])
|
||||
vsPlayCount Int @default(0)
|
||||
vsBurstCount Int @default(0)
|
||||
vsStarCount Int @default(0)
|
||||
vsCoolOrWild Int @default(0)
|
||||
vsSmoothOrRough Int @default(0)
|
||||
vsTripleStarMedals Int @default(0)
|
||||
vsDoubleStarMedals Int @default(0)
|
||||
vsSingleStarMedals Int @default(0)
|
||||
vsPlainMedals Int @default(0)
|
||||
rgPlayCount Int @default(0)
|
||||
rgWinCount Int @default(0)
|
||||
rgTrophy Int @default(0)
|
||||
rgScore Int @default(0)
|
||||
rgStamp Int @default(0)
|
||||
rgAcquireAllCrowns Boolean @default(false)
|
||||
dressupLevel Int @default(0)
|
||||
dressupPoint Int @default(0)
|
||||
stPlayCount Int @default(0)
|
||||
stClearBits Int @default(0)
|
||||
stClearDivCount Int @default(0)
|
||||
stClearCount Int @default(0)
|
||||
stLoseBits BigInt @default(0)
|
||||
stConsecutiveWins Int @default(0)
|
||||
stConsecutiveWinsMax Int @default(0)
|
||||
stCompleted100Episodes Boolean @default(false)
|
||||
|
||||
items CarItem[]
|
||||
items CarItem[]
|
||||
|
||||
carStateDbId Int @unique
|
||||
state CarState @relation(fields: [carStateDbId], references: [dbId])
|
||||
TimeAttackRecord TimeAttackRecord[]
|
||||
carStateDbId Int @unique
|
||||
state CarState @relation(fields: [carStateDbId], references: [dbId])
|
||||
TimeAttackRecord TimeAttackRecord[]
|
||||
}
|
||||
|
||||
model CarItem {
|
||||
Car Car? @relation(fields: [carId], references: [carId])
|
||||
dbId Int @id @default(autoincrement())
|
||||
carId Int
|
||||
category Int
|
||||
itemId Int
|
||||
amount Int
|
||||
Car Car? @relation(fields: [carId], references: [carId])
|
||||
carId Int @unique
|
||||
|
||||
category Int
|
||||
itemId Int
|
||||
amount Int
|
||||
}
|
||||
|
||||
model CarSettings {
|
||||
dbId Int @id @default(autoincrement())
|
||||
car Car?
|
||||
dbId Int @id @default(autoincrement())
|
||||
car Car?
|
||||
|
||||
view Boolean @default(true)
|
||||
transmission Boolean @default(false)
|
||||
retire Boolean @default(false)
|
||||
meter Int @default(0)
|
||||
navigationMap Boolean @default(true)
|
||||
volume Int @default(1)
|
||||
bgm Int @default(0)
|
||||
nameplate Int @default(0)
|
||||
nameplateColor Int @default(0)
|
||||
terminalBackground Int @default(0)
|
||||
view Boolean @default(true)
|
||||
transmission Boolean @default(false)
|
||||
retire Boolean @default(false)
|
||||
meter Int @default(0)
|
||||
navigationMap Boolean @default(true)
|
||||
volume Int @default(1)
|
||||
bgm Int @default(0)
|
||||
nameplate Int @default(0)
|
||||
nameplateColor Int @default(0)
|
||||
terminalBackground Int @default(0)
|
||||
}
|
||||
|
||||
model CarState {
|
||||
dbId Int @id @default(autoincrement())
|
||||
car Car?
|
||||
dbId Int @id @default(autoincrement())
|
||||
car Car?
|
||||
|
||||
hasOpponentGhost Boolean @default(false)
|
||||
eventJoined Boolean @default(false)
|
||||
transferred Boolean @default(false)
|
||||
toBeDeleted Boolean @default(false)
|
||||
hasOpponentGhost Boolean @default(false)
|
||||
eventJoined Boolean @default(false)
|
||||
transferred Boolean @default(false)
|
||||
toBeDeleted Boolean @default(false)
|
||||
}
|
||||
|
||||
model TimeAttackRecord {
|
||||
dbId Int @id @default(autoincrement())
|
||||
dbId Int @id @default(autoincrement())
|
||||
|
||||
car Car @relation(fields: [carId], references: [carId])
|
||||
carId Int
|
||||
car Car @relation(fields: [carId], references: [carId])
|
||||
carId Int
|
||||
|
||||
model Int // Car model, literally just the `model` field from Car
|
||||
time Int
|
||||
course Int
|
||||
isMorning Boolean
|
||||
section1Time Int @map("section1Time")
|
||||
section2Time Int @map("section2Time")
|
||||
section3Time Int @map("section3Time")
|
||||
section4Time Int @map("section4Time")
|
||||
section5Time Int? @map("section5Time")
|
||||
section6Time Int? @map("section6Time")
|
||||
section7Time Int? @map("section7Time")
|
||||
model Int // Car model, literally just the `model` field from Car
|
||||
time Int
|
||||
course Int
|
||||
isMorning Boolean
|
||||
section1Time Int @map("section1Time")
|
||||
section2Time Int @map("section2Time")
|
||||
section3Time Int @map("section3Time")
|
||||
section4Time Int @map("section4Time")
|
||||
section5Time Int? @map("section5Time")
|
||||
section6Time Int? @map("section6Time")
|
||||
section7Time Int? @map("section7Time")
|
||||
tunePower Int @default(0) // Car Power
|
||||
tuneHandling Int @default(0) // Car Handling
|
||||
}
|
||||
|
@ -17,6 +17,17 @@ export interface UnixOptions {
|
||||
}
|
||||
|
||||
export interface GameOptions {
|
||||
// If set to 1, all scratch rewards will be granted to players (including cars)
|
||||
grantAllScratchRewards: number;
|
||||
|
||||
// If set to 1, gives the player a random colour for each of the special cars.
|
||||
// If set to 2, allows the player to pick any of the colours (more cluttered)
|
||||
grantBonusScratchCars: number;
|
||||
|
||||
// If set to 1, all gift cars (i.e. S2000, S660, etc. will be fully tuned.)
|
||||
// If set to 0, they will be left at their default tune (i.e. stock, basic tune, etc.)
|
||||
giftCarsFullyTuned: number,
|
||||
|
||||
// Amount of full-tunes to grant to newly registered cards
|
||||
grantFullTuneTicketToNewUsers: number;
|
||||
}
|
||||
|
@ -3,9 +3,11 @@ import { Module } from "../module";
|
||||
import * as wm from "../wmmt/wm.proto";
|
||||
import * as svc from "../wmmt/service.proto";
|
||||
import { prisma } from "..";
|
||||
import { User } from "@prisma/client";
|
||||
import { Car, User } from "@prisma/client";
|
||||
import { Config } from "../config";
|
||||
import Long from "long";
|
||||
import { userInfo } from "os";
|
||||
import { config } from "dotenv";
|
||||
|
||||
export default class GameModule extends Module {
|
||||
register(app: Application): void {
|
||||
@ -102,8 +104,6 @@ export default class GameModule extends Module {
|
||||
}
|
||||
case wm.wm.protobuf.GameMode.MODE_TIME_ATTACK:
|
||||
{
|
||||
console.log(body);
|
||||
|
||||
// If the game was not timed out / retired
|
||||
if (!(body.retired || body.timeup)) {
|
||||
|
||||
@ -139,13 +139,15 @@ export default class GameModule extends Module {
|
||||
section5Time: body!.taResult!.section_5Time,
|
||||
section6Time: body!.taResult!.section_6Time,
|
||||
section7Time: body!.taResult!.section_7Time,
|
||||
tunePower: body!.car!.tunePower,
|
||||
tuneHandling: body!.car!.tuneHandling
|
||||
}
|
||||
});
|
||||
}
|
||||
else // Creating a new record
|
||||
{
|
||||
console.log('Creating new time attack record');
|
||||
|
||||
|
||||
await prisma.timeAttackRecord.create({
|
||||
data: {
|
||||
carId: body.carId,
|
||||
@ -160,6 +162,8 @@ export default class GameModule extends Module {
|
||||
section5Time: body!.taResult!.section_5Time,
|
||||
section6Time: body!.taResult!.section_6Time,
|
||||
section7Time: body!.taResult!.section_7Time,
|
||||
tunePower: body!.car!.tunePower,
|
||||
tuneHandling: body!.car!.tuneHandling
|
||||
}
|
||||
});
|
||||
break;
|
||||
@ -221,7 +225,9 @@ export default class GameModule extends Module {
|
||||
})
|
||||
|
||||
app.post('/method/load_user', async (req, res) => {
|
||||
|
||||
let body = wm.wm.protobuf.LoadUserRequest.decode(req.body);
|
||||
|
||||
let user = await prisma.user.findFirst({
|
||||
where: {
|
||||
chipId: body.cardChipId,
|
||||
@ -236,7 +242,10 @@ export default class GameModule extends Module {
|
||||
unusedTickets: true
|
||||
}
|
||||
});
|
||||
|
||||
// No user returned
|
||||
if (!user) {
|
||||
|
||||
console.log('no such user');
|
||||
let msg = {
|
||||
error: wm.wm.protobuf.ErrorCode.ERR_SUCCESS,
|
||||
@ -334,7 +343,11 @@ export default class GameModule extends Module {
|
||||
r.send(Buffer.from(end));
|
||||
return;
|
||||
}
|
||||
|
||||
// console.log(user);
|
||||
|
||||
let carStates = user.cars.map(e => e.state);
|
||||
|
||||
let tickets = (user.unusedTickets || []).map(x => {
|
||||
return {
|
||||
itemId: x.itemId,
|
||||
@ -342,6 +355,7 @@ export default class GameModule extends Module {
|
||||
category: x.category
|
||||
}
|
||||
});
|
||||
|
||||
let msg = {
|
||||
error: wm.wm.protobuf.ErrorCode.ERR_SUCCESS,
|
||||
numOfOwnedCars: user.cars.length,
|
||||
@ -482,7 +496,7 @@ export default class GameModule extends Module {
|
||||
r.send(Buffer.from(end));
|
||||
})
|
||||
|
||||
//terminal specific
|
||||
// Load upon enter terminal
|
||||
app.post('/method/load_terminal_information', (req, res) => {
|
||||
let msg = {
|
||||
error: wm.wm.protobuf.ErrorCode.ERR_SUCCESS,
|
||||
@ -503,13 +517,387 @@ export default class GameModule extends Module {
|
||||
.status(200);
|
||||
r.send(Buffer.from(end));
|
||||
})
|
||||
|
||||
app.post('/method/load_scratch_information', (req, res) => {
|
||||
|
||||
// Load unrecieved user items
|
||||
app.post('/method/load_unrecieved_user_items', (req, res) => {
|
||||
|
||||
// In future, might want to check db for player items
|
||||
|
||||
let msg = {
|
||||
error: wm.wm.protobuf.ErrorCode.ERR_SUCCESS,
|
||||
currentSheet: 21,
|
||||
numOfScratched: 0,
|
||||
owned_user_items: [
|
||||
wm.wm.protobuf.UserItem.create({
|
||||
category: 17,
|
||||
itemId: 1
|
||||
})
|
||||
]
|
||||
}
|
||||
|
||||
let resp = wm.wm.protobuf.LoadUnreceivedUserItemsResponse.encode(msg);
|
||||
let end = resp.finish();
|
||||
let r = res
|
||||
.header('Server', 'v388 wangan')
|
||||
.header('Content-Type', 'application/x-protobuf; revision=8053')
|
||||
.header('Content-Length', end.length.toString())
|
||||
.status(200);
|
||||
r.send(Buffer.from(end));
|
||||
})
|
||||
|
||||
// Load user bookmarks
|
||||
app.post('/method/load_bookmarks', async (req, res) => {
|
||||
|
||||
// Get the save bookmark request
|
||||
let body = wm.wm.protobuf.LoadBookmarksRequest.decode(req.body);
|
||||
|
||||
// Check if the user has any existing bookmarks
|
||||
let user = await prisma.user.findFirst({
|
||||
where: {
|
||||
id: Number(body.userId)
|
||||
}
|
||||
});
|
||||
|
||||
// Car bookmarks placeholder
|
||||
let cars : Car[] = [];
|
||||
|
||||
// User is not null
|
||||
if (user)
|
||||
{
|
||||
// Loop over the bookmarked cars
|
||||
for (let carId of user.bookmarks)
|
||||
{
|
||||
// Get the car with the bookmarked car id
|
||||
let car = await prisma.car.findFirst({
|
||||
where: {
|
||||
carId: carId
|
||||
}
|
||||
});
|
||||
|
||||
// If the car is not null
|
||||
if (car)
|
||||
{
|
||||
// Add the car to the cars list
|
||||
cars.push(car);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
let msg = {
|
||||
error: wm.wm.protobuf.ErrorCode.ERR_SUCCESS,
|
||||
cars: cars
|
||||
}
|
||||
|
||||
let resp = wm.wm.protobuf.LoadBookmarksResponse.encode(msg);
|
||||
let end = resp.finish();
|
||||
let r = res
|
||||
.header('Server', 'v388 wangan')
|
||||
.header('Content-Type', 'application/x-protobuf; revision=8053')
|
||||
.header('Content-Length', end.length.toString())
|
||||
.status(200);
|
||||
r.send(Buffer.from(end));
|
||||
})
|
||||
|
||||
// Save user bookmarks
|
||||
app.post('/method/save_bookmarks', async (req, res) => {
|
||||
|
||||
// Get the save bookmark request
|
||||
let body = wm.wm.protobuf.SaveBookmarksRequest.decode(req.body);
|
||||
|
||||
// Update existing bookmarks
|
||||
await prisma.user.update({
|
||||
where: {
|
||||
id: body.userId
|
||||
},
|
||||
data: {
|
||||
bookmarks: body.cars
|
||||
}
|
||||
})
|
||||
|
||||
// Generate the response to the terminal (success messsage)
|
||||
let resp = wm.wm.protobuf.LoadBookmarksResponse.encode({
|
||||
error: wm.wm.protobuf.ErrorCode.ERR_SUCCESS
|
||||
});
|
||||
|
||||
let end = resp.finish();
|
||||
let r = res
|
||||
.header('Server', 'v388 wangan')
|
||||
.header('Content-Type', 'application/x-protobuf; revision=8053')
|
||||
.header('Content-Length', end.length.toString())
|
||||
.status(200);
|
||||
r.send(Buffer.from(end));
|
||||
})
|
||||
|
||||
// Car Summary Request (for bookmarks)
|
||||
app.get('/resource/car_summary', async (req, res) => {
|
||||
|
||||
// Get the query from the request
|
||||
let query = req.query;
|
||||
|
||||
// Get all of the cars matching the query
|
||||
let cars = await prisma.car.findMany({
|
||||
take: Number(query.limit),
|
||||
where: {
|
||||
name: {
|
||||
startsWith: String(query.name)
|
||||
}
|
||||
},
|
||||
});
|
||||
|
||||
let msg = {
|
||||
hitCount: cars.length,
|
||||
cars: cars
|
||||
}
|
||||
|
||||
let resp = wm.wm.protobuf.CarSummary.encode(msg);
|
||||
let end = resp.finish();
|
||||
let r = res
|
||||
.header('Server', 'v388 wangan')
|
||||
.header('Content-Type', 'application/x-protobuf; revision=8053')
|
||||
.header('Content-Length', end.length.toString())
|
||||
.status(200);
|
||||
r.send(Buffer.from(end));
|
||||
|
||||
})
|
||||
|
||||
// Save upon timeout / exit terminal
|
||||
app.post('/method/save_terminal_result', async (req, res) => {
|
||||
|
||||
// Get the contents from the request
|
||||
let body = wm.wm.protobuf.SaveTerminalResultRequest.decode(req.body);
|
||||
|
||||
// user id is required field
|
||||
let user = await prisma.user.findFirst({
|
||||
where: {
|
||||
id: body.userId
|
||||
},
|
||||
});
|
||||
|
||||
// Update the car order (NOT IMPLEMENTED)
|
||||
|
||||
// Update the completed tutorials
|
||||
let storedTutorials = user!.tutorials;
|
||||
|
||||
body.confirmedTutorials.forEach(
|
||||
(idx) => storedTutorials[idx] = true
|
||||
);
|
||||
|
||||
await prisma.user.update({
|
||||
where: {
|
||||
id: body.userId
|
||||
},
|
||||
data: {
|
||||
tutorials: storedTutorials
|
||||
}
|
||||
});
|
||||
|
||||
let msg = {
|
||||
// Success error code
|
||||
error: wm.wm.protobuf.ErrorCode.ERR_SUCCESS,
|
||||
}
|
||||
|
||||
// Encode the save terminal result response
|
||||
let resp = wm.wm.protobuf.SaveTerminalResultResponse.encode(msg);
|
||||
let end = resp.finish();
|
||||
let r = res
|
||||
.header('Server', 'v388 wangan')
|
||||
.header('Content-Type', 'application/x-protobuf; revision=8053')
|
||||
.header('Content-Length', end.length.toString())
|
||||
.status(200);
|
||||
r.send(Buffer.from(end));
|
||||
})
|
||||
|
||||
// Terminal scratch (VERY WIP)
|
||||
app.post('/method/load_scratch_information', async (req, res) => {
|
||||
|
||||
// Get the information from the request
|
||||
let body = wm.wm.protobuf.LoadScratchInformationRequest.decode(req.body);
|
||||
|
||||
// Commenting all of the scratch card shit out for now
|
||||
|
||||
/*
|
||||
// Get all of the scratch sheets for the user
|
||||
let scratchSheets = await prisma.scratchSheet.findMany({
|
||||
where: {
|
||||
userId: body.userId
|
||||
},
|
||||
include: {
|
||||
squares: true
|
||||
}
|
||||
});
|
||||
|
||||
// No scratch sheets for user
|
||||
if (scratchSheets.length == 0)
|
||||
{
|
||||
// Create a new scratch sheet for the user
|
||||
let sheet = await prisma.scratchSheet.create({
|
||||
data: {
|
||||
userId: body.userId
|
||||
}
|
||||
})
|
||||
|
||||
// Populate each square (with FT ticket for now)
|
||||
for (let i=0; i<50; i++) {
|
||||
await prisma.scratchSquare.create({
|
||||
data: {
|
||||
sheetId: sheet.id,
|
||||
category: wm.wm.protobuf.ItemCategory.CAT_RIVAL_MARKER,
|
||||
itemId: 1,
|
||||
earned: false
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// In future, I will very the way this is populated based on settings
|
||||
// i.e. totally random items, items based upon real arcade, etc.
|
||||
|
||||
// Get the data for the newly created sheet
|
||||
let newSheet = await prisma.scratchSheet.findFirst({
|
||||
where: {
|
||||
userId: body.userId
|
||||
},
|
||||
include: {
|
||||
squares: true
|
||||
}
|
||||
});
|
||||
|
||||
// Sheet is created successfully
|
||||
if (newSheet)
|
||||
{
|
||||
// Update the scratch sheet list
|
||||
scratchSheets = [newSheet];
|
||||
}
|
||||
}
|
||||
|
||||
// Generate the scratch sheet proto
|
||||
let scratch_sheets : wm.wm.protobuf.ScratchSheet[] = [];
|
||||
|
||||
// Loop over all of the protos
|
||||
for(let sheet of scratchSheets)
|
||||
{
|
||||
// Get all of the scratch squares
|
||||
let scratch_squares : wm.wm.protobuf.ScratchSheet.ScratchSquare[] = [];
|
||||
|
||||
// Loop over all of the squares
|
||||
for (let square of sheet.squares)
|
||||
{
|
||||
// Add the current square to the protobuf array
|
||||
scratch_squares.push(wm.wm.protobuf.ScratchSheet.ScratchSquare.create({
|
||||
category: square.category,
|
||||
itemId: square.itemId,
|
||||
earned: square.earned
|
||||
}));
|
||||
}
|
||||
|
||||
// Add the scratch sheet to the sheets list
|
||||
scratch_sheets.push(
|
||||
wm.wm.protobuf.ScratchSheet.create({
|
||||
squares: scratch_squares
|
||||
})
|
||||
);
|
||||
}
|
||||
*/
|
||||
|
||||
// Debug: Add all items to the 'acceptable items' list
|
||||
|
||||
// Owned user items list
|
||||
let ownedUserItems : wm.wm.protobuf.UserItem[] = [];
|
||||
|
||||
// Get the current date
|
||||
let date = Date.now();
|
||||
|
||||
// If the grant all scratch rewards switch is set, add them to the list
|
||||
if (Config.getConfig().gameOptions.grantAllScratchRewards)
|
||||
{
|
||||
// Grant one of each item every time the menu is loaded
|
||||
|
||||
// Loop over all of the window sticker styles
|
||||
for(let i=1; i<=60; i++)
|
||||
{
|
||||
// Add one of each of the window sticker styles to the list
|
||||
ownedUserItems.push(wm.wm.protobuf.UserItem.create({
|
||||
category: wm.wm.protobuf.ItemCategory.CAT_WINDOW_DECORATION,
|
||||
itemId: i,
|
||||
earnedAt: date,
|
||||
}));
|
||||
}
|
||||
|
||||
// Loop over all of the rival markers
|
||||
for(let i=1; i<=80; i++)
|
||||
{
|
||||
// Add one of each of the rival markers to the list
|
||||
ownedUserItems.push(wm.wm.protobuf.UserItem.create({
|
||||
category: wm.wm.protobuf.ItemCategory.CAT_RIVAL_MARKER,
|
||||
itemId: i,
|
||||
earnedAt: date,
|
||||
}));
|
||||
}
|
||||
|
||||
// Item ID for the scratch cars
|
||||
let scratchCarIds = [4, 3, 1, 2, 5, 6, 16, 17, 18, 19, 20, 21];
|
||||
|
||||
// I literally ripped this from mozilla.org lmfao
|
||||
let getValueInRange = (min: number, max: number) => {
|
||||
return Math.random() * (max - min) + min;
|
||||
}
|
||||
|
||||
// If the grant bonus scratch cars switch is set, switch on the value
|
||||
switch(Config.getConfig().gameOptions.grantBonusScratchCars)
|
||||
{
|
||||
case 1: // Grant one of each bonus scratch car (random colour)
|
||||
|
||||
// Mini Cooper
|
||||
scratchCarIds.push(getValueInRange(7, 15));
|
||||
|
||||
// S660
|
||||
scratchCarIds.push(getValueInRange(22, 27));
|
||||
|
||||
// S2000
|
||||
scratchCarIds.push(getValueInRange(28, 36));
|
||||
|
||||
// Roadster RF, 280ZT, Leopard
|
||||
scratchCarIds = scratchCarIds.concat([37, 38, 39]);
|
||||
|
||||
break;
|
||||
case 2: // Grant every colour of each bonus scratch cars
|
||||
|
||||
// Mini Cooper
|
||||
scratchCarIds = scratchCarIds.concat([7, 8, 9, 10, 11, 12, 13, 14, 15]);
|
||||
|
||||
// S660
|
||||
scratchCarIds = scratchCarIds.concat([22, 23, 24, 25, 26, 27]);
|
||||
|
||||
// S2000
|
||||
scratchCarIds = scratchCarIds.concat([28, 29, 30, 31, 32, 33, 34, 35, 36]);
|
||||
|
||||
// Roadster RF, 280ZT, Leopard
|
||||
scratchCarIds = scratchCarIds.concat([37, 38, 39]);
|
||||
|
||||
break;
|
||||
default: // Do not grant bonus scratch cars
|
||||
break;
|
||||
}
|
||||
|
||||
// Loop over all of the scratch cars
|
||||
for(let car of scratchCarIds)
|
||||
{
|
||||
// Add one of each of the rival markers to the list
|
||||
ownedUserItems.push(wm.wm.protobuf.UserItem.create({
|
||||
category: 201, // Scratch Car
|
||||
itemId: car,
|
||||
earnedAt: date,
|
||||
}));
|
||||
}
|
||||
}
|
||||
|
||||
let msg = {
|
||||
error: wm.wm.protobuf.ErrorCode.ERR_SUCCESS,
|
||||
scratchSheets: [],
|
||||
currentSheet: 0,
|
||||
numOfScratched: 0,
|
||||
ownedUserItems: ownedUserItems
|
||||
}
|
||||
|
||||
// console.log(scratch_sheets);
|
||||
|
||||
let resp = wm.wm.protobuf.LoadScratchInformationResponse.encode(msg);
|
||||
let end = resp.finish();
|
||||
let r = res
|
||||
@ -520,6 +908,99 @@ export default class GameModule extends Module {
|
||||
r.send(Buffer.from(end));
|
||||
});
|
||||
|
||||
app.post('/method/save_scratch_sheet', async (req, res) => {
|
||||
|
||||
// Get the information from the request
|
||||
let body = wm.wm.protobuf.SaveScratchSheetRequest.decode(req.body);
|
||||
|
||||
/*
|
||||
// Get all of the scratch sheets for the user
|
||||
let scratchSheets = await prisma.scratchSheet.findMany({
|
||||
where: {
|
||||
userId: body.userId
|
||||
},
|
||||
include: {
|
||||
squares: true
|
||||
}
|
||||
})
|
||||
|
||||
// Get the target scratch sheet
|
||||
let scratchSheet = scratchSheets[Number(body.targetSheet)];
|
||||
|
||||
// Get all of the squares for the scratch sheet
|
||||
let scratchSquares = await prisma.scratchSquare.findMany({
|
||||
where: {
|
||||
sheetId: scratchSheet.id
|
||||
}
|
||||
});
|
||||
|
||||
// Get the target scratch square
|
||||
let scratchSquare = scratchSquares[Number(body.targetSquare)];
|
||||
|
||||
// Update the revealed scratch square
|
||||
await prisma.scratchSquare.update({
|
||||
where: {
|
||||
id: scratchSquare.id
|
||||
},
|
||||
data: {
|
||||
earned: true
|
||||
}
|
||||
});
|
||||
|
||||
// Get the number of scratched squares on the page
|
||||
let numOfScratched = await prisma.scratchSquare.count({
|
||||
where: {
|
||||
sheetId: scratchSheet.id,
|
||||
earned: true
|
||||
}
|
||||
})
|
||||
|
||||
// Generate the scratch sheet proto
|
||||
let scratch_sheets : wm.wm.protobuf.ScratchSheet[] = [];
|
||||
|
||||
// Loop over all of the protos
|
||||
for(let sheet of scratchSheets)
|
||||
{
|
||||
// Get all of the scratch squares
|
||||
let scratch_squares : wm.wm.protobuf.ScratchSheet.ScratchSquare[] = [];
|
||||
|
||||
// Loop over all of the squares
|
||||
for (let square of sheet.squares)
|
||||
{
|
||||
// Add the current square to the protobuf array
|
||||
scratch_squares.push(wm.wm.protobuf.ScratchSheet.ScratchSquare.create({
|
||||
category: square.category,
|
||||
itemId: square.itemId,
|
||||
earned: square.earned
|
||||
}));
|
||||
}
|
||||
|
||||
// Add the scratch sheet to the sheets list
|
||||
scratch_sheets.push(
|
||||
wm.wm.protobuf.ScratchSheet.create({
|
||||
squares: scratch_squares
|
||||
})
|
||||
);
|
||||
}
|
||||
*/
|
||||
|
||||
let msg = {
|
||||
error: wm.wm.protobuf.ErrorCode.ERR_SUCCESS,
|
||||
scratchSheets : [],
|
||||
currentSheet: body.targetSheet,
|
||||
numOfScratched: 0,
|
||||
}
|
||||
|
||||
let resp = wm.wm.protobuf.SaveScratchSheetResponse.encode(msg);
|
||||
let end = resp.finish();
|
||||
let r = res
|
||||
.header('Server', 'v388 wangan')
|
||||
.header('Content-Type', 'application/x-protobuf; revision=8053')
|
||||
.header('Content-Length', end.length.toString())
|
||||
.status(200);
|
||||
r.send(Buffer.from(end));
|
||||
})
|
||||
|
||||
app.post('/method/update_car', async (req, res) => {
|
||||
let body = wm.wm.protobuf.UpdateCarRequest.decode(req.body);
|
||||
let car = await prisma.car.findFirst({
|
||||
@ -567,15 +1048,23 @@ export default class GameModule extends Module {
|
||||
})
|
||||
|
||||
app.post('/method/create_car', async (req, res) => {
|
||||
|
||||
// Get the create car request body
|
||||
let body = wm.wm.protobuf.CreateCarRequest.decode(req.body);
|
||||
|
||||
console.log(body);
|
||||
|
||||
// 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 {
|
||||
} else { // No user id, use card chip
|
||||
user = await prisma.user.findFirst({
|
||||
where: {
|
||||
chipId: body.cardChipId,
|
||||
@ -583,30 +1072,75 @@ export default class GameModule extends Module {
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
// 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 fullTuneUsed = false;
|
||||
if (body.userItemId) {
|
||||
|
||||
// Sets if full tune is used or not
|
||||
let fullyTuned = false;
|
||||
|
||||
// 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: {
|
||||
dbId: body.userItemId
|
||||
}
|
||||
});
|
||||
|
||||
console.log(`Item category was ${item.category} and item game ID was ${item.itemId}`);
|
||||
|
||||
// If the item used was a full tune ticket
|
||||
if (item.category == wm.wm.protobuf.ItemCategory.CAT_CAR_TICKET_FREE &&
|
||||
item.itemId == 5)
|
||||
{
|
||||
// This is a full-tune ticket
|
||||
fullTuneUsed = true;
|
||||
// Fully tuned is true
|
||||
fullyTuned = true;
|
||||
}
|
||||
|
||||
console.log('Item deleted!');
|
||||
}
|
||||
// User item not used, but car has 740 HP by default
|
||||
else if (body.car &&
|
||||
(body.car.tunePower == 17) && (body.car.tuneHandling == 17))
|
||||
{
|
||||
// Set fully tuned to be true
|
||||
fullyTuned = true;
|
||||
}
|
||||
// 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
|
||||
fullyTuned = true;
|
||||
}
|
||||
}
|
||||
|
||||
// Default car values
|
||||
let carInsert = {
|
||||
userId: user.id,
|
||||
manufacturer: body.car.manufacturer!,
|
||||
@ -622,8 +1156,21 @@ export default class GameModule extends Module {
|
||||
carStateDbId: state.dbId,
|
||||
regionId: body.car.regionId!,
|
||||
};
|
||||
let additionalInsert = {}
|
||||
if (fullTuneUsed) {
|
||||
|
||||
// Additional car values (for full tune)
|
||||
let additionalInsert = {
|
||||
|
||||
}
|
||||
|
||||
// Car is fully tuned
|
||||
if (fullyTuned) {
|
||||
|
||||
// Updated default values
|
||||
carInsert.level = 8; // C3
|
||||
carInsert.tunePower = 17; // 740 HP
|
||||
carInsert.tuneHandling = 17; // 740 HP
|
||||
|
||||
// Additional full tune values
|
||||
additionalInsert = {
|
||||
stClearBits: 0,
|
||||
stLoseBits: 0,
|
||||
@ -632,6 +1179,8 @@ export default class GameModule extends Module {
|
||||
stConsecutiveWins: 80
|
||||
};
|
||||
}
|
||||
|
||||
// Insert the car into the database
|
||||
let car = await prisma.car.create({
|
||||
data: {
|
||||
...carInsert,
|
||||
@ -697,14 +1246,122 @@ export default class GameModule extends Module {
|
||||
r.send(Buffer.from(end));
|
||||
});
|
||||
|
||||
app.post('/method/load_game_history', (req, res) => {
|
||||
let msg = {
|
||||
app.post('/method/load_game_history', async (req, res) => {
|
||||
|
||||
// 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: {
|
||||
carId: body.carId
|
||||
}
|
||||
});
|
||||
|
||||
// Get the car's time attack records
|
||||
let records = await prisma.timeAttackRecord.findMany({
|
||||
where: {
|
||||
carId: body.carId
|
||||
}
|
||||
});
|
||||
|
||||
console.log(records);
|
||||
|
||||
// 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
|
||||
}));
|
||||
}
|
||||
|
||||
let msg = {
|
||||
error: wm.wm.protobuf.ErrorCode.ERR_SUCCESS,
|
||||
taRankingUpdatedAt: 0,
|
||||
taRecords: ta_records,
|
||||
taRankingUpdatedAt: 1,
|
||||
ghostBattleCount: 0,
|
||||
ghostBattleWinCount: 0,
|
||||
stampSheetCount: 100,
|
||||
stampSheetCount: 0,
|
||||
}
|
||||
|
||||
let resp = wm.wm.protobuf.LoadGameHistoryResponse.encode(msg);
|
||||
let end = resp.finish();
|
||||
let r = res
|
||||
|
Loading…
x
Reference in New Issue
Block a user