Compare commits

..

31 Commits

Author SHA1 Message Date
NotThorny
986259d96b Bump version 2025-11-15 00:41:10 -07:00
NotThorny
97454de75e Fix default config not generating
Fixes #262
2025-11-15 00:35:51 -07:00
NotThorny
f61f4eed51 Bump version 2025-11-14 15:24:14 -07:00
NotThorny
99b45ddf52 Fix reading profile path 2025-11-14 15:24:14 -07:00
NotThorny
fafec01fe3 Fix not loading old configs from correct dir 2025-11-14 02:45:24 -07:00
NotThorny
0c910b7317 Update langs 2025-11-14 02:38:22 -07:00
NotThorny
6f2be3c5a5 Add profiles 2025-11-14 02:37:37 -07:00
NotThorny
d2b8124877 Update AIO to 6.1 2025-10-31 21:17:31 -06:00
NotThorny
247150c62a Update patch 2025-10-25 16:18:44 -06:00
NotThorny
1599c37100 Update AIO 6.0 2025-10-17 00:48:37 -06:00
NotThorny
ecb7936a8f Add 6.0 patch from @pmagixc
Bump version
2025-10-15 21:36:14 -06:00
Thoronium
a40080cca2 Merge pull request #255 from GID0317/main
Update launch_args, Fix login timeout and transparency support
2025-07-01 14:32:09 -06:00
GID
364d138779 Update launch_args and fix login timeout to use the options OptionSection for better UX and easier for theming 2025-07-01 19:35:14 +07:00
GID
f03cc0a09f Update to make the transparency enabled to make easier to support rounded corners windows 2025-07-01 19:31:39 +07:00
Thoronium
7750266a3d Bump version 2025-03-27 01:19:00 -06:00
Thoronium
028ee380f2 Replace 5.x+ individual patch files with universal 2025-03-27 01:17:24 -06:00
Thoronium
fcd08cace5 Bump version 2025-02-26 13:05:21 -07:00
Thoronium
0258aa006a Remove unused patch 2025-02-26 13:04:25 -07:00
Thoronium
8c10c00b53 Update file 2025-02-15 14:28:50 -07:00
Thoronium
fe094c952b Fix typo 2025-02-14 23:49:11 -07:00
Thoronium
63a883cf1d Bump version 2025-02-14 15:25:56 -07:00
Thoronium
8207260968 Add 5.4 AIO 2025-02-14 15:19:18 -07:00
Thoronium
4e72101fda Bump version 2025-02-03 17:11:19 -07:00
Thoronium
14206e87a0 Update menu version 2025-02-03 17:09:56 -07:00
Thoronium
13d129f175 Add 5.3 AIO 2025-02-03 17:03:44 -07:00
Thoronium
14173e5b9f Merge branch 'main' of https://github.com/Grasscutters/Cultivation 2025-01-16 20:45:13 -07:00
Thoronium
3669bb334b Bump version 2025-01-16 20:45:07 -07:00
Thoronium
03fed7a69a Support XXMI launching with args 2025-01-16 20:41:17 -07:00
Thoronium
55a90ea531 Add 5.3 patch
Bump version
2025-01-01 13:47:37 -07:00
Thoronium
b28c3881e6 Bump version 2024-12-23 02:36:28 -07:00
Thoronium
4d98cd9468 Fix comparison 2024-10-31 02:11:46 -06:00
40 changed files with 579 additions and 352 deletions

1
.gitignore vendored
View File

@@ -10,6 +10,7 @@
# production
/build
/target
# misc
.DS_Store

View File

