refactor: 收口 BangDream 卡牌边框资源仓储
This commit is contained in:
parent
60d1950af4
commit
ac5812e079
@ -306,6 +306,7 @@ export interface TsuguHook {
|
||||
- 已新增 `models/band-resource-repository.ts`,把 `Band` 的乐队 Logo 和乐队图标 SVG 资源路径从 `bestdoriUrl + downloadFileCache` 收口到 provider-backed repository;`band-resource-repository.spec.ts` 覆盖两类资源路径和下载调用,本地 `/查角色 1` 图片 smoke 保持非空输出。
|
||||
- 已新增 `models/attribute-resource-repository.ts`,把 `Attribute` 的属性图标 SVG 资源路径从 `bestdoriUrl + downloadFileCache` 收口到 provider-backed repository;`attribute-resource-repository.spec.ts` 覆盖属性图标路径和下载调用,本地 `/查卡 472` 图片 smoke 保持非空输出。
|
||||
- 已新增 `models/server-resource-repository.ts`,把 `Server` 的服务器图标 SVG 资源路径从 `bestdoriUrl + downloadFileCache` 收口到 provider-backed repository,并把台服本地图标路径改走 asset manifest;`server-resource-repository.spec.ts` 覆盖服务器图标路径、台服本地图标路径和下载调用,本地 `/查卡 472` 图片 smoke 保持非空输出。
|
||||
- 已新增 `render-blocks/card-art-resource-repository.ts`,把 `card-art.ts` 的卡牌小图/插画边框资源下载从 `bestdoriUrl + downloadFileCache` 收口到 provider-backed repository,`card-art-spec.ts` 改为只生成 `/res/image/...` 相对资源路径;`card-art-resource-repository.spec.ts` 覆盖边框下载调用,本地 `/查卡 472` 图片 smoke 保持非空输出。
|
||||
- 固化:Windows 下不要用反斜杠测试路径直接调用 Jest pattern,容易出现 `Pattern ... - 0 matches`;指定文件测试统一使用 `pnpm exec jest --runInBand --runTestsByPath test/qqbot/plugins/bangDream/tsugu/<file>.spec.ts ...`,路径用正斜杠。
|
||||
|
||||
### Phase 4:搜索 specification 和 matcher
|
||||
|
||||
@ -0,0 +1,45 @@
|
||||
import { bangDreamBestdoriProvider } from '@/qqbot/plugins/bangDream/tsugu/data-clients/bestdori-provider';
|
||||
import type { BangDreamDataProvider } from '@/qqbot/plugins/bangDream/tsugu/data-clients/data-provider';
|
||||
import type { BangDreamCardArtAttribute } from '@/qqbot/plugins/bangDream/tsugu/render-blocks/card-art-spec';
|
||||
import {
|
||||
createCardIconFramePath,
|
||||
createCardIllustrationFramePath,
|
||||
} from '@/qqbot/plugins/bangDream/tsugu/render-blocks/card-art-spec';
|
||||
|
||||
export class CardArtResourceRepository {
|
||||
constructor(
|
||||
private readonly provider: BangDreamDataProvider = bangDreamBestdoriProvider,
|
||||
) {}
|
||||
|
||||
/**
|
||||
* 下载卡牌小图边框资源。
|
||||
*
|
||||
* @param rarity - 卡牌稀有度。
|
||||
* @param attribute - 卡牌属性。
|
||||
*/
|
||||
async getIconFrameBuffer(
|
||||
rarity: number,
|
||||
attribute: BangDreamCardArtAttribute,
|
||||
): Promise<Buffer> {
|
||||
return await this.provider.getAsset(
|
||||
createCardIconFramePath(rarity, attribute),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* 下载卡牌插画边框资源。
|
||||
*
|
||||
* @param rarity - 卡牌稀有度。
|
||||
* @param attribute - 卡牌属性。
|
||||
*/
|
||||
async getIllustrationFrameBuffer(
|
||||
rarity: number,
|
||||
attribute: BangDreamCardArtAttribute,
|
||||
): Promise<Buffer> {
|
||||
return await this.provider.getAsset(
|
||||
createCardIllustrationFramePath(rarity, attribute),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export const cardArtResourceRepository = new CardArtResourceRepository();
|
||||
@ -45,49 +45,43 @@ export const BANGDREAM_CARD_ART_SPEC = {
|
||||
} as const;
|
||||
|
||||
/**
|
||||
* 创建卡牌小图边框资源 URL。
|
||||
* 创建卡牌小图边框资源路径。
|
||||
*
|
||||
* @param baseUrl - Bestdori 基础地址。
|
||||
* @param rarity - 卡牌稀有度。
|
||||
* @param attribute - 卡牌属性。
|
||||
*/
|
||||
export function createCardIconFrameUrl(
|
||||
baseUrl: string,
|
||||
export function createCardIconFramePath(
|
||||
rarity: number,
|
||||
attribute: BangDreamCardArtAttribute,
|
||||
): string {
|
||||
return createCardFrameUrl(baseUrl, 'card', rarity, attribute);
|
||||
return createCardFramePath('card', rarity, attribute);
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建卡牌插画边框资源 URL。
|
||||
* 创建卡牌插画边框资源路径。
|
||||
*
|
||||
* @param baseUrl - Bestdori 基础地址。
|
||||
* @param rarity - 卡牌稀有度。
|
||||
* @param attribute - 卡牌属性。
|
||||
*/
|
||||
export function createCardIllustrationFrameUrl(
|
||||
baseUrl: string,
|
||||
export function createCardIllustrationFramePath(
|
||||
rarity: number,
|
||||
attribute: BangDreamCardArtAttribute,
|
||||
): string {
|
||||
return createCardFrameUrl(baseUrl, 'frame', rarity, attribute);
|
||||
return createCardFramePath('frame', rarity, attribute);
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据 Bestdori 边框命名规则创建远程资源 URL。
|
||||
* 根据 Bestdori 边框命名规则创建远程资源路径。
|
||||
*
|
||||
* @param baseUrl - Bestdori 基础地址。
|
||||
* @param prefix - 边框资源前缀。
|
||||
* @param rarity - 卡牌稀有度。
|
||||
* @param attribute - 卡牌属性。
|
||||
*/
|
||||
function createCardFrameUrl(
|
||||
baseUrl: string,
|
||||
function createCardFramePath(
|
||||
prefix: 'card' | 'frame',
|
||||
rarity: number,
|
||||
attribute: BangDreamCardArtAttribute,
|
||||
): string {
|
||||
const frameName = rarity === 1 ? `${rarity}-${attribute}` : `${rarity}`;
|
||||
return `${baseUrl}/res/image/${prefix}-${frameName}.png`;
|
||||
return `/res/image/${prefix}-${frameName}.png`;
|
||||
}
|
||||
|
||||
@ -3,19 +3,16 @@ import { Band } from '@/qqbot/plugins/bangDream/tsugu/models/band';
|
||||
import { Attribute } from '@/qqbot/plugins/bangDream/tsugu/models/attribute';
|
||||
import { Card } from '@/qqbot/plugins/bangDream/tsugu/models/card';
|
||||
import { Image, Canvas, loadImage } from 'skia-canvas';
|
||||
import { downloadFileCache } from '@/qqbot/plugins/bangDream/tsugu/data-clients/asset-cache-client';
|
||||
import { drawCardIconSkill } from '@/qqbot/plugins/bangDream/tsugu/render-blocks/skill-text';
|
||||
import { Skill } from '@/qqbot/plugins/bangDream/tsugu/models/skill';
|
||||
import { bestdoriUrl } from '@/qqbot/plugins/bangDream/tsugu/runtime/config';
|
||||
import { loadImageFromPath } from '@/qqbot/plugins/bangDream/tsugu/canvas/image-utils';
|
||||
import { getBangDreamAssetPath } from '@/qqbot/plugins/bangDream/tsugu/runtime/asset-manifest';
|
||||
import { BANGDREAM_RENDER_THEME } from '@/qqbot/plugins/bangDream/tsugu/render-blocks/theme';
|
||||
import {
|
||||
BANGDREAM_CARD_ART_SPEC,
|
||||
BangDreamCardArtAttribute,
|
||||
createCardIconFrameUrl,
|
||||
createCardIllustrationFrameUrl,
|
||||
} from '@/qqbot/plugins/bangDream/tsugu/render-blocks/card-art-spec';
|
||||
import { cardArtResourceRepository } from '@/qqbot/plugins/bangDream/tsugu/render-blocks/card-art-resource-repository';
|
||||
|
||||
const cardTypeIconList: { [type: string]: Image } = {};
|
||||
const starList: { [type: string]: Image } = {};
|
||||
@ -60,8 +57,10 @@ async function getCardIconFrame(
|
||||
rarity: number,
|
||||
attribute: BangDreamCardArtAttribute,
|
||||
): Promise<Image> {
|
||||
const imageUrl = createCardIconFrameUrl(bestdoriUrl, rarity, attribute);
|
||||
const imageBuffer = await downloadFileCache(imageUrl);
|
||||
const imageBuffer = await cardArtResourceRepository.getIconFrameBuffer(
|
||||
rarity,
|
||||
attribute,
|
||||
);
|
||||
return await loadImage(imageBuffer);
|
||||
}
|
||||
|
||||
@ -77,12 +76,11 @@ async function getCardIllustrationFrame(
|
||||
rarity: number,
|
||||
attribute: BangDreamCardArtAttribute,
|
||||
): Promise<Image> {
|
||||
const imageUrl = createCardIllustrationFrameUrl(
|
||||
bestdoriUrl,
|
||||
rarity,
|
||||
attribute,
|
||||
);
|
||||
const imageBuffer = await downloadFileCache(imageUrl);
|
||||
const imageBuffer =
|
||||
await cardArtResourceRepository.getIllustrationFrameBuffer(
|
||||
rarity,
|
||||
attribute,
|
||||
);
|
||||
return await loadImage(imageBuffer);
|
||||
}
|
||||
|
||||
|
||||
@ -0,0 +1,40 @@
|
||||
import type { BangDreamDataProvider } from '@/qqbot/plugins/bangDream/tsugu/data-clients/data-provider';
|
||||
import { CardArtResourceRepository } from '@/qqbot/plugins/bangDream/tsugu/render-blocks/card-art-resource-repository';
|
||||
|
||||
function createProviderMock(): jest.Mocked<BangDreamDataProvider> {
|
||||
return {
|
||||
getAsset: jest.fn(),
|
||||
getJson: jest.fn(),
|
||||
getTracker: jest.fn(),
|
||||
name: 'MockBestdori',
|
||||
resolveUrl: jest.fn((pathOrUrl) => `https://bestdori.example${pathOrUrl}`),
|
||||
};
|
||||
}
|
||||
|
||||
describe('BangDream card art resource repository', () => {
|
||||
it('downloads card icon and illustration frames through the provider', async () => {
|
||||
const provider = createProviderMock();
|
||||
const iconFrameBuffer = Buffer.from('icon-frame');
|
||||
const illustrationFrameBuffer = Buffer.from('illustration-frame');
|
||||
provider.getAsset
|
||||
.mockResolvedValueOnce(iconFrameBuffer)
|
||||
.mockResolvedValueOnce(illustrationFrameBuffer);
|
||||
const repository = new CardArtResourceRepository(provider);
|
||||
|
||||
await expect(repository.getIconFrameBuffer(1, 'cool')).resolves.toBe(
|
||||
iconFrameBuffer,
|
||||
);
|
||||
await expect(
|
||||
repository.getIllustrationFrameBuffer(5, 'happy'),
|
||||
).resolves.toBe(illustrationFrameBuffer);
|
||||
|
||||
expect(provider.getAsset).toHaveBeenNthCalledWith(
|
||||
1,
|
||||
'/res/image/card-1-cool.png',
|
||||
);
|
||||
expect(provider.getAsset).toHaveBeenNthCalledWith(
|
||||
2,
|
||||
'/res/image/frame-5.png',
|
||||
);
|
||||
});
|
||||
});
|
||||
@ -1,29 +1,23 @@
|
||||
import {
|
||||
BANGDREAM_CARD_ART_SPEC,
|
||||
createCardIconFrameUrl,
|
||||
createCardIllustrationFrameUrl,
|
||||
createCardIconFramePath,
|
||||
createCardIllustrationFramePath,
|
||||
} from '@/qqbot/plugins/bangDream/tsugu/render-blocks/card-art-spec';
|
||||
|
||||
describe('BangDream card art spec', () => {
|
||||
it('creates icon frame urls with Bestdori rarity rules', () => {
|
||||
const baseUrl = 'https://bestdori.com';
|
||||
|
||||
expect(createCardIconFrameUrl(baseUrl, 1, 'cool')).toBe(
|
||||
'https://bestdori.com/res/image/card-1-cool.png',
|
||||
);
|
||||
expect(createCardIconFrameUrl(baseUrl, 5, 'happy')).toBe(
|
||||
'https://bestdori.com/res/image/card-5.png',
|
||||
it('creates icon frame paths with Bestdori rarity rules', () => {
|
||||
expect(createCardIconFramePath(1, 'cool')).toBe(
|
||||
'/res/image/card-1-cool.png',
|
||||
);
|
||||
expect(createCardIconFramePath(5, 'happy')).toBe('/res/image/card-5.png');
|
||||
});
|
||||
|
||||
it('creates illustration frame urls with Bestdori rarity rules', () => {
|
||||
const baseUrl = 'https://bestdori.com';
|
||||
|
||||
expect(createCardIllustrationFrameUrl(baseUrl, 1, 'pure')).toBe(
|
||||
'https://bestdori.com/res/image/frame-1-pure.png',
|
||||
it('creates illustration frame paths with Bestdori rarity rules', () => {
|
||||
expect(createCardIllustrationFramePath(1, 'pure')).toBe(
|
||||
'/res/image/frame-1-pure.png',
|
||||
);
|
||||
expect(createCardIllustrationFrameUrl(baseUrl, 4, 'powerful')).toBe(
|
||||
'https://bestdori.com/res/image/frame-4.png',
|
||||
expect(createCardIllustrationFramePath(4, 'powerful')).toBe(
|
||||
'/res/image/frame-4.png',
|
||||
);
|
||||
});
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user