mirror of
https://github.com/thepeacockproject/Peacock
synced 2024-11-22 22:12:45 +01:00
8ec9fb1824
Signed-off-by: Reece Dunham <me@rdil.rocks>
376 lines
18 KiB
TypeScript
376 lines
18 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 { RPCClient } from "./discord/client"
|
|
import { getConfig } from "./configSwizzleManager"
|
|
import type { GameVersion, MissionType } from "./types/types"
|
|
import { getFlag } from "./flags"
|
|
import { log, LogLevel } from "./loggingInterop"
|
|
|
|
let rpcClient: undefined | RPCClient
|
|
/*@__NOINLINE__*/
|
|
const processStartTime = Math.round(Date.now() / 1000)
|
|
|
|
export function initRp(): void {
|
|
Object.keys(getConfig("Entrances", false)).forEach((key) => {
|
|
if (!scenePathToRpAsset(key, []) && PEACOCK_DEV) {
|
|
log(LogLevel.DEBUG, `WARNING missing scene ${key} for RP!`)
|
|
}
|
|
})
|
|
|
|
// creates a new rp client, pretty self-explanatory.
|
|
rpcClient = new RPCClient()
|
|
|
|
// connects to the Peacock discord developer app, which contains the images for the rp.
|
|
rpcClient.login({
|
|
clientId: "846361353027584013",
|
|
})
|
|
|
|
// checks if the rp is on the state "ready", and starts the rp, displaying the details on discord.
|
|
rpcClient.on("ready", () => {
|
|
swapToIdle()
|
|
})
|
|
}
|
|
|
|
/**
|
|
* Sets the user's Discord RP status to "browsing menus" if the feature is enabled.
|
|
*
|
|
* @param gameVersion The game version.
|
|
*/
|
|
export function swapToBrowsingMenusStatus(gameVersion: GameVersion): void {
|
|
if (getFlag("discordRp") === true) {
|
|
rpcClient?.setActivity({
|
|
details: `Playing HITMAN™ ${gameVersion
|
|
.substring(1)
|
|
.replace("1", "(2016)")}`,
|
|
largeImageKey: gameVersion,
|
|
largeImageText: "Browsing Menus",
|
|
smallImageKey: "peacock",
|
|
smallImageText: "Using Peacock",
|
|
startTimestamp:
|
|
getFlag("discordRpAppTime") === true
|
|
? processStartTime
|
|
: Math.round(Date.now() / 1000),
|
|
})
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Sets the user's Discord RP status to "idle" if the feature is enabled.
|
|
*/
|
|
export function swapToIdle(): void {
|
|
if (getFlag("discordRp") === true) {
|
|
rpcClient?.setActivity({
|
|
details: "Idle",
|
|
largeImageKey: "peacock",
|
|
largeImageText: "Idling",
|
|
startTimestamp:
|
|
getFlag("discordRpAppTime") === true
|
|
? processStartTime
|
|
: Math.round(Date.now() / 1000),
|
|
})
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Sets the user's Discord RP status to playing something if the feature is enabled.
|
|
*
|
|
* @param scenePath The path to the loaded scene, used to determine names/assets used.
|
|
* @param missionType The mission's type.
|
|
* @param bricks The mission's loaded bricks.
|
|
*/
|
|
export function swapToLocationStatus(
|
|
scenePath: string,
|
|
missionType: MissionType,
|
|
bricks: string[],
|
|
): void {
|
|
if (getFlag("discordRp") !== true) {
|
|
return
|
|
}
|
|
|
|
const details = scenePathToRpAsset(scenePath, bricks)
|
|
|
|
if (!Array.isArray(details)) {
|
|
// we need to handle this somehow in the future
|
|
return
|
|
}
|
|
|
|
const formattedMissionType =
|
|
missionType === "orbis"
|
|
? "Sarajevo Six"
|
|
: `${missionType
|
|
.substring(0, 1)
|
|
.toUpperCase()}${missionType.substring(1)}`
|
|
|
|
rpcClient?.setActivity({
|
|
state: `${formattedMissionType} in ${details[2]}`,
|
|
details: details[1],
|
|
largeImageKey: details[0],
|
|
largeImageText: details[1],
|
|
smallImageKey: "peacock",
|
|
smallImageText: "Using Peacock",
|
|
startTimestamp:
|
|
getFlag("discordRpAppTime") === true
|
|
? processStartTime
|
|
: Math.round(Date.now() / 1000),
|
|
})
|
|
}
|
|
|
|
type BrickDataMap = Record<string, [string, string, string]>
|
|
|
|
/**
|
|
* Translates a scene path to a Discord RP asset and human-readable name.
|
|
*
|
|
* @param scenePath The scene path.
|
|
* @param bricks The mission's loaded bricks.
|
|
* @returns An array of the RP asset, human-readable name, and location human-readable name.
|
|
*/
|
|
export function scenePathToRpAsset(
|
|
scenePath: string,
|
|
bricks: string[],
|
|
): string[] | undefined {
|
|
const brickAssetsMap = getConfig<BrickDataMap>(
|
|
"DiscordRichAssetsForBricks",
|
|
false,
|
|
)
|
|
|
|
for (const brick of bricks) {
|
|
if (
|
|
Object.prototype.hasOwnProperty.call(
|
|
brickAssetsMap,
|
|
brick.toLowerCase(),
|
|
)
|
|
) {
|
|
return brickAssetsMap[brick.toLowerCase()]!
|
|
}
|
|
}
|
|
|
|
switch (scenePath.toLowerCase()) {
|
|
// paris
|
|
case "assembly:/_pro/scenes/missions/paris/_scene_paris.entity":
|
|
case "assembly:/_pro/scenes/missions/paris/_scene_paris_torenia.entity":
|
|
case "assembly:/_pro/scenes/missions/paris/_scene_fashionshowhit_01.entity":
|
|
case "assembly:/_pro/scenes/missions/paris/_scene_tutorial_contractcreationparis.entity":
|
|
case "assembly:/_pro/scenes/missions/paris/_scene_fashionshowhit_amd.entity":
|
|
return ["parisshowstopper", "The Showstopper", "Paris"]
|
|
case "assembly:/_pro/scenes/missions/paris/_scene_tequilasunrise_01.entity":
|
|
return ["elusivetequilasunrise", "The Forger", "Paris"]
|
|
case "assembly:/_pro/scenes/missions/paris/_scene_whiterussian_01.entity":
|
|
return ["elusivewhiterussian", "The Identity Thief", "Paris"]
|
|
|
|
// sapienza
|
|
case "assembly:/_pro/scenes/missions/coastaltown/_scene_copperhead.entity":
|
|
case "assembly:/_pro/scenes/missions/coastaltown/_scene_mission_copperhead.entity":
|
|
return ["sapienzaicon", "The Icon", "Sapienza"]
|
|
case "assembly:/_pro/scenes/missions/coastaltown/_scene_mamba.entity":
|
|
case "assembly:/_pro/scenes/missions/coastaltown/_scene_mission_mamba.entity":
|
|
return ["sapienzalandslide", "Landslide", "Sapienza"]
|
|
case "assembly:/_pro/scenes/missions/coastaltown/mission01.entity":
|
|
case "assembly:/_pro/scenes/missions/coastaltown/_scene_octopus.entity":
|
|
return ["sapienzaworldoftomorrow", "World of Tomorrow", "Sapienza"]
|
|
case "assembly:/_pro/scenes/missions/coastaltown/scene_ebola.entity":
|
|
return ["sapienzapzauthor", "The Author", "Sapienza"]
|
|
|
|
// marrakesh
|
|
case "assembly:/_pro/scenes/missions/marrakesh/_scene_mission_spider.entity":
|
|
case "assembly:/_pro/scenes/missions/marrakesh/_scene_spider.entity":
|
|
return ["marrakeshguildedcage", "A Gilded Cage", "Marrakesh"]
|
|
case "assembly:/_pro/scenes/missions/marrakesh/_scene_mission_python.entity":
|
|
case "assembly:/_pro/scenes/missions/marrakesh/_scene_python_hellebore.entity":
|
|
case "assembly:/_pro/scenes/missions/marrakesh/_scene_python.entity":
|
|
return ["marrakeshahbos", "A House Built On Sand", "Marrakesh"]
|
|
|
|
// bangkok missions
|
|
case "assembly:/_pro/scenes/missions/bangkok/_scene_mission_tiger.entity":
|
|
case "assembly:/_pro/scenes/missions/bangkok/_scene_tiger.entity":
|
|
return ["bangkokclub27", "Club 27", "Bangkok"]
|
|
case "assembly:/_pro/scenes/missions/bangkok/scene_zika.entity":
|
|
return ["bangkokpzsource", "The Source", "Bangkok"]
|
|
|
|
// colorado missions
|
|
case "assembly:/_pro/scenes/missions/colorado_2/_scene_bull.entity":
|
|
case "assembly:/_pro/scenes/missions/colorado_2/_scene_mission_bull.entity":
|
|
return ["coloradofreedomfighters", "Freedom Fighters", "Colorado"]
|
|
case "assembly:/_pro/scenes/missions/colorado_2/scene_rabies.entity":
|
|
return ["coloradopzvector", "The Vector", "Colorado"]
|
|
|
|
// hokkaido missions
|
|
case "assembly:/_pro/scenes/missions/hokkaido/_scene_mission_snowcrane.entity":
|
|
case "assembly:/_pro/scenes/missions/hokkaido/_scene_snowcrane_tumbleweed.entity":
|
|
case "assembly:/_pro/scenes/missions/hokkaido/_scene_snowcrane.entity":
|
|
return ["hokkaidositusinvertus", "Situs Invertus", "Hokkaido"]
|
|
case "assembly:/_pro/scenes/missions/hokkaido/scene_mamushi.entity":
|
|
return [
|
|
"hokkaidosnowfestival",
|
|
"Hokkaido Snow Festival",
|
|
"Hokkaido",
|
|
]
|
|
case "assembly:/_pro/scenes/missions/hokkaido/_scene_flu.entity":
|
|
return ["hokkaidopz", "Patient Zero", "Hokkaido"]
|
|
|
|
// dartmoor
|
|
case "assembly:/_pro/scenes/missions/ancestral/scene_bulldog.entity":
|
|
return ["dartmoordeathoffamily", "Death in the Family", "Dartmoor"]
|
|
case "assembly:/_pro/scenes/missions/ancestral/scene_smoothsnake.entity":
|
|
return ["dartmoorgardenshow", "Dartmoor Garden Show", "Dartmoor"]
|
|
case "assembly:/_pro/scenes/missions/ancestral/scene_ancestral_vesper.entity":
|
|
return ["elusivevesper", "The Procurers", "Dartmoor"]
|
|
|
|
// columbia
|
|
case "assembly:/_pro/scenes/missions/colombia/mission_millipede/scene_millipede.entity":
|
|
case "assembly:/_pro/scenes/missions/colombia/scene_anaconda.entity":
|
|
return [
|
|
"santafortunaembraceserpent",
|
|
"Embrace of the Serpent",
|
|
"Santa Fortuna",
|
|
]
|
|
case "assembly:/_pro/scenes/missions/colombia/scene_hippo.entity":
|
|
case "assembly:/_pro/scenes/missions/colombia/scene_hippo_calluna.entity":
|
|
case "assembly:/_pro/scenes/missions/colombia/scene_hippo_rafflesia.entity":
|
|
return [
|
|
"santafortunathreeheadedserpent",
|
|
"Three-Headed Serpent",
|
|
"Santa Fortuna",
|
|
]
|
|
|
|
// berlin
|
|
case "assembly:/_pro/scenes/missions/edgy/mission_fox/scene_radler.entity":
|
|
return ["elusiveradler", "The Liability", "Berlin"]
|
|
case "assembly:/_pro/scenes/missions/edgy/mission_fox/scene_fox_basic.entity":
|
|
case "assembly:/_pro/scenes/missions/edgy/mission_fox/scene_fox_contractcreation.entity":
|
|
case "assembly:/_pro/scenes/missions/edgy/mission_fox/scene_fox_cornflower.entity":
|
|
case "assembly:/_pro/scenes/missions/edgy/mission_fox/scene_fox_nightphlox.entity":
|
|
case "assembly:/_pro/scenes/missions/edgy/mission_fox/scene_fox_smilax.entity":
|
|
case "assembly:/_pro/scenes/missions/edgy/mission_fox/scene_fox_smilax_level2.entity":
|
|
case "assembly:/_pro/scenes/missions/edgy/mission_fox/scene_fox_smilax_level3.entity":
|
|
return ["berlinapexpredator", "Apex Predator", "Berlin"]
|
|
case "assembly:/_pro/scenes/missions/edgy/mission_fox/scene_grasssnake.entity":
|
|
return ["berlinegghunt", "Berlin Egg Hunt", "Berlin"]
|
|
|
|
// mendozer
|
|
case "assembly:/_pro/scenes/missions/elegant/scene_llama_elusive_clerico.entity":
|
|
return ["elusiveclerico", "The Heartbreaker", "Mendoza"]
|
|
case "assembly:/_pro/scenes/missions/elegant/scene_llama_elusive_jockeyclub.entity":
|
|
return ["elusivejockeyclub", "The Iconoclast", "Mendoza"]
|
|
case "assembly:/_pro/scenes/missions/elegant/scene_llama.entity":
|
|
case "assembly:/_pro/scenes/missions/elegant/scene_llama_jacaranda.entity":
|
|
case "assembly:/_pro/scenes/missions/elegant/scene_whitedryas.entity":
|
|
case "assembly:/_pro/scenes/missions/elegant/scene_whitedryas_level2.entity":
|
|
case "assembly:/_pro/scenes/missions/elegant/scene_whitedryas_level3.entity":
|
|
return ["mendozafarewell", "The Farewell", "Mendoza"]
|
|
|
|
// dubai
|
|
case "assembly:/_pro/scenes/missions/golden/mission_gecko/scene_gecko_angelica.entity":
|
|
case "assembly:/_pro/scenes/missions/golden/mission_gecko/scene_gecko_basic.entity":
|
|
case "assembly:/_pro/scenes/missions/golden/mission_gecko/scene_gecko_desertrose.entity":
|
|
case "assembly:/_pro/scenes/missions/golden/mission_gecko/scene_gecko_lunaria.entity":
|
|
case "assembly:/_pro/scenes/missions/golden/mission_gecko/scene_gecko_sinstest.entity":
|
|
case "assembly:/_pro/scenes/missions/golden/mission_gecko/scene_gecko_sheepsorrel.entity":
|
|
return ["dubaiontopoftheworld", "On Top Of The World", "Dubai"]
|
|
case "assembly:/_pro/scenes/missions/golden/mission_gecko/scene_gibson.entity":
|
|
return ["elusivegibson", "The Ascensionist", "Dubai"]
|
|
|
|
// chongqing
|
|
case "assembly:/_pro/scenes/missions/wet/scene_wet_makoyana.entity":
|
|
case "assembly:/_pro/scenes/missions/wet/scene_rat_ginseng.entity":
|
|
case "assembly:/_pro/scenes/missions/wet/scene_rat_basic.entity":
|
|
case "assembly:/_pro/scenes/missions/wet/scene_magnolia.entity":
|
|
return ["chongqingendofanera", "End Of An Era", "Chongqing"]
|
|
case "assembly:/_pro/scenes/missions/wet/scene_rat_elusive_redsnapper.entity":
|
|
return ["elusiveredsnapper", "The Rage", "Chongqing"]
|
|
|
|
// training
|
|
case "assembly:/_pro/scenes/missions/thefacility/_scene_polarbear_005.entity":
|
|
case "assembly:/_pro/scenes/missions/thefacility/_scene_mission_polarbear_002_for_escalation_.entity":
|
|
case "assembly:/_pro/scenes/missions/thefacility/_scene_mission_polarbear_002_contracts_creation_tutorial.entity":
|
|
case "assembly:/_pro/scenes/missions/thefacility/_scene_mission_polarbear_intro_firsttime.entity":
|
|
case "assembly:/_pro/scenes/missions/thefacility/_scene_mission_polarbear_module_002.entity":
|
|
case "assembly:/_pro/scenes/missions/thefacility/_scene_mission_polarbear_module_002_b.entity":
|
|
case "assembly:/_pro/scenes/missions/thefacility/_scene_mission_polarbear_module_005.entity":
|
|
return ["icafacilityfinaltest", "ICA Facility", "Greenland"]
|
|
|
|
// new york
|
|
case "assembly:/_pro/scenes/missions/greedy/mission_raccoon/scene_raccoon_basic.entity":
|
|
case "assembly:/_pro/scenes/missions/greedy/mission_raccoon/scene_raccoon_basic_dandelion.entity":
|
|
return ["newyorkgoldenhandshake", "Golden Handshake", "New York"]
|
|
|
|
// haven
|
|
case "assembly:/_pro/scenes/missions/opulent/mission_stingray/scene_stingray_basic.entity":
|
|
case "assembly:/_pro/scenes/missions/opulent/mission_stingray/scene_stingray_arcticthyme.entity":
|
|
return ["havenlastresort", "The Last Resort", "Haven"]
|
|
|
|
// miami
|
|
case "assembly:/_pro/scenes/missions/miami/scene_et_sambuca.entity":
|
|
return ["elusivesambuca", "The Undying", "Miami"]
|
|
case "assembly:/_pro/scenes/missions/miami/scene_flamingo.entity":
|
|
return ["miamifinishline", "The Finish Line", "Miami"]
|
|
case "assembly:/_pro/scenes/missions/miami/scene_cottonmouth.entity":
|
|
return ["miamisilvertounge", "A Silver Tongue", "Miami"]
|
|
|
|
// hawkes bay
|
|
case "assembly:/_pro/scenes/missions/sheep/scene_adonis.entity":
|
|
return ["elusiveadonis", "The Politician", "Hawke's Bay"]
|
|
case "assembly:/_pro/scenes/missions/sheep/scene_sheep.entity":
|
|
return ["hawkenightcall", "Nightcall", "Hawke's Bay"]
|
|
case "assembly:/_pro/scenes/missions/sheep/scene_opuntia.entity":
|
|
return ["opuntia", "Opuntia", "Hawke's Bay"]
|
|
|
|
// sgail
|
|
case "assembly:/_pro/scenes/missions/theark/scene_magpie.entity":
|
|
case "assembly:/_pro/scenes/missions/theark/_scene_magpie_pansy.entity":
|
|
case "assembly:/_pro/scenes/missions/theark/_scene_magpie_lotus.entity":
|
|
return ["sgailarksociety", "The Ark Society", "Isle of Sgáil"]
|
|
|
|
// whittleton
|
|
case "assembly:/_pro/scenes/missions/skunk/scene_skunk.entity":
|
|
case "assembly:/_pro/scenes/missions/skunk/mission_grasshopper/scene_grasshopper.entity":
|
|
return ["whittletonanotherlife", "Another Life", "Whittleton Creek"]
|
|
case "assembly:/_pro/scenes/missions/skunk/scene_gartersnake.entity":
|
|
return ["whittletonbitterpill", "A Bitter Pill", "Whittleton Creek"]
|
|
|
|
// mumbai
|
|
case "assembly:/_pro/scenes/missions/mumbai/scene_mongoose.entity":
|
|
return ["mumbaichasingghost", "Chasing A Ghost", "Mumbai"]
|
|
case "assembly:/_pro/scenes/missions/mumbai/scene_kingcobra.entity":
|
|
return ["mumbaikingcobra", "Illusions of Grandeur", "Mumbai"]
|
|
|
|
// romania
|
|
case "assembly:/_pro/scenes/missions/trapped/scene_bellflower.entity":
|
|
case "assembly:/_pro/scenes/missions/trapped/scene_wolverine.entity":
|
|
return ["romaniatile", "Untouchable", "Romania"]
|
|
|
|
// ambrose
|
|
case "assembly:/_pro/scenes/missions/rocky/scene_dugong.entity":
|
|
return [
|
|
"shadowsinthewater",
|
|
"Shadows in the Water",
|
|
"Ambrose Island",
|
|
]
|
|
|
|
// sniper
|
|
case "assembly:/_pro/scenes/missions/caged/mission_falcon/scene_falcon_sniper.entity":
|
|
return ["sniper_siberia", "Crime and Punishment", "Siberia"]
|
|
case "assembly:/_pro/scenes/missions/hawk/scene_hawk.entity":
|
|
return ["austria", "The Last Yardbird", "Austria"]
|
|
case "assembly:/_pro/scenes/missions/salty/mission_seagull/scene_seagull.entity":
|
|
return ["hantuport", "The Pen and the Sword", "Hantu Port"]
|
|
}
|
|
|
|
return undefined
|
|
}
|