@@ -1,6 +1,6 @@
{
"name": "cultivation",
"version": "1.5.1",
"version": "1.7.2",
"private": true,
"dependencies": {
"@tauri-apps/api": "^1.0.0-rc.5",

2
src-tauri/Cargo.lock generated
View File

@@ -959,7 +959,7 @@ checksum = "b365fabc795046672053e29c954733ec3b05e4be654ab130fe8f1f94d7051f35"
[[package]]
name = "cultivation"
version = "1.5.1"
version = "1.6.3"
dependencies = [
"anime-launcher-sdk",
"anyhow",

View File

@@ -1,13 +1,13 @@
[package]
name = "cultivation"
version = "1.5.1"
version = "1.6.3"
description = "A custom launcher for anime game."
authors = ["KingRainbow44", "SpikeHD"]
license = ""
repository = "https://github.com/Grasscutters/Cultivation.git"
default-run = "cultivation"
edition = "2021"
rust-version = "1.58"
rust-version = "1.57"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

View File

@@ -37,11 +37,13 @@
"web_cache": "删除 webCaches 文件夹",
"launch_args": "启动参数",
"offline_mode": "离线模式",
"fix_res": "修复登录超时"
"fix_res": "修复登录超时",
"show_version": "在按钮上显示游戏版本",
"save_profile": "保存配置配置文件"
},
"downloads": {
"grasscutter_fullbuild": "下载 Grasscutter 一体化",
"grasscutter_fullquest": "下载 5.0 一体化",
"grasscutter_fullquest": "下载 6.1 一体化",
"grasscutter_stable_data": "下载 Grasscutter 稳定版数据",
"grasscutter_latest_data": "下载 Grasscutter 开发版数据",
"grasscutter_stable_data_update": "更新 Grasscutter 稳定版数据",

View File

@@ -37,11 +37,13 @@
"web_cache": "刪除 webCaches 文件夾",
"launch_args": "啟動參數",
"offline_mode": "離線模式",
"fix_res": "修復登入逾時"
"fix_res": "修復登入逾時",
"show_version": "在按鈕上顯示遊戲版本",
"save_profile": "儲存配置設定檔"
},
"downloads": {
"grasscutter_fullbuild": "下載Grasscutter多合一下載",
"grasscutter_fullquest": "下载 5.0 一体化",
"grasscutter_fullquest": "下载 6.1 一体化",
"grasscutter_stable_data": "下載Grasscutter穩定版數據Data",
"grasscutter_latest_data": "下載Grasscutter開發板數據Data",
"grasscutter_stable_data_update": "更新Grasscutter穩定版數據Data",

View File

@@ -39,11 +39,13 @@
"web_cache": "WebCaches-Ordner löschen",
"launch_args": "Start-Argumente",
"offline_mode": "Offline-Modus",
"fix_res": "Login-Zeitüberschreitung beheben"
"fix_res": "Login-Zeitüberschreitung beheben",
"show_version": "Spielversion in Schaltflächen anzeigen",
"save_profile": "Profil speichern"
},
"downloads": {
"grasscutter_fullbuild": "Grasscutter All-in-One herunterladen",
"grasscutter_fullquest": "5.0 All-in-One herunterladen",
"grasscutter_fullquest": "6.1 All-in-One herunterladen",
"grasscutter_stable_data": "Stabile Grasscutter-Daten herunterladen",
"grasscutter_latest_data": "Neueste Grasscutter-Daten herunterladen",
"grasscutter_stable_data_update": "Stabile Grasscutter-Daten aktualisieren",

View File

@@ -39,11 +39,13 @@
"web_cache": "Delete webCaches folder",
"launch_args": "Launch Args",
"offline_mode": "Offline Mode",
"fix_res": "Fix Login Timeout"
"fix_res": "Fix Login Timeout",
"show_version": "Show game version in buttons",
"save_profile": "Save profile"
},
"downloads": {
"grasscutter_fullbuild": "Download Grasscutter All-in-One",
"grasscutter_fullquest": "Download 5.0 All-in-One",
"grasscutter_fullbuild": "Download Grasscutter 4.0 All-in-One",
"grasscutter_fullquest": "Download 6.1 All-in-One",
"grasscutter_stable_data": "Download Grasscutter Stable Data",
"grasscutter_latest_data": "Download Grasscutter Latest Data",
"grasscutter_stable_data_update": "Update Grasscutter Stable Data",

View File

@@ -37,11 +37,13 @@
"web_cache": "Eliminar la carpeta webCaches",
"launch_args": "Args de lanzamiento",
"offline_mode": "Modo sin conexión",
"fix_res": "Reparar el tiempo de espera"
"fix_res": "Reparar el tiempo de espera",
"show_version": "Mostrar versión del juego en botones",
"save_profile": "Guardar perfil"
},
"downloads": {
"grasscutter_fullbuild": "Descargar datos todo en uno de Grasscutter",
"grasscutter_fullquest": "Descargar datos todo en uno de 5.0",
"grasscutter_fullquest": "Descargar datos todo en uno de 6.1",
"grasscutter_stable_data": "Descargar datos Estables de Grasscutter",
"grasscutter_latest_data": "Descargar datos más Recientes de Grasscutter",
"grasscutter_stable_data_update": "Actualizar datos estables de Grasscutter",

View File

@@ -37,11 +37,13 @@
"web_cache": "Supprimer le dossier webCaches",
"launch_args": "Arguments de lancement",
"offline_mode": "Mode hors ligne",
"fix_res": "Réparation du login"
"fix_res": "Réparation du login",
"show_version": "Afficher la version du jeu sur les boutons",
"save_profile": "Enregistrer le profil"
},
"downloads": {
"grasscutter_fullbuild": "Telecharger Grasscutter tout-en-un",
"grasscutter_fullquest": "Télécharger les 5.0 tout-en-un",
"grasscutter_fullquest": "Télécharger les 6.1 tout-en-un",
"grasscutter_stable_data": "Télécharger les donnees de Grasscutter (version stable)",
"grasscutter_latest_data": "Télécharger les donnees de Grasscutter (derniere version)",
"grasscutter_stable_data_update": "Mettre à jour les données de Grasscutter (version stable)",

View File

@@ -36,11 +36,13 @@
"web_cache": "Hapus folder webCaches",
"launch_args": "Luncurkan Args",
"offline_mode": "Mode Offline",
"fix_res": "Perbaiki batas waktu login"
"fix_res": "Perbaiki batas waktu login",
"show_version": "Tampilkan versi game pada tombol",
"save_profile": "Simpan profil"
},
"downloads": {
"grasscutter_fullbuild": "Sedang Mendownload Grasscutter Semua Dalam Satu",
"grasscutter_fullquest": "Unduh 5.0 semua dalam satu",
"grasscutter_fullquest": "Unduh 6.1 semua dalam satu",
"grasscutter_stable_data": "Sedang Mendownload Grasscutter Versi Stabil",
"grasscutter_latest_data": "Sedang Mendownload Grasscutter Data Terbaru",
"grasscutter_stable_data_update": "Memperbaharui Grasscutter Data Stabil",

View File

@@ -37,11 +37,13 @@
"web_cache": "Elimina la cartella webCaches",
"launch_args": "Argomenti di lancio",
"offline_mode": "Modalità Offline",
"fix_res": "Correggere il timeout dell'accesso"
"fix_res": "Correggere il timeout dell'accesso",
"show_version": "Mostra la versione del gioco sui pulsanti",
"save_profile": "Salva il profilo"
},
"downloads": {
"grasscutter_fullbuild": "Scarica Grasscutter Tutto-in-Uno",
"grasscutter_fullquest": "Scarica 5.0 Tutto-in-Uno",
"grasscutter_fullquest": "Scarica 6.1 Tutto-in-Uno",
"grasscutter_stable_data": "Scarica i dati di Grasscutter Stabili",
"grasscutter_latest_data": "Scarica i dati di Grasscutter Più Recenti",
"grasscutter_stable_data_update": "Aggiorna i dati di Grasscutter Stabili",

View File

@@ -37,11 +37,13 @@
"check_aagl": "その他のオプションは、他のランチャーをチェックしてください",
"grasscutter_elevation": "制限されたポートでのGCの実行方法",
"web_cache": "webCachesフォルダを削除",
"launch_args": "Launch Args"
"launch_args": "Launch Args",
"show_version": "ボタンにゲームバージョンを表示",
"save_profile": "プロフィールを保存"
},
"downloads": {
"grasscutter_fullbuild": "Grasscutter All-in-Oneをダウンロード",
"grasscutter_fullquest": "Questing All-in-Oneをダウンロード",
"grasscutter_fullquest": "6.1 All-in-Oneをダウンロード",
"grasscutter_stable_data": "Grasscutter安定版データファイルをダウンロード",
"grasscutter_latest_data": "Grasscutter最新版データファイルをダウンロード",
"grasscutter_stable_data_update": "Grasscutter安定版データファイルをアップデート",

View File

@@ -37,11 +37,13 @@
"web_cache": "webCaches 폴더 삭제",
"launch_args": "실행 인수",
"offline_mode": "오프라인 모드",
"fix_res": "로그인 시간 초과 수정"
"fix_res": "로그인 시간 초과 수정",
"show_version": "버튼에 게임 버전 표시",
"save_profile": "프로필 저장"
},
"downloads": {
"grasscutter_fullbuild": "올인원 Grasscutter 다운로드",
"grasscutter_fullquest": "5.0 올인원 다운로드",
"grasscutter_fullquest": "6.1 올인원 다운로드",
"grasscutter_stable_data": "안정적인 데이터 다운로드",
"grasscutter_latest_data": "최신 데이터 다운로드",
"grasscutter_stable_data_update": "안정적 데이터 업데이트",

View File

@@ -35,11 +35,13 @@
"web_cache": "Dzēsiet mapi WebCaches",
"launch_args": "Palaišanas args",
"offline_mode": "Bezsaistes režīms",
"fix_res": "Fiksēt pieteikšanās laika"
"fix_res": "Fiksēt pieteikšanās laika",
"show_version": "Pogās redzamā spēles versija",
"save_profile": "Saglabāt profilu"
},
"downloads": {
"grasscutter_fullbuild": "Lejupielādējiet Grasscutter viss vienā",
"grasscutter_fullquest": "Lejupielādēt 5.0 viss vienā",
"grasscutter_fullquest": "Lejupielādēt 6.1 viss vienā",
"grasscutter_stable_data": "Lejupielādējiet Grasscutter stabilos datus",
"grasscutter_latest_data": "Lejupielādējiet Grasscutter jaunākos datus",
"grasscutter_stable_data_update": "Atjauniniet Grasscutter stabilos datus",

View File

@@ -36,11 +36,13 @@
"web_cache": "Verwijder de webCaches-map",
"launch_args": "Args starten",
"offline_mode": "Offline Modus",
"fix_res": "Time-out inloggen verhelpen"
"fix_res": "Time-out inloggen verhelpen",
"show_version": "Spelversie weergegeven op knoppen",
"save_profile": "Profiel opslaan"
},
"downloads": {
"grasscutter_fullbuild": "Grasscutter Alles-in-één Downloaden",
"grasscutter_fullquest": "Alles-in-één 5.0 downloaden",
"grasscutter_fullquest": "Alles-in-één 6.1 downloaden",
"grasscutter_stable_data": "Download Stabiele Gegevens Van Grasscutter",
"grasscutter_latest_data": "Download De Nieuwste Gegevens Van Grasscutter",
"grasscutter_stable_data_update": "Stabiele gegevens Van Grasscutter bijwerken",

View File

@@ -39,11 +39,13 @@
"web_cache": "Usuń folder webCaches",
"launch_args": "Argumenty uruchamiania",
"offline_mode": "Tryb offline",
"fix_res": "Napraw limit czasu logowania"
"fix_res": "Napraw limit czasu logowania",
"show_version": "Wersja gry wyświetlana na przyciskach",
"save_profile": "Zapisz profil"
},
"downloads": {
"grasscutter_fullbuild": "Pobierz Grasscutter (wszystko w jednym)",
"grasscutter_fullquest": "Pobierz 5.0 (wszystko w jednym)",
"grasscutter_fullquest": "Pobierz 6.1 (wszystko w jednym)",
"grasscutter_stable_data": "Pobierz stabilne dane Grasscuttera",
"grasscutter_latest_data": "Pobierz najnowsze dane Grasscuttera",
"grasscutter_stable_data_update": "Zaaktualizuj stabilne dane Grasscuttera",

View File

@@ -37,11 +37,13 @@
"web_cache": "Excluir pasta webCaches",
"launch_args": "Argumentos de lançamento",
"offline_mode": "Modo offline",
"fix_res": "Corrigir o tempo limite de login"
"fix_res": "Corrigir o tempo limite de login",
"show_version": "Versão do jogo exibida nos botões",
"save_profile": "Salvar perfil"
},
"downloads": {
"grasscutter_fullbuild": "Baixar o Grasscutter Tudo-em-Um",
"grasscutter_fullquest": "Baixar de 5.0 em um só lugar",
"grasscutter_fullquest": "Baixar de 6.1 em um só lugar",
"grasscutter_stable_data": "Baixar os Dados do Grasscutter Estável",
"grasscutter_latest_data": "Baixar os Dados do Grasscutter Mais Recente",
"grasscutter_stable_data_update": "Atualizar os Dados do Grasscutter Estável",

View File

@@ -36,11 +36,13 @@
"web_cache": "Удалить папку webCaches",
"launch_args": "Параметры запуска",
"offline_mode": "Автономный режим",
"fix_res": "Исправить таймаут входа в систему"
"fix_res": "Исправить таймаут входа в систему",
"show_version": "Версия игры отображается на кнопках",
"save_profile": "Сохранить профиль"
},
"downloads": {
"grasscutter_fullbuild": "Скачать все в одном Grasscutter",
"grasscutter_fullquest": "Скачать 5.0 все в одном",
"grasscutter_fullquest": "Скачать 6.1 все в одном",
"grasscutter_stable_data": "Скачать стабильные данные Grasscutter",
"grasscutter_latest_data": "Скачать последние данные Grasscutter",
"grasscutter_stable_data_update": "Обновить стабильные данные Grasscutter",

View File

@@ -37,11 +37,13 @@
"web_cache": "Xóa thư mục webCaches",
"launch_args": "Khởi chạy đối số",
"offline_mode": "Chế độ ngoại tuyến",
"fix_res": "Sửa lỗi hết thời gian đăng nhập"
"fix_res": "Sửa lỗi hết thời gian đăng nhập",
"show_version": "Hiển thị phiên bản trò chơi trên các nút",
"save_profile": "Lưu hồ sơ"
},
"downloads": {
"grasscutter_fullbuild": "Tải Grasscutter tất cả trong một",
"grasscutter_fullquest": "Tải 5.0 tất cả trong một",
"grasscutter_fullquest": "Tải 6.1 tất cả trong một",
"grasscutter_stable_data": "Tải dữ liệu Grasscutter bản ổn định",
"grasscutter_latest_data": "Tải dữ liệu Grasscutter bản mới nhất",
"grasscutter_stable_data_update": "Cập nhật dữ liệu Grasscutter bản ổn định",

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@@ -30,20 +30,33 @@ pub struct Configuration {
pub redirect_more: Option<bool>,
pub launch_args: Option<String>,
pub offline_mode: Option<bool>,
pub show_version: Option<bool>,
pub profile: Option<String>,
}
pub fn config_path() -> PathBuf {
pub fn config_path(profile: String) -> PathBuf {
let mut path = tauri::api::path::data_dir().unwrap();
path.push("cultivation");
path.push("configuration.json");
if profile.as_str() == "default" {
path.push("configuration.json");
} else {
path.push("profiles");
path.push(profile + ".json");
}
path
}
pub fn get_config() -> Configuration {
let path = config_path();
pub fn get_config(profile_name: String) -> Configuration {
let path = config_path(profile_name.clone());
let config = std::fs::read_to_string(path).unwrap_or("{}".to_string());
let config: Configuration = serde_json::from_str(&config).unwrap_or_default();
//let default = String::from("default");
let prof = config.profile.clone().unwrap_or_default();
if prof != String::from("default") && prof != profile_name.clone() {
return get_config(prof.clone());
}
config
}

View File

@@ -101,7 +101,7 @@ async fn parse_args(inp: &Vec<String>) -> Result<Args, ArgsError> {
args.parse(inp).unwrap();
let config = config::get_config();
let config = config::get_config(String::from("default"));
if args.value_of("help")? {
println!("{}", args.full_usage());
@@ -207,8 +207,10 @@ fn main() -> Result<(), ArgsError> {
is_grasscutter_running,
restart_grasscutter,
get_theme_list,
get_profile_list,
system_helpers::run_command,
system_helpers::run_program,
system_helpers::run_program_args,
system_helpers::run_program_relative,
system_helpers::start_service,
system_helpers::service_status,
@@ -535,3 +537,20 @@ async fn get_theme_list(data_dir: String) -> Vec<HashMap<String, String>> {
themes
}
#[tauri::command]
async fn get_profile_list(data_dir: String) -> Vec<String> {
let profile_loc = format!("{}/profiles", data_dir);
// Ensure folder exists
if !std::path::Path::new(&profile_loc).exists() {
std::fs::create_dir_all(&profile_loc).unwrap();
}
let mut p_list = Vec::new();
for entry in std::fs::read_dir(&profile_loc).unwrap() {
p_list.push(entry.unwrap().file_name().into_string().unwrap());
}
p_list
}

View File

@@ -50,79 +50,80 @@ struct WhatToUnpach {
#[cfg(windows)]
#[tauri::command]
pub async fn patch_game(newer_game: bool, version: String) -> bool {
pub async fn patch_game(_newer_game: bool, version: String) -> bool {
let mut patch_path;
// Altpatch first - Now using as hoyonet switch
if newer_game {
let alt_patch_path = PathBuf::from(system_helpers::install_location()).join("altpatch");
// People keep using this when they shouldn't, 99.8% of people will never need it. Just remove for now.
// if newer_game {
// let alt_patch_path = PathBuf::from(system_helpers::install_location()).join("altpatch");
// Should handle overwriting backup with new version backup later
let backup_path = PathBuf::from(system_helpers::install_location())
.join("altpatch/original-mihoyonet.dll")
.to_str()
.unwrap()
.to_string();
let backup_exists = file_helpers::does_file_exist(&backup_path);
// // Should handle overwriting backup with new version backup later
// let backup_path = PathBuf::from(system_helpers::install_location())
// .join("altpatch/original-mihoyonet.dll")
// .to_str()
// .unwrap()
// .to_string();
// let backup_exists = file_helpers::does_file_exist(&backup_path);
if !backup_exists {
let backup = file_helpers::copy_file_with_new_name(
get_game_rsa_path().await.unwrap()
+ &String::from("/GenshinImpact_Data/Plugins/mihoyonet.dll"),
alt_patch_path.clone().to_str().unwrap().to_string(),
String::from("original-mihoyonet.dll"),
);
// if !backup_exists {
// let backup = file_helpers::copy_file_with_new_name(
// get_game_rsa_path().await.unwrap()
// + &String::from("/GenshinImpact_Data/Plugins/mihoyonet.dll"),
// alt_patch_path.clone().to_str().unwrap().to_string(),
// String::from("original-mihoyonet.dll"),
// );
if !backup {
println!("Unable to backup file!");
}
}
// if !backup {
// println!("Unable to backup file!");
// }
// }
patch_path = PathBuf::from(system_helpers::install_location()).join("altpatch/mihoyonet.dll");
// Copy the other part of patch to game files
let alt_replaced = file_helpers::copy_file_with_new_name(
patch_path.clone().to_str().unwrap().to_string(),
get_game_rsa_path().await.unwrap() + &String::from("/GenshinImpact_Data/Plugins"),
String::from("mihoyonet.dll"),
);
// patch_path = PathBuf::from(system_helpers::install_location()).join("altpatch/mihoyonet.dll");
// // Copy the other part of patch to game files
// let alt_replaced = file_helpers::copy_file_with_new_name(
// patch_path.clone().to_str().unwrap().to_string(),
// get_game_rsa_path().await.unwrap() + &String::from("/GenshinImpact_Data/Plugins"),
// String::from("mihoyonet.dll"),
// );
if !alt_replaced {
return false;
}
// if !alt_replaced {
// return false;
// }
/*** For replacing old backup file with new one, for example when version changes
* Currently replaces when it shouldn't. Will figure it out when it matters
* ***/
// else {
// // Check if game file matches backup
// let matching_alt_backup = file_helpers::are_files_identical(
// &backup_path.clone(),
// PathBuf::from(get_game_rsa_path().await.unwrap())
// .join("/GenshinImpact_Data/Plugins/mihoyonet.dll")
// .to_str()
// .unwrap(),
// );
/*** For replacing old backup file with new one, for example when version changes
* Currently replaces when it shouldn't. Will figure it out when it matters
* ***/
// else {
// // Check if game file matches backup
// let matching_alt_backup = file_helpers::are_files_identical(
// &backup_path.clone(),
// PathBuf::from(get_game_rsa_path().await.unwrap())
// .join("/GenshinImpact_Data/Plugins/mihoyonet.dll")
// .to_str()
// .unwrap(),
// );
// let is_alt_patched = file_helpers::are_files_identical(
// PathBuf::from(system_helpers::install_location()).join("altpatch/mihoyonet.dll").to_str().unwrap(),
// PathBuf::from(get_game_rsa_path().await.unwrap())
// .join("/GenshinImpact_Data/Plugins/mihoyonet.dll")
// .to_str()
// .unwrap(),
// );
// let is_alt_patched = file_helpers::are_files_identical(
// PathBuf::from(system_helpers::install_location()).join("altpatch/mihoyonet.dll").to_str().unwrap(),
// PathBuf::from(get_game_rsa_path().await.unwrap())
// .join("/GenshinImpact_Data/Plugins/mihoyonet.dll")
// .to_str()
// .unwrap(),
// );
// // Check if already alt patched
// if !matching_alt_backup {
// // Copy new backup if it is not patched
// if !is_alt_patched {
// file_helpers::copy_file_with_new_name(
// get_game_rsa_path().await.unwrap() + &String::from("/GenshinImpact_Data/Plugins/mihoyonet.dll"),
// alt_patch_path.clone().to_str().unwrap().to_string(),
// String::from("original-mihoyonet.dll"),
// );
// }
// }
// }
}
// // Check if already alt patched
// if !matching_alt_backup {
// // Copy new backup if it is not patched
// if !is_alt_patched {
// file_helpers::copy_file_with_new_name(
// get_game_rsa_path().await.unwrap() + &String::from("/GenshinImpact_Data/Plugins/mihoyonet.dll"),
// alt_patch_path.clone().to_str().unwrap().to_string(),
// String::from("original-mihoyonet.dll"),
// );
// }
// }
// }
// }
// Standard patch
patch_path = PathBuf::from(system_helpers::install_location()).join("patch/version.dll");
@@ -152,8 +153,14 @@ pub async fn patch_game(newer_game: bool, version: String) -> bool {
return true;
}
// For 5.0 and up
// For 5.0 and up use universal
if i_ver > 49 {
if i_ver < 59 {
patch_path = PathBuf::from(system_helpers::install_location()).join("patch/5version.dll");
} else {
// 6.0 patch not checked/tested if works for old vers, so separate
patch_path = PathBuf::from(system_helpers::install_location()).join("patch/6version.dll");
}
let replaced50 = file_helpers::copy_file_with_new_name(
patch_path.clone().to_str().unwrap().to_string(),
get_game_rsa_path().await.unwrap(),
@@ -342,7 +349,7 @@ pub async fn unpatch_game() -> bool {
}
pub async fn get_game_rsa_path() -> Option<String> {
let config = config::get_config();
let config = config::get_config(String::from("default"));
config.game_install_path.as_ref()?;

View File

@@ -108,6 +108,18 @@ impl SpawnItsFineReally for Command {
}
}
#[tauri::command]
pub fn run_program_args(path: String, args: Option<String>) {
match open::with(
format!("{}", args.unwrap_or_else(|| "".into())),
path.clone(),
) {
Ok(_) => (),
Err(e) => println!("Failed to open program ({}): {}", &path, e),
};
return;
}
#[tauri::command]
pub fn run_program(path: String, args: Option<String>) {
// Without unwrap_or, this can crash when UAC prompt is denied

View File

@@ -7,7 +7,7 @@
},
"package": {
"productName": "Cultivation",
"version": "1.5.1"
"version": "1.7.2"
},
"tauri": {
"allowlist": {
@@ -67,11 +67,13 @@
"windows": [
{
"fullscreen": false,
"transparent": true,
"height": 730,
"resizable": true,
"title": "Cultivation",
"width": 1280,
"decorations": false
"decorations": false,
"center": true
}
]
}

View File

@@ -170,6 +170,8 @@ export class Main extends React.Component<IProps, IState> {
}
// Ensure old configs are updated to use RSA
const updatedProfile = await getConfigOption('profile')
await setConfigOption('profile', updatedProfile)
const updatedConfig = await getConfigOption('patch_rsa')
await setConfigOption('patch_rsa', updatedConfig)

View File

@@ -14,7 +14,7 @@
}
#playButton > div {
margin-bottom: 6px;
margin-bottom: 2px;
}
#playButton .BigButton {
@@ -26,10 +26,27 @@
#serverControls {
color: white;
display: flex;
justify-content: space-between;
flex-direction: row;
text-shadow: 1px 1px 8px black;
}
#menuOptionsContainerProfiles {
justify-self: right;
align-self: right;
padding-left: 8px;
width: min-content;
}
#serverControls select {
width: 150px;
height: 30px;
border: none;
border-bottom: 2px solid #cecece;
border-radius: 6px;
}
.BottomSection .CheckboxDisplay {
border-color: #c5c5c5;
background: #fff;

View File

@@ -3,7 +3,7 @@ import Checkbox from './common/Checkbox'
import BigButton from './common/BigButton'
import TextInput from './common/TextInput'
import HelpButton from './common/HelpButton'
import { getConfig, saveConfig, setConfigOption } from '../../utils/configuration'
import { getConfig, saveConfig, setConfigOption, setProfileOption } from '../../utils/configuration'
import { translate } from '../../utils/language'
import { invoke } from '@tauri-apps/api/tauri'
@@ -43,6 +43,8 @@ interface IState {
migotoSet: boolean
unElevated: boolean
profile: string
profiles: string[]
}
export default class ServerLaunchSection extends React.Component<IProps, IState> {
@@ -66,6 +68,8 @@ export default class ServerLaunchSection extends React.Component<IProps, IState>
akebiSet: false,
migotoSet: false,
unElevated: false,
profile: 'default',
profiles: ['default'],
}
this.toggleGrasscutter = this.toggleGrasscutter.bind(this)
@@ -75,6 +79,7 @@ export default class ServerLaunchSection extends React.Component<IProps, IState>
this.toggleHttps = this.toggleHttps.bind(this)
this.launchServer = this.launchServer.bind(this)
this.setButtonLabel = this.setButtonLabel.bind(this)
this.setProfile = this.setProfile.bind(this)
listen('start_grasscutter', async () => {
this.launchServer()
@@ -102,6 +107,8 @@ export default class ServerLaunchSection extends React.Component<IProps, IState>
akebiSet: config.akebi_path !== '',
migotoSet: config.migoto_path !== '',
unElevated: config.un_elevated || false,
profile: config.profile || 'default',
profiles: (await this.getProfileList()).map((t) => t),
})
this.setButtonLabel()
@@ -149,7 +156,7 @@ export default class ServerLaunchSection extends React.Component<IProps, IState>
// Connect to proxy
if (config.toggle_grasscutter) {
const game_exe = await getGameExecutable()
let newerGame = false
const newerGame = false
const patchable = game_exe?.toLowerCase().includes('yuanshen') || game_exe?.toLowerCase().includes('genshin')
@@ -183,35 +190,36 @@ export default class ServerLaunchSection extends React.Component<IProps, IState>
const versionString = gameVersion?.major.toString() + gameVersion?.minor.toString()
if ((gameVersion?.major == 4 && gameVersion?.minor > 5) || config.newer_game) {
newerGame = true
// Keeps being misused, remove for now.
// if ((gameVersion?.major == 4 && gameVersion?.minor > 5) || config.newer_game) {
// newerGame = true
const path = (await invoke('install_location')) as string
// const path = (await invoke('install_location')) as string
const patchstring = '\\altpatch\\'
const altPatch = path + patchstring
// const patchstring = '\\altpatch\\'
// const altPatch = path + patchstring
const ALT_PATCH =
'https://autopatchhk.yuanshen.com/client_app/download/pc_zip/20231030132335_iOEfPMcbrXpiA8Ca/ScatteredFiles/GenshinImpact_Data/Plugins/mihoyonet.dll'
const pExists = (await invoke('dir_exists', {
path: altPatch,
})) as boolean
// const ALT_PATCH =
// 'https://autopatchhk.yuanshen.com/client_app/download/pc_zip/20231030132335_iOEfPMcbrXpiA8Ca/ScatteredFiles/GenshinImpact_Data/Plugins/mihoyonet.dll'
// const pExists = (await invoke('dir_exists', {
// path: altPatch,
// })) as boolean
if (!pExists) {
await invoke('dir_create', {
path: altPatch,
})
this.props.downloadHandler.addDownload(ALT_PATCH, path + '/altpatch/mihoyonet.dll')
await confirm('Please wait for the download in the bottom left to disappear, then click yes')
}
// if (!pExists) {
// await invoke('dir_create', {
// path: altPatch,
// })
// this.props.downloadHandler.addDownload(ALT_PATCH, path + '/altpatch/mihoyonet.dll')
// await confirm('Please wait for the download in the bottom left to disappear, then click yes')
// }
/* For custom address patch only, used in 4.5 */
// let httpString = 'http://'
// if (this.state.httpsEnabled) {
// httpString = 'https://'
// }
// config.launch_args = '-server=' + httpString + this.state.ip + ':' + this.state.port
}
// /* For custom address patch only, used in 4.5 */
// // let httpString = 'http://'
// // if (this.state.httpsEnabled) {
// // httpString = 'https://'
// // }
// // config.launch_args = '-server=' + httpString + this.state.ip + ':' + this.state.port
// }
const patched = await patchGame(newerGame, versionString)
@@ -278,6 +286,13 @@ export default class ServerLaunchSection extends React.Component<IProps, IState>
if (config.launch_args.length < 1) {
// Run relative when there are no args
await invoke('run_program_relative', { path: exe || config.game_install_path })
}
// Handle XXMI
else if (proc_name?.toLowerCase().includes('xxmi')) {
await invoke('run_program_args', {
path: exe,
args: config.launch_args,
})
} else {
// Run directly when there are args
await invoke('run_program', {
@@ -385,6 +400,25 @@ export default class ServerLaunchSection extends React.Component<IProps, IState>
}
}
async setProfile(value: string) {
this.setState({ profile: value })
await setProfileOption('profile', value)
window.location.reload()
}
async getProfileList() {
const profiles: string[] = await invoke('get_profile_list', {
dataDir: `${await dataDir()}/cultivation`,
})
const list = ['default']
profiles.forEach((t) => {
list.push(t.split('.json')[0])
})
return list
}
render() {
return (
<div id="playButton">
@@ -395,6 +429,23 @@ export default class ServerLaunchSection extends React.Component<IProps, IState>
onChange={this.toggleGrasscutter}
checked={this.state.grasscutterEnabled}
/>
<div className="OptionSection" id="menuOptionsContainerProfiles">
<div className="OptionValue" id="menuOptionsSelectProfiles">
<select
value={this.state.profile}
id="menuOptionsSelectMenuProfiles"
onChange={(event) => {
this.setProfile(event.target.value)
}}
>
{this.state.profiles.map((t) => (
<option key={t} value={t}>
{t}
</option>
))}
</select>
</div>
</div>
</div>
{this.state.grasscutterEnabled && (

View File

@@ -16,7 +16,7 @@ import { ask } from '@tauri-apps/api/dialog'
const FULL_BUILD_DOWNLOAD = 'https://github.com/NotThorny/Grasscutter/releases/download/culti-aio/GrasscutterCulti.zip' // Change to link that can be updated without modifying here
const FULL_QUEST_DOWNLOAD = 'https://github.com/NotThorny/Grasscutter/releases/download/culti-aio/GrasscutterQuests.zip'
const FULL_50_DOWNLOAD = 'https://github.com/NotThorny/Grasscutter/releases/download/culti-aio/GrasscutterLunaGC50.zip' // https://github.com/Kei-Luna/LunaGC_5.0.0
const FULL_50_DOWNLOAD = 'https://github.com/NotThorny/Grasscutter/releases/download/culti-aio/GrasscutterLunaGC61.zip' // https://github.com/pmagixc/LunaGC_6.0.0
const STABLE_REPO_DOWNLOAD = 'https://github.com/Grasscutters/Grasscutter/archive/refs/heads/stable.zip'
const DEV_REPO_DOWNLOAD = 'https://github.com/Grasscutters/Grasscutter/archive/refs/heads/development.zip'
const UNSTABLE_DOWNLOAD = 'https://nightly.link/Grasscutters/Grasscutter/workflows/build/unstable/Grasscutter.zip'

View File

@@ -69,7 +69,10 @@ export class ExtrasMenu extends React.Component<IProps, IState> {
// This injects independent of the game
if (this.state.launch_migoto) {
await this.launchMigoto()
if (await this.launchMigoto()) {
// Already launched the game (ie. via XXMI)
return
}
}
// This injects independent of the game
@@ -104,7 +107,17 @@ export class ExtrasMenu extends React.Component<IProps, IState> {
if (!config.migoto_path) return alert('Migoto not installed or set!')
if (config.migoto_path?.toLowerCase().includes('xxmi')) {
// Get game exe from game path, so we can watch it
const pathArr = config.migoto_path.replace(/\\/g, '/').split('/')
const gameExec = pathArr[pathArr.length - 1]
this.props.playGame(config.migoto_path, gameExec)
return true
}
await invoke('run_program_relative', { path: config.migoto_path })
return false
}
async launchReshade() {

View File

@@ -20,3 +20,8 @@
.OptionSection .HelpButton img {
filter: invert(0%) sepia(91%) saturate(7464%) hue-rotate(101deg) brightness(0%) contrast(107%);
}
input#profile_name {
height: 25px;
border-radius: 6px;
}

View File

@@ -4,7 +4,14 @@ import { dataDir } from '@tauri-apps/api/path'
import DirInput from '../common/DirInput'
import Menu from './Menu'
import Tr, { getLanguages } from '../../../utils/language'
import { setConfigOption, getConfig, getConfigOption, Configuration } from '../../../utils/configuration'
import {
setConfigOption,
getConfig,
getConfigOption,
Configuration,
saveNewProfileConfig,
setProfileOption,
} from '../../../utils/configuration'
import Checkbox from '../common/Checkbox'
import Divider from './Divider'
import { getThemeList } from '../../../utils/themes'
@@ -57,6 +64,8 @@ interface IState {
launch_args: string
offline_mode: boolean
newer_game: boolean
show_version: boolean
profile_name: string
// Linux stuff
grasscutter_elevation: string
@@ -95,6 +104,8 @@ export default class Options extends React.Component<IProps, IState> {
launch_args: '',
offline_mode: false,
newer_game: false,
show_version: true,
profile_name: '',
// Linux stuff
grasscutter_elevation: GrasscutterElevation.None,
@@ -118,6 +129,9 @@ export default class Options extends React.Component<IProps, IState> {
this.addMigotoDelay = this.addMigotoDelay.bind(this)
this.toggleUnElevatedGame = this.toggleUnElevatedGame.bind(this)
this.setLaunchArgs = this.setLaunchArgs.bind(this)
this.toggleShowVersion = this.toggleShowVersion.bind(this)
this.setProfileName = this.setProfileName.bind(this)
this.saveProfile = this.saveProfile.bind(this)
}
async componentDidMount() {
@@ -156,6 +170,7 @@ export default class Options extends React.Component<IProps, IState> {
launch_args: config.launch_args,
offline_mode: config.offline_mode || false,
newer_game: config.newer_game || false,
show_version: config.show_version || false,
// Linux stuff
grasscutter_elevation: config.grasscutter_elevation || GrasscutterElevation.None,
@@ -350,6 +365,17 @@ export default class Options extends React.Component<IProps, IState> {
})
}
async toggleShowVersion() {
const changedVal = !(await getConfigOption('show_version'))
await setConfigOption('show_version', changedVal)
this.setState({
show_version: changedVal,
})
emit('set_config', { show_version: changedVal })
}
async setGCElevation(value: string) {
setConfigOption('grasscutter_elevation', value)
@@ -487,6 +513,28 @@ export default class Options extends React.Component<IProps, IState> {
})
}
setProfileName(text: string) {
this.setState({
profile_name: text,
})
}
async saveProfile() {
if (this.state.profile_name == '') {
alert('No name set')
return
}
const config = await getConfig()
await saveNewProfileConfig(config, this.state.profile_name)
await setProfileOption('profile', this.state.profile_name)
this.setState({
profile_name: '',
})
window.location.reload()
}
render() {
return (
<Menu closeFn={this.props.closeFn} className="Options" heading="Options">
@@ -659,6 +707,24 @@ export default class Options extends React.Component<IProps, IState> {
<Divider />
<div className="OptionSection" id="profileConfigContainer">
<div className="OptionLabel" id="menuOptionsLabelProfile">
<Tr text="options.save_profile" />
</div>
<TextInput
id="profile_name"
key="profile_name"
placeholder={'Profile name...'}
onChange={this.setProfileName}
initalValue={''}
/>
<BigButton onClick={this.saveProfile} id="saveProfile">
{'Save'}
</BigButton>
</div>
<Divider />
<div className="OptionSection" id="menuOptionsContainerGCWGame">
<div className="OptionLabel" id="menuOptionsLabelGCWDame">
<Tr text="options.grasscutter_with_game" />
@@ -711,17 +777,12 @@ export default class Options extends React.Component<IProps, IState> {
/>
</div>
</div>
<div className="OptionSection" id="menuOptionsContainerNewerGame">
<div className="OptionLabel" id="menuOptionsLabelNewerGame">
<Tr text="Patch Mihoyonet" />
<div className="OptionSection" id="menuOptionsContainerShowVer">
<div className="OptionLabel" id="menuOptionsLabelShowVer">
<Tr text="options.show_version" />
</div>
<div className="OptionValue" id="menuOptionsCheckboxNewerGame">
<Checkbox
onChange={() => this.toggleOption('newer_game')}
checked={this.state?.newer_game}
id="newerGame"
/>
<div className="OptionValue" id="menuOptionsButtonShowVer">
<Checkbox onChange={() => this.toggleShowVersion()} checked={this.state.show_version} id="showVer" />
</div>
</div>
@@ -823,25 +884,32 @@ export default class Options extends React.Component<IProps, IState> {
<Tr text="components.delete" />
</BigButton>
</div>
</div>
<div className="OptionSection" id="menuOptionsContainerLaunchArgs">
<div className="OptionLabel" id="menuOptionsLaunchArgs">
<Tr text="options.launch_args" />
</div>
<TextInput
id="launch_args"
key="launch_args"
placeholder={'-arg=value'}
onChange={this.setLaunchArgs}
value={this.state.launch_args}
/>
<div className="OptionValue" id="menuOptionsValueLaunchArgs">
<TextInput
id="launch_args"
key="launch_args"
placeholder={'-arg=value'}
onChange={this.setLaunchArgs}
value={this.state.launch_args}
/>
</div>
</div>
<div className="OptionLabel" id="menuOptionsLabelFixRes">
<Tr text="options.fix_res" />
</div>
<div className="OptionValue" id="menuOptionsButtonfixRes">
<BigButton onClick={this.fixRes} id="fixRes">
<Tr text="components.fix" />
</BigButton>
<div className="OptionSection" id="menuOptionsContainerFixRes">
<div className="OptionLabel" id="menuOptionsLabelFixRes">
<Tr text="options.fix_res" />
</div>
<div className="OptionValue" id="menuOptionsButtonfixRes">
<BigButton onClick={this.fixRes} id="fixRes">
<Tr text="components.fix" />
</BigButton>
</div>
</div>
</Menu>
)

View File

@@ -143,7 +143,7 @@ export default class NewsSection extends React.Component<IProps, IState> {
<tr>
<td>
Work in progress area! These numbers may be outdated, so please do not use them as reference. Latest
version: Grasscutter 1.7.4 - Cultivation 1.5.1
version: Grasscutter 1.7.4 (4.0) / Forks (6.1) - Cultivation 1.7.2
</td>
</tr>
)

View File

@@ -31,6 +31,8 @@ let defaultConfig: Configuration
launch_args: '',
offline_mode: false,
newer_game: false,
show_version: true,
profile: 'default',
// Linux stuff
grasscutter_elevation: 'None',
@@ -68,6 +70,8 @@ export interface Configuration {
launch_args: string
offline_mode: boolean
newer_game: boolean
show_version: boolean
profile: string
// Linux stuff
grasscutter_elevation: string
@@ -90,6 +94,15 @@ export async function setConfigOption<K extends keyof Configuration>(key: K, val
await saveConfig(<Configuration>config)
}
export async function setProfileOption<K extends keyof Configuration>(key: K, value: Configuration[K]): Promise<void> {
const config = await getConfig()
config[key] = value
const defaultConfig = await getDefaultConfig()
defaultConfig[key] = value
await saveProfileConfig(<Configuration>defaultConfig)
}
export async function getConfigOption<K extends keyof Configuration>(key: K): Promise<Configuration[K]> {
const config = await getConfig()
const defaults = defaultConfig
@@ -113,16 +126,82 @@ export async function getConfig() {
return parsed
}
export async function getDefaultConfig() {
const raw = await readDefaultConfigFile()
let parsed: Configuration = defaultConfig
try {
parsed = <Configuration>JSON.parse(raw)
} catch (e) {
// We could not open the file
console.log(e)
}
return parsed
}
export async function saveConfig(obj: Configuration) {
const raw = JSON.stringify(obj)
await writeConfigFile(raw)
}
export async function saveProfileConfig(obj: Configuration) {
const local = await dataDir()
const raw = JSON.stringify(obj)
const prevPath = configFilePath
configFilePath = local + 'cultivation/configuration.json'
await writeConfigFile(raw)
configFilePath = prevPath
}
export async function saveNewProfileConfig(obj: Configuration, prof: string) {
obj['profile'] = prof
const local = await dataDir()
const raw = JSON.stringify(obj)
configFilePath = local + 'cultivation/profiles/' + obj['profile'] + '.json'
const file: fs.FsTextFileOption = {
path: configFilePath,
contents: raw,
}
await fs.writeFile(file)
}
async function readConfigFile() {
const local = await dataDir()
if (!configFilePath) configFilePath = local + 'cultivation/configuration.json'
if (!configFilePath) {
configFilePath = local + 'cultivation/configuration.json'
}
const dataFiles = await fs.readDir(local + 'cultivation')
// Ensure config exists
if (!dataFiles.find((fileOrDir) => fileOrDir?.name === 'configuration.json')) {
// Create config file
const file: fs.FsTextFileOption = {
path: configFilePath,
contents: JSON.stringify(defaultConfig),
}
await fs.writeFile(file)
}
// Read existing config to get profile name
const raw = await fs.readTextFile(configFilePath)
const cfg = <Configuration>JSON.parse(raw)
// Switch file to config-specified profile
let pf = cfg['profile']
if (pf && pf != 'default') {
const pff = pf
pf = 'profiles/' + pff + '.json'
} else {
pf = 'configuration.json'
}
configFilePath = local + 'cultivation/' + pf
// Ensure Cultivation dir exists
const dirs = await fs.readDir(local)
@@ -140,23 +219,16 @@ async function readConfigFile() {
await fs.createDir(local + 'cultivation/grasscutter').catch((e) => console.log(e))
}
const dataFiles = await fs.readDir(local + 'cultivation')
// Ensure config exists
if (!dataFiles.find((fileOrDir) => fileOrDir?.name === 'configuration.json')) {
// Create config file
const file: fs.FsTextFileOption = {
path: configFilePath,
contents: JSON.stringify(defaultConfig),
}
await fs.writeFile(file)
}
// Finally, read the file
return await fs.readTextFile(configFilePath)
}
async function readDefaultConfigFile() {
const local = await dataDir()
configFilePath = local + 'cultivation/configuration.json'
return await fs.readTextFile(configFilePath)
}
async function writeConfigFile(raw: string) {
// All external config functions call readConfigFile, which ensure files exists
await fs.writeFile({

View File

@@ -109,25 +109,35 @@ export default class DownloadHandler {
downloadingJar() {
// Kinda hacky but it works
return this.downloads.some((d) => d.path.includes('grasscutter.zip') && d.status != ('finished' || 'error'))
return this.downloads.some(
(d) => d.path.includes('grasscutter.zip') && !(d.status.includes('finished') || d.status.includes('error'))
)
}
downloadingFullBuild() {
// Kinda hacky but it works
return this.downloads.some((d) => d.path.includes('GrasscutterCulti') && d.status != ('finished' || 'error'))
return this.downloads.some(
(d) => d.path.includes('GrasscutterCulti') && !(d.status.includes('finished') || d.status.includes('error'))
)
}
downloadingResources() {
// Kinda hacky but it works
return this.downloads.some((d) => d.path.includes('resources') && d.status != ('finished' || 'error'))
return this.downloads.some(
(d) => d.path.includes('resources') && !(d.status.includes('finished') || d.status.includes('error'))
)
}
downloadingRepo() {
return this.downloads.some((d) => d.path.includes('grasscutter_repo.zip') && d.status != ('finished' || 'error'))
return this.downloads.some(
(d) => d.path.includes('grasscutter_repo.zip') && !(d.status.includes('finished') || d.status.includes('error'))
)
}
downloadingMigoto() {
return this.downloads.some((d) => d.path.includes('3dmigoto') && d.status != ('finished' || 'error'))
return this.downloads.some(
(d) => d.path.includes('3dmigoto') && !(d.status.includes('finished') || d.status.includes('error'))
)
}
addDownload(url: string, path: string, onFinish?: () => void) {

View File

@@ -50,20 +50,34 @@ export async function getGameDataFolder() {
export async function getGameVersion() {
const GameData = await getGameDataFolder()
const platform = await invoke('get_platform')
if (!GameData) {
return null
}
const hasAsb = await invoke('dir_exists', {
let hasAsb = await invoke('dir_exists', {
path: GameData + '\\StreamingAssets\\asb_settings.json',
})
if (platform != 'windows') {
hasAsb = await invoke('dir_exists', {
path: GameData + '/StreamingAssets/asb_settings.json',
})
}
if (!hasAsb) {
// For games that cannot determine game version
const otherGameVer: string = await invoke('read_file', {
let otherGameVer: string = await invoke('read_file', {
path: GameData + '\\StreamingAssets\\BinaryVersion.bytes',
})
if (platform != 'windows') {
otherGameVer = await invoke('read_file', {
path: GameData + '/StreamingAssets/BinaryVersion.bytes',
})
}
const versionRaw = otherGameVer.split('.')
const version = {
major: parseInt(versionRaw[0]),

221
yarn.lock
View File

@@ -2938,21 +2938,21 @@ bluebird@^3.5.5:
resolved "https://registry.yarnpkg.com/bluebird/-/bluebird-3.7.2.tgz#9f229c15be272454ffa973ace0dbee79a1b0c36f"
integrity sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==
body-parser@1.20.3:
version "1.20.3"
resolved "https://registry.yarnpkg.com/body-parser/-/body-parser-1.20.3.tgz#1953431221c6fb5cd63c4b36d53fab0928e548c6"
integrity sha512-7rAxByjUMqQ3/bHJy7D6OGXvx/MMc4IqBn/X0fcM1QUcAItpZrBEYhWGem+tzXH90c+G01ypMcYJBO9Y30203g==
body-parser@1.20.0:
version "1.20.0"
resolved "https://registry.yarnpkg.com/body-parser/-/body-parser-1.20.0.tgz#3de69bd89011c11573d7bfee6a64f11b6bd27cc5"
integrity sha512-DfJ+q6EPcGKZD1QWUjSpqp+Q7bDQTsQIF4zfUAtZ6qk+H/3/QRhg9CEp39ss+/T2vw0+HaidC0ecJj/DRLIaKg==
dependencies:
bytes "3.1.2"
content-type "~1.0.5"
content-type "~1.0.4"
debug "2.6.9"
depd "2.0.0"
destroy "1.2.0"
http-errors "2.0.0"
iconv-lite "0.4.24"
on-finished "2.4.1"
qs "6.13.0"
raw-body "2.5.2"
qs "6.10.3"
raw-body "2.5.1"
type-is "~1.6.18"
unpipe "1.0.0"
@@ -3043,17 +3043,6 @@ call-bind@^1.0.0, call-bind@^1.0.2:
function-bind "^1.1.1"
get-intrinsic "^1.0.2"
call-bind@^1.0.7:
version "1.0.7"
resolved "https://registry.yarnpkg.com/call-bind/-/call-bind-1.0.7.tgz#06016599c40c56498c18769d2730be242b6fa3b9"
integrity sha512-GHTSNSYICQ7scH7sZ+M2rFopRoLh8t2bLSW6BbgrtLsahOIB5iyAVJf9GjWK3cYTDaMj4XdBpM1cA6pIS0Kv2w==
dependencies:
es-define-property "^1.0.0"
es-errors "^1.3.0"
function-bind "^1.1.2"
get-intrinsic "^1.2.4"
set-function-length "^1.2.1"
callsites@^3.0.0:
version "3.1.0"
resolved "https://registry.yarnpkg.com/callsites/-/callsites-3.1.0.tgz#b3630abd8943432f54b3f0519238e33cd7df2f73"
@@ -3358,11 +3347,6 @@ content-type@~1.0.4:
resolved "https://registry.yarnpkg.com/content-type/-/content-type-1.0.4.tgz#e138cc75e040c727b1966fe5e5f8c9aee256fe3b"
integrity sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA==
content-type@~1.0.5:
version "1.0.5"
resolved "https://registry.yarnpkg.com/content-type/-/content-type-1.0.5.tgz#8b773162656d1d1086784c8f23a54ce6d73d7918"
integrity sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==
convert-source-map@^1.4.0, convert-source-map@^1.6.0, convert-source-map@^1.7.0:
version "1.8.0"
resolved "https://registry.yarnpkg.com/convert-source-map/-/convert-source-map-1.8.0.tgz#f3373c32d21b4d780dd8004514684fb791ca4369"
@@ -3375,10 +3359,10 @@ cookie-signature@1.0.6:
resolved "https://registry.yarnpkg.com/cookie-signature/-/cookie-signature-1.0.6.tgz#e303a882b342cc3ee8ca513a79999734dab3ae2c"
integrity sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==
cookie@0.7.1:
version "0.7.1"
resolved "https://registry.yarnpkg.com/cookie/-/cookie-0.7.1.tgz#2f73c42142d5d5cf71310a74fc4ae61670e5dbc9"
integrity sha512-6DnInpx7SJ2AK3+CTUE/ZM0vWTUboZCegxhC2xiIydHR9jNuTAASBrfEpHhiGOZw/nX51bHt6YQl8jsGo4y/0w==
cookie@0.5.0:
version "0.5.0"
resolved "https://registry.yarnpkg.com/cookie/-/cookie-0.5.0.tgz#d1f5d71adec6558c58f389987c366aa47e994f8b"
integrity sha512-YZ3GUyn/o8gfKJlnlX7g7xq4gyO6OSuhGPKaaGssGB2qgDUS0gPgtTvoyZLTt9Ab6dC4hfc9dV5arkvc/OCmrw==
core-js-compat@^3.21.0, core-js-compat@^3.22.1:
version "3.23.5"
@@ -3717,15 +3701,6 @@ default-gateway@^6.0.3:
dependencies:
execa "^5.0.0"
define-data-property@^1.1.4:
version "1.1.4"
resolved "https://registry.yarnpkg.com/define-data-property/-/define-data-property-1.1.4.tgz#894dc141bb7d3060ae4366f6a0107e68fbe48c5e"
integrity sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==
dependencies:
es-define-property "^1.0.0"
es-errors "^1.3.0"
gopd "^1.0.1"
define-lazy-prop@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/define-lazy-prop/-/define-lazy-prop-2.0.0.tgz#3f7ae421129bcaaac9bc74905c98a0009ec9ee7f"
@@ -3989,11 +3964,6 @@ encodeurl@~1.0.2:
resolved "https://registry.yarnpkg.com/encodeurl/-/encodeurl-1.0.2.tgz#ad3ff4c86ec2d029322f5a02c3a9a606c95b3f59"
integrity sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==
encodeurl@~2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/encodeurl/-/encodeurl-2.0.0.tgz#7b8ea898077d7e409d3ac45474ea38eaf0857a58"
integrity sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg==
enhanced-resolve@^5.10.0:
version "5.12.0"
resolved "https://registry.yarnpkg.com/enhanced-resolve/-/enhanced-resolve-5.12.0.tgz#300e1c90228f5b570c4d35babf263f6da7155634"
@@ -4055,18 +4025,6 @@ es-array-method-boxes-properly@^1.0.0:
resolved "https://registry.yarnpkg.com/es-array-method-boxes-properly/-/es-array-method-boxes-properly-1.0.0.tgz#873f3e84418de4ee19c5be752990b2e44718d09e"
integrity sha512-wd6JXUmyHmt8T5a2xreUwKcGPq6f1f+WwIJkijUqiGcJz1qqnZgP6XIK+QyIWU5lT7imeNxUll48bziG+TSYcA==
es-define-property@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/es-define-property/-/es-define-property-1.0.0.tgz#c7faefbdff8b2696cf5f46921edfb77cc4ba3845"
integrity sha512-jxayLKShrEqqzJ0eumQbVhTYQM27CfT1T35+gCgDFoL82JLsXqTJ76zv6A0YLOgEnLUMvLzsDsGIrl8NFpT2gQ==
dependencies:
get-intrinsic "^1.2.4"
es-errors@^1.3.0:
version "1.3.0"
resolved "https://registry.yarnpkg.com/es-errors/-/es-errors-1.3.0.tgz#05f75a25dab98e4fb1dcd5e1472c0546d5057c8f"
integrity sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==
es-module-lexer@^0.9.0:
version "0.9.3"
resolved "https://registry.yarnpkg.com/es-module-lexer/-/es-module-lexer-0.9.3.tgz#6f13db00cc38417137daf74366f535c8eb438f19"
@@ -4445,36 +4403,36 @@ expect@^27.5.1:
jest-message-util "^27.5.1"
express@^4.17.3:
version "4.21.1"
resolved "https://registry.yarnpkg.com/express/-/express-4.21.1.tgz#9dae5dda832f16b4eec941a4e44aa89ec481b281"
integrity sha512-YSFlK1Ee0/GC8QaO91tHcDxJiE/X4FbpAyQWkxAvG6AXCuR65YzK8ua6D9hvi/TzUfZMpc+BwuM1IPw8fmQBiQ==
version "4.18.1"
resolved "https://registry.yarnpkg.com/express/-/express-4.18.1.tgz#7797de8b9c72c857b9cd0e14a5eea80666267caf"
integrity sha512-zZBcOX9TfehHQhtupq57OF8lFZ3UZi08Y97dwFCkD8p9d/d2Y3M+ykKcwaMDEL+4qyUolgBDX6AblpR3fL212Q==
dependencies:
accepts "~1.3.8"
array-flatten "1.1.1"
body-parser "1.20.3"
body-parser "1.20.0"
content-disposition "0.5.4"
content-type "~1.0.4"
cookie "0.7.1"
cookie "0.5.0"
cookie-signature "1.0.6"
debug "2.6.9"
depd "2.0.0"
encodeurl "~2.0.0"
encodeurl "~1.0.2"
escape-html "~1.0.3"
etag "~1.8.1"
finalhandler "1.3.1"
finalhandler "1.2.0"
fresh "0.5.2"
http-errors "2.0.0"
merge-descriptors "1.0.3"
merge-descriptors "1.0.1"
methods "~1.1.2"
on-finished "2.4.1"
parseurl "~1.3.3"
path-to-regexp "0.1.10"
path-to-regexp "0.1.7"
proxy-addr "~2.0.7"
qs "6.13.0"
qs "6.10.3"
range-parser "~1.2.1"
safe-buffer "5.2.1"
send "0.19.0"
serve-static "1.16.2"
send "0.18.0"
serve-static "1.15.0"
setprototypeof "1.2.0"
statuses "2.0.1"
type-is "~1.6.18"
@@ -4562,13 +4520,13 @@ fill-range@^7.0.1:
dependencies:
to-regex-range "^5.0.1"
finalhandler@1.3.1:
version "1.3.1"
resolved "https://registry.yarnpkg.com/finalhandler/-/finalhandler-1.3.1.tgz#0c575f1d1d324ddd1da35ad7ece3df7d19088019"
integrity sha512-6BN9trH7bp3qvnrRyzsBz+g3lZxTNZTbVO2EV1CS0WIcDbawYVdYvGflME/9QP0h0pYlCDBCTjYa9nZzMDpyxQ==
finalhandler@1.2.0:
version "1.2.0"
resolved "https://registry.yarnpkg.com/finalhandler/-/finalhandler-1.2.0.tgz#7d23fe5731b207b4640e4fcd00aec1f9207a7b32"
integrity sha512-5uXcUVftlQMFnWC9qu/svkWv3GTd2PfUhK/3PLkYNAe7FbqJMt3515HaxE6eRL74GdsriiwujiawdaB1BpEISg==
dependencies:
debug "2.6.9"
encodeurl "~2.0.0"
encodeurl "~1.0.2"
escape-html "~1.0.3"
on-finished "2.4.1"
parseurl "~1.3.3"
@@ -4714,11 +4672,6 @@ function-bind@^1.1.1:
resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.1.tgz#a56899d3ea3c9bab874bb9773b7c5ede92f4895d"
integrity sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==
function-bind@^1.1.2:
version "1.1.2"
resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.2.tgz#2c02d864d97f3ea6c8830c464cbd11ab6eab7a1c"
integrity sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==
function.prototype.name@^1.1.5:
version "1.1.5"
resolved "https://registry.yarnpkg.com/function.prototype.name/-/function.prototype.name-1.1.5.tgz#cce0505fe1ffb80503e6f9e46cc64e46a12a9621"
@@ -4758,17 +4711,6 @@ get-intrinsic@^1.0.2, get-intrinsic@^1.1.0, get-intrinsic@^1.1.1:
has "^1.0.3"
has-symbols "^1.0.3"
get-intrinsic@^1.1.3, get-intrinsic@^1.2.4:
version "1.2.4"
resolved "https://registry.yarnpkg.com/get-intrinsic/-/get-intrinsic-1.2.4.tgz#e385f5a4b5227d449c3eabbad05494ef0abbeadd"
integrity sha512-5uYhsJH8VJBTv7oslg4BznJYhDoRI6waYCxMmCdnTrcCrHA/fCFKoTFz2JKKE0HdDFUF7/oQuhzumXJK7paBRQ==
dependencies:
es-errors "^1.3.0"
function-bind "^1.1.2"
has-proto "^1.0.1"
has-symbols "^1.0.3"
hasown "^2.0.0"
get-own-enumerable-property-symbols@^3.0.0:
version "3.0.2"
resolved "https://registry.yarnpkg.com/get-own-enumerable-property-symbols/-/get-own-enumerable-property-symbols-3.0.2.tgz#b5fde77f22cbe35f390b4e089922c50bce6ef664"
@@ -4863,13 +4805,6 @@ globby@^11.0.4, globby@^11.1.0:
merge2 "^1.4.1"
slash "^3.0.0"
gopd@^1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/gopd/-/gopd-1.0.1.tgz#29ff76de69dac7489b7c0918a5788e56477c332c"
integrity sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==
dependencies:
get-intrinsic "^1.1.3"
graceful-fs@^4.1.2, graceful-fs@^4.1.6, graceful-fs@^4.2.0, graceful-fs@^4.2.4, graceful-fs@^4.2.6, graceful-fs@^4.2.9:
version "4.2.10"
resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.10.tgz#147d3a006da4ca3ce14728c7aefc287c367d7a6c"
@@ -4914,18 +4849,6 @@ has-property-descriptors@^1.0.0:
dependencies:
get-intrinsic "^1.1.1"
has-property-descriptors@^1.0.2:
version "1.0.2"
resolved "https://registry.yarnpkg.com/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz#963ed7d071dc7bf5f084c5bfbe0d1b6222586854"
integrity sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==
dependencies:
es-define-property "^1.0.0"
has-proto@^1.0.1:
version "1.0.3"
resolved "https://registry.yarnpkg.com/has-proto/-/has-proto-1.0.3.tgz#b31ddfe9b0e6e9914536a6ab286426d0214f77fd"
integrity sha512-SJ1amZAJUiZS+PhsVLf5tGydlaVB8EdFpaSO4gmiUKUOxk8qzn5AIy4ZeJUmh22znIdk/uMAUT2pl3FxzVUH+Q==
has-symbols@^1.0.1, has-symbols@^1.0.2, has-symbols@^1.0.3:
version "1.0.3"
resolved "https://registry.yarnpkg.com/has-symbols/-/has-symbols-1.0.3.tgz#bb7b2c4349251dce87b125f7bdf874aa7c8b39f8"
@@ -4945,13 +4868,6 @@ has@^1.0.3:
dependencies:
function-bind "^1.1.1"
hasown@^2.0.0:
version "2.0.2"
resolved "https://registry.yarnpkg.com/hasown/-/hasown-2.0.2.tgz#003eaf91be7adc372e84ec59dc37252cedb80003"
integrity sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==
dependencies:
function-bind "^1.1.2"
he@^1.2.0:
version "1.2.0"
resolved "https://registry.yarnpkg.com/he/-/he-1.2.0.tgz#84ae65fa7eafb165fddb61566ae14baf05664f0f"
@@ -6343,10 +6259,10 @@ memfs@^3.1.2, memfs@^3.4.3:
dependencies:
fs-monkey "^1.0.3"
merge-descriptors@1.0.3:
version "1.0.3"
resolved "https://registry.yarnpkg.com/merge-descriptors/-/merge-descriptors-1.0.3.tgz#d80319a65f3c7935351e5cfdac8f9318504dbed5"
integrity sha512-gaNvAS7TZ897/rVaZ0nMtAyxNyi/pdbjbAwUpFQpN70GqnVfOiXpeUUMKRBmzXaSQ8DdTX4/0ms62r2K+hE6mQ==
merge-descriptors@1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/merge-descriptors/-/merge-descriptors-1.0.1.tgz#b00aaa556dd8b44568150ec9d1b953f3f90cbb61"
integrity sha512-cCi6g3/Zr1iqQi6ySbseM1Xvooa98N0w31jzUYrXPX2xqObmFGHJ0tQ5u74H3mVh7wLouTseZyYIq39g8cNp1w==
merge-stream@^2.0.0:
version "2.0.0"
@@ -6577,11 +6493,6 @@ object-inspect@^1.12.0, object-inspect@^1.12.2, object-inspect@^1.9.0:
resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.12.2.tgz#c0641f26394532f28ab8d796ab954e43c009a8ea"
integrity sha512-z+cPxW0QGUp0mcqcsgQyLVRDoXFQbXOwBaqyF7VIgI4TWNQsDHrBpUQslRmIfAoYWdYzs6UlKJtB2XJpTaNSpQ==
object-inspect@^1.13.1:
version "1.13.2"
resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.13.2.tgz#dea0088467fb991e67af4058147a24824a3043ff"
integrity sha512-IRZSRuzJiynemAXPYtPe5BoI/RESNYR7TYm50MC5Mqbd3Jmw5y790sErYw3V6SryFJD64b74qQQs9wn5Bg/k3g==
object-keys@^1.1.1:
version "1.1.1"
resolved "https://registry.yarnpkg.com/object-keys/-/object-keys-1.1.1.tgz#1c47f272df277f3b1daf061677d9c82e2322c60e"
@@ -6860,10 +6771,10 @@ path-parse@^1.0.7:
resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.7.tgz#fbc114b60ca42b30d9daf5858e4bd68bbedb6735"
integrity sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==
path-to-regexp@0.1.10:
version "0.1.10"
resolved "https://registry.yarnpkg.com/path-to-regexp/-/path-to-regexp-0.1.10.tgz#67e9108c5c0551b9e5326064387de4763c4d5f8b"
integrity sha512-7lf7qcQidTku0Gu3YDPc8DJ1q7OOucfa/BSsIwjuh56VU7katFvuM8hULfkwB3Fns/rsVF7PwPKVw1sl5KQS9w==
path-to-regexp@0.1.7:
version "0.1.7"
resolved "https://registry.yarnpkg.com/path-to-regexp/-/path-to-regexp-0.1.7.tgz#df604178005f522f15eb4490e7247a1bfaa67f8c"
integrity sha512-5DFkuoqlv1uYQKxy8omFBeJPQcdoE07Kv2sferDCrAq1ohOU+MSDswDIbnx3YAM60qIOnYa53wBhXW0EbMonrQ==
path-type@^4.0.0:
version "4.0.0"
@@ -7568,12 +7479,12 @@ q@^1.1.2:
resolved "https://registry.yarnpkg.com/q/-/q-1.5.1.tgz#7e32f75b41381291d04611f1bf14109ac00651d7"
integrity sha512-kV/CThkXo6xyFEZUugw/+pIOywXcDbFYgSct5cT3gqlbkBE1SJdwy6UQoZvodiWF/ckQLZyDE/Bu1M6gVu5lVw==
qs@6.13.0:
version "6.13.0"
resolved "https://registry.yarnpkg.com/qs/-/qs-6.13.0.tgz#6ca3bd58439f7e245655798997787b0d88a51906"
integrity sha512-+38qI9SOr8tfZ4QmJNplMUxqjbe7LKvvZgWdExBOmd+egZTtjLB67Gu0HRX3u/XOq7UU2Nx6nsjvS16Z9uwfpg==
qs@6.10.3:
version "6.10.3"
resolved "https://registry.yarnpkg.com/qs/-/qs-6.10.3.tgz#d6cde1b2ffca87b5aa57889816c5f81535e22e8e"
integrity sha512-wr7M2E0OFRfIfJZjKGieI8lBKb7fRCH4Fv5KNPEs7gJ8jadvotdsS08PzOKR7opXhZ/Xkjtt3WF9g38drmyRqQ==
dependencies:
side-channel "^1.0.6"
side-channel "^1.0.4"
querystringify@^2.1.1:
version "2.2.0"
@@ -7609,10 +7520,10 @@ range-parser@^1.2.1, range-parser@~1.2.1:
resolved "https://registry.yarnpkg.com/range-parser/-/range-parser-1.2.1.tgz#3cf37023d199e1c24d1a55b84800c2f3e6468031"
integrity sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==
raw-body@2.5.2:
version "2.5.2"
resolved "https://registry.yarnpkg.com/raw-body/-/raw-body-2.5.2.tgz#99febd83b90e08975087e8f1f9419a149366b68a"
integrity sha512-8zGqypfENjCIqGhgXToC8aB2r7YrBX+AQAfIPs/Mlk+BtPTztOvTS01NRW/3Eh60J+a48lt8qsCzirQ6loCVfA==
raw-body@2.5.1:
version "2.5.1"
resolved "https://registry.yarnpkg.com/raw-body/-/raw-body-2.5.1.tgz#fe1b1628b181b700215e5fd42389f98b71392857"
integrity sha512-qqJBtEyVgS0ZmPGdCFPWJ3FreoqvG4MVQln/kCgF7Olq95IbOp0/BWyMwbdtn4VTvkM8Y7khCQ2Xgk/tcrCXig==
dependencies:
bytes "3.1.2"
http-errors "2.0.0"
@@ -8135,10 +8046,10 @@ semver@^7.3.2, semver@^7.3.5, semver@^7.3.7:
dependencies:
lru-cache "^6.0.0"
send@0.19.0:
version "0.19.0"
resolved "https://registry.yarnpkg.com/send/-/send-0.19.0.tgz#bbc5a388c8ea6c048967049dbeac0e4a3f09d7f8"
integrity sha512-dW41u5VfLXu8SJh5bwRmyYUbAoSB3c9uQh6L8h/KtsFREPWpbX1lrljJo186Jc4nmci/sGUZ9a0a0J2zgfq2hw==
send@0.18.0:
version "0.18.0"
resolved "https://registry.yarnpkg.com/send/-/send-0.18.0.tgz#670167cc654b05f5aa4a767f9113bb371bc706be"
integrity sha512-qqWzuOjSFOuqPjFe4NOsMLafToQQwBSOEpS+FwEt3A2V3vKubTquT3vmLTQpFgMXp8AlFWFuP1qKaJZOtPpVXg==
dependencies:
debug "2.6.9"
depd "2.0.0"
@@ -8181,27 +8092,15 @@ serve-index@^1.9.1:
mime-types "~2.1.17"
parseurl "~1.3.2"
serve-static@1.16.2:
version "1.16.2"
resolved "https://registry.yarnpkg.com/serve-static/-/serve-static-1.16.2.tgz#b6a5343da47f6bdd2673848bf45754941e803296"
integrity sha512-VqpjJZKadQB/PEbEwvFdO43Ax5dFBZ2UECszz8bQ7pi7wt//PWe1P6MN7eCnjsatYtBT6EuiClbjSWP2WrIoTw==
serve-static@1.15.0:
version "1.15.0"
resolved "https://registry.yarnpkg.com/serve-static/-/serve-static-1.15.0.tgz#faaef08cffe0a1a62f60cad0c4e513cff0ac9540"
integrity sha512-XGuRDNjXUijsUL0vl6nSD7cwURuzEgglbOaFuZM9g3kwDXOWVTck0jLzjPzGD+TazWbboZYu52/9/XPdUgne9g==
dependencies:
encodeurl "~2.0.0"
encodeurl "~1.0.2"
escape-html "~1.0.3"
parseurl "~1.3.3"
send "0.19.0"
set-function-length@^1.2.1:
version "1.2.2"
resolved "https://registry.yarnpkg.com/set-function-length/-/set-function-length-1.2.2.tgz#aac72314198eaed975cf77b2c3b6b880695e5449"
integrity sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==
dependencies:
define-data-property "^1.1.4"
es-errors "^1.3.0"
function-bind "^1.1.2"
get-intrinsic "^1.2.4"
gopd "^1.0.1"
has-property-descriptors "^1.0.2"
send "0.18.0"
setprototypeof@1.1.0:
version "1.1.0"
@@ -8239,16 +8138,6 @@ side-channel@^1.0.4:
get-intrinsic "^1.0.2"
object-inspect "^1.9.0"
side-channel@^1.0.6:
version "1.0.6"
resolved "https://registry.yarnpkg.com/side-channel/-/side-channel-1.0.6.tgz#abd25fb7cd24baf45466406b1096b7831c9215f2"
integrity sha512-fDW/EZ6Q9RiO8eFG8Hj+7u/oW+XrPTIChwCOM2+th2A6OblDtYYIpve9m+KvI9Z4C9qSEXlaGR6bTEYHReuglA==
dependencies:
call-bind "^1.0.7"
es-errors "^1.3.0"
get-intrinsic "^1.2.4"
object-inspect "^1.13.1"
signal-exit@^3.0.2, signal-exit@^3.0.3, signal-exit@^3.0.7:
version "3.0.7"
resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.7.tgz#a9a1767f8af84155114eaabd73f99273c8f59ad9"