Skip to content

Commit

Permalink
fea(h6): support Statistics page
Browse files Browse the repository at this point in the history
And it's better than official, because we fixed IOI's mistake by flipping the difficulty when passing it to the scaleform class! This took me a whole hour to realise.
  • Loading branch information
AnthonyFuller committed Aug 26, 2024
1 parent eb0d2c3 commit cb80038
Show file tree
Hide file tree
Showing 2 changed files with 189 additions and 4 deletions.
188 changes: 185 additions & 3 deletions components/2016/legacyMenuData.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,21 @@
*/

import { Router } from "express"
import { RequestWithJwt } from "../types/types"
import { getConfig } from "../configSwizzleManager"
import {
type ChallengeCategoryCompletion,
ChallengeCompletion,
CompletionData,
type PeacockLocationsData,
RequestWithJwt,
Unlockable,
} from "../types/types"
import { getConfig, getVersionedConfig } from "../configSwizzleManager"
import { controller } from "../controller"
import { getParentLocationByName } from "../contracts/dataGen"
import {
generateCompletionData,
getParentLocationByName,
} from "../contracts/dataGen"
import { ChallengeFilterType, Pro1FilterType } from "../candle/challengeHelpers"

const legacyMenuDataRouter = Router()

Expand Down Expand Up @@ -69,4 +80,175 @@ legacyMenuDataRouter.get(
},
)

type StatisticsData = {
DifficultyLevelData: {
Name: "normal" | "pro1"
SubLocationData: {
ParentLocation: Unlockable
Location: Unlockable
CompletionData: CompletionData
ChallengeCategoryCompletion: ChallengeCategoryCompletion[]
ChallengeCompletion: ChallengeCompletion
}[]
}[]
}

legacyMenuDataRouter.get(
"/Statistics",
// @ts-expect-error Has jwt props.
(req: RequestWithJwt, res) => {
const data: StatisticsData = {
DifficultyLevelData: [
{
Name: "normal",
SubLocationData: [],
},
{
Name: "pro1",
SubLocationData: [],
},
],
}

// This is essentially a rewrite of getPlayerProfileData except without
// the player profile data
const locationData = getVersionedConfig<PeacockLocationsData>(
"LocationsData",
req.gameVersion,
false,
)

// Contains the parent ids of ones that have had their pro1 data
// added. It's a hacky workaround.
const processedParents: string[] = []

for (const subLocation of Object.values(locationData.children)) {
const parentLocation =
locationData.parents[
subLocation.Properties.ParentLocation || ""
]

const normalChallenges =
controller.challengeService.getGroupedChallengeLists(
{
type: ChallengeFilterType.ParentLocation,
parent: parentLocation.Id,
pro1Filter: Pro1FilterType.Exclude,
},
parentLocation.Id,
req.gameVersion,
)

const normalCompletion: ChallengeCategoryCompletion[] = []

for (const challengeGroup in normalChallenges) {
const challengeCompletion =
controller.challengeService.countTotalNCompletedChallenges(
{
challengeGroup: normalChallenges[challengeGroup],
},
req.jwt.unique_name,
req.gameVersion,
)

normalCompletion.push({
Name: normalChallenges[challengeGroup][0].CategoryName,
...challengeCompletion,
})
}

data.DifficultyLevelData[0].SubLocationData.push({
ParentLocation: parentLocation,
Location: subLocation,
ChallengeCategoryCompletion: normalCompletion,
CompletionData: {
...generateCompletionData(
subLocation.Id,
req.jwt.unique_name,
req.gameVersion,
"mission",
"normal",
),
...{
HideProgression:
subLocation.Properties.ProgressionKey !==
subLocation.Id ||
parentLocation.Id ===
"LOCATION_PARENT_ICA_FACILITY",
},
},
ChallengeCompletion:
controller.challengeService.countTotalNCompletedChallenges(
normalChallenges,
req.jwt.unique_name,
req.gameVersion,
100,
),
})

if (
parentLocation.Id === "LOCATION_PARENT_ICA_FACILITY" ||
processedParents.includes(parentLocation.Id)
)
continue

processedParents.push(parentLocation.Id)

const pro1Challenges =
controller.challengeService.getGroupedChallengeLists(
{
type: ChallengeFilterType.ParentLocation,
parent: parentLocation.Id,
pro1Filter: Pro1FilterType.Only,
},
parentLocation.Id,
req.gameVersion,
)

const pro1Completion: ChallengeCategoryCompletion[] = []

for (const challengeGroup in pro1Challenges) {
const challengeCompletion =
controller.challengeService.countTotalNCompletedChallenges(
{
challengeGroup: pro1Challenges[challengeGroup],
},
req.jwt.unique_name,
req.gameVersion,
)

pro1Completion.push({
Name: pro1Challenges[challengeGroup][0].CategoryName,
...challengeCompletion,
})
}

data.DifficultyLevelData[1].SubLocationData.push({
ParentLocation: parentLocation,
Location: subLocation,
ChallengeCategoryCompletion: pro1Completion,
CompletionData: generateCompletionData(
subLocation.Id,
req.jwt.unique_name,
req.gameVersion,
"mission",
"pro1",
),
ChallengeCompletion:
controller.challengeService.countTotalNCompletedChallenges(
pro1Challenges,
req.jwt.unique_name,
req.gameVersion,
100,
),
})
}

res.json({
template: getConfig("LegacyStatisticsTemplate", false),
data,
})
},
)

export { legacyMenuDataRouter }
5 changes: 4 additions & 1 deletion components/candle/challengeService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1614,12 +1614,14 @@ export class ChallengeService extends ChallengeRegistry {
* @param challengeLists A GroupIndexedChallengeLists object, holding some challenges to be counted
* @param userId The userId of the user to acquire completion information
* @param gameVersion The version of the game
* @param multiplier What to multiply the final completion percentage by
* @returns An object with two properties: ChallengesCount and CompletedChallengesCount.
*/
countTotalNCompletedChallenges(
challengeLists: GroupIndexedChallengeLists,
userId: string,
gameVersion: GameVersion,
multiplier = 1,
): ChallengeCompletion {
const userData = getUserData(userId, gameVersion)

Expand All @@ -1642,7 +1644,8 @@ export class ChallengeService extends ChallengeRegistry {
return {
ChallengesCount: challengesCount,
CompletedChallengesCount: completedChallengesCount,
CompletionPercent: completedChallengesCount / challengesCount,
CompletionPercent:
(completedChallengesCount / challengesCount) * multiplier,
}
}

Expand Down

0 comments on commit cb80038

Please sign in to comment.