mirror of
https://github.com/an-anime-team/an-anime-game-launcher.git
synced 2025-03-20 07:00:00 +03:00
commit
56ed3b13e8
9 changed files with 331 additions and 70 deletions
22
Cargo.lock
generated
22
Cargo.lock
generated
|
@ -58,6 +58,7 @@ dependencies = [
|
|||
"anyhow",
|
||||
"cached 0.42.0",
|
||||
"dirs",
|
||||
"discord-rich-presence",
|
||||
"glib-build-tools",
|
||||
"gtk4",
|
||||
"lazy_static",
|
||||
|
@ -668,6 +669,18 @@ dependencies = [
|
|||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "discord-rich-presence"
|
||||
version = "0.2.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "47fc4beffb85ee1461588499073a4d9c20dcc7728c4b13d6b282ab6c508947e5"
|
||||
dependencies = [
|
||||
"serde",
|
||||
"serde_derive",
|
||||
"serde_json",
|
||||
"uuid",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "dispatch"
|
||||
version = "0.2.0"
|
||||
|
@ -2254,6 +2267,15 @@ version = "2.1.2"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e8db7427f936968176eaa7cdf81b7f98b980b18495ec28f1b5791ac3bfe3eea9"
|
||||
|
||||
[[package]]
|
||||
name = "uuid"
|
||||
version = "0.8.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bc5cf98d8186244414c848017f0e2676b3fcb46807f6668a97dfe67359a3c4b7"
|
||||
dependencies = [
|
||||
"getrandom",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "vcpkg"
|
||||
version = "0.2.15"
|
||||
|
|
|
@ -16,6 +16,7 @@ opt-level = 3
|
|||
glib-build-tools = "0.16"
|
||||
|
||||
[dependencies]
|
||||
discord-rich-presence = "0.2.3"
|
||||
gtk = { package = "gtk4", version = "0.5", features = ["v4_8"] }
|
||||
adw = { package = "libadwaita", version = "0.2", features = ["v1_2"] }
|
||||
rfd = { version = "0.10", features = ["xdg-portal"], default-features = false }
|
||||
|
|
|
@ -55,6 +55,35 @@ Adw.PreferencesPage page {
|
|||
]
|
||||
};
|
||||
}
|
||||
Adw.ActionRow discord_rpc_row
|
||||
{
|
||||
title: "Discord RPC";
|
||||
subtitle: "Discord RPC allows you to provide Discord the info that you are currently playing the game to let your friends know.";
|
||||
Gtk.Switch discord_rpc_switch {
|
||||
valign: center;
|
||||
}
|
||||
}
|
||||
|
||||
Adw.ActionRow discord_rpc_desc_row
|
||||
{
|
||||
title: "Discord RPC Heading";
|
||||
subtitle: "Set a custom heading for the activity status!\n(Requires launcher restart, or disable and re-enable the RPC)";
|
||||
Gtk.Entry discord_rpc_desc
|
||||
{
|
||||
valign:center;
|
||||
}
|
||||
}
|
||||
|
||||
Adw.ActionRow discord_rpc_state_row
|
||||
{
|
||||
title: "Discord RPC State";
|
||||
subtitle: "Set a custom description for the activity status!\n(Requires launcher restart, or disable and re-enable the RPC)";
|
||||
Gtk.Entry discord_rpc_state
|
||||
{
|
||||
valign:center;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Adw.ComboRow fsr_combo {
|
||||
title: "FSR";
|
||||
|
@ -74,6 +103,8 @@ Adw.PreferencesPage page {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
Adw.ActionRow gamemode_row {
|
||||
title: "Gamemode";
|
||||
subtitle: "This prioritizes the game over the rest of the processes";
|
||||
|
|
55
src/lib/config/game/enhancements/discordrpc.rs
Normal file
55
src/lib/config/game/enhancements/discordrpc.rs
Normal file
|
@ -0,0 +1,55 @@
|
|||
use std::thread::JoinHandle;
|
||||
|
||||
use serde::{Deserialize, Serialize};
|
||||
use serde_json::Value as JsonValue;
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
pub struct DiscordRpc {
|
||||
pub enabled: bool,
|
||||
pub large_image_key: String,
|
||||
pub app_id: String,
|
||||
pub description: String,
|
||||
pub state: String,
|
||||
}
|
||||
|
||||
impl Default for DiscordRpc {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
enabled: true,
|
||||
large_image_key: "gi-icon".to_string(),
|
||||
app_id: "901534333360304168".to_string(),
|
||||
description: "Bullying Paimon".to_string(),
|
||||
state: "In the weeb game".to_string(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<&JsonValue> for DiscordRpc {
|
||||
fn from(value: &JsonValue) -> Self {
|
||||
let default = Self::default();
|
||||
Self {
|
||||
enabled: match value.get("enabled") {
|
||||
Some(value) => value.as_bool().unwrap_or(default.enabled),
|
||||
None => default.enabled,
|
||||
},
|
||||
|
||||
description: match value.get("description") {
|
||||
Some(value) => value.as_str().unwrap_or(&default.description).to_string(),
|
||||
None => default.description,
|
||||
},
|
||||
|
||||
state: match value.get("state") {
|
||||
Some(value) => value.as_str().unwrap_or(&default.state).to_string(),
|
||||
None => default.state,
|
||||
},
|
||||
|
||||
large_image_key: match value.get("large_image_key") {
|
||||
Some(value) => value
|
||||
.as_str()
|
||||
.unwrap_or(&default.large_image_key)
|
||||
.to_string(),
|
||||
None => default.large_image_key,
|
||||
},
|
||||
app_id: "901534333360304168".to_string(),
|
||||
}
|
||||
}
|
||||
}
|
|
@ -5,7 +5,7 @@ pub mod fsr;
|
|||
pub mod hud;
|
||||
pub mod fps_unlocker;
|
||||
pub mod gamescope;
|
||||
|
||||
pub mod discordrpc;
|
||||
pub mod prelude {
|
||||
pub use super::gamescope::prelude::*;
|
||||
pub use super::fps_unlocker::prelude::*;
|
||||
|
@ -14,17 +14,21 @@ pub mod prelude {
|
|||
pub use super::fsr::Fsr;
|
||||
pub use super::hud::HUD;
|
||||
pub use super::fps_unlocker::FpsUnlocker;
|
||||
pub use super::discordrpc::DiscordRpc;
|
||||
}
|
||||
|
||||
use prelude::*;
|
||||
|
||||
use crate::lib::config;
|
||||
|
||||
#[derive(Debug, Clone, Serialize, Deserialize, Default)]
|
||||
pub struct Enhancements {
|
||||
pub fsr: Fsr,
|
||||
pub gamemode: bool,
|
||||
pub hud: HUD,
|
||||
pub fps_unlocker: FpsUnlocker,
|
||||
pub gamescope: Gamescope
|
||||
pub gamescope: Gamescope,
|
||||
pub discord_rpc: DiscordRpc,
|
||||
}
|
||||
|
||||
impl From<&JsonValue> for Enhancements {
|
||||
|
@ -55,7 +59,11 @@ impl From<&JsonValue> for Enhancements {
|
|||
gamescope: match value.get("gamescope") {
|
||||
Some(value) => Gamescope::from(value),
|
||||
None => default.gamescope
|
||||
}
|
||||
},
|
||||
discord_rpc: match value.get("discord_rpc") {
|
||||
Some(value) => DiscordRpc::from(value),
|
||||
None => default.discord_rpc
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,8 +2,8 @@ use std::process::Command;
|
|||
|
||||
use anime_game_core::genshin::telemetry;
|
||||
|
||||
use super::consts;
|
||||
use super::config;
|
||||
use super::consts;
|
||||
use super::fps_unlocker::FpsUnlocker;
|
||||
|
||||
/*#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||
|
@ -61,24 +61,25 @@ pub fn try_get_terminal() -> Option<Terminal> {
|
|||
}*/
|
||||
|
||||
/// Try to run the game
|
||||
///
|
||||
///
|
||||
/// If `debug = true`, then the game will be run in the new terminal window
|
||||
pub fn run() -> anyhow::Result<()> {
|
||||
let config = config::get()?;
|
||||
|
||||
if !config.game.path.exists() {
|
||||
return Err(anyhow::anyhow!("Game is not installed"));
|
||||
}
|
||||
|
||||
let wine_executable = match config.try_get_wine_executable() {
|
||||
Some(path) => path,
|
||||
None => return Err(anyhow::anyhow!("Couldn't find wine executable"))
|
||||
None => return Err(anyhow::anyhow!("Couldn't find wine executable")),
|
||||
};
|
||||
|
||||
// Check telemetry servers
|
||||
|
||||
if let Some(server) = telemetry::is_disabled(consts::TELEMETRY_CHECK_TIMEOUT) {
|
||||
return Err(anyhow::anyhow!("Telemetry server is not disabled: {server}"));
|
||||
return Err(anyhow::anyhow!(
|
||||
"Telemetry server is not disabled: {server}"
|
||||
));
|
||||
}
|
||||
|
||||
// Prepare fps unlocker
|
||||
|
@ -94,28 +95,51 @@ pub fn run() -> anyhow::Result<()> {
|
|||
// Ok(None) means unknown version, so we should delete it before downloading newer one
|
||||
// because otherwise downloader will try to continue downloading "partially downloaded" file
|
||||
if let Ok(None) = other {
|
||||
std::fs::remove_file(FpsUnlocker::get_binary_in(&config.game.enhancements.fps_unlocker.path))?;
|
||||
std::fs::remove_file(FpsUnlocker::get_binary_in(
|
||||
&config.game.enhancements.fps_unlocker.path,
|
||||
))?;
|
||||
}
|
||||
|
||||
match FpsUnlocker::download(&config.game.enhancements.fps_unlocker.path) {
|
||||
Ok(unlocker) => unlocker,
|
||||
Err(err) => return Err(anyhow::anyhow!("Failed to download FPS unlocker: {err}"))
|
||||
Err(err) => {
|
||||
return Err(anyhow::anyhow!("Failed to download FPS unlocker: {err}"))
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
// Generate FPS unlocker config file
|
||||
if let Err(err) = unlocker.update_config(config.game.enhancements.fps_unlocker.config.clone()) {
|
||||
return Err(anyhow::anyhow!("Failed to update FPS unlocker config: {err}"));
|
||||
if let Err(err) =
|
||||
unlocker.update_config(config.game.enhancements.fps_unlocker.config.clone())
|
||||
{
|
||||
return Err(anyhow::anyhow!(
|
||||
"Failed to update FPS unlocker config: {err}"
|
||||
));
|
||||
}
|
||||
|
||||
let bat_path = config.game.path.join("fpsunlocker.bat");
|
||||
let original_bat_path = config.game.path.join("launcher.bat");
|
||||
|
||||
// Generate fpsunlocker.bat from launcher.bat
|
||||
std::fs::write(bat_path, std::fs::read_to_string(original_bat_path)?
|
||||
.replace("start GenshinImpact.exe %*", &format!("start GenshinImpact.exe %*\n\nZ:\ncd \"{}\"\nstart unlocker.exe", unlocker.dir().to_string_lossy()))
|
||||
.replace("start YuanShen.exe %*", &format!("start YuanShen.exe %*\n\nZ:\ncd \"{}\"\nstart unlocker.exe", unlocker.dir().to_string_lossy())))?;
|
||||
std::fs::write(
|
||||
bat_path,
|
||||
std::fs::read_to_string(original_bat_path)?
|
||||
.replace(
|
||||
"start GenshinImpact.exe %*",
|
||||
&format!(
|
||||
"start GenshinImpact.exe %*\n\nZ:\ncd \"{}\"\nstart unlocker.exe",
|
||||
unlocker.dir().to_string_lossy()
|
||||
),
|
||||
)
|
||||
.replace(
|
||||
"start YuanShen.exe %*",
|
||||
&format!(
|
||||
"start YuanShen.exe %*\n\nZ:\ncd \"{}\"\nstart unlocker.exe",
|
||||
unlocker.dir().to_string_lossy()
|
||||
),
|
||||
),
|
||||
)?;
|
||||
}
|
||||
|
||||
// Prepare bash -c '<command>'
|
||||
|
@ -132,7 +156,11 @@ pub fn run() -> anyhow::Result<()> {
|
|||
bash_chain += &format!("{virtual_desktop} ");
|
||||
}
|
||||
|
||||
bash_chain += if config.game.enhancements.fps_unlocker.enabled { "fpsunlocker.bat " } else { "launcher.bat " };
|
||||
bash_chain += if config.game.enhancements.fps_unlocker.enabled {
|
||||
"fpsunlocker.bat "
|
||||
} else {
|
||||
"launcher.bat "
|
||||
};
|
||||
|
||||
if config.game.wine.borderless {
|
||||
bash_chain += "-screen-fullscreen 0 -popupwindow ";
|
||||
|
@ -150,7 +178,7 @@ pub fn run() -> anyhow::Result<()> {
|
|||
|
||||
let bash_chain = match &config.game.command {
|
||||
Some(command) => command.replace("%command%", &bash_chain),
|
||||
None => bash_chain
|
||||
None => bash_chain,
|
||||
};
|
||||
|
||||
let mut command = Command::new("bash");
|
||||
|
@ -174,7 +202,6 @@ pub fn run() -> anyhow::Result<()> {
|
|||
command.envs(config.game.enhancements.hud.get_env_vars(&config));
|
||||
command.envs(config.game.enhancements.fsr.get_env_vars());
|
||||
command.envs(config.game.wine.language.get_env_vars());
|
||||
|
||||
command.envs(config.game.environment);
|
||||
|
||||
// Run command
|
||||
|
|
141
src/main.rs
141
src/main.rs
|
@ -1,15 +1,18 @@
|
|||
use gtk::prelude::*;
|
||||
|
||||
use gtk::{CssProvider, StyleContext, STYLE_PROVIDER_PRIORITY_APPLICATION};
|
||||
use discord_rich_presence::{
|
||||
activity::{self, Activity, Party, Secrets},
|
||||
DiscordIpc, DiscordIpcClient,
|
||||
};
|
||||
use gtk::gdk::Display;
|
||||
use gtk::glib;
|
||||
use gtk::glib::clone;
|
||||
use gtk::prelude::*;
|
||||
use gtk::{CssProvider, StyleContext, STYLE_PROVIDER_PRIORITY_APPLICATION};
|
||||
|
||||
use std::path::Path;
|
||||
use std::fs;
|
||||
use std::path::Path;
|
||||
|
||||
pub mod ui;
|
||||
pub mod lib;
|
||||
pub mod ui;
|
||||
|
||||
use ui::*;
|
||||
|
||||
|
@ -29,55 +32,112 @@ fn main() {
|
|||
glib::set_program_name(Some("An Anime Game Launcher"));
|
||||
|
||||
// Create app
|
||||
let application = gtk::Application::new(
|
||||
Some(APP_ID),
|
||||
Default::default()
|
||||
);
|
||||
let application = gtk::Application::new(Some(APP_ID), Default::default());
|
||||
|
||||
application.add_main_option(
|
||||
"run-game",
|
||||
"run-game",
|
||||
glib::Char::from(0),
|
||||
glib::OptionFlags::empty(),
|
||||
glib::OptionArg::None,
|
||||
"Run the game",
|
||||
None
|
||||
None,
|
||||
);
|
||||
|
||||
application.add_main_option(
|
||||
"just-run-game",
|
||||
"just-run-game",
|
||||
glib::Char::from(0),
|
||||
glib::OptionFlags::empty(),
|
||||
glib::OptionArg::None,
|
||||
"Run the game whenever it possible, ignoring updates predownloads",
|
||||
None
|
||||
None,
|
||||
);
|
||||
|
||||
let run_game = std::rc::Rc::new(std::cell::Cell::new(false));
|
||||
let just_run_game = std::rc::Rc::new(std::cell::Cell::new(false));
|
||||
|
||||
application.connect_handle_local_options(clone!(@strong run_game, @strong just_run_game => move |_, arg| {
|
||||
if arg.contains("just-run-game") {
|
||||
just_run_game.set(true);
|
||||
}
|
||||
application.connect_handle_local_options(
|
||||
clone!(@strong run_game, @strong just_run_game => move |_, arg| {
|
||||
if arg.contains("just-run-game") {
|
||||
just_run_game.set(true);
|
||||
}
|
||||
|
||||
else if arg.contains("run-game") {
|
||||
run_game.set(true);
|
||||
}
|
||||
else if arg.contains("run-game") {
|
||||
run_game.set(true);
|
||||
}
|
||||
|
||||
-1
|
||||
}));
|
||||
-1
|
||||
}),
|
||||
);
|
||||
|
||||
// Init app window and show it
|
||||
application.connect_activate(move |app| {
|
||||
let config = lib::config::get().expect("Failed to load config");
|
||||
|
||||
let mut client =
|
||||
DiscordIpcClient::new(config.game.enhancements.discord_rpc.app_id.as_str())
|
||||
.expect("Failed to create client");
|
||||
|
||||
|
||||
let mut activity_set:bool = false;
|
||||
let mut connected: bool = false;
|
||||
let _thread = std::thread::spawn(move || loop {
|
||||
let conf = lib::config::get().expect("Failed to load config");
|
||||
// println!("activity_set: {:?} connected: {:?}",activity_set,connected);
|
||||
if conf.game.enhancements.discord_rpc.enabled {
|
||||
if !connected{
|
||||
match client.connect() {
|
||||
Ok(_) => {
|
||||
println!("Client connected to Discord successfully.");connected=true;
|
||||
}
|
||||
Err(_) => {
|
||||
println!(
|
||||
"Client failed to connect to Discord, Please try again or relaunch Discord."
|
||||
);
|
||||
}
|
||||
};
|
||||
}
|
||||
let act = activity::Activity::new()
|
||||
.state(config.game.enhancements.discord_rpc.state.as_str())
|
||||
.details(config.game.enhancements.discord_rpc.description.as_str())
|
||||
.assets(activity::Assets::new()
|
||||
.large_image(config.game.enhancements.discord_rpc.large_image_key.as_str()
|
||||
));
|
||||
|
||||
if !activity_set{
|
||||
match client.set_activity(act) {
|
||||
Ok(_) => {println!("Client set activity successfully."); activity_set=true;}
|
||||
Err(_) => {println!("Client failed to set activity, Please try again or relaunch Discord.");}
|
||||
};
|
||||
}
|
||||
|
||||
std::thread::sleep(std::time::Duration::from_millis(1000));
|
||||
} else {
|
||||
if activity_set{
|
||||
match client.clear_activity(){
|
||||
Ok(_) => {println!("Client activity cleared successfully.");connected=false;activity_set=false}
|
||||
Err(_) => {println!("Failed to clear.");}
|
||||
}
|
||||
}
|
||||
|
||||
if connected{
|
||||
match client.close(){
|
||||
Ok(_) => {println!("Client connection closed.");connected=false;}
|
||||
Err(_) => {println!("Failed to clear.");}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
std::thread::sleep(std::time::Duration::from_millis(1000));
|
||||
});
|
||||
// Apply CSS styles to the application
|
||||
let provider = CssProvider::new();
|
||||
|
||||
provider.load_from_data(include_bytes!("../assets/styles.css"));
|
||||
|
||||
|
||||
StyleContext::add_provider_for_display(
|
||||
&Display::default().expect("Could not connect to a display"),
|
||||
&provider,
|
||||
STYLE_PROVIDER_PRIORITY_APPLICATION
|
||||
STYLE_PROVIDER_PRIORITY_APPLICATION,
|
||||
);
|
||||
|
||||
// Create default launcher folder if needed
|
||||
|
@ -85,16 +145,13 @@ fn main() {
|
|||
|
||||
if !launcher_dir.exists() || launcher_dir.join(".first-run").exists() {
|
||||
fs::create_dir_all(&launcher_dir).expect("Failed to create default launcher dir");
|
||||
fs::write(launcher_dir.join(".first-run"), "").expect("Failed to create .first-run file");
|
||||
fs::write(launcher_dir.join(".first-run"), "")
|
||||
.expect("Failed to create .first-run file");
|
||||
|
||||
let first_run = FirstRunApp::new(app).expect("Failed to init FirstRunApp");
|
||||
|
||||
first_run.show();
|
||||
}
|
||||
|
||||
else {
|
||||
let config = lib::config::get().expect("Failed to load config");
|
||||
|
||||
} else {
|
||||
// Create wine builds folder
|
||||
if !Path::new(&config.game.wine.builds).exists() {
|
||||
fs::create_dir_all(config.game.wine.builds)
|
||||
|
@ -118,9 +175,7 @@ fn main() {
|
|||
|
||||
if !run_game.get() && !just_run_game.get() {
|
||||
main.show();
|
||||
}
|
||||
|
||||
else {
|
||||
} else {
|
||||
use lib::launcher::states::LauncherState;
|
||||
|
||||
let just_run_game = just_run_game.get();
|
||||
|
@ -132,20 +187,22 @@ fn main() {
|
|||
if let LauncherState::PredownloadAvailable { game, voices } = state {
|
||||
if just_run_game {
|
||||
state = &LauncherState::Launch;
|
||||
}
|
||||
|
||||
else if let Ok(config) = lib::config::get() {
|
||||
} else if let Ok(config) = lib::config::get() {
|
||||
let mut predownloaded = true;
|
||||
|
||||
let temp = config.launcher.temp.unwrap_or("/tmp".into());
|
||||
|
||||
if !temp.join(game.file_name().unwrap_or(String::from("\0"))).exists() {
|
||||
if !temp
|
||||
.join(game.file_name().unwrap_or(String::from("\0")))
|
||||
.exists()
|
||||
{
|
||||
predownloaded = false;
|
||||
}
|
||||
|
||||
else {
|
||||
} else {
|
||||
for voice in voices {
|
||||
if !temp.join(voice.file_name().unwrap_or(String::from("\0"))).exists() {
|
||||
if !temp
|
||||
.join(voice.file_name().unwrap_or(String::from("\0")))
|
||||
.exists()
|
||||
{
|
||||
predownloaded = false;
|
||||
|
||||
break;
|
||||
|
@ -167,7 +224,7 @@ fn main() {
|
|||
std::process::exit(0);
|
||||
}
|
||||
|
||||
_ => main.show()
|
||||
_ => main.show(),
|
||||
}
|
||||
});
|
||||
}
|
||||
|
|
|
@ -275,6 +275,7 @@ impl App {
|
|||
///
|
||||
/// Changes will happen in the main thread so you can call `update` method from separate thread
|
||||
pub fn init_actions(self) -> Self {
|
||||
|
||||
let (sender, receiver) = glib::MainContext::channel::<Actions>(glib::PRIORITY_DEFAULT);
|
||||
|
||||
// I prefer to avoid using clone! here because it breaks my code autocompletion
|
||||
|
@ -878,7 +879,6 @@ impl App {
|
|||
};
|
||||
|
||||
self.actions.set(actions);
|
||||
|
||||
result
|
||||
}
|
||||
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
use gtk::ffi::gtk_text_view_set_overwrite;
|
||||
use gtk::prelude::*;
|
||||
use adw::prelude::*;
|
||||
|
||||
|
@ -6,6 +7,7 @@ use gtk::glib::clone;
|
|||
|
||||
use crate::lib;
|
||||
use crate::lib::config;
|
||||
use crate::lib::config::game::enhancements::discordrpc;
|
||||
use crate::lib::config::prelude::*;
|
||||
|
||||
use crate::ui::*;
|
||||
|
@ -45,7 +47,16 @@ pub struct AppWidgets {
|
|||
pub fps_unlocker_power_saving_switcher: gtk::Switch,
|
||||
pub fps_unlocker_monitor_num: gtk::SpinButton,
|
||||
pub fps_unlocker_window_mode_combo: adw::ComboRow,
|
||||
pub fps_unlocker_priority_combo: adw::ComboRow
|
||||
pub fps_unlocker_priority_combo: adw::ComboRow,
|
||||
|
||||
pub discord_rpc_row: adw::ActionRow,
|
||||
pub discord_rpc: gtk::Switch,
|
||||
|
||||
pub discord_rpc_state_row: adw::ActionRow,
|
||||
pub discord_rpc_state: gtk::Entry,
|
||||
|
||||
pub discord_rpc_desc_row: adw::ActionRow,
|
||||
pub discord_rpc_desc: gtk::Entry,
|
||||
}
|
||||
|
||||
impl AppWidgets {
|
||||
|
@ -79,7 +90,14 @@ impl AppWidgets {
|
|||
fps_unlocker_power_saving_switcher: get_object(&builder, "fps_unlocker_power_saving_switcher")?,
|
||||
fps_unlocker_monitor_num: get_object(&builder, "fps_unlocker_monitor_num")?,
|
||||
fps_unlocker_window_mode_combo: get_object(&builder, "fps_unlocker_window_mode_combo")?,
|
||||
fps_unlocker_priority_combo: get_object(&builder, "fps_unlocker_priority_combo")?
|
||||
fps_unlocker_priority_combo: get_object(&builder, "fps_unlocker_priority_combo")?,
|
||||
discord_rpc: get_object(&builder,"discord_rpc_switch")?,
|
||||
discord_rpc_row: get_object(&builder, "discord_rpc_row")?,
|
||||
discord_rpc_state: get_object(&builder, "discord_rpc_state")?,
|
||||
discord_rpc_state_row: get_object(&builder, "discord_rpc_state_row")?,
|
||||
|
||||
discord_rpc_desc: get_object(&builder, "discord_rpc_desc")?,
|
||||
discord_rpc_desc_row: get_object(&builder, "discord_rpc_desc_row")?,
|
||||
};
|
||||
|
||||
// Set availale wine languages
|
||||
|
@ -102,6 +120,11 @@ impl AppWidgets {
|
|||
result.gamescope_row.set_sensitive(false);
|
||||
result.gamescope_row.set_tooltip_text(Some("Gamescope is not installed"));
|
||||
}
|
||||
// result.discord_rpc_desc_row.set_sensitive(true);
|
||||
// result.discord_rpc_state_row.set_sensitive(true);
|
||||
result.discord_rpc_row.set_sensitive(true);
|
||||
result.discord_rpc.set_sensitive(true);
|
||||
|
||||
|
||||
Ok(result)
|
||||
}
|
||||
|
@ -157,9 +180,9 @@ impl App {
|
|||
self.widgets.borderless.connect_state_notify(move |switch| {
|
||||
if let Ok(mut config) = config::get() {
|
||||
config.game.wine.borderless = switch.state();
|
||||
|
||||
config::update(config);
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
// Virtual desktop resolution selection
|
||||
|
@ -207,7 +230,6 @@ impl App {
|
|||
self.widgets.fsr_combo.connect_selected_notify(move |row| {
|
||||
if let Ok(mut config) = config::get() {
|
||||
config.game.enhancements.fsr.strength = 5 - row.selected() as u64;
|
||||
|
||||
config::update(config);
|
||||
}
|
||||
});
|
||||
|
@ -220,12 +242,44 @@ impl App {
|
|||
config::update(config);
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
self.widgets.discord_rpc.connect_state_notify(move |switch|{
|
||||
if let Ok(mut config) = config::get()
|
||||
{
|
||||
config.game.enhancements.discord_rpc.enabled = switch.state();
|
||||
// config.game.enhancements.discord_rpc.toggle();
|
||||
config::update(config);
|
||||
}
|
||||
});
|
||||
|
||||
self.widgets.discord_rpc_state.connect_changed(move |state|
|
||||
{
|
||||
if let Ok(mut config) = config::get()
|
||||
{
|
||||
let string = state.text().as_str().to_string();
|
||||
std::thread::sleep(std::time::Duration::from_millis(10));
|
||||
config.game.enhancements.discord_rpc.state = string;
|
||||
// println!("[Debug] Updated string: {}",config.game.enhancements.discord_rpc.state);
|
||||
config::update(config);
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
self.widgets.discord_rpc_desc.connect_changed(move |state|
|
||||
{
|
||||
if let Ok(mut config) = config::get()
|
||||
{
|
||||
let string = state.text().as_str().to_string();
|
||||
std::thread::sleep(std::time::Duration::from_millis(10));
|
||||
config.game.enhancements.discord_rpc.description = string;
|
||||
// println!("[Debug] Updated string: {}",config.game.enhancements.discord_rpc.description);
|
||||
config::update(config);
|
||||
}
|
||||
});
|
||||
// Gamemode switching
|
||||
self.widgets.gamemode_switcher.connect_state_notify(move |switch| {
|
||||
if let Ok(mut config) = config::get() {
|
||||
config.game.enhancements.gamemode = switch.state();
|
||||
|
||||
config::update(config);
|
||||
}
|
||||
});
|
||||
|
@ -264,11 +318,12 @@ impl App {
|
|||
}
|
||||
});
|
||||
|
||||
|
||||
|
||||
// FPS unlocker -> power saving swithing
|
||||
self.widgets.fps_unlocker_power_saving_switcher.connect_state_notify(move |switch| {
|
||||
if let Ok(mut config) = config::get() {
|
||||
config.game.enhancements.fps_unlocker.config.power_saving = switch.state();
|
||||
|
||||
config::update(config);
|
||||
}
|
||||
});
|
||||
|
@ -286,7 +341,6 @@ impl App {
|
|||
self.widgets.fps_unlocker_window_mode_combo.connect_selected_notify(move |row| {
|
||||
if let Ok(mut config) = config::get() {
|
||||
config.game.enhancements.fps_unlocker.config.window_mode = row.selected() as u64;
|
||||
|
||||
config::update(config);
|
||||
}
|
||||
});
|
||||
|
@ -295,11 +349,12 @@ impl App {
|
|||
self.widgets.fps_unlocker_priority_combo.connect_selected_notify(move |row| {
|
||||
if let Ok(mut config) = config::get() {
|
||||
config.game.enhancements.fps_unlocker.config.priority = row.selected() as u64;
|
||||
|
||||
config::update(config);
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
|
||||
self
|
||||
}
|
||||
|
||||
|
@ -355,6 +410,11 @@ impl App {
|
|||
// FSR switching
|
||||
self.widgets.fsr_switcher.set_state(config.game.enhancements.fsr.enabled);
|
||||
|
||||
// Discord RPC
|
||||
self.widgets.discord_rpc.set_state(config.game.enhancements.discord_rpc.enabled);
|
||||
self.widgets.discord_rpc_state.set_placeholder_text(Some(config.game.enhancements.discord_rpc.state.as_str()));
|
||||
self.widgets.discord_rpc_desc.set_placeholder_text(Some(config.game.enhancements.discord_rpc.description.as_str()));
|
||||
|
||||
// Gamemode switching
|
||||
self.widgets.gamemode_switcher.set_state(config.game.enhancements.gamemode);
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue