Peacock
Peacock copied to clipboard
controller.challengeService.removeChallenge unable to remove global challenges
Describe the bug
controller.challengeService.removeChallenge
is unable to remove global challenges. Returns the error: TypeError: Cannot read properties of undefined (reading 'get')
To reproduce
Put this in a script to repro, this is to remove a challenge from the escalation track: controller.challengeService.removeChallenge("7c4e7906-ad19-46c0-96f4-4fc301a562b4", "h3")
Global challenges are special and aren't handled by the challenge system - they are a config.
Is there any way to handle them via plugin?
You can modify the list by accessingcontroller.configManager.configs.GlobalChallenges
Gotcha, thanks.
Actually, this doesn't work as 7c4e7906-ad19-46c0-96f4-4fc301a562b4 is not in that config. It is only in contractdata/GLOBAL /_ESCALATION_CHALLENGES.json
This bug is caused by global challenge ParentLocationId
being ""
, while they are registered under GLOBAL_*
virtual location id.
For example: When _ESCALATION_CHALLENGES.json
is being registered by Peacock, it will register their groups challenges inside a GLOBAL_ESCALATION_CHALLENGES
"location". However all those challenges have a ParentLocationId
value set to ""
, and that value is being used to determine the location id that holds the global challenge group during removeChallenge
call.
Additionally, this also affects reBatchIntoSwitchedData
: If challenge group first registered challenge is a global challenge, it will return an empty challenge list. (This bug prevents ability to register global-only challenge packs)
Refs:
-
controller._handleChallengeResources
- it usesdata.meta.Location
to set which location the challenge group is registered under. -
challengeService.removeChallenge
- it useschallenge.ParentLocationId
, and in case of global challenge it does not match its actual storage key, causing the error in question. -
challengeService.reBatchIntoSwitchedData
- if challenge is global it will return empty list, due to next ref -
challengeService.getGroupByIdLoc
- due to location ID passed being""
- in case of global challenges it will ALWAYS return undefined unless requested challenge group is native global one, handled by if statements.
Solutions:
- Patch each global challenge to match
ParentLocationId
to its group location ID in the .json files. (Not a good one) - Assign
ParentLocationId
when registering challenges. (Also not a good one) - Use same approach as
inGroup
field and assigninLocation
field and use that for location lookbacks. This one seem most reasonable, however it will make it impossible to make user-made global-visible challenge groups (like Classics)
My general proposal:
- Introduce
inLocation
field. - Introduce an API when registering groups to make them globally visible.
- Can be done by extra argument for
registerGroup
, a custom field of group definition or separatemarkGlobal
method or along the lines. - During
getGroupByIdLoc
check if request group is global, and return merged challenge group, as with Classics.
- Can be done by extra argument for
I can prepare a PR with fix and global marker myself, as long as consensus on API is met.