Update launcher to support up-coming new texture_replacement format (#494)

Didn't bother trying to make this backwards compatible, texture packs
will need to update, and users will need to update the launcher and
tooling to the latest version. It would be too annoying to make this
fully non-breaking (ie. people update their tooling but not the launcher
or vise-versa). Not worth the effort.

Release once 0.2.13 is out, this has been tested end-to-end:
![Screenshot 2024-05-30
212348](https://github.com/open-goal/launcher/assets/13153231/2765059a-c414-4f1b-bbfb-0a8470907bac)
![Screenshot 2024-05-30
212539](https://github.com/open-goal/launcher/assets/13153231/62346158-f498-4793-8cb8-c2529722e495)
![Screenshot 2024-05-30
212402](https://github.com/open-goal/launcher/assets/13153231/f6df5a8f-d807-4960-b10a-362837fed514)
This commit is contained in:
Tyler Wilding 2024-05-30 21:45:05 -04:00 committed by GitHub
parent 45e8b8311d
commit 4e09bc805a
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
7 changed files with 1021 additions and 945 deletions

View file

@ -472,3 +472,32 @@ pub async fn get_playtime(
))),
}
}
#[tauri::command]
pub async fn does_active_tooling_version_meet_minimum(
config: tauri::State<'_, tokio::sync::Mutex<LauncherConfig>>,
minimum_patch: u64,
minimum_minor: u64,
minimum_major: u64,
) -> Result<bool, CommandError> {
let config_lock = config.lock().await;
match &config_lock.active_version {
Some(version) => {
// If we can't determine the version, assume 0,0,0
let tooling_version = Version::parse(version.strip_prefix('v').unwrap_or(&version))
.unwrap_or(Version::new(0, 0, 0));
if tooling_version.patch >= minimum_patch
&& tooling_version.minor >= minimum_minor
&& tooling_version.major >= minimum_major
{
Ok(true)
} else {
Ok(false)
}
}
None => {
log::warn!("No active tooling version set, can't check if the minimum!");
Ok(false)
}
}
}

View file

