feat(aklive2d): use cf pages to store assets (upload) [1/2]
This commit is contained in:
@@ -1,4 +0,0 @@
|
||||
**/*
|
||||
!.git
|
||||
!CNAME
|
||||
!.nojekyll
|
||||
4
.github/workflows/cf-pages.yaml
vendored
4
.github/workflows/cf-pages.yaml
vendored
@@ -16,9 +16,9 @@ jobs:
|
||||
- name: Install dependencies
|
||||
run: pnpm i
|
||||
- name: Build all
|
||||
run: pnpm run build-all
|
||||
run: pnpm run operator:build-all
|
||||
- name: Build directory
|
||||
run: pnpm run vite:directory:build
|
||||
run: pnpm run directory:build
|
||||
- name: Publish to Cloudflare Pages
|
||||
uses: cloudflare/pages-action@v1
|
||||
with:
|
||||
|
||||
2
.github/workflows/update-charwords.yaml
vendored
2
.github/workflows/update-charwords.yaml
vendored
@@ -22,8 +22,6 @@ jobs:
|
||||
run: pnpm i
|
||||
- name: Update charwords
|
||||
run: pnpm run charwords:update
|
||||
- name: Build operator charwords
|
||||
run: pnpm run charwords:build
|
||||
- name: Commit changes if any
|
||||
uses: stefanzweifel/git-auto-commit-action@v4
|
||||
with:
|
||||
|
||||
4
.gitignore
vendored
4
.gitignore
vendored
@@ -137,4 +137,6 @@ _*.json
|
||||
*test*
|
||||
*_v2/*
|
||||
assets/*
|
||||
temp/*
|
||||
temp/*
|
||||
operator/*
|
||||
data/operator/*
|
||||
9
.vscode/launch.json
vendored
9
.vscode/launch.json
vendored
@@ -25,7 +25,7 @@
|
||||
"type": "node-terminal",
|
||||
"name": "Run Script: build-all",
|
||||
"request": "launch",
|
||||
"command": "pnpm run build-all",
|
||||
"command": "pnpm run operator:build-all",
|
||||
"cwd": "${workspaceFolder}"
|
||||
},
|
||||
{
|
||||
@@ -76,6 +76,13 @@
|
||||
"request": "launch",
|
||||
"command": "pnpm run offical_update",
|
||||
"cwd": "${workspaceFolder}"
|
||||
},
|
||||
{
|
||||
"type": "node-terminal",
|
||||
"name": "Run Script: cf:upload",
|
||||
"request": "launch",
|
||||
"command": "pnpm run cf:upload",
|
||||
"cwd": "${workspaceFolder}"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
73
aklive2d.js
73
aklive2d.js
@@ -7,7 +7,7 @@ import { fork } from 'child_process';
|
||||
import getConfig from './libs/config.js'
|
||||
import ProjectJson from './libs/project_json.js'
|
||||
import EnvGenerator from './libs/env_generator.js'
|
||||
import { write, rmdir, copy, writeSync, copyDir, readdirSync, exists } from './libs/file.js'
|
||||
import { write, rmdir, copy, writeSync, copyDir, readdirSync, exists, mkdir } from './libs/file.js'
|
||||
import AssetsProcessor from './libs/assets_processor.js'
|
||||
import init from './libs/initializer.js'
|
||||
import directory from './libs/directory.js'
|
||||
@@ -15,14 +15,18 @@ import Background from './libs/background.js'
|
||||
import CharwordTable from './libs/charword_table.js';
|
||||
import Music from './libs/music.js';
|
||||
import OfficalInfo from './libs/offical_info.js';
|
||||
import CFPages from './libs/cf_pages.js';
|
||||
|
||||
async function main() {
|
||||
global.__projectRoot = path.dirname(fileURLToPath(import.meta.url))
|
||||
const officalInfo = new OfficalInfo()
|
||||
global.__config = getConfig(officalInfo)
|
||||
|
||||
global.__error = []
|
||||
|
||||
const OPERATOR_SOURCE_FOLDER = path.join(__projectRoot, __config.folder.operator)
|
||||
const OPERATOR_SOURCE_DATA_FOLDER = path.join(__projectRoot, __config.folder.operator_data)
|
||||
const OPERATOR_SHARE_FOLDER = path.join(OPERATOR_SOURCE_DATA_FOLDER, __config.folder.share)
|
||||
|
||||
const op = process.argv[2]
|
||||
let OPERATOR_NAMES = process.argv.slice(3);
|
||||
|
||||
@@ -35,17 +39,12 @@ async function main() {
|
||||
* directory: build directory
|
||||
*/
|
||||
switch (op) {
|
||||
case 'directory':
|
||||
assert(OPERATOR_NAMES.length !== 0, 'Please set a mode for Directory.')
|
||||
fork(path.join(__projectRoot, 'vite.config.js'), [op, OPERATOR_NAMES])
|
||||
return
|
||||
case 'build-all':
|
||||
case 'charwords:build':
|
||||
case 'operator:build-all':
|
||||
for (const [key,] of Object.entries(__config.operators)) {
|
||||
OPERATOR_NAMES.push(key)
|
||||
}
|
||||
break
|
||||
case 'preview':
|
||||
case 'operator:preview':
|
||||
assert(OPERATOR_NAMES.length !== 0, 'Please set the operator name.')
|
||||
fork(path.join(__projectRoot, 'vite.config.js'), [op, OPERATOR_NAMES])
|
||||
return
|
||||
@@ -58,16 +57,22 @@ async function main() {
|
||||
case 'offical_update':
|
||||
await officalInfo.update()
|
||||
process.exit(0)
|
||||
case 'cf:upload':
|
||||
(new CFPages()).upload()
|
||||
process.exit(0)
|
||||
case 'cf:download':
|
||||
(new CFPages()).download()
|
||||
process.exit(0)
|
||||
default:
|
||||
break
|
||||
}
|
||||
|
||||
assert(OPERATOR_NAMES.length !== 0, 'Please set the operator name.')
|
||||
|
||||
const background = new Background()
|
||||
const background = new Background(OPERATOR_SHARE_FOLDER, OPERATOR_SOURCE_FOLDER)
|
||||
await background.process()
|
||||
const backgrounds = ['operator_bg.png', ...background.files]
|
||||
const { musicToCopy, musicMapping } = musicTable.copy()
|
||||
const { musicToCopy, musicMapping } = musicTable.copy(OPERATOR_SHARE_FOLDER)
|
||||
|
||||
for (const e of musicToCopy) {
|
||||
const musicPath = path.join(e.source, e.filename)
|
||||
@@ -83,12 +88,10 @@ async function main() {
|
||||
}
|
||||
|
||||
for (const OPERATOR_NAME of OPERATOR_NAMES) {
|
||||
const OPERATOR_SOURCE_FOLDER = path.join(__projectRoot, __config.folder.operator)
|
||||
const OPERATOR_RELEASE_FOLDER = path.join(__projectRoot, __config.folder.release, OPERATOR_NAME)
|
||||
const SHOWCASE_PUBLIC_ASSSETS_FOLDER = path.join(OPERATOR_RELEASE_FOLDER, "assets")
|
||||
const EXTRACTED_FOLDER = path.join(OPERATOR_SOURCE_FOLDER, OPERATOR_NAME, 'extracted')
|
||||
const VOICE_FOLDERS = __config.folder.voice.sub.map((sub) => path.join(OPERATOR_SOURCE_FOLDER, OPERATOR_NAME, __config.folder.voice.main, sub.name))
|
||||
const OPERATOR_SHARE_FOLDER = path.join(OPERATOR_SOURCE_FOLDER, __config.folder.share)
|
||||
const EXTRACTED_FOLDER = path.join(OPERATOR_SOURCE_DATA_FOLDER, OPERATOR_NAME, 'extracted')
|
||||
const VOICE_FOLDERS = __config.folder.voice.sub.map((sub) => path.join(OPERATOR_SOURCE_DATA_FOLDER, OPERATOR_NAME, __config.folder.voice.main, sub.name))
|
||||
|
||||
/**
|
||||
* Skip assets generation part
|
||||
@@ -104,6 +107,7 @@ async function main() {
|
||||
}
|
||||
|
||||
rmdir(OPERATOR_RELEASE_FOLDER)
|
||||
mkdir(path.join(OPERATOR_SOURCE_FOLDER, OPERATOR_NAME))
|
||||
|
||||
const charwordTableLookup = charwordTable.lookup(OPERATOR_NAME)
|
||||
const voiceJson = {}
|
||||
@@ -143,13 +147,6 @@ async function main() {
|
||||
console.log(`charword_table is not available`)
|
||||
}
|
||||
|
||||
switch (op) {
|
||||
case 'charwords:build':
|
||||
continue
|
||||
default:
|
||||
break
|
||||
}
|
||||
|
||||
// check whether voice files has been added
|
||||
const customVoiceName = voiceLangs.filter(i => !__config.folder.voice.sub.map(e => e.lang).includes(i))[0]
|
||||
const voiceLangMapping = __config.folder.voice.sub.filter(e => {
|
||||
@@ -161,7 +158,7 @@ async function main() {
|
||||
}
|
||||
})
|
||||
for (const voiceSubFolderMapping of voiceLangMapping) {
|
||||
const voiceSubFolder = path.join(OPERATOR_SOURCE_FOLDER, OPERATOR_NAME, __config.folder.voice.main, voiceSubFolderMapping.name)
|
||||
const voiceSubFolder = path.join(OPERATOR_SOURCE_DATA_FOLDER, OPERATOR_NAME, __config.folder.voice.main, voiceSubFolderMapping.name)
|
||||
if (readdirSync(voiceSubFolder).length === 0) {
|
||||
__error.push(`Voice folder ${voiceSubFolderMapping.name} for ${OPERATOR_NAME} is empty.`)
|
||||
}
|
||||
@@ -237,10 +234,10 @@ async function main() {
|
||||
})
|
||||
|
||||
const assetsProcessor = new AssetsProcessor(OPERATOR_NAME, OPERATOR_SHARE_FOLDER)
|
||||
assetsProcessor.process(EXTRACTED_FOLDER).then((content) => {
|
||||
write(JSON.stringify(content.assetsJson, null), path.join(OPERATOR_SOURCE_FOLDER, OPERATOR_NAME, `assets.json`))
|
||||
})
|
||||
|
||||
const assetContent = await assetsProcessor.process(EXTRACTED_FOLDER)
|
||||
write(JSON.stringify(assetContent.assetsJson, null), path.join(OPERATOR_SOURCE_FOLDER, OPERATOR_NAME, `assets.json`))
|
||||
|
||||
// copy remaining files
|
||||
const filesToCopy = [
|
||||
...background.getFilesToCopy(SHOWCASE_PUBLIC_ASSSETS_FOLDER),
|
||||
...musicToCopy.map(entry => {
|
||||
@@ -251,7 +248,7 @@ async function main() {
|
||||
}),
|
||||
{
|
||||
filename: 'preview.jpg',
|
||||
source: path.join(OPERATOR_SOURCE_FOLDER, OPERATOR_NAME),
|
||||
source: path.join(OPERATOR_SOURCE_DATA_FOLDER, OPERATOR_NAME),
|
||||
target: path.join(OPERATOR_RELEASE_FOLDER)
|
||||
},
|
||||
{
|
||||
@@ -281,7 +278,7 @@ async function main() {
|
||||
|
||||
const foldersToCopy = [
|
||||
{
|
||||
source: path.join(OPERATOR_SOURCE_FOLDER, OPERATOR_NAME, __config.folder.voice.main),
|
||||
source: path.join(OPERATOR_SOURCE_DATA_FOLDER, OPERATOR_NAME, __config.folder.voice.main),
|
||||
target: path.join(SHOWCASE_PUBLIC_ASSSETS_FOLDER, __config.folder.voice.main)
|
||||
}
|
||||
]
|
||||
@@ -289,20 +286,18 @@ async function main() {
|
||||
copyDir(folder.source, folder.target)
|
||||
})
|
||||
}
|
||||
|
||||
directory({ backgrounds, musicMapping })
|
||||
switch (op) {
|
||||
case op.startsWith('directory'):
|
||||
directory(OPERATOR_SOURCE_DATA_FOLDER, { backgrounds, musicMapping })
|
||||
default:
|
||||
break
|
||||
}
|
||||
if (__error.length > 0) {
|
||||
const str = `${__error.length} error${__error.length > 1 ? 's were' : ' was'} found:\n${__error.join('\n')}`
|
||||
throw new Error(str)
|
||||
} else {
|
||||
switch (op) {
|
||||
case 'charwords:build':
|
||||
return
|
||||
default:
|
||||
for (const OPERATOR_NAME of OPERATOR_NAMES) {
|
||||
fork(path.join(__projectRoot, 'vite.config.js'), [op, OPERATOR_NAME])
|
||||
}
|
||||
return
|
||||
for (const OPERATOR_NAME of OPERATOR_NAMES) {
|
||||
fork(path.join(__projectRoot, 'vite.config.js'), [op, OPERATOR_NAME])
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
folder:
|
||||
auto_update_data: ./data/auto_update
|
||||
operator_data: ./data/operator/
|
||||
directory_src: directory
|
||||
showcase_src: showcase
|
||||
operator: ./operator/
|
||||
|
||||
1
data/auto_update/audio_data_1722478731000.json
Normal file
1
data/auto_update/audio_data_1722478731000.json
Normal file
File diff suppressed because one or more lines are too long
1
data/auto_update/charword_table.json
Normal file
1
data/auto_update/charword_table.json
Normal file
File diff suppressed because one or more lines are too long
1
data/auto_update/charword_table_en_US_1722478623000.json
Normal file
1
data/auto_update/charword_table_en_US_1722478623000.json
Normal file
File diff suppressed because one or more lines are too long
1
data/auto_update/charword_table_ja_JP_1722400682000.json
Normal file
1
data/auto_update/charword_table_ja_JP_1722400682000.json
Normal file
File diff suppressed because one or more lines are too long
1
data/auto_update/charword_table_ko_KR_1722478414000.json
Normal file
1
data/auto_update/charword_table_ko_KR_1722478414000.json
Normal file
File diff suppressed because one or more lines are too long
1
data/auto_update/charword_table_zh_CN_1722478731000.json
Normal file
1
data/auto_update/charword_table_zh_CN_1722478731000.json
Normal file
File diff suppressed because one or more lines are too long
1
data/auto_update/display_meta_table_1723104164000.json
Normal file
1
data/auto_update/display_meta_table_1723104164000.json
Normal file
File diff suppressed because one or more lines are too long
1
data/auto_update/music_table.json
Normal file
1
data/auto_update/music_table.json
Normal file
@@ -0,0 +1 @@
|
||||
[{"id":"bg_rhodes_day","intro":"Audio/Sound_Beta_2/Music/beta1_180603/m_sys_void_intro","loop":"Audio/Sound_Beta_2/Music/beta1_180603/m_sys_void_loop"},{"id":"bg_rhodes_night","intro":"Audio/Sound_Beta_2/Music/beta2_180603/m_sys_tech_intro","loop":"Audio/Sound_Beta_2/Music/beta2_180603/m_sys_tech_loop"},{"id":"bg_main_victoria_1","intro":"Audio/Sound_Beta_2/Music/AVG/m_avg_ghosthunter_intro","loop":"Audio/Sound_Beta_2/Music/AVG/m_avg_ghosthunter_loop"},{"id":"bg_siesta_1","intro":"Audio/Sound_Beta_2/Music/obt/m_sys_ddd_intro","loop":"Audio/Sound_Beta_2/Music/obt/m_sys_ddd_loop"},{"id":"bg_kazimierz_1","intro":"Audio/Sound_Beta_2/Music/beta3_181101/m_dia_street_intro","loop":"Audio/Sound_Beta_2/Music/beta3_181101/m_dia_street_loop"},{"id":"bg_ursus_1","intro":"Audio/Sound_Beta_2/Music/static/m_avg/m_avg_loneliness_intro","loop":"Audio/Sound_Beta_2/Music/static/m_avg/m_avg_loneliness_loop"},{"id":"bg_yan_1","intro":null,"loop":"Audio/Sound_Beta_2/Music/act15side/m_sys_bitw_loop"},{"id":"bg_iberia_1","intro":"Audio/Sound_Beta_2/Music/act18d3d0/m_sys_act18d3d0_intro","loop":"Audio/Sound_Beta_2/Music/act18d3d0/m_sys_act18d3d0_loop"},{"id":"bg_anniversary_1","intro":"Audio/Sound_Beta_2/Music/beta2_180603/m_dia_nightoflongmen_intro","loop":"Audio/Sound_Beta_2/Music/beta2_180603/m_dia_nightoflongmen_loop"},{"id":"bg_rogue_1","intro":null,"loop":"Audio/Sound_Beta_2/Music/rogue_1/m_avg_rglk1secretevent_loop"},{"id":"bg_rogue_2","intro":null,"loop":"Audio/Sound_Beta_2/Music/rogue_2/m_sys_rglk2DLC_loop"},{"id":"bg_laterano_1","intro":"Audio/Sound_Beta_2/Music/act16side/m_sys_act16side_intro","loop":"Audio/Sound_Beta_2/Music/act16side/m_sys_act16side_loop"},{"id":"bg_rhine_1","intro":"Audio/Sound_Beta_2/Music/act19side/m_sys_act19side_intro","loop":"Audio/Sound_Beta_2/Music/act19side/m_sys_act19side_loop"},{"id":"bg_kalts_1","intro":"Audio/Sound_Beta_2/Music/act18d0d0/m_sys_act18d0d0_intro","loop":"Audio/Sound_Beta_2/Music/act18d0d0/m_sys_act18d0d0_loop"},{"id":"bg_rogue_3","intro":"Audio/Sound_Beta_2/Music/rogue_3/m_bat_rglk3DLC_intro","loop":"Audio/Sound_Beta_2/Music/rogue_3/m_bat_rglk3DLC_loop"},{"id":"bg_rainbowsix_1","intro":null,"loop":"Audio/Sound_Beta_2/Music/act32side/m_act32side_sys_loop"},{"id":"bg_rhodes_flower_1","intro":"Audio/Sound_Beta_2/Music/act16mini/m_sys_act16mini_intro","loop":"Audio/Sound_Beta_2/Music/act16mini/m_sys_act16mini_loop"},{"id":"bg_sanrio_1","intro":null,"loop":"Audio/Sound_Beta_2/Music/act27side/m_avg_SiestaCity"},{"id":"operator_bg","intro":"m_sys_void_intro","loop":"m_sys_void_loop"}]
|
||||
@@ -3,7 +3,7 @@ VITE_APP_VOICE_URL=jp/CN_037.ogg
|
||||
VITE_VOICE_FOLDERS={"main":"voice","sub":[{"name":"jp","lang":"JP"},{"name":"cn","lang":"CN_MANDARIN"},{"name":"en","lang":"EN"},{"name":"kr","lang":"KR"},{"name":"custom","lang":"CUSTOM"}]}
|
||||
VITE_DIRECTORY_FOLDER="_assets"
|
||||
VITE_BACKGROUND_FOLDER="background"
|
||||
VITE_AVAILABLE_OPERATORS=["chen","dusk","dusk_everything_is_a_miracle","ling","nearl","nian","nian_unfettered_freedom","phatom_focus","rosmontis","skadi","skadi_sublimation","w","w_wonder","specter","gavial","surtr_colorful_wonderland","lee_trust_your_eyes","texas_the_omertosa","nearl_relight","rosmontis_become_anew","passager_dream_in_a_moment","mizuki_summer_feast","chongyue","ling_it_does_wash_the_strings","pozemka_snowy_plains_in_words","chen_ten_thousand_mountains","specter_born_as_one","muelsyse","kaltsit_remnant","eyjafjalla_the_hvit_aska","goldenglow_summer_flowers_fa394","gavial_the_invincible_holiday_hd26","ling_towering_is_cliff_of_nostalgia","virtuosa","texas_the_omertosa_wingbreaker","mwynar_w_dali","reed_the_frame_shadow_curator","shu","lin_heavenly_mirage","chongyue_alighting","wisadel","muelsyse_young_branch","skadi_the_corrupting_heart_red_countess","ines_under_the_flaming_dome","silverash_never_melting_ice","reed_the_frame_shadow_summer_flower"]
|
||||
VITE_AVAILABLE_OPERATORS=["chen","dusk","dusk_everything_is_a_miracle","ling","nearl","nian","nian_unfettered_freedom","phatom_focus","rosmontis","skadi","skadi_sublimation","w","w_wonder","specter","gavial","surtr_colorful_wonderland","lee_trust_your_eyes","texas_the_omertosa","nearl_relight","rosmontis_become_anew","passager_dream_in_a_moment","mizuki_summer_feast","chongyue","ling_it_does_wash_the_strings","pozemka_snowy_plains_in_words","chen_ten_thousand_mountains","specter_born_as_one","muelsyse","kaltsit_remnant","eyjafjalla_the_hvit_aska","goldenglow_summer_flowers_fa394","gavial_the_invincible_holiday_hd26","ling_towering_is_cliff_of_nostalgia","virtuosa","texas_the_omertosa_wingbreaker","mwynar_w_dali","reed_the_frame_shadow_curator","shu","lin_heavenly_mirage","chongyue_alighting","wisadel","muelsyse_young_branch","skadi_the_corrupting_heart_red_countess","ines_under_the_flaming_dome","silverash_never_melting_ice","reed_the_frame_shadow_summer_flower","eyjafjalla_the_hvit_aska_a_picnic_before_a_long_trip","pepe","nightingale_iakhu_of_flows"]
|
||||
VITE_ERROR_FILES={"files":[{"key":"build_char_128_plosis_epoque%233","paddings":{"left":-120,"right":150,"top":10,"bottom":0}},{"key":"build_char_128_plosis","paddings":{"left":-90,"right":100,"top":10,"bottom":0}}],"voice":"CN_034.ogg"}
|
||||
VITE_MUSIC_FOLDER=music
|
||||
VITE_MUSIC_MAPPING={"bg_rhodes_day.png":{"intro":"m_sys_void_intro.ogg","loop":"m_sys_void_loop.ogg"},"bg_rhodes_night.png":{"intro":"m_sys_tech_intro.ogg","loop":"m_sys_tech_loop.ogg"},"bg_main_victoria_1.png":{"intro":"m_avg_ghosthunter_intro.ogg","loop":"m_avg_ghosthunter_loop.ogg"},"bg_siesta_1.png":{"intro":"m_sys_ddd_intro.ogg","loop":"m_sys_ddd_loop.ogg"},"bg_kazimierz_1.png":{"intro":"m_dia_street_intro.ogg","loop":"m_dia_street_loop.ogg"},"bg_ursus_1.png":{"intro":"m_avg_loneliness_intro.ogg","loop":"m_avg_loneliness_loop.ogg"},"bg_yan_1.png":{"intro":null,"loop":"m_sys_bitw_loop.ogg"},"bg_iberia_1.png":{"intro":"m_sys_act18d3d0_intro.ogg","loop":"m_sys_act18d3d0_loop.ogg"},"bg_anniversary_1.png":{"intro":"m_dia_nightoflongmen_intro.ogg","loop":"m_dia_nightoflongmen_loop.ogg"},"bg_rogue_1.png":{"intro":null,"loop":"m_avg_rglk1secretevent_loop.ogg"},"bg_rogue_2.png":{"intro":null,"loop":"m_sys_rglk2DLC_loop.ogg"},"bg_laterano_1.png":{"intro":"m_sys_act16side_intro.ogg","loop":"m_sys_act16side_loop.ogg"},"bg_rhine_1.png":{"intro":"m_sys_act19side_intro.ogg","loop":"m_sys_act19side_loop.ogg"},"bg_kalts_1.png":{"intro":"m_sys_act18d0d0_intro.ogg","loop":"m_sys_act18d0d0_loop.ogg"},"bg_rogue_3.png":{"intro":"m_bat_rglk3DLC_intro.ogg","loop":"m_bat_rglk3DLC_loop.ogg"},"bg_rainbowsix_1.png":{"intro":null,"loop":"m_act32side_sys_loop.ogg"},"bg_rhodes_flower_1.png":{"intro":"m_sys_act16mini_intro.ogg","loop":"m_sys_act16mini_loop.ogg"},"bg_sanrio_1.png":{"intro":null,"loop":"m_avg_SiestaCity.ogg"},"operator_bg.png":{"intro":"m_sys_void_intro.ogg","loop":"m_sys_void_loop.ogg"}}
|
||||
142
directory/src/scss/operator/Operator.module.scss
Normal file
142
directory/src/scss/operator/Operator.module.scss
Normal file
@@ -0,0 +1,142 @@
|
||||
@use "@/scss/_page_base.scss";
|
||||
|
||||
.main {
|
||||
padding: 3rem 0 2rem 0;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: flex-start;
|
||||
|
||||
.container {
|
||||
background-position: center;
|
||||
background-repeat: no-repeat;
|
||||
background-size: cover;
|
||||
width: 100%;
|
||||
position: relative;
|
||||
margin-bottom: 2rem;
|
||||
user-select: none;
|
||||
|
||||
&:before {
|
||||
content: "";
|
||||
display: block;
|
||||
padding-top: 100%;
|
||||
}
|
||||
|
||||
.wrapper {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
bottom: 0;
|
||||
right: 0;
|
||||
}
|
||||
|
||||
@media (max-width: 1280px) {
|
||||
width: 100%;
|
||||
position: relative;
|
||||
margin-bottom: 2rem;
|
||||
&:before {
|
||||
content: "";
|
||||
display: block;
|
||||
padding-top: 100%;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.settings {
|
||||
margin-right: 1.5rem;
|
||||
user-select: none;
|
||||
margin-left: 1rem;
|
||||
|
||||
.title {
|
||||
font-size: 1.25rem;
|
||||
border-left: 3px solid currentColor;
|
||||
padding-left: 0.75rem;
|
||||
margin-bottom: 0.8rem;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
cursor: pointer;
|
||||
|
||||
.switch {
|
||||
bottom: -10px;
|
||||
position: relative;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.text {
|
||||
color: var(--text-color);
|
||||
line-height: 1.2;
|
||||
}
|
||||
|
||||
.logo {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 30%;
|
||||
height: auto;
|
||||
opacity: 0.3;
|
||||
}
|
||||
|
||||
.voice {
|
||||
position: absolute;
|
||||
left: 0;
|
||||
bottom: 20%;
|
||||
z-index: 1;
|
||||
max-width: 480px;
|
||||
width: 85%;
|
||||
opacity: 0;
|
||||
margin: 16px;
|
||||
transition: all 0.5s cubic-bezier(0.65, 0.05, 0.36, 1);
|
||||
visibility: hidden;
|
||||
font-family: 'Noto Sans SC', 'Noto Sans JP', 'Noto Sans KR', 'Noto Sans', sans-serif;
|
||||
|
||||
.type {
|
||||
background-color: #9e9e9e;
|
||||
color: #000;
|
||||
display: inline-block;
|
||||
position: absolute;
|
||||
top: -12px;
|
||||
left: -8px;
|
||||
padding: 2px 8px;
|
||||
font-size: 14px;
|
||||
max-width: 180px;
|
||||
width: 65%;
|
||||
box-shadow: 0 3px 6px #00000080;
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
.subtitle {
|
||||
background-color: #000000a6;
|
||||
color: #fff;
|
||||
padding: 16px;
|
||||
font-size: 18px;
|
||||
box-shadow: 0 6px 12px #00000080;
|
||||
position: relative;
|
||||
word-break: break-word;
|
||||
}
|
||||
|
||||
.triangle {
|
||||
position: absolute;
|
||||
bottom: 0px;
|
||||
right: 8px;
|
||||
width: 0;
|
||||
height: 0;
|
||||
border-style: solid;
|
||||
border-width: 8px 8px 8px 8px;
|
||||
border-color: white transparent transparent transparent;
|
||||
}
|
||||
|
||||
&.active {
|
||||
opacity: 1;
|
||||
visibility: visible;
|
||||
}
|
||||
|
||||
@media (max-width: 1280px) {
|
||||
bottom: 0;
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 1280px) {
|
||||
flex-direction: column-reverse;
|
||||
align-items: stretch;
|
||||
}
|
||||
}
|
||||
@@ -2,29 +2,29 @@
|
||||
import path from 'path';
|
||||
import fs from 'fs';
|
||||
import sharp from "sharp";
|
||||
import { mkdir } from './file.js'
|
||||
|
||||
export default class Background {
|
||||
#backgroundFolder
|
||||
#backgroundOutputFolder
|
||||
#extractFolder
|
||||
#files
|
||||
|
||||
constructor() {
|
||||
this.#backgroundFolder = path.join(__projectRoot, __config.folder.operator, __config.folder.share, __config.folder.background);
|
||||
constructor(shareDir, targetDir) {
|
||||
this.#backgroundFolder = path.join(shareDir, __config.folder.background);
|
||||
this.#backgroundOutputFolder = path.join(targetDir, `_${__config.folder.background}`);
|
||||
this.#extractFolder = path.join(this.#backgroundFolder, 'extracted');
|
||||
mkdir(this.#backgroundOutputFolder);
|
||||
}
|
||||
|
||||
async process() {
|
||||
this.#files = fs.readdirSync(this.#extractFolder).filter((f) => {
|
||||
return f.endsWith('.png') && f.includes('_left');
|
||||
})
|
||||
if (this.#files.length !== fs.readdirSync(this.#backgroundFolder).length - 1) {
|
||||
await Promise.all(this.#files.map(async (f) => {
|
||||
const filenamePrefix = path.parse(f).name.replace('_left', '');
|
||||
await this.#composite(filenamePrefix, '.png');
|
||||
}))
|
||||
} else {
|
||||
console.log('Background images already exist, skip generation.')
|
||||
}
|
||||
await Promise.all(this.#files.map(async (f) => {
|
||||
const filenamePrefix = path.parse(f).name.replace('_left', '');
|
||||
await this.#composite(filenamePrefix, '.png');
|
||||
}))
|
||||
}
|
||||
|
||||
async #composite(filenamePrefix, fileExt) {
|
||||
@@ -45,7 +45,7 @@ export default class Background {
|
||||
left: metadata.width,
|
||||
},
|
||||
])
|
||||
.toFile(path.join(this.#backgroundFolder, `${filenamePrefix}${fileExt}`));
|
||||
.toFile(path.join(this.#backgroundOutputFolder, `${filenamePrefix}${fileExt}`));
|
||||
}
|
||||
|
||||
get files() {
|
||||
@@ -56,7 +56,7 @@ export default class Background {
|
||||
return this.#files.map((f) => {
|
||||
return {
|
||||
filename: f.replace('_left', ''),
|
||||
source: path.join(this.#backgroundFolder),
|
||||
source: path.join(this.#backgroundOutputFolder),
|
||||
target: path.join(publicAssetsDir, __config.folder.background)
|
||||
};
|
||||
})
|
||||
|
||||
66
libs/cf_pages.js
Normal file
66
libs/cf_pages.js
Normal file
@@ -0,0 +1,66 @@
|
||||
/* eslint-disable no-undef */
|
||||
import path from 'path';
|
||||
import { spawnSync } from 'child_process';
|
||||
import { readdirSync, fileTypeSync, writeSync } from './file.js';
|
||||
|
||||
export default class CFPages {
|
||||
#uploadPath = path.join(__projectRoot, __config.folder.operator_data);
|
||||
#gitignorePath = path.join(__projectRoot, '.gitignore');
|
||||
|
||||
constructor() {
|
||||
|
||||
}
|
||||
|
||||
upload() {
|
||||
const tree = this.#generateDirTree(this.#uploadPath);
|
||||
writeSync(JSON.stringify(tree, null), path.join(this.#uploadPath, 'index.json'));
|
||||
const wrangler = spawnSync('pnpm', ['wrangler', 'pages', 'deploy', this.#uploadPath]);
|
||||
|
||||
console.log('error', wrangler.error);
|
||||
console.log('stdout ', wrangler.stdout.toString());
|
||||
console.log('stderr ', wrangler.stderr.toString());
|
||||
}
|
||||
|
||||
download() {
|
||||
|
||||
}
|
||||
|
||||
#generateDirTree(dir) {
|
||||
const files = readdirSync(dir);
|
||||
let tree = {
|
||||
name: path.basename(dir),
|
||||
type: 'dir',
|
||||
children: []
|
||||
};
|
||||
for (const file of files) {
|
||||
if (this.#isToIgnore(file)) {
|
||||
continue;
|
||||
}
|
||||
const filePath = path.join(dir, file);
|
||||
const dirType = fileTypeSync(filePath);
|
||||
if (dirType === 'dir') {
|
||||
tree.children.push(this.#generateDirTree(filePath))
|
||||
} else {
|
||||
tree.children.push({
|
||||
name: file,
|
||||
type: 'file'
|
||||
});
|
||||
}
|
||||
}
|
||||
if (tree.children.length === 0) {
|
||||
return null;
|
||||
}
|
||||
return tree
|
||||
}
|
||||
|
||||
// TODO
|
||||
#isToIgnore(file) {
|
||||
switch (file) {
|
||||
case '.DS_Store':
|
||||
case 'index.json':
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -30,7 +30,7 @@ export function getOperatorId(operatorConfig) {
|
||||
|
||||
export default class CharwordTable {
|
||||
#operatorIDs = Object.values(__config.operators).map(operator => { return getOperatorId(operator) })
|
||||
#charwordTablePath = path.join(__projectRoot, __config.folder.operator, __config.folder.share)
|
||||
#charwordTablePath = path.join(__projectRoot, __config.folder.auto_update_data)
|
||||
#charwordTableFile = path.join(this.#charwordTablePath, 'charword_table.json')
|
||||
#charwordTable = JSON.parse(readSync(this.#charwordTableFile)) || {
|
||||
config: {
|
||||
|
||||
@@ -1,12 +1,11 @@
|
||||
/* eslint-disable no-undef */
|
||||
import path from 'path'
|
||||
import { writeSync, copy, readSync as readFile } from './file.js'
|
||||
import { read } from './yaml.js';
|
||||
import AssetsProcessor from './assets_processor.js'
|
||||
import EnvGenerator from './env_generator.js'
|
||||
|
||||
export default function ({ backgrounds, musicMapping }) {
|
||||
const extractedFolder = path.join(__projectRoot, __config.folder.operator, '_directory')
|
||||
export default function (dataDir, { backgrounds, musicMapping }) {
|
||||
const extractedFolder = path.join(dataDir, '_directory')
|
||||
const targetFolder = path.join(__projectRoot, __config.folder.release, __config.folder.directory);
|
||||
const directoryAssetFolder = path.join(__projectRoot, 'directory', 'src');
|
||||
const sourceFolder = path.join(__projectRoot, __config.folder.operator);
|
||||
@@ -24,7 +23,7 @@ export default function ({ backgrounds, musicMapping }) {
|
||||
|
||||
cur.workshopId = null
|
||||
try {
|
||||
cur.workshopId = JSON.parse(readFile(path.join(__projectRoot, __config.folder.operator, cur.link, 'project.json'))).workshopid
|
||||
cur.workshopId = JSON.parse(readFile(path.join(dataDir, cur.link, 'project.json'))).workshopid
|
||||
} catch (e) {
|
||||
console.log(`No workshop id for ${cur.link}!`)
|
||||
}
|
||||
|
||||
@@ -73,3 +73,11 @@ export function readdirSync(dir) {
|
||||
}
|
||||
return fs.readdirSync(dir)
|
||||
}
|
||||
|
||||
export function fileTypeSync(dir) {
|
||||
if (!exists(dir)) {
|
||||
console.warn(`Source ${dir} does not exist.`)
|
||||
return null
|
||||
}
|
||||
return fs.statSync(dir).isDirectory() ? 'dir' : 'file'
|
||||
}
|
||||
|
||||
@@ -5,7 +5,7 @@ import Downloader from "./downloader.js"
|
||||
|
||||
export default class Music {
|
||||
#downloader = new Downloader()
|
||||
#sharedPath = path.join(__projectRoot, __config.folder.operator, __config.folder.share)
|
||||
#sharedPath = path.join(__projectRoot, __config.folder.auto_update_data)
|
||||
|
||||
async process() {
|
||||
const { metaTable, audioDataTable } = await this.#download()
|
||||
@@ -49,8 +49,8 @@ export default class Music {
|
||||
}
|
||||
}
|
||||
|
||||
copy() {
|
||||
const musicFolder = path.join(__projectRoot, __config.folder.operator, __config.folder.share, __config.folder.music);
|
||||
copy(shareDir) {
|
||||
const musicFolder = path.join(shareDir, __config.folder.music);
|
||||
const musicTable = JSON.parse(readSync(path.join(this.#sharedPath, `music_table.json`)))
|
||||
const musicMapping = {}
|
||||
const musicToCopy = []
|
||||
|
||||
26
package.json
26
package.json
@@ -4,23 +4,18 @@
|
||||
"version": "0.0.0",
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
"dev": "node aklive2d dev",
|
||||
"build": "node aklive2d build",
|
||||
"build-all": "node aklive2d build-all",
|
||||
"preview": "node aklive2d preview",
|
||||
"operator:dev": "node aklive2d operator:dev",
|
||||
"operator:build": "node aklive2d operator:build",
|
||||
"operator:build-all": "node aklive2d operator:build-all",
|
||||
"init": "node aklive2d init",
|
||||
"directory": "node aklive2d directory",
|
||||
"charwords:update": "node aklive2d charwords:update",
|
||||
"charwords:build": "node aklive2d charwords:build",
|
||||
"logo": "node aklive2d logo",
|
||||
"music": "node aklive2d music",
|
||||
"vite:dev": "vite",
|
||||
"vite:build": "vite build",
|
||||
"vite:preview": "vite preview",
|
||||
"vite:directory:dev": "vite dev",
|
||||
"vite:directory:build": "vite build",
|
||||
"vite:directory:preview": "vite preview",
|
||||
"offical_update": "node aklive2d offical_update"
|
||||
"directory:dev": "vite dev",
|
||||
"directory:build": "vite build",
|
||||
"directory:preview": "vite preview",
|
||||
"offical_update": "node aklive2d offical_update",
|
||||
"cf:upload": "node aklive2d cf:upload",
|
||||
"cf:download": "node aklive2d cf:download"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/react": "^18.3.3",
|
||||
@@ -37,7 +32,8 @@
|
||||
"stylelint": "^16.8.1",
|
||||
"stylelint-config-standard": "^36.0.1",
|
||||
"stylelint-config-standard-scss": "^13.1.0",
|
||||
"vite": "^5.3.5"
|
||||
"vite": "^5.3.5",
|
||||
"wrangler": "^3.71.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"@parcellab/react-use-umami": "^2.0.1",
|
||||
|
||||
697
pnpm-lock.yaml
generated
697
pnpm-lock.yaml
generated
File diff suppressed because it is too large
Load Diff
@@ -1,7 +1,7 @@
|
||||
/* eslint-disable no-undef */
|
||||
import path from 'path'
|
||||
import { fileURLToPath } from 'url'
|
||||
import { defineConfig, splitVendorChunkPlugin } from 'vite'
|
||||
import { defineConfig } from 'vite'
|
||||
import assert from 'assert'
|
||||
import react from '@vitejs/plugin-react-swc'
|
||||
import getConfig from './libs/config.js'
|
||||
@@ -18,7 +18,6 @@ class ViteRunner {
|
||||
#globalConfig = getConfig(this.#officalInfo)
|
||||
#mode
|
||||
#baseViteConfig = {
|
||||
plugins: [splitVendorChunkPlugin()],
|
||||
configFile: false,
|
||||
base: "",
|
||||
server: {
|
||||
@@ -32,22 +31,19 @@ class ViteRunner {
|
||||
get config() {
|
||||
let result;
|
||||
const temp = process.env.npm_lifecycle_event.split(':')
|
||||
this.#mode = temp[0] === "vite" ? temp[1] : process.argv[2]
|
||||
switch (this.#mode) {
|
||||
const runType = temp[0]
|
||||
this.#mode = temp[1]
|
||||
switch (runType) {
|
||||
case 'directory':
|
||||
result = {
|
||||
data: this.#directoryConfig,
|
||||
}
|
||||
const op = temp[2] || process.argv[3]
|
||||
if (op !== 'preview') {
|
||||
if (this.#mode !== 'preview') {
|
||||
rmdir(path.resolve(__projectRoot, this.#globalConfig.folder.release, "_directory"))
|
||||
rmdir(path.resolve(__projectRoot, this.#globalConfig.folder.release, "index.html"))
|
||||
}
|
||||
break
|
||||
case 'dev':
|
||||
case 'build':
|
||||
case 'build-all':
|
||||
case 'preview':
|
||||
case 'operator':
|
||||
result = {
|
||||
data: this.#operatorConfig,
|
||||
}
|
||||
@@ -143,12 +139,10 @@ class ViteRunner {
|
||||
}
|
||||
|
||||
get #directoryConfig() {
|
||||
if (process.env.npm_lifecycle_event === 'vite:directory:build') {
|
||||
if (process.env.npm_lifecycle_event === 'directory:build') {
|
||||
global.__config = this.#globalConfig
|
||||
}
|
||||
const directoryDir = path.resolve(__projectRoot, this.#globalConfig.folder.directory_src)
|
||||
this.#mode = process.argv[3]
|
||||
// const publicDir = path.resolve(__projectRoot, this.#globalConfig.folder.release)
|
||||
const assetsDir = '_directory'
|
||||
return {
|
||||
...this.#baseViteConfig,
|
||||
@@ -191,15 +185,18 @@ class ViteRunner {
|
||||
}
|
||||
|
||||
async function main() {
|
||||
if (process.env.npm_lifecycle_event.includes('vite')) {
|
||||
if (process.env.npm_lifecycle_event.includes('directory')) {
|
||||
const officalInfo = new OfficalInfo()
|
||||
global.__config = getConfig(officalInfo)
|
||||
const background = new Background()
|
||||
const OPERATOR_SOURCE_FOLDER = path.join(__projectRoot, __config.folder.operator)
|
||||
const OPERATOR_SOURCE_DATA_FOLDER = path.join(__projectRoot, __config.folder.operator_data)
|
||||
const OPERATOR_SHARE_FOLDER = path.join(OPERATOR_SOURCE_DATA_FOLDER, __config.folder.share)
|
||||
const background = new Background(OPERATOR_SHARE_FOLDER, OPERATOR_SOURCE_FOLDER)
|
||||
await background.process()
|
||||
const backgrounds = ['operator_bg.png', ...background.files]
|
||||
const { musicMapping } = (new Music()).copy()
|
||||
const { musicMapping } = (new Music()).copy(OPERATOR_SHARE_FOLDER)
|
||||
|
||||
directory({ backgrounds, musicMapping })
|
||||
directory(OPERATOR_SOURCE_DATA_FOLDER, { backgrounds, musicMapping })
|
||||
return
|
||||
}
|
||||
const runner = new ViteRunner()
|
||||
|
||||
Reference in New Issue
Block a user