1
0
mirror of synced 2025-02-11 16:43:00 +01:00
Bayshore/src/modules/startup.ts

605 lines
24 KiB
TypeScript
Raw Normal View History

2022-07-11 09:15:30 +01:00
import { Application } from "express";
import {Module} from "module";
import { Config } from "../config";
2022-08-15 10:47:34 +07:00
import { prisma } from "..";
// Import Proto
import * as wm from "../wmmt/wm.proto";
2022-07-27 18:38:50 +07:00
import * as wmsrv from "../wmmt/service.proto";
2022-08-15 10:47:34 +07:00
// Import Util
import * as common from "../util/common";
2022-07-11 09:15:30 +01:00
export default class StartupModule extends Module {
register(app: Application): void {
2022-08-15 10:47:34 +07:00
// Register system info upon booting
app.post('/method/register_system_info', async (req, res) => {
// Get the request body for the load stamp target request
let body = wm.wm.protobuf.RegisterSystemInfoRequest.decode(req.body);
// Get current date
let date = Math.floor(new Date().getTime() / 1000);
2022-08-15 18:30:50 +07:00
// Get current / previous active OCM Event
2022-08-15 10:47:34 +07:00
let ocmEventDate = await prisma.oCMEvent.findFirst({
2022-08-15 18:48:54 +07:00
where: {
OR: [
{
// qualifyingPeriodStartAt is less than current date
qualifyingPeriodStartAt: { lte: date },
// qualifyingPeriodCloseAt is greater than current date
qualifyingPeriodCloseAt: { gte: date },
},
{
// competitionStartAt is less than current date
competitionStartAt: { lte: date },
// competitionCloseAt is greater than current date
competitionCloseAt: { gte: date },
},
{
// competitionCloseAt is less than current date
competitionCloseAt: { lte: date },
// competitionEndAt is greater than current date
competitionEndAt: {gte: date },
}
],
},
2022-08-15 16:37:19 +07:00
orderBy: [
{
dbId: 'desc'
},
{
competitionEndAt: 'desc',
},
],
2022-08-15 10:47:34 +07:00
});
2022-08-15 18:48:54 +07:00
if(!(ocmEventDate))
{
ocmEventDate = await prisma.oCMEvent.findFirst({
orderBy: [
{
dbId: 'desc'
},
{
competitionEndAt: 'desc',
},
],
});
}
2022-08-15 10:47:34 +07:00
// Declare GhostCompetitionSchedule
let compeSch;
2022-08-15 16:37:19 +07:00
if(ocmEventDate)
{
let pastDay = date - ocmEventDate.competitionEndAt
2022-08-15 10:47:34 +07:00
2022-08-15 16:37:19 +07:00
if(pastDay < 604800)
{
// Creating GhostCompetitionSchedule
compeSch = wm.wm.protobuf.GhostCompetitionSchedule.create({
2022-08-15 10:47:34 +07:00
2022-08-15 16:37:19 +07:00
// OCM Competition ID (1 = C1 (Round 16), 4 = Nagoya (Round 19), 8 = Hiroshima (Round 21))
competitionId: ocmEventDate.competitionId,
2022-08-15 10:47:34 +07:00
2022-08-15 16:37:19 +07:00
// OCM Qualifying Start Timestamp
qualifyingPeriodStartAt: ocmEventDate.qualifyingPeriodStartAt,
2022-08-15 10:47:34 +07:00
2022-08-15 16:37:19 +07:00
// OCM Qualifying Close Timestamp
qualifyingPeriodCloseAt: ocmEventDate.qualifyingPeriodCloseAt,
2022-08-15 10:47:34 +07:00
2022-08-15 16:37:19 +07:00
// OCM Competition (Main Draw) Start Timestamp
competitionStartAt: ocmEventDate.competitionStartAt,
2022-08-15 10:47:34 +07:00
2022-08-15 16:37:19 +07:00
// OCM Competition (Main Draw) Close Timestamp
competitionCloseAt: ocmEventDate.competitionCloseAt,
2022-08-15 10:47:34 +07:00
2022-08-15 16:37:19 +07:00
// OCM Competition (Main Draw) End Timestamp
competitionEndAt: ocmEventDate.competitionEndAt,
2022-08-15 10:47:34 +07:00
2022-08-15 16:37:19 +07:00
// idk what this is
lengthOfPeriod: ocmEventDate.lengthOfPeriod,
2022-08-15 10:47:34 +07:00
2022-08-15 16:37:19 +07:00
// idk what this is
lengthOfInterval: ocmEventDate.lengthOfInterval,
2022-08-15 10:47:34 +07:00
2022-08-15 16:37:19 +07:00
// Area for the event (GID_RUNAREA_*, 8 is GID_RUNAREA_NAGOYA)
area: ocmEventDate.area,
// idk what this is
minigamePatternId: ocmEventDate.minigamePatternId
});
}
2022-08-15 10:47:34 +07:00
}
// Response data
2022-07-11 11:45:36 +01:00
let msg = {
error: wm.wm.protobuf.ErrorCode.ERR_SUCCESS,
2022-08-15 10:47:34 +07:00
regionId: body.allnetRegion0,
placeId: body.regionName0,
allowedClientLogTypes: [],
ghostSelectionMinRedoWait: 30,
ghostSelectionMaxRedoWait: 4000,
2022-07-11 11:45:36 +01:00
featureVersion: {
version: 9,
2022-07-11 11:45:36 +01:00
year: 2022,
month: 7,
pluses: 0,
releaseAt: 0 // idk what this is
2022-08-15 10:47:34 +07:00
},
competitionSchedule: compeSch || null // OCM Event Available or not
2022-07-11 11:45:36 +01:00
}
2022-08-15 10:47:34 +07:00
// Encode the response
let message = wm.wm.protobuf.RegisterSystemInfoResponse.encode(msg);
// Send the response to the client
common.sendResponse(message, res);
})
2022-08-15 10:47:34 +07:00
// Place List
app.get('/resource/place_list', (req, res) => {
console.log('place list');
2022-08-15 10:47:34 +07:00
// Empty list of place records
let places: wm.wm.protobuf.Place[] = [];
2022-08-15 10:47:34 +07:00
// Response data
places.push(new wm.wm.protobuf.Place({
2022-07-11 12:29:28 +01:00
placeId: "JPN0123",
regionId: 1,
shopName: Config.getConfig().shopName,
country: "JPN"
}));
2022-08-15 10:47:34 +07:00
// Encode the response
let message = wm.wm.protobuf.PlaceList.encode({places});
// Send the response to the client
common.sendResponse(message, res);
2022-07-11 11:45:36 +01:00
})
2022-08-15 10:47:34 +07:00
// Get Ranking data for attract screen (TA, Ghost, VS)
app.get('/resource/ranking', async (req, res) => {
console.log('ranking');
2022-08-15 10:47:34 +07:00
// Empty list of all ranking records (Combination of TA, VS Stars, and Ghost Battle Win)
2022-07-27 18:38:50 +07:00
let lists: wmsrv.wm.protobuf.Ranking.List[] = [];
// Get TA Ranking
2022-08-15 10:47:34 +07:00
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'
2022-07-28 12:25:59 +07:00
},
2022-08-15 10:47:34 +07:00
take: 10, // Take top 10
});
2022-08-15 10:47:34 +07:00
// 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
}
});
2022-08-15 10:47:34 +07:00
// 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,
2022-08-15 10:47:34 +07:00
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
}));
}
2022-08-15 10:47:34 +07:00
// 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
}
2022-08-15 10:47:34 +07:00
// Push the data to the ranking data
list_ta.push(wmsrv.wm.protobuf.Ranking.Entry.create({
carId: 0,
rank: 0,
result: resultTime,
name: '',
2022-08-15 10:47:34 +07:00
regionId: 1, // Hokkaido
model: Math.floor(Math.random() * 50), // Randomizing Car data
visualModel: Math.floor(Math.random() * 100), // Randomizing Car data
defaultColor: 0,
tunePower: 0,
tuneHandling: 0,
2022-08-15 10:47:34 +07:00
title: 'Wangan Beginner', // 湾岸の新人
level: 0 // N
}));
}
}
lists.push(new wmsrv.wm.protobuf.Ranking.List({
rankingType: i, // RANKING_TA_*AREA*
topRecords: list_ta
}));
}
2022-08-15 10:47:34 +07:00
// There is no user's TA record for certain area
else{
// Empty list of ranking records for time attack
let list_ta: wmsrv.wm.protobuf.Ranking.Entry[] = [];
// Generate the top 10 TA time data
for(let j=0; j<11; j++){
let resulttime = 599999; // 9:59:999 time
// GID_TACOURSE_TOKYOALL & GID_TACOURSE_KANAGAWAALL area
if(i === 22 || i === 23){
resulttime = 1199999 // 19:59:999 time
}
2022-08-15 10:47:34 +07:00
// Push the data to the ranking data
list_ta.push(wmsrv.wm.protobuf.Ranking.Entry.create({
carId: 0,
rank: 0,
result: resulttime,
name: '',
2022-08-15 10:47:34 +07:00
regionId: 1, // Hokkaido
model: Math.floor(Math.random() * 50), // Randomizing Car data
visualModel: Math.floor(Math.random() * 100), // Randomizing Car data
defaultColor: 0,
tunePower: 0,
tuneHandling: 0,
2022-08-15 10:47:34 +07:00
title: 'Wangan Beginner', // 湾岸の新人
level: 0 // N
}));
}
2022-08-15 10:47:34 +07:00
// Push the certain area ranking data to the list
lists.push(new wmsrv.wm.protobuf.Ranking.List({
2022-07-27 18:38:50 +07:00
rankingType: i, // RANKING_TA_*AREA*
2022-08-15 10:47:34 +07:00
topRecords: list_ta // Top 10 TA time record data
}));
}
}
// Get VS Star Ranking
2022-08-15 10:47:34 +07:00
// Get the user's VS Stars data
let car_vs = await prisma.car.findMany({
orderBy: {
vsStarCount: 'desc'
2022-07-28 12:25:59 +07:00
},
2022-08-15 10:47:34 +07:00
take: 20, // Take top 20
});
2022-08-15 10:47:34 +07:00
// 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
}));
}
2022-08-15 10:47:34 +07:00
// If the VS stars record by user is less than 20 user
if(car_vs.length < 20){
// Take the remaining unfilled
for(let j=car_vs.length; j<21; j++){
// Push the data to the ranking data
list_vs.push(wmsrv.wm.protobuf.Ranking.Entry.create({
carId: 0,
rank: 0,
result: 0,
name: '',
2022-08-15 10:47:34 +07:00
regionId: 1, // Hokkaido
model: Math.floor(Math.random() * 50), // Randomizing Car data
visualModel: Math.floor(Math.random() * 100), // Randomizing Car data
defaultColor: 0,
tunePower: 0,
tuneHandling: 0,
2022-08-15 10:47:34 +07:00
title: 'Wangan Beginner', // 湾岸の新人
level: 0 // N
}));
}
}
2022-08-15 10:47:34 +07:00
// Push the data
2022-07-27 18:38:50 +07:00
lists.push(new wmsrv.wm.protobuf.Ranking.List({
rankingType: 100, // RANKING_VS_STAR
2022-08-15 10:47:34 +07:00
topRecords: list_vs // Top 20 VS stars record data
}));
2022-07-27 18:38:50 +07:00
// Get Ghost Defeated Ranking
2022-08-15 10:47:34 +07:00
// Get the user's Ghost Win data
let car_ghost = await prisma.car.findMany({
orderBy: {
rgWinCount: 'desc'
2022-07-28 12:25:59 +07:00
},
2022-08-15 10:47:34 +07:00
take: 20, // Take top 20
});
2022-08-15 10:47:34 +07:00
// 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
}));
}
2022-08-15 10:47:34 +07:00
// If the Ghost Win record by user is less than 20 user
if(car_ghost.length < 20){
// Take the remaining unfilled
for(let j=car_ghost.length; j<21; j++){
// Push the data to the ranking data
list_ghost.push(wmsrv.wm.protobuf.Ranking.Entry.create({
carId: 0,
rank: 0,
result: 0,
name: '',
2022-08-15 10:47:34 +07:00
regionId: 1, // Hokkaido
model: Math.floor(Math.random() * 50), // Randomizing Car data
visualModel: Math.floor(Math.random() * 100), // Randomizing Car data
defaultColor: 0,
tunePower: 0,
tuneHandling: 0,
2022-08-15 10:47:34 +07:00
title: 'Wangan Beginner', // 湾岸の新人
level: 0 // N
}));
}
}
2022-08-15 10:47:34 +07:00
// Push the data
2022-07-27 18:38:50 +07:00
lists.push(new wmsrv.wm.protobuf.Ranking.List({
rankingType: 101, // RANKING_GHOST_DEFEATED_COUNT
2022-08-15 10:47:34 +07:00
topRecords: list_ghost // Top 20 Ghost Win record data
}));
2022-08-15 10:47:34 +07:00
// Encode the response
let message = wmsrv.wm.protobuf.Ranking.encode({lists});
// Send the response to the client
common.sendResponse(message, res);
})
2022-08-15 10:47:34 +07:00
// Ping
app.post('/method/ping', (req, res) => {
console.log('ping');
let body = wm.wm.protobuf.PingRequest.decode(req.body);
2022-08-15 10:47:34 +07:00
// Response data
let ping = {
error: wm.wm.protobuf.ErrorCode.ERR_SUCCESS,
pong: body.ping || 1
};
2022-08-15 10:47:34 +07:00
// Encode the response
let message = wm.wm.protobuf.PingResponse.encode(ping);
// Send the response to the client
common.sendResponse(message, res);
})
2022-07-28 12:25:59 +07:00
2022-08-15 10:47:34 +07:00
// Crown List for attract screen and Crown Ghost Battle mode
2022-07-28 12:25:59 +07:00
app.get('/resource/crown_list', async (req, res) => {
console.log('crown_list');
2022-08-15 10:47:34 +07:00
// Empty list of crown records
let list_crown: wmsrv.wm.protobuf.Crown[] = [];
// Get the crown holder data
let car_crown = await prisma.carCrown.findMany({
2022-07-29 16:13:21 +07:00
orderBy: {
area: 'asc'
}
});
2022-08-15 10:47:34 +07:00
// Crown holder data available
if(car_crown.length !== 0){
2022-07-29 16:13:21 +07:00
let counter = 0;
2022-08-15 10:47:34 +07:00
// Loop GID_RUNAREA
for(let i=0; i<19; i++){
// 14 - 16 are dummy area, 17 is C1 Closed
if(i >= 14){
i = 18; // GID_RUNAREA_HIROSHIMA
2022-07-30 19:21:26 +07:00
}
2022-08-15 10:47:34 +07:00
// Crown holder for certain area available
if(car_crown[counter].area === i){
// Get user's data
2022-07-29 16:13:21 +07:00
let car = await prisma.car.findFirst({
where: {
carId: car_crown[counter].carId
},
include: {
gtWing: true
}
});
2022-08-15 10:47:34 +07:00
// If regionId is 0 or not set, game will crash after defeating the ghost
if(car!.regionId === 0)
{
/* Region Id
01 = Hokkaido
02 = Aomori
03 = Iwate
04 = Miyagi
05 = Akita
06 = Yamagata
07 = Fukushima
08 = Ibaraki
09 = Tochigi
10 = Gunma
11 = Saitama
12 = Chiba
13 = Tokyo
19 = Yamanashi
*/
car!.regionId = i + 1; // Change car region id
2022-07-30 19:22:44 +07:00
}
2022-08-15 10:47:34 +07:00
// Set the tunePower used when capturing ghost crown
car!.tunePower = car_crown[counter].tunePower;
// Set the tunePower used when capturing ghost crown
car!.tuneHandling = car_crown[counter].tuneHandling;
// Error handling if played At timestamp value is current date and timestamp is bigger than 9 July 2022 (using GMT+7 timestamp)
if(car_crown[counter].playedAt !== 0 && car_crown[counter].playedAt >= 1657299600)
2022-08-09 08:49:12 +07:00
{
// 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;
}
2022-08-15 10:47:34 +07:00
// 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)
2022-08-09 08:49:12 +07:00
{
2022-08-15 10:47:34 +07:00
// Acquired crown timestamp become 9 July 2022 (using GMT+7 timestamp)
car!.lastPlayedAt = 1657299600;
2022-08-09 08:49:12 +07:00
2022-08-15 10:47:34 +07:00
// Acquired crown timestamp become 9 July 2022 (using GMT+7 timestamp)
car_crown[counter].playedAt = 1657299600;
2022-08-09 08:49:12 +07:00
}
2022-08-15 10:47:34 +07:00
let playedPlace = wm.wm.protobuf.Place.create({
placeId: 'JPN0123',
shopName: Config.getConfig().shopName,
regionId: 18,
country: 'JPN'
});
// Push the car data to the crown holder data
list_crown.push(wmsrv.wm.protobuf.Crown.create({
2022-07-29 16:13:21 +07:00
carId: car_crown[counter].carId,
2022-07-30 19:21:26 +07:00
area: car_crown[counter].area, // GID_RUNAREA_C1 - GID_RUNAREA_TURNPIKE & GID_RUNAREA_HIROSHIMA
2022-07-29 16:13:21 +07:00
unlockAt: car_crown[counter].playedAt,
2022-08-15 10:47:34 +07:00
car: {
...car!,
lastPlayedPlace: playedPlace
}
2022-07-29 16:13:21 +07:00
}));
if(counter < car_crown.length-1){
counter++;
}
}
2022-08-15 10:47:34 +07:00
// Crown holder for certain area not available
else{
// Push the default data by the game to the crown holder data
list_crown.push(wmsrv.wm.protobuf.Crown.create({
2022-07-29 16:13:21 +07:00
carId: i,
2022-07-30 19:21:26 +07:00
area: i, // GID_RUNAREA_C1 - GID_RUNAREA_TURNPIKE & GID_RUNAREA_HIROSHIMA
2022-07-28 14:51:53 +07:00
unlockAt: 0,
}));
}
2022-07-28 12:25:59 +07:00
}
}
2022-08-15 10:47:34 +07:00
// There is no user's crown holder data available
else{
// Loop GID_RUNAREA
for(let i=0; i<19; i++){
// 14 - 16 are dummy area, 17 is C1 Closed
if(i >= 14){
i = 18; // GID_RUNAREA_HIROSHIMA
}
2022-08-15 10:47:34 +07:00
// Push the default data by the game to the crown holder data
list_crown.push(wmsrv.wm.protobuf.Crown.create({
2022-07-28 12:25:59 +07:00
carId: i,
area: i, // GID_RUNAREA_C1 - GID_RUNAREA_TURNPIKE & GID_RUNAREA_HIROSHIMA
2022-07-28 12:25:59 +07:00
unlockAt: 0,
}));
}
2022-07-29 16:13:21 +07:00
}
2022-07-28 12:25:59 +07:00
2022-08-15 10:47:34 +07:00
// Response data
2022-07-28 12:25:59 +07:00
let msg = {
crowns: list_crown
};
2022-08-15 10:47:34 +07:00
// Encode the response
let message = wmsrv.wm.protobuf.CrownList.encode(msg);
// Send the response to the client
common.sendResponse(message, res);
2022-07-28 12:25:59 +07:00
})
2022-07-11 09:15:30 +01:00
}
}