forked from akanyan/STARTLINER
fix: also add post scripts
This commit is contained in:
11
CHANGELOG.md
11
CHANGELOG.md
@ -1,8 +1,13 @@
|
||||
## 0.20.0
|
||||
## 0.20.1
|
||||
|
||||
- Added user-customizable pre-launch scripts
|
||||
- Added japanese localization
|
||||
- Fixed the file editor not updating state properly
|
||||
- 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
|
||||
|
||||
|
@ -255,7 +255,7 @@ impl Profile {
|
||||
|
||||
let mut game_builder;
|
||||
let mut amd_builder;
|
||||
let mut prelaunch = None;
|
||||
let mut prescript = None;
|
||||
|
||||
let target_path = PathBuf::from(&self.data.sgt.target);
|
||||
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()));
|
||||
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")]
|
||||
{
|
||||
@ -284,14 +273,12 @@ impl Profile {
|
||||
|
||||
game_builder.arg(sgt_dir.join(self.meta.game.inject_exe()));
|
||||
amd_builder.arg("cmd.exe");
|
||||
}
|
||||
|
||||
let prelaunch_path = self.config_dir().join("prelaunch.sh");
|
||||
if prelaunch_path.exists() {
|
||||
prelaunch_builder = Some(Command::new("sh"));
|
||||
c.arg(prelaunch_path);
|
||||
log::debug!("Prelaunch: {:?}", c);
|
||||
prelaunch = Some(c.spawn()?);
|
||||
}
|
||||
let script_ext = if cfg!(target_os = "windows") { "bat" } else { "sh" };
|
||||
let prescript_path = self.config_dir().join(format!("pre.{script_ext}"));
|
||||
if prescript_path.exists() {
|
||||
prescript = util::spawn_script(prescript_path, &exe_dir, "\"STARTLINER launch script\"");
|
||||
}
|
||||
|
||||
amd_builder.env(
|
||||
@ -440,11 +427,11 @@ impl Profile {
|
||||
util::pkill("amdaemon.exe").await;
|
||||
}
|
||||
|
||||
if let Some(mut _child) = prelaunch {
|
||||
if let Some(mut _child) = prescript {
|
||||
#[cfg(target_os = "windows")]
|
||||
{
|
||||
// child.kill() doesn't work
|
||||
util::pkill_title("STARTLINER Prelaunch").await;
|
||||
util::pkill_title("STARTLINER launch script").await;
|
||||
}
|
||||
#[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");
|
||||
|
||||
log::debug!("Fin");
|
||||
|
@ -49,15 +49,17 @@ impl Profile {
|
||||
|
||||
{
|
||||
let sgt = &mut prf.data.sgt;
|
||||
sgt.target = PathBuf::new();
|
||||
if sgt.amfs.is_absolute() {
|
||||
sgt.amfs = PathBuf::new();
|
||||
}
|
||||
if sgt.option.is_absolute() {
|
||||
sgt.option = PathBuf::new();
|
||||
}
|
||||
if sgt.appdata.is_absolute() {
|
||||
sgt.appdata = PathBuf::new();
|
||||
if !is_diagnostic {
|
||||
sgt.target = PathBuf::new();
|
||||
if sgt.amfs.is_absolute() {
|
||||
sgt.amfs = PathBuf::new();
|
||||
}
|
||||
if sgt.option.is_absolute() {
|
||||
sgt.option = 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)?;
|
||||
|
||||
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",
|
||||
"productName": "STARTLINER",
|
||||
"version": "0.20.0",
|
||||
"version": "0.20.1",
|
||||
"identifier": "zip.patafour.startliner",
|
||||
"build": {
|
||||
"beforeDevCommand": "bun run dev",
|
||||
|
@ -12,8 +12,8 @@ invoke('get_changelog').then((s) => (changelog.value = s as string));
|
||||
|
||||
<template>
|
||||
<h1>About</h1>
|
||||
STARTLINER is a launcher, configuration tool and mod manager for
|
||||
O.N.G.E.K.I. and CHUNITHM.
|
||||
STARTLINER is a configuration tool, mod manager and start.bat automation
|
||||
engine for O.N.G.E.K.I. and CHUNITHM.
|
||||
<h1>Changelog</h1>
|
||||
<ScrollPanel style="height: 200px">
|
||||
<div class="markdown">
|
||||
|
@ -71,10 +71,12 @@ const recommendedTooltip = computed(() => {
|
||||
const installRecommended = () => {
|
||||
if (prf.current?.meta.game === 'ongeki') {
|
||||
pkgs.installFromKey('segatools-mu3hook');
|
||||
prf.current.data.sgt.hook = 'segatools-mu3hook';
|
||||
}
|
||||
if (prf.current?.meta.game === 'chunithm') {
|
||||
pkgs.installFromKey('segatools-chusanhook');
|
||||
pkgs.installFromKey('mempatcher-mempatcher');
|
||||
prf.current.data.sgt.hook = 'segatools-chusanhook';
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
@ -29,10 +29,17 @@ const files = new Set<string>();
|
||||
).includes('chunithm');
|
||||
})();
|
||||
|
||||
const fileList = {
|
||||
ongeki: ['aime.txt', 'inohara.cfg', 'mu3.ini', 'segatools-base.ini'],
|
||||
chunithm: ['aime.txt', 'saekawa.toml', 'segatools-base.ini'],
|
||||
};
|
||||
const fileList = [
|
||||
'aime.txt',
|
||||
'inohara.cfg',
|
||||
'saekawa.toml',
|
||||
'mu3.ini',
|
||||
'segatools-base.ini',
|
||||
'pre.sh',
|
||||
'pre.bat',
|
||||
'post.sh',
|
||||
'post.bat',
|
||||
];
|
||||
|
||||
const diagnosticList = {
|
||||
ongeki: ['mu3.ini', 'segatools-base.ini'],
|
||||
@ -62,8 +69,7 @@ const fileListCurrent: Ref<string[]> = ref([]);
|
||||
const recalcFileList = async () => {
|
||||
const res: string[] = [];
|
||||
files.clear();
|
||||
for (const idx in fileList[prf.current!.meta.game]) {
|
||||
const f = fileList[prf.current!.meta.game][idx];
|
||||
for (const f of fileList) {
|
||||
const p = await path.join(await prf.configDir, f);
|
||||
if (await invoke('file_exists', { path: p })) {
|
||||
res.push(f);
|
||||
|
@ -41,18 +41,33 @@ const prf = usePrfStore();
|
||||
<FileEditor filename="segatools-base.ini" />
|
||||
</OptionRow>
|
||||
<OptionRow
|
||||
:title="t('cfg.misc.prelaunch')"
|
||||
:tooltip="t('cfg.misc.prelaunchTooltip')"
|
||||
:title="t('cfg.misc.prescript')"
|
||||
:tooltip="t('cfg.misc.prescriptTooltip')"
|
||||
>
|
||||
<FileEditor
|
||||
v-if="extension === 'bat'"
|
||||
filename="prelaunch.bat"
|
||||
:defaultValue="`@echo off\n\nREM This script will be launched alongside the game\n`"
|
||||
filename="pre.bat"
|
||||
:defaultValue="`@echo off\n\nREM This script will launch before (and alongside) the game\n`"
|
||||
/>
|
||||
<FileEditor
|
||||
v-else-if="extension === 'sh'"
|
||||
filename="prelaunch.sh"
|
||||
:defaultValue="`#!/bin/sh\n\n# This script will be launched alongside the game\n`"
|
||||
filename="pre.sh"
|
||||
: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>
|
||||
</OptionCategory>
|
||||
|
@ -166,8 +166,11 @@ export default {
|
||||
other: 'Other segatools options',
|
||||
otherTooltip:
|
||||
'Advanced or situational options not covered by STARTLINER',
|
||||
prelaunch: 'Prelaunch script',
|
||||
prelaunchTooltip: 'Optional script that runs before the game.',
|
||||
prescript: 'Launch script',
|
||||
prescriptTooltip: 'Optional script that runs before the game.',
|
||||
postscript: 'End script',
|
||||
postscriptTooltip:
|
||||
'Optional script that runs after the game has ended.',
|
||||
},
|
||||
extensions: {
|
||||
title: 'Extensions',
|
||||
|
@ -144,7 +144,7 @@ export default {
|
||||
general: '一般',
|
||||
builtIn: 'segatools内蔵エミュレーション',
|
||||
targetTooltip:
|
||||
'STARTLINERはそれ以外のクリーンなデータに解凍された実行可能ファイルを期待する。',
|
||||
'STARTLINERはそれ以外のクリーンなデータにクラック実行可能ファイルを期待する。',
|
||||
hooks: 'フック',
|
||||
ioModules: 'IOモジュール',
|
||||
ioModulesDesc: 'これは望ましい入力方法と一致するはずです。',
|
||||
@ -206,8 +206,10 @@ export default {
|
||||
intelTooltip: '代わりにamdaemonにパッチを当てることを推奨する。',
|
||||
other: 'その他segatools設定',
|
||||
otherTooltip: 'STARTLINERに含まれない上級者向けまたは状況別設定',
|
||||
prelaunch: 'スタート前スクリプト',
|
||||
prelaunchTooltip: 'ゲームの前に実行されるスクリプト',
|
||||
prescript: '起動前のスクリプト',
|
||||
prescriptTooltip: 'ゲームの前に実行されるスクリプト',
|
||||
postscript: '終了後のスクリプト',
|
||||
postscriptTooltip: 'ゲーム終了後に実行されるスクリプト',
|
||||
},
|
||||
extensions: {
|
||||
title: 'エクステンション',
|
||||
|
@ -206,8 +206,11 @@ export default {
|
||||
other: 'Inne opcje segatools',
|
||||
otherTooltip:
|
||||
'Zaawansowane lub sytuacyjne opcje, które nie są objęte przez STARTLINERA',
|
||||
prelaunch: 'Skrypt przedstartowy',
|
||||
prelaunchTooltip: 'Opcjonalny skrypt uruchamiany przed grą.',
|
||||
prescript: 'Skrypt startowy',
|
||||
prescriptTooltip: 'Opcjonalny skrypt uruchamiany przed grą.',
|
||||
postscript: 'Skrypt końcowy',
|
||||
postscriptTooltip:
|
||||
'Opcjonalny skrypt uruchamiany po zakończeniu gry.',
|
||||
},
|
||||
extensions: {
|
||||
title: 'Rozszerzenia',
|
||||
|
Reference in New Issue
Block a user