Skip to content

Commit 72d1307

Browse files
committed
add: class score data
1 parent b9ebf65 commit 72d1307

File tree

7 files changed

+190
-6
lines changed

7 files changed

+190
-6
lines changed

src/cache/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,3 +44,4 @@ export const freeQuestsCache = new CacheFile<FreeQuest[]>(
4444
"data/freeQuestsList.json"
4545
);
4646
export const warsCache = new CacheFile<War[]>("data/warsList.json");
47+
export const scoresCache = new CacheFile<ClassScore[]>("data/scoreList.json");
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
import type { ClassBoard } from "@atlasacademy/api-connector/dist/Schema/ClassBoard";
2+
import { CacheFile } from "..";
3+
import { log } from "~/utils/logger";
4+
import { connectorEN, connectorJP } from "./connector";
5+
6+
const cacheFiles = new Map<SupportedRegion, CacheFile<ClassBoard[]>>();
7+
8+
export async function getNiceClassScore(
9+
region: SupportedRegion,
10+
update = false
11+
) {
12+
const connector = region == "EN" ? connectorEN : connectorJP;
13+
const descriptor = `class_score_list for region ${region}`;
14+
let scoreList: ClassBoard[];
15+
let cacheFile = cacheFiles.get(region);
16+
if (!cacheFile) {
17+
const filePath = `data/cache/${region}/class_score_list.json`;
18+
cacheFile = new CacheFile(filePath);
19+
cacheFiles.set(region, cacheFile);
20+
}
21+
22+
if (!update) {
23+
const exists = await cacheFile.exists();
24+
if (!exists) {
25+
log.warn(`${descriptor} does not yet exist, forcing update`);
26+
update = true;
27+
}
28+
}
29+
30+
if (update) {
31+
log.debug(`Fetching ${descriptor}`);
32+
scoreList = await connector.classBoardList();
33+
await cacheFile.write(scoreList);
34+
log.info(`Updated ${descriptor}`);
35+
} else {
36+
try {
37+
const data = await cacheFile.read();
38+
if (!Array.isArray(data)) throw new Error("");
39+
scoreList = data;
40+
log.debug(`Using cached ${descriptor}`);
41+
} catch (e) {
42+
log.error(`Could not retrieve ${descriptor}`);
43+
throw e;
44+
}
45+
}
46+
47+
return scoreList;
48+
}
Lines changed: 98 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,98 @@
1+
import { ClassBoardSquareFlag } from "@atlasacademy/api-connector/dist/Schema/ClassBoard";
2+
import type { ClassBoard } from "@atlasacademy/api-connector/dist/Schema/ClassBoard";
3+
import type { ItemProcessor } from "./processItemData";
4+
import { convertClassName } from "./classNames";
5+
6+
export function createClassScoreProcessor(itemProcessor: ItemProcessor) {
7+
const scoreMap: Record<ID, ClassScore> = {};
8+
9+
function getClassScoreList() {
10+
return Object.values(scoreMap).sort((a, b) => a.id - b.id);
11+
}
12+
13+
function processClassScores(
14+
niceScoreJP: ClassBoard[],
15+
niceScoreEN: ClassBoard[]
16+
) {
17+
for (const boardJP of niceScoreJP) {
18+
const boardEN =
19+
boardJP.id == 8 // TEMP: Extra 1 is still locked on EN
20+
? undefined
21+
: niceScoreEN.find(board => board.id == boardJP.id);
22+
const en = Boolean(boardEN);
23+
const boardClasses = new Set<ServantClass>();
24+
25+
for (const boardClass of boardJP.classes) {
26+
boardClasses.add(convertClassName(boardClass.className));
27+
}
28+
29+
const score: ClassScore = {
30+
id: boardJP.id,
31+
name: boardEN?.name || boardJP.name,
32+
classes: Array.from(boardClasses),
33+
nodes: {},
34+
startNodes: []
35+
};
36+
37+
// process squares
38+
for (const square of boardJP.squares) {
39+
// skip if blank
40+
if (square.flags.includes(ClassBoardSquareFlag.BLANK)) continue;
41+
42+
const node: ClassScoreNode = {
43+
id: square.id,
44+
qp: 0,
45+
items: [],
46+
next: []
47+
};
48+
49+
// process items
50+
for (const itemAmount of square.items) {
51+
// why is QP an item here?
52+
if (itemAmount.item.id == 1) {
53+
node.qp += itemAmount.amount;
54+
continue;
55+
}
56+
57+
// add to node
58+
node.items.push([itemAmount.item.id, itemAmount.amount]);
59+
60+
// if item not previously processed do that now and push it to list
61+
itemProcessor.registerItem(itemAmount.item, en);
62+
}
63+
64+
// process lock items
65+
if (square.lock) {
66+
for (const itemAmount of square.lock.items) {
67+
// why is QP an item here?
68+
if (itemAmount.item.id == 1) {
69+
node.qp += itemAmount.amount;
70+
continue;
71+
}
72+
73+
// add to node
74+
node.items.push([itemAmount.item.id, itemAmount.amount]);
75+
76+
// if item not previously processed do that now and push it to list
77+
itemProcessor.registerItem(itemAmount.item, en);
78+
}
79+
}
80+
81+
// register node in map
82+
score.nodes[square.id] = node;
83+
}
84+
85+
// process lines
86+
for (const line of boardJP.lines) {
87+
const prev = score.nodes[line.prevSquareId];
88+
const next = score.nodes[line.nextSquareId];
89+
if (!prev || !next) continue;
90+
prev.next.push(next.id);
91+
}
92+
93+
scoreMap[score.id] = score;
94+
}
95+
}
96+
97+
return { getClassScoreList, processClassScores };
98+
}

