1
mirror of https://github.com/thepeacockproject/Peacock synced 2025-03-21 00:04:22 +01:00

701 lines
23 KiB
TypeScript
Raw Normal View History

/*
* 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 { decode } from "jsonwebtoken"
import type { NextFunction, Response } from "express"
import type {
GameVersion,
MissionManifestObjective,
Multi-Version Mastery and Sniper Scoring (#270) * Add multi-version mastery files * Add pro1 unlocks to legacy allunlockables * Add 47's suit to scpc all unlockables * Add and remove various configs * Remove some useless promises * Fix scpc hub * Fix issue with user profile saving * Fix scpc issues for hub * Add singleplayer/multiplayer sniper * A great many things - Add multi-version mastery - Improve sniper mastery support - Improve general H2016 support * Fix some warnings * Fix pro1 mastery on destination screens * Remove entP from createInventory, lock/unlock pro1 accordingly * Remove JSDoc entP parameter from createInventory * Remove difficultyunlocks from safehouse pages * Add versioned user profiles * Prettier run * Remove false point from user profiles docs * Add comment about profile versioning to types * Fix default profile links * Remove remaining lowercase * Fix sniper showing XP as XP * Add game versions to the unlockable map * Update getMasteryForUnlockable call in planning * Fix missing locations when updating profiles * Update versions to v7 * Fix ICA Facility destination mastery * Fix sniper challenge unlockables showing in inventory * Sniper Scoring (#273) * Initial sniper scoring * Fix linting errors * Update require table * Calculate and display final sniper score on end screen * Bump SMP version to v5.7.0 * Update since version for scoring * Fix create inventory call for sniper scoring * Support sniper unlockables in the inventory * Update versions to v7 * Reflect changes to createInventory in scoreHandler * Get unlockable name in completion data * It was not okay. * Thanks webstorm * Add support for /profiles/page/GetMasteryCompletionDataForUnlockable * Support sniper play next * Remove sniper gamemodes template from overrides * Remove debug prints from scoring event handler * Fix challenge multiplier * Exclude sniper unlockables from stashpoint * Start fixing up the missionEnd response for sniper * Update misleading comment * Use existing global challenge to check for SA on sniper contracts * Re-add removed global challenges * Proper support for the mission end screen on sniper contracts * Remove redundant label --------- Signed-off-by: Anthony Fuller <24512050+AnthonyFuller@users.noreply.github.com> Co-authored-by: Govert de Gans <grappigegovert@hotmail.com> * Add co-op sniper scoring defs * Update MasteryUnlockable template * Bump SMP version to v5.9.3 * Re-add deepmerge * Fix SMP checksum * Fix linting errors caused by merge * Fix score handler imports * Move load flags * Remove unnecessary game version arg * Whoopsies Co-authored-by: Reece Dunham <me@rdil.rocks> Signed-off-by: Anthony Fuller <24512050+AnthonyFuller@users.noreply.github.com> --------- Signed-off-by: Anthony Fuller <24512050+AnthonyFuller@users.noreply.github.com> Co-authored-by: Govert de Gans <grappigegovert@hotmail.com> Co-authored-by: Reece Dunham <me@rdil.rocks>
2023-07-24 23:47:28 +01:00
PeacockLocationsData,
RepositoryId,
RequestWithJwt,
ServerVersion,
Unlockable,
UserProfile,
} from "./types/types"
import axios, { AxiosError } from "axios"
import { log, LogLevel } from "./loggingInterop"
import { writeFileSync } from "fs"
import { getFlag } from "./flags"
Multi-Version Mastery and Sniper Scoring (#270) * Add multi-version mastery files * Add pro1 unlocks to legacy allunlockables * Add 47's suit to scpc all unlockables * Add and remove various configs * Remove some useless promises * Fix scpc hub * Fix issue with user profile saving * Fix scpc issues for hub * Add singleplayer/multiplayer sniper * A great many things - Add multi-version mastery - Improve sniper mastery support - Improve general H2016 support * Fix some warnings * Fix pro1 mastery on destination screens * Remove entP from createInventory, lock/unlock pro1 accordingly * Remove JSDoc entP parameter from createInventory * Remove difficultyunlocks from safehouse pages * Add versioned user profiles * Prettier run * Remove false point from user profiles docs * Add comment about profile versioning to types * Fix default profile links * Remove remaining lowercase * Fix sniper showing XP as XP * Add game versions to the unlockable map * Update getMasteryForUnlockable call in planning * Fix missing locations when updating profiles * Update versions to v7 * Fix ICA Facility destination mastery * Fix sniper challenge unlockables showing in inventory * Sniper Scoring (#273) * Initial sniper scoring * Fix linting errors * Update require table * Calculate and display final sniper score on end screen * Bump SMP version to v5.7.0 * Update since version for scoring * Fix create inventory call for sniper scoring * Support sniper unlockables in the inventory * Update versions to v7 * Reflect changes to createInventory in scoreHandler * Get unlockable name in completion data * It was not okay. * Thanks webstorm * Add support for /profiles/page/GetMasteryCompletionDataForUnlockable * Support sniper play next * Remove sniper gamemodes template from overrides * Remove debug prints from scoring event handler * Fix challenge multiplier * Exclude sniper unlockables from stashpoint * Start fixing up the missionEnd response for sniper * Update misleading comment * Use existing global challenge to check for SA on sniper contracts * Re-add removed global challenges * Proper support for the mission end screen on sniper contracts * Remove redundant label --------- Signed-off-by: Anthony Fuller <24512050+AnthonyFuller@users.noreply.github.com> Co-authored-by: Govert de Gans <grappigegovert@hotmail.com> * Add co-op sniper scoring defs * Update MasteryUnlockable template * Bump SMP version to v5.9.3 * Re-add deepmerge * Fix SMP checksum * Fix linting errors caused by merge * Fix score handler imports * Move load flags * Remove unnecessary game version arg * Whoopsies Co-authored-by: Reece Dunham <me@rdil.rocks> Signed-off-by: Anthony Fuller <24512050+AnthonyFuller@users.noreply.github.com> --------- Signed-off-by: Anthony Fuller <24512050+AnthonyFuller@users.noreply.github.com> Co-authored-by: Govert de Gans <grappigegovert@hotmail.com> Co-authored-by: Reece Dunham <me@rdil.rocks>
2023-07-24 23:47:28 +01:00
import { getConfig, getVersionedConfig } from "./configSwizzleManager"
/**
* True if the server is being run by the launcher, false otherwise.
*/
export const IS_LAUNCHER = process.env.IS_PEACOCK_LAUNCHER === "true"
export const ServerVer: ServerVersion = {
_Major: 8,
2023-10-27 04:53:47 +01:00
_Minor: 14,
_Build: 0,
_Revision: 0,
}
export const PEACOCKVER = REV_IDENT
export const PEACOCKVERSTRING = HUMAN_VERSION
export const uuidRegex =
/^[a-zA-Z0-9]{8}-[a-zA-Z0-9]{4}-[a-zA-Z0-9]{4}-[a-zA-Z0-9]{4}-[a-zA-Z0-9]{12}$/
export const contractTypes = ["featured", "usercreated"]
2023-02-13 12:24:34 -05:00
export const versions: GameVersion[] = ["h1", "h2", "h3"]
export const contractCreationTutorialId = "d7e2607c-6916-48e2-9588-976c7d8998bb"
Multi-Version Mastery and Sniper Scoring (#270) * Add multi-version mastery files * Add pro1 unlocks to legacy allunlockables * Add 47's suit to scpc all unlockables * Add and remove various configs * Remove some useless promises * Fix scpc hub * Fix issue with user profile saving * Fix scpc issues for hub * Add singleplayer/multiplayer sniper * A great many things - Add multi-version mastery - Improve sniper mastery support - Improve general H2016 support * Fix some warnings * Fix pro1 mastery on destination screens * Remove entP from createInventory, lock/unlock pro1 accordingly * Remove JSDoc entP parameter from createInventory * Remove difficultyunlocks from safehouse pages * Add versioned user profiles * Prettier run * Remove false point from user profiles docs * Add comment about profile versioning to types * Fix default profile links * Remove remaining lowercase * Fix sniper showing XP as XP * Add game versions to the unlockable map * Update getMasteryForUnlockable call in planning * Fix missing locations when updating profiles * Update versions to v7 * Fix ICA Facility destination mastery * Fix sniper challenge unlockables showing in inventory * Sniper Scoring (#273) * Initial sniper scoring * Fix linting errors * Update require table * Calculate and display final sniper score on end screen * Bump SMP version to v5.7.0 * Update since version for scoring * Fix create inventory call for sniper scoring * Support sniper unlockables in the inventory * Update versions to v7 * Reflect changes to createInventory in scoreHandler * Get unlockable name in completion data * It was not okay. * Thanks webstorm * Add support for /profiles/page/GetMasteryCompletionDataForUnlockable * Support sniper play next * Remove sniper gamemodes template from overrides * Remove debug prints from scoring event handler * Fix challenge multiplier * Exclude sniper unlockables from stashpoint * Start fixing up the missionEnd response for sniper * Update misleading comment * Use existing global challenge to check for SA on sniper contracts * Re-add removed global challenges * Proper support for the mission end screen on sniper contracts * Remove redundant label --------- Signed-off-by: Anthony Fuller <24512050+AnthonyFuller@users.noreply.github.com> Co-authored-by: Govert de Gans <grappigegovert@hotmail.com> * Add co-op sniper scoring defs * Update MasteryUnlockable template * Bump SMP version to v5.9.3 * Re-add deepmerge * Fix SMP checksum * Fix linting errors caused by merge * Fix score handler imports * Move load flags * Remove unnecessary game version arg * Whoopsies Co-authored-by: Reece Dunham <me@rdil.rocks> Signed-off-by: Anthony Fuller <24512050+AnthonyFuller@users.noreply.github.com> --------- Signed-off-by: Anthony Fuller <24512050+AnthonyFuller@users.noreply.github.com> Co-authored-by: Govert de Gans <grappigegovert@hotmail.com> Co-authored-by: Reece Dunham <me@rdil.rocks>
2023-07-24 23:47:28 +01:00
/**
* The latest profile version, this should be changed in conjunction with the updating mechanism.
*
* See docs/USER_PROFILES.md for more.
*/
export const LATEST_PROFILE_VERSION = 1
export async function checkForUpdates(): Promise<void> {
if (getFlag("updateChecking") === false) {
return
}
try {
const res = await axios(
"https://backend.rdil.rocks/peacock/latest-version",
)
const current = res.data
if (PEACOCKVER < 0 && current < -PEACOCKVER) {
log(
LogLevel.INFO,
`Thank you for trying out this testing version of Peacock! Please report any bugs by posting in the #help channel on Discord or by submitting an issue on GitHub.`,
)
} else if (PEACOCKVER > 0 && current === PEACOCKVER) {
log(LogLevel.DEBUG, "Peacock is up to date.")
} else {
log(
LogLevel.WARN,
`Peacock is out-of-date! Check the Discord for the latest release.`,
)
}
} catch (e) {
log(LogLevel.WARN, "Failed to check for updates!")
}
}
export function getRemoteService(gameVersion: GameVersion): string {
return gameVersion === "h3"
? "hm3-service"
: gameVersion === "h2"
? "pc2-service"
: "pc-service"
}
/**
* Middleware that validates the authentication token sent by the client.
*
* @param req The express request object.
* @param res The express response object.
* @param next The express next function.
*/
export function extractToken(
req: RequestWithJwt,
res?: Response,
next?: NextFunction,
): void {
const header = req.header("Authorization")
const auth = header ? header.split(" ") : []
if (auth.length === 2 && auth[0].toLowerCase() === "bearer") {
// @ts-expect-error Type overlap
req.jwt = <string>decode(auth[1])
if (!uuidRegex.test(req.jwt.unique_name)) {
res?.status(424).send("profile appears to be corrupted")
return
}
next?.()
return
}
req.shouldCease = true
next?.("router")
}
export const DEFAULT_MASTERY_MAXLEVEL = 20
export const XP_PER_LEVEL = 6000
export function getMaxProfileLevel(gameVersion: GameVersion): number {
if (gameVersion === "h3") {
return 7500
}
return 5000
}
/**
* Calculates the level for the given XP based on XP_PER_LEVEL.
* Minimum level returned is 1.
*/
export function levelForXp(xp: number): number {
return Math.max(1, Math.floor(xp / XP_PER_LEVEL) + 1)
}
/**
* Calculates the required XP for the given level based on XP_PER_LEVEL.
* Minimum XP returned is 0.
*/
export function xpRequiredForLevel(level: number): number {
return Math.max(0, (level - 1) * XP_PER_LEVEL)
}
// TODO: Determine some mathematical function
export const EVERGREEN_LEVEL_INFO: number[] = [
0, 5000, 10000, 17000, 24000, 31000, 38000, 45000, 52000, 61000, 70000,
79000, 88000, 97000, 106000, 115000, 124000, 133000, 142000, 154000, 166000,
178000, 190000, 202000, 214000, 226000, 238000, 250000, 262000, 280000,
298000, 316000, 334000, 352000, 370000, 388000, 406000, 424000, 442000,
468000, 494000, 520000, 546000, 572000, 598000, 624000, 650000, 676000,
702000, 736000, 770000, 804000, 838000, 872000, 906000, 940000, 974000,
1008000, 1042000, 1082000, 1122000, 1162000, 1202000, 1242000, 1282000,
1322000, 1362000, 1402000, 1442000, 1492000, 1542000, 1592000, 1642000,
1692000, 1742000, 1792000, 1842000, 1892000, 1942000, 2002000, 2062000,
2122000, 2182000, 2242000, 2302000, 2362000, 2422000, 2482000, 2542000,
2692000, 2842000, 2992000, 3142000, 3292000, 3442000, 3592000, 3742000,
3892000, 4042000, 4192000,
]
export function evergreenLevelForXp(xp: number): number {
for (let i = 1; i < EVERGREEN_LEVEL_INFO.length; i++) {
if (xp >= EVERGREEN_LEVEL_INFO[i]) {
continue
}
return i
}
return 1
}
export function xpRequiredForEvergreenLevel(level: number): number {
return EVERGREEN_LEVEL_INFO[level - 1]
}
// TODO: Determine some mathematical function
export const SNIPER_LEVEL_INFO: number[] = [
0, 50000, 150000, 500000, 1000000, 1700000, 2500000, 3500000, 5000000,
7000000, 9500000, 12500000, 16000000, 20000000, 25000000, 31000000,
38000000, 47000000, 58000000, 70000000,
]
Multi-Version Mastery and Sniper Scoring (#270) * Add multi-version mastery files * Add pro1 unlocks to legacy allunlockables * Add 47's suit to scpc all unlockables * Add and remove various configs * Remove some useless promises * Fix scpc hub * Fix issue with user profile saving * Fix scpc issues for hub * Add singleplayer/multiplayer sniper * A great many things - Add multi-version mastery - Improve sniper mastery support - Improve general H2016 support * Fix some warnings * Fix pro1 mastery on destination screens * Remove entP from createInventory, lock/unlock pro1 accordingly * Remove JSDoc entP parameter from createInventory * Remove difficultyunlocks from safehouse pages * Add versioned user profiles * Prettier run * Remove false point from user profiles docs * Add comment about profile versioning to types * Fix default profile links * Remove remaining lowercase * Fix sniper showing XP as XP * Add game versions to the unlockable map * Update getMasteryForUnlockable call in planning * Fix missing locations when updating profiles * Update versions to v7 * Fix ICA Facility destination mastery * Fix sniper challenge unlockables showing in inventory * Sniper Scoring (#273) * Initial sniper scoring * Fix linting errors * Update require table * Calculate and display final sniper score on end screen * Bump SMP version to v5.7.0 * Update since version for scoring * Fix create inventory call for sniper scoring * Support sniper unlockables in the inventory * Update versions to v7 * Reflect changes to createInventory in scoreHandler * Get unlockable name in completion data * It was not okay. * Thanks webstorm * Add support for /profiles/page/GetMasteryCompletionDataForUnlockable * Support sniper play next * Remove sniper gamemodes template from overrides * Remove debug prints from scoring event handler * Fix challenge multiplier * Exclude sniper unlockables from stashpoint * Start fixing up the missionEnd response for sniper * Update misleading comment * Use existing global challenge to check for SA on sniper contracts * Re-add removed global challenges * Proper support for the mission end screen on sniper contracts * Remove redundant label --------- Signed-off-by: Anthony Fuller <24512050+AnthonyFuller@users.noreply.github.com> Co-authored-by: Govert de Gans <grappigegovert@hotmail.com> * Add co-op sniper scoring defs * Update MasteryUnlockable template * Bump SMP version to v5.9.3 * Re-add deepmerge * Fix SMP checksum * Fix linting errors caused by merge * Fix score handler imports * Move load flags * Remove unnecessary game version arg * Whoopsies Co-authored-by: Reece Dunham <me@rdil.rocks> Signed-off-by: Anthony Fuller <24512050+AnthonyFuller@users.noreply.github.com> --------- Signed-off-by: Anthony Fuller <24512050+AnthonyFuller@users.noreply.github.com> Co-authored-by: Govert de Gans <grappigegovert@hotmail.com> Co-authored-by: Reece Dunham <me@rdil.rocks>
2023-07-24 23:47:28 +01:00
export function sniperLevelForXp(xp: number): number {
for (let i = 1; i < SNIPER_LEVEL_INFO.length; i++) {
if (xp >= SNIPER_LEVEL_INFO[i]) {
continue
}
return i
}
return 1
}
/**
* Get the number of xp needed to reach a level in sniper missions.
* @param level The level in question.
* @returns The xp, as a number.
*/
export function xpRequiredForSniperLevel(level: number): number {
return SNIPER_LEVEL_INFO[level - 1]
}
/**
* Clamps the given value between a minimum and maximum value
*/
export function clampValue(value: number, min: number, max: number) {
return Math.max(min, Math.min(value, max))
}
Multi-Version Mastery and Sniper Scoring (#270) * Add multi-version mastery files * Add pro1 unlocks to legacy allunlockables * Add 47's suit to scpc all unlockables * Add and remove various configs * Remove some useless promises * Fix scpc hub * Fix issue with user profile saving * Fix scpc issues for hub * Add singleplayer/multiplayer sniper * A great many things - Add multi-version mastery - Improve sniper mastery support - Improve general H2016 support * Fix some warnings * Fix pro1 mastery on destination screens * Remove entP from createInventory, lock/unlock pro1 accordingly * Remove JSDoc entP parameter from createInventory * Remove difficultyunlocks from safehouse pages * Add versioned user profiles * Prettier run * Remove false point from user profiles docs * Add comment about profile versioning to types * Fix default profile links * Remove remaining lowercase * Fix sniper showing XP as XP * Add game versions to the unlockable map * Update getMasteryForUnlockable call in planning * Fix missing locations when updating profiles * Update versions to v7 * Fix ICA Facility destination mastery * Fix sniper challenge unlockables showing in inventory * Sniper Scoring (#273) * Initial sniper scoring * Fix linting errors * Update require table * Calculate and display final sniper score on end screen * Bump SMP version to v5.7.0 * Update since version for scoring * Fix create inventory call for sniper scoring * Support sniper unlockables in the inventory * Update versions to v7 * Reflect changes to createInventory in scoreHandler * Get unlockable name in completion data * It was not okay. * Thanks webstorm * Add support for /profiles/page/GetMasteryCompletionDataForUnlockable * Support sniper play next * Remove sniper gamemodes template from overrides * Remove debug prints from scoring event handler * Fix challenge multiplier * Exclude sniper unlockables from stashpoint * Start fixing up the missionEnd response for sniper * Update misleading comment * Use existing global challenge to check for SA on sniper contracts * Re-add removed global challenges * Proper support for the mission end screen on sniper contracts * Remove redundant label --------- Signed-off-by: Anthony Fuller <24512050+AnthonyFuller@users.noreply.github.com> Co-authored-by: Govert de Gans <grappigegovert@hotmail.com> * Add co-op sniper scoring defs * Update MasteryUnlockable template * Bump SMP version to v5.9.3 * Re-add deepmerge * Fix SMP checksum * Fix linting errors caused by merge * Fix score handler imports * Move load flags * Remove unnecessary game version arg * Whoopsies Co-authored-by: Reece Dunham <me@rdil.rocks> Signed-off-by: Anthony Fuller <24512050+AnthonyFuller@users.noreply.github.com> --------- Signed-off-by: Anthony Fuller <24512050+AnthonyFuller@users.noreply.github.com> Co-authored-by: Govert de Gans <grappigegovert@hotmail.com> Co-authored-by: Reece Dunham <me@rdil.rocks>
2023-07-24 23:47:28 +01:00
/**
* Updates a user profile depending on the current version (if any).
* @param profile The userprofile to update
* @param gameVersion The game version
* @returns The updated user profile
*/
function updateUserProfile(
profile: UserProfile,
gameVersion: GameVersion,
): void {
/**
* This switch is structured such that the current profile version will return.
* thus stopping the function.
*
* As the version number is incremented, the previous version should be added
* as a case to update it to the newest version.
*/
switch (profile.Version) {
case LATEST_PROFILE_VERSION:
// This profile updated to the latest version, we're done.
return
default: {
// Check that the profile version is indeed undefined. If it isn't,
// we've forgotten to add a version to the switch.
if (profile.Version !== undefined) {
log(
LogLevel.ERROR,
`Unhandled profile version ${profile.Version}`,
)
return
}
/* ////// VERSION 1 ////// */
Multi-Version Mastery and Sniper Scoring (#270) * Add multi-version mastery files * Add pro1 unlocks to legacy allunlockables * Add 47's suit to scpc all unlockables * Add and remove various configs * Remove some useless promises * Fix scpc hub * Fix issue with user profile saving * Fix scpc issues for hub * Add singleplayer/multiplayer sniper * A great many things - Add multi-version mastery - Improve sniper mastery support - Improve general H2016 support * Fix some warnings * Fix pro1 mastery on destination screens * Remove entP from createInventory, lock/unlock pro1 accordingly * Remove JSDoc entP parameter from createInventory * Remove difficultyunlocks from safehouse pages * Add versioned user profiles * Prettier run * Remove false point from user profiles docs * Add comment about profile versioning to types * Fix default profile links * Remove remaining lowercase * Fix sniper showing XP as XP * Add game versions to the unlockable map * Update getMasteryForUnlockable call in planning * Fix missing locations when updating profiles * Update versions to v7 * Fix ICA Facility destination mastery * Fix sniper challenge unlockables showing in inventory * Sniper Scoring (#273) * Initial sniper scoring * Fix linting errors * Update require table * Calculate and display final sniper score on end screen * Bump SMP version to v5.7.0 * Update since version for scoring * Fix create inventory call for sniper scoring * Support sniper unlockables in the inventory * Update versions to v7 * Reflect changes to createInventory in scoreHandler * Get unlockable name in completion data * It was not okay. * Thanks webstorm * Add support for /profiles/page/GetMasteryCompletionDataForUnlockable * Support sniper play next * Remove sniper gamemodes template from overrides * Remove debug prints from scoring event handler * Fix challenge multiplier * Exclude sniper unlockables from stashpoint * Start fixing up the missionEnd response for sniper * Update misleading comment * Use existing global challenge to check for SA on sniper contracts * Re-add removed global challenges * Proper support for the mission end screen on sniper contracts * Remove redundant label --------- Signed-off-by: Anthony Fuller <24512050+AnthonyFuller@users.noreply.github.com> Co-authored-by: Govert de Gans <grappigegovert@hotmail.com> * Add co-op sniper scoring defs * Update MasteryUnlockable template * Bump SMP version to v5.9.3 * Re-add deepmerge * Fix SMP checksum * Fix linting errors caused by merge * Fix score handler imports * Move load flags * Remove unnecessary game version arg * Whoopsies Co-authored-by: Reece Dunham <me@rdil.rocks> Signed-off-by: Anthony Fuller <24512050+AnthonyFuller@users.noreply.github.com> --------- Signed-off-by: Anthony Fuller <24512050+AnthonyFuller@users.noreply.github.com> Co-authored-by: Govert de Gans <grappigegovert@hotmail.com> Co-authored-by: Reece Dunham <me@rdil.rocks>
2023-07-24 23:47:28 +01:00
// Profile has no version, update it to version 1, then re-run
// the function to update it to subsequent versions.
const sniperLocs = {
LOCATION_PARENT_AUSTRIA: [
"FIREARMS_SC_HERO_SNIPER_HM",
"FIREARMS_SC_HERO_SNIPER_KNIGHT",
"FIREARMS_SC_HERO_SNIPER_STONE",
],
LOCATION_PARENT_SALTY: [
"FIREARMS_SC_SEAGULL_HM",
"FIREARMS_SC_SEAGULL_KNIGHT",
"FIREARMS_SC_SEAGULL_STONE",
],
LOCATION_PARENT_CAGED: [
"FIREARMS_SC_FALCON_HM",
"FIREARMS_SC_FALCON_KNIGHT",
"FIREARMS_SC_FALCON_STONE",
],
}
// We need this to ensure all locations are added.
const allLocs = Object.keys(
getVersionedConfig<PeacockLocationsData>(
"LocationsData",
gameVersion,
false,
).parents,
).map((key) => key.toLocaleLowerCase())
profile.Extensions.progression.Locations = allLocs.reduce(
(obj, key) => {
const newKey = key.toLocaleUpperCase()
const curData =
profile.Extensions.progression.Locations[key]
if (gameVersion === "h1") {
// No sniper locations, but we add normal and pro1
obj[newKey] = {
// Data from previous profiles only contains normal and is the default.
normal: {
Xp: curData.Xp ?? 0,
Level: curData.Level ?? 1,
PreviouslySeenXp: curData.PreviouslySeenXp ?? 0,
},
pro1: {
Xp: 0,
Level: 1,
PreviouslySeenXp: 0,
},
}
} else {
// We need to update sniper locations.
obj[newKey] = sniperLocs[newKey]
? sniperLocs[newKey].reduce((obj, uId) => {
obj[uId] = {
Xp: 0,
Level: 1,
PreviouslySeenXp: 0,
}
return obj
}, {})
: {
Xp: curData.Xp ?? 0,
Level: curData.Level ?? 1,
PreviouslySeenXp:
curData.PreviouslySeenXp ?? 0,
}
}
return obj
},
{},
)
2023-11-27 12:56:32 -05:00
// ts-expect-error Legacy property.
Multi-Version Mastery and Sniper Scoring (#270) * Add multi-version mastery files * Add pro1 unlocks to legacy allunlockables * Add 47's suit to scpc all unlockables * Add and remove various configs * Remove some useless promises * Fix scpc hub * Fix issue with user profile saving * Fix scpc issues for hub * Add singleplayer/multiplayer sniper * A great many things - Add multi-version mastery - Improve sniper mastery support - Improve general H2016 support * Fix some warnings * Fix pro1 mastery on destination screens * Remove entP from createInventory, lock/unlock pro1 accordingly * Remove JSDoc entP parameter from createInventory * Remove difficultyunlocks from safehouse pages * Add versioned user profiles * Prettier run * Remove false point from user profiles docs * Add comment about profile versioning to types * Fix default profile links * Remove remaining lowercase * Fix sniper showing XP as XP * Add game versions to the unlockable map * Update getMasteryForUnlockable call in planning * Fix missing locations when updating profiles * Update versions to v7 * Fix ICA Facility destination mastery * Fix sniper challenge unlockables showing in inventory * Sniper Scoring (#273) * Initial sniper scoring * Fix linting errors * Update require table * Calculate and display final sniper score on end screen * Bump SMP version to v5.7.0 * Update since version for scoring * Fix create inventory call for sniper scoring * Support sniper unlockables in the inventory * Update versions to v7 * Reflect changes to createInventory in scoreHandler * Get unlockable name in completion data * It was not okay. * Thanks webstorm * Add support for /profiles/page/GetMasteryCompletionDataForUnlockable * Support sniper play next * Remove sniper gamemodes template from overrides * Remove debug prints from scoring event handler * Fix challenge multiplier * Exclude sniper unlockables from stashpoint * Start fixing up the missionEnd response for sniper * Update misleading comment * Use existing global challenge to check for SA on sniper contracts * Re-add removed global challenges * Proper support for the mission end screen on sniper contracts * Remove redundant label --------- Signed-off-by: Anthony Fuller <24512050+AnthonyFuller@users.noreply.github.com> Co-authored-by: Govert de Gans <grappigegovert@hotmail.com> * Add co-op sniper scoring defs * Update MasteryUnlockable template * Bump SMP version to v5.9.3 * Re-add deepmerge * Fix SMP checksum * Fix linting errors caused by merge * Fix score handler imports * Move load flags * Remove unnecessary game version arg * Whoopsies Co-authored-by: Reece Dunham <me@rdil.rocks> Signed-off-by: Anthony Fuller <24512050+AnthonyFuller@users.noreply.github.com> --------- Signed-off-by: Anthony Fuller <24512050+AnthonyFuller@users.noreply.github.com> Co-authored-by: Govert de Gans <grappigegovert@hotmail.com> Co-authored-by: Reece Dunham <me@rdil.rocks>
2023-07-24 23:47:28 +01:00
delete profile.Extensions.progression["Unlockables"]
profile.Version = 1
return updateUserProfile(profile, gameVersion)
}
}
}
/**
* Returns whether a location is a sniper location. Works for both parent and child locations.
* @param location The location ID string.
* @returns A boolean denoting the result.
*/
export function isSniperLocation(location: string): boolean {
return (
location.includes("AUSTRIA") ||
location.includes("SALTY") ||
location.includes("CAGED")
)
}
Multi-Version Mastery and Sniper Scoring (#270) * Add multi-version mastery files * Add pro1 unlocks to legacy allunlockables * Add 47's suit to scpc all unlockables * Add and remove various configs * Remove some useless promises * Fix scpc hub * Fix issue with user profile saving * Fix scpc issues for hub * Add singleplayer/multiplayer sniper * A great many things - Add multi-version mastery - Improve sniper mastery support - Improve general H2016 support * Fix some warnings * Fix pro1 mastery on destination screens * Remove entP from createInventory, lock/unlock pro1 accordingly * Remove JSDoc entP parameter from createInventory * Remove difficultyunlocks from safehouse pages * Add versioned user profiles * Prettier run * Remove false point from user profiles docs * Add comment about profile versioning to types * Fix default profile links * Remove remaining lowercase * Fix sniper showing XP as XP * Add game versions to the unlockable map * Update getMasteryForUnlockable call in planning * Fix missing locations when updating profiles * Update versions to v7 * Fix ICA Facility destination mastery * Fix sniper challenge unlockables showing in inventory * Sniper Scoring (#273) * Initial sniper scoring * Fix linting errors * Update require table * Calculate and display final sniper score on end screen * Bump SMP version to v5.7.0 * Update since version for scoring * Fix create inventory call for sniper scoring * Support sniper unlockables in the inventory * Update versions to v7 * Reflect changes to createInventory in scoreHandler * Get unlockable name in completion data * It was not okay. * Thanks webstorm * Add support for /profiles/page/GetMasteryCompletionDataForUnlockable * Support sniper play next * Remove sniper gamemodes template from overrides * Remove debug prints from scoring event handler * Fix challenge multiplier * Exclude sniper unlockables from stashpoint * Start fixing up the missionEnd response for sniper * Update misleading comment * Use existing global challenge to check for SA on sniper contracts * Re-add removed global challenges * Proper support for the mission end screen on sniper contracts * Remove redundant label --------- Signed-off-by: Anthony Fuller <24512050+AnthonyFuller@users.noreply.github.com> Co-authored-by: Govert de Gans <grappigegovert@hotmail.com> * Add co-op sniper scoring defs * Update MasteryUnlockable template * Bump SMP version to v5.9.3 * Re-add deepmerge * Fix SMP checksum * Fix linting errors caused by merge * Fix score handler imports * Move load flags * Remove unnecessary game version arg * Whoopsies Co-authored-by: Reece Dunham <me@rdil.rocks> Signed-off-by: Anthony Fuller <24512050+AnthonyFuller@users.noreply.github.com> --------- Signed-off-by: Anthony Fuller <24512050+AnthonyFuller@users.noreply.github.com> Co-authored-by: Govert de Gans <grappigegovert@hotmail.com> Co-authored-by: Reece Dunham <me@rdil.rocks>
2023-07-24 23:47:28 +01:00
export function castUserProfile(
profile: UserProfile,
gameVersion: GameVersion,
path?: string,
): UserProfile {
const j = fastClone(profile)
if (!j.Extensions || Object.keys(j.Extensions).length === 0) {
log(LogLevel.DEBUG, "No extensions - skipping validation")
return j
}
let dirty = false
for (const item of [
"PeacockEscalations",
"PeacockFavoriteContracts",
"PeacockPlayedContracts",
"PeacockCompletedEscalations",
2023-01-29 04:35:07 +00:00
"CPD",
]) {
if (!Object.prototype.hasOwnProperty.call(j.Extensions, item)) {
log(LogLevel.DEBUG, `Err missing property ${item}`)
log(
LogLevel.WARN,
`A requested user profile is missing some vital data.`,
)
log(
LogLevel.WARN,
`Attempting to repair the profile automatically...`,
)
if (item === "PeacockEscalations") {
j.Extensions.PeacockEscalations = {}
}
if (item === "PeacockCompletedEscalations") {
j.Extensions.PeacockCompletedEscalations = []
}
if (item === "PeacockFavoriteContracts") {
j.Extensions.PeacockFavoriteContracts = []
}
2023-01-29 04:35:07 +00:00
if (item === "CPD") {
j.Extensions.CPD = {}
}
if (item === "PeacockPlayedContracts") {
j.Extensions.PeacockPlayedContracts = {}
}
dirty = true
}
}
// Fix Extensions.gamepersistentdata.HitsFilterType.
// None of the old profiles should have "MyPlaylist".
if (
!Object.prototype.hasOwnProperty.call(
j.Extensions.gamepersistentdata.HitsFilterType,
"MyPlaylist",
)
) {
j.Extensions.gamepersistentdata.HitsFilterType = {
MyHistory: "all",
MyContracts: "all",
MyPlaylist: "all",
}
}
if (j.Extensions?.gamepersistentdata?.PersistentBool) {
switch (getFlag("mapDiscoveryState")) {
case "REVEALED":
{
const areas = Object.keys(getConfig("AreaMap", false))
for (const area of areas) {
j.Extensions.gamepersistentdata.PersistentBool[area] =
true
}
}
break
case "CLOUDED":
j.Extensions.gamepersistentdata.PersistentBool = {
__Full:
j.Extensions.gamepersistentdata.PersistentBool
?.__Full ?? {},
}
break
}
}
Multi-Version Mastery and Sniper Scoring (#270) * Add multi-version mastery files * Add pro1 unlocks to legacy allunlockables * Add 47's suit to scpc all unlockables * Add and remove various configs * Remove some useless promises * Fix scpc hub * Fix issue with user profile saving * Fix scpc issues for hub * Add singleplayer/multiplayer sniper * A great many things - Add multi-version mastery - Improve sniper mastery support - Improve general H2016 support * Fix some warnings * Fix pro1 mastery on destination screens * Remove entP from createInventory, lock/unlock pro1 accordingly * Remove JSDoc entP parameter from createInventory * Remove difficultyunlocks from safehouse pages * Add versioned user profiles * Prettier run * Remove false point from user profiles docs * Add comment about profile versioning to types * Fix default profile links * Remove remaining lowercase * Fix sniper showing XP as XP * Add game versions to the unlockable map * Update getMasteryForUnlockable call in planning * Fix missing locations when updating profiles * Update versions to v7 * Fix ICA Facility destination mastery * Fix sniper challenge unlockables showing in inventory * Sniper Scoring (#273) * Initial sniper scoring * Fix linting errors * Update require table * Calculate and display final sniper score on end screen * Bump SMP version to v5.7.0 * Update since version for scoring * Fix create inventory call for sniper scoring * Support sniper unlockables in the inventory * Update versions to v7 * Reflect changes to createInventory in scoreHandler * Get unlockable name in completion data * It was not okay. * Thanks webstorm * Add support for /profiles/page/GetMasteryCompletionDataForUnlockable * Support sniper play next * Remove sniper gamemodes template from overrides * Remove debug prints from scoring event handler * Fix challenge multiplier * Exclude sniper unlockables from stashpoint * Start fixing up the missionEnd response for sniper * Update misleading comment * Use existing global challenge to check for SA on sniper contracts * Re-add removed global challenges * Proper support for the mission end screen on sniper contracts * Remove redundant label --------- Signed-off-by: Anthony Fuller <24512050+AnthonyFuller@users.noreply.github.com> Co-authored-by: Govert de Gans <grappigegovert@hotmail.com> * Add co-op sniper scoring defs * Update MasteryUnlockable template * Bump SMP version to v5.9.3 * Re-add deepmerge * Fix SMP checksum * Fix linting errors caused by merge * Fix score handler imports * Move load flags * Remove unnecessary game version arg * Whoopsies Co-authored-by: Reece Dunham <me@rdil.rocks> Signed-off-by: Anthony Fuller <24512050+AnthonyFuller@users.noreply.github.com> --------- Signed-off-by: Anthony Fuller <24512050+AnthonyFuller@users.noreply.github.com> Co-authored-by: Govert de Gans <grappigegovert@hotmail.com> Co-authored-by: Reece Dunham <me@rdil.rocks>
2023-07-24 23:47:28 +01:00
if (j.Version !== LATEST_PROFILE_VERSION) {
// This profile is not the latest version. We must update it.
log(LogLevel.DEBUG, `Profile is outdated, updating...`)
updateUserProfile(j, gameVersion)
dirty = true
}
if (dirty) {
Multi-Version Mastery and Sniper Scoring (#270) * Add multi-version mastery files * Add pro1 unlocks to legacy allunlockables * Add 47's suit to scpc all unlockables * Add and remove various configs * Remove some useless promises * Fix scpc hub * Fix issue with user profile saving * Fix scpc issues for hub * Add singleplayer/multiplayer sniper * A great many things - Add multi-version mastery - Improve sniper mastery support - Improve general H2016 support * Fix some warnings * Fix pro1 mastery on destination screens * Remove entP from createInventory, lock/unlock pro1 accordingly * Remove JSDoc entP parameter from createInventory * Remove difficultyunlocks from safehouse pages * Add versioned user profiles * Prettier run * Remove false point from user profiles docs * Add comment about profile versioning to types * Fix default profile links * Remove remaining lowercase * Fix sniper showing XP as XP * Add game versions to the unlockable map * Update getMasteryForUnlockable call in planning * Fix missing locations when updating profiles * Update versions to v7 * Fix ICA Facility destination mastery * Fix sniper challenge unlockables showing in inventory * Sniper Scoring (#273) * Initial sniper scoring * Fix linting errors * Update require table * Calculate and display final sniper score on end screen * Bump SMP version to v5.7.0 * Update since version for scoring * Fix create inventory call for sniper scoring * Support sniper unlockables in the inventory * Update versions to v7 * Reflect changes to createInventory in scoreHandler * Get unlockable name in completion data * It was not okay. * Thanks webstorm * Add support for /profiles/page/GetMasteryCompletionDataForUnlockable * Support sniper play next * Remove sniper gamemodes template from overrides * Remove debug prints from scoring event handler * Fix challenge multiplier * Exclude sniper unlockables from stashpoint * Start fixing up the missionEnd response for sniper * Update misleading comment * Use existing global challenge to check for SA on sniper contracts * Re-add removed global challenges * Proper support for the mission end screen on sniper contracts * Remove redundant label --------- Signed-off-by: Anthony Fuller <24512050+AnthonyFuller@users.noreply.github.com> Co-authored-by: Govert de Gans <grappigegovert@hotmail.com> * Add co-op sniper scoring defs * Update MasteryUnlockable template * Bump SMP version to v5.9.3 * Re-add deepmerge * Fix SMP checksum * Fix linting errors caused by merge * Fix score handler imports * Move load flags * Remove unnecessary game version arg * Whoopsies Co-authored-by: Reece Dunham <me@rdil.rocks> Signed-off-by: Anthony Fuller <24512050+AnthonyFuller@users.noreply.github.com> --------- Signed-off-by: Anthony Fuller <24512050+AnthonyFuller@users.noreply.github.com> Co-authored-by: Govert de Gans <grappigegovert@hotmail.com> Co-authored-by: Reece Dunham <me@rdil.rocks>
2023-07-24 23:47:28 +01:00
writeFileSync(path ?? `userdata/users/${j.Id}.json`, JSON.stringify(j))
log(LogLevel.INFO, "Profile successfully repaired!")
}
return j
}
export const defaultSuits = {
LOCATION_PARENT_ICA_FACILITY: "TOKEN_OUTFIT_GREENLAND_HERO_TRAININGSUIT",
LOCATION_PARENT_PARIS: "TOKEN_OUTFIT_PARIS_HERO_PARISSUIT",
LOCATION_PARENT_COASTALTOWN: "TOKEN_OUTFIT_SAPIENZA_HERO_SAPIENZASUIT",
LOCATION_COASTALTOWN_MOVIESET:
"TOKEN_OUTFIT_SAPIENZA_HERO_SAPIENZASUIT_NOGLASSES",
LOCATION_COASTALTOWN_EBOLA:
"TOKEN_OUTFIT_SAPIENZA_HERO_SAPIENZASUIT_NOGLASSES",
LOCATION_PARENT_MARRAKECH: "TOKEN_OUTFIT_MARRAKESH_HERO_MARRAKESHSUIT",
LOCATION_PARENT_BANGKOK: "TOKEN_OUTFIT_BANGKOK_HERO_BANGKOKSUIT",
LOCATION_PARENT_COLORADO: "TOKEN_OUTFIT_COLORADO_HERO_COLORADOSUIT",
LOCATION_PARENT_HOKKAIDO: "TOKEN_OUTFIT_HOKKAIDO_HERO_HOKKAIDOSUIT",
LOCATION_PARENT_NEWZEALAND: "TOKEN_OUTFIT_WET_SUIT",
LOCATION_PARENT_MIAMI: "TOKEN_OUTFIT_MIAMI_HERO_MIAMISUIT",
LOCATION_PARENT_COLOMBIA: "TOKEN_OUTFIT_COLOMBIA_HERO_COLOMBIASUIT",
LOCATION_PARENT_MUMBAI: "TOKEN_OUTFIT_MUMBAI_HERO_MUMBAISUIT",
LOCATION_PARENT_NORTHAMERICA:
"TOKEN_OUTFIT_NORTHAMERICA_HERO_NORTHAMERICASUIT",
LOCATION_PARENT_NORTHSEA: "TOKEN_OUTFIT_NORTHSEA_HERO_NORTHSEASUIT",
LOCATION_PARENT_GREEDY: "TOKEN_OUTFIT_GREEDY_HERO_GREEDYSUIT",
LOCATION_PARENT_OPULENT: "TOKEN_OUTFIT_OPULENT_HERO_OPULENTSUIT",
LOCATION_PARENT_GOLDEN: "TOKEN_OUTFIT_HERO_GECKO_SUIT",
LOCATION_PARENT_ANCESTRAL: "TOKEN_OUTFIT_ANCESTRAL_HERO_ANCESTRALSUIT",
LOCATION_ANCESTRAL_SMOOTHSNAKE:
"TOKEN_OUTFIT_ANCESTRAL_HERO_SMOOTHSNAKESUIT",
LOCATION_PARENT_EDGY: "TOKEN_OUTFIT_EDGY_HERO_EDGYSUIT",
LOCATION_PARENT_WET: "TOKEN_OUTFIT_WET_HERO_WETSUIT",
LOCATION_PARENT_ELEGANT: "TOKEN_OUTFIT_ELEGANT_HERO_LLAMASUIT",
LOCATION_PARENT_TRAPPED: "TOKEN_OUTFIT_TRAPPED_WOLVERINE_SUIT",
LOCATION_PARENT_ROCKY: "TOKEN_OUTFIT_HERO_DUGONG_SUIT",
}
/**
* Default suits that are attainable via challenges or mastery in this version.
* NOTE: Currently this is hardcoded. To allow for flexibility and extensibility, this should be generated in real-time
* using the Drops of challenges and masteries. However, that would require looping through all challenges and masteries
* for all default suits, which is slow. This is a trade-off.
* @param gameVersion The game version.
* @returns The default suits that are attainable via challenges or mastery.
*/
export function attainableDefaults(gameVersion: GameVersion): string[] {
return gameVersion === "h1"
? []
: gameVersion === "h2"
? ["TOKEN_OUTFIT_WET_SUIT"]
: [
"TOKEN_OUTFIT_GREENLAND_HERO_TRAININGSUIT",
"TOKEN_OUTFIT_WET_SUIT",
"TOKEN_OUTFIT_HERO_DUGONG_SUIT",
]
}
/**
* Gets the default suit for a given sub-location and parent location.
* Priority is given to the sub-location, then the parent location, then 47's signature suit.
* @param subLocation The sub-location.
* @returns The default suit for the given sub-location and parent location.
*/
2023-11-27 12:56:32 -05:00
export function getDefaultSuitFor(subLocation: Unlockable): string | undefined {
return (
defaultSuits[subLocation.Id] ||
defaultSuits[subLocation.Properties.ParentLocation] ||
"TOKEN_OUTFIT_HITMANSUIT"
)
}
export const nilUuid = "00000000-0000-0000-0000-000000000000"
export const hitmapsUrl = "https://backend.rdil.rocks/partners/hitmaps/contract"
export function isObjectiveActive(
objective: MissionManifestObjective,
doneObjectives: Set<RepositoryId>,
): boolean {
if (objective.Activation !== undefined) {
if (Array.isArray(objective.Activation.$eq)) {
return (
objective.Activation.$eq[1] === "Completed" &&
doneObjectives.has(
(<string>objective.Activation.$eq[0]).substring(1),
)
)
}
}
return false
}
export const jokes = [
"STILL... we are close now, 47.",
"James Batty, the plaintiff, wants Janus to stop his annual landing of a helicopter, near the local creek.",
"Searching for local masons in your area...",
"I wonder what kind of curry currymaker makes",
"Listening for uncommon guard voice lines...",
"Mistah Jason Portman, please come to the hospital entrance. A doctor will escort you to your checkup. That was for: mistah Jason Portman.",
"Nakamura-San, please come to the operating theatre. Stat.",
"Ugh, my knee is so sore.",
"Mister Prichard I presume? Hi, I'm Chen Ting. Pleasure to meet you.",
"Find your inner... zen",
"I love those little drones when they scoot around like that.",
"Welcome, welcome! Hello! Good to see you. So lovely to see so many familiar faces here today.",
"hi so i own hitman 1 and 2 i got hitman 1 and 2 on disc hitman 1 def edition and hitman 2 gold disc both on ps4 and when i got hitman 2 i downloaded the best legesy pack and all of my saves are on hitman 2 but i got rid of that game will i need both of them to get all the levels onto hitman 3 and im staying on ps4",
"The weather is always nice in Paris.",
"Have you seen a girl around? Short hair, with a bright green bag?",
"The show is just about to start.",
"Entering the Ether lab requires a uniform and a keycard... luckily, it seems both are within reach.",
"Welcome to Bangkok, 47. The target has been in residence at the hotel for almost a month and security is tight, with several other high-profile guests also at the hotel. Good Hunting.",
]
/**
* The current game difficulty.
*/
export const gameDifficulty = {
/**
* The game isn't on a set difficulty (missions with no difficulties data?).
*/
unset: 0,
/**
* Casual mode.
*/
casual: 1,
easy: 1,
/**
* Professional (normal) mode.
*/
normal: 2,
/**
* Master mode.
*/
master: 4,
hard: 4,
2022-12-12 16:38:55 -05:00
} as const
export function difficultyToString(difficulty: number): string {
switch (difficulty) {
case 1:
return "casual"
case 2:
return "normal"
case 4:
return "master"
case 0:
default:
return "unset"
}
}
/**
* Handle an {@link AxiosError} from axios.
*
* @see https://axios-http.com/docs/handling_errors
* @param error The error from axios.
*/
export function handleAxiosError(error: AxiosError): void {
if (error.response) {
// The request was made and the server responded with a status code
// that falls out of the range of 2xx
log(LogLevel.DEBUG, `code ${error.response.status}`)
} else if (error.request) {
// The request was made but no response was received
// `error.request` is an instance of http.ClientRequest
log(LogLevel.DEBUG, `bad fetch`)
} else {
// Something happened in setting up the request that triggered an Error
log(LogLevel.DEBUG, `generic`)
}
}
export function unlockOrderComparer(a: Unlockable, b: Unlockable): number {
return (
(a?.Properties?.UnlockOrder ?? Number.POSITIVE_INFINITY) -
(b?.Properties?.UnlockOrder ?? Number.POSITIVE_INFINITY) || 0
)
}
/**
* Converts a contract's public ID as a long-form number into the version with dashes.
*
* @param publicId The ID without dashes.
* @returns The ID with dashes.
*/
export function addDashesToPublicId(publicId: string): string {
if (publicId.includes("-")) {
// this work is already done
return publicId
}
let id = publicId
id = id.slice(0, 1) + "-" + id.slice(1)
id = id.slice(0, 4) + "-" + id.slice(4)
id = id.slice(0, 12) + "-" + id.slice(12)
return id
}
/**
* A fast implementation of deep object cloning.
*
* @param item The item to clone.
* @returns The new item.
*/
export function fastClone<T>(item: T): T {
return structuredClone(item)
}
Rewrite the escalation service to use group contracts (#63) * 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>
2023-04-13 22:13:16 -04:00
/**
* Returns if the specified repository ID is a suit.
*
* @param repoId The repository ID.
* @returns If the repository ID points to a suit.
*/
export function isSuit(repoId: string): boolean {
const suitsToTypeMap: Record<string, string> = {}
const unlockablesFiltered = getConfig<readonly Unlockable[]>(
"allunlockables",
false,
).filter((unlockable) => unlockable.Type === "disguise")
for (const u of unlockablesFiltered) {
2023-11-27 12:56:32 -05:00
if (u.Subtype && u.Properties.RepositoryId) {
suitsToTypeMap[u.Properties.RepositoryId] = u.Subtype
}
}
Rewrite the escalation service to use group contracts (#63) * 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>
2023-04-13 22:13:16 -04:00
return suitsToTypeMap[repoId]
? suitsToTypeMap[repoId] !== "disguise"
: false
}