Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions packages/webgal/public/game/config.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{
"gameName": "新的 WebGAL 游戏",
"gameKey": "7fe160a6",
"titleImage": "WebGAL_New_Enter_Image.webp",
"titleBgm": "s_Title.mp3",
"gameLogo": ["WebGalEnter.webp"],
"enableExtra": true
}
6 changes: 0 additions & 6 deletions packages/webgal/public/game/config.txt

This file was deleted.

2 changes: 1 addition & 1 deletion packages/webgal/src/Core/initializeScript.ts
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ export const initializeScript = (): void => {
// 获得 user Animation
getUserAnimation();
// 获取游戏信息
infoFetcher('./game/config.txt');
infoFetcher('./game/config.json');
// 获取start场景
const sceneUrl: string = assetSetter('start.txt', fileType.scene);
// 场景写入到运行时
Expand Down
112 changes: 60 additions & 52 deletions packages/webgal/src/Core/util/coreInitialFunction/infoFetcher.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,67 +2,75 @@ import { webgalStore } from '@/store/store';
import { setGlobalVar } from '@/store/userDataReducer';
import { setEnableAppreciationMode } from '@/store/GUIReducer';
import { Live2D, WebGAL } from '@/Core/WebGAL';
import { WebgalParser } from '@/Core/parser/sceneParser';
import { getStorageAsync, setStorage } from '@/Core/controller/storage/storageController';
import { initKey } from '@/Core/controller/storage/fastSaveLoad';
import { getFastSaveFromStorage, getSavesFromStorage } from '@/Core/controller/storage/savesController';
import { logger } from '@/Core/util/logger';
import axios from 'axios';

interface IWebgalConfig {
gameName?: string; // 游戏名称
gameKey?: string; // 游戏Key
gameLogo?: string[]; // 游戏Logo
titleImage?: string; // 标题图片
titleBgm?: string; // 标题背景音乐
description?: string; // 游戏描述
defaultLanguage?: string; // 默认语言
packageName?: string; // 包名
enableExtra?: boolean; // 启用鉴赏功能
enablePanic?: boolean; // 启用紧急回避
enableLegacyExpressionBlendMode?: boolean; // 启用旧版 Live2D 表情混合模式
}

/**
* 获取游戏信息
* @param url 游戏信息路径
*/
export const infoFetcher = (url: string) => {
export const infoFetcher = async (url: string) => {
const dispatch = webgalStore.dispatch;
axios.get(url).then(async (r) => {
let gameConfigRaw: string = r.data;
let gameConfig = WebgalParser.parseConfig(gameConfigRaw);
logger.info('获取到游戏信息', gameConfig);
// 先把 key 找到并设置了
const keyItem = gameConfig.find((e) => e.command === 'Game_key');
WebGAL.gameKey = (keyItem?.args?.[0] as string) ?? '';
initKey();
await getStorageAsync();
getFastSaveFromStorage();
getSavesFromStorage(0, 0);
// 按照游戏的配置开始设置对应的状态
gameConfig.forEach((e) => {
const { command, args } = e;
if (args.length > 0) {
if (args.length > 1) {
dispatch(
setGlobalVar({
key: command,
value: args.join('|'),
}),
);
} else {
let res: any = args[0].trim();
if (/^(true|false)$/g.test(args[0])) {
res = res === 'true';
} else if (/^[0-9]+\.?[0-9]+$/g.test(args[0])) {
res = Number(res);
}

dispatch(
setGlobalVar({
key: command,
value: res,
}),
);

if (command === 'Enable_Appreciation') {
dispatch(setEnableAppreciationMode(res));
}
if (command === 'Legacy_Expression_Blend_Mode') {
Live2D.legacyExpressionBlendMode = res === true;
}
}
}
});
// @ts-expect-error renderPromiseResolve is a global variable
window.renderPromiseResolve();
setStorage();
});
const resp = await axios.get(url);
const gameConfig: IWebgalConfig = resp.data;
logger.info('获取到游戏信息', gameConfig);
// 先把 key 找到并设置了
WebGAL.gameKey = gameConfig.gameKey ?? '';
initKey();
await getStorageAsync();
getFastSaveFromStorage();
getSavesFromStorage(0, 0);
// 将游戏配置写入为全局变量
for (const [key, value] of Object.entries(gameConfig)) {
if (value === undefined) continue;
if (typeof value === 'boolean' || typeof value === 'number' || typeof value === 'string') {
dispatch(
setGlobalVar({
key: key,
value: value,
}),
);
} else if (Array.isArray(value)) {
dispatch(
setGlobalVar({
key: key,
value: value.join('|'),
}),
);
} else {
dispatch(
setGlobalVar({
key: key,
value: String(value),
}),
);
}
Comment on lines +57 to +64

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

这个 else 代码块会将所有未明确处理的类型(例如, 对象)转换为字符串。如果将来配置中添加了嵌套对象, 它将被转换为 "[object Object]" 并存入全局变量, 这可能不是预期的行为。为了使代码更健壮, 建议对不支持的类型抛出错误或至少记录一个警告, 以防止意外行为。

}
// 配置游戏
if (gameConfig.enableExtra !== undefined) {
dispatch(setEnableAppreciationMode(gameConfig.enableExtra));
}
if (gameConfig.enableLegacyExpressionBlendMode !== undefined) {
Live2D.legacyExpressionBlendMode = gameConfig.enableLegacyExpressionBlendMode;
}
// @ts-expect-error renderPromiseResolve is a global variable
window.renderPromiseResolve();
setStorage();
};
14 changes: 7 additions & 7 deletions packages/webgal/src/hooks/useConfigData.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import { useEffect } from 'react';
import { useSelector } from 'react-redux';

const useConfigData = () => {
const _map = ['Title_img', 'Game_Logo', 'Title_bgm', 'Game_name', 'Game_key'];
const _map = ['titleImage', 'gameLogo', 'titleBgm', 'gameName', 'gameKey'];
const configData = useSelector((state: RootState) => state.userData.globalGameVar);
return useEffect(() => {
// configData发生变化
Expand All @@ -19,33 +19,33 @@ const useConfigData = () => {
}
const val = configData[i] as string;
switch (i) {
case 'Title_img': {
case 'titleImage': {
const titleUrl = assetSetter(val, fileType.background);
webgalStore.dispatch(setGuiAsset({ asset: 'titleBg', value: titleUrl }));
setEbg(titleUrl);
break;
}

case 'Game_Logo': {
case 'gameLogo': {
const logos = val.split('|');
const logoUrlList = logos.map((val) => assetSetter(val, fileType.background));
webgalStore.dispatch(setLogoImage(logoUrlList));
break;
}

case 'Title_bgm': {
case 'titleBgm': {
const bgmUrl = assetSetter(val, fileType.bgm);
webgalStore.dispatch(setGuiAsset({ asset: 'titleBgm', value: bgmUrl }));
break;
}

case 'Game_name': {
case 'gameName': {
WebGAL.gameName = val;
document.title = val;
break;
}

case 'Game_key': {
case 'gameKey': {
WebGAL.gameKey = val;
getStorage();
getFastSaveFromStorage();
Expand All @@ -55,6 +55,6 @@ const useConfigData = () => {
}
}
return () => {};
}, [configData.Game_Logo, configData.Game_key, configData.Game_name, configData.Title_bgm, configData.Title_img]);
}, [configData.gameLogo, configData.gameKey, configData.gameName, configData.titleBgm, configData.titleImage]);
};
export default useConfigData;