Skip to content

Commit 1201a05

Browse files
committed
fix: bump operation version to 3 and fix incorrect value of requirements.module
1 parent 8bd52ea commit 1201a05

File tree

12 files changed

+200
-58
lines changed

12 files changed

+200
-58
lines changed

scripts/shared.ts

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -167,12 +167,13 @@ export async function getOperators() {
167167

168168
if (['TRAP'].includes(op.profession)) return []
169169

170-
const modules = equipsByOperatorId[id]
171-
?.sort((a, b) => a.charEquipOrder - b.charEquipOrder)
172-
.map(({ typeName1, typeName2 }) => {
173-
return typeName1 === 'ORIGINAL' ? '' : typeName2
174-
})
175-
.map((m) => (m === 'A' ? 'α' : m === 'D' ? 'Δ' : m))
170+
const modules = uniq(
171+
equipsByOperatorId[id]
172+
?.sort((a, b) => a.charEquipOrder - b.charEquipOrder)
173+
.map(({ typeName1, typeName2 }) => {
174+
return typeName1 === 'ORIGINAL' ? '' : typeName2
175+
}),
176+
)
176177
return [
177178
{
178179
id: id,
@@ -185,7 +186,7 @@ export async function getOperators() {
185186
? 0
186187
: Number(op.rarity?.split('TIER_').join('') || 0),
187188
alt_name: op.appellation,
188-
modules,
189+
modules: modules.length > 0 ? modules : undefined,
189190
},
190191
]
191192
}),

src/components/editor2/editor-state.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,9 @@ export interface EditorState {
2626
metadata: EditorMetadata
2727
}
2828

29-
const defaultOperation = operationLooseSchema.parse({ version: 2 })
29+
const defaultOperation = operationLooseSchema.parse({
30+
version: CopilotDocV1.VERSION,
31+
})
3032

