1
0
mirror of synced 2024-12-04 11:07:58 +01:00

merge to master branch

This commit is contained in:
Shiroi Kitsu 2023-01-17 22:19:21 +07:00
parent a6af839596
commit 1d3a8e6880
24 changed files with 247 additions and 158 deletions

3
.gitignore vendored
View File

@ -8,4 +8,5 @@ cert.pfx
key.pem key.pem
config.json config.json
package-lock.json package-lock.json
ecosystem.config.js ecosystem.config.js
static/*

View File

@ -1,10 +1,6 @@
# Bayshore # Bayshore
Wangan Midnight Maximum Tune 6 server reimplementation written in TypeScript Wangan Midnight Maximum Tune 6 server reimplementation written in TypeScript
<p align="center">
<img src="https://repository-images.githubusercontent.com/523956269/9a72b45d-7b27-4237-8aeb-476865a6d6d6" width="640" title="hover text">
</p>
## Credits ## Credits
This software is part of [Project Asakura](https://github.com/ProjectAsakura). This software is part of [Project Asakura](https://github.com/ProjectAsakura).

View File

@ -11,6 +11,7 @@
"giftCarsFullyTuned": 0, "giftCarsFullyTuned": 0,
"scratchEnabled": 1, "scratchEnabled": 1,
"scratchType": 1, "scratchType": 1,
"giveMeterReward": 0 "giveMeterReward": 0,
"newCardsBanned": 0
} }
} }

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,3 @@
-- AlterTable
ALTER TABLE "Car" ALTER COLUMN "stLoseBits" SET DEFAULT 0,
ALTER COLUMN "regionId" SET DEFAULT 1;

View File

@ -0,0 +1,16 @@
-- AlterTable
ALTER TABLE "Car" ALTER COLUMN "stLoseBits" SET DEFAULT 0,
ALTER COLUMN "regionId" SET DEFAULT 18;
-- CreateTable
CREATE TABLE "FileList" (
"fileId" SERIAL NOT NULL,
"fileType" INTEGER NOT NULL,
"fileSize" INTEGER NOT NULL,
"urlFileName" TEXT NOT NULL,
"sha1sum" TEXT NOT NULL,
"notBefore" INTEGER NOT NULL,
"notAfter" INTEGER NOT NULL,
CONSTRAINT "FileList_pkey" PRIMARY KEY ("fileId")
);

View File

@ -0,0 +1,5 @@
-- AlterTable
ALTER TABLE "Car" ALTER COLUMN "stLoseBits" SET DEFAULT 0;
-- AlterTable
ALTER TABLE "FileList" ADD COLUMN "filePath" TEXT NOT NULL DEFAULT '';

View File

@ -86,7 +86,7 @@ model Car {
rivalMarker Int @default(0) rivalMarker Int @default(0)
lastPlayedAt Int @default(0) lastPlayedAt Int @default(0)
aura Int @default(0) aura Int @default(0)
regionId Int @default(0) regionId Int @default(18)
country String @default("JPN") country String @default("JPN")
// This is more data about the car // This is more data about the car
@ -436,4 +436,15 @@ model PlaceList {
regionId Int regionId Int
shopName String shopName String
country String country String
}
model FileList {
fileId Int @id @default(autoincrement())
fileType Int
fileSize Int
urlFileName String
sha1sum String
notBefore Int
notAfter Int
filePath String @default("")
} }

View File

@ -48,6 +48,11 @@ export interface GameOptions {
// Give meter reward every n*100 play // Give meter reward every n*100 play
giveMeterReward: number; //1 is on, 0 is off giveMeterReward: number; //1 is on, 0 is off
// if the new card is not in the User databese
// set this option to 1 will not create a new card
// and prevent new card registration
newCardsBanned: number;//1 is on, 0 is off
} }
export class Config { export class Config {
@ -66,4 +71,4 @@ export class Config {
return this.cfg; return this.cfg;
} }
} }

View File

@ -123,7 +123,7 @@ export default class CarModule extends Module {
locked: 'desc' locked: 'desc'
} }
}) })
if(opponentTargetCount > 0) if(opponentTargetCount > 0)
{ {
console.log('Challengers Available'); console.log('Challengers Available');

View File

@ -417,6 +417,7 @@ export default class GhostModule extends Module {
{ {
// Get current date // Get current date
let date = Math.floor(new Date().getTime() / 1000); let date = Math.floor(new Date().getTime() / 1000);
let playedPlace = wm.wm.protobuf.Place.create({ let playedPlace = wm.wm.protobuf.Place.create({
placeId: Config.getConfig().placeId, placeId: Config.getConfig().placeId,
regionId: Config.getConfig().regionId, regionId: Config.getConfig().regionId,

View File

@ -421,11 +421,9 @@ export default class GhostModule extends Module {
if(!(ocmEventDate)) if(!(ocmEventDate))
{ {
ocmEventDate = await prisma.oCMEvent.findFirst({ ocmEventDate = await prisma.oCMEvent.findFirst({
orderBy: [ orderBy:{
{ competitionId: 'desc'
competitionId: 'desc' },
},
],
}); });
} }

View File

@ -496,12 +496,26 @@ export default class ResourceModule extends Module {
common.sendResponse(message, res); common.sendResponse(message, res);
}) })
app.use("/static", e.static(
path.join(__dirname, '..', '..', 'static'), // For File List
{ cacheControl: false } app.get('/static/:filename', async function(req, res){
));
// Static Files
let paths = await prisma.fileList.findFirst({
where:{
urlFileName: req.params.filename
},
select: {
filePath: true
}
});
res.sendFile(path.resolve(paths!.filePath, req.params.filename), { cacheControl: false });
});
// File List
app.get('/resource/file_list', async (req, res) => { app.get('/resource/file_list', async (req, res) => {
console.log('file_list'); console.log('file_list');
@ -510,15 +524,25 @@ export default class ResourceModule extends Module {
// This is literally just bare-bones so the shit boots // This is literally just bare-bones so the shit boots
let files: wm.wm.protobuf.FileList.FileInfo[] = []; let files: wm.wm.protobuf.FileList.FileInfo[] = [];
files.push(wm.wm.protobuf.FileList.FileInfo.create({ let fileList = await prisma.fileList.findMany({
fileId: 1, orderBy:{
fileType: wm.wm.protobuf.FileType.FILE_PROMOTION_ANNOUNCEMENT, fileId: 'asc'
fileSize: 383791, }
url: 'https://'+Config.getConfig().serverIp+':9002/static/000002-bayshore.bin', });
sha1sum: Buffer.from('F1A1AF6F7273F2BA5189CDB15165028B56E022E6', "hex"),
notBefore: 0, for(let i=0; i<fileList.length; i++)
notAfter: 2147483647, {
})); files.push(wm.wm.protobuf.FileList.FileInfo.create({
fileId: fileList[i].fileId,
fileType: fileList[i].fileType,
fileSize: fileList[i].fileSize,
url: 'https://'+Config.getConfig().serverIp+':9002/static/' +fileList[i].urlFileName,
sha1sum: Buffer.from(fileList[i].sha1sum, "hex"),
notBefore: fileList[i].notBefore,
notAfter: fileList[i].notAfter,
}));
}
// Response data // Response data
let msg = { let msg = {
@ -535,6 +559,7 @@ export default class ResourceModule extends Module {
}) })
// Ghost List
app.get('/resource/ghost_list', async (req, res) => { app.get('/resource/ghost_list', async (req, res) => {
console.log('ghost_list'); console.log('ghost_list');

View File

@ -30,10 +30,9 @@ export default class StartupModule extends Module {
// competitionEndAt is greater than current date // competitionEndAt is greater than current date
competitionEndAt: { gte: date }, competitionEndAt: { gte: date },
}, },
orderBy: orderBy: {
{
competitionEndAt: 'desc', competitionEndAt: 'desc',
}, }
}); });
let pastEvent = 0; let pastEvent = 0;
@ -57,6 +56,8 @@ export default class StartupModule extends Module {
if(pastDay < 604800) if(pastDay < 604800)
{ {
console.log("OCM Event Available");
// Creating GhostCompetitionSchedule // Creating GhostCompetitionSchedule
competitionSchedule = wm.wm.protobuf.GhostCompetitionSchedule.create({ competitionSchedule = wm.wm.protobuf.GhostCompetitionSchedule.create({
@ -94,6 +95,8 @@ export default class StartupModule extends Module {
if(pastEvent === 1) if(pastEvent === 1)
{ {
console.log("Previous OCM Event Available");
lastCompetitionId = ocmEventDate.competitionId lastCompetitionId = ocmEventDate.competitionId
} }
} }

View File

@ -68,78 +68,107 @@ export default class UserModule extends Module {
return; return;
} }
let user = await prisma.user.create({ // Check if new card registration is allowed or not
data: { let newCardsBanned = Config.getConfig().gameOptions.newCardsBanned;
chipId: body.cardChipId,
accessCode: body.accessCode,
tutorials: [
false, //TUTORIAL_ID_STORY = 0,
false, //TUTORIAL_ID_TIME_ATTACK = 1,
false, //TUTORIAL_ID_GHOST = 2,
false, //TUTORIAL_ID_GHOST_CHALLENGE = 3,
false, //TUTORIAL_ID_GHOST_LEVEL = 4,
false, //TUTORIAL_ID_UNUSED_5 = 5,
false, //TUTORIAL_ID_GHOST_SEARCH = 6,
false, //TUTORIAL_ID_GHOST_COMPETITION = 7,
false, //TUTORIAL_ID_HP600_CARD = 8,
false, //TUTORIAL_ID_UNUSED_9 = 9,
false, //TUTORIAL_ID_COMPETITION_QUALIFIED = 10,
false, //TUTORIAL_ID_COMPETITION_TERMINAL = 11,
false, //TUTORIAL_ID_COMPETITION_NOTICE = 12,
false, //TUTORIAL_ID_COMPETITION_FINISHED = 13,
false, //TUTORIAL_ID_UNUSED_14 = 14,
false, //TUTORIAL_ID_UNUSED_15 = 15,
false, //TUTORIAL_ID_UNUSED_16 = 16,
false, //TUTORIAL_ID_UNUSED_17 = 17,
false, //TUTORIAL_ID_UNUSED_18 = 18,
false, //TUTORIAL_ID_UNUSED_19 = 19,
true, //TUTORIAL_ID_GHOST_STAMP = 20,
true, //TUTORIAL_ID_GHOST_STAMP_DECLINED = 21,
true, //TUTORIAL_ID_GHOST_STAMP_FRIENDS = 22,
true, //TUTORIAL_ID_TERMINAL_SCRATCH = 23,
true, //TUTORIAL_ID_TURN_SCRATCH_SHEET = 24,
false, //TUTORIAL_ID_INVITE_FRIEND_CAMPAIGN = 25,
false, //TUTORIAL_ID_CAR_COUPON_FULL_TUNED_RECEIVABLE = 26,
false, //TUTORIAL_ID_VS_CONTINUE_TICKET = 27,
false, //TUTORIAL_ID_UNUSED_28 = 28,
false, //TUTORIAL_ID_UNUSED_29 = 29,
false, //TUTORIAL_ID_UNUSED_30 = 30,
false, //TUTORIAL_ID_DRESS_UP = 31,
true, //TUTORIAL_ID_MULTI_GHOST = 32,
true, //TUTORIAL_ID_STORY_NEW_FEATURE = 33,
true, //TUTORIAL_ID_GHOST_NEW_FEATURE = 34,
true, //TUTORIAL_ID_GHOST_REGION_MAP = 35
], // New card registration is allowed
} if (newCardsBanned === 0)
});
console.log('user made')
if (!user)
{ {
msg.error = wm.wm.protobuf.ErrorCode.ERR_REQUEST; let user = await prisma.user.create({
} data: {
chipId: body.cardChipId,
accessCode: body.accessCode,
tutorials: [
false, // TUTORIAL_ID_STORY = 0,
false, // TUTORIAL_ID_TIME_ATTACK = 1,
false, // TUTORIAL_ID_GHOST = 2,
false, // TUTORIAL_ID_GHOST_CHALLENGE = 3,
false, // TUTORIAL_ID_UNUSED_4 = 4,
false, // TUTORIAL_ID_UNUSED_5 = 5,
false, // TUTORIAL_ID_GHOST_SEARCH = 6,
false, // TUTORIAL_ID_GHOST_COMPETITION = 7,
false, // TUTORIAL_ID_HP600_CARD = 8,
false, // TUTORIAL_ID_UNUSED_9 = 9,
false, // TUTORIAL_ID_COMPETITION_QUALIFIED = 10,
false, // TUTORIAL_ID_COMPETITION_TERMINAL = 11,
false, // TUTORIAL_ID_COMPETITION_NOTICE = 12,
false, // TUTORIAL_ID_COMPETITION_FINISHED = 13,
false, // TUTORIAL_ID_UNUSED_14 = 14,
false, // TUTORIAL_ID_UNUSED_15 = 15,
false, // TUTORIAL_ID_UNUSED_16 = 16,
false, // TUTORIAL_ID_UNUSED_17 = 17,
false, // TUTORIAL_ID_UNUSED_18 = 18,
false, // TUTORIAL_ID_UNUSED_19 = 19,
false, // TUTORIAL_ID_GHOST_STAMP = 20,
false, // TUTORIAL_ID_GHOST_STAMP_DECLINED = 21,
false, // TUTORIAL_ID_GHOST_STAMP_FRIENDS = 22,
false, // TUTORIAL_ID_TERMINAL_SCRATCH = 23,
false, // TUTORIAL_ID_TURN_SCRATCH_SHEET = 24,
false, // TUTORIAL_ID_INVITE_FRIEND_CAMPAIGN = 25,
false, // TUTORIAL_ID_CAR_COUPON_FULL_TUNED_RECEIVABLE = 26,
false, // TUTORIAL_ID_VS_CONTINUE_TICKET = 27,
false, // TUTORIAL_ID_UNUSED_28 = 28,
false, // TUTORIAL_ID_UNUSED_29 = 29,
false, // TUTORIAL_ID_UNUSED_30 = 30,
false, // TUTORIAL_ID_DRESS_UP = 31,
false, // TUTORIAL_ID_UNUSED_32 = 32,
false, // TUTORIAL_ID_STORY_NEW_FEATURE = 33,
false, // TUTORIAL_ID_GHOST_NEW_FEATURE = 34,
false, // TUTORIAL_ID_UNUSED_35 = 35,
false, // TUTORIAL_ID_GHOST_EXPEDITION_NEW = 36,
false, // TUTORIAL_ID_GHOST_EXPEDITION_WANTED = 37,
false, // TUTORIAL_ID_GHOST_EXPEDITION_WANTED2 = 38,
false, // TUTORIAL_ID_GHOST_EXPEDITION_REWARD = 39,
false, // TUTORIAL_ID_MULTI_GHOST_VS_2 = 40,
false, // TUTORIAL_ID_MULTI_GHOST_VS_3 = 41,
false, // TUTORIAL_ID_GHOST_SELECT_BY_OTHER_PLACE = 42,
false, // TUTORIAL_ID_GHOST_SELECT_BY_MANUFACTURER = 43,
false, // TUTORIAL_ID_GHOST_SELECT_BY_OTHER_MANUFACTURER = 44,
false, // TUTORIAL_ID_GHOST_SELECT_BY_PLAYED = 45,
false, // TUTORIAL_ID_GHOST_HIGHWAY_NEW = 46,
false, // TUTORIAL_ID_GHOST_HIGHWAY_STATION = 47,
false, // TUTORIAL_ID_GHOST_HIGHWAY_BOSS = 48,
false, // TUTORIAL_ID_GHOST_TROPHY = 49,
false, // TUTORIAL_ID_GHOST_SELECT = 50,
false, // TUTORIAL_ID_GHOST_SELECT_BY_SAME_PLACE = 51
],
}
});
let ftTicketGrant = Config.getConfig().gameOptions.grantFullTuneTicketToNewUsers; console.log('user made')
if (ftTicketGrant > 0) if (!user)
{
console.log(`Granting Full-Tune Ticket x${ftTicketGrant} to new user...`);
for (let i=0; i<ftTicketGrant; i++)
{ {
await prisma.userItem.create({ msg.error = wm.wm.protobuf.ErrorCode.ERR_REQUEST;
data: {
userId: user.id,
category: wm.wm.protobuf.ItemCategory.CAT_CAR_TICKET_FREE,
itemId: 5,
type: 0 // Car Ticket
}
});
} }
console.log('Done!'); 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!');
}
}
// New card registration is not allowed / closed
else
{
console.log('New card / user registration is closed');
msg.error = wm.wm.protobuf.ErrorCode.ERR_REQUEST;
} }
// Encode the response // Encode the response
@ -258,6 +287,7 @@ export default class UserModule extends Module {
} }
// else{} User don't have a car... returning default windowStickerString and windowStickerFont value // else{} User don't have a car... returning default windowStickerString and windowStickerFont value
// Check if last played id is null
if(user.cars[0].lastPlayedPlaceId === null || user.cars[0].lastPlayedPlaceId === undefined) if(user.cars[0].lastPlayedPlaceId === null || user.cars[0].lastPlayedPlaceId === undefined)
{ {
for(let i=0; i<user.cars.length; i++) for(let i=0; i<user.cars.length; i++)
@ -481,32 +511,20 @@ export default class UserModule extends Module {
} }
} }
if(!ocmEventDate) // OCM HoF Ghost Registered from Terminal
{ let checkRegisteredGhost = await prisma.ghostRegisteredFromTerminal.findFirst({
let ocmEventDate = await prisma.oCMEvent.findFirst({ where:{
orderBy: { carId: user.cars[i].carId,
competitionEndAt: 'desc',
}
});
if(ocmEventDate)
{
let checkRegisteredGhost = await prisma.ghostRegisteredFromTerminal.findFirst({
where:{
carId: user.cars[i].carId,
competitionId: ocmEventDate.competitionId
}
});
if(checkRegisteredGhost)
{
carStates[i].hasOpponentGhost = true;
}
else
{
carStates[i].hasOpponentGhost = false;
}
} }
});
if(checkRegisteredGhost)
{
carStates[i].hasOpponentGhost = true;
}
else
{
carStates[i].hasOpponentGhost = false;
} }
} }
@ -767,4 +785,4 @@ export default class UserModule extends Module {
}) })
*/ */
} }
} }

