diff --git a/.gitignore b/.gitignore index acf29b7..3639a88 100644 --- a/.gitignore +++ b/.gitignore @@ -9,4 +9,5 @@ key.pem config.json package-lock.json ecosystem.config.js -static/* \ No newline at end of file +static/* +screenshot/* \ No newline at end of file diff --git a/config.example.json b/config.example.json index 386d268..025e00f 100644 --- a/config.example.json +++ b/config.example.json @@ -12,6 +12,7 @@ "scratchEnabled": 1, "scratchType": 1, "giveMeterReward": 0, - "newCardsBanned": 0 + "newCardsBanned": 0, + "enableScreenshot": 0 } } \ No newline at end of file diff --git a/src/allnet.ts b/src/allnet.ts index 0376d45..4b89bf8 100644 --- a/src/allnet.ts +++ b/src/allnet.ts @@ -4,6 +4,7 @@ import { unzipSync } from "zlib"; import { Module } from "./module"; import iconv from "iconv-lite"; import { Config } from "./config"; +import * as common from "./modules/util/common"; // TODO: Move this into the config const STARTUP_URI = `https://${Config.getConfig().serverIp || "localhost"}:9002`; @@ -75,7 +76,7 @@ export default class AllnetModule extends Module { let regionName = Config.getConfig().regionName; let placeId = Config.getConfig().placeId; let country = Config.getConfig().country; - let regionId = Config.getConfig().regionId; + let regionId = common.sanitizeInputNotZero(Number(Config.getConfig().regionId)) || 1; // TODO: Implement board authentication here. diff --git a/src/config.ts b/src/config.ts index d8ed0e4..d3ac8c1 100644 --- a/src/config.ts +++ b/src/config.ts @@ -47,12 +47,16 @@ export interface GameOptions { grantFullTuneTicketToNewUsers: number; // Give meter reward every n*100 play - giveMeterReward: number; //1 is on, 0 is off + giveMeterReward: number; // 1 is on, 0 is off // if the new card is not in the User databese // set this option to 1 will not create a new card // and prevent new card registration - newCardsBanned: number;//1 is on, 0 is off + newCardsBanned: number; // 1 is on, 0 is off + + // revision check + // set this option to 1 to enable screenshot feature + enableScreenshot: number; // 1 is on, 0 is off } export class Config { diff --git a/src/modules/cars.ts b/src/modules/cars.ts index d164244..50c2e83 100644 --- a/src/modules/cars.ts +++ b/src/modules/cars.ts @@ -1,4 +1,5 @@ import { Application } from "express"; +import { Config } from "../config"; import { Module } from "module"; import { prisma } from ".."; @@ -28,6 +29,19 @@ export default class CarModule extends Module { // Get Challenger Data let opponentsTarget = await carFunctions.getOpponentsTarget(body.carId, registeredTarget.registeredargetAvailable); + // Set Screenshot Count + let screenshotCount = 0; + + // Check if screenshot feature enabled or not + let enableScreenshot = Config.getConfig().gameOptions.enableScreenshot || 0; + + // Screenshot feature enabled + if(enableScreenshot === 1) + { + // Set the screnshot chance count + screenshotCount = 99; + } + // Response data let msg = { error: wm.wm.protobuf.ErrorCode.ERR_SUCCESS, @@ -43,7 +57,7 @@ export default class CarModule extends Module { rgPreviousVersionPlayCount: 0, stCompleted_100Episodes: car!.stCompleted100Episodes, auraMotifAutoChange: false, - screenshotCount: 0, + screenshotCount: screenshotCount, transferred: false, // Stamp or Challenger @@ -136,33 +150,52 @@ export default class CarModule extends Module { // Get the request body for the update car request let body = wm.wm.protobuf.UpdateCarRequest.decode(req.body); - // Update the car - await carFunctions.updateCar(body); - - // Update the car setting - await carFunctions.updateCarSetting(body); - - // Update the car window Sticker - await carFunctions.updateCarWindowSticker(body); - - // Update the car Custom Wing - await carFunctions.updateCarCustomWing(body); - - // Get car item (custom color or discarded card) - if(body.earnedItems.length !== 0) + // Not deleting car + if(body.toBeDeleted === false || body.toBeDeleted === undefined || body.toBeDeleted === null) { - console.log('Car Item reward available, continuing ...'); - for(let i=0; i= opponentTargetCount) + { + random = Math.floor(Math.random() * opponentTargetCount + 0.9); + } + + // Random Number not yet selected + if(randomArray.indexOf(random) === -1) + { + // Push current number to array + randomArray.push(random); + } } - // Try randomize it again if it's 1 - if(random === 1) - { - random = Math.floor(Math.random() * opponentTargetCount); - } + // Pick the array number + let pickRandom = Math.floor(Math.random() * randomArray.length + 0.9); + random = randomArray[pickRandom]; // Check opponents target let opponentTarget = await prisma.carStampTarget.findMany({ @@ -157,9 +176,14 @@ export async function getOpponentsTarget(carId: number, registeredargetAvailable stampTargetCarId: carId, recommended: true, }, - orderBy:{ - locked: 'desc' - }, + orderBy: [ + { + id: 'asc' + }, + { + recommended: 'desc' + } + ], skip: random, take: 1, }); @@ -205,6 +229,12 @@ export async function getOpponentsTarget(carId: number, registeredargetAvailable result = Math.abs(carChallengers.result); } + // Error handling if regionId is below 1 or above 47 + if(carTarget!.regionId < 1 || carTarget!.regionId > 47) + { + carTarget!.regionId = Math.floor(Math.random() * 10) + 10; + } + // Push the data challenger = wmproto.wm.protobuf.ChallengerCar.create({ car: carTarget, @@ -322,26 +352,33 @@ export async function createCar(body: wm.protobuf.CreateCarRequest) } } - // Randomize regionId - let regionId: number = 18; + // Randomize pick + let random: number = 1; + let randomArray: number[] = []; // Randomize it 5 times - for(let i=0; i<5; i++) - { - regionId = Math.floor(Math.random() * 47) + 1; + while(randomArray.length < 5) + { + // Pick random car Id + random = Math.floor(Math.random() * 47 + 0.9) + 1; + + // Try randomize it again if it's 0, and fix if more than car length + if(random < 1 || random > 47) + { + random = Math.floor(Math.random() * 47 + 0.9) + 1; + } + + // Random Number not yet selected + if(randomArray.indexOf(random) === -1) + { + // Push current number to array + randomArray.push(random); + } } - // Try randomize it again if it's 1 - if(regionId === 1) - { - regionId = Math.floor(Math.random() * 47) + 1; - } - - // Error handling if regionId is below 1 or above 47 - if(regionId < 1 || regionId > 47) - { - regionId = Math.floor(Math.random() * 10) + 10; - } + // Pick the array number + let pickRandom = Math.floor(Math.random() * randomArray.length + 0.9); + random = randomArray[pickRandom]; // Default car values let carInsert = { @@ -358,7 +395,7 @@ export async function createCar(body: wm.protobuf.CreateCarRequest) carSettingsDbId: settings.dbId, carStateDbId: state.dbId, carGTWingDbId: gtWing.dbId, - regionId: regionId, + regionId: random, lastPlayedAt: date, lastPlayedPlaceId: 1, // Server Default }; diff --git a/src/modules/game.ts b/src/modules/game.ts index 7188485..60aeecb 100644 --- a/src/modules/game.ts +++ b/src/modules/game.ts @@ -230,22 +230,22 @@ export default class GameModule extends Module { // Save Screenshot app.post('/method/save_screenshot', async (req, res) => { - // Get the information from the request + // Get the request body let body = wm.wm.protobuf.SaveScreenshotRequest.decode(req.body); - - // TODO: Actual stuff here - // This is literally just bare-bones so the shit boots + + // Perform the save screenshot request for the car + await gameFunction.saveScreenshot(body); // Response data let msg = { error: wm.wm.protobuf.ErrorCode.ERR_SUCCESS, }; - // Encode the response + // Encode the response let message = wm.wm.protobuf.SaveScreenshotResponse.encode(msg); - + // Send the response to the client common.sendResponse(message, res); - }); + }) } } diff --git a/src/modules/game/functions.ts b/src/modules/game/functions.ts index f5bd011..25d3a95 100644 --- a/src/modules/game/functions.ts +++ b/src/modules/game/functions.ts @@ -1,4 +1,7 @@ import { prisma } from "../.."; +import { Config } from "../../config"; +import path from "path"; +import fs from "fs"; // Import Proto import { wm } from "../../wmmt/wm.proto"; @@ -407,4 +410,41 @@ export async function getGhostBattleRecord(body: wm.protobuf.LoadGameHistoryRequ } return { ghostBattle_records } +} + + +// Save Screenshot +export async function saveScreenshot(body: wm.protobuf.SaveScreenshotRequest) +{ + // Check if screenshot feature enabled or not + let enableScreenshot = Config.getConfig().gameOptions.enableScreenshot || 0; + + // Screenshot feature enabled + if(enableScreenshot === 1) + { + let filename: string | undefined = undefined; + + filename = `${body.timestamp}_${body.carId}_${body.imageType}.png`; + + let dir = path.join('screenshot'); + + if (!fs.existsSync(dir)){ + fs.mkdirSync(dir); + } + + // Combine the filename with the save location + let fullname = path.join('screenshot', filename); + + // Attempt to write to the file + fs.writeFile(fullname, body.image, (err) => { + if (err) + { + console.log(err); + } + else + { + console.log(`Screenshot saved successfully as '${filename}'`) + } + }); + } } \ No newline at end of file diff --git a/src/modules/ghost/ghost_history.ts b/src/modules/ghost/ghost_history.ts index 3b339e8..5b149b7 100644 --- a/src/modules/ghost/ghost_history.ts +++ b/src/modules/ghost/ghost_history.ts @@ -195,7 +195,6 @@ export async function saveOCMGhostHistory(body: wm.protobuf.SaveGameResultReques where:{ carId: saveExGhostHistory.carId, ocmMainDraw: saveExGhostHistory.ocmMainDraw, - area: saveExGhostHistory.area, competitionId: ocmEventDate!.competitionId, periodId: 0 } @@ -207,7 +206,7 @@ export async function saveOCMGhostHistory(body: wm.protobuf.SaveGameResultReques if(countGBR) { // Check if the newest advantage distance is bigger than the older advantage distance - if(countGBR!.result < saveExGhostHistory.result) + if(countGBR.result < saveExGhostHistory.result) { console.log('OCM Ghost Tally found'); @@ -217,7 +216,6 @@ export async function saveOCMGhostHistory(body: wm.protobuf.SaveGameResultReques // Get OCM Period ID let OCM_periodId = await prisma.oCMPeriod.findFirst({ where:{ - competitionDbId: ocmEventDate!.dbId, competitionId: ocmEventDate!.competitionId, startAt: { @@ -248,7 +246,6 @@ export async function saveOCMGhostHistory(body: wm.protobuf.SaveGameResultReques let getGBR = await prisma.oCMGhostBattleRecord.findFirst({ where:{ carId: saveExGhostHistory.carId, - area: saveExGhostHistory.area, competitionId: ocmEventDate!.competitionId, } }); @@ -323,7 +320,7 @@ export async function saveOCMGhostHistory(body: wm.protobuf.SaveGameResultReques else { console.log('OCM Ghost Battle Record not found'); - console.log('Creating new OOCM Ghost Battle Record entry'); + console.log('Creating new OCM Ghost Battle Record entry'); // Current date is OCM Main Draw if(ocmEventDate!.competitionStartAt < date && ocmEventDate!.competitionCloseAt > date) diff --git a/src/modules/resource.ts b/src/modules/resource.ts index eef6913..dce627d 100644 --- a/src/modules/resource.ts +++ b/src/modules/resource.ts @@ -25,10 +25,13 @@ export default class ResourceModule extends Module { // Empty list of place records let places: wm.wm.protobuf.Place[] = []; + // Region ID must not 0 + let regionId = common.sanitizeInputNotZero(Number(Config.getConfig().regionId)) || 1; + // Response data places.push(new wm.wm.protobuf.Place({ placeId: Config.getConfig().placeId || 'JPN0123', - regionId: Number(Config.getConfig().regionId) || 1, + regionId: regionId, shopName: Config.getConfig().shopName || 'Bayshore', country: Config.getConfig().country || 'JPN' })); @@ -46,7 +49,7 @@ export default class ResourceModule extends Module { await prisma.placeList.create({ data:{ placeId: Config.getConfig().placeId || 'JPN0123', - regionId: Number(Config.getConfig().regionId) || 1, + regionId: regionId, shopName: Config.getConfig().shopName || 'Bayshore', country: Config.getConfig().country || 'JPN' } @@ -61,7 +64,7 @@ export default class ResourceModule extends Module { id: checkPlaceList.id }, data:{ - regionId: Number(Config.getConfig().regionId), + regionId: regionId, shopName: Config.getConfig().shopName, country: Config.getConfig().country } diff --git a/src/modules/users.ts b/src/modules/users.ts index bb80143..eef85a3 100644 --- a/src/modules/users.ts +++ b/src/modules/users.ts @@ -20,8 +20,8 @@ export default class UserModule extends Module { // Get the request body for the load user request let body = wm.wm.protobuf.LoadUserRequest.decode(req.body); - // Block blank card.ini data - if(body.cardChipId.match(/7F5C9744F11111114326.*/)) + // Block blank card.ini data and vanilla TP blank card data + if(body.cardChipId.match(/7F5C9744F11111114326.*/) || body.cardChipId.match(/0000000000.*/)) { body.cardChipId = ''; body.accessCode = ''; @@ -39,6 +39,9 @@ export default class UserModule extends Module { state: true, gtWing: true, lastPlayedPlace: true + }, + where:{ + state: { toBeDeleted: false } // except deleted car } } } @@ -59,12 +62,7 @@ export default class UserModule extends Module { if (!body.cardChipId || !body.accessCode) { - let msg = { - error: wm.wm.protobuf.ErrorCode.ERR_USER_SUCCEEDED, - numOfOwnedCars: 0, - spappState: wm.wm.protobuf.SmartphoneAppState.SPAPP_UNREGISTERED, - transferState: wm.wm.protobuf.TransferState.NOT_REGISTERED - } + msg.error = wm.wm.protobuf.ErrorCode.ERR_USER_SUCCEEDED; // Encode the response let message = wm.wm.protobuf.LoadUserResponse.encode(msg);