@ -88,6 +88,8 @@ pub async fn list_extracted_texture_pack_info(
let mut file_list = Vec::new();
for entry in glob::glob(
&entry_path
.join("custom_assets")
.join(&game_name)
.join("texture_replacements/**/*.png")
.to_string_lossy(),
)
@ -96,7 +98,12 @@ pub async fn list_extracted_texture_pack_info(
match entry {
Ok(path) => {
let relative_path = path
.strip_prefix(&entry_path.join("texture_replacements"))
.strip_prefix(
&entry_path
.join("custom_assets")
.join(&game_name)
.join("texture_replacements"),
)
.map_err(|_| {
CommandError::GameFeatures(format!(
"Unable to read texture packs from {}",
@ -178,7 +185,7 @@ pub async fn extract_new_texture_pack(
Some(path) => Path::new(path),
};
// First, we'll check the zip file to make sure it has a `texture_replacements` folder before extracting
// First, we'll check the zip file to make sure it has a `custom_assets/<game>/texture_replacements` folder before extracting
let zip_path_buf = PathBuf::from(zip_path);
let texture_pack_name = match zip_path_buf.file_stem() {
Some(name) => name.to_string_lossy().to_string(),
@ -188,15 +195,18 @@ pub async fn extract_new_texture_pack(
));
}
};
let expected_top_level_dir = format!("custom_assets/{}/texture_replacements", &game_name);
let valid_zip =
check_if_zip_contains_top_level_dir(&zip_path_buf, "texture_replacements".to_string())
.map_err(|err| {
check_if_zip_contains_top_level_dir(&zip_path_buf, expected_top_level_dir.clone()).map_err(
|err| {
log::error!("Unable to read texture replacement zip file: {}", err);
CommandError::GameFeatures(format!("Unable to read texture replacement pack: {}", err))
})?;
},
)?;
if !valid_zip {
log::error!(
"Invalid texture pack, no top-level `texture_replacements` folder: {}",
"Invalid texture pack, no top-level `{}` folder in: {}",
&expected_top_level_dir,
zip_path_buf.display()
);
return Ok(false);
@ -250,6 +260,8 @@ pub async fn update_texture_pack_data(
.join("active")
.join(&game_name)
.join("data")
.join("custom_assets")
.join(&game_name)
.join("texture_replacements");
// Reset texture replacement directory
delete_dir(&game_texture_pack_dir)?;
@ -264,6 +276,8 @@ pub async fn update_texture_pack_data(
.join(&game_name)
.join("texture-packs")
.join(&pack)
.join("custom_assets")
.join(&game_name)
.join("texture_replacements");
log::info!("Appending textures from: {}", texture_pack_dir.display());
match overwrite_dir(&texture_pack_dir, &game_texture_pack_dir) {

View file

@ -161,6 +161,7 @@ fn main() {
commands::config::get_installed_version,
commands::config::get_locale,
commands::config::get_playtime,
commands::config::does_active_tooling_version_meet_minimum,
commands::config::has_old_data_directory,
commands::config::is_avx_requirement_met,
commands::config::is_diskspace_requirement_met,

View file

@ -1,3 +1,4 @@
use log::info;
use std::io::{BufReader, Cursor};
use std::path::PathBuf;
use std::{
@ -122,6 +123,7 @@ pub fn check_if_zip_contains_top_level_dir(
for i in 0..zip.len() {
let file = zip.by_index(i)?;
// Check if the entry is a directory and has the desired folder name
info!("{}", file.name());
if file.name().starts_with(&expected_dir) {
return Ok(true);
}

View file

@ -9,7 +9,7 @@
"features_textures_description": "You can enable as many packs as you want, but if multiple packs replace the same file the order matters. For example if two packs replace the grass, the first pack in the list will take precedence.",
"features_textures_disabled": "Disabled",
"features_textures_enabled": "Enabled",
"features_textures_invalidPack": "Invalid texture pack format, ensure it contains a top-level `texture_replacements` folder.",
"features_textures_invalidPack": "Invalid texture pack format, ensure it contains the correct top-level folder and valid metadata.",
"features_textures_listHeading": "Currently Added Packs",
"features_textures_moveDown_buttonAlt": "move texture pack down in order",
"features_textures_moveUp_buttonAlt": "move texture pack up in order",
@ -23,6 +23,7 @@
"gameControls_button_decompile_helpText": "Extracts game assets (ie. to apply texture replacements)",
"gameControls_button_decompile": "Decompile",
"gameControls_button_features_textures": "Texture Packs",
"gameControls_button_features_textures_disabled": "Texture pack feature disabled, update your launcher and tooling version",
"gameControls_button_features": "Features",
"gameControls_button_openREPL": "Open REPL",
"gameControls_button_openSavesFolder": "Open Saves Folder",

View file

@ -13,11 +13,15 @@
DropdownItem,
DropdownDivider,
Helper,
Tooltip,
} from "flowbite-svelte";
import { resetGameSettings, uninstallGame } from "$lib/rpc/game";
import { platform } from "@tauri-apps/api/os";
import { getLaunchGameString, launchGame, openREPL } from "$lib/rpc/binaries";
import { getPlaytime } from "$lib/rpc/config";
import {
doesActiveToolingVersionMeetMinimum,
getPlaytime,
} from "$lib/rpc/config";
import { _ } from "svelte-i18n";
import { navigate } from "svelte-navigator";
import { listen } from "@tauri-apps/api/event";
@ -35,6 +39,7 @@
let isLinux = false;
let playtime = "";
let modSupportEnabled = false;
let textureSupportEnabled = true;
onMount(async () => {
modSupportEnabled = await isModSupportEanbled();
@ -58,6 +63,8 @@
playtime = formatPlaytime(result);
});
}
textureSupportEnabled = await doesActiveToolingVersionMeetMinimum(0, 2, 13);
});
// format the time from the settings file which is stored as seconds
@ -152,12 +159,18 @@
>
<Dropdown placement="top-end" class="!bg-slate-900">
<DropdownItem
disabled={!textureSupportEnabled}
on:click={async () => {
navigate(`/${getInternalName(activeGame)}/features/texture_packs`);
}}
>
{$_("gameControls_button_features_textures")}
</DropdownItem>
{#if !textureSupportEnabled}
<Tooltip
>{$_("gameControls_button_features_textures_disabled")}</Tooltip
>
{/if}
{#if modSupportEnabled}
<DropdownItem
on:click={async () => {

View file

@ -274,3 +274,19 @@ export async function doesActiveToolingVersionSupportGame(
export async function getPlaytime(gameName: string): Promise<number> {
return await invoke_rpc("get_playtime", { gameName: gameName }, () => 0);
}
export async function doesActiveToolingVersionMeetMinimum(
minimumMajor: number,
minimumMinor: number,
minimumPatch: number,
): Promise<boolean> {
return await invoke_rpc(
"does_active_tooling_version_meet_minimum",
{
minimumPatch: minimumPatch,
minimumMinor: minimumMinor,
minimumMajor: minimumMajor,
},
() => false,
);
}