Compare commits
5 Commits
Author | SHA1 | Date | |
---|---|---|---|
2304a78db4 | |||
81cf2cf413 | |||
45b06e4478 | |||
77f5b6cd5e | |||
67872bc4d1 |
17
CHANGELOG.md
17
CHANGELOG.md
@ -1,8 +1,17 @@
|
|||||||
## 0.20.0
|
## 0.21.0
|
||||||
|
|
||||||
- Added user-customizable pre-launch scripts
|
- Added simplified chinese localization (courtesy of Chilor)
|
||||||
- Added japanese localization
|
|
||||||
- Fixed the file editor not updating state properly
|
## 0.20.1
|
||||||
|
|
||||||
|
- Added japanese localization (courtesy of SALEC)
|
||||||
|
- Added user-customizable scripts
|
||||||
|
- The launch script runs directly before the game, and is equivalent to adding lines above `start "AM Daemon" ...` in start.bat
|
||||||
|
- The end script runs after the game has closed for any reason, and is equivalent to adding lines below `taskkill /f /im amdaemon.exe ...` in start.bat
|
||||||
|
- This functionality is needed for cursed things such as brokenithm
|
||||||
|
- Fixed the file editor not updating its state properly
|
||||||
|
- Fixed diagnostic exports not exporting paths
|
||||||
|
- Fixed "Install recommended packages" not enabling the segatools hook
|
||||||
|
|
||||||
## 0.19.1
|
## 0.19.1
|
||||||
|
|
||||||
|
@ -255,7 +255,7 @@ impl Profile {
|
|||||||
|
|
||||||
let mut game_builder;
|
let mut game_builder;
|
||||||
let mut amd_builder;
|
let mut amd_builder;
|
||||||
let mut prelaunch = None;
|
let mut prescript = None;
|
||||||
|
|
||||||
let target_path = PathBuf::from(&self.data.sgt.target);
|
let target_path = PathBuf::from(&self.data.sgt.target);
|
||||||
let exe_dir = target_path.parent().ok_or_else(|| anyhow!("Invalid target path"))?;
|
let exe_dir = target_path.parent().ok_or_else(|| anyhow!("Invalid target path"))?;
|
||||||
@ -265,17 +265,6 @@ impl Profile {
|
|||||||
{
|
{
|
||||||
game_builder = Command::new(sgt_dir.join(self.meta.game.inject_exe()));
|
game_builder = Command::new(sgt_dir.join(self.meta.game.inject_exe()));
|
||||||
amd_builder = Command::new("cmd.exe");
|
amd_builder = Command::new("cmd.exe");
|
||||||
|
|
||||||
let prelaunch_path = self.config_dir().join("prelaunch.bat");
|
|
||||||
if prelaunch_path.exists() {
|
|
||||||
let mut c = Command::new("cmd");
|
|
||||||
c.args(["/C", "start"]);
|
|
||||||
c.raw_arg("\"STARTLINER Prelaunch\"");
|
|
||||||
c.args(["cmd", "/C"]);
|
|
||||||
c.arg(prelaunch_path);
|
|
||||||
log::debug!("Prelaunch: {:?}", c);
|
|
||||||
prelaunch = Some(c.spawn()?);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
#[cfg(target_os = "linux")]
|
#[cfg(target_os = "linux")]
|
||||||
{
|
{
|
||||||
@ -284,14 +273,12 @@ impl Profile {
|
|||||||
|
|
||||||
game_builder.arg(sgt_dir.join(self.meta.game.inject_exe()));
|
game_builder.arg(sgt_dir.join(self.meta.game.inject_exe()));
|
||||||
amd_builder.arg("cmd.exe");
|
amd_builder.arg("cmd.exe");
|
||||||
|
}
|
||||||
|
|
||||||
let prelaunch_path = self.config_dir().join("prelaunch.sh");
|
let script_ext = if cfg!(target_os = "windows") { "bat" } else { "sh" };
|
||||||
if prelaunch_path.exists() {
|
let prescript_path = self.config_dir().join(format!("pre.{script_ext}"));
|
||||||
prelaunch_builder = Some(Command::new("sh"));
|
if prescript_path.exists() {
|
||||||
c.arg(prelaunch_path);
|
prescript = util::spawn_script(prescript_path, &exe_dir, "\"STARTLINER launch script\"");
|
||||||
log::debug!("Prelaunch: {:?}", c);
|
|
||||||
prelaunch = Some(c.spawn()?);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
amd_builder.env(
|
amd_builder.env(
|
||||||
@ -440,11 +427,11 @@ impl Profile {
|
|||||||
util::pkill("amdaemon.exe").await;
|
util::pkill("amdaemon.exe").await;
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(mut _child) = prelaunch {
|
if let Some(mut _child) = prescript {
|
||||||
#[cfg(target_os = "windows")]
|
#[cfg(target_os = "windows")]
|
||||||
{
|
{
|
||||||
// child.kill() doesn't work
|
// child.kill() doesn't work
|
||||||
util::pkill_title("STARTLINER Prelaunch").await;
|
util::pkill_title("STARTLINER launch script").await;
|
||||||
}
|
}
|
||||||
#[cfg(target_os = "linux")]
|
#[cfg(target_os = "linux")]
|
||||||
{
|
{
|
||||||
@ -452,6 +439,11 @@ impl Profile {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let postscript_path = self.config_dir().join(format!("post.{script_ext}"));
|
||||||
|
if postscript_path.exists() {
|
||||||
|
_ = util::spawn_script(postscript_path, &exe_dir, "\"STARTLINER end script\"");
|
||||||
|
}
|
||||||
|
|
||||||
set.join_next().await.expect("No spawn").expect("No result");
|
set.join_next().await.expect("No spawn").expect("No result");
|
||||||
|
|
||||||
log::debug!("Fin");
|
log::debug!("Fin");
|
||||||
|
@ -49,15 +49,17 @@ impl Profile {
|
|||||||
|
|
||||||
{
|
{
|
||||||
let sgt = &mut prf.data.sgt;
|
let sgt = &mut prf.data.sgt;
|
||||||
sgt.target = PathBuf::new();
|
if !is_diagnostic {
|
||||||
if sgt.amfs.is_absolute() {
|
sgt.target = PathBuf::new();
|
||||||
sgt.amfs = PathBuf::new();
|
if sgt.amfs.is_absolute() {
|
||||||
}
|
sgt.amfs = PathBuf::new();
|
||||||
if sgt.option.is_absolute() {
|
}
|
||||||
sgt.option = PathBuf::new();
|
if sgt.option.is_absolute() {
|
||||||
}
|
sgt.option = PathBuf::new();
|
||||||
if sgt.appdata.is_absolute() {
|
}
|
||||||
sgt.appdata = PathBuf::new();
|
if sgt.appdata.is_absolute() {
|
||||||
|
sgt.appdata = PathBuf::new();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -220,4 +220,38 @@ pub fn create_shortcut(
|
|||||||
file.Save(Some(lnk_path.to_str().ok_or_else(|| anyhow!("Illegal shortcut path"))?), true)?;
|
file.Save(Some(lnk_path.to_str().ok_or_else(|| anyhow!("Illegal shortcut path"))?), true)?;
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn spawn_script(path: impl AsRef<Path>, cwd: impl AsRef<Path>, title: &str) -> Option<tokio::process::Child> {
|
||||||
|
// Seems? like this autism is needed to:
|
||||||
|
// 1. pop up a cmd window
|
||||||
|
// 2. launch the batch
|
||||||
|
// 3. die afterwards
|
||||||
|
let mut c;
|
||||||
|
|
||||||
|
#[cfg(target_os = "windows")]
|
||||||
|
{
|
||||||
|
c = Command::new("cmd");
|
||||||
|
c.args(["/C", "start"]);
|
||||||
|
c.raw_arg(title);
|
||||||
|
c.args(["cmd", "/C"]);
|
||||||
|
c.arg(path.as_ref());
|
||||||
|
c.current_dir(cwd);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(target_os = "linux")]
|
||||||
|
{
|
||||||
|
c = Command::new("sh");
|
||||||
|
c.arg(path.as_ref());
|
||||||
|
c.current_dir(cwd);
|
||||||
|
}
|
||||||
|
|
||||||
|
log::debug!("Script launch: {:?}", c);
|
||||||
|
match c.spawn() {
|
||||||
|
Ok(child) => Some(child),
|
||||||
|
Err(e) => {
|
||||||
|
log::error!("unable to launch {:?}: {e}", path.as_ref());
|
||||||
|
None
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"$schema": "https://schema.tauri.app/config/2",
|
"$schema": "https://schema.tauri.app/config/2",
|
||||||
"productName": "STARTLINER",
|
"productName": "STARTLINER",
|
||||||
"version": "0.20.0",
|
"version": "0.21.0",
|
||||||
"identifier": "zip.patafour.startliner",
|
"identifier": "zip.patafour.startliner",
|
||||||
"build": {
|
"build": {
|
||||||
"beforeDevCommand": "bun run dev",
|
"beforeDevCommand": "bun run dev",
|
||||||
|
@ -12,8 +12,8 @@ invoke('get_changelog').then((s) => (changelog.value = s as string));
|
|||||||
|
|
||||||
<template>
|
<template>
|
||||||
<h1>About</h1>
|
<h1>About</h1>
|
||||||
STARTLINER is a launcher, configuration tool and mod manager for
|
STARTLINER is a configuration tool, mod manager and start.bat automation
|
||||||
O.N.G.E.K.I. and CHUNITHM.
|
engine for O.N.G.E.K.I. and CHUNITHM.
|
||||||
<h1>Changelog</h1>
|
<h1>Changelog</h1>
|
||||||
<ScrollPanel style="height: 200px">
|
<ScrollPanel style="height: 200px">
|
||||||
<div class="markdown">
|
<div class="markdown">
|
||||||
|
@ -71,10 +71,12 @@ const recommendedTooltip = computed(() => {
|
|||||||
const installRecommended = () => {
|
const installRecommended = () => {
|
||||||
if (prf.current?.meta.game === 'ongeki') {
|
if (prf.current?.meta.game === 'ongeki') {
|
||||||
pkgs.installFromKey('segatools-mu3hook');
|
pkgs.installFromKey('segatools-mu3hook');
|
||||||
|
prf.current.data.sgt.hook = 'segatools-mu3hook';
|
||||||
}
|
}
|
||||||
if (prf.current?.meta.game === 'chunithm') {
|
if (prf.current?.meta.game === 'chunithm') {
|
||||||
pkgs.installFromKey('segatools-chusanhook');
|
pkgs.installFromKey('segatools-chusanhook');
|
||||||
pkgs.installFromKey('mempatcher-mempatcher');
|
pkgs.installFromKey('mempatcher-mempatcher');
|
||||||
|
prf.current.data.sgt.hook = 'segatools-chusanhook';
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
|
@ -60,7 +60,7 @@ prf.reload();
|
|||||||
<AimeOptions />
|
<AimeOptions />
|
||||||
<MiscOptions />
|
<MiscOptions />
|
||||||
<OptionCategory
|
<OptionCategory
|
||||||
title="Extensions"
|
:title="t('cfg.extensions.title')"
|
||||||
v-if="prf.current?.meta.game === 'chunithm'"
|
v-if="prf.current?.meta.game === 'chunithm'"
|
||||||
>
|
>
|
||||||
<OptionRow :title="t('cfg.extensions.saekawa')">
|
<OptionRow :title="t('cfg.extensions.saekawa')">
|
||||||
|
@ -29,10 +29,17 @@ const files = new Set<string>();
|
|||||||
).includes('chunithm');
|
).includes('chunithm');
|
||||||
})();
|
})();
|
||||||
|
|
||||||
const fileList = {
|
const fileList = [
|
||||||
ongeki: ['aime.txt', 'inohara.cfg', 'mu3.ini', 'segatools-base.ini'],
|
'aime.txt',
|
||||||
chunithm: ['aime.txt', 'saekawa.toml', 'segatools-base.ini'],
|
'inohara.cfg',
|
||||||
};
|
'saekawa.toml',
|
||||||
|
'mu3.ini',
|
||||||
|
'segatools-base.ini',
|
||||||
|
'pre.sh',
|
||||||
|
'pre.bat',
|
||||||
|
'post.sh',
|
||||||
|
'post.bat',
|
||||||
|
];
|
||||||
|
|
||||||
const diagnosticList = {
|
const diagnosticList = {
|
||||||
ongeki: ['mu3.ini', 'segatools-base.ini'],
|
ongeki: ['mu3.ini', 'segatools-base.ini'],
|
||||||
@ -62,8 +69,7 @@ const fileListCurrent: Ref<string[]> = ref([]);
|
|||||||
const recalcFileList = async () => {
|
const recalcFileList = async () => {
|
||||||
const res: string[] = [];
|
const res: string[] = [];
|
||||||
files.clear();
|
files.clear();
|
||||||
for (const idx in fileList[prf.current!.meta.game]) {
|
for (const f of fileList) {
|
||||||
const f = fileList[prf.current!.meta.game][idx];
|
|
||||||
const p = await path.join(await prf.configDir, f);
|
const p = await path.join(await prf.configDir, f);
|
||||||
if (await invoke('file_exists', { path: p })) {
|
if (await invoke('file_exists', { path: p })) {
|
||||||
res.push(f);
|
res.push(f);
|
||||||
@ -211,6 +217,7 @@ const importPick = async () => {
|
|||||||
{ title: 'English', value: 'en' },
|
{ title: 'English', value: 'en' },
|
||||||
{ title: '日本語', value: 'ja' },
|
{ title: '日本語', value: 'ja' },
|
||||||
{ title: 'Polski', value: 'pl' },
|
{ title: 'Polski', value: 'pl' },
|
||||||
|
{ title: '简体中文', value: 'zh-Hans' },
|
||||||
]"
|
]"
|
||||||
size="small"
|
size="small"
|
||||||
option-label="title"
|
option-label="title"
|
||||||
|
@ -203,7 +203,7 @@ const tryStart = () => {
|
|||||||
v-tooltip="disabledTooltip"
|
v-tooltip="disabledTooltip"
|
||||||
:disabled="disabledTooltip !== null"
|
:disabled="disabledTooltip !== null"
|
||||||
icon="pi pi-play"
|
icon="pi pi-play"
|
||||||
label="START"
|
:label="t('start.button.start')"
|
||||||
aria-label="start"
|
aria-label="start"
|
||||||
size="small"
|
size="small"
|
||||||
class="m-2.5"
|
class="m-2.5"
|
||||||
|
@ -41,18 +41,33 @@ const prf = usePrfStore();
|
|||||||
<FileEditor filename="segatools-base.ini" />
|
<FileEditor filename="segatools-base.ini" />
|
||||||
</OptionRow>
|
</OptionRow>
|
||||||
<OptionRow
|
<OptionRow
|
||||||
:title="t('cfg.misc.prelaunch')"
|
:title="t('cfg.misc.prescript')"
|
||||||
:tooltip="t('cfg.misc.prelaunchTooltip')"
|
:tooltip="t('cfg.misc.prescriptTooltip')"
|
||||||
>
|
>
|
||||||
<FileEditor
|
<FileEditor
|
||||||
v-if="extension === 'bat'"
|
v-if="extension === 'bat'"
|
||||||
filename="prelaunch.bat"
|
filename="pre.bat"
|
||||||
:defaultValue="`@echo off\n\nREM This script will be launched alongside the game\n`"
|
:defaultValue="`@echo off\n\nREM This script will launch before (and alongside) the game\n`"
|
||||||
/>
|
/>
|
||||||
<FileEditor
|
<FileEditor
|
||||||
v-else-if="extension === 'sh'"
|
v-else-if="extension === 'sh'"
|
||||||
filename="prelaunch.sh"
|
filename="pre.sh"
|
||||||
:defaultValue="`#!/bin/sh\n\n# This script will be launched alongside the game\n`"
|
:defaultValue="`#!/bin/sh\n\n# This script will launch before (and alongside) the game\n`"
|
||||||
|
/>
|
||||||
|
</OptionRow>
|
||||||
|
<OptionRow
|
||||||
|
:title="t('cfg.misc.postscript')"
|
||||||
|
:tooltip="t('cfg.misc.postscriptTooltip')"
|
||||||
|
>
|
||||||
|
<FileEditor
|
||||||
|
v-if="extension === 'bat'"
|
||||||
|
filename="post.bat"
|
||||||
|
:defaultValue="`@echo off\n\nREM This script will launch after the game has died\n`"
|
||||||
|
/>
|
||||||
|
<FileEditor
|
||||||
|
v-else-if="extension === 'sh'"
|
||||||
|
filename="post.sh"
|
||||||
|
:defaultValue="`#!/bin/sh\n\n# This script will launch after the game has died\n`"
|
||||||
/>
|
/>
|
||||||
</OptionRow>
|
</OptionRow>
|
||||||
</OptionCategory>
|
</OptionCategory>
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
import en from './i18n/en';
|
import en from './i18n/en';
|
||||||
import { createI18n } from 'vue-i18n';
|
import { createI18n } from 'vue-i18n';
|
||||||
|
|
||||||
export type Locale = 'en' | 'ja' | 'pl';
|
export type Locale = 'en' | 'ja' | 'pl' | 'zh-Hans';
|
||||||
|
|
||||||
const loadLocaleMessages = async (locale: Locale) => {
|
const loadLocaleMessages = async (locale: Locale) => {
|
||||||
return (await import(`./i18n/${locale}.ts`)).default;
|
return (await import(`./i18n/${locale}.ts`)).default;
|
||||||
@ -13,7 +13,7 @@ const i18n = createI18n({
|
|||||||
fallbackLocale: 'en',
|
fallbackLocale: 'en',
|
||||||
warnHtmlInMessage: false,
|
warnHtmlInMessage: false,
|
||||||
warnHtmlMessage: false,
|
warnHtmlMessage: false,
|
||||||
messages: { en, ja: {}, pl: {} },
|
messages: { en, ja: {}, pl: {}, 'zh-Hans': {} },
|
||||||
});
|
});
|
||||||
|
|
||||||
const setLocale = async (locale: Locale) => {
|
const setLocale = async (locale: Locale) => {
|
||||||
|
@ -166,8 +166,11 @@ export default {
|
|||||||
other: 'Other segatools options',
|
other: 'Other segatools options',
|
||||||
otherTooltip:
|
otherTooltip:
|
||||||
'Advanced or situational options not covered by STARTLINER',
|
'Advanced or situational options not covered by STARTLINER',
|
||||||
prelaunch: 'Prelaunch script',
|
prescript: 'Launch script',
|
||||||
prelaunchTooltip: 'Optional script that runs before the game.',
|
prescriptTooltip: 'Optional script that runs before the game.',
|
||||||
|
postscript: 'End script',
|
||||||
|
postscriptTooltip:
|
||||||
|
'Optional script that runs after the game has ended.',
|
||||||
},
|
},
|
||||||
extensions: {
|
extensions: {
|
||||||
title: 'Extensions',
|
title: 'Extensions',
|
||||||
|
@ -144,7 +144,7 @@ export default {
|
|||||||
general: '一般',
|
general: '一般',
|
||||||
builtIn: 'segatools内蔵エミュレーション',
|
builtIn: 'segatools内蔵エミュレーション',
|
||||||
targetTooltip:
|
targetTooltip:
|
||||||
'STARTLINERはそれ以外のクリーンなデータに解凍された実行可能ファイルを期待する。',
|
'STARTLINERはそれ以外のクリーンなデータにクラック実行可能ファイルを期待する。',
|
||||||
hooks: 'フック',
|
hooks: 'フック',
|
||||||
ioModules: 'IOモジュール',
|
ioModules: 'IOモジュール',
|
||||||
ioModulesDesc: 'これは望ましい入力方法と一致するはずです。',
|
ioModulesDesc: 'これは望ましい入力方法と一致するはずです。',
|
||||||
@ -206,8 +206,10 @@ export default {
|
|||||||
intelTooltip: '代わりにamdaemonにパッチを当てることを推奨する。',
|
intelTooltip: '代わりにamdaemonにパッチを当てることを推奨する。',
|
||||||
other: 'その他segatools設定',
|
other: 'その他segatools設定',
|
||||||
otherTooltip: 'STARTLINERに含まれない上級者向けまたは状況別設定',
|
otherTooltip: 'STARTLINERに含まれない上級者向けまたは状況別設定',
|
||||||
prelaunch: 'スタート前スクリプト',
|
prescript: '起動前のスクリプト',
|
||||||
prelaunchTooltip: 'ゲームの前に実行されるスクリプト',
|
prescriptTooltip: 'ゲームの前に実行されるスクリプト',
|
||||||
|
postscript: '終了後のスクリプト',
|
||||||
|
postscriptTooltip: 'ゲーム終了後に実行されるスクリプト',
|
||||||
},
|
},
|
||||||
extensions: {
|
extensions: {
|
||||||
title: 'エクステンション',
|
title: 'エクステンション',
|
||||||
|
@ -206,8 +206,11 @@ export default {
|
|||||||
other: 'Inne opcje segatools',
|
other: 'Inne opcje segatools',
|
||||||
otherTooltip:
|
otherTooltip:
|
||||||
'Zaawansowane lub sytuacyjne opcje, które nie są objęte przez STARTLINERA',
|
'Zaawansowane lub sytuacyjne opcje, które nie są objęte przez STARTLINERA',
|
||||||
prelaunch: 'Skrypt przedstartowy',
|
prescript: 'Skrypt startowy',
|
||||||
prelaunchTooltip: 'Opcjonalny skrypt uruchamiany przed grą.',
|
prescriptTooltip: 'Opcjonalny skrypt uruchamiany przed grą.',
|
||||||
|
postscript: 'Skrypt końcowy',
|
||||||
|
postscriptTooltip:
|
||||||
|
'Opcjonalny skrypt uruchamiany po zakończeniu gry.',
|
||||||
},
|
},
|
||||||
extensions: {
|
extensions: {
|
||||||
title: 'Rozszerzenia',
|
title: 'Rozszerzenia',
|
||||||
|
256
src/i18n/zh-Hans.ts
Normal file
256
src/i18n/zh-Hans.ts
Normal file
@ -0,0 +1,256 @@
|
|||||||
|
export default {
|
||||||
|
ok: '确定',
|
||||||
|
cancel: '取消',
|
||||||
|
enable: '启用',
|
||||||
|
disable: '禁用',
|
||||||
|
default: '默认',
|
||||||
|
search: '搜索',
|
||||||
|
next: '下一个',
|
||||||
|
skip: '跳过',
|
||||||
|
close: '关闭',
|
||||||
|
by: '来自 {namespace}',
|
||||||
|
updateAll: '更新全部',
|
||||||
|
start: {
|
||||||
|
failed: '启动检查失败',
|
||||||
|
accept: '仍要运行',
|
||||||
|
error: {
|
||||||
|
package: 'Package缺失',
|
||||||
|
dependency: '依赖缺失',
|
||||||
|
tool: 'Tools缺失',
|
||||||
|
unknown: '未知错误',
|
||||||
|
},
|
||||||
|
tooltip: {
|
||||||
|
game: '需要指定游戏路径',
|
||||||
|
amfs: '需要指定amfs路径',
|
||||||
|
segatools: '需要segatools hook package',
|
||||||
|
},
|
||||||
|
button: {
|
||||||
|
start: '启动',
|
||||||
|
stop: '停止',
|
||||||
|
unchecked: '跳过检查并启动',
|
||||||
|
shortcut: '创建桌面快捷方式',
|
||||||
|
help: '帮助',
|
||||||
|
refresh: '重新应用MOD并启动',
|
||||||
|
cache: '清空MOD缓存',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
game: {
|
||||||
|
ongeki: '音击',
|
||||||
|
chunithm: '中二节奏',
|
||||||
|
},
|
||||||
|
profile: {
|
||||||
|
welcome: '欢迎来到STARTLINER! 创建一个配置文件以开始.',
|
||||||
|
create: '{game} 配置文件',
|
||||||
|
delete: '删除配置文件',
|
||||||
|
reallyDelete: '确定删除 {profile}?',
|
||||||
|
template: 'STARTLINER 模板',
|
||||||
|
importTemplate: '导入模板',
|
||||||
|
exportTemplate: '导出配置文件',
|
||||||
|
export: '导出',
|
||||||
|
standardExport: '模板',
|
||||||
|
diagnostic: '诊断',
|
||||||
|
},
|
||||||
|
creator: {
|
||||||
|
header: 'Package作者',
|
||||||
|
basic: '基本信息',
|
||||||
|
name: '名称',
|
||||||
|
description: '介绍',
|
||||||
|
website: '网站',
|
||||||
|
type: 'Package类型',
|
||||||
|
rainy: '标准',
|
||||||
|
segatools: 'Segatools',
|
||||||
|
native: '原生',
|
||||||
|
games: '游戏',
|
||||||
|
packageFormat: 'Package格式规范',
|
||||||
|
},
|
||||||
|
store: {
|
||||||
|
installRecommended: '安装推荐的Packages',
|
||||||
|
installed: '显示已安装',
|
||||||
|
deprecated: '显示已弃用',
|
||||||
|
nsfw: '显示NSFW',
|
||||||
|
incompatible: 'STARTLINER暂不支持此Package.',
|
||||||
|
|
||||||
|
includeCategories: '包含类别',
|
||||||
|
excludeCategories: '排除类别',
|
||||||
|
},
|
||||||
|
pkglist: {
|
||||||
|
missing: '缺失',
|
||||||
|
local: '本地Packages',
|
||||||
|
namespace: '按名称',
|
||||||
|
type: '按类型',
|
||||||
|
category: '按类别',
|
||||||
|
standard: '标准MOD',
|
||||||
|
native: '原生MOD',
|
||||||
|
segatools: 'Segatools',
|
||||||
|
unsupported: '不支持',
|
||||||
|
exclusions: '排除项:',
|
||||||
|
},
|
||||||
|
patch: {
|
||||||
|
loading: '加载中...',
|
||||||
|
noneFound:
|
||||||
|
"未找到兼容的Patch. 请确认你使用的是已解密且未经修补的文件.",
|
||||||
|
forceLoad: '强制加载',
|
||||||
|
// Example patch name override
|
||||||
|
// 'standard-no-encryption': 'No encryption',
|
||||||
|
// 'standard-no-encryption-tooltip': 'Will also disable TLS',
|
||||||
|
// It is also possible to add a tooltip where there normally is none
|
||||||
|
// 'standard-maximum-tracks-tooltip': 'The number of tracks per credit',
|
||||||
|
// For more info check https://gitea.tendokyu.moe/akanyan/STARTLINER/wiki/Translation-%26-Localization
|
||||||
|
},
|
||||||
|
cfg: {
|
||||||
|
afterRestart: '将在重新启动后应用',
|
||||||
|
hardware: '硬件',
|
||||||
|
segatools: {
|
||||||
|
general: '通用',
|
||||||
|
builtIn: 'Segatools内置模拟',
|
||||||
|
targetTooltip:
|
||||||
|
'STARTLINER希望将已解密的可执行文件放入其他干净的数据中.',
|
||||||
|
hooks: 'Hook',
|
||||||
|
ioModules: 'IO模块',
|
||||||
|
ioModulesDesc: '此处应符合您希望使用的输入方式.',
|
||||||
|
ioBuiltIn: 'Segatools内置(键盘)',
|
||||||
|
io4: '原生IO4',
|
||||||
|
installTooltip: '{thing} 可从Package Store下载.',
|
||||||
|
},
|
||||||
|
display: {
|
||||||
|
title: '显示',
|
||||||
|
resolution: '游戏分辨率',
|
||||||
|
primary: '主显示器',
|
||||||
|
target: '目标显示器',
|
||||||
|
mode: '模式',
|
||||||
|
rotation: '旋转',
|
||||||
|
refreshRate: '刷新率',
|
||||||
|
borderlessFullscreen: '无边框全屏',
|
||||||
|
borderlessFullscreenTooltip:
|
||||||
|
'将显示器的分辨率调整为游戏分辨率.',
|
||||||
|
dontSwitchPrimary: '跳过主显示器切换',
|
||||||
|
dontSwitchPrimaryTooltip:
|
||||||
|
'仅在更换到主显示器遇到问题时启用此选项,显示器必须具有匹配的刷新率.',
|
||||||
|
index: '显示器索引',
|
||||||
|
portrait: '纵向',
|
||||||
|
landscape: '横向',
|
||||||
|
flipped: '翻转',
|
||||||
|
window: '窗口化',
|
||||||
|
borderless: '无边框窗口化',
|
||||||
|
fullscreen: '全屏',
|
||||||
|
},
|
||||||
|
network: {
|
||||||
|
title: '网络',
|
||||||
|
type: '服务器类型',
|
||||||
|
remote: '在线',
|
||||||
|
localArtemis: '本地 (ARTEMiS)',
|
||||||
|
artemisPath: 'ARTEMiS路径',
|
||||||
|
address: '服务器地址',
|
||||||
|
keychip: '加密狗号 (Keychip)',
|
||||||
|
subnet: '子网 (Subnet)',
|
||||||
|
addrSuffix: '地址后缀 (Address suffix)',
|
||||||
|
},
|
||||||
|
aime: {
|
||||||
|
type: 'Aime读卡器类型',
|
||||||
|
modules: 'AimeIO',
|
||||||
|
code: 'Aime卡号',
|
||||||
|
codeTooltip:
|
||||||
|
'仅适用于Segatools内置模拟或第三方AimeIO',
|
||||||
|
aimedb: '对实体卡使用AiMeDB',
|
||||||
|
aimedbTooltip:
|
||||||
|
'实体卡需要使用AiMeDB来解析真实卡号,如果您想要获取卡片背面印刷的真实卡号,请启用此选项.',
|
||||||
|
serialPort: '读卡器端口',
|
||||||
|
serialPortTooltip: `端口号可在 设备和打印机 或 设备管理器 中查看
|
||||||
|
对于AIC Pico,应选择AIME Port.`,
|
||||||
|
serverName: '服务器名称',
|
||||||
|
},
|
||||||
|
misc: {
|
||||||
|
title: '杂项',
|
||||||
|
intel: '修复Intel 10代及以上CPU存在的OpenSSL问题',
|
||||||
|
intelTooltip: '推荐使用该选项来代替给amdaemon打补丁.',
|
||||||
|
other: '其他segatools选项',
|
||||||
|
otherTooltip:
|
||||||
|
'未被STARTLINER覆盖的高级选项',
|
||||||
|
prescript: '启动脚本',
|
||||||
|
prescriptTooltip: '在游戏启动前运行的脚本.',
|
||||||
|
postscript: '结束脚本',
|
||||||
|
postscriptTooltip:
|
||||||
|
'在游戏进程结束后运行的脚本.',
|
||||||
|
},
|
||||||
|
extensions: {
|
||||||
|
title: '扩展',
|
||||||
|
bepInExConsole: 'BepInEx控制台',
|
||||||
|
audioMode: '音频模式',
|
||||||
|
audioTooltip:
|
||||||
|
'独占双声道音频需要MOD: 7EVENDAYSHOLIDAYS-ExclusiveAudio',
|
||||||
|
audioShared: '共享',
|
||||||
|
audio6Ch: '独占六声道',
|
||||||
|
audio2Ch: '独占双声道',
|
||||||
|
sampleRate: '采样率',
|
||||||
|
blacklist: '歌曲ID黑名单',
|
||||||
|
blacklistTooltip:
|
||||||
|
'黑名单中的歌曲分数不会被保存和上传',
|
||||||
|
bonusTracks: '解锁Bonus Track',
|
||||||
|
bonusTracksTooltip:
|
||||||
|
'禁用此选项可帮助你整理歌曲列表',
|
||||||
|
saekawa: 'Saekawa配置文件',
|
||||||
|
inohara: 'Inohara配置文件',
|
||||||
|
},
|
||||||
|
keyboard: {
|
||||||
|
title: '键盘',
|
||||||
|
tooltip:
|
||||||
|
'仅适用于Segatools内置(键盘)或兼容的第三方IO(如mu3io.NET)',
|
||||||
|
leverMode: '摇杆模式',
|
||||||
|
mouse: '鼠标',
|
||||||
|
irTooltip:
|
||||||
|
'当使用键盘游玩时,请只绑定ir1;其余的请设置为未绑定',
|
||||||
|
},
|
||||||
|
wine: {
|
||||||
|
prefix: 'Wine前缀',
|
||||||
|
runtime: 'Wine运行时',
|
||||||
|
},
|
||||||
|
startliner: {
|
||||||
|
offlineMode: '离线模式',
|
||||||
|
offlineModeTooltip: '禁用Package Store.',
|
||||||
|
autoUpdate: '自动更新',
|
||||||
|
verbose: '详细日志',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
onboarding: {
|
||||||
|
or: '或',
|
||||||
|
backButton: '控制器背后的按钮',
|
||||||
|
standard: `
|
||||||
|
你可能会卡在这个界面:
|
||||||
|
|
||||||
|
{bigblack}Aグループの基準機から設定を取得{endbig}
|
||||||
|
|
||||||
|
在这种情况下, 你需要跳转到测试模式(Test), 在游戏设定中 {black}ゲーム設定{end} 将 "从机" {black}基準機に従う{end} 切换到 "基准机" {black}基準機{end}.
|
||||||
|
|
||||||
|
测试模式可通过 %TESTMENU% 进入.
|
||||||
|
`,
|
||||||
|
|
||||||
|
'ongeki-system-processing': `
|
||||||
|
你可能会在这个界面上停留一段时间. _这是正常的_. 这个游戏加载数据需要很长时间.
|
||||||
|
|
||||||
|
如果你安装了 <code>7EVENDAYSHOLIDAYS/LoadBoost</code>, 后续启动会变得更快.
|
||||||
|
`,
|
||||||
|
|
||||||
|
'ongeki-lever': `
|
||||||
|
你需要校准你的摇杆, 不然你会看到错误3301.
|
||||||
|
|
||||||
|
前往摇杆设定 ({black}レバー設定{end}), 将摇杆移动至两边, 然后按下"结束" ({black}終了{end}) 和 "保存" ({black}保存する{end}).
|
||||||
|
`,
|
||||||
|
|
||||||
|
'chunithm-server': `
|
||||||
|
如果你卡在这个界面, 请重启游戏.
|
||||||
|
|
||||||
|
如果问题依旧存在, {link}请检查你的网络配置{endlink}
|
||||||
|
`,
|
||||||
|
|
||||||
|
finale: `
|
||||||
|
您随时都可以通过右键点击START按钮重新回到这个页面.
|
||||||
|
|
||||||
|
附录:
|
||||||
|
|
||||||
|
- {segaguide}SEGAguide{endlink}
|
||||||
|
- {twotorial}two-torial{endlink}
|
||||||
|
|
||||||
|
## 玩得愉快
|
||||||
|
`,
|
||||||
|
},
|
||||||
|
};
|
Reference in New Issue
Block a user