poi-plugin-quest-info-2 0.7.2 → 0.7.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.eslintrc.js +1 -0
- package/build/kcanotifyGamedata/quests-ko.json +0 -5
- package/build/prePostQuest.json +4498 -0
- package/build/questCategory.json +588 -588
- package/build/questMap.json +575 -0
- package/i18n/en-US.json +1 -0
- package/i18n/ja-JP.json +1 -0
- package/i18n/ko-KR.json +1 -0
- package/i18n/zh-CN.json +1 -0
- package/i18n/zh-TW.json +1 -0
- package/package.json +3 -3
- package/src/__tests__/__snapshots__/questCategory.spec.ts.snap +113 -113
- package/src/__tests__/kcanotifyData.spec.ts +13 -0
- package/src/__tests__/kcwikiData.spec.ts +10 -0
- package/src/__tests__/questCategory.spec.ts +3 -3
- package/src/components/QuestCard/MinimalQuestCard.tsx +11 -14
- package/src/components/QuestCard/index.tsx +86 -55
- package/src/components/QuestCard/styles.ts +17 -0
- package/src/components/QuestList.tsx +3 -6
- package/src/components/{PreTaskTag.tsx → QuestTag.tsx} +3 -2
- package/src/questHelper.ts +10 -2
- package/src/store/quest.ts +3 -3
- package/scripts/convertAssets.ts +0 -57
- package/scripts/downloadKcQuestsData.ts +0 -136
- package/scripts/downloadKcanotifyGamedata.ts +0 -132
- package/scripts/downloadSprites.ts +0 -126
- package/scripts/genQuestCategory.ts +0 -58
- package/scripts/proxyFetch.ts +0 -42
- package/scripts/utils.ts +0 -8
|
@@ -15,3 +15,16 @@ Array [
|
|
|
15
15
|
]
|
|
16
16
|
`)
|
|
17
17
|
})
|
|
18
|
+
|
|
19
|
+
describe('should format correct', () => {
|
|
20
|
+
Object.keys(QuestData).forEach((lang) => {
|
|
21
|
+
test(`${lang} key format`, () => {
|
|
22
|
+
Object.keys(QuestData[lang as keyof typeof QuestData]).forEach((key) => {
|
|
23
|
+
// gameId should not extra space
|
|
24
|
+
expect(key.trim()).toEqual(key)
|
|
25
|
+
// gameId should be number
|
|
26
|
+
expect(String(+key)).toEqual(key)
|
|
27
|
+
})
|
|
28
|
+
})
|
|
29
|
+
})
|
|
30
|
+
})
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { version, KcwikiQuestData } from '../../build/kcQuestsData'
|
|
2
|
+
import newQuestData from '../../build/kcQuestsData/quests-scn-new.json'
|
|
2
3
|
|
|
3
4
|
describe('should version correct', () => {
|
|
4
5
|
test('should KcwikiQuestData Game data version correct', () => {
|
|
@@ -25,4 +26,13 @@ describe('should format correct', () => {
|
|
|
25
26
|
expect(String(+key)).toEqual(key)
|
|
26
27
|
})
|
|
27
28
|
})
|
|
29
|
+
|
|
30
|
+
test('new quest key format', () => {
|
|
31
|
+
Object.keys(newQuestData).forEach((gameId) => {
|
|
32
|
+
// gameId should not extra space
|
|
33
|
+
expect(gameId.trim()).toEqual(gameId)
|
|
34
|
+
// gameId should be number
|
|
35
|
+
expect(String(+gameId)).toEqual(gameId)
|
|
36
|
+
})
|
|
37
|
+
})
|
|
28
38
|
})
|
|
@@ -21,11 +21,11 @@ describe('should questCategory correct', () => {
|
|
|
21
21
|
Object.entries(questCategory).map(([key, val]) => [
|
|
22
22
|
key,
|
|
23
23
|
val
|
|
24
|
-
.sort((a, b) =>
|
|
24
|
+
.sort((a, b) => a - b)
|
|
25
25
|
.map((gameId) => ({
|
|
26
26
|
gameId,
|
|
27
|
-
code: mergeData[gameId as keyof typeof mergeData].code,
|
|
28
|
-
name: mergeData[gameId as keyof typeof mergeData].name,
|
|
27
|
+
code: mergeData[String(gameId) as keyof typeof mergeData].code,
|
|
28
|
+
name: mergeData[String(gameId) as keyof typeof mergeData].name,
|
|
29
29
|
})),
|
|
30
30
|
])
|
|
31
31
|
)
|
|
@@ -1,19 +1,16 @@
|
|
|
1
|
-
import { Elevation, Text, Tooltip } from '@blueprintjs/core'
|
|
2
|
-
import React from 'react'
|
|
1
|
+
import { Card, Elevation, Text, Tooltip } from '@blueprintjs/core'
|
|
2
|
+
import React, { forwardRef } from 'react'
|
|
3
|
+
import type { StyledComponentProps } from 'styled-components'
|
|
3
4
|
import { guessQuestCategory, QUEST_STATUS } from '../../questHelper'
|
|
4
5
|
import type { QuestCardProps } from './index'
|
|
5
6
|
import { CardBody, CardTail, CatIndicator, FlexCard } from './styles'
|
|
6
7
|
import { questStatusMap } from './utils'
|
|
7
8
|
|
|
8
|
-
export const MinimalQuestCard
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
status = QUEST_STATUS.DEFAULT,
|
|
14
|
-
onClick,
|
|
15
|
-
style,
|
|
16
|
-
}) => {
|
|
9
|
+
export const MinimalQuestCard = forwardRef<
|
|
10
|
+
Card,
|
|
11
|
+
// eslint-disable-next-line @typescript-eslint/ban-types
|
|
12
|
+
QuestCardProps & StyledComponentProps<typeof Card, any, {}, never>
|
|
13
|
+
>(({ code, name, desc, tip, status = QUEST_STATUS.DEFAULT, ...props }, ref) => {
|
|
17
14
|
const indicatorColor = guessQuestCategory(code).color
|
|
18
15
|
const TailIcon = questStatusMap[status]
|
|
19
16
|
|
|
@@ -29,10 +26,10 @@ export const MinimalQuestCard: React.FC<QuestCardProps> = ({
|
|
|
29
26
|
}
|
|
30
27
|
>
|
|
31
28
|
<FlexCard
|
|
29
|
+
ref={ref}
|
|
32
30
|
elevation={Elevation.ZERO}
|
|
33
31
|
interactive={true}
|
|
34
|
-
|
|
35
|
-
style={style}
|
|
32
|
+
{...props}
|
|
36
33
|
>
|
|
37
34
|
<CatIndicator color={indicatorColor}></CatIndicator>
|
|
38
35
|
<CardBody>
|
|
@@ -45,4 +42,4 @@ export const MinimalQuestCard: React.FC<QuestCardProps> = ({
|
|
|
45
42
|
</FlexCard>
|
|
46
43
|
</Tooltip>
|
|
47
44
|
)
|
|
48
|
-
}
|
|
45
|
+
})
|
|
@@ -1,74 +1,105 @@
|
|
|
1
|
-
import { Elevation, H5, Text } from '@blueprintjs/core'
|
|
2
|
-
import React from 'react'
|
|
3
|
-
import
|
|
1
|
+
import { Card, Elevation, H5, Text } from '@blueprintjs/core'
|
|
2
|
+
import React, { forwardRef } from 'react'
|
|
3
|
+
import type { StyledComponentProps } from 'styled-components'
|
|
4
4
|
import { usePluginTranslation } from '../../poi/hooks'
|
|
5
|
-
import { guessQuestCategory, QUEST_STATUS } from '../../questHelper'
|
|
6
|
-
import {
|
|
7
|
-
import {
|
|
5
|
+
import { getPrePost, guessQuestCategory, QUEST_STATUS } from '../../questHelper'
|
|
6
|
+
import { QuestTag } from '../QuestTag'
|
|
7
|
+
import {
|
|
8
|
+
CardActionWrapper,
|
|
9
|
+
CardBody,
|
|
10
|
+
CardMedia,
|
|
11
|
+
CardTail,
|
|
12
|
+
FlexCard,
|
|
13
|
+
SpanText,
|
|
14
|
+
TagsWrapper,
|
|
15
|
+
} from './styles'
|
|
8
16
|
import { questIconMap, questStatusMap } from './utils'
|
|
9
17
|
|
|
10
18
|
export type QuestCardProps = {
|
|
19
|
+
gameId: number
|
|
11
20
|
code: string
|
|
12
21
|
name: string
|
|
13
22
|
desc: string | JSX.Element
|
|
14
23
|
tip?: string
|
|
15
24
|
tip2?: string
|
|
16
25
|
status?: QUEST_STATUS
|
|
17
|
-
|
|
18
|
-
onClick?: (e: React.MouseEvent<HTMLDivElement, MouseEvent>) => void
|
|
19
|
-
style?: React.CSSProperties
|
|
26
|
+
preQuest?: string[]
|
|
20
27
|
}
|
|
21
28
|
|
|
22
|
-
const
|
|
23
|
-
display: flex;
|
|
24
|
-
align-items: baseline;
|
|
25
|
-
`
|
|
26
|
-
|
|
27
|
-
export const LargeQuestCard = ({
|
|
28
|
-
code,
|
|
29
|
-
name,
|
|
30
|
-
desc,
|
|
31
|
-
tip,
|
|
32
|
-
tip2,
|
|
33
|
-
preTask,
|
|
34
|
-
status = QUEST_STATUS.DEFAULT,
|
|
35
|
-
onClick,
|
|
36
|
-
style,
|
|
37
|
-
}: QuestCardProps) => {
|
|
38
|
-
const headIcon = questIconMap[guessQuestCategory(code).type]
|
|
39
|
-
const TailIcon = questStatusMap[status]
|
|
29
|
+
const CardAction = ({ gameId }: { gameId: number }) => {
|
|
40
30
|
const { t } = usePluginTranslation()
|
|
41
31
|
|
|
32
|
+
const preQuests = getPrePost(gameId)
|
|
33
|
+
|
|
42
34
|
return (
|
|
43
|
-
<
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
{tip && <i>{tip}</i>}
|
|
55
|
-
<PreTaskTagWrapper>
|
|
56
|
-
{!!preTask?.length && <span>{t('Requires')}</span>}
|
|
57
|
-
{preTask?.map((i) => (
|
|
58
|
-
<PreTaskTag key={i} code={i}></PreTaskTag>
|
|
59
|
-
))}
|
|
60
|
-
</PreTaskTagWrapper>
|
|
61
|
-
</CardBody>
|
|
35
|
+
<CardActionWrapper>
|
|
36
|
+
<TagsWrapper>
|
|
37
|
+
{!!preQuests.pre.length && (
|
|
38
|
+
<>
|
|
39
|
+
<SpanText>{t('Requires')}</SpanText>
|
|
40
|
+
{preQuests.pre.map((i) => (
|
|
41
|
+
<QuestTag key={i} code={i}></QuestTag>
|
|
42
|
+
))}
|
|
43
|
+
</>
|
|
44
|
+
)}
|
|
45
|
+
</TagsWrapper>
|
|
62
46
|
|
|
63
|
-
<
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
47
|
+
<TagsWrapper>
|
|
48
|
+
{!!preQuests.post.length && (
|
|
49
|
+
<>
|
|
50
|
+
<SpanText>{t('Unlocks')}</SpanText>
|
|
51
|
+
{preQuests.post.map((i) => (
|
|
52
|
+
<QuestTag key={i} code={i}></QuestTag>
|
|
53
|
+
))}
|
|
54
|
+
</>
|
|
55
|
+
)}
|
|
56
|
+
</TagsWrapper>
|
|
57
|
+
</CardActionWrapper>
|
|
67
58
|
)
|
|
68
59
|
}
|
|
69
60
|
|
|
70
|
-
export const QuestCard
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
61
|
+
export const QuestCard = forwardRef<
|
|
62
|
+
Card,
|
|
63
|
+
// eslint-disable-next-line @typescript-eslint/ban-types
|
|
64
|
+
QuestCardProps & StyledComponentProps<typeof Card, any, {}, never>
|
|
65
|
+
>(
|
|
66
|
+
(
|
|
67
|
+
{
|
|
68
|
+
gameId,
|
|
69
|
+
code,
|
|
70
|
+
name,
|
|
71
|
+
desc,
|
|
72
|
+
tip,
|
|
73
|
+
tip2,
|
|
74
|
+
status = QUEST_STATUS.DEFAULT,
|
|
75
|
+
...props
|
|
76
|
+
},
|
|
77
|
+
ref
|
|
78
|
+
) => {
|
|
79
|
+
const headIcon = questIconMap[guessQuestCategory(code).type]
|
|
80
|
+
const TailIcon = questStatusMap[status]
|
|
81
|
+
|
|
82
|
+
return (
|
|
83
|
+
<FlexCard
|
|
84
|
+
ref={ref}
|
|
85
|
+
elevation={Elevation.ZERO}
|
|
86
|
+
interactive={false}
|
|
87
|
+
{...props}
|
|
88
|
+
>
|
|
89
|
+
<CardMedia src={headIcon}></CardMedia>
|
|
90
|
+
<CardBody>
|
|
91
|
+
<H5>{[code, name].filter((i) => i != undefined).join(' - ')}</H5>
|
|
92
|
+
<Text>{desc}</Text>
|
|
93
|
+
{tip2 && <b>{tip2}</b>}
|
|
94
|
+
{tip && <i>{tip}</i>}
|
|
95
|
+
|
|
96
|
+
<CardAction gameId={gameId}></CardAction>
|
|
97
|
+
</CardBody>
|
|
98
|
+
|
|
99
|
+
<CardTail>
|
|
100
|
+
<TailIcon />
|
|
101
|
+
</CardTail>
|
|
102
|
+
</FlexCard>
|
|
103
|
+
)
|
|
104
|
+
}
|
|
105
|
+
)
|
|
@@ -40,3 +40,20 @@ export const CardTail = styled.div`
|
|
|
40
40
|
height: 20px;
|
|
41
41
|
}
|
|
42
42
|
`
|
|
43
|
+
|
|
44
|
+
export const CardActionWrapper = styled.div`
|
|
45
|
+
display: flex;
|
|
46
|
+
flex-direction: column;
|
|
47
|
+
align-items: baseline;
|
|
48
|
+
`
|
|
49
|
+
|
|
50
|
+
export const TagsWrapper = styled.div`
|
|
51
|
+
display: flex;
|
|
52
|
+
flex: 1;
|
|
53
|
+
flex-wrap: wrap;
|
|
54
|
+
align-items: center;
|
|
55
|
+
`
|
|
56
|
+
|
|
57
|
+
export const SpanText = styled.span`
|
|
58
|
+
white-space: nowrap;
|
|
59
|
+
`
|
|
@@ -11,7 +11,6 @@ import type { ListRowProps } from 'react-virtualized'
|
|
|
11
11
|
import styled from 'styled-components'
|
|
12
12
|
import { QUEST_STATUS } from '../questHelper'
|
|
13
13
|
import type { UnionQuest } from '../questHelper'
|
|
14
|
-
import { useLargeCard } from '../store'
|
|
15
14
|
import { QuestCard } from './QuestCard'
|
|
16
15
|
import { useIsQuestPluginTab } from '../poi/hooks'
|
|
17
16
|
import { QUEST_API_STATE } from '../poi/types'
|
|
@@ -67,7 +66,7 @@ const useQuestsRowRenderer = (quests: UnionQuest[]) => {
|
|
|
67
66
|
desc={desc}
|
|
68
67
|
tip={memo}
|
|
69
68
|
tip2={memo2}
|
|
70
|
-
|
|
69
|
+
preQuest={pre}
|
|
71
70
|
status={questStatus}
|
|
72
71
|
></QuestCard>
|
|
73
72
|
</div>
|
|
@@ -80,16 +79,14 @@ const useQuestsRowRenderer = (quests: UnionQuest[]) => {
|
|
|
80
79
|
}
|
|
81
80
|
|
|
82
81
|
export const QuestList: React.FC<{ quests: UnionQuest[] }> = ({ quests }) => {
|
|
83
|
-
const { largeCard } = useLargeCard()
|
|
84
82
|
const activeTab = useIsQuestPluginTab()
|
|
85
83
|
const listRef = useRef<List>(null)
|
|
86
84
|
const rowRenderer: ListRowRenderer = useQuestsRowRenderer(quests)
|
|
87
85
|
|
|
88
86
|
useEffect(() => {
|
|
89
|
-
const largeCardIdx = quests.findIndex((i) => i.gameId === largeCard)
|
|
90
87
|
cache.clearAll()
|
|
91
|
-
listRef.current?.recomputeRowHeights(
|
|
92
|
-
}, [quests
|
|
88
|
+
listRef.current?.recomputeRowHeights()
|
|
89
|
+
}, [quests])
|
|
93
90
|
|
|
94
91
|
useEffect(() => {
|
|
95
92
|
if (activeTab) {
|
|
@@ -6,15 +6,16 @@ import { useFilterTags } from '../store/filterTags'
|
|
|
6
6
|
import { useSearchInput } from '../store/search'
|
|
7
7
|
|
|
8
8
|
const TagWrapper = styled(Tag)`
|
|
9
|
-
margin:
|
|
9
|
+
margin: 2px 4px;
|
|
10
10
|
user-select: none;
|
|
11
|
+
overflow: visible;
|
|
11
12
|
|
|
12
13
|
& > span {
|
|
13
14
|
cursor: pointer;
|
|
14
15
|
}
|
|
15
16
|
`
|
|
16
17
|
|
|
17
|
-
export const
|
|
18
|
+
export const QuestTag = ({ code }: { code: string }) => {
|
|
18
19
|
const { setSearchInput } = useSearchInput()
|
|
19
20
|
const { setCategoryTagsAll, setTypeTagsAll } = useFilterTags()
|
|
20
21
|
|
package/src/questHelper.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import questCategory from '../build/questCategory.json'
|
|
2
2
|
import newQuestData from '../build/kcQuestsData/quests-scn-new.json'
|
|
3
|
+
import prePostQuest from '../build/prePostQuest.json'
|
|
3
4
|
import { GameQuest, QUEST_API_STATE } from './poi/types'
|
|
4
5
|
|
|
5
6
|
type DocQuest = {
|
|
@@ -29,7 +30,7 @@ type DocQuest = {
|
|
|
29
30
|
}
|
|
30
31
|
|
|
31
32
|
export type UnionQuest = {
|
|
32
|
-
gameId:
|
|
33
|
+
gameId: number
|
|
33
34
|
gameQuest?: GameQuest
|
|
34
35
|
docQuest: DocQuest
|
|
35
36
|
}
|
|
@@ -40,7 +41,7 @@ const monthlyQuest = new Set(questCategory.monthlyQuest)
|
|
|
40
41
|
const quarterlyQuest = new Set(questCategory.quarterlyQuest)
|
|
41
42
|
const yearlyQuest = new Set(questCategory.yearlyQuest)
|
|
42
43
|
const singleQuest = new Set(questCategory.singleQuest)
|
|
43
|
-
const newQuest = new Set(newQuestData)
|
|
44
|
+
const newQuest = new Set(newQuestData.map((gameId) => +gameId))
|
|
44
45
|
|
|
45
46
|
export const isInProgressQuest = (quest: GameQuest) =>
|
|
46
47
|
quest.api_state === QUEST_API_STATE.IN_PROGRESS ||
|
|
@@ -196,6 +197,13 @@ export const isUnknownCategoryQuest = ({ code }: DocQuest) =>
|
|
|
196
197
|
// Starts with unknown character
|
|
197
198
|
/^[^ABCDEFG]/.test(code)
|
|
198
199
|
|
|
200
|
+
export const getPrePost = (gameId: number) => {
|
|
201
|
+
if (!(gameId in prePostQuest)) {
|
|
202
|
+
return { pre: [], post: [] }
|
|
203
|
+
}
|
|
204
|
+
return prePostQuest[String(gameId) as keyof typeof prePostQuest]
|
|
205
|
+
}
|
|
206
|
+
|
|
199
207
|
export enum QUEST_STATUS {
|
|
200
208
|
LOCKED,
|
|
201
209
|
DEFAULT,
|
package/src/store/quest.ts
CHANGED
|
@@ -44,12 +44,12 @@ export const useQuest = (): UnionQuest[] => {
|
|
|
44
44
|
|
|
45
45
|
if (syncWithGame && gameQuest.length) {
|
|
46
46
|
return gameQuest.map((quest) => {
|
|
47
|
-
const gameId =
|
|
47
|
+
const gameId = quest.api_no
|
|
48
48
|
if (gameId in docQuestMap) {
|
|
49
49
|
return {
|
|
50
50
|
gameId,
|
|
51
51
|
gameQuest: quest,
|
|
52
|
-
docQuest: docQuestMap[gameId as keyof typeof docQuestMap],
|
|
52
|
+
docQuest: docQuestMap[String(gameId) as keyof typeof docQuestMap],
|
|
53
53
|
}
|
|
54
54
|
}
|
|
55
55
|
|
|
@@ -68,7 +68,7 @@ export const useQuest = (): UnionQuest[] => {
|
|
|
68
68
|
} else {
|
|
69
69
|
// Return all recorded quests
|
|
70
70
|
return Object.entries(docQuestMap).map(([gameId, val]) => ({
|
|
71
|
-
gameId,
|
|
71
|
+
gameId: +gameId,
|
|
72
72
|
// Maybe empty
|
|
73
73
|
gameQuest: gameQuest.find((quest) => quest.api_no === Number(gameId))!,
|
|
74
74
|
docQuest: val,
|
package/scripts/convertAssets.ts
DELETED
|
@@ -1,57 +0,0 @@
|
|
|
1
|
-
import fs from 'fs'
|
|
2
|
-
import path from 'path'
|
|
3
|
-
import { prepareDir } from './utils'
|
|
4
|
-
|
|
5
|
-
const ASSETS_PATH = path.resolve('assets')
|
|
6
|
-
const OUTPUT_PATH = path.resolve('build')
|
|
7
|
-
const OUTPUT_FILE = path.resolve(OUTPUT_PATH, 'assets.ts')
|
|
8
|
-
const CONVERT_EXTS = ['jpg', 'png'] as const
|
|
9
|
-
|
|
10
|
-
const HEADER = `/* eslint-disable prettier/prettier */
|
|
11
|
-
/**
|
|
12
|
-
* This file was automatically generated by \`${path.relative(
|
|
13
|
-
// project root
|
|
14
|
-
process.cwd(),
|
|
15
|
-
__filename
|
|
16
|
-
)}\`
|
|
17
|
-
* Do not edit this file directly.
|
|
18
|
-
*/` as const
|
|
19
|
-
|
|
20
|
-
function base64Encode(file: string) {
|
|
21
|
-
const bitmap = fs.readFileSync(file)
|
|
22
|
-
return bitmap.toString('base64')
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
function main() {
|
|
26
|
-
prepareDir(OUTPUT_PATH)
|
|
27
|
-
const imageData = fs
|
|
28
|
-
.readdirSync(ASSETS_PATH)
|
|
29
|
-
// exclusive ignored ext
|
|
30
|
-
.filter((f) => CONVERT_EXTS.some((ext) => f.endsWith('.' + ext)))
|
|
31
|
-
.map((fileName) => {
|
|
32
|
-
const filePath = path.resolve(ASSETS_PATH, fileName)
|
|
33
|
-
const parsedFile = path.parse(fileName)
|
|
34
|
-
return {
|
|
35
|
-
name: parsedFile.name,
|
|
36
|
-
ext: parsedFile.ext.slice(1),
|
|
37
|
-
base64: base64Encode(filePath),
|
|
38
|
-
}
|
|
39
|
-
})
|
|
40
|
-
|
|
41
|
-
const data = `${HEADER}
|
|
42
|
-
|
|
43
|
-
${imageData
|
|
44
|
-
.map(
|
|
45
|
-
({ name, ext, base64 }) =>
|
|
46
|
-
`export const ${name} = 'data:image/${ext};base64, ${base64}'`
|
|
47
|
-
)
|
|
48
|
-
.join('\n')}
|
|
49
|
-
`
|
|
50
|
-
|
|
51
|
-
fs.writeFileSync(OUTPUT_FILE, data)
|
|
52
|
-
|
|
53
|
-
// eslint-disable-next-line no-console
|
|
54
|
-
console.log('Converted', imageData.length, 'images.')
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
main()
|
|
@@ -1,136 +0,0 @@
|
|
|
1
|
-
/* eslint-disable no-console */
|
|
2
|
-
import { existsSync, readFileSync, writeFileSync } from 'fs'
|
|
3
|
-
import pangu from 'pangu'
|
|
4
|
-
import path from 'path'
|
|
5
|
-
import { fetch } from './proxyFetch'
|
|
6
|
-
import { prepareDir } from './utils'
|
|
7
|
-
|
|
8
|
-
// See https://github.com/kcwikizh/kcQuests
|
|
9
|
-
|
|
10
|
-
const OUTPUT_PATH = path.resolve('build', 'kcQuestsData')
|
|
11
|
-
const DATA_FILE_NAME = 'quests-scn.json'
|
|
12
|
-
const DATA_URL = `https://kcwikizh.github.io/kcQuests/${DATA_FILE_NAME}`
|
|
13
|
-
const NEW_QUEST_FILE_NAME = 'quests-scn-new.json'
|
|
14
|
-
const NEW_QUEST_URL = `https://kcwikizh.github.io/kcQuests/${NEW_QUEST_FILE_NAME}`
|
|
15
|
-
const VERSION_URL =
|
|
16
|
-
'https://api.github.com/repos/kcwikizh/kcQuests/branches/main'
|
|
17
|
-
|
|
18
|
-
// maybe need ignore some expired quest
|
|
19
|
-
const IGNORE_DATA = [] as const
|
|
20
|
-
|
|
21
|
-
const getRemoteVersion = async () => {
|
|
22
|
-
const resp = await fetch(VERSION_URL)
|
|
23
|
-
if (!resp.ok) {
|
|
24
|
-
throw new Error(`Fetch Error!\nurl: ${resp.url}\nstatus: ${resp.status}`)
|
|
25
|
-
}
|
|
26
|
-
return (await resp.json()).commit.sha
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
const getLocalVersion = () => {
|
|
30
|
-
const localVersionFile = path.resolve(OUTPUT_PATH, 'DATA_VERSION')
|
|
31
|
-
const version = existsSync(localVersionFile)
|
|
32
|
-
? readFileSync(localVersionFile).toString()
|
|
33
|
-
: '0'
|
|
34
|
-
return version
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
/**
|
|
38
|
-
* @example
|
|
39
|
-
* ```ts
|
|
40
|
-
* import zh_CN from './quests-scn.json'
|
|
41
|
-
* export default {
|
|
42
|
-
* 'zh-CN': zh_CN,
|
|
43
|
-
* }
|
|
44
|
-
* export const version = '5.1.2.1'
|
|
45
|
-
* ```
|
|
46
|
-
*/
|
|
47
|
-
const genTS = (version: string) => {
|
|
48
|
-
const importCode = `import zh_CN from './quests-scn.json'`
|
|
49
|
-
|
|
50
|
-
const exportCode = [
|
|
51
|
-
'export const KcwikiQuestData = {',
|
|
52
|
-
` 'zh-CN': zh_CN,`,
|
|
53
|
-
'}',
|
|
54
|
-
].join('\n')
|
|
55
|
-
|
|
56
|
-
const versionCode = `export const version = '${version}'`
|
|
57
|
-
return `${importCode}\n\n${exportCode}\n\n${versionCode}\n`
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
const downloadQuestData = async () => {
|
|
61
|
-
const resp = await fetch(DATA_URL)
|
|
62
|
-
if (!resp.ok) {
|
|
63
|
-
console.error(`Fetch Error!\nurl: ${resp.url}\nstatus: ${resp.status}`)
|
|
64
|
-
return
|
|
65
|
-
}
|
|
66
|
-
const text = await resp.text()
|
|
67
|
-
|
|
68
|
-
const json = JSON.parse(text) as {
|
|
69
|
-
[gameId: string]: {
|
|
70
|
-
code: string
|
|
71
|
-
name: string
|
|
72
|
-
desc: string
|
|
73
|
-
memo?: string
|
|
74
|
-
memo2?: string
|
|
75
|
-
}
|
|
76
|
-
}
|
|
77
|
-
for (const gameId in json) {
|
|
78
|
-
const { code, name, desc, memo, memo2 } = json[gameId]
|
|
79
|
-
json[gameId].code = code.trim()
|
|
80
|
-
json[gameId].name = pangu.spacing(name)
|
|
81
|
-
json[gameId].desc = pangu.spacing(desc)
|
|
82
|
-
if (memo) {
|
|
83
|
-
json[gameId].memo = pangu.spacing(memo)
|
|
84
|
-
}
|
|
85
|
-
if (memo2) {
|
|
86
|
-
json[gameId].memo2 = pangu.spacing(memo2)
|
|
87
|
-
}
|
|
88
|
-
}
|
|
89
|
-
|
|
90
|
-
IGNORE_DATA.forEach((gameId) => delete json[gameId])
|
|
91
|
-
const data = JSON.stringify(json, undefined, 2)
|
|
92
|
-
writeFileSync(path.resolve(OUTPUT_PATH, DATA_FILE_NAME), data)
|
|
93
|
-
}
|
|
94
|
-
|
|
95
|
-
const downloadNewQuest = async () => {
|
|
96
|
-
const resp = await fetch(NEW_QUEST_URL)
|
|
97
|
-
if (!resp.ok) {
|
|
98
|
-
console.error(`Fetch Error!\nurl: ${resp.url}\nstatus: ${resp.status}`)
|
|
99
|
-
return
|
|
100
|
-
}
|
|
101
|
-
const text = await resp.text()
|
|
102
|
-
const json = Object.keys(JSON.parse(text))
|
|
103
|
-
const data = JSON.stringify(json, undefined, 2)
|
|
104
|
-
writeFileSync(path.resolve(OUTPUT_PATH, NEW_QUEST_FILE_NAME), data)
|
|
105
|
-
}
|
|
106
|
-
|
|
107
|
-
const main = async () => {
|
|
108
|
-
const args = process.argv.slice(2)
|
|
109
|
-
|
|
110
|
-
prepareDir(OUTPUT_PATH)
|
|
111
|
-
const remoteVersion = await getRemoteVersion()
|
|
112
|
-
const localVersion = getLocalVersion()
|
|
113
|
-
if (remoteVersion === localVersion) {
|
|
114
|
-
console.log('The local version is up to date. Version:', localVersion)
|
|
115
|
-
if (!args.find((v) => v === '-f' || v === '--force')) {
|
|
116
|
-
return
|
|
117
|
-
}
|
|
118
|
-
} else {
|
|
119
|
-
console.log('New Version Detected. Version:', remoteVersion)
|
|
120
|
-
}
|
|
121
|
-
|
|
122
|
-
console.log(`Download kcQuests data...`)
|
|
123
|
-
await Promise.all([downloadQuestData(), downloadNewQuest()])
|
|
124
|
-
|
|
125
|
-
const ts = genTS(remoteVersion)
|
|
126
|
-
writeFileSync(`${OUTPUT_PATH}/index.ts`, ts)
|
|
127
|
-
|
|
128
|
-
// Finally record the version number
|
|
129
|
-
writeFileSync(`${OUTPUT_PATH}/DATA_VERSION`, remoteVersion)
|
|
130
|
-
}
|
|
131
|
-
|
|
132
|
-
main()
|
|
133
|
-
|
|
134
|
-
process.on('unhandledRejection', (up) => {
|
|
135
|
-
throw up
|
|
136
|
-
})
|