mirror of
https://github.com/thepeacockproject/Peacock
synced 2024-11-22 22:12:45 +01:00
4575924e80
* Rewrite the escalation service to use group contracts (#28) * Fix build and type errors Signed-off-by: Reece Dunham <me@rdil.rocks> * Improve Escalation Functionality with Contract Groups (#160) * Fix Sinbad escalation and add group definition * Add group contracts and fix InGroup IDs where needed * Run prettier * Add missing group definitions * Fixed id issues with sinbad * Fix missionsInLocation.ts * Added groupdefinitions (#198) Added localization and missing groupdefinitions for Peacock custom escalations * Fix incorrect escalation contract ids * Remove missing escalations * Add Ataro group definition * Add 7DS entrances * Restore no2016 functionality, add xmas to no2016 list * Add missing deluxe escalation entrance * Fix linting * Added h3 escalations (#204) * Added h3 escalations Added all remaining escalations from h3 maps * Prettier yeehaw --------- Co-authored-by: Anthony Fuller <24512050+AnthonyFuller@users.noreply.github.com> * Fix escalation completion * Fix smilax level 1 * Fix escalation challenges not completing * Get groups when resolving contracts * track escalation challenge completion * fix mission end page for escalation challenges * Update GameChangerProperties * Update EvergreenGameChangerProperties * Add new GameChangerProperties * Fix aborting on invalid escalation group * remove dupe yellow rabbit suit * Fixed DGS having no challenges on career page * run prettier * Update Proloff Level 2 * Update escalation hub tile to work with group contracts * Move escalations and elusives to subfolders * Add 7DS campaign * Fix escalation level picker * Fix escalations being incorrectly marked as completed * Remove completed status when editing escalation level progress * Add new H3 escalations to level picker * Add Season tag to elusives for future use * Add Season tag to typedefs * Respect Season tag when sending elusives * Add Legacy Escalations * Remove milfoil for now, add escalations to missions * Move xmas escalation * Fix Snowdrop not showing in 2016 * Add missing entitlements to escalations * Fix play next level in 2016, remove use of deprecated function * Move remaining Peacock escalations * Swap out featured Peacock escalation --------- Signed-off-by: Reece Dunham <me@rdil.rocks> Co-authored-by: moonysolari <118079569+moonysolari@users.noreply.github.com> Co-authored-by: Kaki <66200818+Kakiking@users.noreply.github.com> Co-authored-by: moonysolari <changyiding@126.com> Co-authored-by: riisikumi <54016129+riisikumi@users.noreply.github.com> Co-authored-by: AnthonyFuller <24512050+AnthonyFuller@users.noreply.github.com>
226 lines
6.3 KiB
TypeScript
226 lines
6.3 KiB
TypeScript
/*
|
|
* The Peacock Project - a HITMAN server replacement.
|
|
* Copyright (C) 2021-2023 The Peacock Project Team
|
|
*
|
|
* This program is free software: you can redistribute it and/or modify
|
|
* it under the terms of the GNU Affero General Public License as published by
|
|
* the Free Software Foundation, either version 3 of the License, or
|
|
* (at your option) any later version.
|
|
*
|
|
* This program is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU Affero General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU Affero General Public License
|
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
*/
|
|
|
|
import { Request, Response, Router } from "express"
|
|
import { getConfig } from "./configSwizzleManager"
|
|
import { readFileSync } from "atomically"
|
|
import { GameVersion, UserProfile } from "./types/types"
|
|
import { join } from "path"
|
|
import { uuidRegex, versions } from "./utils"
|
|
import { getUserData, loadUserData, writeUserData } from "./databaseHandler"
|
|
import { readdirSync } from "fs"
|
|
import { controller } from "./controller"
|
|
import { log, LogLevel } from "./loggingInterop"
|
|
|
|
const webFeaturesRouter = Router()
|
|
|
|
if (PEACOCK_DEV) {
|
|
webFeaturesRouter.use((_req, res, next) => {
|
|
res.set("Access-Control-Allow-Origin", "*")
|
|
res.set(
|
|
"Access-Control-Allow-Methods",
|
|
"GET,HEAD,PUT,PATCH,POST,DELETE",
|
|
)
|
|
res.set("Access-Control-Allow-Headers", "Content-Type")
|
|
next()
|
|
})
|
|
}
|
|
|
|
function formErrorMessage(res: Response, message: string): void {
|
|
res.json({
|
|
success: false,
|
|
error: message,
|
|
})
|
|
}
|
|
|
|
webFeaturesRouter.get("/codenames", (req, res) => {
|
|
res.json(getConfig("EscalationCodenames", false))
|
|
})
|
|
|
|
webFeaturesRouter.get(
|
|
"/local-users",
|
|
(req: Request<unknown, unknown, unknown, { gv: GameVersion }>, res) => {
|
|
if (!req.query.gv || !versions.includes(req.query.gv ?? null)) {
|
|
res.json([])
|
|
return
|
|
}
|
|
|
|
let dir
|
|
|
|
if (req.query.gv === "h3") {
|
|
dir = join("userdata", "users")
|
|
} else {
|
|
dir = join("userdata", req.query.gv, "users")
|
|
}
|
|
|
|
const files: string[] = readdirSync(dir).filter(
|
|
(name) => name !== "lop.json",
|
|
)
|
|
|
|
const result = []
|
|
|
|
for (const file of files) {
|
|
const read = JSON.parse(
|
|
readFileSync(join(dir, file)).toString(),
|
|
) as UserProfile
|
|
|
|
result.push({
|
|
id: read.Id,
|
|
name: read.Gamertag,
|
|
platform: read.EpicId ? "Epic" : "Steam",
|
|
})
|
|
}
|
|
|
|
res.json(result)
|
|
},
|
|
)
|
|
|
|
function validateUserAndGv(
|
|
req: Request<unknown, unknown, unknown, { gv: GameVersion; user: string }>,
|
|
res: Response,
|
|
): boolean {
|
|
if (!req.query.gv || !versions.includes(req.query.gv ?? null)) {
|
|
formErrorMessage(
|
|
res,
|
|
'The request must contain a valid game version among "h1", "h2", and "h3".',
|
|
)
|
|
return false
|
|
}
|
|
|
|
if (!req.query.user || !uuidRegex.test(req.query.user)) {
|
|
formErrorMessage(res, "The request must contain the uuid of a user.")
|
|
return false
|
|
}
|
|
|
|
return true
|
|
}
|
|
|
|
webFeaturesRouter.get(
|
|
"/modify",
|
|
async (
|
|
req: Request<
|
|
unknown,
|
|
unknown,
|
|
unknown,
|
|
{ gv: GameVersion; user: string; level: string; id: string }
|
|
>,
|
|
res,
|
|
) => {
|
|
if (!validateUserAndGv(req, res)) {
|
|
return
|
|
}
|
|
if (!req.query.level) {
|
|
formErrorMessage(
|
|
res,
|
|
"The request must contain the level to set the escalation to.",
|
|
)
|
|
return
|
|
}
|
|
if (
|
|
isNaN(parseInt(req.query.level)) ||
|
|
parseInt(req.query.level) <= 0
|
|
) {
|
|
formErrorMessage(res, "The level must be a positive integer.")
|
|
return
|
|
}
|
|
|
|
if (!req.query.id || !uuidRegex.test(req.query.id)) {
|
|
formErrorMessage(
|
|
res,
|
|
"The request must contain the uuid of an escalation.",
|
|
)
|
|
return
|
|
}
|
|
|
|
try {
|
|
await loadUserData(req.query.user, req.query.gv)
|
|
} catch (e) {
|
|
formErrorMessage(res, "Failed to load user data.")
|
|
return
|
|
}
|
|
if (controller.escalationMappings.get(req.query.id) === undefined) {
|
|
formErrorMessage(res, "Unknown escalation.")
|
|
return
|
|
}
|
|
|
|
if (
|
|
Object.keys(controller.escalationMappings.get(req.query.id))
|
|
.length < parseInt(req.query.level, 10)
|
|
) {
|
|
formErrorMessage(
|
|
res,
|
|
"Cannot exceed the maximum level for this escalation!",
|
|
)
|
|
return
|
|
}
|
|
|
|
log(
|
|
LogLevel.INFO,
|
|
`Setting the level of escalation ${req.query.id} to ${req.query.level}`,
|
|
)
|
|
const read = getUserData(req.query.user, req.query.gv)
|
|
|
|
read.Extensions.PeacockEscalations[req.query.id] = parseInt(
|
|
req.query.level,
|
|
)
|
|
|
|
if (
|
|
read.Extensions.PeacockCompletedEscalations.includes(req.query.id)
|
|
) {
|
|
read.Extensions.PeacockCompletedEscalations =
|
|
read.Extensions.PeacockCompletedEscalations.filter(
|
|
(val) => val !== req.query.level,
|
|
)
|
|
}
|
|
|
|
writeUserData(req.query.user, req.query.gv)
|
|
|
|
res.json({ success: true })
|
|
},
|
|
)
|
|
|
|
webFeaturesRouter.get(
|
|
"/user-progress",
|
|
async (
|
|
req: Request<
|
|
unknown,
|
|
unknown,
|
|
unknown,
|
|
{ gv: GameVersion; user: string }
|
|
>,
|
|
res,
|
|
) => {
|
|
if (!validateUserAndGv(req, res)) {
|
|
return
|
|
}
|
|
|
|
try {
|
|
await loadUserData(req.query.user, req.query.gv)
|
|
} catch (e) {
|
|
formErrorMessage(res, "Failed to load user data.")
|
|
return
|
|
}
|
|
|
|
const d = getUserData(req.query.user, req.query.gv)
|
|
|
|
res.json(d.Extensions.PeacockEscalations)
|
|
},
|
|
)
|
|
|
|
export { webFeaturesRouter }
|