Deduplicate campaign reward references

This commit is contained in:
2026-07-05 14:13:27 +09:00
parent 7196ab3dbd
commit d0085eeb18
2 changed files with 38 additions and 14 deletions

View File

@@ -905,6 +905,18 @@ function uniqueStrings(value: unknown): string[] {
].slice(0, maxCampaignStringListEntries);
}
function uniqueByKey<T>(entries: T[], keyForEntry: (entry: T) => string) {
const seen = new Set<string>();
return entries.filter((entry) => {
const key = keyForEntry(entry);
if (!key || seen.has(key)) {
return false;
}
seen.add(key);
return true;
});
}
function normalizeKeyString(value: unknown): string {
if (typeof value !== 'string') {
return '';
@@ -1658,21 +1670,27 @@ function cloneCampaignRewardSnapshot(rewards?: CampaignRewardSnapshot): Campaign
supplies: uniqueStrings(rewardRecord.supplies),
equipment: uniqueStrings(rewardRecord.equipment),
reputation: uniqueStrings(rewardRecord.reputation),
recruits: arrayOrEmpty<unknown>(rewardRecord.recruits)
.filter(isPlainObject)
.map((recruit) => ({
unitId: normalizeKeyString(recruit.unitId),
name: normalizeDisplayString(recruit.name)
}))
.filter((recruit) => recruit.unitId && recruit.name)
recruits: uniqueByKey(
arrayOrEmpty<unknown>(rewardRecord.recruits)
.filter(isPlainObject)
.map((recruit) => ({
unitId: normalizeKeyString(recruit.unitId),
name: normalizeDisplayString(recruit.name)
}))
.filter((recruit) => recruit.unitId && recruit.name),
(recruit) => recruit.unitId
)
.slice(0, maxCampaignStringListEntries),
unlocks: arrayOrEmpty<unknown>(rewardRecord.unlocks)
.filter(isPlainObject)
.map((unlock) => ({
battleId: normalizeKeyString(unlock.battleId),
title: normalizeDisplayString(unlock.title)
}))
.filter((unlock) => unlock.battleId && unlock.title)
unlocks: uniqueByKey(
arrayOrEmpty<unknown>(rewardRecord.unlocks)
.filter(isPlainObject)
.map((unlock) => ({
battleId: normalizeKeyString(unlock.battleId),
title: normalizeDisplayString(unlock.title)
}))
.filter((unlock) => unlock.battleId && unlock.title),
(unlock) => unlock.battleId
)
.slice(0, maxCampaignStringListEntries),
note: note.length > 0 && note.length <= maxCampaignRewardNoteLength ? note : undefined
};