Several changes

- updated core library; now launcher will continue downloading
  of partially downloaded files
- added downloading speed limiter (`config.json` -> `launcher.speed_limit`)
- added `Config::try_get_selected_dxvk_info` method;
  now launcher loads currently applied dxvk version from the wine prefix files
This commit is contained in:
Observer KRypt0n_ 2022-09-08 17:27:37 +02:00
parent 79d63a174e
commit 57c36ae52d
No known key found for this signature in database
GPG key ID: 844DA47BA25FE1E2
12 changed files with 89 additions and 45 deletions

2
Cargo.lock generated
View file

@ -31,7 +31,7 @@ dependencies = [
[[package]]
name = "anime-game-core"
version = "0.5.2"
version = "1.0.2"
dependencies = [
"anyhow",
"bzip2",

@ -1 +1 @@
Subproject commit 2206e00a963a3e1421a9d45d8f71f32a5c9b7acb
Subproject commit 12541266d567f3459430ba37e12b0d809d12733d

@ -1 +1 @@
Subproject commit 59283a76adc8d270ff5f67b630b7dfa905ec34a9
Subproject commit 6ad1433587fa487e0d72c545178a61f8961c3b21

View file

@ -5,8 +5,7 @@ use crate::lib::consts::launcher_dir;
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct Dxvk {
pub builds: String,
pub selected: Option<String>
pub builds: String
}
impl Default for Dxvk {
@ -14,8 +13,7 @@ impl Default for Dxvk {
let launcher_dir = launcher_dir().expect("Failed to get launcher dir");
Self {
builds: format!("{launcher_dir}/dxvks"),
selected: None
builds: format!("{launcher_dir}/dxvks")
}
}
}
@ -28,20 +26,6 @@ impl From<&JsonValue> for Dxvk {
builds: match value.get("builds") {
Some(value) => value.as_str().unwrap_or(&default.builds).to_string(),
None => default.builds
},
selected: match value.get("selected") {
Some(value) => {
if value.is_null() {
None
} else {
match value.as_str() {
Some(value) => Some(value.to_string()),
None => default.selected
}
}
},
None => default.selected
}
}
}

View file

@ -63,6 +63,7 @@ impl From<CoreGameEdition> for GameEdition {
pub struct Launcher {
pub language: String,
pub temp: Option<String>,
pub speed_limit: u64,
pub repairer: Repairer,
pub edition: GameEdition
}
@ -72,6 +73,7 @@ impl Default for Launcher {
Self {
language: String::from("en-us"),
temp: launcher_dir(),
speed_limit: 0,
repairer: Repairer::default(),
edition: GameEdition::default()
}
@ -102,6 +104,11 @@ impl From<&JsonValue> for Launcher {
None => default.temp
},
speed_limit: match value.get("speed_limit") {
Some(value) => value.as_u64().unwrap_or(default.speed_limit),
None => default.speed_limit
},
repairer: match value.get("repairer") {
Some(value) => Repairer::from(value),
None => default.repairer

View file

@ -12,6 +12,10 @@ use super::wine::{
Version as WineVersion,
List as WineList
};
use super::dxvk::{
Version as DxvkVersion,
List as DxvkList
};
pub mod launcher;
pub mod game;
@ -135,15 +139,10 @@ impl Config {
pub fn try_get_selected_wine_info(&self) -> Option<WineVersion> {
match &self.game.wine.selected {
Some(selected) => {
for group in WineList::get() {
for version in group.versions {
if &version.name == selected {
return Some(version.clone());
}
}
}
None
WineList::get().iter()
.flat_map(|group| group.versions.clone())
.filter(|version| version.name.eq(selected))
.next()
},
None => None
}
@ -166,6 +165,34 @@ impl Config {
}
}
}
/// Try to get DXVK version applied to wine prefix
///
/// Returns:
/// 1) `Ok(Some(..))` if version was found
/// 2) `Ok(None)` if version wasn't found, so too old or dxvk is not applied
/// 3) `Err(..)` if failed to get applied dxvk version, likely because wrong prefix path specified
pub fn try_get_selected_dxvk_info(&self) -> std::io::Result<Option<DxvkVersion>> {
let bytes = match std::fs::read(format!("{}/drive_c/windows/system32/dxgi.dll", &self.game.wine.prefix)) {
Ok(bytes) => bytes[1600000..1700000].to_vec(),
Err(_) => std::fs::read(format!("{}/drive_c/windows/system32/d3d11.dll", &self.game.wine.prefix))?[2400000..2500000].to_vec()
};
Ok({
DxvkList::get()
.iter()
.flat_map(|group| group.versions.clone())
.filter(|version| {
let version = format!("\0v{}\0", &version.version);
let version = version.as_bytes();
bytes.windows(version.len())
.position(|window| window == version)
.is_some()
})
.next()
})
}
}
impl From<&JsonValue> for Config {

View file

@ -62,7 +62,7 @@ pub struct Group {
pub versions: Vec<Version>
}
#[derive(Debug, Clone, Serialize, Deserialize)]
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct Version {
pub name: String,
pub version: String,

View file

@ -132,8 +132,8 @@ pub fn run(debug: bool) -> std::io::Result<()> {
command.env("WINEPREFIX", &config.game.wine.prefix);
// Add DXVK_ASYNC=1 for dxvk-async builds automatically
if let Some(dxvk) = &config.game.dxvk.selected {
if dxvk.contains("async") {
if let Ok(Some(dxvk)) = &config.try_get_selected_dxvk_info() {
if dxvk.version.contains("async") {
command.env("DXVK_ASYNC", "1");
}
}

View file

@ -263,6 +263,10 @@ impl App {
installer.temp_folder = temp_folder;
}
installer.downloader
.set_downloading_speed(config.launcher.speed_limit)
.expect("Failed to set downloading speed limit");
// Download wine
#[allow(unused_must_use)]
installer.install(&config.game.wine.builds, move |state| {
@ -317,6 +321,10 @@ impl App {
if let Some(temp_folder) = config.launcher.temp {
installer.temp_folder = temp_folder;
}
installer.downloader
.set_downloading_speed(config.launcher.speed_limit)
.expect("Failed to set downloading speed limit");
// Download DXVK
#[allow(unused_must_use)]
@ -358,7 +366,7 @@ impl App {
},
ProgressUpdateResult::Finished => {
let mut config = config::get().unwrap();
let config = config::get().unwrap();
// Apply DXVK
let this = this.clone();
@ -368,12 +376,7 @@ impl App {
match dxvk_version.apply(&config.game.dxvk.builds, &config.game.wine.prefix) {
Ok(output) => {
println!("Applied DXVK:\n\n{}", String::from_utf8_lossy(&output.stdout));
// Update dxvk config
config.game.dxvk.selected = Some(dxvk_version.name.clone());
config::update_raw(config.clone()).unwrap();
// Remove .first-run file
let launcher_dir = crate::lib::consts::launcher_dir().unwrap();

View file

@ -435,6 +435,10 @@ impl App {
installer.temp_folder = temp_folder;
}
installer.downloader
.set_downloading_speed(config.launcher.speed_limit)
.expect("Failed to set downloading speed limit");
let (sender, receiver) = glib::MainContext::channel::<InstallerUpdate>(glib::PRIORITY_DEFAULT);
let this = this.clone();

View file

@ -439,16 +439,21 @@ impl App {
Actions::UpdateDxvkComboRow => {
let model = gtk::StringList::new(&[]);
let list = dxvk::List::list_downloaded(config.game.dxvk.builds)
let list = dxvk::List::list_downloaded(&config.game.dxvk.builds)
.expect("Failed to list downloaded DXVK versions");
let mut raw_list = Vec::new();
let mut selected = 0;
let curr = match config.try_get_selected_dxvk_info() {
Ok(Some(curr)) => Some(curr.name),
_ => None
};
for version in list {
model.append(&version.name);
if let Some(curr) = &config.game.dxvk.selected {
if let Some(curr) = &curr {
if &version.name == curr {
selected = raw_list.len() as u32;
}
@ -480,9 +485,16 @@ impl App {
if let Some(dxvk_versions) = &values.downloaded_dxvk_versions {
let version = dxvk_versions[*i].clone();
let mut apply = true;
if config.game.dxvk.selected != Some(version.name.clone()) {
config.game.dxvk.selected = Some(version.name.clone());
if let Ok(Some(curr)) = config.try_get_selected_dxvk_info() {
if version == curr {
apply = false;
}
}
if apply {
this.widgets.dxvk_selected.set_sensitive(false);
std::thread::spawn(clone!(@strong config, @strong this => move || {
match version.apply(&config.game.dxvk.builds, &config.game.wine.prefix) {
@ -493,6 +505,8 @@ impl App {
)))).unwrap();
}
}
this.widgets.dxvk_selected.set_sensitive(true);
}));
}
}

View file

@ -78,13 +78,18 @@ pub trait DownloadComponent {
});
let (send, recv) = std::sync::mpsc::channel();
let config = config::get()?;
let mut installer = Installer::new(self.get_download_uri())?;
if let Some(temp_folder) = config::get()?.launcher.temp {
if let Some(temp_folder) = config.launcher.temp {
installer.temp_folder = temp_folder;
}
installer.downloader
.set_downloading_speed(config.launcher.speed_limit)
.expect("Failed to set downloading speed limit");
let installation_path = installation_path.to_string();
send.send(installer).unwrap();