Merge branch 'dev'
This commit is contained in:
commit
f9e384d50c
119 changed files with 12276 additions and 2303 deletions
Binary file not shown.
Before Width: | Height: | Size: 133 KiB After Width: | Height: | Size: 70 KiB |
Binary file not shown.
Before Width: | Height: | Size: 262 KiB After Width: | Height: | Size: 259 KiB |
Binary file not shown.
854
backend/Cargo.lock
generated
854
backend/Cargo.lock
generated
File diff suppressed because it is too large
Load diff
|
@ -1,21 +1,22 @@
|
|||
[package]
|
||||
name = "powertools"
|
||||
version = "1.4.0"
|
||||
version = "2.0.0"
|
||||
edition = "2021"
|
||||
authors = ["NGnius (Graham) <ngniusness@gmail.com>"]
|
||||
description = "Backend (superuser) functionality for PowerTools"
|
||||
license = "GPL-3.0-only"
|
||||
repository = "https://github.com/NGnius/PowerTools"
|
||||
repository = "https://git.ngni.us/NG-SD-Plugins/PowerTools"
|
||||
keywords = ["utility", "power-management", "root", "decky"]
|
||||
readme = "../README.md"
|
||||
|
||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
|
||||
[dependencies]
|
||||
usdpl-back = { version = "0.10.1", features = ["blocking"] }#, path = "../../usdpl-rs/usdpl-back"}
|
||||
usdpl-back = { version = "0.10.1", features = ["blocking", "decky"] }#, path = "../../usdpl-rs/usdpl-back"}
|
||||
serde = { version = "1.0", features = ["derive"] }
|
||||
serde_json = "1.0"
|
||||
sysfuss = { version = "0.2", features = ["derive"] }#, path = "../../sysfs-nav" }
|
||||
ron = "0.8"
|
||||
sysfuss = { version = "0.2", features = ["derive"] }#,path = "../../sysfs-nav"}
|
||||
|
||||
# async
|
||||
tokio = { version = "*", features = ["time"] }
|
||||
|
@ -26,11 +27,25 @@ log = "0.4"
|
|||
simplelog = "0.12"
|
||||
|
||||
# limits & driver functionality
|
||||
limits_core = { version = "2", path = "./limits_core" }
|
||||
limits_core = { version = "3", path = "./limits_core" }
|
||||
regex = "1"
|
||||
libryzenadj = { version = "0.12" }
|
||||
|
||||
# steam deck libs
|
||||
smokepatio = { version = "0.1", features = [ "std" ], path = "../../smokepatio" }
|
||||
libc = "0.2"
|
||||
|
||||
# online settings
|
||||
community_settings_core = { version = "0.1", path = "./community_settings_core" }
|
||||
chrono = { version = "0.4", features = [ "serde" ] }
|
||||
|
||||
# hardware enablement
|
||||
#libryzenadj = { version = "0.14", path = "../../libryzenadj-rs-14" }
|
||||
libryzenadj = { version = "0.13" }
|
||||
|
||||
# ureq's tls feature does not like musl targets
|
||||
ureq = { version = "2", features = ["json", "gzip", "brotli", "charset"], default-features = false, optional = true }
|
||||
ureq = { version = "2", features = ["json", "gzip", "brotli", "charset", "tls"], default-features = false, optional = true }
|
||||
|
||||
clap = { version = "4.4", features = [ "derive" ] }
|
||||
|
||||
[features]
|
||||
default = ["online", "decky"]
|
||||
|
@ -38,6 +53,7 @@ decky = ["usdpl-back/decky"]
|
|||
crankshaft = ["usdpl-back/crankshaft"]
|
||||
encrypt = ["usdpl-back/encrypt"]
|
||||
online = ["ureq"]
|
||||
experimental = []
|
||||
dev_stuff = []
|
||||
|
||||
[profile.release]
|
||||
|
@ -45,13 +61,13 @@ debug = false
|
|||
strip = true
|
||||
lto = true
|
||||
codegen-units = 1
|
||||
opt-level = 3
|
||||
|
||||
[profile.docker]
|
||||
inherits = "release"
|
||||
debug = false
|
||||
strip = true
|
||||
lto = "thin"
|
||||
codegen-units = 16
|
||||
opt-level = 2
|
||||
codegen-units = 8
|
||||
debug-assertions = false
|
||||
overflow-checks = false
|
||||
|
|
|
@ -3,10 +3,11 @@
|
|||
#cargo build --release --target x86_64-unknown-linux-musl
|
||||
#cargo build --target x86_64-unknown-linux-musl
|
||||
#cross build
|
||||
cargo build
|
||||
cargo build --release
|
||||
#cargo build
|
||||
|
||||
mkdir -p ../bin
|
||||
#cp --preserve=mode ./target/x86_64-unknown-linux-musl/release/powertools ../bin/backend
|
||||
#cp --preserve=mode ./target/x86_64-unknown-linux-musl/debug/powertools ../bin/backend
|
||||
cp --preserve=mode ./target/release/powertools ../bin/backend
|
||||
#cp --preserve=mode ./target/debug/powertools ../bin/backend
|
||||
cp --preserve=mode ./target/debug/powertools ../bin/backend
|
||||
|
|
65
backend/community_settings_core/Cargo.lock
generated
Normal file
65
backend/community_settings_core/Cargo.lock
generated
Normal file
|
@ -0,0 +1,65 @@
|
|||
# This file is automatically @generated by Cargo.
|
||||
# It is not intended for manual editing.
|
||||
version = 3
|
||||
|
||||
[[package]]
|
||||
name = "community_settings_core"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "proc-macro2"
|
||||
version = "1.0.70"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "39278fbbf5fb4f646ce651690877f89d1c5811a3d4acb27700c1cb3cdb78fd3b"
|
||||
dependencies = [
|
||||
"unicode-ident",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "quote"
|
||||
version = "1.0.33"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5267fca4496028628a95160fc423a33e8b2e6af8a5302579e322e4b520293cae"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde"
|
||||
version = "1.0.193"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "25dd9975e68d0cb5aa1120c288333fc98731bd1dd12f561e468ea4728c042b89"
|
||||
dependencies = [
|
||||
"serde_derive",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde_derive"
|
||||
version = "1.0.193"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "43576ca501357b9b071ac53cdc7da8ef0cbd9493d8df094cd821777ea6e894d3"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "syn"
|
||||
version = "2.0.41"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "44c8b28c477cc3bf0e7966561e3460130e1255f7a1cf71931075f1c5e7a7e269"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"unicode-ident",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "unicode-ident"
|
||||
version = "1.0.12"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b"
|
9
backend/community_settings_core/Cargo.toml
Normal file
9
backend/community_settings_core/Cargo.toml
Normal file
|
@ -0,0 +1,9 @@
|
|||
[package]
|
||||
name = "community_settings_core"
|
||||
version = "0.1.0"
|
||||
edition = "2021"
|
||||
|
||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
|
||||
[dependencies]
|
||||
serde = { version = "1.0", features = ["derive"] }
|
1
backend/community_settings_core/src/lib.rs
Normal file
1
backend/community_settings_core/src/lib.rs
Normal file
|
@ -0,0 +1 @@
|
|||
pub mod v1;
|
23
backend/community_settings_core/src/v1/metadata.rs
Normal file
23
backend/community_settings_core/src/v1/metadata.rs
Normal file
|
@ -0,0 +1,23 @@
|
|||
use serde::{Deserialize, Serialize};
|
||||
|
||||
#[derive(Serialize, Deserialize, Clone)]
|
||||
pub struct Metadata {
|
||||
pub name: String,
|
||||
pub steam_app_id: u32,
|
||||
pub steam_user_id: u64,
|
||||
pub steam_username: String,
|
||||
pub tags: Vec<String>,
|
||||
/// Should always be a valid u128, but some parsers do not support that
|
||||
pub id: String,
|
||||
pub config: super::Config,
|
||||
}
|
||||
|
||||
impl Metadata {
|
||||
pub fn set_id(&mut self, id: u128) {
|
||||
self.id = id.to_string()
|
||||
}
|
||||
|
||||
pub fn get_id(&self) -> u128 {
|
||||
self.id.parse().expect("metadata id must be u128")
|
||||
}
|
||||
}
|
5
backend/community_settings_core/src/v1/mod.rs
Normal file
5
backend/community_settings_core/src/v1/mod.rs
Normal file
|
@ -0,0 +1,5 @@
|
|||
mod metadata;
|
||||
mod setting;
|
||||
|
||||
pub use metadata::Metadata;
|
||||
pub use setting::*;
|
47
backend/community_settings_core/src/v1/setting.rs
Normal file
47
backend/community_settings_core/src/v1/setting.rs
Normal file
|
@ -0,0 +1,47 @@
|
|||
use serde::{Deserialize, Serialize};
|
||||
|
||||
/// Base setting file containing all information for all components
|
||||
#[derive(Serialize, Deserialize, Clone)]
|
||||
pub struct Config {
|
||||
pub cpus: Vec<Cpu>,
|
||||
pub gpu: Gpu,
|
||||
pub battery: Battery,
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, Clone, Copy)]
|
||||
pub struct MinMax<T> {
|
||||
pub max: Option<T>,
|
||||
pub min: Option<T>,
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, Clone)]
|
||||
pub struct Battery {
|
||||
pub charge_rate: Option<u64>,
|
||||
pub charge_mode: Option<String>,
|
||||
#[serde(default)]
|
||||
pub events: Vec<BatteryEvent>,
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, Clone)]
|
||||
pub struct BatteryEvent {
|
||||
pub trigger: String,
|
||||
pub charge_rate: Option<u64>,
|
||||
pub charge_mode: Option<String>,
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, Clone)]
|
||||
pub struct Cpu {
|
||||
pub online: bool,
|
||||
pub clock_limits: Option<MinMax<u64>>,
|
||||
pub governor: String,
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, Clone)]
|
||||
pub struct Gpu {
|
||||
pub fast_ppt: Option<u64>,
|
||||
pub slow_ppt: Option<u64>,
|
||||
pub tdp: Option<u64>,
|
||||
pub tdp_boost: Option<u64>,
|
||||
pub clock_limits: Option<MinMax<u64>>,
|
||||
pub memory_clock: Option<u64>,
|
||||
}
|
1538
backend/community_settings_srv/Cargo.lock
generated
Normal file
1538
backend/community_settings_srv/Cargo.lock
generated
Normal file
File diff suppressed because it is too large
Load diff
21
backend/community_settings_srv/Cargo.toml
Normal file
21
backend/community_settings_srv/Cargo.toml
Normal file
|
@ -0,0 +1,21 @@
|
|||
[package]
|
||||
name = "community_settings_srv"
|
||||
version = "0.1.0"
|
||||
edition = "2021"
|
||||
|
||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
|
||||
[dependencies]
|
||||
community_settings_core = { version = "0.1", path = "../community_settings_core" }
|
||||
serde = { version = "1.0", features = ["derive"] }
|
||||
serde_json = "1.0"
|
||||
ron = "0.8"
|
||||
|
||||
clap = { version = "4", features = ["derive", "std", "color"], default-features = false }
|
||||
tokio = { version = "1", features = ["full"] }
|
||||
actix-web = { version = "4.4" }
|
||||
mime = { version = "0.3.17" }
|
||||
|
||||
# logging
|
||||
log = "0.4"
|
||||
simplelog = "0.12"
|
7
backend/community_settings_srv/README.md
Normal file
7
backend/community_settings_srv/README.md
Normal file
|
@ -0,0 +1,7 @@
|
|||
# community_settings_srv
|
||||
|
||||
Back-end for browsing community-contributed settings files for games.
|
||||
|
||||
### Technical
|
||||
|
||||
This does not use a database because I'm trying to speedrun the destruction of any semblance of performance for my filesystem. Everything is stored as a file, with symlinks to make it possible to find files multiple ways.
|
121
backend/community_settings_srv/src/api/get_game.rs
Normal file
121
backend/community_settings_srv/src/api/get_game.rs
Normal file
|
@ -0,0 +1,121 @@
|
|||
use actix_web::{get, web, Responder, http::header};
|
||||
|
||||
use crate::cli::Cli;
|
||||
use crate::file_util;
|
||||
|
||||
const MAX_RESULTS: usize = 50;
|
||||
|
||||
fn special_settings() -> Vec<community_settings_core::v1::Metadata> {
|
||||
vec![
|
||||
community_settings_core::v1::Metadata {
|
||||
name: "Zeroth the Least".to_owned(),
|
||||
steam_app_id: 0,
|
||||
steam_user_id: 76561198116690523,
|
||||
steam_username: "NGnius".to_owned(),
|
||||
tags: vec!["0".to_owned(), "gr8".to_owned()],
|
||||
id: 0.to_string(),
|
||||
config: community_settings_core::v1::Config {
|
||||
cpus: vec![
|
||||
community_settings_core::v1::Cpu {
|
||||
online: true,
|
||||
clock_limits: Some(community_settings_core::v1::MinMax { max: Some(1), min: Some(0) }),
|
||||
governor: "Michaëlle Jean".to_owned(),
|
||||
},
|
||||
community_settings_core::v1::Cpu {
|
||||
online: false,
|
||||
clock_limits: Some(community_settings_core::v1::MinMax { max: Some(1), min: Some(0) }),
|
||||
governor: "Adrienne Clarkson".to_owned(),
|
||||
},
|
||||
community_settings_core::v1::Cpu {
|
||||
online: true,
|
||||
clock_limits: Some(community_settings_core::v1::MinMax { max: Some(1), min: Some(0) }),
|
||||
governor: "Michael Collins".to_owned(),
|
||||
}
|
||||
],
|
||||
gpu: community_settings_core::v1::Gpu {
|
||||
fast_ppt: Some(1),
|
||||
slow_ppt: Some(1),
|
||||
tdp: None,
|
||||
tdp_boost: None,
|
||||
clock_limits: Some(community_settings_core::v1::MinMax { max: Some(1), min: Some(0) }),
|
||||
memory_clock: Some(404),
|
||||
},
|
||||
battery: community_settings_core::v1::Battery {
|
||||
charge_rate: Some(42),
|
||||
charge_mode: Some("nuclear fusion".to_owned()),
|
||||
events: vec![
|
||||
community_settings_core::v1::BatteryEvent {
|
||||
trigger: "anything but one on a gun".to_owned(),
|
||||
charge_rate: Some(42),
|
||||
charge_mode: Some("neutral".to_owned()),
|
||||
}
|
||||
],
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
fn get_some_settings_by_app_id(steam_app_id: u32, cli: &'static Cli) -> std::io::Result<Vec<community_settings_core::v1::Metadata>> {
|
||||
let app_id_folder = file_util::setting_folder_by_app_id(&cli.folder, steam_app_id);
|
||||
let mut files: Vec<_> = app_id_folder.read_dir()?
|
||||
.filter_map(|res| res.ok())
|
||||
.filter(|f| f.path().extension().map(|ext| ext == file_util::RON_EXTENSION).unwrap_or(false))
|
||||
.filter_map(|f| f.metadata().ok().map(|meta| (f, meta)))
|
||||
.filter_map(|(f, meta)| meta.created().ok().map(|time| (f, meta, time)))
|
||||
.collect();
|
||||
files.sort_by(|(_, _, a_created), (_, _, b_created)| a_created.cmp(b_created));
|
||||
|
||||
let mut results = Vec::with_capacity(MAX_RESULTS);
|
||||
for (_, (f, _, _)) in files.into_iter().enumerate().take_while(|(i, _)| *i < MAX_RESULTS) {
|
||||
let reader = std::io::BufReader::new(std::fs::File::open(f.path())?);
|
||||
let setting = match ron::de::from_reader(reader) {
|
||||
Ok(x) => x,
|
||||
Err(e) => {
|
||||
let e_msg = format!("{}", e);
|
||||
return Err(std::io::Error::new(std::io::ErrorKind::InvalidData, e_msg));
|
||||
}
|
||||
};
|
||||
results.push(setting);
|
||||
}
|
||||
Ok(results)
|
||||
}
|
||||
|
||||
#[get("/api/setting/by_app_id/{id}")]
|
||||
pub async fn get_setting_by_app_id_handler(
|
||||
id: web::Path<u32>,
|
||||
accept: web::Header<header::Accept>,
|
||||
cli: web::Data<&'static Cli>,
|
||||
) -> std::io::Result<impl Responder> {
|
||||
let id: u32 = *id;
|
||||
println!("Accept: {}", accept.to_string());
|
||||
let preferred = accept.preference();
|
||||
if super::is_mime_type_ron_capable(&preferred) {
|
||||
// Send RON
|
||||
let ron = if id != 0 {
|
||||
get_some_settings_by_app_id(id, &*cli)?
|
||||
} else {
|
||||
special_settings()
|
||||
};
|
||||
// TODO don't dump to string
|
||||
let result_body = ron::ser::to_string(&ron).unwrap();
|
||||
Ok(actix_web::HttpResponse::Ok()
|
||||
//.insert_header(header::ContentType("application/ron".parse().unwrap()))
|
||||
.insert_header(header::ContentType(mime::STAR_STAR))
|
||||
.body(actix_web::body::BoxBody::new(result_body))
|
||||
)
|
||||
} else {
|
||||
// Send JSON (fallback)
|
||||
let json = if id != 0 {
|
||||
get_some_settings_by_app_id(id, &*cli)?
|
||||
} else {
|
||||
special_settings()
|
||||
};
|
||||
// TODO don't dump to string
|
||||
let result_body = serde_json::to_string(&json).unwrap();
|
||||
Ok(actix_web::HttpResponse::Ok()
|
||||
.insert_header(header::ContentType::json())
|
||||
.body(actix_web::body::BoxBody::new(result_body))
|
||||
)
|
||||
}
|
||||
}
|
121
backend/community_settings_srv/src/api/get_setting.rs
Normal file
121
backend/community_settings_srv/src/api/get_setting.rs
Normal file
|
@ -0,0 +1,121 @@
|
|||
use actix_web::{get, web, Responder, http::header};
|
||||
|
||||
use crate::cli::Cli;
|
||||
use crate::file_util;
|
||||
|
||||
fn special_settings() -> community_settings_core::v1::Metadata {
|
||||
community_settings_core::v1::Metadata {
|
||||
name: "Zeroth the Least".to_owned(),
|
||||
steam_app_id: 1675200,
|
||||
steam_user_id: 76561198116690523,
|
||||
steam_username: "NGnius".to_owned(),
|
||||
tags: vec!["0".to_owned(), "gr8".to_owned()],
|
||||
id: 0.to_string(),
|
||||
config: community_settings_core::v1::Config {
|
||||
cpus: vec![
|
||||
community_settings_core::v1::Cpu {
|
||||
online: true,
|
||||
clock_limits: Some(community_settings_core::v1::MinMax { max: Some(1), min: Some(0) }),
|
||||
governor: "Michaëlle Jean".to_owned(),
|
||||
},
|
||||
community_settings_core::v1::Cpu {
|
||||
online: false,
|
||||
clock_limits: Some(community_settings_core::v1::MinMax { max: Some(1), min: Some(0) }),
|
||||
governor: "Adrienne Clarkson".to_owned(),
|
||||
},
|
||||
community_settings_core::v1::Cpu {
|
||||
online: true,
|
||||
clock_limits: Some(community_settings_core::v1::MinMax { max: Some(1), min: Some(0) }),
|
||||
governor: "Michael Collins".to_owned(),
|
||||
}
|
||||
],
|
||||
gpu: community_settings_core::v1::Gpu {
|
||||
fast_ppt: Some(1),
|
||||
slow_ppt: Some(1),
|
||||
tdp: None,
|
||||
tdp_boost: None,
|
||||
clock_limits: Some(community_settings_core::v1::MinMax { max: Some(1), min: Some(0) }),
|
||||
memory_clock: Some(404),
|
||||
},
|
||||
battery: community_settings_core::v1::Battery {
|
||||
charge_rate: Some(42),
|
||||
charge_mode: Some("nuclear fusion".to_owned()),
|
||||
events: vec![
|
||||
community_settings_core::v1::BatteryEvent {
|
||||
trigger: "anything but one on a gun".to_owned(),
|
||||
charge_rate: Some(42),
|
||||
charge_mode: Some("neutral".to_owned()),
|
||||
}
|
||||
],
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[get("/api/setting/by_id/{id}")]
|
||||
pub async fn get_setting_handler(
|
||||
id: web::Path<String>,
|
||||
accept: web::Header<header::Accept>,
|
||||
cli: web::Data<&'static Cli>,
|
||||
) -> std::io::Result<impl Responder> {
|
||||
println!("Accept: {}", accept.to_string());
|
||||
let id: u128 = match id.parse() {
|
||||
Ok(x) => x,
|
||||
Err(e) => return Err(std::io::Error::new(std::io::ErrorKind::InvalidInput, format!("invalid setting id `{}` (should be u128): {}", id, e))),
|
||||
};
|
||||
let preferred = accept.preference();
|
||||
if super::is_mime_type_ron_capable(&preferred) {
|
||||
// Send RON
|
||||
let ron = if id != 0 {
|
||||
let path = file_util::setting_path_by_id(&cli.folder, id, file_util::RON_EXTENSION);
|
||||
if !path.exists() {
|
||||
return Err(std::io::Error::new(std::io::ErrorKind::NotFound, format!("setting id {} does not exist", id)));
|
||||
}
|
||||
// TODO? cache this instead of always loading it from file
|
||||
let reader = std::io::BufReader::new(std::fs::File::open(path)?);
|
||||
match ron::de::from_reader(reader) {
|
||||
Ok(x) => x,
|
||||
Err(e) => {
|
||||
let e_msg = format!("{}", e);
|
||||
return Err(std::io::Error::new(std::io::ErrorKind::InvalidData, e_msg));
|
||||
}
|
||||
}
|
||||
} else {
|
||||
special_settings()
|
||||
};
|
||||
// TODO don't dump to string
|
||||
let result_body = ron::ser::to_string(&ron).unwrap();
|
||||
Ok(actix_web::HttpResponse::Ok()
|
||||
//.insert_header(header::ContentType("application/ron".parse().unwrap()))
|
||||
.insert_header(header::ContentType(mime::STAR_STAR))
|
||||
.body(actix_web::body::BoxBody::new(result_body))
|
||||
)
|
||||
} else {
|
||||
// Send JSON (fallback)
|
||||
let json = if id != 0 {
|
||||
let path = file_util::setting_path_by_id(&cli.folder, id, file_util::JSON_EXTENSION);
|
||||
// TODO? cache this instead of always loading it from file
|
||||
let reader = std::io::BufReader::new(std::fs::File::open(path)?);
|
||||
match serde_json::from_reader(reader) {
|
||||
Ok(x) => x,
|
||||
Err(e) => {
|
||||
let e_msg = format!("{}", e);
|
||||
if let Some(io_e) = e.io_error_kind() {
|
||||
return Err(std::io::Error::new(io_e, e_msg));
|
||||
} else {
|
||||
return Err(std::io::Error::new(std::io::ErrorKind::InvalidData, e_msg));
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
} else {
|
||||
special_settings()
|
||||
};
|
||||
// TODO don't dump to string
|
||||
let result_body = serde_json::to_string(&json).unwrap();
|
||||
Ok(actix_web::HttpResponse::Ok()
|
||||
.insert_header(header::ContentType::json())
|
||||
.body(actix_web::body::BoxBody::new(result_body))
|
||||
)
|
||||
}
|
||||
}
|
12
backend/community_settings_srv/src/api/mod.rs
Normal file
12
backend/community_settings_srv/src/api/mod.rs
Normal file
|
@ -0,0 +1,12 @@
|
|||
mod get_game;
|
||||
mod get_setting;
|
||||
mod save_setting;
|
||||
|
||||
pub use get_game::get_setting_by_app_id_handler as get_setting_by_steam_app_id;
|
||||
pub use get_setting::get_setting_handler as get_setting_by_id;
|
||||
pub use save_setting::save_setting_handler as save_setting_with_new_id;
|
||||
|
||||
pub(self) fn is_mime_type_ron_capable(mimetype: &mime::Mime) -> bool {
|
||||
(mimetype.type_() == "application" || mimetype.type_() == mime::STAR)
|
||||
&& (mimetype.subtype() == "ron" || mimetype.subtype() == "cc.replicated.ron" || mimetype.subtype() == "w-ron")
|
||||
}
|
120
backend/community_settings_srv/src/api/save_setting.rs
Normal file
120
backend/community_settings_srv/src/api/save_setting.rs
Normal file
|
@ -0,0 +1,120 @@
|
|||
use actix_web::{post, web, Responder, http::header};
|
||||
|
||||
use crate::cli::Cli;
|
||||
use crate::file_util;
|
||||
|
||||
const PAYLOAD_LIMIT: usize = 10_000_000; // 10 Megabyte
|
||||
|
||||
#[post("/api/setting")]
|
||||
pub async fn save_setting_handler(
|
||||
data: web::Payload,
|
||||
content_type: web::Header<header::ContentType>,
|
||||
cli: web::Data<&'static Cli>,
|
||||
) -> std::io::Result<impl Responder> {
|
||||
//println!("Content-Type: {}", content_type.to_string());
|
||||
let bytes = match data.to_bytes_limited(PAYLOAD_LIMIT).await {
|
||||
Ok(Ok(x)) => x,
|
||||
Ok(Err(e)) => return Err(std::io::Error::new(std::io::ErrorKind::InvalidData, format!("wut: {}", e))),
|
||||
Err(_e) => return Err(std::io::Error::new(std::io::ErrorKind::InvalidData, "too many bytes in payload")),
|
||||
};
|
||||
let next_id = file_util::next_setting_id(&cli.folder);
|
||||
let parsed_data: community_settings_core::v1::Metadata = if super::is_mime_type_ron_capable(&content_type) {
|
||||
// Parse as RON
|
||||
match ron::de::from_reader(bytes.as_ref()) {
|
||||
Ok(x) => x,
|
||||
Err(e) => {
|
||||
let e_msg = format!("{}", e);
|
||||
return Err(std::io::Error::new(std::io::ErrorKind::InvalidData, e_msg));
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// Parse JSON (fallback)
|
||||
match serde_json::from_reader(bytes.as_ref()) {
|
||||
Ok(x) => x,
|
||||
Err(e) => {
|
||||
let e_msg = format!("{}", e);
|
||||
if let Some(io_e) = e.io_error_kind() {
|
||||
return Err(std::io::Error::new(io_e, e_msg));
|
||||
} else {
|
||||
return Err(std::io::Error::new(std::io::ErrorKind::InvalidData, e_msg));
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
};
|
||||
// TODO validate user and app id
|
||||
// Reject blocked users and apps
|
||||
let path_ron = file_util::setting_path_by_id(&cli.folder, next_id, file_util::RON_EXTENSION);
|
||||
let writer = std::io::BufWriter::new(std::fs::File::create(&path_ron)?);
|
||||
if let Err(e) = ron::ser::to_writer(writer, &parsed_data) {
|
||||
let e_msg = format!("{}", e);
|
||||
return Err(std::io::Error::new(std::io::ErrorKind::InvalidData, e_msg));
|
||||
}
|
||||
|
||||
let path_json = file_util::setting_path_by_id(&cli.folder, next_id, file_util::JSON_EXTENSION);
|
||||
let writer = std::io::BufWriter::new(std::fs::File::create(&path_json)?);
|
||||
if let Err(e) = serde_json::to_writer(writer, &parsed_data) {
|
||||
let e_msg = format!("{}", e);
|
||||
if let Some(io_e) = e.io_error_kind() {
|
||||
return Err(std::io::Error::new(io_e, e_msg));
|
||||
} else {
|
||||
return Err(std::io::Error::new(std::io::ErrorKind::InvalidData, e_msg));
|
||||
}
|
||||
}
|
||||
|
||||
// create symlinks for other ways of looking up these settings files
|
||||
let filename_ron = file_util::filename(next_id, file_util::RON_EXTENSION);
|
||||
let filename_json = file_util::filename(next_id, file_util::JSON_EXTENSION);
|
||||
|
||||
// create symlinks to app id folder
|
||||
let app_id_folder = file_util::setting_folder_by_app_id(&cli.folder, parsed_data.steam_app_id);
|
||||
if !app_id_folder.exists() {
|
||||
std::fs::create_dir(&app_id_folder)?;
|
||||
}
|
||||
#[cfg(target_family = "windows")] // NOTE: windows support is untested and unmaintained
|
||||
{
|
||||
std::os::windows::fs::symlink_file(&path_ron, app_id_folder.join(&filename_ron))?;
|
||||
std::os::windows::fs::symlink_file(&path_json, app_id_folder.join(&filename_json))?;
|
||||
}
|
||||
#[cfg(target_family = "unix")]
|
||||
{
|
||||
std::os::unix::fs::symlink(&path_ron, app_id_folder.join(&filename_ron))?;
|
||||
std::os::unix::fs::symlink(&path_json, app_id_folder.join(&filename_json))?;
|
||||
}
|
||||
|
||||
// create symlinks for user id folder
|
||||
let user_id_folder = file_util::setting_folder_by_user_id(&cli.folder, parsed_data.steam_user_id);
|
||||
if !user_id_folder.exists() {
|
||||
std::fs::create_dir(&user_id_folder)?;
|
||||
}
|
||||
#[cfg(target_family = "windows")] // NOTE: windows support is untested and unmaintained
|
||||
{
|
||||
std::os::windows::fs::symlink_file(&path_ron, user_id_folder.join(&filename_ron))?;
|
||||
std::os::windows::fs::symlink_file(&path_json, user_id_folder.join(&filename_json))?;
|
||||
}
|
||||
#[cfg(target_family = "unix")]
|
||||
{
|
||||
std::os::unix::fs::symlink(&path_ron, user_id_folder.join(&filename_ron))?;
|
||||
std::os::unix::fs::symlink(&path_json, user_id_folder.join(&filename_json))?;
|
||||
}
|
||||
|
||||
// create symlinks for each tag
|
||||
for tag in parsed_data.tags.iter() {
|
||||
let tag_folder = file_util::setting_folder_by_tag(&cli.folder, tag);
|
||||
if !tag_folder.exists() {
|
||||
std::fs::create_dir(&tag_folder)?;
|
||||
}
|
||||
#[cfg(target_family = "windows")] // NOTE: windows support is untested and unmaintained
|
||||
{
|
||||
std::os::windows::fs::symlink_file(&path_ron, tag_folder.join(&filename_ron))?;
|
||||
std::os::windows::fs::symlink_file(&path_json, tag_folder.join(&filename_json))?;
|
||||
}
|
||||
#[cfg(target_family = "unix")]
|
||||
{
|
||||
std::os::unix::fs::symlink(&path_ron, tag_folder.join(&filename_ron))?;
|
||||
std::os::unix::fs::symlink(&path_json, tag_folder.join(&filename_json))?;
|
||||
}
|
||||
}
|
||||
|
||||
Ok(actix_web::HttpResponse::NoContent())
|
||||
}
|
23
backend/community_settings_srv/src/cli.rs
Normal file
23
backend/community_settings_srv/src/cli.rs
Normal file
|
@ -0,0 +1,23 @@
|
|||
use clap::Parser;
|
||||
|
||||
#[derive(Parser, Debug, Clone)]
|
||||
#[command(author, version, about, long_about = None)]
|
||||
pub struct Cli {
|
||||
/// Root folder to store contributed setting files
|
||||
#[arg(short, long, default_value = "./community_settings")]
|
||||
pub folder: std::path::PathBuf,
|
||||
|
||||
/// Server port
|
||||
#[arg(short, long, default_value_t = 8080)]
|
||||
pub port: u16,
|
||||
|
||||
/// Log file location
|
||||
#[arg(short, long, default_value = "/tmp/powertools_community_settings_srv.log")]
|
||||
pub log: std::path::PathBuf,
|
||||
}
|
||||
|
||||
impl Cli {
|
||||
pub fn get() -> Self {
|
||||
Self::parse()
|
||||
}
|
||||
}
|
86
backend/community_settings_srv/src/file_util.rs
Normal file
86
backend/community_settings_srv/src/file_util.rs
Normal file
|
@ -0,0 +1,86 @@
|
|||
use std::path::{Path, PathBuf};
|
||||
use std::sync::Mutex;
|
||||
|
||||
pub const RON_EXTENSION: &'static str = "ron";
|
||||
pub const JSON_EXTENSION: &'static str = "json";
|
||||
|
||||
const SETTING_FOLDER: &'static str = "settings";
|
||||
const ID_FOLDER: &'static str = "by_id";
|
||||
const APP_ID_FOLDER: &'static str = "by_app_id";
|
||||
const USER_ID_FOLDER: &'static str = "by_user_id";
|
||||
const TAG_FOLDER: &'static str = "by_tag";
|
||||
|
||||
static LAST_SETTING_ID: Mutex<u128> = Mutex::new(0);
|
||||
|
||||
pub fn build_folder_layout(root: impl AsRef<Path>) -> std::io::Result<()> {
|
||||
std::fs::create_dir_all(
|
||||
root.as_ref()
|
||||
.join(SETTING_FOLDER)
|
||||
.join(ID_FOLDER)
|
||||
)?;
|
||||
std::fs::create_dir_all(
|
||||
root.as_ref()
|
||||
.join(SETTING_FOLDER)
|
||||
.join(APP_ID_FOLDER)
|
||||
)?;
|
||||
std::fs::create_dir_all(
|
||||
root.as_ref()
|
||||
.join(SETTING_FOLDER)
|
||||
.join(USER_ID_FOLDER)
|
||||
)?;
|
||||
std::fs::create_dir_all(
|
||||
root.as_ref()
|
||||
.join(SETTING_FOLDER)
|
||||
.join(TAG_FOLDER)
|
||||
)?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn filename(id: u128, ext: &str) -> String {
|
||||
format!("{}.{}", id, ext)
|
||||
}
|
||||
|
||||
pub fn setting_path_by_id(root: impl AsRef<Path>, id: u128, ext: &str) -> PathBuf {
|
||||
root.as_ref()
|
||||
.join(SETTING_FOLDER)
|
||||
.join(ID_FOLDER)
|
||||
.join(filename(id, ext))
|
||||
}
|
||||
|
||||
pub fn setting_folder_by_app_id(root: impl AsRef<Path>, steam_app_id: u32) -> PathBuf {
|
||||
root.as_ref()
|
||||
.join(SETTING_FOLDER)
|
||||
.join(APP_ID_FOLDER)
|
||||
.join(steam_app_id.to_string())
|
||||
}
|
||||
|
||||
pub fn setting_folder_by_user_id(root: impl AsRef<Path>, steam_user_id: u64) -> PathBuf {
|
||||
root.as_ref()
|
||||
.join(SETTING_FOLDER)
|
||||
.join(USER_ID_FOLDER)
|
||||
.join(steam_user_id.to_string())
|
||||
}
|
||||
|
||||
pub fn setting_folder_by_tag(root: impl AsRef<Path>, tag: &str) -> PathBuf {
|
||||
root.as_ref()
|
||||
.join(SETTING_FOLDER)
|
||||
.join(TAG_FOLDER)
|
||||
.join(tag)
|
||||
}
|
||||
|
||||
pub fn next_setting_id(root: impl AsRef<Path>) -> u128 {
|
||||
let mut lock = LAST_SETTING_ID.lock().unwrap();
|
||||
let mut last_id = *lock;
|
||||
if last_id == 0 {
|
||||
// needs init
|
||||
let mut path = setting_path_by_id(root.as_ref(), last_id, RON_EXTENSION);
|
||||
while path.exists() {
|
||||
last_id += 1;
|
||||
path = setting_path_by_id(root.as_ref(), last_id, RON_EXTENSION);
|
||||
}
|
||||
*lock = last_id;
|
||||
println!("setting id initialized to {}", last_id);
|
||||
}
|
||||
*lock += 1;
|
||||
*lock
|
||||
}
|
45
backend/community_settings_srv/src/main.rs
Normal file
45
backend/community_settings_srv/src/main.rs
Normal file
|
@ -0,0 +1,45 @@
|
|||
mod api;
|
||||
mod cli;
|
||||
mod file_util;
|
||||
|
||||
use actix_web::{web, App, HttpServer};
|
||||
|
||||
#[tokio::main]
|
||||
async fn main() -> std::io::Result<()> {
|
||||
let args = cli::Cli::get();
|
||||
println!("cli: {:?}", args);
|
||||
|
||||
simplelog::WriteLogger::init(
|
||||
#[cfg(debug_assertions)]
|
||||
{
|
||||
log::LevelFilter::Debug
|
||||
},
|
||||
#[cfg(not(debug_assertions))]
|
||||
{
|
||||
log::LevelFilter::Info
|
||||
},
|
||||
Default::default(),
|
||||
std::fs::File::create(&args.log).expect("Failed to create log file"),
|
||||
//std::fs::File::create("/home/deck/powertools-rs.log").unwrap(),
|
||||
)
|
||||
.unwrap();
|
||||
log::debug!("Logging to: {}", args.log.display());
|
||||
|
||||
// setup
|
||||
log::debug!("Building folder layout (if not exists) at: {}", &args.folder.display());
|
||||
file_util::build_folder_layout(&args.folder)?;
|
||||
|
||||
let leaked_args: &'static cli::Cli = Box::leak::<'static>(Box::new(args));
|
||||
HttpServer::new(move || {
|
||||
App::new()
|
||||
.app_data(web::Data::new(leaked_args))
|
||||
//.app_data(web::Data::new(IndexPage::load("dist/index.html").unwrap()))
|
||||
//.app_data(basic::Config::default().realm("Restricted area"))
|
||||
.service(api::get_setting_by_id)
|
||||
.service(api::get_setting_by_steam_app_id)
|
||||
.service(api::save_setting_with_new_id)
|
||||
})
|
||||
.bind(("0.0.0.0", leaked_args.port))?
|
||||
.run()
|
||||
.await
|
||||
}
|
26
backend/limits_core/Cargo.lock
generated
26
backend/limits_core/Cargo.lock
generated
|
@ -2,18 +2,11 @@
|
|||
# It is not intended for manual editing.
|
||||
version = 3
|
||||
|
||||
[[package]]
|
||||
name = "itoa"
|
||||
version = "1.0.8"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "62b02a5381cc465bd3041d84623d0fa3b66738b52b8e2fc3bab8ad63ab032f4a"
|
||||
|
||||
[[package]]
|
||||
name = "limits_core"
|
||||
version = "2.0.1"
|
||||
version = "3.0.0"
|
||||
dependencies = [
|
||||
"serde",
|
||||
"serde_json",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -34,12 +27,6 @@ dependencies = [
|
|||
"proc-macro2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ryu"
|
||||
version = "1.0.14"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "fe232bdf6be8c8de797b22184ee71118d63780ea42ac85b61d1baa6d3b782ae9"
|
||||
|
||||
[[package]]
|
||||
name = "serde"
|
||||
version = "1.0.166"
|
||||
|
@ -60,17 +47,6 @@ dependencies = [
|
|||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde_json"
|
||||
version = "1.0.99"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "46266871c240a00b8f503b877622fe33430b3c7d963bdc0f2adc511e54a1eae3"
|
||||
dependencies = [
|
||||
"itoa",
|
||||
"ryu",
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "syn"
|
||||
version = "2.0.23"
|
||||
|
|
|
@ -1,10 +1,9 @@
|
|||
[package]
|
||||
name = "limits_core"
|
||||
version = "2.0.1"
|
||||
version = "3.0.0"
|
||||
edition = "2021"
|
||||
|
||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
|
||||
[dependencies]
|
||||
serde = { version = "1.0", features = ["derive"] }
|
||||
serde_json = "1.0"
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
use std::default::Default;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use std::default::Default;
|
||||
|
||||
/// Base JSON limits information
|
||||
#[derive(Serialize, Deserialize, Debug, Clone)]
|
||||
|
@ -20,7 +20,7 @@ impl Default for Base {
|
|||
name: "Steam Deck Custom".to_owned(),
|
||||
conditions: super::Conditions {
|
||||
dmi: None,
|
||||
cpuinfo: Some("model name\t: AMD Custom APU 0405\n".to_owned()),
|
||||
cpuinfo: Some("model name\t: AMD Custom APU (0405)|(0932)\n".to_owned()),
|
||||
os: None,
|
||||
command: None,
|
||||
file_exists: Some("./pt_oc.json".into()),
|
||||
|
@ -35,7 +35,7 @@ impl Default for Base {
|
|||
name: "Steam Deck".to_owned(),
|
||||
conditions: super::Conditions {
|
||||
dmi: None,
|
||||
cpuinfo: Some("model name\t: AMD Custom APU 0405\n".to_owned()),
|
||||
cpuinfo: Some("model name\t: AMD Custom APU (0405)|(0932)\n".to_owned()),
|
||||
os: None,
|
||||
command: None,
|
||||
file_exists: None,
|
||||
|
@ -131,7 +131,7 @@ impl Default for Base {
|
|||
name: "AMD R7 6800U".to_owned(),
|
||||
conditions: super::Conditions {
|
||||
dmi: None,
|
||||
cpuinfo: Some("model name\t+: AMD Ryzen 7 6800U\n".to_owned()),
|
||||
cpuinfo: Some("model name\t+: AMD Ryzen 7 6800U( with Radeon Graphics)?\n".to_owned()),
|
||||
os: None,
|
||||
command: None,
|
||||
file_exists: None,
|
||||
|
@ -174,8 +174,8 @@ impl Default for Base {
|
|||
super::DeveloperMessage {
|
||||
id: 1,
|
||||
title: "Welcome".to_owned(),
|
||||
body: "Thanks for installing PowerTools! For more information, please check the wiki. For bugs and requests, please create an issue on GitHub.".to_owned(),
|
||||
url: Some("https://github.com/NGnius/PowerTools/wiki".to_owned()),
|
||||
body: "Thanks for installing PowerTools! For more information, please check the wiki. For bugs and requests, please create an issue.".to_owned(),
|
||||
url: Some("https://git.ngni.us/NG-SD-Plugins/PowerTools/wiki".to_owned()),
|
||||
}
|
||||
],
|
||||
refresh: Some("http://limits.ngni.us:45000/powertools/v1".to_owned())
|
||||
|
|
341
backend/limits_core/src/json_v2/base.rs
Normal file
341
backend/limits_core/src/json_v2/base.rs
Normal file
|
@ -0,0 +1,341 @@
|
|||
use serde::{Deserialize, Serialize};
|
||||
use std::default::Default;
|
||||
|
||||
/// Base JSON limits information
|
||||
#[derive(Serialize, Deserialize, Debug, Clone)]
|
||||
pub struct Base {
|
||||
/// System-specific configurations
|
||||
pub configs: Vec<super::Config>,
|
||||
/// Server messages
|
||||
pub messages: Vec<super::DeveloperMessage>,
|
||||
/// Base URL for the config store
|
||||
pub store: String,
|
||||
/// URL from which to grab the next update
|
||||
pub refresh: Option<String>,
|
||||
}
|
||||
|
||||
impl Default for Base {
|
||||
fn default() -> Self {
|
||||
Base {
|
||||
configs: vec![
|
||||
super::Config {
|
||||
name: "Devs mode best mode".to_owned(),
|
||||
conditions: super::Conditions {
|
||||
dmi: None,
|
||||
cpuinfo: None,
|
||||
os: None,
|
||||
file_exists: Some("/etc/powertools_dev_mode".into()),
|
||||
},
|
||||
limits: super::Limits {
|
||||
cpu: super::Limit {
|
||||
provider: super::CpuLimitType::DevMode,
|
||||
limits: super::GenericCpusLimit::default_for(super::CpuLimitType::DevMode),
|
||||
},
|
||||
gpu: super::Limit {
|
||||
provider: super::GpuLimitType::DevMode,
|
||||
limits: super::GenericGpuLimit::default_for(super::GpuLimitType::DevMode),
|
||||
},
|
||||
battery: super::Limit {
|
||||
provider: super::BatteryLimitType::DevMode,
|
||||
limits: super::GenericBatteryLimit::default_for(super::BatteryLimitType::DevMode),
|
||||
},
|
||||
}
|
||||
},
|
||||
super::Config {
|
||||
name: "Steam Deck".to_owned(),
|
||||
conditions: super::Conditions {
|
||||
dmi: None,
|
||||
cpuinfo: Some("model name\t: AMD Custom APU 0405\n".to_owned()),
|
||||
os: None,
|
||||
file_exists: None,
|
||||
},
|
||||
limits: super::Limits {
|
||||
cpu: super::Limit {
|
||||
provider: super::CpuLimitType::SteamDeck,
|
||||
limits: super::GenericCpusLimit::default_for(super::CpuLimitType::SteamDeck),
|
||||
},
|
||||
gpu: super::Limit {
|
||||
provider: super::GpuLimitType::SteamDeck,
|
||||
limits: super::GenericGpuLimit::default_for(super::GpuLimitType::SteamDeck),
|
||||
},
|
||||
battery: super::Limit {
|
||||
provider: super::BatteryLimitType::SteamDeck,
|
||||
limits: super::GenericBatteryLimit::default_for(super::BatteryLimitType::SteamDeck),
|
||||
},
|
||||
}
|
||||
},
|
||||
super::Config {
|
||||
name: "Steam Deck OLED".to_owned(),
|
||||
conditions: super::Conditions {
|
||||
dmi: None,
|
||||
cpuinfo: Some("model name\t: AMD Custom APU 0932\n".to_owned()),
|
||||
os: None,
|
||||
file_exists: None,
|
||||
},
|
||||
limits: super::Limits {
|
||||
cpu: super::Limit {
|
||||
provider: super::CpuLimitType::SteamDeckOLED,
|
||||
limits: super::GenericCpusLimit::default_for(super::CpuLimitType::SteamDeckOLED),
|
||||
},
|
||||
gpu: super::Limit {
|
||||
provider: super::GpuLimitType::SteamDeckOLED,
|
||||
limits: super::GenericGpuLimit::default_for(super::GpuLimitType::SteamDeckOLED),
|
||||
},
|
||||
battery: super::Limit {
|
||||
provider: super::BatteryLimitType::SteamDeckOLED,
|
||||
limits: super::GenericBatteryLimit::default_for(super::BatteryLimitType::SteamDeckOLED),
|
||||
},
|
||||
}
|
||||
},
|
||||
super::Config {
|
||||
name: "AMD R3 2300U".to_owned(),
|
||||
conditions: super::Conditions {
|
||||
dmi: None,
|
||||
cpuinfo: Some("model name\t+: AMD Ryzen 3 2300U\n".to_owned()),
|
||||
os: None,
|
||||
file_exists: None,
|
||||
},
|
||||
limits: super::Limits {
|
||||
cpu: super::CpuLimit {
|
||||
provider: super::CpuLimitType::GenericAMD,
|
||||
limits: super::GenericCpusLimit {
|
||||
cpus: vec![
|
||||
super::GenericCpuLimit {
|
||||
clock_min: Some(super::RangeLimit { min: Some(1000), max: Some(3700) }),
|
||||
clock_max: Some(super::RangeLimit { min: Some(1000), max: Some(3700) }),
|
||||
clock_step: Some(100),
|
||||
skip_resume_reclock: false,
|
||||
..Default::default()
|
||||
}; 4],
|
||||
global_governors: true,
|
||||
..Default::default()
|
||||
}
|
||||
},
|
||||
gpu: super::GpuLimit {
|
||||
provider: super::GpuLimitType::GenericAMD,
|
||||
limits: super::GenericGpuLimit {
|
||||
fast_ppt: Some(super::RangeLimit { min: Some(1_000), max: Some(25_000) }),
|
||||
slow_ppt: Some(super::RangeLimit { min: Some(1_000), max: Some(25_000) }),
|
||||
ppt_step: Some(1_000),
|
||||
ppt_divisor: Some(1_000),
|
||||
clock_min: Some(super::RangeLimit { min: Some(400), max: Some(1100) }),
|
||||
clock_max: Some(super::RangeLimit { min: Some(400), max: Some(1100) }),
|
||||
clock_step: Some(100),
|
||||
..Default::default()
|
||||
}
|
||||
},
|
||||
battery: super::Limit {
|
||||
provider: super::BatteryLimitType::Generic,
|
||||
limits: super::GenericBatteryLimit::default_for(super::BatteryLimitType::Generic),
|
||||
}
|
||||
},
|
||||
},
|
||||
super::Config {
|
||||
name: "AMD R5 5560U".to_owned(),
|
||||
conditions: super::Conditions {
|
||||
dmi: None,
|
||||
cpuinfo: Some("model name\t+: AMD Ryzen 5 5560U\n".to_owned()),
|
||||
os: None,
|
||||
file_exists: None,
|
||||
},
|
||||
limits: super::Limits {
|
||||
cpu: super::CpuLimit {
|
||||
provider: super::CpuLimitType::GenericAMD,
|
||||
limits: super::GenericCpusLimit {
|
||||
cpus: vec![
|
||||
super::GenericCpuLimit {
|
||||
clock_min: Some(super::RangeLimit { min: Some(1000), max: Some(4000) }),
|
||||
clock_max: Some(super::RangeLimit { min: Some(1000), max: Some(4000) }),
|
||||
clock_step: Some(100),
|
||||
skip_resume_reclock: false,
|
||||
..Default::default()
|
||||
}; 12], // 6 cores with SMTx2
|
||||
global_governors: true,
|
||||
..Default::default()
|
||||
}
|
||||
},
|
||||
gpu: super::GpuLimit {
|
||||
provider: super::GpuLimitType::GenericAMD,
|
||||
limits: super::GenericGpuLimit {
|
||||
fast_ppt: Some(super::RangeLimit { min: Some(1_000), max: Some(25_000) }),
|
||||
slow_ppt: Some(super::RangeLimit { min: Some(1_000), max: Some(25_000) }),
|
||||
ppt_step: Some(1_000),
|
||||
ppt_divisor: Some(1_000),
|
||||
clock_min: Some(super::RangeLimit { min: Some(400), max: Some(1600) }),
|
||||
clock_max: Some(super::RangeLimit { min: Some(400), max: Some(1600) }),
|
||||
clock_step: Some(100),
|
||||
..Default::default()
|
||||
}
|
||||
},
|
||||
battery: super::Limit {
|
||||
provider: super::BatteryLimitType::Generic,
|
||||
limits: super::GenericBatteryLimit::default_for(super::BatteryLimitType::Generic),
|
||||
}
|
||||
}
|
||||
},
|
||||
super::Config {
|
||||
name: "AMD R7 5825U".to_owned(),
|
||||
conditions: super::Conditions {
|
||||
dmi: None,
|
||||
cpuinfo: Some("model name\t+: AMD Ryzen 7 5825U\n".to_owned()),
|
||||
os: None,
|
||||
file_exists: None,
|
||||
},
|
||||
limits: super::Limits {
|
||||
cpu: super::CpuLimit {
|
||||
provider: super::CpuLimitType::GenericAMD,
|
||||
limits: super::GenericCpusLimit {
|
||||
cpus: vec![
|
||||
super::GenericCpuLimit {
|
||||
clock_min: Some(super::RangeLimit { min: Some(1000), max: Some(4500) }),
|
||||
clock_max: Some(super::RangeLimit { min: Some(1000), max: Some(4500) }),
|
||||
clock_step: Some(100),
|
||||
skip_resume_reclock: false,
|
||||
..Default::default()
|
||||
}; 16], // 8 cores with SMTx2
|
||||
global_governors: true,
|
||||
..Default::default()
|
||||
}
|
||||
},
|
||||
gpu: super::GpuLimit {
|
||||
provider: super::GpuLimitType::GenericAMD,
|
||||
limits: super::GenericGpuLimit {
|
||||
fast_ppt: Some(super::RangeLimit { min: Some(1_000), max: Some(28_000) }),
|
||||
slow_ppt: Some(super::RangeLimit { min: Some(1_000), max: Some(28_000) }),
|
||||
ppt_step: Some(1_000),
|
||||
ppt_divisor: Some(1_000),
|
||||
clock_min: Some(super::RangeLimit { min: Some(400), max: Some(2200) }),
|
||||
clock_max: Some(super::RangeLimit { min: Some(400), max: Some(2200) }),
|
||||
clock_step: Some(100),
|
||||
..Default::default()
|
||||
}
|
||||
},
|
||||
battery: super::Limit {
|
||||
provider: super::BatteryLimitType::Generic,
|
||||
limits: super::GenericBatteryLimit::default_for(super::BatteryLimitType::Generic),
|
||||
}
|
||||
}
|
||||
},
|
||||
super::Config {
|
||||
name: "AMD R7 6800U".to_owned(),
|
||||
conditions: super::Conditions {
|
||||
dmi: None,
|
||||
cpuinfo: Some("model name\t+: AMD Ryzen 7 6800U( with Radeon Graphics)?\n".to_owned()),
|
||||
os: None,
|
||||
file_exists: None,
|
||||
},
|
||||
limits: super::Limits {
|
||||
cpu: super::CpuLimit {
|
||||
provider: super::CpuLimitType::GenericAMD,
|
||||
limits: super::GenericCpusLimit {
|
||||
cpus: vec![
|
||||
super::GenericCpuLimit {
|
||||
clock_min: Some(super::RangeLimit { min: Some(1000), max: Some(4700) }),
|
||||
clock_max: Some(super::RangeLimit { min: Some(1000), max: Some(4700) }),
|
||||
clock_step: Some(100),
|
||||
skip_resume_reclock: false,
|
||||
..Default::default()
|
||||
}; 16], // 8 cores with SMTx2
|
||||
global_governors: true,
|
||||
..Default::default()
|
||||
}
|
||||
},
|
||||
gpu: super::GpuLimit {
|
||||
provider: super::GpuLimitType::GenericAMD,
|
||||
limits: super::GenericGpuLimit {
|
||||
fast_ppt: Some(super::RangeLimit { min: Some(1_000), max: Some(28_000) }),
|
||||
slow_ppt: Some(super::RangeLimit { min: Some(1_000), max: Some(28_000) }),
|
||||
ppt_step: Some(1_000),
|
||||
ppt_divisor: Some(1_000),
|
||||
clock_min: Some(super::RangeLimit { min: Some(400), max: Some(2200) }),
|
||||
clock_max: Some(super::RangeLimit { min: Some(400), max: Some(2200) }),
|
||||
clock_step: Some(100),
|
||||
..Default::default()
|
||||
}
|
||||
},
|
||||
battery: super::Limit {
|
||||
provider: super::BatteryLimitType::Generic,
|
||||
limits: super::GenericBatteryLimit::default_for(super::BatteryLimitType::Generic),
|
||||
}
|
||||
}
|
||||
},
|
||||
super::Config {
|
||||
name: "AMD R7 7840U".to_owned(),
|
||||
conditions: super::Conditions {
|
||||
dmi: None,
|
||||
cpuinfo: Some("model name\\s+: AMD Ryzen 7 7840U( w\\/ Radeon 780M Graphics)?\n".to_owned()),
|
||||
os: None,
|
||||
file_exists: None,
|
||||
},
|
||||
limits: super::Limits {
|
||||
cpu: super::CpuLimit {
|
||||
provider: super::CpuLimitType::GenericAMD,
|
||||
limits: super::GenericCpusLimit {
|
||||
cpus: vec![
|
||||
super::GenericCpuLimit {
|
||||
clock_min: Some(super::RangeLimit { min: Some(400), max: Some(5100) }),
|
||||
clock_max: Some(super::RangeLimit { min: Some(400), max: Some(5100) }),
|
||||
clock_step: Some(100),
|
||||
skip_resume_reclock: false,
|
||||
..Default::default()
|
||||
}; 16], // 8 cores with SMTx2
|
||||
global_governors: true,
|
||||
..Default::default()
|
||||
}
|
||||
},
|
||||
gpu: super::GpuLimit {
|
||||
provider: super::GpuLimitType::GenericAMD,
|
||||
limits: super::GenericGpuLimit {
|
||||
fast_ppt: Some(super::RangeLimit { min: Some(1_000), max: Some(53_000) }),
|
||||
slow_ppt: Some(super::RangeLimit { min: Some(1_000), max: Some(43_000) }),
|
||||
ppt_step: Some(1_000),
|
||||
ppt_divisor: Some(1_000),
|
||||
clock_min: None,
|
||||
clock_max: None,
|
||||
clock_step: None,
|
||||
..Default::default()
|
||||
}
|
||||
},
|
||||
battery: super::Limit {
|
||||
provider: super::BatteryLimitType::Generic,
|
||||
limits: super::GenericBatteryLimit::default_for(super::BatteryLimitType::Generic),
|
||||
}
|
||||
}
|
||||
},
|
||||
super::Config {
|
||||
name: "Fallback".to_owned(),
|
||||
conditions: super::Conditions {
|
||||
dmi: None,
|
||||
cpuinfo: None,
|
||||
os: None,
|
||||
file_exists: None,
|
||||
},
|
||||
limits: super::Limits {
|
||||
cpu: super::Limit {
|
||||
provider: super::CpuLimitType::Unknown,
|
||||
limits: super::GenericCpusLimit::default_for(super::CpuLimitType::Unknown),
|
||||
},
|
||||
gpu: super::Limit {
|
||||
provider: super::GpuLimitType::Unknown,
|
||||
limits: super::GenericGpuLimit::default_for(super::GpuLimitType::Unknown),
|
||||
},
|
||||
battery: super::Limit {
|
||||
provider: super::BatteryLimitType::Unknown,
|
||||
limits: super::GenericBatteryLimit::default_for(super::BatteryLimitType::Unknown),
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
messages: vec![
|
||||
super::DeveloperMessage {
|
||||
id: 1,
|
||||
title: "Welcome".to_owned(),
|
||||
body: "Thanks for installing PowerTools! For more information, please check the wiki. For bugs and requests, please create an issue.".to_owned(),
|
||||
url: Some("https://git.ngni.us/NG-SD-Plugins/PowerTools/wiki".to_owned()),
|
||||
}
|
||||
],
|
||||
store: "https://powertools.ngni.us".to_owned(),
|
||||
refresh: Some("http://limits.ngni.us:45000/powertools/v2".to_owned())
|
||||
}
|
||||