mirror of
https://github.com/thepeacockproject/Peacock
synced 2024-11-22 22:12:45 +01:00
51868f88a2
* Add support for Career -> Mastery page * Add support H2016 for Career -> Mastery page * Fix mastery not showing on H2016 destinations page * Switch pro1 mastery to available like destinations
342 lines
14 KiB
TypeScript
342 lines
14 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/>.
|
|
*/
|
|
|
|
/* eslint-disable @typescript-eslint/ban-ts-comment */
|
|
// @ts-nocheck
|
|
|
|
import { existsSync, mkdirSync, readFileSync, writeFileSync } from "fs"
|
|
import { join } from "path"
|
|
import { log, LogLevel } from "./loggingInterop"
|
|
|
|
import Roadmap from "../static/Roadmap.json"
|
|
import StoreData from "../static/StoreData.json"
|
|
import FilterData from "../static/FilterData.json"
|
|
import LocationsData from "../static/LocationsData.json"
|
|
import GameChangerProperties from "../static/GameChangerProperties.json"
|
|
import allunlockables from "../static/allunlockables.json"
|
|
import connectionConfigTemplate from "../static/config.json"
|
|
import onlineconfig from "../static/onlineconfig.json"
|
|
import privacypolicy from "../static/privacypolicy.json"
|
|
import UserDefault from "../static/UserDefault.json"
|
|
import AgencyPickups from "../static/AgencyPickups.json"
|
|
import Entrances from "../static/Entrances.json"
|
|
import LeaderboardEntriesTemplate from "../static/LeaderboardEntriesTemplate.json"
|
|
import LeaderboardsViewTemplate from "../static/LeaderboardsViewTemplate.json"
|
|
import MissionEndReadyTemplate from "../static/MissionEndReadyTemplate.json"
|
|
import MissionEndNotReadyTemplate from "../static/MissionEndNotReadyTemplate.json"
|
|
import SelectAgencyPickupTemplate from "../static/SelectAgencyPickupTemplate.json"
|
|
import SelectEntranceTemplate from "../static/SelectEntranceTemplate.json"
|
|
import StashpointTemplate from "../static/StashpointTemplate.json"
|
|
import LoadMenuTemplate from "../static/LoadMenuTemplate.json"
|
|
import SaveMenuTemplate from "../static/SaveMenuTemplate.json"
|
|
import Playstyles from "../static/Playstyles.json"
|
|
import HubPageData from "../static/HubPageData.json"
|
|
import DashboardCategoryEscalation from "../static/DashboardCategoryEscalation.json"
|
|
import GlobalChallenges from "../static/GlobalChallenges.json"
|
|
import ContractsTemplate from "../static/ContractsTemplate.json"
|
|
import CreateContractPlanningTemplate from "../static/CreateContractPlanningTemplate.json"
|
|
import CreateContractReturnTemplate from "../static/CreateContractReturnTemplate.json"
|
|
import PlayerProfilePage from "../static/PlayerProfileView.json"
|
|
import Legacyallunlockables from "../static/Legacyallunlockables.json"
|
|
import LegacyGlobalChallenges from "../static/LegacyGlobalChallenges.json"
|
|
import LegacySafehouseTemplate from "../static/LegacySafehouseTemplate.json"
|
|
import LegacyHubTemplate from "../static/LegacyHubTemplate.json"
|
|
import LegacyPlanningTemplate from "../static/LegacyPlanningTemplate.json"
|
|
import LegacySelectAgencyPickupTemplate from "../static/LegacySelectAgencyPickupTemplate.json"
|
|
import LegacySelectEntranceTemplate from "../static/LegacySelectEntranceTemplate.json"
|
|
import LegacyStashpointTemplate from "../static/LegacyStashpointTemplate.json"
|
|
import LegacyUserDefault from "../static/LegacyUserDefault.json"
|
|
import LegacyContractSearchResponseTemplate from "../static/LegacyContractSearchResponseTemplate.json"
|
|
import LegacyFilterData from "../static/LegacyFilterData.json"
|
|
import PlayNextTemplate from "../static/PlayNextTemplate.json"
|
|
import LookupContractByIdTemplate from "../static/LookupContractByIdTemplate.json"
|
|
import LookupContractFavoriteTemplate from "../static/LookupContractFavoriteTemplate.json"
|
|
import MissionStories from "../static/MissionStories.json"
|
|
import DebriefingLeaderboardsTemplate from "../static/DebriefingLeaderboardsTemplate.json"
|
|
import LegacyHitsCategoryTemplate from "../static/LegacyHitsCategoryTemplate.json"
|
|
import LegacyStoreData from "../static/LegacyStoreData.json"
|
|
import LegacyDestinations from "../static/LegacyDestinations.json"
|
|
import LegacyDestinationTemplate from "../static/LegacyDestinationTemplate.json"
|
|
import LegacyLocationsData from "../static/LegacyLocationsData.json"
|
|
import LegacySaveMenuTemplate from "../static/LegacySaveMenuTemplate.json"
|
|
import LegacyLoadMenuTemplate from "../static/LegacyLoadMenuTemplate.json"
|
|
import LegacyLookupContractByIdTemplate from "../static/LegacyLookupContractByIdTemplate.json"
|
|
import EiderDashboard from "../static/EiderDashboard.json"
|
|
import H2allunlockables from "../static/H2allunlockables.json"
|
|
import H2DestinationsData from "../static/H2DestinationsData.json"
|
|
import H2StoreData from "../static/H2StoreData.json"
|
|
import H2ContractSearchResponseTemplate from "../static/H2ContractSearchResponseTemplate.json"
|
|
import H2LocationsData from "../static/H2LocationsData.json"
|
|
import H2FilterData from "../static/H2FilterData.json"
|
|
import H2DashboardTemplate from "../static/H2DashboardTemplate.json"
|
|
import H2LookupContractTemplate from "../static/H2LookupContractTemplate.json"
|
|
import FrankensteinHubTemplate from "../static/FrankensteinHubTemplate.json"
|
|
import FrankensteinMmSpTemplate from "../static/FrankensteinMmSpTemplate.json"
|
|
import FrankensteinMmMpTemplate from "../static/FrankensteinMmMpTemplate.json"
|
|
import FrankensteinScoreOverviewTemplate from "../static/FrankensteinScoreOverviewTemplate.json"
|
|
import FrankensteinPlanningTemplate from "../static/FrankensteinPlanningTemplate.json"
|
|
import Videos from "../static/Videos.json"
|
|
import ChallengeLocationTemplate from "../static/ChallengeLocationTemplate.json"
|
|
import H2ChallengeLocationTemplate from "../static/H2ChallengeLocationTemplate.json"
|
|
import LegacyChallengeLocationTemplate from "../static/LegacyChallengeLocationTemplate.json"
|
|
import ReportTemplate from "../static/ReportTemplate.json"
|
|
import ContractSearchPageTemplate from "../static/ContractSearchPageTemplate.json"
|
|
import ContractSearchPaginateTemplate from "../static/ContractSearchPaginateTemplate.json"
|
|
import ContractSearchResponseTemplate from "../static/ContractSearchResponseTemplate.json"
|
|
import LegacyDebriefingChallengesTemplate from "../static/LegacyDebriefingChallengesTemplate.json"
|
|
import DebriefingChallengesTemplate from "../static/DebriefingChallengesTemplate.json"
|
|
import MasteryUnlockablesTemplate from "../static/MasteryUnlockablesTemplate.json"
|
|
import SniperLoadouts from "../static/SniperLoadouts.json"
|
|
import Scpcallunlockables from "../static/Scpcallunlockables.json"
|
|
import DiscordRichAssetsForBricks from "../static/DiscordRichAssetsForBricks.json"
|
|
import EscalationCodenames from "../static/EscalationCodenames.json"
|
|
import scoreoverviewtemplate from "../static/scoreoverviewtemplate.json"
|
|
import PeacockGameChangerProperties from "../static/PeacockGameChangerProperties.json"
|
|
import MultiplayerPresets from "../static/MultiplayerPresets.json"
|
|
import LobbySlimTemplate from "../static/LobbySlimTemplate.json"
|
|
import MasteryDataForLocationTemplate from "../static/MasteryDataForLocationTemplate.json"
|
|
import LegacyMasteryLocationTemplate from "../static/LegacyMasteryLocationTemplate.json"
|
|
import DefaultCpdConfig from "../static/DefaultCpdConfig.json"
|
|
import EvergreenGameChangerProperties from "../static/EvergreenGameChangerProperties.json"
|
|
import AreaMap from "../static/AreaMap.json"
|
|
import HitsCategoryElusiveTemplate from "../static/HitsCategoryElusiveTemplate.json"
|
|
import type { GameVersion } from "./types/types"
|
|
import { fastClone } from "./utils"
|
|
|
|
/**
|
|
* All the configurations. Gets modified before being exported.
|
|
*
|
|
* @private
|
|
*/
|
|
const configs: Record<string, unknown> = {
|
|
Roadmap,
|
|
StoreData,
|
|
FilterData,
|
|
LocationsData,
|
|
LeaderboardsViewTemplate,
|
|
LeaderboardEntriesTemplate,
|
|
GameChangerProperties,
|
|
allunlockables,
|
|
config: connectionConfigTemplate,
|
|
onlineconfig,
|
|
privacypolicy,
|
|
UserDefault,
|
|
AgencyPickups,
|
|
Entrances,
|
|
MissionEndReadyTemplate,
|
|
MissionEndNotReadyTemplate,
|
|
SelectAgencyPickupTemplate,
|
|
SelectEntranceTemplate,
|
|
StashpointTemplate,
|
|
LoadMenuTemplate,
|
|
SaveMenuTemplate,
|
|
Playstyles,
|
|
HubPageData,
|
|
DashboardCategoryEscalation,
|
|
GlobalChallenges,
|
|
ContractsTemplate,
|
|
CreateContractPlanningTemplate,
|
|
CreateContractReturnTemplate,
|
|
PlayerProfilePage,
|
|
Legacyallunlockables,
|
|
LegacyGlobalChallenges,
|
|
LegacySafehouseTemplate,
|
|
LegacyHubTemplate,
|
|
LegacyPlanningTemplate,
|
|
LegacySelectAgencyPickupTemplate,
|
|
LegacySelectEntranceTemplate,
|
|
LegacyStashpointTemplate,
|
|
LegacyUserDefault,
|
|
LegacyFilterData,
|
|
PlayNextTemplate,
|
|
LookupContractByIdTemplate,
|
|
LookupContractFavoriteTemplate,
|
|
MissionStories,
|
|
DebriefingLeaderboardsTemplate,
|
|
LegacyHitsCategoryTemplate,
|
|
LegacyStoreData,
|
|
LegacyDestinations,
|
|
LegacyDestinationTemplate,
|
|
LegacyLocationsData,
|
|
LegacySaveMenuTemplate,
|
|
LegacyLoadMenuTemplate,
|
|
LegacyContractSearchResponseTemplate,
|
|
LegacyDebriefingChallengesTemplate,
|
|
DebriefingChallengesTemplate,
|
|
LegacyLookupContractByIdTemplate,
|
|
EiderDashboard,
|
|
FrankensteinHubTemplate,
|
|
H2allunlockables,
|
|
H2DestinationsData,
|
|
H2StoreData,
|
|
H2ContractSearchResponseTemplate,
|
|
H2LocationsData,
|
|
H2LookupContractByIdTemplate: H2LookupContractTemplate,
|
|
H2LookupContractFavoriteTemplate: H2LookupContractTemplate,
|
|
H2FilterData,
|
|
H2DashboardTemplate,
|
|
FrankensteinMmSpTemplate,
|
|
FrankensteinMmMpTemplate,
|
|
FrankensteinPlanningTemplate,
|
|
FrankensteinScoreOverviewTemplate,
|
|
Videos,
|
|
ChallengeLocationTemplate,
|
|
H2ChallengeLocationTemplate,
|
|
LegacyChallengeLocationTemplate,
|
|
ReportTemplate,
|
|
ContractSearchPageTemplate,
|
|
ContractSearchPaginateTemplate,
|
|
ContractSearchResponseTemplate,
|
|
MasteryUnlockablesTemplate,
|
|
SniperLoadouts,
|
|
Scpcallunlockables,
|
|
DiscordRichAssetsForBricks,
|
|
EscalationCodenames,
|
|
scoreoverviewtemplate,
|
|
PeacockGameChangerProperties,
|
|
MultiplayerPresets,
|
|
LobbySlimTemplate,
|
|
MasteryDataForLocationTemplate,
|
|
LegacyMasteryLocationTemplate,
|
|
DefaultCpdConfig,
|
|
EvergreenGameChangerProperties,
|
|
AreaMap,
|
|
HitsCategoryElusiveTemplate,
|
|
}
|
|
|
|
Object.keys(configs).forEach((cfg) => {
|
|
// Parse the string into an object
|
|
configs[cfg] = JSON.parse(configs[cfg])
|
|
|
|
const overridePath = join("overrides", `${cfg}.json`)
|
|
|
|
if (existsSync(overridePath)) {
|
|
log(LogLevel.INFO, `Loaded override config for ${cfg}.`)
|
|
configs[cfg] = JSON.parse(readFileSync(overridePath).toString())
|
|
}
|
|
})
|
|
|
|
export { configs }
|
|
|
|
/**
|
|
* Get a config file.
|
|
* Configs for H1 start with "Legacy", "H2" for HITMAN 2, and no prefix for HITMAN 3.
|
|
*
|
|
* @param config The name of the config file.
|
|
* @param clone If the value should be cloned (saves memory if false, but as a side effect, modifications will affect the actual config).
|
|
* @returns The config.
|
|
* @throws {Error} If the config file specified doesn't exist.
|
|
*/
|
|
export function getConfig<T = unknown>(config: string, clone: boolean): T {
|
|
if (configs.hasOwnProperty.call(configs, config)) {
|
|
if (!clone) {
|
|
return configs[config]
|
|
}
|
|
|
|
// properly create object clones
|
|
// this could be better, but this is the best temporary solution
|
|
return fastClone(configs[config])
|
|
}
|
|
|
|
throw new Error(`Tried to lookup config that does not exist: ${config}`)
|
|
}
|
|
|
|
/**
|
|
* Get a config file intended for the specified game version.
|
|
*
|
|
* @param config The name of the config file.
|
|
* @param gameVersion The game's version ("h1", "h2", or "h3").
|
|
* @param clone If the config should be cloned (saves memory if false, but as a side effect, modifications will affect the actual config).
|
|
* @returns The config.
|
|
* @see getConfig
|
|
* @throws {Error} If the config file specified doesn't exist.
|
|
*/
|
|
export function getVersionedConfig<T = unknown>(
|
|
config: string,
|
|
gameVersion: GameVersion,
|
|
clone: boolean,
|
|
): T {
|
|
let h1Prefix = ""
|
|
|
|
if (
|
|
// is this scpc, do we have a scpc config?
|
|
gameVersion === "scpc" &&
|
|
Object.prototype.hasOwnProperty.call(configs, `Scpc${config}`)
|
|
) {
|
|
h1Prefix = "Scpc"
|
|
} else {
|
|
// the above condition wasn't true
|
|
if (["scpc", "h1"].includes(gameVersion)) {
|
|
h1Prefix = "Legacy"
|
|
}
|
|
}
|
|
|
|
// if this is H2, but we don't have a h2 specific config, fall back to h3
|
|
if (
|
|
gameVersion === "h2" &&
|
|
!Object.prototype.hasOwnProperty.call(configs, `H2${config}`)
|
|
) {
|
|
return getConfig(config, clone)
|
|
}
|
|
|
|
return getConfig(
|
|
`${h1Prefix}${gameVersion === "h2" ? "H2" : ""}${config}`,
|
|
clone,
|
|
)
|
|
}
|
|
|
|
/**
|
|
* Creates an override config.
|
|
*
|
|
* @param name The name of the config to override.
|
|
*/
|
|
export function swizzle(name: string): void {
|
|
if (existsSync(join("overrides", `${name}.json`))) {
|
|
log(
|
|
LogLevel.ERROR,
|
|
`That file already exists in overrides/${name}.json - Aborting.`,
|
|
)
|
|
process.exit(1)
|
|
}
|
|
|
|
if (!Object.prototype.hasOwnProperty.call(configs, name)) {
|
|
log(LogLevel.ERROR, `No configs have the name ${name} - Aborting.`)
|
|
process.exit(1)
|
|
}
|
|
|
|
if (!existsSync("overrides")) {
|
|
mkdirSync("overrides")
|
|
}
|
|
|
|
writeFileSync(
|
|
join("overrides", `${name}.json`),
|
|
JSON.stringify(configs[name]),
|
|
)
|
|
|
|
log(LogLevel.INFO, `Done! Wrote override to overrides/${name}.json`)
|
|
}
|
|
|
|
/**
|
|
* Gets a list of swizzleable configurations.
|
|
*
|
|
* @returns A list of swizzleable configs.
|
|
*/
|
|
export function getSwizzleable(): string[] {
|
|
return Object.keys(configs)
|
|
}
|