View File

@ -43,18 +43,22 @@ export function getBigIntFromLong(n: Long)
return Number(bigInt); return Number(bigInt);
} }
// Undefined Input Sanitization
export function sanitizeInput(value: any) export function sanitizeInput(value: any)
{ {
return (value == null || value == undefined) ? undefined : value; return (value == null || value == undefined) ? undefined : value;
} }
// Undefined and Zero Input Sanitization
export function sanitizeInputNotZero(value: any) export function sanitizeInputNotZero(value: any)
{ {
return (value !== null && value !== undefined && value !== 0) ? value : undefined; return (value !== null && value !== undefined && value !== 0) ? value : undefined;
} }
// Get Time Stamp
export function getTimeStamp(date: Date = new Date()) export function getTimeStamp(date: Date = new Date())
{ {
// Return a timestamp string for the current / provided time // Return a timestamp string for the current / provided time

View File

@ -135,7 +135,7 @@ export async function saveGhostBattleResult(body: wm.protobuf.SaveGameResultRequ
...dataGhost, ...dataGhost,
...dataCar, ...dataCar,
} }
}); });
await prisma.carGTWing.update({ await prisma.carGTWing.update({
where: { where: {
@ -205,9 +205,9 @@ export async function saveGhostBattleResult(body: wm.protobuf.SaveGameResultRequ
if (ghostResultCrown) if (ghostResultCrown)
{ {
let carId: number = 0; let carId: number = 0;
if(body.car?.carId) if(body.carId)
{ {
carId = Number(body.car.carId); carId = Number(body.carId);
} }
// Ghost Crown update data // Ghost Crown update data

View File

@ -142,7 +142,7 @@ export async function saveOCMGhostHistory(body: wm.protobuf.SaveGameResultReques
saveExGhostHistory.result = rgResult.opponents[0].result; saveExGhostHistory.result = rgResult.opponents[0].result;
} }
// Get played Area // Get area
if(common.sanitizeInput(rgResult.path)) if(common.sanitizeInput(rgResult.path))
{ {
let getArea = await ghost_get_area_from_path.getArea(rgResult.path); let getArea = await ghost_get_area_from_path.getArea(rgResult.path);
@ -210,6 +210,7 @@ export async function saveOCMGhostHistory(body: wm.protobuf.SaveGameResultReques
if(countGBR!.result < saveExGhostHistory.result) if(countGBR!.result < saveExGhostHistory.result)
{ {
console.log('OCM Ghost Tally found'); console.log('OCM Ghost Tally found');
// Current date is OCM Main Draw // Current date is OCM Main Draw
if(ocmEventDate!.competitionStartAt < date && ocmEventDate!.competitionCloseAt > date) if(ocmEventDate!.competitionStartAt < date && ocmEventDate!.competitionCloseAt > date)
{ {
@ -330,8 +331,7 @@ export async function saveOCMGhostHistory(body: wm.protobuf.SaveGameResultReques
// Get OCM Period ID // Get OCM Period ID
let OCM_periodId = await prisma.oCMPeriod.findFirst({ let OCM_periodId = await prisma.oCMPeriod.findFirst({
where:{ where:{
competitionDbId: ocmEventDate!.dbId, competitionId: ocmEventDate!.competitionId,
competitionId: ocmEventDate!.competitionId
}, },
orderBy:{ orderBy:{
periodId: 'desc' periodId: 'desc'
@ -360,6 +360,7 @@ export async function saveOCMGhostHistory(body: wm.protobuf.SaveGameResultReques
if(ocmTallyfind) if(ocmTallyfind)
{ {
console.log('Updating OCM Tally Record'); console.log('Updating OCM Tally Record');
// Update the OCM Tally Record // Update the OCM Tally Record
await prisma.oCMTally.update({ await prisma.oCMTally.update({
where:{ where:{

View File

@ -24,12 +24,12 @@ export async function sendStamp(body: wm.protobuf.SaveGameResultRequest)
} }
// Get the area // Get the area
let area; let area: Number = 0;
if(rgResult.path) if(rgResult.path)
{ {
let getArea = await ghost_get_area_from_path.getArea(rgResult.path); let getArea = await ghost_get_area_from_path.getArea(rgResult.path);
area = getArea.area; area = Number(getArea.area);
} }
// Check how many opponents available // Check how many opponents available

View File

@ -1,5 +1,4 @@
import { prisma } from "../.."; import { prisma } from "../..";
import { OCMTop1GhostTrail } from "@prisma/client";
// Import Proto // Import Proto
import * as ghost_ocm_area from "./ghost_ocm_area"; import * as ghost_ocm_area from "./ghost_ocm_area";

1
yarn_build_protos.bat Normal file
View File

@ -0,0 +1 @@
yarn build_protos

1
yarn_dev.bat Normal file
View File

@ -0,0 +1 @@
yarn dev

2
yarn_prisma.bat Normal file
View File

@ -0,0 +1,2 @@
yarn prisma generate
yarn prisma migrate deploy