1
0
mirror of synced 2025-02-12 09:02:57 +01:00
Bayshore/src/modules/game.ts

1894 lines
53 KiB
TypeScript
Raw Normal View History

import e, { Application } from "express";
2022-07-12 15:50:05 +01:00
import { Module } from "../module";
import * as wm from "../wmmt/wm.proto";
import * as svc from "../wmmt/service.proto";
2022-07-15 15:39:59 +01:00
import { prisma } from "..";
import { Car, User } from "@prisma/client";
import { Config } from "../config";
2022-07-18 13:15:57 +01:00
import Long from "long";
import { userInfo } from "os";
import { config } from "dotenv";
import * as scratch from "../util/scratch";
import { envelopeItemTypeToDataCategory } from "@sentry/utils";
2022-07-12 15:50:05 +01:00
export default class GameModule extends Module {
register(app: Application): void {
2022-07-15 19:26:29 +01:00
app.post('/method/save_game_result', async (req, res) => {
let body = wm.wm.protobuf.SaveGameResultRequest.decode(req.body);
let car = await prisma.car.findFirst({
where: {
carId: body.carId
}
});
2022-07-20 00:23:50 +07:00
let storyLose: boolean = false;
2022-07-15 19:26:29 +01:00
switch (body.gameMode) {
case wm.wm.protobuf.GameMode.MODE_STORY:
{
2022-07-20 00:23:50 +07:00
if (!(body.retired)) {
let maxConsecutiveWins = car!.stConsecutiveWinsMax;
if (maxConsecutiveWins < body.stResult!.stConsecutiveWins!) {
maxConsecutiveWins = body.stResult!.stConsecutiveWins!;
2022-07-18 13:15:57 +01:00
}
2022-07-20 00:23:50 +07:00
let divcount = body.stResult?.stClearDivCount;
let saveEx: any = {};
if (body.stResult?.stLoseBits !== null && body.stResult?.stLoseBits !== undefined) {
let actualLoseBits = BigInt(0);
if (body.stResult?.stLoseBits! instanceof Long) {
actualLoseBits = actualLoseBits | BigInt(body.stResult?.stLoseBits.high);
actualLoseBits = actualLoseBits << BigInt(32);
actualLoseBits = actualLoseBits | BigInt(body.stResult?.stLoseBits.low);
saveEx.stLoseBits = Number(actualLoseBits);
if(saveEx.stLoseBits > 0){
storyLose = true;
}
}
} else {
saveEx.stLoseBits = car?.stLoseBits;
}
if (divcount !== null && divcount !== undefined && divcount !== 0) {
console.log(body.stResult?.stClearDivCount);
saveEx.stClearDivCount = divcount;
} else {
saveEx.stClearDivCount = car?.stClearDivCount;
}
if (body.stResult?.stClearBits !== null && body.stResult?.stClearBits !== undefined && storyLose !== true) {
saveEx.stClearBits = body.stResult?.stClearBits;
} else {
saveEx.stClearBits = car?.stClearBits;
}
if (body.stResult?.stPlayCount !== null && body.stResult?.stPlayCount !== undefined) {
saveEx.stPlayCount = body.stResult?.stPlayCount!;
} else {
saveEx.stPlayCount = car?.stPlayCount;
}
if (body.stResult?.stClearCount !== null && body.stResult?.stClearCount !== undefined && body.stResult?.stClearCount !== 0) {
saveEx.stClearCount = body.stResult?.stClearCount!;
} else {
saveEx.stClearCount = car?.stClearCount;
}
if (body.stResult?.stConsecutiveWins !== null && body.stResult?.stConsecutiveWins !== undefined) {
saveEx.stConsecutiveWins = body.stResult?.stConsecutiveWins!;
} else {
saveEx.stConsecutiveWins = car?.stConsecutiveWins;
}
if (body.stResult?.tuningPoint !== null && body.stResult?.tuningPoint !== undefined) {
saveEx.tuningPoints = body.stResult?.tuningPoint!;
} else {
saveEx.tuningPoints = car?.tuningPoints;
}
if (body.stResult?.stCompleted_100Episodes !== null && body.stResult?.stCompleted_100Episodes !== undefined) {
saveEx.stCompleted100Episodes = body.stResult?.stCompleted_100Episodes!;
} else {
saveEx.stCompleted100Episodes = car?.stCompleted100Episodes;
}
console.log(saveEx);
let c = await prisma.car.update({
where: {
carId: body.carId
},
data: saveEx
});
console.log('-------');
2022-07-20 00:23:50 +07:00
console.log(c);
2022-07-18 12:50:49 +01:00
}
2022-07-15 19:26:29 +01:00
break;
}
case wm.wm.protobuf.GameMode.MODE_TIME_ATTACK:
{
// If the game was not timed out / retired
if (!(body.retired || body.timeup)) {
console.log('Game not retired / timed out, continuing ...')
// Get the current time attack record for the car
let currentRecord = await prisma.timeAttackRecord.findFirst({
where: {
carId: body.carId, // , model: body.car!.model!,
course: body.taResult!.course
}
});
// Record already exists
if (currentRecord)
{
// If the existing record is faster, do not continue
if (body.taResult!.time > currentRecord.time) break;
console.log('Updating time attack record...')
await prisma.timeAttackRecord.update({
where: {
// Could be null - if it is null, this will insert.
dbId: currentRecord!.dbId
},
data: {
time: body.taResult!.time,
section1Time: body!.taResult!.section_1Time,
section2Time: body!.taResult!.section_2Time,
section3Time: body!.taResult!.section_3Time,
section4Time: body!.taResult!.section_4Time,
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
{
2022-07-16 23:08:07 +01:00
console.log('Creating new time attack record');
2022-07-16 23:08:07 +01:00
await prisma.timeAttackRecord.create({
data: {
carId: body.carId,
model: body.car!.model!,
time: body.taResult!.time,
isMorning: body.taResult!.isMorning,
course: body.taResult!.course,
section1Time: body!.taResult!.section_1Time,
section2Time: body!.taResult!.section_2Time,
section3Time: body!.taResult!.section_3Time,
section4Time: body!.taResult!.section_4Time,
section5Time: body!.taResult!.section_5Time,
section6Time: body!.taResult!.section_6Time,
section7Time: body!.taResult!.section_7Time,
tunePower: body!.car!.tunePower,
tuneHandling: body!.car!.tuneHandling
2022-07-16 23:08:07 +01:00
}
});
break;
}
}
break;
}
case wm.wm.protobuf.GameMode.MODE_GHOST_BATTLE:
{
if (!(body.retired)) {
let saveEx: any = {};
if (body.rgResult?.rgRegionMapScore !== null && body.rgResult?.rgRegionMapScore !== undefined) {
saveEx.rgRegionMapScore = body.rgResult?.rgRegionMapScore!;
} else {
saveEx.rgRegionMapScore = car?.rgRegionMapScore;
}
if (body.rgResult?.rgPlayCount !== null && body.rgResult?.rgPlayCount !== undefined) {
saveEx.rgPlayCount = body.rgResult?.rgPlayCount!;
} else {
saveEx.rgPlayCount = car?.rgPlayCount;
}
if (body.rgResult?.dressupLevel !== null && body.rgResult?.dressupLevel !== undefined) {
saveEx.dressupLevel = body.rgResult?.dressupLevel!;
} else {
saveEx.dressupLevel = car?.dressupLevel;
}
if (body.rgResult?.dressupPoint !== null && body.rgResult?.dressupPoint !== undefined) {
saveEx.dressupPoint = body.rgResult?.dressupPoint!;
} else {
saveEx.dressupPoint = car?.dressupPoint;
}
if (body.car?.wheel !== null && body.car?.wheel !== undefined) {
saveEx.wheel = body.car?.wheel!;
} else {
saveEx.wheel = car?.wheel;
}
if (body.car?.wheelColor !== null && body.car?.wheelColor !== undefined) {
saveEx.wheelColor = body.car?.wheelColor!;
} else {
saveEx.wheelColor = car?.wheelColor;
}
if (body.car?.aero !== null && body.car?.aero !== undefined) {
saveEx.aero = body.car?.aero!;
} else {
saveEx.aero = car?.aero;
}
if (body.car?.bonnet !== null && body.car?.bonnet !== undefined) {
saveEx.bonnet = body.car?.bonnet!;
} else {
saveEx.bonnet = car?.bonnet;
}
if (body.car?.wing !== null && body.car?.wing !== undefined) {
saveEx.wing = body.car?.wing!;
} else {
saveEx.wing = car?.wing;
}
if (body.car?.mirror !== null && body.car?.mirror !== undefined) {
saveEx.mirror = body.car?.mirror!;
} else {
saveEx.mirror = car?.mirror;
}
if (body.car?.neon !== null && body.car?.neon !== undefined) {
saveEx.neon = body.car?.neon!;
} else {
saveEx.neon = car?.neon;
}
if (body.car?.trunk !== null && body.car?.trunk !== undefined) {
saveEx.trunk = body.car?.trunk!;
} else {
saveEx.trunk = car?.trunk;
}
if (body.car?.plate !== null && body.car?.plate !== undefined) {
saveEx.plate = body.car?.plate!;
} else {
saveEx.plate = car?.plate;
}
if (body.car?.plateColor !== null && body.car?.plateColor !== undefined) {
saveEx.plateColor = body.car?.plateColor!;
} else {
saveEx.plateColor = car?.plateColor;
}
if (body.car?.plateNumber !== null && body.car?.plateNumber !== undefined) {
saveEx.plateNumber = body.car?.plateNumber!;
} else {
saveEx.plateNumber = car?.plateNumber;
}
if (body.car?.ghostLevel !== null && body.car?.ghostLevel !== undefined) {
saveEx.ghostLevel = body.car?.ghostLevel!;
} else {
saveEx.ghostLevel = car?.ghostLevel;
}
let winCounter = 0;
if(body.rgResult?.rgRegionMapScore !== null && body.rgResult?.rgRegionMapScore !== undefined && body.rgResult?.rgRegionMapScore.length !== 0){
for(let i=0; i<body.rgResult.rgRegionMapScore.length; i++){
winCounter += body.rgResult.rgRegionMapScore[i];
}
2022-07-21 12:24:43 +07:00
}
saveEx.rgWinCount = winCounter;
saveEx.rgScore = winCounter;
let c = await prisma.car.update({
where: {
carId: body.carId
},
data: saveEx
});
}
}
2022-07-15 19:26:29 +01:00
}
// Get car item
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
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
2022-07-18 10:13:31 +01:00
await prisma.car.update({
where: {
carId: body.carId,
},
data: {
aura: body.car!.aura!,
auraMotif: body.car!.auraMotif!,
2022-07-18 10:13:31 +01:00
odometer: body.odometer,
playCount: body.playCount,
level: body.car!.level!,
title: body.car!.title!,
tunePower: body.car!.tunePower!,
tuneHandling: body.car!.tuneHandling!,
2022-07-22 15:36:21 +07:00
windowSticker: body.car!.windowSticker!,
earnedCustomColor: body.earnedCustomColor!
2022-07-18 10:13:31 +01:00
}
})
// Update car settings
2022-07-16 21:08:06 +01:00
await prisma.carSettings.update({
where: {
dbId: car!.carSettingsDbId
},
data: {
...body.setting
}
});
// Update user
2022-07-15 21:16:20 +01:00
let user = await prisma.user.findFirst({
where: {
id: body.car!.userId!
}
});
// User object exists
if (user)
{
// Get user tutorials
let storedTutorials = user!.tutorials;
// Update any seen tutorials
body.confirmedTutorials.forEach(
(idx) => storedTutorials[idx] = true
);
// Get the order of the user's cars
let carOrder = user?.carOrder;
// Get the index of the selected car
let index = carOrder.indexOf(body.carId);
// If the selected car is not first
if (index > 0)
{
// Remove that index from the array
carOrder.slice(index);
// Add it back to the front
carOrder.unshift(body.carId);
2022-07-15 19:55:15 +01:00
}
// Otherwise, just ignore it
// Update the values
await prisma.user.update({
where: {
id: body.car!.userId!
},
data: {
tutorials: storedTutorials,
carOrder: carOrder
}
});
}
2022-07-15 19:55:15 +01:00
2022-07-15 19:26:29 +01:00
let msg = {
error: wm.wm.protobuf.ErrorCode.ERR_SUCCESS,
}
let resp = wm.wm.protobuf.SaveGameResultResponse.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));
})
2022-07-15 15:39:59 +01:00
app.post('/method/load_user', async (req, res) => {
let body = wm.wm.protobuf.LoadUserRequest.decode(req.body);
2022-07-15 15:39:59 +01:00
let user = await prisma.user.findFirst({
where: {
chipId: body.cardChipId,
accessCode: body.accessCode
},
2022-07-15 15:39:59 +01:00
include: {
cars: {
include: {
state: true,
}
}
2022-07-15 15:39:59 +01:00
}
});
// No user returned
2022-07-15 15:39:59 +01:00
if (!user) {
console.log('no such user');
let msg = {
error: wm.wm.protobuf.ErrorCode.ERR_SUCCESS,
numOfOwnedCars: 0,
cars: [],
spappState: wm.wm.protobuf.SmartphoneAppState.SPAPP_UNREGISTERED,
transferState: wm.wm.protobuf.TransferState.NOT_REGISTERED
};
2022-07-17 19:27:27 +01:00
if (!body.cardChipId || !body.accessCode) {
let msg = {
error: wm.wm.protobuf.ErrorCode.ERR_ID_BANNED,
numOfOwnedCars: 0,
spappState: wm.wm.protobuf.SmartphoneAppState.SPAPP_UNREGISTERED,
transferState: wm.wm.protobuf.TransferState.NOT_REGISTERED
}
let resp = wm.wm.protobuf.LoadUserResponse.encode(msg);
let end = resp.finish();
let r = res
.header('Server', 'v388 wangan')
.header('Content-Type', 'application/x-protobuf; revision=8053')
.header('Content-Length', end.length.toString())
.status(200);
r.send(Buffer.from(end));
return;
}
2022-07-15 15:39:59 +01:00
let user = await prisma.user.create({
data: {
chipId: body.cardChipId,
accessCode: body.accessCode,
tutorials: [
false, //TUTORIAL_ID_STORY
false, //TUTORIAL_ID_TIME_ATTACK
false, //TUTORIAL_ID_GHOST
false, //TUTORIAL_ID_GHOST_CHALLENGE
false, //TUTORIAL_ID_GHOST_LEVEL
false, //TUTORIAL_ID_UNUSED_5
false, //TUTORIAL_ID_GHOST_SEARCH
false, //TUTORIAL_ID_GHOST_COMPETITION
false, //TUTORIAL_ID_HP600_CARD
false, //TUTORIAL_ID_UNUSED_9
false, //TUTORIAL_ID_COMPETITION_QUALIFIED
false, //TUTORIAL_ID_COMPETITION_TERMINAL
false, //TUTORIAL_ID_COMPETITION_NOTICE
false, //TUTORIAL_ID_COMPETITION_FINISHED
false, //TUTORIAL_ID_UNUSED_14
false, //TUTORIAL_ID_UNUSED_15
false, //TUTORIAL_ID_UNUSED_16
false, //TUTORIAL_ID_UNUSED_17
false, //TUTORIAL_ID_UNUSED_18
false, //TUTORIAL_ID_UNUSED_19
false, //TUTORIAL_ID_GHOST_STAMP
false, //TUTORIAL_ID_GHOST_STAMP_DECLINED
false, //TUTORIAL_ID_GHOST_STAMP_FRIENDS
2022-07-18 10:13:31 +01:00
true, //TUTORIAL_ID_TERMINAL_SCRATCH
true, //TUTORIAL_ID_TURN_SCRATCH_SHEET
2022-07-15 15:39:59 +01:00
false, //TUTORIAL_ID_INVITE_FRIEND_CAMPAIGN
false, //TUTORIAL_ID_CAR_COUPON_FULL_TUNED_RECEIVABLE
false, //TUTORIAL_ID_VS_CONTINUE_TICKET
false, //TUTORIAL_ID_UNUSED_28
false, //TUTORIAL_ID_UNUSED_29
false, //TUTORIAL_ID_UNUSED_30
false, //TUTORIAL_ID_DRESS_UP
false, //TUTORIAL_ID_MULTI_GHOST
2022-07-15 19:26:29 +01:00
true, //TUTORIAL_ID_STORY_NEW_FEATURE
true, //TUTORIAL_ID_GHOST_NEW_FEATURE
true, //TUTORIAL_ID_GHOST_REGION_MAP
2022-07-15 15:39:59 +01:00
],
}
});
console.log('user made')
if (!user) {
msg.error = wm.wm.protobuf.ErrorCode.ERR_REQUEST;
}
let ftTicketGrant = Config.getConfig().gameOptions.grantFullTuneTicketToNewUsers;
if (ftTicketGrant > 0) {
console.log(`Granting Full-Tune Ticket x${ftTicketGrant} to new user...`);
for (let i=0; i<ftTicketGrant; i++) {
await prisma.userItem.create({
data: {
userId: user.id,
category: wm.wm.protobuf.ItemCategory.CAT_CAR_TICKET_FREE,
itemId: 5,
type: 0 // Car Ticket
}
});
}
console.log('Done!');
}
2022-07-15 15:39:59 +01:00
let resp = wm.wm.protobuf.LoadUserResponse.encode(msg);
let end = resp.finish();
let r = res
.header('Server', 'v388 wangan')
.header('Content-Type', 'application/x-protobuf; revision=8053')
.header('Content-Length', end.length.toString())
.status(200);
r.send(Buffer.from(end));
return;
}
// Get the number of scratch cards for the user
let scratchSheetCount = await prisma.scratchSheet.count({
where: {
userId: user!.id
}
})
console.log("Current sheet count:", scratchSheetCount);
// If the user has no scratch sheets
if (scratchSheetCount == 0)
{
console.log("Generating first sheet ...");
// Generate a new scratch sheet for the user
await scratch.generateScratchSheet(user!.id, 1);
// Set the current scratch sheet to 1
await prisma.user.update({
where: {
id: user!.id
},
data: {
currentSheet: 1
}
});
}
// Get the user's cars
let cars = user.cars;
// If the car order array has not been created
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, and both car IDs exist
if (user)
{
// Compare both values using the car order array
let compare = user?.carOrder.indexOf(a!.carId) - user?.carOrder.indexOf(b!.carId);
// Return the comparison
return compare;
}
else // Car IDs not present in car order list
{
throw Error("UserNotFoundException");
}
});
}
else // Car order undefined
{
// We will define it here
let carOrder : number[] = [];
// Loop over all of the user cars
for(let car of user.cars)
{
// Add the car id to the list
carOrder.push(car.carId);
}
// Update the car id property for the user
await prisma.user.update({
where: {
id: user.id
},
data: {
carOrder: carOrder
}
})
}
// Get the states of the user's cars
2022-07-15 15:39:59 +01:00
let carStates = user.cars.map(e => e.state);
// Get all of the user's tickets
let tickets = await prisma.userItem.findMany({
where: {
userId: user.id,
type: 0
},
select: {
itemId: true,
category: true,
userItemId: true
2022-07-16 21:03:30 +01:00
}
})
2022-07-15 15:39:59 +01:00
let msg = {
error: wm.wm.protobuf.ErrorCode.ERR_SUCCESS,
numOfOwnedCars: user.cars.length,
spappState: wm.wm.protobuf.SmartphoneAppState.SPAPP_UNREGISTERED,
transferState: wm.wm.protobuf.TransferState.TRANSFERRED,
2022-07-15 15:39:59 +01:00
carStates,
// 5 cars in-game, 200 cars on terminal
cars: user.cars.slice(0, body.maxCars),
2022-07-15 15:39:59 +01:00
userId: user.id,
banapassportAmId: 1,
mbId: 1,
2022-07-16 15:54:01 +01:00
tutorials: user.tutorials,
2022-07-16 21:03:30 +01:00
unusedCarTickets: tickets,
2022-07-15 15:39:59 +01:00
}
if (user.userBanned) {
msg.error = wm.wm.protobuf.ErrorCode.ERR_ID_BANNED;
}
let resp = wm.wm.protobuf.LoadUserResponse.encode(msg);
let end = resp.finish();
let r = res
.header('Server', 'v388 wangan')
.header('Content-Type', 'application/x-protobuf; revision=8053')
.header('Content-Length', end.length.toString())
.status(200);
r.send(Buffer.from(end));
})
2022-07-16 20:33:21 +07:00
app.post('/method/load_drive_information', async (req, res) => {
let body = wm.wm.protobuf.LoadDriveInformationRequest.decode(req.body);
let user = await prisma.user.findFirst({
where: {
id: body.userId,
}
});
// Get all of the user's tickets
let tickets = await prisma.userItem.findMany({
where: {
userId: body.userId,
type: 0
},
select: {
itemId: true,
category: true,
userItemId: true
2022-07-16 21:03:30 +01:00
}
})
2022-07-17 15:01:48 +01:00
let notice = (Config.getConfig().notices || []);
let noticeWindows = notice.map(a => wm.wm.protobuf.NoticeEntry.NOTICE_UNUSED_1);
2022-07-12 15:50:05 +01:00
let msg = {
error: wm.wm.protobuf.ErrorCode.ERR_SUCCESS,
2022-07-17 15:01:48 +01:00
noticeWindow: noticeWindows,
noticeWindowMessage: notice,
2022-07-14 13:38:18 +07:00
transferNotice: {
needToSeeTransferred: false,
2022-07-14 10:00:03 +01:00
totalMaxiGold: 0,
numOfPorscheCars: 0,
porscheModels: [],
hasR35: false,
2022-07-14 13:38:18 +07:00
},
restrictedModels: [],
announceFeature: false,
announceMobile: false,
2022-07-16 21:03:30 +01:00
availableTickets: tickets,
2022-07-12 15:50:05 +01:00
}
let resp = wm.wm.protobuf.LoadDriveInformationResponse.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));
})
2022-07-15 15:39:59 +01:00
app.post('/method/load_time_attack_record', async (req, res) => {
2022-07-15 15:39:59 +01:00
let body = wm.wm.protobuf.LoadTimeAttackRecordRequest.decode(req.body);
let taRecordsForModel = await prisma.timeAttackRecord.findMany({
take: 100,
where: {
model: body.model,
course: body.course
},
orderBy: {
2022-07-17 10:26:40 +01:00
time: 'asc'
}
});
let taRecordsOverall = await prisma.timeAttackRecord.findMany({
take: 100,
where: {
course: body.course
},
orderBy: {
2022-07-17 10:26:40 +01:00
time: 'asc'
}
});
let taRecordPb = await prisma.timeAttackRecord.findFirst({
where: {
carId: body.carId,
course: body.course
},
orderBy: {
2022-07-17 10:26:40 +01:00
time: 'asc'
}
});
if (!taRecordPb) {
let msg = {
error: wm.wm.protobuf.ErrorCode.ERR_SUCCESS,
wholeRanking: taRecordsOverall.map(a => a.time),
modelRanking: taRecordsForModel.map(a => a.time)
};
let resp = wm.wm.protobuf.LoadTimeAttackRecordResponse.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));
return;
}
let msg = {
2022-07-14 13:38:18 +07:00
error: wm.wm.protobuf.ErrorCode.ERR_SUCCESS,
wholeRanking: taRecordsOverall.map(a => a.time),
modelRanking: taRecordsForModel.map(a => a.time),
personalBestTime: taRecordPb.time,
2022-07-17 15:14:16 +01:00
pbSection_1Time: taRecordPb.section1Time,
pbSection_2Time: taRecordPb.section2Time,
pbSection_3Time: taRecordPb.section3Time,
pbSection_4Time: taRecordPb.section4Time,
pbSection_5Time: taRecordPb.section5Time,
pbSection_6Time: taRecordPb.section6Time,
pbSection_7Time: taRecordPb.section7Time,
2022-07-15 15:39:59 +01:00
};
let resp = wm.wm.protobuf.LoadTimeAttackRecordResponse.encode(msg);
2022-07-15 15:39:59 +01:00
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 upon enter terminal
2022-07-15 15:39:59 +01:00
app.post('/method/load_terminal_information', (req, res) => {
let msg = {
error: wm.wm.protobuf.ErrorCode.ERR_SUCCESS,
prizeReceivable: false,
transferNotice: {
needToSeeTransferred: false
2022-07-14 13:38:18 +07:00
},
2022-07-15 15:39:59 +01:00
announceFeature: false,
freeScratched: true
2022-07-15 15:39:59 +01:00
}
let resp = wm.wm.protobuf.LoadDriveInformationResponse.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));
})
// Recieve user items
app.post('/method/receive_user_items', async (req, res) => {
// Get the request body
let body = wm.wm.protobuf.ReceiveUserItemsRequest.decode(req.body);
// Loop over all of the item IDs
for(let targetItem of body.targetItemIds)
{
// Get the item info for the target item
let item = await prisma.userItem.findFirst({
where: {
userItemId: targetItem
}
});
// Item is returned
if (item)
{
// Insert the item into the car items
await prisma.carItem.create({
data: {
carId: body.carId,
category: item.category,
itemId: item.itemId,
amount: 1
}
});
// Delete the accepted item
await prisma.userItem.delete({
where: {
userItemId: targetItem
}
});
}
else // No item found
{
console.log("Warning: Item " + targetItem + " not found. Item not added.");
}
}
let msg = {
error: wm.wm.protobuf.ErrorCode.ERR_SUCCESS
}
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));
})
// Load user bookmarks
2022-07-20 17:29:28 +10:00
app.post('/method/load_bookmarks', async (req, res) => {
2022-07-20 17:29:28 +10:00
// 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({
2022-07-20 17:29:28 +10:00
where: {
id: Number(body.userId)
2022-07-20 17:29:28 +10:00
}
});
// Car bookmarks placeholder
let cars : Car[] = [];
// User is not null
if (user)
2022-07-20 17:29:28 +10:00
{
// Loop over the bookmarked cars
for (let carId of user.bookmarks)
2022-07-20 17:29:28 +10:00
{
// 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,
2022-07-20 17:29:28 +10:00
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));
})
2022-07-20 17:29:28 +10:00
// 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({
2022-07-20 17:29:28 +10:00
where: {
id: body.userId
},
data: {
bookmarks: body.cars
2022-07-20 17:29:28 +10:00
}
})
2022-07-20 17:29:28 +10:00
// 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 completed tutorials
let storedTutorials = user!.tutorials;
body.confirmedTutorials.forEach(
(idx) => storedTutorials[idx] = true
);
await prisma.user.update({
where: {
id: body.userId
},
data: {
tutorials: storedTutorials
}
});
// If the car order was modified
// Update the car order in the table
if (body.carOrder.length > 0)
{
await prisma.user.update({
where: {
id: body.userId
},
data: {
carOrder: body.carOrder
}
});
}
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
2022-07-20 17:29:28 +10:00
app.post('/method/load_scratch_information', async (req, res) => {
// Get the information from the request
let body = wm.wm.protobuf.LoadScratchInformationRequest.decode(req.body);
// Get the current date/time (unix epoch)
let date = Math.floor(new Date().getTime() / 1000)
2022-07-20 17:29:28 +10:00
// Scratch sheet proto
let scratchSheetProto : wm.wm.protobuf.ScratchSheet[] = [];
2022-07-20 17:29:28 +10:00
// Current scratch sheet (default: Sheet 1 (R2))
let currentSheet = 1;
2022-07-20 17:29:28 +10:00
// User has scratched already (default: True)
let scratched = 1;
2022-07-20 17:29:28 +10:00
// Get the scratch sheet configuration
let scratchEnabled = Config.getConfig().gameOptions.scratchEnabled;
2022-07-20 17:29:28 +10:00
// If the scratch game is enabled
if (scratchEnabled)
{
// Get all of the info for the user
let user = await prisma.user.findFirst({
2022-07-20 17:29:28 +10:00
where: {
id: body.userId
2022-07-20 17:29:28 +10:00
}
});
// Get the updated scratch sheet proto
scratchSheetProto = await scratch.getScratchSheetProto(body.userId);
2022-07-20 17:29:28 +10:00
// User is defined
if (user)
2022-07-20 17:29:28 +10:00
{
// Update the currentSheet, scratched values
currentSheet = user.currentSheet;
2022-07-20 17:29:28 +10:00
// If unlimited scratches is set
if (scratchEnabled == 2)
{
// User can scratch again
scratched = 0;
}
else // Otherwise, daily scratches
{
// If a day has passed, allow the user to scratch again
scratched = scratch.dayPassed(
new Date(date*1000), // Todays date
new Date(user.lastScratched*1000) // Last Scratched date
);
}
}
2022-07-20 17:29:28 +10:00
}
// Owned user items list
let ownedUserItems : wm.wm.protobuf.UserItem[] = [];
// Get the user items list
ownedUserItems = await scratch.getScratchItemList(body.userId, date);
let msg = {
error: wm.wm.protobuf.ErrorCode.ERR_SUCCESS,
scratchSheets: scratchSheetProto,
currentSheet: currentSheet,
numOfScratched: scratched,
ownedUserItems: ownedUserItems
}
let resp = wm.wm.protobuf.LoadScratchInformationResponse.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));
});
// Change terminal scratch page
app.post('/method/turn_scratch_sheet', async (req, res) => {
let body = wm.wm.protobuf.TurnScratchSheetRequest.decode(req.body);
// Update the active scratch sheet
await prisma.user.update({
where: {
id: body.userId
},
data: {
currentSheet: body.targetSheet
}
});
2022-07-15 15:39:59 +01:00
let msg = {
error: wm.wm.protobuf.ErrorCode.ERR_SUCCESS,
}
let resp = wm.wm.protobuf.TurnScratchSheetResponse.encode(msg);
2022-07-15 15:39:59 +01:00
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));
})
2022-07-15 15:39:59 +01:00
// Update scratch sheet
2022-07-20 17:29:28 +10:00
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 the current date/time (unix epoch)
let date = Math.floor(new Date().getTime() / 1000)
// Get all of the info for the user
let user = await prisma.user.findFirst({
where: {
id: body.userId
}
});
2022-07-20 17:29:28 +10:00
// Get all of the scratch sheets for the user
let scratchSheets = await prisma.scratchSheet.findMany({
where: {
userId: body.userId
},
include: {
squares: {
orderBy: {
id: 'asc'
}
}
2022-07-20 17:29:28 +10:00
}
})
// Get the target scratch sheet (subtract one for zero-index)
let scratchSheet = scratchSheets[Number(body.targetSheet)-1];
2022-07-20 17:29:28 +10:00
// Get all of the squares for the scratch sheet
let scratchSquares = await prisma.scratchSquare.findMany({
where: {
sheetId: scratchSheet.id
},
orderBy: {
id: 'asc'
2022-07-20 17:29:28 +10:00
}
});
// Get the target scratch square
let scratchSquare = scratchSquares[Number(body.targetSquare)];
// Get the item from the scratch square
let earnedItem = wm.wm.protobuf.UserItem.create({
category: scratchSquare.category,
itemId: scratchSquare.itemId,
earnedAt: date
2022-07-20 17:29:28 +10:00
});
try // Attempt to update scratch sheet
2022-07-20 17:29:28 +10:00
{
// Add the item to the user's scratch items list
await prisma.userItem.create({
data: {
userId: body.userId,
category: scratchSquare.category,
itemId: scratchSquare.itemId,
type: 1, // Scratch item
earnedAt: date
}
});
// Update the revealed scratch square
await prisma.scratchSquare.update({
where: {
id: scratchSquare.id
},
data: {
earned: true
}
});
2022-07-20 17:29:28 +10:00
// Update the last scratched timestamp
await prisma.user.update({
where: {
id: body.userId
},
data: {
lastScratched: date
}
});
// If the box we uncovered is the car
if (scratchSquare.category == 201)
2022-07-20 17:29:28 +10:00
{
// Generate a new scratch sheet for the user
await scratch.generateScratchSheet(body.userId, body.targetSheet + 1)
}
}
catch (error) // Failed to update scratch sheet
{
console.log("Failed to update scratch sheet! Reason:", error);
2022-07-20 17:29:28 +10:00
}
// Get the updated content for the scratch sheet
// Scratch sheet proto
let scratchSheetProto : wm.wm.protobuf.ScratchSheet[] = []
// Get the updated scratch sheet proto
scratchSheetProto = await scratch.getScratchSheetProto(body.userId);
2022-07-20 17:29:28 +10:00
let msg = {
error: wm.wm.protobuf.ErrorCode.ERR_SUCCESS,
scratchSheets : scratchSheetProto,
2022-07-20 17:29:28 +10:00
currentSheet: body.targetSheet,
numOfScratched: 1,
earnedItem: earnedItem
2022-07-20 17:29:28 +10:00
}
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));
})
2022-07-15 15:39:59 +01:00
app.post('/method/update_car', async (req, res) => {
let body = wm.wm.protobuf.UpdateCarRequest.decode(req.body);
let car = await prisma.car.findFirst({
where: {
2022-07-15 16:04:44 +01:00
carId: body.carId
2022-07-15 15:39:59 +01:00
},
include: {
settings: true
}
});
// Update the car info
await prisma.car.update({
where: {
carId: body.carId
},
data: {
// Car components customisable in terminal
customColor: body.car?.customColor || 0,
wheel: body.car?.wheel || 0,
aero: body.car?.aero || 0,
bonnet: body.car?.bonnet || 0,
wing: body.car?.wing || 0,
mirror: body.car?.mirror || 0,
neon: body.car?.neon || 0,
trunk: body.car?.trunk || 0,
plate: body.car?.plate || 0,
plateColor: body.car?.plateColor || 0,
windowSticker: body.car?.windowSticker || false,
windowStickerString: body.car?.windowStickerString || '',
windowStickerFont: body.car?.windowStickerFont || 0,
rivalMarker: body.car?.rivalMarker || 0,
aura: body.car?.aura || 0,
auraMotif: body.car?.auraMotif || 0
}
})
// Update the car settings
2022-07-15 15:39:59 +01:00
await prisma.carSettings.update({
where: {
dbId: car?.carSettingsDbId,
},
data: {
2022-07-15 15:39:59 +01:00
...body.setting
}
});
// Get car item
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
}
});
}
}
2022-07-15 15:39:59 +01:00
let msg = {
error: wm.wm.protobuf.ErrorCode.ERR_SUCCESS,
2022-07-14 13:38:18 +07:00
}
2022-07-15 15:39:59 +01:00
let resp = wm.wm.protobuf.UpdateCarResponse.encode(msg);
2022-07-14 13:38:18 +07:00
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));
})
2022-07-15 15:39:59 +01:00
2022-07-14 13:38:18 +07:00
app.post('/method/load_stamp_target', (req, res) => {
let msg = {
error: wm.wm.protobuf.ErrorCode.ERR_SUCCESS,
}
let resp = wm.wm.protobuf.LoadStampTargetResponse.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));
})
2022-07-15 15:39:59 +01:00
app.post('/method/create_car', async (req, res) => {
// Get the create car request body
2022-07-15 15:39:59 +01:00
let body = wm.wm.protobuf.CreateCarRequest.decode(req.body);
// Get the current date/time (unix epoch)
let date = Math.floor(new Date().getTime() / 1000)
// Retrieve user from card chip / user id
2022-07-15 15:39:59 +01:00
let user: User | null;
// User ID provided, use that
2022-07-15 15:39:59 +01:00
if (body.userId) {
user = await prisma.user.findFirst({
where: {
id: body.userId
},
});
} else { // No user id, use card chip
2022-07-15 15:39:59 +01:00
user = await prisma.user.findFirst({
where: {
chipId: body.cardChipId,
accessCode: body.accessCode
},
})
}
// User not found, terminate
2022-07-15 15:39:59 +01:00
if (!user) throw new Error();
// Generate blank car settings object
2022-07-15 15:39:59 +01:00
let settings = await prisma.carSettings.create({
data: {}
});
// Generate blank car state object
2022-07-15 15:39:59 +01:00
let state = await prisma.carState.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)
{
2022-07-16 21:03:30 +01:00
console.log(`Item used - ID ${body.userItemId}`);
// Remove the user item from the database
2022-07-16 21:03:30 +01:00
let item = await prisma.userItem.delete({
where: {
userItemId: body.userItemId
2022-07-16 21:03:30 +01:00
}
});
console.log('Item deleted!');
switch(item.category)
2022-07-16 21:03:30 +01:00
{
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}`);
2022-07-16 21:03:30 +01:00
}
// 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;
}
// 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;
}
}
// Default car values
2022-07-16 21:03:30 +01:00
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,
2022-07-18 10:13:31 +01:00
carStateDbId: state.dbId,
2022-07-18 10:50:20 +01:00
regionId: body.car.regionId!,
lastPlayedAt: date,
2022-07-16 21:03:30 +01:00
};
// 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 = {
stClearBits: 0,
stLoseBits: 0,
stClearCount: 20,
stClearDivCount: 1,
stConsecutiveWins: 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
};
2022-07-16 21:03:30 +01:00
}
// Insert the car into the database
2022-07-15 15:39:59 +01:00
let car = await prisma.car.create({
data: {
2022-07-16 21:03:30 +01:00
...carInsert,
2022-07-17 17:15:24 +01:00
...additionalInsert,
2022-07-15 15:39:59 +01:00
}
2022-07-16 21:03:30 +01:00
});
// Get the user's current car order
let carOrder = user.carOrder;
// Add the new car to the front of the id
carOrder.unshift(car.carId);
// Add the car to the front of the order
await prisma.user.update({
where: {
id: user.id
},
data: {
carOrder: carOrder
}
});
2022-07-15 16:04:44 +01:00
console.log(`Created new car ${car.name} with ID ${car.carId}`);
2022-07-12 15:50:05 +01:00
let msg = {
error: wm.wm.protobuf.ErrorCode.ERR_SUCCESS,
2022-07-15 16:04:44 +01:00
carId: car.carId,
2022-07-16 21:03:30 +01:00
car,
...carInsert,
...additionalInsert
2022-07-12 15:50:05 +01:00
}
let resp = wm.wm.protobuf.CreateCarResponse.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));
})
2022-07-15 15:39:59 +01:00
2022-07-15 16:04:44 +01:00
app.post('/method/load_car', async (req, res) => {
let body = wm.wm.protobuf.LoadCarRequest.decode(req.body);
let car = await prisma.car.findFirst({
where: {
carId: body.carId
},
include: {
settings: true,
items: true,
}
});
2022-07-18 13:19:06 +01:00
// This is fucking terrible
let longLoseBits = Long.fromString(car!.stLoseBits.toString());
2022-07-15 16:04:44 +01:00
let msg = {
error: wm.wm.protobuf.ErrorCode.ERR_SUCCESS,
car: {
2022-07-16 21:03:30 +01:00
...car!
2022-07-15 16:04:44 +01:00
},
2022-07-16 21:03:30 +01:00
tuningPoint: car!.tuningPoints,
setting: car!.settings,
vsStarCountMax: car!.vsStarCount,
2022-07-15 16:04:44 +01:00
rgPreviousVersionPlayCount: 0,
2022-07-16 21:03:30 +01:00
stCompleted_100Episodes: car!.stCompleted100Episodes,
2022-07-15 16:04:44 +01:00
auraMotifAutoChange: false,
screenshotCount: 0,
transferred: false,
2022-07-18 13:19:06 +01:00
...car!,
stLoseBits: longLoseBits,
ownedItems: car!.items,
lastPlayedAt: car!.lastPlayedAt
2022-07-15 16:04:44 +01:00
};
let resp = wm.wm.protobuf.LoadCarResponse.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/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
}
});
// 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 = {
2022-07-12 15:50:05 +01:00
error: wm.wm.protobuf.ErrorCode.ERR_SUCCESS,
taRecords: ta_records,
taRankingUpdatedAt: 1,
2022-07-15 15:39:59 +01:00
ghostBattleCount: 0,
ghostBattleWinCount: 0,
stampSheetCount: 0,
2022-07-12 15:50:05 +01:00
}
2022-07-12 15:50:05 +01:00
let resp = wm.wm.protobuf.LoadGameHistoryResponse.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));
})
2022-07-15 15:39:59 +01:00
2022-07-12 15:50:05 +01:00
app.post('/method/update_user_session', (req, res) => {
// Get the request body
// let body = wm.wm.protobuf.UpdateUserSessionRequest.decode(req.body);
2022-07-12 15:50:05 +01:00
let msg = {
error: wm.wm.protobuf.ErrorCode.ERR_SUCCESS,
}
let resp = wm.wm.protobuf.UpdateUserSessionResponse.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/load_ghost_battle_info', async (req, res) => {
let body = wm.wm.protobuf.LoadGhostBattleInfoRequest.decode(req.body);
//---------------MAYBE NOT CORRECT---------------
let msg = {
error: wm.wm.protobuf.ErrorCode.ERR_SUCCESS,
stampSheetCount: 100,
};
//-----------------------------------------------
let resp = wm.wm.protobuf.LoadGhostBattleInfoResponse.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/search_cars_by_level', async (req, res) => {
let body = wm.wm.protobuf.SearchCarsByLevelRequest.decode(req.body);
//---------------MAYBE NOT CORRECT---------------
let rampVal = 0;
let pathVal = 0;
if(body.area === 0){ //GID_RUNAREA_C1
rampVal = 0;
pathVal = Math.floor(Math.random() * 10);
}
else if(body.area === 1){ //GID_RUNAREA_RING
rampVal = 0;
pathVal = Math.floor(Math.random() * 6) + 10;
}
else if(body.area === 2){ //GID_RUNAREA_SUBTOKYO_3_4
rampVal = 0;
pathVal = Math.floor(Math.random() * 2) + 16;
}
else if(body.area === 3){ //GID_RUNAREA_SUBTOKYO_5
rampVal = 0;
pathVal = Math.floor(Math.random() * 2) + 18;
}
else if(body.area === 4){ //GID_RUNAREA_WANGAN
rampVal = 0;
pathVal = Math.floor(Math.random() * 7) + 20;
}
else if(body.area === 5){ //GID_RUNAREA_K1
rampVal = 0;
pathVal = Math.floor(Math.random() * 7) + 27;
}
else if(body.area === 6){ //GID_RUNAREA_YAESU
rampVal = 0;
pathVal = Math.floor(Math.random() * 4) + 34;
}
else if(body.area === 7){ //GID_RUNAREA_YOKOHAMA
rampVal = 0;
pathVal = Math.floor(Math.random() * 11) + 38;
}
else if(body.area === 8){ //GID_RUNAREA_NAGOYA
rampVal = 0;
pathVal = 49;
}
else if(body.area === 9){ //GID_RUNAREA_OSAKA
rampVal = 0;
pathVal = Math.floor(Math.random() * 4) + 50;
}
else if(body.area === 10){ //GID_RUNAREA_KOBE
rampVal = 0;
pathVal = Math.floor(Math.random() * 2) + 54;
}
else if(body.area === 11){ //GID_RUNAREA_FUKUOKA
rampVal = 0;
pathVal = Math.floor(Math.random() * 4) + 58;
}
else if(body.area === 12){ //GID_RUNAREA_HAKONE
rampVal = 0;
pathVal = Math.floor(Math.random() * 2) + 62;
}
else if(body.area === 13){ //GID_RUNAREA_TURNPIKE
rampVal = 0;
pathVal = Math.floor(Math.random() * 2) + 64;
}
//14 - 16 is dummy area
else if(body.area === 17){ //GID_RUNAREA_C1_CLOSED
rampVal = 0;
pathVal = Math.floor(Math.random() * 10); //probably not correct
}
else if(body.area === 18){ //GID_RUNAREA_HIROSHIMA
rampVal = 0;
pathVal = Math.floor(Math.random() * 2) + 56;
}
let msg = {
error: wm.wm.protobuf.ErrorCode.ERR_SUCCESS,
ramp: rampVal,
path: pathVal,
selectionMethod: 2,
};
//-----------------------------------------------
let resp = wm.wm.protobuf.SearchCarsByLevelResponse.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/load_ghost_drive_data', async (req, res) => {
let body = wm.wm.protobuf.LoadGhostDriveDataRequest.decode(req.body);
2022-07-22 18:09:18 +07:00
//---------------MAYBE NOT CORRECT---------------
let msg = {
error: wm.wm.protobuf.ErrorCode.ERR_SUCCESS,
path: body.path
};
//-----------------------------------------------
let resp = wm.wm.protobuf.LoadGhostDriveDataResponse.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));
})
2022-07-12 15:50:05 +01:00
}
2022-07-14 13:38:18 +07:00
}