Skip to content

Commit

Permalink
move around flatpak utility functions and implement workaround for fl…
Browse files Browse the repository at this point in the history
…atpak bug

until flatpak/flatpak#6084 is merged and available
in distributions
  • Loading branch information
slonkazoid committed Jan 19, 2025
1 parent 08e4743 commit 96f9966
Show file tree
Hide file tree
Showing 2 changed files with 108 additions and 79 deletions.
96 changes: 18 additions & 78 deletions crates/libmoonlight/src/installer.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
use super::types::{Branch, DetectedInstall, GitHubRelease, InstallInfo, MoonlightBranch};
use super::util::{get_download_dir, get_home_dir};
use crate::types::{
FlatpakFilesystemOverride, FlatpakFilesystemOverridePermission, FlatpakOverrides,
use crate::{
ensure_flatpak_overrides, get_app_dir, get_local_share, get_local_share_workaround,
get_moonlight_dir, DOWNLOAD_DIR, PATCHED_ASAR,
};
use crate::{get_app_dir, get_local_share, get_moonlight_dir, DOWNLOAD_DIR, PATCHED_ASAR};
use std::path::PathBuf;

const USER_AGENT: &str =
Expand Down Expand Up @@ -203,7 +203,10 @@ impl Installer {
}

"linux" => {
let local_share = get_local_share();
// this is a crime but it has to be done...
// please merge pr flatpak devs
let local_shares = [get_local_share(), get_local_share_workaround()];

let dirs = [
("Discord", Branch::Stable, None),
("DiscordPTB", Branch::PTB, None),
Expand All @@ -216,13 +219,16 @@ impl Installer {

let mut installs = vec![];
for (dir, branch, id) in dirs {
let path = local_share.join(dir);
if path.join(branch.name()).exists() {
installs.push(DetectedInstall {
branch,
path,
flatpak_id: id.map(Into::into),
});
for local_share in &local_shares {
let path = local_share.join(dir);
if path.join(branch.name()).exists() {
installs.push(DetectedInstall {
branch,
path,
flatpak_id: id.map(Into::into),
});
break;
}
}
}

Expand All @@ -239,72 +245,6 @@ impl Installer {
Ok(!get_app_dir(&install.path)?.join("app.asar").exists())
}

fn get_flatpak_overrides(&self, id: &str) -> crate::Result<Option<FlatpakOverrides>> {
let overrides = get_local_share().join("flatpak").join("overrides");

std::fs::create_dir_all(&overrides)?;

let app_overrides = overrides.join(id);

let file = match std::fs::OpenOptions::new().read(true).open(&app_overrides) {
Ok(v) => v,
Err(err) => match err.kind() {
std::io::ErrorKind::NotFound => return Ok(None),
_ => return Err(err.into()),
},
};

serde_ini::from_read(file).or(Ok(None))
}

fn ensure_flatpak_overrides(&self, id: &str) -> crate::Result<()> {
let overrides = self.get_flatpak_overrides(id)?;

let has = overrides
.as_ref()
.and_then(|v| v.context.as_ref())
.and_then(|v| v.filesystems.as_ref())
.is_some_and(|v| {
v.iter().any(|entry| {
entry.path == "xdg-config/moonlight-mod"
&& entry.permission == FlatpakFilesystemOverridePermission::ReadWrite
})
});

if has {
return Ok(());
}

let mut overrides = overrides.unwrap_or_default();

if overrides.context.is_none() {
overrides.context = Some(Default::default());
}
let context = overrides.context.as_mut().unwrap();

if context.filesystems.is_none() {
context.filesystems = Some(Default::default());
}
let filesystem = context.filesystems.as_mut().unwrap();

filesystem.push(FlatpakFilesystemOverride {
path: String::from("xdg-config/moonlight-mod"),
permission: FlatpakFilesystemOverridePermission::ReadWrite,
});

let app_overrides = get_local_share().join("flatpak").join("overrides").join(id);
let mut file = std::fs::OpenOptions::new()
.write(true)
.create(true)
.truncate(true)
.append(false)
.open(&app_overrides)?;

serde_ini::to_writer(&mut file, &overrides).expect("ini serialization to succeed");

Ok(())
}

pub fn patch_install(
&self,
install: &DetectedInstall,
Expand Down Expand Up @@ -339,7 +279,7 @@ const DOWNLOAD_DIR = {};
std::fs::write(app_dir.join("app/injector.js"), injector)?;

if let Some(flatpak_id) = install.flatpak_id.as_deref() {
self.ensure_flatpak_overrides(flatpak_id)?;
ensure_flatpak_overrides(flatpak_id)?;
}

Ok(())
Expand Down
91 changes: 90 additions & 1 deletion crates/libmoonlight/src/util.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
#[cfg(unix)]
use nix::unistd::{Uid, User};

use crate::types::{Branch, DetectedInstall, InstallInfo};
use crate::types::{
Branch, DetectedInstall, FlatpakFilesystemOverride, FlatpakFilesystemOverridePermission,
FlatpakOverrides, InstallInfo,
};
use std::path::{Path, PathBuf};

pub const DOWNLOAD_DIR: &str = "dist";
Expand Down Expand Up @@ -101,8 +104,94 @@ pub fn get_local_share() -> PathBuf {
.unwrap_or_else(|| get_home_dir().join(".local/share"))
}

// https://github.com/flatpak/flatpak/pull/6084
pub fn get_local_share_workaround() -> PathBuf {
get_home_dir().join(".local").join("share")
}

fn get_flatpak_home() -> PathBuf {
let a = get_local_share().join("flatpak");
if a.exists() {
a
} else {
let b = get_local_share_workaround().join("flatpak");
if b.exists() {
b
} else {
a
}
}
}

pub fn get_dot_config() -> PathBuf {
std::env::var_os("XDG_CONFIG_HOME")
.map(PathBuf::from)
.unwrap_or_else(|| get_home_dir().join(".config"))
}

fn get_flatpak_overrides(id: &str) -> crate::Result<Option<FlatpakOverrides>> {
let overrides = get_flatpak_home().join("overrides");

std::fs::create_dir_all(&overrides)?;

let app_overrides = overrides.join(id);

let file = match std::fs::OpenOptions::new().read(true).open(&app_overrides) {
Ok(v) => v,
Err(err) => match err.kind() {
std::io::ErrorKind::NotFound => return Ok(None),
_ => return Err(err.into()),
},
};

serde_ini::from_read(file).or(Ok(None))
}

pub fn ensure_flatpak_overrides(id: &str) -> crate::Result<()> {
let overrides = get_flatpak_overrides(id)?;

let has = overrides
.as_ref()
.and_then(|v| v.context.as_ref())
.and_then(|v| v.filesystems.as_ref())
.is_some_and(|v| {
v.iter().any(|entry| {
entry.path == "xdg-config/moonlight-mod"
&& entry.permission == FlatpakFilesystemOverridePermission::ReadWrite
})
});

if has {
return Ok(());
}

let mut overrides = overrides.unwrap_or_default();

if overrides.context.is_none() {
overrides.context = Some(Default::default());
}
let context = overrides.context.as_mut().unwrap();

if context.filesystems.is_none() {
context.filesystems = Some(Default::default());
}
let filesystem = context.filesystems.as_mut().unwrap();

filesystem.push(FlatpakFilesystemOverride {
path: String::from("xdg-config/moonlight-mod"),
permission: FlatpakFilesystemOverridePermission::ReadWrite,
});

// ensured that it exists in get_flatpak_overrides
let app_overrides = get_flatpak_home().join("overrides").join(id);
let mut file = std::fs::OpenOptions::new()
.write(true)
.create(true)
.truncate(true)
.append(false)
.open(&app_overrides)?;

serde_ini::to_writer(&mut file, &overrides).expect("ini serialization to succeed");

Ok(())
}

0 comments on commit 96f9966

Please sign in to comment.