diff --git a/apps/directory/src/routes/path/Home.jsx b/apps/directory/src/routes/path/Home.jsx index 9d3b567..864c59e 100644 --- a/apps/directory/src/routes/path/Home.jsx +++ b/apps/directory/src/routes/path/Home.jsx @@ -120,7 +120,7 @@ export default function Home() { const list = navigationList.filter((item) => { return ( item.name.toLowerCase().indexOf(searchField.toLowerCase()) !== - -1 || item.type === 'date' + -1 || item.type === 'date' ) }) const newList = [] @@ -222,7 +222,7 @@ export default function Home() { } viewBox={ entry.type === - 'operator' + 'operator' ? '0 0 88.969 71.469' : '0 0 94.563 67.437' } @@ -234,25 +234,24 @@ export default function Home() { } > {language === - 'zh-CN' + 'zh-CN' ? entry.type === - 'skin' - ? `${ - entry - .skinName[ - 'zh-CN' - ] - } · ${entry.operatorName}` + 'skin' + ? `${entry + .skinName[ + 'zh-CN' + ] + } · ${entry.operatorName}` : entry.operatorName : entry - .skinName[ - 'en-US' - ]} + .skinName[ + 'en-US' + ]}
@@ -369,9 +368,9 @@ function OperatorElement({ item, hidden, handleVoicePlay }) { { item.codename[ - language.startsWith('en') - ? alternateLang - : textDefaultLang + language.startsWith('en') + ? alternateLang + : textDefaultLang ] } @@ -430,13 +429,13 @@ function ImageElement({ item }) { const { language } = useLanguage() return ( {item.codename[language]} ) } ImageElement.propTypes = { item: PropTypes.object.isRequired, - fallback_name: PropTypes.string, + portrait_filename: PropTypes.string, codename: PropTypes.object, } diff --git a/apps/showcase/src/components/aklive2d.js b/apps/showcase/src/components/aklive2d.js index 173a709..97638ac 100644 --- a/apps/showcase/src/components/aklive2d.js +++ b/apps/showcase/src/components/aklive2d.js @@ -1,10 +1,8 @@ import Background from '@/components/background' import Events from '@/components/events' -import Fallback from '@/components/fallback' import { addEventListeners, insertHTMLChild, - isWebGLSupported, updateElementPosition, } from '@/components/helper' import Insight from '@/components/insight' @@ -42,11 +40,7 @@ export default class AKLive2D { this.#background = new Background(this.#appEl) this.#voice = new Voice(this.#appEl) this.#music = new Music(this.#appEl) - if (isWebGLSupported()) { - this.#player = new Player(this.#appEl) - } else { - new Fallback(this.#appEl) - } + this.#player = new Player(this.#appEl) addEventListeners([ { event: Events.Player.Ready.name, diff --git a/apps/showcase/src/components/fallback.css b/apps/showcase/src/components/fallback.css deleted file mode 100644 index 8552eca..0000000 --- a/apps/showcase/src/components/fallback.css +++ /dev/null @@ -1,16 +0,0 @@ -#fallback-box { - display: flex; - justify-content: center; - align-items: center; - width: 100%; - height: 100%; -} - -#fallback { - margin: auto; - background-position: center; - background-repeat: no-repeat; - background-size: cover; - width: 100%; - height: 100%; -} diff --git a/apps/showcase/src/components/fallback.js b/apps/showcase/src/components/fallback.js deleted file mode 100644 index b2f6f3d..0000000 --- a/apps/showcase/src/components/fallback.js +++ /dev/null @@ -1,40 +0,0 @@ -import { insertHTMLChild } from '@/components/helper' -import '@/components/fallback.css' -import buildConfig from '!/config.json' - -export default class Fallback { - #el = document.createElement('div') - - constructor(parentEl) { - alert('WebGL is unavailable. Fallback image will be used.') - const calculateScale = (width, height) => { - return { - x: window.innerWidth / width, - y: window.innerHeight / height, - } - } - const fallback = () => { - const el = document.getElementById('fallback-container') - const scale = calculateScale( - buildConfig.image_width, - buildConfig.image_height - ) - el.style.width = '100%' - el.style.height = - buildConfig.image_height * - (scale.x > scale.y ? scale.y : scale.x) + - 'px' - } - window.addEventListener('resize', fallback, true) - this.#el.id = 'fallback-box' - this.#el.innerHTML = ` -
-
-
- ` - insertHTMLChild(parentEl, this.#el) - fallback() - } -} diff --git a/apps/showcase/src/components/helper.js b/apps/showcase/src/components/helper.js index 521c0af..037f84c 100644 --- a/apps/showcase/src/components/helper.js +++ b/apps/showcase/src/components/helper.js @@ -1,15 +1,3 @@ -export const isWebGLSupported = () => { - try { - const canvas = document.createElement('canvas') - const ctx = - canvas.getContext('webgl') || - canvas.getContext('experimental-webgl') - return ctx != null - } catch { - return false - } -} - export const insertHTMLChild = (parent, child) => { parent.appendChild(child) } diff --git a/packages/assets/config.yaml b/packages/assets/config.yaml index 4e677b7..5976031 100644 --- a/packages/assets/config.yaml +++ b/packages/assets/config.yaml @@ -1,12 +1,12 @@ dynchars: dynchars item_to_download: - - homebackground/wrapper - - ui_camp_logo - - charportraits - - voice.*/extra - - char_128 + - homebackground/wrapper + - ui_camp_logo + - voice.*/extra + - char_128 + - spritepack/char_portrait.* additional_regex: - - ^(?!(avg|charpack))(.*)$ + - ^(?!(avg|charpack))(.*)$ servers: - - name: cn - url: https://ak-conf.hypergryph.com/config/prod/official/network_config \ No newline at end of file + - name: cn + url: https://ak-conf.hypergryph.com/config/prod/official/network_config diff --git a/packages/assets/libs/download.ts b/packages/assets/libs/download.ts index fb0b4af..0eab116 100644 --- a/packages/assets/libs/download.ts +++ b/packages/assets/libs/download.ts @@ -36,6 +36,7 @@ const download = async ( const lpacksRes: Response = await fetch( `${urls.hu}/Android/assets/${version}/hot_update_list.json` ) + console.log(urls, lpacksRes) const updateList: UpdateList = await lpacksRes.json() const itemToDownload: Set = new Set(config.item_to_download) updateList.abInfos.map((item: AbInfosItem) => { diff --git a/packages/config/config.yaml b/packages/config/config.yaml index ff8d06d..a04d1e5 100644 --- a/packages/config/config.yaml +++ b/packages/config/config.yaml @@ -1,109 +1,106 @@ site_id: aklive2d total_size: 26214400 # 1024 * 1024 * 25 akassets: - project_name: akassets - url: https://akassets.pages.dev + project_name: akassets + url: https://akassets.pages.dev insight: - id: aklive2d - url: https://insight.halyul.dev/on-demand.js + id: aklive2d + url: https://insight.halyul.dev/on-demand.js module: - assets: - config_yaml: config.yaml - background: background - music: music - charword_table: charword_table - project_json: project_json - background: - operator_bg_png: operator_bg.png - charword_table: - charword_table_json: charword_table.json - music: - music_table_json: music_table.json - display_meta_table_json: display_meta_table.json - audio_data_json: audio_data.json - official_info: - official_info_json: official_info.json - operator: - operator: operator - config: config - template_yaml: _template.yaml - config_yaml: config.yaml - portraits: _portraits - logos_assets: _logos - logos: logos - directory_assets: _directory - MonoBehaviour: MonoBehaviour - Texture2D: Texture2D - character_table_json: character_table.json - skin_table_json: skin_table.json - title: - zh-CN: '明日方舟:' - en-US: 'Arknights: ' - sp_filename_prefix: sp_ - sp_title: - zh-CN: '「SP」 ' - en-US: '[SP] ' - project_json: - project_json: project.json - preview_jpg: preview.jpg - template_yaml: project_json.yaml - wrangler: - index_json: index.json - vite_helpers: - config_json: config.json + assets: + config_yaml: config.yaml + background: background + music: music + charword_table: charword_table + project_json: project_json + background: + operator_bg_png: operator_bg.png + charword_table: + charword_table_json: charword_table.json + music: + music_table_json: music_table.json + display_meta_table_json: display_meta_table.json + audio_data_json: audio_data.json + official_info: + official_info_json: official_info.json + operator: + operator: operator + config: config + template_yaml: _template.yaml + config_yaml: config.yaml + logos_assets: _logos + logos: logos + directory_assets: _directory + character_table_json: character_table.json + skin_table_json: skin_table.json + title: + zh-CN: "明日方舟:" + en-US: "Arknights: " + sp_filename_prefix: sp_ + sp_title: + zh-CN: "「SP」 " + en-US: "[SP] " + project_json: + project_json: project.json + preview_jpg: preview.jpg + template_yaml: project_json.yaml + wrangler: + index_json: index.json + vite_helpers: + config_json: config.json app: - showcase: - public: public - assets: assets - release: release - directory: - assets: _assets - title: AKLive2D - voice: jp/CN_037.ogg - portraits: portraits - error: - files: - - key: build_char_128_plosis_epoque#3 - paddings: - left: -120 - right: 150 - top: 10 - bottom: 0 - - key: build_char_128_plosis - paddings: - left: -90 - right: 100 - top: 10 - bottom: 0 - - key: build_char_128_plosis_yun#4 - paddings: - left: -90 - right: 100 - top: 10 - bottom: 0 - voice: - file: CN_034.ogg - target: error.ogg + showcase: + public: public + assets: assets + release: release + directory: + assets: _assets + title: AKLive2D + voice: jp/CN_037.ogg + portraits: portraits + error: + files: + - key: build_char_128_plosis_epoque#3 + paddings: + left: -120 + right: 150 + top: 10 + bottom: 0 + - key: build_char_128_plosis + paddings: + left: -90 + right: 100 + top: 10 + bottom: 0 + - key: build_char_128_plosis_yun#4 + paddings: + left: -90 + right: 100 + top: 10 + bottom: 0 + voice: + file: CN_034.ogg + target: error.ogg dir_name: - data: data - dist: dist - extracted: extracted - auto_update: auto_update - voice: - main: voice - sub: - - name: jp - lang: JP - lookup_region: zh_CN - - name: cn - lang: CN_MANDARIN - lookup_region: zh_CN - - name: en - lang: EN - lookup_region: en_US - - name: kr - lang: KR - lookup_region: ko_KR - - name: custom - lang: CUSTOM - lookup_region: zh_CN + data: data + dist: dist + extracted: extracted + auto_update: auto_update + voice: + main: voice + sub: + - name: jp + lang: JP + lookup_region: zh_CN + - name: cn + lang: CN_MANDARIN + lookup_region: zh_CN + - name: en + lang: EN + lookup_region: en_US + - name: kr + lang: KR + lookup_region: ko_KR + - name: custom + lang: CUSTOM + lookup_region: zh_CN diff --git a/packages/config/types.ts b/packages/config/types.ts index 27e3476..494237a 100644 --- a/packages/config/types.ts +++ b/packages/config/types.ts @@ -41,12 +41,9 @@ export type Config = { config: string template_yaml: string config_yaml: string - portraits: string logos_assets: string logos: string directory_assets: string - MonoBehaviour: string - Texture2D: string character_table_json: string skin_table_json: string title: TitleLanguages diff --git a/packages/operator/index.ts b/packages/operator/index.ts index b9a23c4..45551c1 100644 --- a/packages/operator/index.ts +++ b/packages/operator/index.ts @@ -162,7 +162,6 @@ const generateMapping = () => { type === 'skin' ? skinEntry.skinId.replace(/@/, '_') : `${skinEntry.charId}_2` - operator.fallback_name = `${operator.portrait_filename}${operator.isSP ? '_sp' : ''}` const regions = Object.keys( operator.codename diff --git a/packages/operator/libs/builder.ts b/packages/operator/libs/builder.ts index c3593f4..44ac200 100644 --- a/packages/operator/libs/builder.ts +++ b/packages/operator/libs/builder.ts @@ -1,12 +1,11 @@ import path from 'node:path' import config from '@aklive2d/config' -import { alphaComposite, file } from '@aklive2d/libs' +import { file } from '@aklive2d/libs' import operators, { DIST_DIR, generateAssetsJson, OPERATOR_SOURCE_FOLDER, } from '../index.ts' -import type { PortraitHub, PortraitJson } from '../types.ts' import { getDistFolder, getExtractedFolder } from './utils.ts' export const build = async (namesToBuild: string[]) => { @@ -39,75 +38,10 @@ const generateAssets = async (name: string) => { file.rmdir(outDir) file.mkdir(outDir) - const fallback_name = operators[name].fallback_name - const fallbackFilename = `${fallback_name}.png` - const alphaCompositeFilename = `${path.parse(fallbackFilename).name}[alpha].png` - if (file.exists(path.join(extractedDir, alphaCompositeFilename))) { - const fallbackBuffer = await alphaComposite.process( - fallbackFilename, - alphaCompositeFilename, - extractedDir - ) - file.writeSync( - fallbackBuffer, - path.join(getDistFolder(name), fallbackFilename) - ) - } else { - await file.copy( - path.join(extractedDir, fallbackFilename), - path.join(getDistFolder(name), fallbackFilename) - ) - } - - // generate portrait - const portraitDir = path.join( - OPERATOR_SOURCE_FOLDER, - config.module.operator.portraits - ) - const portraitHubContent = file.readSync( - path.join( - portraitDir, - config.module.operator.MonoBehaviour, - 'portrait_hub.json' - ) - ) as string - if (!portraitHubContent) throw new Error('portrait_hub.json not found') - const portraitHub: PortraitHub = JSON.parse(portraitHubContent) - const portrait_filename_lowerCase = - operators[name].portrait_filename.toLowerCase() - const portraitItem = portraitHub._sprites.find( - (item) => item.name.toLowerCase() === portrait_filename_lowerCase - ) - if (!portraitItem) throw new Error(`portrait ${fallback_name} not found`) - const portraitAtlas = portraitItem.atlas - const portraitJsonText = file.readSync( - path.join( - portraitDir, - config.module.operator.MonoBehaviour, - `portraits#${portraitAtlas}.json` - ) - ) as string - if (!portraitJsonText) - throw new Error(`portrait ${fallback_name} json not found`) - const portraitJson: PortraitJson = JSON.parse(portraitJsonText) - const item = portraitJson._sprites.find( - (item) => item.name.toLowerCase() === portrait_filename_lowerCase - ) - if (!item) throw new Error(`portrait ${fallback_name} not found`) - const rect = { - ...item.rect, - rotate: item.rotate, - } - const protraitFilename = `portraits#${portraitAtlas}.png` - const portraitBuffer = await alphaComposite.process( - protraitFilename, - `${path.parse(protraitFilename).name}a.png`, - path.join(portraitDir, config.module.operator.Texture2D) - ) - const croppedBuffer = await alphaComposite.crop(portraitBuffer, rect) - file.writeSync( - croppedBuffer, - path.join(getDistFolder(name), `${fallback_name}_portrait.png`) + const portraitFilename = `${operators[name].portrait_filename}.png` + await file.copy( + path.join(extractedDir, portraitFilename), + path.join(getDistFolder(name), portraitFilename) ) await generateAssetsJson( diff --git a/packages/operator/types.ts b/packages/operator/types.ts index c773f4e..849581a 100644 --- a/packages/operator/types.ts +++ b/packages/operator/types.ts @@ -5,7 +5,6 @@ export type OperatorEntryType = 'operator' | 'skin' export interface OperatorConfig { filename: string logo: string - fallback_name: string portrait_filename: string viewport_left: number // should be default to 0 in the future viewport_right: number @@ -29,69 +28,6 @@ export type Config = { [name: string]: OperatorConfig } -type FileIDPathID = { - m_FileID: number - m_PathID: number -} - -export type PortraitHub = { - m_GameObject: FileIDPathID - m_Enabled: number - m_Script: FileIDPathID - m_Name: string - _sprites: { - name: string - atlas: number - }[] - _atlases: string[] - _inputSpriteDir: string - _outputAtlasDir: string - _rootAtlasName: string - _spriteSize: { - width: number - height: number - } - _cntPerAtlas: number - _maxAtlasSize: number -} - -type SignedItem = { - name: string - guid: string - md5: string -} - -export type PortraitJson = { - m_GameObject: FileIDPathID - m_Enabled: number - m_Script: FileIDPathID - m_Name: string - _sprites: { - name: string - guid: string - atlas: number - rect: { - x: number - y: number - w: number - h: number - } - rotate: number - }[] - _atlas: { - index: number - texture: FileIDPathID - alpha: FileIDPathID - size: number - } - _index: number - _sign: { - m_sprites: SignedItem[] - m_atlases: SignedItem[] - m_alphas: SignedItem[] - } -} - export type AssetsJson = { filename: string path?: string diff --git a/packages/vite-helpers/index.ts b/packages/vite-helpers/index.ts index 7712153..e0f772b 100644 --- a/packages/vite-helpers/index.ts +++ b/packages/vite-helpers/index.ts @@ -76,7 +76,7 @@ export const copyShowcaseData = ( }, { fn: file.symlink, - filename: `${operators[name].fallback_name}.png`, + filename: `${operators[name].portrait_filename}.png`, source: path.resolve( ASSETS_DIST_DIR, config.module.operator.operator, @@ -129,7 +129,10 @@ export const copyShowcaseData = ( link: operators[name].link, filename: filename.replace(/#/g, '%23'), logo_filename: operators[name].logo, - fallback_filename: operators[name].fallback_name.replace(/#/g, '%23'), + portrait_filename: operators[name].portrait_filename.replace( + /#/g, + '%23' + ), viewport_left: operators[name].viewport_left, viewport_right: operators[name].viewport_right, viewport_top: operators[name].viewport_top, @@ -319,7 +322,7 @@ export const copyDirectoryData = async ({ ] operatorFilesToCopy.map((key) => { - const portraitName = `${operators[key].fallback_name}_portrait.png` + const portraitName = `${operators[key].portrait_filename}.png` filesToCopy.push({ src: path.join( sourceFolder,