src/cache/prepare-cache/processNiceServant.ts

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,28 @@
11
import type { ServantWithLore as NiceServant } from "@atlasacademy/api-connector/dist/Schema/Servant";
2+
import type { ClassBoard } from "@atlasacademy/api-connector/dist/Schema/ClassBoard";
23
import { log } from "~/utils/logger";
3-
import { itemsCache, servantsCache, skillsCache } from "~/cache";
4+
import { itemsCache, scoresCache, servantsCache, skillsCache } from "~/cache";
45
import { indexServantNames } from "./servantNames";
56
import { createItemProcessor } from "./processItemData";
67
import { createEnhancementProcessor } from "./processEnhancementStage";
78
import { createSkillProcessor } from "./processServantSkill";
89
import { createServantProcessor } from "./processServant";
910
import { processServantMashu } from "./processServantMashu";
1011
import { createNPsProcessor } from "./processNoblePhantasm";
12+
import { createClassScoreProcessor } from "./processClassScore";
1113

1214
export async function processNiceServant(
1315
niceServantJP: NiceServant[],
14-
niceServantEN: NiceServant[]
16+
niceServantEN: NiceServant[],
17+
niceScoreJP: ClassBoard[],
18+
niceScoreEN: ClassBoard[]
1519
) {
1620
const servantNames = indexServantNames(niceServantJP, niceServantEN);
1721
const itemProcessor = createItemProcessor();
1822
const enhancementProcessor = createEnhancementProcessor(itemProcessor);
1923
const skillProcessor = createSkillProcessor();
2024
const npsProcessor = createNPsProcessor();
25+
const scoreProcessor = createClassScoreProcessor(itemProcessor);
2126
const servantsProcessor = createServantProcessor({
2227
enhancementProcessor,
2328
skillProcessor,
@@ -48,20 +53,26 @@ export async function processNiceServant(
4853
servantsProcessor.processServant(servantJP, servantEN);
4954
}
5055

56+
// process class scores
57+
scoreProcessor.processClassScores(niceScoreJP, niceScoreEN);
58+
5159
const itemsList = itemProcessor.getItemList();
5260
const servantsList = servantsProcessor.getServantsList();
5361
const skillsList = skillProcessor.getSkillList();
5462
const npsList = npsProcessor.getNPsList();
5563
const costumesList = enhancementProcessor.getCostumesList();
64+
const scoreList = scoreProcessor.getClassScoreList();
5665
log.info(`${itemsList.length} Items found`);
5766
log.info(`${servantsList.length} Servants found`);
5867
log.info(`${skillsList.length} Skills found`);
5968
log.info(`${npsList.length} NPs found`);
6069
log.info(`${costumesList.length} Costumes found`);
70+
log.info(`${scoreList.length} Class Score boards found`);
6171

6272
await Promise.all([
6373
itemsCache.write(itemsList),
6474
servantsCache.write(servantsList),
65-
skillsCache.write(skillsList)
75+
skillsCache.write(skillsList),
76+
scoresCache.write(scoreList)
6677
]);
6778
}

src/cache/prepare-cache/script.ts

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import { getNiceServant } from "./getNiceServant";
77
import { processNiceServant } from "./processNiceServant";
88
import { getNiceWar } from "./getNiceWar";
99
import { processNiceWar } from "./processNiceWar";
10+
import { getNiceClassScore } from "./getNiceClassScore";
1011

1112
const timer = createTimer();
1213
const { values: args } = parseArgs({
@@ -48,10 +49,19 @@ async function main() {
4849
getNiceWar("JP"),
4950
getNiceWar("EN")
5051
]);
52+
const [niceScoreJP, niceScoreEN] = await Promise.all([
53+
getNiceClassScore("JP"),
54+
getNiceClassScore("EN")
55+
]);
5156

5257
// perform data update
5358
await Promise.all([
54-
processNiceServant(niceServantJP, niceServantEN),
59+
processNiceServant(
60+
niceServantJP,
61+
niceServantEN,
62+
niceScoreJP,
63+
niceScoreEN
64+
),
5565
processNiceWar(niceWarJP, niceWarEN)
5666
]);
5767
log.success("Wrote new data cache");
@@ -88,6 +98,10 @@ async function main() {
8898
getNiceWar("JP", updateJP),
8999
getNiceWar("EN", updateEN)
90100
]);
101+
const [niceScoreJP, niceScoreEN] = await Promise.all([
102+
getNiceClassScore("JP"),
103+
getNiceClassScore("EN")
104+
]);
91105

92106
if (!noUpdate) {
93107
// update local info
@@ -102,7 +116,7 @@ async function main() {
102116

103117
// perform data update
104118
await Promise.all([
105-
processNiceServant(niceServantJP, niceServantEN),
119+
processNiceServant(niceServantJP, niceServantEN, niceScoreJP, niceScoreEN),
106120
processNiceWar(
107121
niceWarJP,
108122
niceWarEN,

src/cache/types.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,9 +20,10 @@ export interface CacheInfo {
2020
/**
2121
* Current Cache Version
2222
*/
23-
export const CACHE_VER = 1;
23+
export const CACHE_VER = 2;
2424

2525
/* Cache Version History:
2626
v0: Development
2727
v1: added nice_war
28+
v2: added nice_class_Score
2829
*/

src/types/score.d.ts

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
interface ClassScoreNode extends EnhancementStage {
2+
id: number;
3+
detail?: string; // don't know if this can be guaranteed yet
4+
next: Array<number>;
5+
}
6+
7+
interface ClassScore extends EntityBase {
8+
classes: ServantClass[];
9+
nodes: Record<number, ClassScoreNode>;
10+
startNodes: Array<number>;
11+
}

0 commit comments

Comments
 (0)