3133
export const defaultEditorState: EditorState = {
3234
operation: toEditorOperation(defaultOperation),

src/components/editor2/operator/OperatorItem.tsx

Lines changed: 48 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ import {
1515
alternativeOperatorSkillUsages,
1616
getDefaultRequirements,
1717
getEliteIconUrl,
18+
getModuleName,
1819
getSkillCount,
1920
getSkillUsageAltTitle,
2021
useLocalizedOperatorName,
@@ -429,31 +430,54 @@ export const OperatorItem: FC<OperatorItemProps> = memo(
429430
<Select
430431
className="row-start-4"
431432
filterable={false}
432-
items={info.modules}
433+
items={[
434+
CopilotDocV1.Module.Default,
435+
...info.modules
436+
.map((m) =>
437+
m
438+
? (CopilotDocV1.Module[m] as
439+
| CopilotDocV1.Module
440+
| undefined)
441+
: CopilotDocV1.Module.Original,
442+
)
443+
.filter((m) => m !== undefined),
444+
]}
433445
itemRenderer={(
434-
item,
435-
{ index, handleClick, handleFocus, modifiers },
446+
value,
447+
{ handleClick, handleFocus, modifiers },
436448
) => (
437449
<MenuItem
438450
roleStructure="listoption"
439-
key={item}
451+
key={value}
440452
className={clsx(
441453
'min-w-12 !rounded-none text-base font-serif font-bold text-center text-slate-600 dark:text-slate-300',
442454
modifiers.active && Classes.ACTIVE,
443455
)}
444-
text={item || <Icon icon="disable" />}
456+
text={
457+
value === CopilotDocV1.Module.Default ? (
458+
<Icon icon="disable" />
459+
) : value === CopilotDocV1.Module.Original ? (
460+
<Icon icon="small-square" />
461+
) : (
462+
getModuleName(value)
463+
)
464+
}
465+
title={t.components.editor2.OperatorItem.module_title({
466+
count: value,
467+
name: getModuleName(value),
468+
})}
445469
onClick={handleClick}
446470
onFocus={handleFocus}
447-
selected={index === requirements.module}
471+
selected={value === requirements.module}
448472
/>
449473
)}
450-
onItemSelect={(item) => {
474+
onItemSelect={(value) => {
451475
edit(() => {
452476
onChange?.({
453477
...operator,
454478
requirements: {
455479
...operator.requirements,
456-
module: info.modules.indexOf(item),
480+
module: value,
457481
},
458482
})
459483
return {
@@ -472,15 +496,28 @@ export const OperatorItem: FC<OperatorItemProps> = memo(
472496
<Button
473497
small
474498
minimal
475-
title={t.components.editor2.OperatorItem.module}
499+
title={
500+
t.components.editor2.OperatorItem.module +
501+
': ' +
502+
t.components.editor2.OperatorItem.module_title({
503+
count: requirements.module,
504+
name: getModuleName(requirements.module),
505+
})
506+
}
476507
className={clsx(
477508
'w-4 h-4 !p-0 flex items-center justify-center font-serif !font-bold !text-base !rounded-none !border-2 !border-current',
478-
requirements.module
509+
requirements.module !== CopilotDocV1.Module.Default
479510
? '!bg-purple-100 dark:!bg-purple-900 dark:!text-purple-200 !text-purple-800'
480511
: '!bg-gray-300 dark:!bg-gray-600 opacity-15 dark:opacity-25 hover:opacity-30 dark:hover:opacity-50',
481512
)}
482513
>
483-
{info.modules[requirements.module]}
514+
{requirements.module ===
515+
CopilotDocV1.Module.Default ? null : requirements.module ===
516+
CopilotDocV1.Module.Original ? (
517+
<Icon icon="small-square" />
518+
) : (
519+
getModuleName(requirements.module)
520+
)}
484521
</Button>
485522
</Select>
486523
)}

src/components/editor2/reconciliation.ts

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import { atom } from 'jotai'
33
import { defaults, uniqueId } from 'lodash-es'
44
import { PartialDeep, SetOptional, SetRequired } from 'type-fest'
55

6+
import { migrateOperation } from '../../models/converter'
67
import { CopilotDocV1 } from '../../models/copilot.schema'
78
import { FavGroup, favGroupAtom } from '../../store/useFavGroups'
89
import { FavOperator, favOperatorAtom } from '../../store/useFavOperators'
@@ -218,7 +219,9 @@ export function toEditorOperation(
218219
source: CopilotOperationLoose,
219220
): EditorOperation {
220221
const camelCased = camelcaseKeys(source, { deep: true })
221-
const operation = JSON.parse(JSON.stringify(camelCased)) as typeof camelCased
222+
const operation = JSON.parse(
223+
JSON.stringify(migrateOperation(camelCased as CopilotDocV1.Operation)),
224+
) as typeof camelCased
222225
const converted = {
223226
...operation,
224227
actions: operation.actions.map((action, index) => {
@@ -227,7 +230,7 @@ export function toEditorOperation(
227230
postDelay,
228231
rearDelay,
229232
...newAction
230-
}: WithoutIdDeep<EditorAction> & (typeof camelCased)['actions'][number] =
233+
}: WithoutIdDeep<EditorAction> & (typeof operation)['actions'][number] =
231234
action
232235
// intermediatePostDelay 等于当前动作的 preDelay
233236
if (preDelay !== undefined) {
@@ -301,7 +304,7 @@ export function toMaaOperation(
301304
group.opers.some((operator) => operator.requirements),
302305
)
303306
) {
304-
converted.version = 2
307+
converted.version = CopilotDocV1.VERSION
305308
}
306309
}
307310

src/components/editor2/validation/schema.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ const operator_requirements = z.looseObject({
4343
elite: z.number().int().min(0).max(2).optional(),
4444
level: z.number().int().min(0).optional(),
4545
skill_level: z.number().int().min(0).max(10).optional(),
46-
module: z.number().int().min(0).optional(),
46+
module: z.number().int().optional(),
4747
potentiality: z.number().int().min(0).max(6).optional(),
4848
})
4949

src/components/viewer/OperationViewer.tsx

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@ import { Level } from '../../models/operation'
5454
import {
5555
OPERATORS,
5656
getEliteIconUrl,
57+
getModuleName,
5758
getSkillCount,
5859
useLocalizedOperatorName,
5960
withDefaultRequirements,
@@ -359,12 +360,19 @@ const OperatorCard: FC<{
359360
fallback={displayName}
360361
sourceSize={96}
361362
/>
362-
{info?.modules && module !== 0 && (
363+
{module !== CopilotDocV1.Module.Default && (
363364
<div
364-
title={t.components.editor2.label.opers.requirements.module}
365+
title={t.components.viewer.OperationViewer.module_title({
366+
count: module,
367+
name: getModuleName(module),
368+
})}
365369
className="absolute -bottom-1 right-1 font-serif font-bold text-lg text-white [text-shadow:0_0_3px_#a855f7,0_0_5px_#a855f7]"
366370
>
367-
{info.modules[module]}
371+
{module === CopilotDocV1.Module.Original ? (
372+
<Icon icon="small-square" />
373+
) : (
374+
getModuleName(module)
375+
)}
368376
</div>
369377
)}
370378
</div>

src/i18n/translations.json

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -828,6 +828,18 @@
828828
"cn": "模组",
829829
"en": "Module"
830830
},
831+
"module_title": {
832+
"cn": {
833+
"-1": "不改变",
834+
"0": "切换到初始模组",
835+
"other": "切换到{{name}}模组"
836+
},
837+
"en": {
838+
"-1": "Don't Change",
839+
"0": "Switch to Original Module",
840+
"other": "Switch to {{name}} Module"
841+
}
842+
},
831843
"skill_not_available": {
832844
"cn": "当前等级未解锁该技能",
833845
"en": "This skill is not available at the current level"
@@ -3016,6 +3028,16 @@
30163028
"cn": "无干员",
30173029
"en": "No Operator"
30183030
},
3031+
"module_title": {
3032+
"cn": {
3033+
"0": "初始模组",
3034+
"other": "{{name}}模组"
3035+
},
3036+
"en": {
3037+
"0": "Original Module",
3038+
"other": "{{name}} Module"
3039+
}
3040+
},
30193041
"action_sequence": {
30203042
"cn": "动作序列",
30213043
"en": "Action Sequence"

src/models/converter.ts

Lines changed: 41 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,20 @@
11
import camelcaseKeys from 'camelcase-keys'
22
import { CopilotInfo } from 'maa-copilot-client'
33

4-
import type { CopilotDocV1 } from 'models/copilot.schema'
4+
import { CopilotDocV1 } from 'models/copilot.schema'
55

66
import { i18n } from '../i18n/i18n'
7+
import { findOperatorByName } from './operator'
78

89
export function toCopilotOperation(
910
apiOperation: CopilotInfo,
1011
): CopilotDocV1.Operation {
1112
try {
1213
const json = JSON.parse(apiOperation.content)
13-
return camelcaseKeys(json, { deep: true })
14+
const operation: CopilotDocV1.Operation = camelcaseKeys(json, {
15+
deep: true,
16+
})
17+
return migrateOperation(operation)
1418
} catch (e) {
1519
console.error('Failed to parse operation', apiOperation, e)
1620
}
@@ -24,3 +28,38 @@ export function toCopilotOperation(
2428
stageName: '',
2529
}
2630
}
31+
32+
export function migrateOperation(
33+
operation: CopilotDocV1.Operation,
34+
): CopilotDocV1.Operation {
35+
if (operation.version === 2) {
36+
// in version 2, the module property is set to the index of the module in the modules array,
37+
// we need to convert it using the correct CopilotDocV1.Module mapping
38+
return {
39+
...operation,
40+
version: CopilotDocV1.VERSION,
41+
opers: operation.opers?.map((operator) => {
42+
if (operator.requirements?.module === undefined) {
43+
return operator
44+
}
45+
const modules = findOperatorByName(operator.name)?.modules
46+
if (!modules) {
47+
return operator
48+
}
49+
const actualModuleName = modules[operator.requirements.module]
50+
const actualModule =
51+
actualModuleName in CopilotDocV1.Module
52+
? (CopilotDocV1.Module[actualModuleName] as CopilotDocV1.Module)
53+
: CopilotDocV1.Module.Default
54+
return {
55+
...operator,
56+
requirements: {
57+
...operator.requirements,
58+
module: actualModule,
59+
},
60+
}
61+
}),
62+
}
63+
}
64+
return operation
65+
}

src/models/copilot.schema.json

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -127,10 +127,8 @@
127127
},
128128
"module": {
129129
"type": "integer",
130-
"description": "Module requirement, optional, 0 by default",
131-
"minimum": 0,
132-
"maximum": 1,
133-
"default": 0
130+
"description": "Module requirement, optional, -1 by default",
131+
"default": -1
134132
},
135133
"potentiality": {
136134
"type": "integer",

src/models/copilot.schema.ts

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@ import { OpDifficulty } from './operation'
55
* https://maa.plus/docs/zh-cn/protocol/copilot-schema.html
66
*/
77
export namespace CopilotDocV1 {
8+
export const VERSION = 3
9+
810
export interface Operation {
911
version?: number
1012
actions?: Action[]
@@ -164,8 +166,20 @@ export namespace CopilotDocV1 {
164166
export interface Requirements {
165167
elite?: number
166168
level?: number
167-
module?: number
169+
module?: Module
168170
potentiality?: number
169171
skillLevel?: number
170172
}
173+
174+
export enum Module {
175+
/** 默认值,不做任何操作 */
176+
Default = -1,
177+
/** 切换为初始模组 */
178+
Original = 0,
179+
/** 切换为对应的模组 */
180+
X = 1,
181+
Y = 2,
182+
A = 3,
183+
D = 4,
184+
}
171185
}

0 commit comments

Comments
 (0)