Compare commits
5 Commits
Author | SHA1 | Date | |
---|---|---|---|
469ba5f574 | |||
8f05a04350 | |||
4ddc54d528 | |||
c4d023ed43 | |||
9b86af282e |
15
CHANGELOG.md
15
CHANGELOG.md
@ -1,3 +1,18 @@
|
|||||||
|
## 0.20.0
|
||||||
|
|
||||||
|
- Added user-customizable pre-launch scripts
|
||||||
|
- Added japanese localization
|
||||||
|
- Fixed the file editor not updating state properly
|
||||||
|
|
||||||
|
## 0.19.1
|
||||||
|
|
||||||
|
- Fixed the update button enabling the package
|
||||||
|
- Fixed deep URLs with rainycolor.org
|
||||||
|
|
||||||
|
## 0.19.0
|
||||||
|
|
||||||
|
- Added diagnostic exports
|
||||||
|
|
||||||
## 0.18.3
|
## 0.18.3
|
||||||
|
|
||||||
- Updated Rainycolor's domain・真
|
- Updated Rainycolor's domain・真
|
||||||
|
@ -125,12 +125,13 @@ pub async fn kill() -> Result<(), String> {
|
|||||||
pub async fn install_package(
|
pub async fn install_package(
|
||||||
state: State<'_, tokio::sync::Mutex<AppData>>,
|
state: State<'_, tokio::sync::Mutex<AppData>>,
|
||||||
key: PkgKey,
|
key: PkgKey,
|
||||||
force: bool
|
force: bool,
|
||||||
|
enable: bool
|
||||||
) -> Result<InstallResult, String> {
|
) -> Result<InstallResult, String> {
|
||||||
log::debug!("invoke: install_package({})", key);
|
log::debug!("invoke: install_package({})", key);
|
||||||
|
|
||||||
let mut appd = state.lock().await;
|
let mut appd = state.lock().await;
|
||||||
appd.pkgs.install_package(&key, force, true)
|
appd.pkgs.install_package(&key, force, true, enable)
|
||||||
.await
|
.await
|
||||||
.map_err(|e| e.to_string())
|
.map_err(|e| e.to_string())
|
||||||
}
|
}
|
||||||
@ -532,14 +533,14 @@ pub async fn clear_cache(state: State<'_, Mutex<AppData>>) -> Result<(), String>
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[tauri::command]
|
#[tauri::command]
|
||||||
pub async fn list_platform_capabilities() -> Result<Vec<String>, ()> {
|
pub fn list_platform_capabilities() -> Result<Vec<String>, ()> {
|
||||||
log::debug!("invoke: list_platform_capabilities");
|
log::debug!("invoke: list_platform_capabilities");
|
||||||
|
|
||||||
#[cfg(target_os = "windows")]
|
#[cfg(target_os = "windows")]
|
||||||
return Ok(vec!["display".to_owned(), "shortcut".to_owned(), "chunithm".to_owned()]);
|
return Ok(vec!["display".to_owned(), "shortcut".to_owned(), "chunithm".to_owned(), "preload-bat".to_owned()]);
|
||||||
|
|
||||||
#[cfg(target_os = "linux")]
|
#[cfg(target_os = "linux")]
|
||||||
return Ok(vec!["wine".to_owned()]);
|
return Ok(vec!["wine".to_owned(), "preload-sh".to_owned()]);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[tauri::command]
|
#[tauri::command]
|
||||||
|
@ -17,6 +17,12 @@ pub struct DownloadTick {
|
|||||||
ratio: f32,
|
ratio: f32,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Serialize, Deserialize, Clone, Debug)]
|
||||||
|
pub struct DownloadEndPayload {
|
||||||
|
pub key: PkgKey,
|
||||||
|
pub enable: bool
|
||||||
|
}
|
||||||
|
|
||||||
impl DownloadHandler {
|
impl DownloadHandler {
|
||||||
pub fn new(app: AppHandle) -> DownloadHandler {
|
pub fn new(app: AppHandle) -> DownloadHandler {
|
||||||
DownloadHandler {
|
DownloadHandler {
|
||||||
@ -25,7 +31,7 @@ impl DownloadHandler {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn download_zip(&mut self, zip_path: &PathBuf, pkg: &Package) -> Result<()> {
|
pub fn download_zip(&mut self, zip_path: &PathBuf, pkg: &Package, enable: bool) -> Result<()> {
|
||||||
let rmt = pkg.rmt.as_ref()
|
let rmt = pkg.rmt.as_ref()
|
||||||
.ok_or_else(|| anyhow!("Attempted to download a package without remote data"))?
|
.ok_or_else(|| anyhow!("Attempted to download a package without remote data"))?
|
||||||
.clone();
|
.clone();
|
||||||
@ -34,12 +40,18 @@ impl DownloadHandler {
|
|||||||
} else {
|
} else {
|
||||||
// TODO clear cache button should clear this
|
// TODO clear cache button should clear this
|
||||||
self.paths.insert(zip_path.clone());
|
self.paths.insert(zip_path.clone());
|
||||||
tauri::async_runtime::spawn(Self::download_zip_proc(self.app.clone(), zip_path.clone(), pkg.key(), rmt));
|
tauri::async_runtime::spawn(Self::download_zip_proc(self.app.clone(), zip_path.clone(), pkg.key(), rmt, enable));
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn download_zip_proc(app: AppHandle, zip_path: PathBuf, pkg_key: PkgKey, rmt: Remote) -> Result<()> {
|
async fn download_zip_proc(
|
||||||
|
app: AppHandle,
|
||||||
|
zip_path: PathBuf,
|
||||||
|
pkg_key: PkgKey,
|
||||||
|
rmt: Remote,
|
||||||
|
enable: bool
|
||||||
|
) -> Result<()> {
|
||||||
use futures::StreamExt;
|
use futures::StreamExt;
|
||||||
use tokio::io::AsyncWriteExt;
|
use tokio::io::AsyncWriteExt;
|
||||||
|
|
||||||
@ -66,7 +78,10 @@ impl DownloadHandler {
|
|||||||
|
|
||||||
log::debug!("downloaded to {:?}", zip_path);
|
log::debug!("downloaded to {:?}", zip_path);
|
||||||
|
|
||||||
app.emit("download-end", pkg_key)?;
|
app.emit("download-end", DownloadEndPayload {
|
||||||
|
key: pkg_key,
|
||||||
|
enable
|
||||||
|
})?;
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
@ -102,16 +102,23 @@ pub async fn run(_args: Vec<String>) {
|
|||||||
});
|
});
|
||||||
|
|
||||||
app.listen("download-end", closure!(clone apph, |ev| {
|
app.listen("download-end", closure!(clone apph, |ev| {
|
||||||
let raw = ev.payload();
|
let payload = serde_json::from_str::<download_handler::DownloadEndPayload>(ev.payload());
|
||||||
log::debug!("download-end triggered: {}", raw);
|
match payload {
|
||||||
let key = PkgKey(raw[1..raw.len()-1].to_owned());
|
Ok(payload) => {
|
||||||
let apph = apph.clone();
|
log::debug!("download-end triggered: {:?}", payload);
|
||||||
tauri::async_runtime::spawn(async move {
|
let key = payload.key;
|
||||||
let mutex = apph.state::<Mutex<AppData>>();
|
let apph = apph.clone();
|
||||||
let mut appd = mutex.lock().await;
|
tauri::async_runtime::spawn(async move {
|
||||||
let res = appd.pkgs.install_package(&key, true, false).await;
|
let mutex = apph.state::<Mutex<AppData>>();
|
||||||
log::debug!("download-end install {:?}", res);
|
let mut appd = mutex.lock().await;
|
||||||
});
|
let res = appd.pkgs.install_package(&key, true, false, payload.enable).await;
|
||||||
|
log::debug!("download-end install {:?}", res);
|
||||||
|
});
|
||||||
|
},
|
||||||
|
Err(err) => {
|
||||||
|
log::error!("invalid download payload: {err}");
|
||||||
|
}
|
||||||
|
}
|
||||||
}));
|
}));
|
||||||
|
|
||||||
app.listen("launch-end", closure!(clone apph, |_| {
|
app.listen("launch-end", closure!(clone apph, |_| {
|
||||||
@ -134,11 +141,13 @@ pub async fn run(_args: Vec<String>) {
|
|||||||
tauri::async_runtime::spawn(async move {
|
tauri::async_runtime::spawn(async move {
|
||||||
let mutex = apph.state::<Mutex<AppData>>();
|
let mutex = apph.state::<Mutex<AppData>>();
|
||||||
let mut appd = mutex.lock().await;
|
let mut appd = mutex.lock().await;
|
||||||
let res = appd.toggle_package(payload.pkg.clone(), ToggleAction::EnableSelf);
|
if payload.enable == true {
|
||||||
log::debug!(
|
let res = appd.toggle_package(payload.pkg.clone(), ToggleAction::EnableSelf);
|
||||||
"install-end-prelude toggle {:?}",
|
log::debug!(
|
||||||
res
|
"install-end-prelude toggle {:?}",
|
||||||
);
|
res
|
||||||
|
);
|
||||||
|
}
|
||||||
use tauri::Emitter;
|
use tauri::Emitter;
|
||||||
let res = apph.emit("install-end", payload);
|
let res = apph.emit("install-end", payload);
|
||||||
log::debug!("install-end {:?}", res);
|
log::debug!("install-end {:?}", res);
|
||||||
@ -261,7 +270,7 @@ fn deep_link(app: AppHandle, args: Vec<String>) {
|
|||||||
log::info!("deep link: {}", url);
|
log::info!("deep link: {}", url);
|
||||||
|
|
||||||
let regex = regex::Regex::new(
|
let regex = regex::Regex::new(
|
||||||
r"rainycolor://v1/install/rainy\.patafour\.zip/([^/]+)/([^/]+)/[0-9]+\.[0-9]+\.[0-9]+/"
|
r"rainycolor://v1/install/www\.rainycolor\.org/([^/]+)/([^/]+)/[0-9]+\.[0-9]+\.[0-9]+/"
|
||||||
).expect("Invalid regex");
|
).expect("Invalid regex");
|
||||||
|
|
||||||
if let Some(caps) = regex.captures(url) {
|
if let Some(caps) = regex.captures(url) {
|
||||||
@ -273,11 +282,13 @@ fn deep_link(app: AppHandle, args: Vec<String>) {
|
|||||||
let mut appd = mutex.lock().await;
|
let mut appd = mutex.lock().await;
|
||||||
if appd.pkgs.is_offline() {
|
if appd.pkgs.is_offline() {
|
||||||
log::warn!("Deep link installation failed: offline");
|
log::warn!("Deep link installation failed: offline");
|
||||||
} else if let Err(e) = appd.pkgs.install_package(&key, true, true).await {
|
} else if let Err(e) = appd.pkgs.install_package(&key, true, true, true).await {
|
||||||
log::warn!("Deep link installation failed: {}", e.to_string());
|
log::warn!("Deep link installation failed: {}", e.to_string());
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
log::error!("No caps");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -23,7 +23,8 @@ pub struct PackageStore {
|
|||||||
|
|
||||||
#[derive(Clone, Serialize, Deserialize, Debug)]
|
#[derive(Clone, Serialize, Deserialize, Debug)]
|
||||||
pub struct Payload {
|
pub struct Payload {
|
||||||
pub pkg: PkgKey
|
pub pkg: PkgKey,
|
||||||
|
pub enable: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Copy, Serialize, Deserialize, Debug)]
|
#[derive(Clone, Copy, Serialize, Deserialize, Debug)]
|
||||||
@ -180,7 +181,13 @@ impl PackageStore {
|
|||||||
self.offline = false;
|
self.offline = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn install_package(&mut self, key: &PkgKey, force: bool, install_deps: bool) -> Result<InstallResult> {
|
pub async fn install_package(
|
||||||
|
&mut self,
|
||||||
|
key: &PkgKey,
|
||||||
|
force: bool,
|
||||||
|
install_deps: bool,
|
||||||
|
enable: bool
|
||||||
|
) -> Result<InstallResult> {
|
||||||
log::info!("installation request: {}/{}/{}", key, force, install_deps);
|
log::info!("installation request: {}/{}/{}", key, force, install_deps);
|
||||||
|
|
||||||
let pkg = self.store.get(key)
|
let pkg = self.store.get(key)
|
||||||
@ -193,7 +200,8 @@ impl PackageStore {
|
|||||||
}
|
}
|
||||||
|
|
||||||
self.app.emit("install-start", Payload {
|
self.app.emit("install-start", Payload {
|
||||||
pkg: key.to_owned()
|
pkg: key.to_owned(),
|
||||||
|
enable
|
||||||
})?;
|
})?;
|
||||||
|
|
||||||
let rmt = pkg.rmt.as_ref()
|
let rmt = pkg.rmt.as_ref()
|
||||||
@ -203,7 +211,7 @@ impl PackageStore {
|
|||||||
let mut set = HashSet::new();
|
let mut set = HashSet::new();
|
||||||
self.resolve_deps(rmt.clone(), &mut set)?;
|
self.resolve_deps(rmt.clone(), &mut set)?;
|
||||||
for dep in set {
|
for dep in set {
|
||||||
Box::pin(self.install_package(&dep, false, false)).await?;
|
Box::pin(self.install_package(&dep, false, false, enable)).await?;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -214,7 +222,7 @@ impl PackageStore {
|
|||||||
let part_path = zip_path.join(".part");
|
let part_path = zip_path.join(".part");
|
||||||
|
|
||||||
if !zip_path.exists() && !part_path.exists() {
|
if !zip_path.exists() && !part_path.exists() {
|
||||||
self.dlh.download_zip(&zip_path, &pkg)?;
|
self.dlh.download_zip(&zip_path, &pkg, enable)?;
|
||||||
log::debug!("deferring {}", key);
|
log::debug!("deferring {}", key);
|
||||||
return Ok(InstallResult::Deferred);
|
return Ok(InstallResult::Deferred);
|
||||||
}
|
}
|
||||||
@ -230,7 +238,8 @@ impl PackageStore {
|
|||||||
self.reload_package(key.to_owned()).await;
|
self.reload_package(key.to_owned()).await;
|
||||||
|
|
||||||
self.app.emit("install-end-prelude", Payload {
|
self.app.emit("install-end-prelude", Payload {
|
||||||
pkg: key.to_owned()
|
pkg: key.to_owned(),
|
||||||
|
enable
|
||||||
})?;
|
})?;
|
||||||
|
|
||||||
log::info!("installed {}", key);
|
log::info!("installed {}", key);
|
||||||
@ -252,7 +261,8 @@ impl PackageStore {
|
|||||||
|
|
||||||
if rv.is_ok() {
|
if rv.is_ok() {
|
||||||
self.app.emit("install-end-prelude", Payload {
|
self.app.emit("install-end-prelude", Payload {
|
||||||
pkg: key.to_owned()
|
pkg: key.to_owned(),
|
||||||
|
enable: false
|
||||||
})?;
|
})?;
|
||||||
log::info!("deleted {}", key);
|
log::info!("deleted {}", key);
|
||||||
}
|
}
|
||||||
|
@ -255,6 +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 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"))?;
|
||||||
@ -264,6 +265,17 @@ 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")]
|
||||||
{
|
{
|
||||||
@ -272,6 +284,14 @@ 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");
|
||||||
|
if prelaunch_path.exists() {
|
||||||
|
prelaunch_builder = Some(Command::new("sh"));
|
||||||
|
c.arg(prelaunch_path);
|
||||||
|
log::debug!("Prelaunch: {:?}", c);
|
||||||
|
prelaunch = Some(c.spawn()?);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
amd_builder.env(
|
amd_builder.env(
|
||||||
@ -420,6 +440,18 @@ impl Profile {
|
|||||||
util::pkill("amdaemon.exe").await;
|
util::pkill("amdaemon.exe").await;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if let Some(mut _child) = prelaunch {
|
||||||
|
#[cfg(target_os = "windows")]
|
||||||
|
{
|
||||||
|
// child.kill() doesn't work
|
||||||
|
util::pkill_title("STARTLINER Prelaunch").await;
|
||||||
|
}
|
||||||
|
#[cfg(target_os = "linux")]
|
||||||
|
{
|
||||||
|
_child.start_kill()?;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
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");
|
||||||
|
@ -105,6 +105,12 @@ pub async fn pkill(process_name: &str) {
|
|||||||
.creation_flags(CREATE_NO_WINDOW).output().await;
|
.creation_flags(CREATE_NO_WINDOW).output().await;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(target_os = "windows")]
|
||||||
|
pub async fn pkill_title(window_title: &str) {
|
||||||
|
_ = Command::new("taskkill.exe").arg("/fi").raw_arg(format!("\"WindowTitle eq {window_title}\""))
|
||||||
|
.creation_flags(CREATE_NO_WINDOW).output().await;
|
||||||
|
}
|
||||||
|
|
||||||
#[cfg(target_os = "linux")]
|
#[cfg(target_os = "linux")]
|
||||||
pub async fn pkill(process_name: &str) {
|
pub async fn pkill(process_name: &str) {
|
||||||
_ = Command::new("pkill").arg(process_name)
|
_ = Command::new("pkill").arg(process_name)
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"$schema": "https://schema.tauri.app/config/2",
|
"$schema": "https://schema.tauri.app/config/2",
|
||||||
"productName": "STARTLINER",
|
"productName": "STARTLINER",
|
||||||
"version": "0.19.0",
|
"version": "0.20.0",
|
||||||
"identifier": "zip.patafour.startliner",
|
"identifier": "zip.patafour.startliner",
|
||||||
"build": {
|
"build": {
|
||||||
"beforeDevCommand": "bun run dev",
|
"beforeDevCommand": "bun run dev",
|
||||||
|
@ -295,7 +295,7 @@ listen<DownloadingStatus>('download-progress', (event) => {
|
|||||||
pkg.hasAvailableUpdates
|
pkg.hasAvailableUpdates
|
||||||
"
|
"
|
||||||
icon="pi pi-download"
|
icon="pi pi-download"
|
||||||
label="UPDATE ALL"
|
:label="t('updateAll')"
|
||||||
size="small"
|
size="small"
|
||||||
class="mr-4 m-2.5"
|
class="mr-4 m-2.5"
|
||||||
@click="pkg.updateAll()"
|
@click="pkg.updateAll()"
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { ref } from 'vue';
|
import { onMounted, ref } from 'vue';
|
||||||
import Button from 'primevue/button';
|
import Button from 'primevue/button';
|
||||||
import * as path from '@tauri-apps/api/path';
|
import * as path from '@tauri-apps/api/path';
|
||||||
import { open } from '@tauri-apps/plugin-dialog';
|
import { open } from '@tauri-apps/plugin-dialog';
|
||||||
@ -12,6 +12,7 @@ const props = defineProps({
|
|||||||
filename: String,
|
filename: String,
|
||||||
promptname: String,
|
promptname: String,
|
||||||
extension: String,
|
extension: String,
|
||||||
|
defaultValue: String,
|
||||||
});
|
});
|
||||||
|
|
||||||
const exists = ref(false);
|
const exists = ref(false);
|
||||||
@ -35,6 +36,12 @@ const save = async () => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const filePick = async () => {
|
const filePick = async () => {
|
||||||
|
if (props.defaultValue !== undefined) {
|
||||||
|
contents.value = props.defaultValue;
|
||||||
|
exists.value = true;
|
||||||
|
await save();
|
||||||
|
return;
|
||||||
|
}
|
||||||
const p = await open({
|
const p = await open({
|
||||||
multiple: false,
|
multiple: false,
|
||||||
directory: false,
|
directory: false,
|
||||||
@ -54,13 +61,13 @@ const filePick = async () => {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
(async () => {
|
onMounted(async () => {
|
||||||
if (props.filename === undefined) {
|
if (props.filename === undefined) {
|
||||||
throw new Error('FileEditor without a filename');
|
throw new Error('FileEditor without a filename');
|
||||||
}
|
}
|
||||||
target_path.value = await path.join(await prf.configDir, props.filename);
|
target_path.value = await path.join(await prf.configDir, props.filename);
|
||||||
await load(target_path.value);
|
await load(target_path.value);
|
||||||
})();
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
|
@ -53,6 +53,6 @@ const remove = async () => {
|
|||||||
class="self-center ml-4"
|
class="self-center ml-4"
|
||||||
style="width: 2rem; height: 2rem"
|
style="width: 2rem; height: 2rem"
|
||||||
:loading="pkg?.js.downloading"
|
:loading="pkg?.js.downloading"
|
||||||
v-on:click="async () => await pkgs.install(pkg)"
|
v-on:click="async () => await pkgs.install(pkg, true)"
|
||||||
/>
|
/>
|
||||||
</template>
|
</template>
|
||||||
|
@ -209,7 +209,7 @@ const importPick = async () => {
|
|||||||
style="width: 200px"
|
style="width: 200px"
|
||||||
:options="[
|
:options="[
|
||||||
{ title: 'English', value: 'en' },
|
{ title: 'English', value: 'en' },
|
||||||
// { title: '日本語', value: 'ja' },
|
{ title: '日本語', value: 'ja' },
|
||||||
{ title: 'Polski', value: 'pl' },
|
{ title: 'Polski', value: 'pl' },
|
||||||
]"
|
]"
|
||||||
size="small"
|
size="small"
|
||||||
|
@ -17,6 +17,7 @@ const install = async () => {
|
|||||||
await invoke('install_package', {
|
await invoke('install_package', {
|
||||||
key: pkgKey(props.pkg),
|
key: pkgKey(props.pkg),
|
||||||
force: true,
|
force: true,
|
||||||
|
enable: false,
|
||||||
});
|
});
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
if (props.pkg !== undefined) {
|
if (props.pkg !== undefined) {
|
||||||
|
@ -1,13 +1,27 @@
|
|||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
|
import { ref } from 'vue';
|
||||||
import ToggleSwitch from 'primevue/toggleswitch';
|
import ToggleSwitch from 'primevue/toggleswitch';
|
||||||
import FileEditor from '../FileEditor.vue';
|
import FileEditor from '../FileEditor.vue';
|
||||||
import OptionCategory from '../OptionCategory.vue';
|
import OptionCategory from '../OptionCategory.vue';
|
||||||
import OptionRow from '../OptionRow.vue';
|
import OptionRow from '../OptionRow.vue';
|
||||||
|
import { invoke } from '../../invoke';
|
||||||
import { usePrfStore } from '../../stores';
|
import { usePrfStore } from '../../stores';
|
||||||
import { useI18n } from 'vue-i18n';
|
import { useI18n } from 'vue-i18n';
|
||||||
|
|
||||||
const { t } = useI18n();
|
const { t } = useI18n();
|
||||||
|
|
||||||
|
const extension = ref('');
|
||||||
|
|
||||||
|
invoke('list_platform_capabilities').then(async (v: unknown) => {
|
||||||
|
if (Array.isArray(v)) {
|
||||||
|
if (v.includes('preload-sh')) {
|
||||||
|
extension.value = 'sh';
|
||||||
|
} else if (v.includes('preload-bat')) {
|
||||||
|
extension.value = 'bat';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
const prf = usePrfStore();
|
const prf = usePrfStore();
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
@ -26,5 +40,20 @@ const prf = usePrfStore();
|
|||||||
<!-- <Button icon="pi pi-refresh" size="small" /> -->
|
<!-- <Button icon="pi pi-refresh" size="small" /> -->
|
||||||
<FileEditor filename="segatools-base.ini" />
|
<FileEditor filename="segatools-base.ini" />
|
||||||
</OptionRow>
|
</OptionRow>
|
||||||
|
<OptionRow
|
||||||
|
:title="t('cfg.misc.prelaunch')"
|
||||||
|
:tooltip="t('cfg.misc.prelaunchTooltip')"
|
||||||
|
>
|
||||||
|
<FileEditor
|
||||||
|
v-if="extension === 'bat'"
|
||||||
|
filename="prelaunch.bat"
|
||||||
|
:defaultValue="`@echo off\n\nREM This script will be launched 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`"
|
||||||
|
/>
|
||||||
|
</OptionRow>
|
||||||
</OptionCategory>
|
</OptionCategory>
|
||||||
</template>
|
</template>
|
||||||
|
@ -9,6 +9,7 @@ export default {
|
|||||||
skip: 'Skip',
|
skip: 'Skip',
|
||||||
close: 'Close',
|
close: 'Close',
|
||||||
by: 'by {namespace}',
|
by: 'by {namespace}',
|
||||||
|
updateAll: 'UPDATE ALL',
|
||||||
start: {
|
start: {
|
||||||
failed: 'Start check failed',
|
failed: 'Start check failed',
|
||||||
accept: 'Run anyway',
|
accept: 'Run anyway',
|
||||||
@ -165,6 +166,8 @@ 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',
|
||||||
|
prelaunchTooltip: 'Optional script that runs before the game.',
|
||||||
},
|
},
|
||||||
extensions: {
|
extensions: {
|
||||||
title: 'Extensions',
|
title: 'Extensions',
|
||||||
|
279
src/i18n/ja.ts
279
src/i18n/ja.ts
@ -1,14 +1,293 @@
|
|||||||
export default {
|
export default {
|
||||||
|
ok: 'OK',
|
||||||
|
cancel: 'キャンセル',
|
||||||
|
enable: '有効にする',
|
||||||
|
disable: '無効にする',
|
||||||
|
default: 'デフォルト',
|
||||||
|
search: '探索',
|
||||||
|
next: '次',
|
||||||
|
skip: 'スキップ',
|
||||||
|
close: '閉じる',
|
||||||
|
by: '{namespace}製',
|
||||||
|
updateAll: 'すべてを更新',
|
||||||
|
start: {
|
||||||
|
failed: '起動チェックに失敗',
|
||||||
|
accept: 'とにかく実行',
|
||||||
|
error: {
|
||||||
|
package: 'パッケージが見つからない',
|
||||||
|
dependency: '依存関係が見つからない',
|
||||||
|
tool: 'ツールが見つからない',
|
||||||
|
unknown: '不明エラー',
|
||||||
|
},
|
||||||
|
tooltip: {
|
||||||
|
game: 'ゲームパスを指定する必要があります',
|
||||||
|
amfs: 'amfsパスを指定する必要があります',
|
||||||
|
segatools: 'segatoolsフックパッケージが必要です',
|
||||||
|
},
|
||||||
|
button: {
|
||||||
|
start: '起動',
|
||||||
|
stop: '停止',
|
||||||
|
unchecked: 'チェックをスキップして起動',
|
||||||
|
shortcut: 'デスクトップショートカットを作成',
|
||||||
|
help: 'ヘルプ',
|
||||||
|
refresh: 'MODを再適用して起動',
|
||||||
|
cache: 'MODキャッシュのクリア',
|
||||||
|
},
|
||||||
|
},
|
||||||
game: {
|
game: {
|
||||||
ongeki: 'オンゲキ',
|
ongeki: 'オンゲキ',
|
||||||
chunithm: 'チュウニズム',
|
chunithm: 'チュウニズム',
|
||||||
},
|
},
|
||||||
profile: {
|
profile: {
|
||||||
|
welcome: 'STARTLINERへようこそ! プロフィルの作成から始めよう。',
|
||||||
create: '{game}のプロフィル',
|
create: '{game}のプロフィル',
|
||||||
|
delete: 'プロフィル削除',
|
||||||
|
reallyDelete: '本当に{profile}を削除しますか?',
|
||||||
|
template: 'STARTLINERのテンプレート',
|
||||||
|
importTemplate: 'テンプレートのインポート',
|
||||||
|
exportTemplate: 'プロフィルのエクスポート',
|
||||||
|
export: 'エクスポート',
|
||||||
|
standardExport: 'テンプレート',
|
||||||
|
diagnostic: '診断',
|
||||||
|
},
|
||||||
|
creator: {
|
||||||
|
header: 'パッケージ製作者',
|
||||||
|
basic: '基本情報',
|
||||||
|
name: '名',
|
||||||
|
description: '説明',
|
||||||
|
website: 'ウェブサイト',
|
||||||
|
type: 'パッケージタイプ',
|
||||||
|
rainy: 'スタンダード',
|
||||||
|
segatools: 'segatools',
|
||||||
|
native: 'ネイティブ',
|
||||||
|
games: 'ゲーム',
|
||||||
|
packageFormat: 'パッケージフォーマット仕様',
|
||||||
|
},
|
||||||
|
store: {
|
||||||
|
installRecommended: 'おすすめパッケージのインストール',
|
||||||
|
installed: 'インストールされているの表示',
|
||||||
|
deprecated: '非推奨の表示',
|
||||||
|
nsfw: 'NSFWの表示',
|
||||||
|
incompatible: 'このパッケージは現在STARTLINERと互換性がありません。',
|
||||||
|
|
||||||
|
includeCategories: 'カテゴリーを含む',
|
||||||
|
excludeCategories: 'カテゴリーを除く',
|
||||||
|
},
|
||||||
|
pkglist: {
|
||||||
|
missing: '行方不明',
|
||||||
|
local: 'ローカルパッケージ',
|
||||||
|
namespace: '名前空間順',
|
||||||
|
type: 'タイプ順',
|
||||||
|
category: 'カテゴリ順',
|
||||||
|
standard: 'スタンダードMOD',
|
||||||
|
native: 'ネイティブMOD',
|
||||||
|
segatools: 'segatools',
|
||||||
|
unsupported: '未対応',
|
||||||
|
exclusions: '除外:',
|
||||||
|
},
|
||||||
|
patch: {
|
||||||
|
loading: 'ロード中...',
|
||||||
|
noneFound:
|
||||||
|
'互換性のあるパッチが見つかりません。パッチが適用されていないファイルを使用していることを確認してください。',
|
||||||
|
forceLoad: '強制ロード',
|
||||||
|
'standard-shared-audio':
|
||||||
|
'共有オーディオモードを強制、システムオーディオサンプルレートは48000Hzでなければなりません',
|
||||||
|
'standard-shared-audio-tooltip':
|
||||||
|
'互換性は向上するが、待ち時間が増える可能性があります',
|
||||||
|
'standard-2ch': '2チャンネルオーディオ出力を強制',
|
||||||
|
'standard-2ch-tooltip': '低音過負荷の可能性',
|
||||||
|
'standard-song-timer': '音楽選択タイマーを無効にする',
|
||||||
|
'standard-map-timer': 'マップ選択タイマー',
|
||||||
|
'standard-map-timer-tooltip':
|
||||||
|
'負に設定すると、タイマーは968+値となる(例:968+-1=967)',
|
||||||
|
'standard-ticket-timer': 'チケット選択タイマー',
|
||||||
|
'standard-ticket-timer-tooltip':
|
||||||
|
'負に設定すると、タイマーは968+値となる(例:968+-1=967)',
|
||||||
|
'standard-course-timer': 'コース選択タイマー',
|
||||||
|
'standard-course-timer-tooltip':
|
||||||
|
'負に設定すると、タイマーは968+値となる(例:968+-1=967)',
|
||||||
|
'standard-unlimited-tracks': '最大トラック数無制限',
|
||||||
|
'standard-unlimited-tracks-tooltip':
|
||||||
|
'1クレジットにつき7曲以上再生する場合はチェックが必要',
|
||||||
|
'standard-maximum-tracks': '最大トラック数',
|
||||||
|
'standard-no-encryption': '暗号化無し',
|
||||||
|
'standard-no-encryption-tooltip': 'TLSも無効にする',
|
||||||
|
'standard-no-tls': 'TLS無し',
|
||||||
|
'standard-no-tls-tooltip': 'タイトルサーバーの回避策',
|
||||||
|
'standard-head-to-head': 'ヘッド・トゥ・ヘッドパッチ',
|
||||||
|
'standard-head-to-head-tooltip':
|
||||||
|
'ヘッド・トゥ・ヘッドプレイに接続しようとする際に、無限に同期しないことがあった問題を修正',
|
||||||
|
'standard-bypass-1080p': '1080pモニターチェックのバイパス',
|
||||||
|
'standard-bypass-120hz': '120hzモニターチェックのバイパス',
|
||||||
|
'standard-force-free-play-text': 'FREE PLAYクレジットテキストを強制',
|
||||||
|
'standard-force-free-play-text-tooltip':
|
||||||
|
'クレジット数をFREE PLAYに置き換える',
|
||||||
|
'standard-custom-free-play-length': 'カスタムFREE PLAYテキストの長さ',
|
||||||
|
'standard-custom-free-play-length-tooltip':
|
||||||
|
'強制FREE PLAYクレジットテキストが有効な場合に表示されるテキストの長さを変更します。',
|
||||||
|
'standard-custom-free-play-text': 'カスタムFREE PLAYテキスト',
|
||||||
|
'standard-custom-free-play-text-tooltip':
|
||||||
|
'無限クレジットを使用する場合、FREE PLAYのテキストを置き換える。',
|
||||||
|
'standard-localhost':
|
||||||
|
'ネットワークサーバーとして127.0.0.1/localhostを許可',
|
||||||
|
'standard-credit-freeze': 'クレジットフリーズ ',
|
||||||
|
'standard-credit-freeze-tooltip':
|
||||||
|
'クレジットの使用を防ぎます。ゲームを開始したり、プレミアムチケットを購入したりするには、少なくとも1つのクレジットが使用可能でなければならない。',
|
||||||
|
'standard-openssl-fix': 'OpenSSL SHAクラッシュのバグ修正',
|
||||||
|
'standard-openssl-fix-tooltip':
|
||||||
|
'第10世代以降のインテルCPUのクラッシュを修正',
|
||||||
},
|
},
|
||||||
cfg: {
|
cfg: {
|
||||||
|
afterRestart: '再起動後に適用',
|
||||||
|
hardware: 'ハードウェア',
|
||||||
|
segatools: {
|
||||||
|
general: '一般',
|
||||||
|
builtIn: 'segatools内蔵エミュレーション',
|
||||||
|
targetTooltip:
|
||||||
|
'STARTLINERはそれ以外のクリーンなデータに解凍された実行可能ファイルを期待する。',
|
||||||
|
hooks: 'フック',
|
||||||
|
ioModules: 'IOモジュール',
|
||||||
|
ioModulesDesc: 'これは望ましい入力方法と一致するはずです。',
|
||||||
|
ioBuiltIn: 'segatools内蔵(キーボードー)',
|
||||||
|
io4: 'ネイティブIO4',
|
||||||
|
installTooltip:
|
||||||
|
'{thing}はパッケージストアからダウンロードできます。',
|
||||||
|
},
|
||||||
|
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: 'キーチップ',
|
||||||
|
subnet: 'サブネット',
|
||||||
|
addrSuffix: 'アドレスサフィックス',
|
||||||
|
},
|
||||||
aime: {
|
aime: {
|
||||||
type: 'Aimeタイプ',
|
type: 'Aimeタイプ',
|
||||||
|
modules: 'Aimeモジュール ',
|
||||||
|
code: 'アクセスコード',
|
||||||
|
codeTooltip:
|
||||||
|
'segatools内蔵エミュレーションまたは互換性のあるサードパーティ製パッケージでのみ使用可能。',
|
||||||
|
aimedb: '物理カードにはAiMeDBを使う',
|
||||||
|
aimedbTooltip:
|
||||||
|
'物理カードがアクセスコードを取得するためにAiMeDBを使用するかどうか。ゲームがホストされたネットワークを使用している場合、このオプションを有効にすると、物理筐体で取得するのと同じアカウントデータ/プロフィルがロードされます。',
|
||||||
|
serialPort: 'Aimeシリアルポート',
|
||||||
|
serialPortTooltip: `ポートはデバイスとプリンター、またはgooglechromelabs.github.io/serial-terminalで確認できます
|
||||||
|
AIC Picoの場合は、AIMEポートを選択する。`,
|
||||||
|
serverName: 'サーバー名',
|
||||||
|
},
|
||||||
|
misc: {
|
||||||
|
title: 'その他',
|
||||||
|
intel: '第10世代以降インテル向けOpenSSLバグの回避策',
|
||||||
|
intelTooltip: '代わりにamdaemonにパッチを当てることを推奨する。',
|
||||||
|
other: 'その他segatools設定',
|
||||||
|
otherTooltip: 'STARTLINERに含まれない上級者向けまたは状況別設定',
|
||||||
|
prelaunch: 'スタート前スクリプト',
|
||||||
|
prelaunchTooltip: 'ゲームの前に実行されるスクリプト',
|
||||||
|
},
|
||||||
|
extensions: {
|
||||||
|
title: 'エクステンション',
|
||||||
|
bepInExConsole: 'BepInExコンソール',
|
||||||
|
audioMode: 'オーディオモード',
|
||||||
|
audioTooltip:
|
||||||
|
'排他2チャンネルモードには7EVENDAYSHOLIDAYS-ExclusiveAudioが必要です',
|
||||||
|
audioShared: '共有',
|
||||||
|
audio6Ch: '排他6チャンネル',
|
||||||
|
audio2Ch: '排他2チャンネル',
|
||||||
|
sampleRate: 'サンプルレート',
|
||||||
|
blacklist: '曲IDブラックリスト',
|
||||||
|
blacklistTooltip:
|
||||||
|
'このID範囲内の譜面のスコアは保存もアップロードもされない',
|
||||||
|
bonusTracks: 'ボーナストラックのアンロック',
|
||||||
|
bonusTracksTooltip:
|
||||||
|
'このオプションを無効にすると、曲リストが整理されます',
|
||||||
|
saekawa: 'Saekawa設定ファイル',
|
||||||
|
inohara: 'Inohara設定ファイル',
|
||||||
|
},
|
||||||
|
keyboard: {
|
||||||
|
title: 'キーボード',
|
||||||
|
tooltip:
|
||||||
|
'IOモジュールがsegatools内蔵(キーボード)または互換性のあるサードパーティモジュール(mu3io.NETなど)に設定されている場合のみ適用可能。',
|
||||||
|
leverMode: 'レバーモード',
|
||||||
|
mouse: 'マウス',
|
||||||
|
irTooltip:
|
||||||
|
'実際のキーボードで演奏する場合は、ir1だけをバインドし、残りはバインドしない。',
|
||||||
|
},
|
||||||
|
wine: {
|
||||||
|
prefix: 'Wineのプレフィックス',
|
||||||
|
runtime: 'Wineのランタイム',
|
||||||
|
},
|
||||||
|
startliner: {
|
||||||
|
offlineMode: 'オフラインモード',
|
||||||
|
offlineModeTooltip: 'パッケージストアを無効にする。',
|
||||||
|
autoUpdate: '自動更新',
|
||||||
|
verbose: '詳細ログ',
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
onboarding: {
|
||||||
|
or: 'または',
|
||||||
|
backButton: 'コントローラー背面のボタン',
|
||||||
|
standard: `
|
||||||
|
以下のような画面に引っかかるかもしれません:
|
||||||
|
|
||||||
|
{bigblack}Aグループの基準機から設定を取得{endbig}
|
||||||
|
|
||||||
|
その場合、テストメニューに移動し、{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}
|
||||||
|
|
||||||
|
## 楽しもう!
|
||||||
|
`,
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
@ -9,6 +9,7 @@ export default {
|
|||||||
skip: 'Pomiń',
|
skip: 'Pomiń',
|
||||||
close: 'Zamknij',
|
close: 'Zamknij',
|
||||||
by: 'od {namespace}',
|
by: 'od {namespace}',
|
||||||
|
updateAll: 'ZAKTUALIZUJ WSZYSTKO',
|
||||||
start: {
|
start: {
|
||||||
failed: 'Uruchomienie nie powiodło się',
|
failed: 'Uruchomienie nie powiodło się',
|
||||||
accept: 'Uruchom mimo to',
|
accept: 'Uruchom mimo to',
|
||||||
@ -205,6 +206,8 @@ 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',
|
||||||
|
prelaunchTooltip: 'Opcjonalny skrypt uruchamiany przed grą.',
|
||||||
},
|
},
|
||||||
extensions: {
|
extensions: {
|
||||||
title: 'Rozszerzenia',
|
title: 'Rozszerzenia',
|
||||||
|
@ -189,7 +189,7 @@ export const usePkgStore = defineStore('pkg', {
|
|||||||
await this.reloadAll();
|
await this.reloadAll();
|
||||||
},
|
},
|
||||||
|
|
||||||
async install(pkg: Package | undefined) {
|
async install(pkg: Package | undefined, enable: boolean) {
|
||||||
if (pkg === undefined) {
|
if (pkg === undefined) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -198,6 +198,7 @@ export const usePkgStore = defineStore('pkg', {
|
|||||||
await invoke('install_package', {
|
await invoke('install_package', {
|
||||||
key: pkgKey(pkg),
|
key: pkgKey(pkg),
|
||||||
force: true,
|
force: true,
|
||||||
|
enable,
|
||||||
});
|
});
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
if (pkg !== undefined) {
|
if (pkg !== undefined) {
|
||||||
@ -211,6 +212,7 @@ export const usePkgStore = defineStore('pkg', {
|
|||||||
await invoke('install_package', {
|
await invoke('install_package', {
|
||||||
key,
|
key,
|
||||||
force: true,
|
force: true,
|
||||||
|
enable: false,
|
||||||
});
|
});
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
console.error(err);
|
console.error(err);
|
||||||
@ -221,7 +223,7 @@ export const usePkgStore = defineStore('pkg', {
|
|||||||
const list = [];
|
const list = [];
|
||||||
for (const pkg of this.allLocal) {
|
for (const pkg of this.allLocal) {
|
||||||
if (pkg.rmt && pkg.rmt.version > pkg.loc!.version) {
|
if (pkg.rmt && pkg.rmt.version > pkg.loc!.version) {
|
||||||
list.push(this.install(pkg));
|
list.push(this.install(pkg, false));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
await Promise.all(list);
|
await Promise.all(list);
|
||||||
@ -322,9 +324,10 @@ export const usePrfStore = defineStore('prf', () => {
|
|||||||
const generalStore = useGeneralStore();
|
const generalStore = useGeneralStore();
|
||||||
|
|
||||||
const configDir = computed(async () => {
|
const configDir = computed(async () => {
|
||||||
|
const title = `profile-${current.value?.meta.game}-${current.value?.meta.name}`;
|
||||||
return path.join(
|
return path.join(
|
||||||
await generalStore.configDir,
|
await generalStore.configDir,
|
||||||
`profile-${current.value?.meta.game}-${current.value?.meta.name}`
|
title
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user