From 376638672659659f6cd5ea5c7e142cc9d06f6b7a Mon Sep 17 00:00:00 2001 From: "NGnius (Graham)" Date: Fri, 2 Dec 2022 21:12:13 -0500 Subject: [PATCH] Add hardware limits provider and auto detection with online updater (cached locally) --- .gitignore | 1 + backend/Cargo.lock | 129 +++ backend/Cargo.toml | 9 +- backend/limits_core/Cargo.toml | 10 + backend/limits_core/src/json/base.rs | 49 + backend/limits_core/src/json/battery_limit.rs | 15 + backend/limits_core/src/json/conditions.rs | 20 + backend/limits_core/src/json/config.rs | 8 + backend/limits_core/src/json/cpu_limit.rs | 15 + backend/limits_core/src/json/gpu_limit.rs | 15 + backend/limits_core/src/json/limits.rs | 9 + backend/limits_core/src/json/mod.rs | 17 + backend/limits_core/src/json/target.rs | 9 + backend/limits_core/src/lib.rs | 1 + backend/limits_srv/Cargo.lock | 1026 +++++++++++++++++ backend/limits_srv/Cargo.toml | 12 + backend/limits_srv/pt_limits.json | 43 + backend/limits_srv/src/main.rs | 53 + backend/src/consts.rs | 2 + backend/src/main.rs | 3 +- backend/src/persist/battery.rs | 2 +- backend/src/persist/cpu.rs | 2 +- backend/src/persist/driver.rs | 4 +- backend/src/persist/general.rs | 2 +- backend/src/persist/gpu.rs | 2 +- backend/src/settings/detect/auto_detect.rs | 191 +++ backend/src/settings/detect/limits_worker.rs | 110 ++ backend/src/settings/detect/mod.rs | 5 + backend/src/settings/detect/utility.rs | 3 + backend/src/settings/driver.rs | 172 +-- backend/src/settings/generic/battery.rs | 10 + backend/src/settings/generic/cpu.rs | 37 + backend/src/settings/generic/gpu.rs | 15 +- backend/src/settings/mod.rs | 2 + 34 files changed, 1864 insertions(+), 139 deletions(-) create mode 100644 backend/limits_core/Cargo.toml create mode 100644 backend/limits_core/src/json/base.rs create mode 100644 backend/limits_core/src/json/battery_limit.rs create mode 100644 backend/limits_core/src/json/conditions.rs create mode 100644 backend/limits_core/src/json/config.rs create mode 100644 backend/limits_core/src/json/cpu_limit.rs create mode 100644 backend/limits_core/src/json/gpu_limit.rs create mode 100644 backend/limits_core/src/json/limits.rs create mode 100644 backend/limits_core/src/json/mod.rs create mode 100644 backend/limits_core/src/json/target.rs create mode 100644 backend/limits_core/src/lib.rs create mode 100644 backend/limits_srv/Cargo.lock create mode 100644 backend/limits_srv/Cargo.toml create mode 100644 backend/limits_srv/pt_limits.json create mode 100644 backend/limits_srv/src/main.rs create mode 100644 backend/src/settings/detect/auto_detect.rs create mode 100644 backend/src/settings/detect/limits_worker.rs create mode 100644 backend/src/settings/detect/mod.rs create mode 100644 backend/src/settings/detect/utility.rs diff --git a/.gitignore b/.gitignore index ed38553..22cbe24 100644 --- a/.gitignore +++ b/.gitignore @@ -44,3 +44,4 @@ yalc.lock /backend/target /bin /backend/out +/**/target diff --git a/backend/Cargo.lock b/backend/Cargo.lock index 94ef8d0..3093cd0 100644 --- a/backend/Cargo.lock +++ b/backend/Cargo.lock @@ -2,6 +2,12 @@ # It is not intended for manual editing. version = 3 +[[package]] +name = "adler" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" + [[package]] name = "aead" version = "0.4.3" @@ -38,6 +44,30 @@ dependencies = [ "zeroize", ] +[[package]] +name = "aho-corasick" +version = "0.7.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cc936419f96fa211c1b9166887b38e5e40b19958e5b895be7c1f93adec7071ac" +dependencies = [ + "memchr", +] + +[[package]] +name = "alloc-no-stdlib" +version = "2.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cc7bb162ec39d46ab1ca8c77bf72e890535becd1751bb45f64c597edb4c8c6b3" + +[[package]] +name = "alloc-stdlib" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "94fb8275041c72129eb51b7d0322c29b8387a0386127718b096429201a5d6ece" +dependencies = [ + "alloc-no-stdlib", +] + [[package]] name = "async-recursion" version = "1.0.0" @@ -96,6 +126,16 @@ dependencies = [ "generic-array", ] +[[package]] +name = "brotli-decompressor" +version = "2.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "59ad2d4653bf5ca36ae797b1f4bb4dbddb60ce49ca4aed8a2ce4829f60425b80" +dependencies = [ + "alloc-no-stdlib", + "alloc-stdlib", +] + [[package]] name = "buf_redux" version = "0.8.4" @@ -124,6 +164,12 @@ version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" +[[package]] +name = "chunked_transfer" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fff857943da45f546682664a79488be82e69e43c1a7a2307679ab9afb3a66d2e" + [[package]] name = "cipher" version = "0.3.0" @@ -142,6 +188,15 @@ dependencies = [ "libc", ] +[[package]] +name = "crc32fast" +version = "1.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b540bd8bc810d3885c6ea91e2018302f68baba2129ab3e88f32389ee9370880d" +dependencies = [ + "cfg-if", +] + [[package]] name = "crypto-common" version = "0.1.6" @@ -180,6 +235,15 @@ dependencies = [ "crypto-common", ] +[[package]] +name = "encoding_rs" +version = "0.8.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9852635589dc9f9ea1b6fe9f05b50ef208c85c834a562f0c6abb1c475736ec2b" +dependencies = [ + "cfg-if", +] + [[package]] name = "fastrand" version = "1.8.0" @@ -189,6 +253,16 @@ dependencies = [ "instant", ] +[[package]] +name = "flate2" +version = "1.0.25" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a8a2db397cb1c8772f31494cb8917e48cd1e64f0fa7efac59fbd741a0a8ce841" +dependencies = [ + "crc32fast", + "miniz_oxide", +] + [[package]] name = "fnv" version = "1.0.7" @@ -433,6 +507,14 @@ version = "0.2.126" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "349d5a591cd28b49e1d1037471617a32ddcda5731b99419008085f72d5a53836" +[[package]] +name = "limits_core" +version = "0.1.0" +dependencies = [ + "serde", + "serde_json", +] + [[package]] name = "log" version = "0.4.17" @@ -470,6 +552,15 @@ dependencies = [ "unicase", ] +[[package]] +name = "miniz_oxide" +version = "0.6.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b275950c28b37e794e8c55d88aeb5e139d0ce23fdbbeda68f8d7174abdf9e8fa" +dependencies = [ + "adler", +] + [[package]] name = "mio" version = "0.8.4" @@ -592,11 +683,14 @@ name = "powertools-rs" version = "1.1.0" dependencies = [ "async-trait", + "limits_core", "log", + "regex", "serde", "serde_json", "simplelog", "tokio", + "ureq", "usdpl-back", ] @@ -669,6 +763,23 @@ dependencies = [ "bitflags", ] +[[package]] +name = "regex" +version = "1.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e076559ef8e241f2ae3479e36f97bd5741c0330689e217ad51ce2c76808b868a" +dependencies = [ + "aho-corasick", + "memchr", + "regex-syntax", +] + +[[package]] +name = "regex-syntax" +version = "0.6.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "456c603be3e8d448b072f410900c09faf164fbce2d480456f50eea6e25f9c848" + [[package]] name = "remove_dir_all" version = "0.5.3" @@ -1063,6 +1174,24 @@ dependencies = [ "subtle", ] +[[package]] +name = "ureq" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b97acb4c28a254fd7a4aeec976c46a7fa404eac4d7c134b30c75144846d7cb8f" +dependencies = [ + "base64", + "brotli-decompressor", + "chunked_transfer", + "encoding_rs", + "flate2", + "log", + "once_cell", + "serde", + "serde_json", + "url", +] + [[package]] name = "url" version = "2.2.2" diff --git a/backend/Cargo.toml b/backend/Cargo.toml index 5b9f403..ae4ad1e 100644 --- a/backend/Cargo.toml +++ b/backend/Cargo.toml @@ -18,11 +18,18 @@ async-trait = { version = "0.1" } log = "0.4" simplelog = "0.12" +# limits & driver functionality +limits_core = { version = "0.1.0", path = "./limits_core" } +regex = "1" +# ureq's tls feature does not like musl targets +ureq = { version = "2.5", features = ["json", "gzip", "brotli", "charset"], default-features = false, optional = true } + [features] -default = [] +default = ["online"] decky = ["usdpl-back/decky"] crankshaft = ["usdpl-back/crankshaft"] encrypt = ["usdpl-back/encrypt"] +online = ["ureq"] [profile.release] debug = false diff --git a/backend/limits_core/Cargo.toml b/backend/limits_core/Cargo.toml new file mode 100644 index 0000000..58ceabd --- /dev/null +++ b/backend/limits_core/Cargo.toml @@ -0,0 +1,10 @@ +[package] +name = "limits_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"] } +serde_json = "1.0" diff --git a/backend/limits_core/src/json/base.rs b/backend/limits_core/src/json/base.rs new file mode 100644 index 0000000..c25e5de --- /dev/null +++ b/backend/limits_core/src/json/base.rs @@ -0,0 +1,49 @@ +use std::default::Default; +use serde::{Deserialize, Serialize}; + +/// Base JSON limits information +#[derive(Serialize, Deserialize, Debug, Clone)] +pub struct Base { + /// System-specific configurations + pub configs: Vec, + /// URL from which to grab the next update + pub refresh: Option, +} + +impl Default for Base { + fn default() -> Self { + Base { + configs: vec![ + 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, + command: None, + }, + limits: vec![ + super::Limits::Cpu(super::CpuLimit::SteamDeck), + super::Limits::Gpu(super::GpuLimit::SteamDeck), + super::Limits::Battery(super::BatteryLimit::SteamDeck), + ] + }, + super::Config { + name: "Fallback".to_owned(), + conditions: super::Conditions { + dmi: None, + cpuinfo: None, + os: None, + command: None, + }, + limits: vec![ + super::Limits::Cpu(super::CpuLimit::Unknown), + super::Limits::Gpu(super::GpuLimit::Unknown), + super::Limits::Battery(super::BatteryLimit::Unknown), + ] + } + ], + refresh: Some("http://limits.ngni.us:45000/powertools/v1".to_owned()) + } + } +} diff --git a/backend/limits_core/src/json/battery_limit.rs b/backend/limits_core/src/json/battery_limit.rs new file mode 100644 index 0000000..ca44689 --- /dev/null +++ b/backend/limits_core/src/json/battery_limit.rs @@ -0,0 +1,15 @@ +use serde::{Deserialize, Serialize}; + +#[derive(Serialize, Deserialize, Debug, Clone)] +#[serde(tag = "target")] +pub enum BatteryLimit { + SteamDeck, + SteamDeckAdvance, + Generic(GenericBatteryLimit), + Unknown, +} + +#[derive(Serialize, Deserialize, Debug, Clone)] +pub struct GenericBatteryLimit { + /* TODO */ +} diff --git a/backend/limits_core/src/json/conditions.rs b/backend/limits_core/src/json/conditions.rs new file mode 100644 index 0000000..2016cb9 --- /dev/null +++ b/backend/limits_core/src/json/conditions.rs @@ -0,0 +1,20 @@ +use serde::{Deserialize, Serialize}; + +/// Conditions under which a config applies +#[derive(Serialize, Deserialize, Debug, Clone)] +pub struct Conditions { + /// Regex pattern for dmidecode output + pub dmi: Option, + /// Regex pattern for /proc/cpuinfo reading + pub cpuinfo: Option, + /// Regex pattern for /etc/os-release reading + pub os: Option, + /// Custom command to run, where an exit code of 0 means a successful match + pub command: Option, +} + +impl Conditions { + pub fn is_empty(&self) -> bool { + self.dmi.is_none() && self.cpuinfo.is_none() && self.os.is_none() && self.command.is_none() + } +} diff --git a/backend/limits_core/src/json/config.rs b/backend/limits_core/src/json/config.rs new file mode 100644 index 0000000..57d70ac --- /dev/null +++ b/backend/limits_core/src/json/config.rs @@ -0,0 +1,8 @@ +use serde::{Deserialize, Serialize}; + +#[derive(Serialize, Deserialize, Debug, Clone)] +pub struct Config { + pub name: String, + pub conditions: super::Conditions, + pub limits: Vec, +} diff --git a/backend/limits_core/src/json/cpu_limit.rs b/backend/limits_core/src/json/cpu_limit.rs new file mode 100644 index 0000000..d413cda --- /dev/null +++ b/backend/limits_core/src/json/cpu_limit.rs @@ -0,0 +1,15 @@ +use serde::{Deserialize, Serialize}; + +#[derive(Serialize, Deserialize, Debug, Clone)] +#[serde(tag = "target")] +pub enum CpuLimit { + SteamDeck, + SteamDeckAdvance, + Generic(GenericCpuLimit), + Unknown, +} + +#[derive(Serialize, Deserialize, Debug, Clone)] +pub struct GenericCpuLimit { + /* TODO */ +} diff --git a/backend/limits_core/src/json/gpu_limit.rs b/backend/limits_core/src/json/gpu_limit.rs new file mode 100644 index 0000000..712b8b1 --- /dev/null +++ b/backend/limits_core/src/json/gpu_limit.rs @@ -0,0 +1,15 @@ +use serde::{Deserialize, Serialize}; + +#[derive(Serialize, Deserialize, Debug, Clone)] +#[serde(tag = "target")] +pub enum GpuLimit { + SteamDeck, + SteamDeckAdvance, + Generic(GenericGpuLimit), + Unknown, +} + +#[derive(Serialize, Deserialize, Debug, Clone)] +pub struct GenericGpuLimit { + /* TODO */ +} diff --git a/backend/limits_core/src/json/limits.rs b/backend/limits_core/src/json/limits.rs new file mode 100644 index 0000000..10abd4e --- /dev/null +++ b/backend/limits_core/src/json/limits.rs @@ -0,0 +1,9 @@ +use serde::{Deserialize, Serialize}; + +#[derive(Serialize, Deserialize, Debug, Clone)] +#[serde(tag = "limits")] +pub enum Limits { + Cpu(super::CpuLimit), + Gpu(super::GpuLimit), + Battery(super::BatteryLimit), +} diff --git a/backend/limits_core/src/json/mod.rs b/backend/limits_core/src/json/mod.rs new file mode 100644 index 0000000..250e218 --- /dev/null +++ b/backend/limits_core/src/json/mod.rs @@ -0,0 +1,17 @@ +mod base; +mod battery_limit; +mod conditions; +mod config; +mod cpu_limit; +mod gpu_limit; +mod limits; +mod target; + +pub use base::Base; +pub use battery_limit::{BatteryLimit, GenericBatteryLimit}; +pub use conditions::Conditions; +pub use cpu_limit::{CpuLimit, GenericCpuLimit}; +pub use gpu_limit::{GpuLimit, GenericGpuLimit}; +pub use config::Config; +pub use limits::Limits; +pub use target::Target; diff --git a/backend/limits_core/src/json/target.rs b/backend/limits_core/src/json/target.rs new file mode 100644 index 0000000..768df6f --- /dev/null +++ b/backend/limits_core/src/json/target.rs @@ -0,0 +1,9 @@ +use serde::{Deserialize, Serialize}; + +#[derive(Serialize, Deserialize, Debug, Clone)] +pub enum Target { + SteamDeck, + SteamDeckAdvance, + Generic, + Unknown, +} diff --git a/backend/limits_core/src/lib.rs b/backend/limits_core/src/lib.rs new file mode 100644 index 0000000..22fdbb3 --- /dev/null +++ b/backend/limits_core/src/lib.rs @@ -0,0 +1 @@ +pub mod json; diff --git a/backend/limits_srv/Cargo.lock b/backend/limits_srv/Cargo.lock new file mode 100644 index 0000000..0bb3b66 --- /dev/null +++ b/backend/limits_srv/Cargo.lock @@ -0,0 +1,1026 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 3 + +[[package]] +name = "autocfg" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" + +[[package]] +name = "base64" +version = "0.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9e1b586273c5702936fe7b7d6896644d8be71e6314cfe09d3167c95f712589e8" + +[[package]] +name = "bitflags" +version = "1.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" + +[[package]] +name = "block-buffer" +version = "0.10.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "69cce20737498f97b993470a6e536b8523f0af7892a4f928cceb1ac5e52ebe7e" +dependencies = [ + "generic-array", +] + +[[package]] +name = "buf_redux" +version = "0.8.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b953a6887648bb07a535631f2bc00fbdb2a2216f135552cb3f534ed136b9c07f" +dependencies = [ + "memchr", + "safemem", +] + +[[package]] +name = "byteorder" +version = "1.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610" + +[[package]] +name = "bytes" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dfb24e866b15a1af2a1b663f10c6b6b8f397a84aadb828f12e5b289ec23a3a3c" + +[[package]] +name = "cfg-if" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" + +[[package]] +name = "cpufeatures" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "28d997bd5e24a5928dd43e46dc529867e207907fe0b239c3477d924f7f2ca320" +dependencies = [ + "libc", +] + +[[package]] +name = "crypto-common" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3" +dependencies = [ + "generic-array", + "typenum", +] + +[[package]] +name = "digest" +version = "0.10.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8168378f4e5023e7218c89c891c0fd8ecdb5e5e4f18cb78f38cf245dd021e76f" +dependencies = [ + "block-buffer", + "crypto-common", +] + +[[package]] +name = "fastrand" +version = "1.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a7a407cfaa3385c4ae6b23e84623d48c2798d06e3e6a1878f7f59f17b3f86499" +dependencies = [ + "instant", +] + +[[package]] +name = "fnv" +version = "1.0.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" + +[[package]] +name = "form_urlencoded" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a9c384f161156f5260c24a097c56119f9be8c798586aecc13afbcbe7b7e26bf8" +dependencies = [ + "percent-encoding", +] + +[[package]] +name = "futures-channel" +version = "0.3.25" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "52ba265a92256105f45b719605a571ffe2d1f0fea3807304b522c1d778f79eed" +dependencies = [ + "futures-core", + "futures-sink", +] + +[[package]] +name = "futures-core" +version = "0.3.25" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "04909a7a7e4633ae6c4a9ab280aeb86da1236243a77b694a49eacd659a4bd3ac" + +[[package]] +name = "futures-sink" +version = "0.3.25" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "39c15cf1a4aa79df40f1bb462fb39676d0ad9e366c2a33b590d7c66f4f81fcf9" + +[[package]] +name = "futures-task" +version = "0.3.25" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2ffb393ac5d9a6eaa9d3fdf37ae2776656b706e200c8e16b1bdb227f5198e6ea" + +[[package]] +name = "futures-util" +version = "0.3.25" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "197676987abd2f9cadff84926f410af1c183608d36641465df73ae8211dc65d6" +dependencies = [ + "futures-core", + "futures-sink", + "futures-task", + "pin-project-lite", + "pin-utils", + "slab", +] + +[[package]] +name = "generic-array" +version = "0.14.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bff49e947297f3312447abdca79f45f4738097cc82b06e72054d2223f601f1b9" +dependencies = [ + "typenum", + "version_check", +] + +[[package]] +name = "getrandom" +version = "0.2.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c05aeb6a22b8f62540c194aac980f2115af067bfe15a0734d7277a768d396b31" +dependencies = [ + "cfg-if", + "libc", + "wasi", +] + +[[package]] +name = "h2" +version = "0.3.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5f9f29bc9dda355256b2916cf526ab02ce0aeaaaf2bad60d65ef3f12f11dd0f4" +dependencies = [ + "bytes", + "fnv", + "futures-core", + "futures-sink", + "futures-util", + "http", + "indexmap", + "slab", + "tokio", + "tokio-util", + "tracing", +] + +[[package]] +name = "hashbrown" +version = "0.12.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" + +[[package]] +name = "headers" +version = "0.3.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f3e372db8e5c0d213e0cd0b9be18be2aca3d44cf2fe30a9d46a65581cd454584" +dependencies = [ + "base64", + "bitflags", + "bytes", + "headers-core", + "http", + "httpdate", + "mime", + "sha1", +] + +[[package]] +name = "headers-core" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e7f66481bfee273957b1f20485a4ff3362987f85b2c236580d81b4eb7a326429" +dependencies = [ + "http", +] + +[[package]] +name = "hermit-abi" +version = "0.1.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "62b467343b94ba476dcb2500d242dadbb39557df889310ac77c5d99100aaac33" +dependencies = [ + "libc", +] + +[[package]] +name = "http" +version = "0.2.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "75f43d41e26995c17e71ee126451dd3941010b0514a81a9d11f3b341debc2399" +dependencies = [ + "bytes", + "fnv", + "itoa", +] + +[[package]] +name = "http-body" +version = "0.4.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d5f38f16d184e36f2408a55281cd658ecbd3ca05cce6d6510a176eca393e26d1" +dependencies = [ + "bytes", + "http", + "pin-project-lite", +] + +[[package]] +name = "httparse" +version = "1.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d897f394bad6a705d5f4104762e116a75639e470d80901eed05a860a95cb1904" + +[[package]] +name = "httpdate" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c4a1e36c821dbe04574f602848a19f742f4fb3c98d40449f11bcad18d6b17421" + +[[package]] +name = "hyper" +version = "0.14.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "034711faac9d2166cb1baf1a2fb0b60b1f277f8492fd72176c17f3515e1abd3c" +dependencies = [ + "bytes", + "futures-channel", + "futures-core", + "futures-util", + "h2", + "http", + "http-body", + "httparse", + "httpdate", + "itoa", + "pin-project-lite", + "socket2", + "tokio", + "tower-service", + "tracing", + "want", +] + +[[package]] +name = "idna" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e14ddfc70884202db2244c223200c204c2bda1bc6e0998d11b5e024d657209e6" +dependencies = [ + "unicode-bidi", + "unicode-normalization", +] + +[[package]] +name = "indexmap" +version = "1.9.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1885e79c1fc4b10f0e172c475f458b7f7b93061064d98c3293e98c5ba0c8b399" +dependencies = [ + "autocfg", + "hashbrown", +] + +[[package]] +name = "instant" +version = "0.1.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a5bbe824c507c5da5956355e86a746d82e0e1464f65d862cc5e71da70e94b2c" +dependencies = [ + "cfg-if", +] + +[[package]] +name = "itoa" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4217ad341ebadf8d8e724e264f13e593e0648f5b3e94b3896a5df283be015ecc" + +[[package]] +name = "libc" +version = "0.2.137" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fc7fcc620a3bff7cdd7a365be3376c97191aeaccc2a603e600951e452615bf89" + +[[package]] +name = "limits_core" +version = "0.1.0" +dependencies = [ + "serde", + "serde_json", +] + +[[package]] +name = "limits_srv" +version = "0.1.0" +dependencies = [ + "limits_core", + "serde_json", + "tokio", + "warp", +] + +[[package]] +name = "log" +version = "0.4.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "abb12e687cfb44aa40f41fc3978ef76448f9b6038cad6aef4259d3c095a2382e" +dependencies = [ + "cfg-if", +] + +[[package]] +name = "memchr" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d" + +[[package]] +name = "mime" +version = "0.3.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2a60c7ce501c71e03a9c9c0d35b861413ae925bd979cc7a4e30d060069aaac8d" + +[[package]] +name = "mime_guess" +version = "2.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4192263c238a5f0d0c6bfd21f336a313a4ce1c450542449ca191bb657b4642ef" +dependencies = [ + "mime", + "unicase", +] + +[[package]] +name = "mio" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e5d732bc30207a6423068df043e3d02e0735b155ad7ce1a6f76fe2baa5b158de" +dependencies = [ + "libc", + "log", + "wasi", + "windows-sys", +] + +[[package]] +name = "multipart" +version = "0.18.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "00dec633863867f29cb39df64a397cdf4a6354708ddd7759f70c7fb51c5f9182" +dependencies = [ + "buf_redux", + "httparse", + "log", + "mime", + "mime_guess", + "quick-error", + "rand", + "safemem", + "tempfile", + "twoway", +] + +[[package]] +name = "num_cpus" +version = "1.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f6058e64324c71e02bc2b150e4f3bc8286db6c83092132ffa3f6b1eab0f9def5" +dependencies = [ + "hermit-abi", + "libc", +] + +[[package]] +name = "once_cell" +version = "1.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "86f0b0d4bf799edbc74508c1e8bf170ff5f41238e5f8225603ca7caaae2b7860" + +[[package]] +name = "percent-encoding" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "478c572c3d73181ff3c2539045f6eb99e5491218eae919370993b890cdbdd98e" + +[[package]] +name = "pin-project" +version = "1.0.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ad29a609b6bcd67fee905812e544992d216af9d755757c05ed2d0e15a74c6ecc" +dependencies = [ + "pin-project-internal", +] + +[[package]] +name = "pin-project-internal" +version = "1.0.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "069bdb1e05adc7a8990dce9cc75370895fbe4e3d58b9b73bf1aee56359344a55" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "pin-project-lite" +version = "0.2.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e0a7ae3ac2f1173085d398531c705756c94a4c56843785df85a60c1a0afac116" + +[[package]] +name = "pin-utils" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" + +[[package]] +name = "ppv-lite86" +version = "0.2.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de" + +[[package]] +name = "proc-macro2" +version = "1.0.47" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5ea3d908b0e36316caf9e9e2c4625cdde190a7e6f440d794667ed17a1855e725" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "quick-error" +version = "1.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a1d01941d82fa2ab50be1e79e6714289dd7cde78eba4c074bc5a4374f650dfe0" + +[[package]] +name = "quote" +version = "1.0.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bbe448f377a7d6961e30f5955f9b8d106c3f5e449d493ee1b125c1d43c2b5179" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "rand" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" +dependencies = [ + "libc", + "rand_chacha", + "rand_core", +] + +[[package]] +name = "rand_chacha" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" +dependencies = [ + "ppv-lite86", + "rand_core", +] + +[[package]] +name = "rand_core" +version = "0.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" +dependencies = [ + "getrandom", +] + +[[package]] +name = "redox_syscall" +version = "0.2.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fb5a58c1855b4b6819d59012155603f0b22ad30cad752600aadfcb695265519a" +dependencies = [ + "bitflags", +] + +[[package]] +name = "remove_dir_all" +version = "0.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3acd125665422973a33ac9d3dd2df85edad0f4ae9b00dafb1a05e43a9f5ef8e7" +dependencies = [ + "winapi", +] + +[[package]] +name = "rustls-pemfile" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5eebeaeb360c87bfb72e84abdb3447159c0eaececf1bef2aecd65a8be949d1c9" +dependencies = [ + "base64", +] + +[[package]] +name = "ryu" +version = "1.0.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4501abdff3ae82a1c1b477a17252eb69cee9e66eb915c1abaa4f44d873df9f09" + +[[package]] +name = "safemem" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ef703b7cb59335eae2eb93ceb664c0eb7ea6bf567079d843e09420219668e072" + +[[package]] +name = "scoped-tls" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e1cf6437eb19a8f4a6cc0f7dca544973b0b78843adbfeb3683d1a94a0024a294" + +[[package]] +name = "serde" +version = "1.0.148" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e53f64bb4ba0191d6d0676e1b141ca55047d83b74f5607e6d8eb88126c52c2dc" +dependencies = [ + "serde_derive", +] + +[[package]] +name = "serde_derive" +version = "1.0.148" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a55492425aa53521babf6137309e7d34c20bbfbbfcfe2c7f3a047fd1f6b92c0c" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "serde_json" +version = "1.0.89" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "020ff22c755c2ed3f8cf162dbb41a7268d934702f3ed3631656ea597e08fc3db" +dependencies = [ + "itoa", + "ryu", + "serde", +] + +[[package]] +name = "serde_urlencoded" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3491c14715ca2294c4d6a88f15e84739788c1d030eed8c110436aafdaa2f3fd" +dependencies = [ + "form_urlencoded", + "itoa", + "ryu", + "serde", +] + +[[package]] +name = "sha-1" +version = "0.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f5058ada175748e33390e40e872bd0fe59a19f265d0158daa551c5a88a76009c" +dependencies = [ + "cfg-if", + "cpufeatures", + "digest", +] + +[[package]] +name = "sha1" +version = "0.10.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f04293dc80c3993519f2d7f6f511707ee7094fe0c6d3406feb330cdb3540eba3" +dependencies = [ + "cfg-if", + "cpufeatures", + "digest", +] + +[[package]] +name = "slab" +version = "0.4.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4614a76b2a8be0058caa9dbbaf66d988527d86d003c11a94fbd335d7661edcef" +dependencies = [ + "autocfg", +] + +[[package]] +name = "socket2" +version = "0.4.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "02e2d2db9033d13a1567121ddd7a095ee144db4e1ca1b1bda3419bc0da294ebd" +dependencies = [ + "libc", + "winapi", +] + +[[package]] +name = "syn" +version = "1.0.104" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4ae548ec36cf198c0ef7710d3c230987c2d6d7bd98ad6edc0274462724c585ce" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "tempfile" +version = "3.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5cdb1ef4eaeeaddc8fbd371e5017057064af0911902ef36b39801f67cc6d79e4" +dependencies = [ + "cfg-if", + "fastrand", + "libc", + "redox_syscall", + "remove_dir_all", + "winapi", +] + +[[package]] +name = "thiserror" +version = "1.0.37" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "10deb33631e3c9018b9baf9dcbbc4f737320d2b576bac10f6aefa048fa407e3e" +dependencies = [ + "thiserror-impl", +] + +[[package]] +name = "thiserror-impl" +version = "1.0.37" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "982d17546b47146b28f7c22e3d08465f6b8903d0ea13c1660d9d84a6e7adcdbb" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "tinyvec" +version = "1.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "87cc5ceb3875bb20c2890005a4e226a4651264a5c75edb2421b52861a0a0cb50" +dependencies = [ + "tinyvec_macros", +] + +[[package]] +name = "tinyvec_macros" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cda74da7e1a664f795bb1f8a87ec406fb89a02522cf6e50620d016add6dbbf5c" + +[[package]] +name = "tokio" +version = "1.22.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d76ce4a75fb488c605c54bf610f221cea8b0dafb53333c1a67e8ee199dcd2ae3" +dependencies = [ + "autocfg", + "bytes", + "libc", + "memchr", + "mio", + "num_cpus", + "pin-project-lite", + "socket2", + "tokio-macros", + "winapi", +] + +[[package]] +name = "tokio-macros" +version = "1.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9724f9a975fb987ef7a3cd9be0350edcbe130698af5b8f7a631e23d42d052484" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "tokio-stream" +version = "0.1.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d660770404473ccd7bc9f8b28494a811bc18542b915c0855c51e8f419d5223ce" +dependencies = [ + "futures-core", + "pin-project-lite", + "tokio", +] + +[[package]] +name = "tokio-tungstenite" +version = "0.17.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f714dd15bead90401d77e04243611caec13726c2408afd5b31901dfcdcb3b181" +dependencies = [ + "futures-util", + "log", + "tokio", + "tungstenite", +] + +[[package]] +name = "tokio-util" +version = "0.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0bb2e075f03b3d66d8d8785356224ba688d2906a371015e225beeb65ca92c740" +dependencies = [ + "bytes", + "futures-core", + "futures-sink", + "pin-project-lite", + "tokio", + "tracing", +] + +[[package]] +name = "tower-service" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6bc1c9ce2b5135ac7f93c72918fc37feb872bdc6a5533a8b85eb4b86bfdae52" + +[[package]] +name = "tracing" +version = "0.1.37" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ce8c33a8d48bd45d624a6e523445fd21ec13d3653cd51f681abf67418f54eb8" +dependencies = [ + "cfg-if", + "log", + "pin-project-lite", + "tracing-core", +] + +[[package]] +name = "tracing-core" +version = "0.1.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "24eb03ba0eab1fd845050058ce5e616558e8f8d8fca633e6b163fe25c797213a" +dependencies = [ + "once_cell", +] + +[[package]] +name = "try-lock" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "59547bce71d9c38b83d9c0e92b6066c4253371f15005def0c30d9657f50c7642" + +[[package]] +name = "tungstenite" +version = "0.17.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e27992fd6a8c29ee7eef28fc78349aa244134e10ad447ce3b9f0ac0ed0fa4ce0" +dependencies = [ + "base64", + "byteorder", + "bytes", + "http", + "httparse", + "log", + "rand", + "sha-1", + "thiserror", + "url", + "utf-8", +] + +[[package]] +name = "twoway" +version = "0.1.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "59b11b2b5241ba34be09c3cc85a36e56e48f9888862e19cedf23336d35316ed1" +dependencies = [ + "memchr", +] + +[[package]] +name = "typenum" +version = "1.15.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dcf81ac59edc17cc8697ff311e8f5ef2d99fcbd9817b34cec66f90b6c3dfd987" + +[[package]] +name = "unicase" +version = "2.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "50f37be617794602aabbeee0be4f259dc1778fabe05e2d67ee8f79326d5cb4f6" +dependencies = [ + "version_check", +] + +[[package]] +name = "unicode-bidi" +version = "0.3.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "099b7128301d285f79ddd55b9a83d5e6b9e97c92e0ea0daebee7263e932de992" + +[[package]] +name = "unicode-ident" +version = "1.0.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6ceab39d59e4c9499d4e5a8ee0e2735b891bb7308ac83dfb4e80cad195c9f6f3" + +[[package]] +name = "unicode-normalization" +version = "0.1.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c5713f0fc4b5db668a2ac63cdb7bb4469d8c9fed047b1d0292cc7b0ce2ba921" +dependencies = [ + "tinyvec", +] + +[[package]] +name = "url" +version = "2.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0d68c799ae75762b8c3fe375feb6600ef5602c883c5d21eb51c09f22b83c4643" +dependencies = [ + "form_urlencoded", + "idna", + "percent-encoding", +] + +[[package]] +name = "utf-8" +version = "0.7.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09cc8ee72d2a9becf2f2febe0205bbed8fc6615b7cb429ad062dc7b7ddd036a9" + +[[package]] +name = "version_check" +version = "0.9.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" + +[[package]] +name = "want" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1ce8a968cb1cd110d136ff8b819a556d6fb6d919363c61534f6860c7eb172ba0" +dependencies = [ + "log", + "try-lock", +] + +[[package]] +name = "warp" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed7b8be92646fc3d18b06147664ebc5f48d222686cb11a8755e561a735aacc6d" +dependencies = [ + "bytes", + "futures-channel", + "futures-util", + "headers", + "http", + "hyper", + "log", + "mime", + "mime_guess", + "multipart", + "percent-encoding", + "pin-project", + "rustls-pemfile", + "scoped-tls", + "serde", + "serde_json", + "serde_urlencoded", + "tokio", + "tokio-stream", + "tokio-tungstenite", + "tokio-util", + "tower-service", + "tracing", +] + +[[package]] +name = "wasi" +version = "0.11.0+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" + +[[package]] +name = "winapi" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" +dependencies = [ + "winapi-i686-pc-windows-gnu", + "winapi-x86_64-pc-windows-gnu", +] + +[[package]] +name = "winapi-i686-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" + +[[package]] +name = "winapi-x86_64-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" + +[[package]] +name = "windows-sys" +version = "0.42.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5a3e1820f08b8513f676f7ab6c1f99ff312fb97b553d30ff4dd86f9f15728aa7" +dependencies = [ + "windows_aarch64_gnullvm", + "windows_aarch64_msvc", + "windows_i686_gnu", + "windows_i686_msvc", + "windows_x86_64_gnu", + "windows_x86_64_gnullvm", + "windows_x86_64_msvc", +] + +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.42.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "41d2aa71f6f0cbe00ae5167d90ef3cfe66527d6f613ca78ac8024c3ccab9a19e" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.42.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dd0f252f5a35cac83d6311b2e795981f5ee6e67eb1f9a7f64eb4500fbc4dcdb4" + +[[package]] +name = "windows_i686_gnu" +version = "0.42.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fbeae19f6716841636c28d695375df17562ca208b2b7d0dc47635a50ae6c5de7" + +[[package]] +name = "windows_i686_msvc" +version = "0.42.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "84c12f65daa39dd2babe6e442988fc329d6243fdce47d7d2d155b8d874862246" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.42.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bf7b1b21b5362cbc318f686150e5bcea75ecedc74dd157d874d754a2ca44b0ed" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.42.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09d525d2ba30eeb3297665bd434a54297e4170c7f1a44cad4ef58095b4cd2028" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.42.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f40009d85759725a34da6d89a94e63d7bdc50a862acf0dbc7c8e488f1edcb6f5" diff --git a/backend/limits_srv/Cargo.toml b/backend/limits_srv/Cargo.toml new file mode 100644 index 0000000..48989d9 --- /dev/null +++ b/backend/limits_srv/Cargo.toml @@ -0,0 +1,12 @@ +[package] +name = "limits_srv" +version = "0.1.0" +edition = "2021" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +limits_core = { version = "0.1.0", path = "../limits_core" } +serde_json = "1.0" +warp = { version = "0.3" } +tokio = { version = "1.22", features = ["macros", "rt", "rt-multi-thread"] } diff --git a/backend/limits_srv/pt_limits.json b/backend/limits_srv/pt_limits.json new file mode 100644 index 0000000..4dcef89 --- /dev/null +++ b/backend/limits_srv/pt_limits.json @@ -0,0 +1,43 @@ +{ + "configs": [ + { + "name": "Steam Deck", + "conditions": { + "cpuinfo": "model name\t: AMD Custom APU 0405\n" + }, + "limits": [ + { + "limits": "Cpu", + "target": "SteamDeck" + }, + { + "limits": "Gpu", + "target": "SteamDeck" + }, + { + "limits": "Battery", + "target": "SteamDeck" + } + ] + }, + { + "name": "Fallback", + "conditions": {}, + "limits": [ + { + "limits": "Cpu", + "target": "Unknown" + }, + { + "limits": "Gpu", + "target": "Unknown" + }, + { + "limits": "Battery", + "target": "Unknown" + } + ] + } + ], + "refresh": "http://limits.ngni.us:45000/powertools/v1" +} diff --git a/backend/limits_srv/src/main.rs b/backend/limits_srv/src/main.rs new file mode 100644 index 0000000..7f423f3 --- /dev/null +++ b/backend/limits_srv/src/main.rs @@ -0,0 +1,53 @@ +use std::sync::atomic::{Ordering, AtomicU64}; +use std::sync::{RwLock, Arc}; + +use warp::Filter; + +use limits_core::json::Base; + +static VISIT_COUNT: AtomicU64 = AtomicU64::new(0); + +fn get_limits(base: Base) -> impl warp::Reply { + VISIT_COUNT.fetch_add(1, Ordering::AcqRel); + //println!("Count: {} + 1", old_count); + warp::reply::json(&base) +} + +fn get_visits() -> impl warp::Reply { + let count = VISIT_COUNT.load(Ordering::Relaxed); + //println!("Count: {}", count); + warp::reply::json(&count) +} + +fn routes(base: Arc>) -> impl Filter + Clone { + warp::get().and( + warp::path!("powertools" / "v1") + .map(move || { + let base = base.read().expect("Failed to acquire base limits read lock").clone(); + get_limits(base) + }) + .or( + warp::path!("powertools" / "count") + .map(get_visits) + ) + ).recover(recovery) +} + +pub async fn recovery(reject: warp::Rejection) -> Result { + if reject.is_not_found() { + Ok(warp::hyper::StatusCode::NOT_FOUND) + } else { + Err(reject) + } +} + +#[tokio::main] +async fn main() { + let file = std::fs::File::open("./pt_limits.json").expect("Failed to read limits file"); + let limits: Base = serde_json::from_reader(file).expect("Failed to parse limits file"); + assert!(limits.refresh.is_some(), "`refresh` cannot be null, since it will brick future refreshes"); + + warp::serve(routes(Arc::new(RwLock::new(limits)))) + .run(([0, 0, 0, 0], 8080)) + .await; +} diff --git a/backend/src/consts.rs b/backend/src/consts.rs index 055d0ff..842051a 100644 --- a/backend/src/consts.rs +++ b/backend/src/consts.rs @@ -5,3 +5,5 @@ pub const PACKAGE_VERSION: &'static str = env!("CARGO_PKG_VERSION"); pub const DEFAULT_SETTINGS_FILE: &str = "default_settings.json"; pub const DEFAULT_SETTINGS_NAME: &str = "Main"; + +pub const LIMITS_FILE: &str = "limits_cache.json"; diff --git a/backend/src/main.rs b/backend/src/main.rs index 3985ca0..2d25c95 100644 --- a/backend/src/main.rs +++ b/backend/src/main.rs @@ -53,7 +53,8 @@ fn main() -> Result<(), ()> { log::info!("Starting back-end ({} v{})", PACKAGE_NAME, PACKAGE_VERSION); println!("Starting back-end ({} v{})", PACKAGE_NAME, PACKAGE_VERSION); - crate::settings::driver::auto_detect_loud(); + let _limits_handle = crate::settings::limits_worker_spawn(); + log::info!("Detected device automatically, starting with driver: {:?} (This can be overriden)", crate::settings::auto_detect_provider()); let mut loaded_settings = persist::SettingsJson::open(utility::settings_dir().join(DEFAULT_SETTINGS_FILE)) .map(|settings| settings::Settings::from_json(settings, DEFAULT_SETTINGS_FILE.into())) diff --git a/backend/src/persist/battery.rs b/backend/src/persist/battery.rs index e5c08c7..962cfbb 100644 --- a/backend/src/persist/battery.rs +++ b/backend/src/persist/battery.rs @@ -3,7 +3,7 @@ use std::default::Default; use serde::{Deserialize, Serialize}; -#[derive(Serialize, Deserialize)] +#[derive(Serialize, Deserialize, Clone)] pub struct BatteryJson { pub charge_rate: Option, pub charge_mode: Option, diff --git a/backend/src/persist/cpu.rs b/backend/src/persist/cpu.rs index 0af2781..442206a 100644 --- a/backend/src/persist/cpu.rs +++ b/backend/src/persist/cpu.rs @@ -7,7 +7,7 @@ use super::MinMaxJson; //const SCALING_FREQUENCIES: &[u64] = &[1700000, 2400000, 2800000]; -#[derive(Serialize, Deserialize)] +#[derive(Serialize, Deserialize, Clone)] pub struct CpuJson { pub online: bool, pub clock_limits: Option>, diff --git a/backend/src/persist/driver.rs b/backend/src/persist/driver.rs index 91244a2..f1486b5 100644 --- a/backend/src/persist/driver.rs +++ b/backend/src/persist/driver.rs @@ -4,7 +4,6 @@ use serde::{Deserialize, Serialize}; #[derive(Serialize, Deserialize, Default, Debug, Clone)] pub enum DriverJson { - #[default] #[serde(rename = "steam-deck", alias = "gabe-boy")] SteamDeck, #[serde(rename = "steam-deck-oc", alias = "gabe-boy-advance")] @@ -13,4 +12,7 @@ pub enum DriverJson { Generic, #[serde(rename = "unknown")] Unknown, + #[default] + #[serde(rename = "auto")] + AutoDetect, } diff --git a/backend/src/persist/general.rs b/backend/src/persist/general.rs index b85df70..22f94da 100644 --- a/backend/src/persist/general.rs +++ b/backend/src/persist/general.rs @@ -56,7 +56,7 @@ impl SettingsJson { } } -#[derive(Serialize, Deserialize)] +#[derive(Serialize, Deserialize, Clone)] pub struct MinMaxJson { pub max: T, pub min: T, diff --git a/backend/src/persist/gpu.rs b/backend/src/persist/gpu.rs index ecb352f..933f2c4 100644 --- a/backend/src/persist/gpu.rs +++ b/backend/src/persist/gpu.rs @@ -4,7 +4,7 @@ use std::default::Default; use super::MinMaxJson; use serde::{Deserialize, Serialize}; -#[derive(Serialize, Deserialize)] +#[derive(Serialize, Deserialize, Clone)] pub struct GpuJson { pub fast_ppt: Option, pub slow_ppt: Option, diff --git a/backend/src/settings/detect/auto_detect.rs b/backend/src/settings/detect/auto_detect.rs new file mode 100644 index 0000000..9a3c550 --- /dev/null +++ b/backend/src/settings/detect/auto_detect.rs @@ -0,0 +1,191 @@ +use std::fs::File; + +use regex::RegexBuilder; + +use limits_core::json::{Limits, BatteryLimit, CpuLimit, GpuLimit}; + +use crate::persist::{DriverJson, SettingsJson}; +use crate::settings::{TGeneral, TCpus, TGpu, TBattery, Driver, General}; + +#[inline] +pub fn auto_detect_provider() -> DriverJson { + let provider = auto_detect0(None, crate::utility::settings_dir().join("autodetect.json")) + .general + .provider(); + //log::info!("Detected device automatically, compatible driver: {:?}", provider); + provider +} + +/// Device detection logic +pub fn auto_detect0(settings_opt: Option, json_path: std::path::PathBuf) -> Driver { + let mut builder = DriverBuilder::new(json_path); + + let cpu_info: String = usdpl_back::api::files::read_single("/proc/cpuinfo").unwrap_or_default(); + log::debug!("Read from /proc/cpuinfo:\n{}", cpu_info); + let os_info: String = usdpl_back::api::files::read_single("/etc/os-release").unwrap_or_default(); + log::debug!("Read from /etc/os-release:\n{}", os_info); + let dmi_info: String = std::process::Command::new("dmidecode").output().map(|out| String::from_utf8_lossy(&out.stdout).into_owned()).unwrap_or_default(); + log::debug!("Read dmidecode:\n{}", dmi_info); + + let limits_path = super::utility::limits_path(); + let limits = match File::open(&limits_path) { + Ok(f) => { + match serde_json::from_reader(f) { + Ok(lim) => lim, + Err(e) => { + log::warn!("Failed to parse limits file `{}`, cannot use for auto_detect: {}", limits_path.display(), e); + limits_core::json::Base::default() + } + } + }, + Err(e) => { + log::warn!("Failed to open limits file `{}` (trying force refresh...): {}", limits_path.display(), e); + super::limits_worker::get_limits_blocking() + } + }; + + // build driver based on limits conditions + for conf in limits.configs { + let conditions = conf.conditions; + let mut matches = true; + if conditions.is_empty() { + matches = !builder.is_complete(); + } else { + if let Some(dmi) = &conditions.dmi { + let pattern = RegexBuilder::new(dmi) + .multi_line(true) + .build() + .expect("Invalid DMI regex"); + matches &=pattern.is_match(&dmi_info); + } + if let Some(cpuinfo) = &conditions.cpuinfo { + let pattern = RegexBuilder::new(cpuinfo) + .multi_line(true) + .build() + .expect("Invalid CPU regex"); + matches &=pattern.is_match(&cpu_info); + } + if let Some(os) = &conditions.os { + let pattern = RegexBuilder::new(os) + .multi_line(true) + .build() + .expect("Invalid OS regex"); + matches &=pattern.is_match(&os_info); + } + if let Some(cmd) = &conditions.command { + match std::process::Command::new("bash") + .args(["-c", cmd]) + .status() { + Ok(status) => matches &= status.code().map(|c| c == 0).unwrap_or(false), + Err(e) => log::warn!("Ignoring bash limits error: {}", e), + } + } + } + if matches { + if let Some(settings) = &settings_opt { + for limit in conf.limits { + match limit { + Limits::Cpu(cpus) => { + let cpu_driver: Box = match cpus { + CpuLimit::SteamDeck => Box::new(crate::settings::steam_deck::Cpus::from_json(settings.cpus.clone(), settings.version)), + CpuLimit::SteamDeckAdvance => Box::new(crate::settings::steam_deck_adv::Cpus::from_json(settings.cpus.clone(), settings.version)), + CpuLimit::Generic(x) => Box::new(crate::settings::generic::Cpus::from_json_and_limits(settings.cpus.clone(), settings.version, x)), + CpuLimit::Unknown => Box::new(crate::settings::unknown::Cpus::from_json(settings.cpus.clone(), settings.version)), + }; + builder.cpus = Some(cpu_driver); + }, + Limits::Gpu(gpu) => { + let driver: Box = match gpu { + GpuLimit::SteamDeck => Box::new(crate::settings::steam_deck::Gpu::from_json(settings.gpu.clone(), settings.version)), + GpuLimit::SteamDeckAdvance => Box::new(crate::settings::steam_deck_adv::Gpu::from_json(settings.gpu.clone(), settings.version)), + GpuLimit::Generic(x) => Box::new(crate::settings::generic::Gpu::from_json_and_limits(settings.gpu.clone(), settings.version, x)), + GpuLimit::Unknown => Box::new(crate::settings::unknown::Gpu::from_json(settings.gpu.clone(), settings.version)), + }; + builder.gpu = Some(driver); + }, + Limits::Battery(batt) => { + let driver: Box = match batt { + BatteryLimit::SteamDeck => Box::new(crate::settings::steam_deck::Battery::from_json(settings.battery.clone(), settings.version)), + BatteryLimit::SteamDeckAdvance => Box::new(crate::settings::steam_deck::Battery::from_json(settings.battery.clone(), settings.version)), + BatteryLimit::Generic(x) => Box::new(crate::settings::generic::Battery::from_json_and_limits(settings.battery.clone(), settings.version, x)), + BatteryLimit::Unknown => Box::new(crate::settings::unknown::Battery), + }; + builder.battery = Some(driver); + } + } + } + } else { + for limit in conf.limits { + match limit { + Limits::Cpu(cpus) => { + let cpu_driver: Box = match cpus { + CpuLimit::SteamDeck => Box::new(crate::settings::steam_deck::Cpus::system_default()), + CpuLimit::SteamDeckAdvance => Box::new(crate::settings::steam_deck_adv::Cpus::system_default()), + CpuLimit::Generic(x) => Box::new(crate::settings::generic::Cpus::from_limits(x)), + CpuLimit::Unknown => Box::new(crate::settings::unknown::Cpus::system_default()), + }; + builder.cpus = Some(cpu_driver); + }, + Limits::Gpu(gpu) => { + let driver: Box = match gpu { + GpuLimit::SteamDeck => Box::new(crate::settings::steam_deck::Gpu::system_default()), + GpuLimit::SteamDeckAdvance => Box::new(crate::settings::steam_deck_adv::Gpu::system_default()), + GpuLimit::Generic(x) => Box::new(crate::settings::generic::Gpu::from_limits(x)), + GpuLimit::Unknown => Box::new(crate::settings::unknown::Gpu::system_default()), + }; + builder.gpu = Some(driver); + }, + Limits::Battery(batt) => { + let driver: Box = match batt { + BatteryLimit::SteamDeck => Box::new(crate::settings::steam_deck::Battery::system_default()), + BatteryLimit::SteamDeckAdvance => Box::new(crate::settings::steam_deck::Battery::system_default()), + BatteryLimit::Generic(x) => Box::new(crate::settings::generic::Battery::from_limits(x)), + BatteryLimit::Unknown => Box::new(crate::settings::unknown::Battery), + }; + builder.battery = Some(driver); + } + } + } + } + + } + } + + builder.build() +} + +struct DriverBuilder { + general: Box, + cpus: Option>, + gpu: Option>, + battery: Option>, +} + +impl DriverBuilder { + fn new(json_path: std::path::PathBuf) -> Self { + Self { + general: Box::new(General { + persistent: false, + path: json_path, + name: crate::consts::DEFAULT_SETTINGS_NAME.to_owned(), + driver: DriverJson::AutoDetect, + }), + cpus: None, + gpu: None, + battery: None, + } + } + + fn is_complete(&self) -> bool { + self.cpus.is_some() && self.gpu.is_some() && self.battery.is_some() + } + + fn build(self) -> Driver { + Driver { + general: self.general, + cpus: self.cpus.unwrap_or_else(|| Box::new(crate::settings::unknown::Cpus::system_default())), + gpu: self.gpu.unwrap_or_else(|| Box::new(crate::settings::unknown::Gpu::system_default())), + battery: self.battery.unwrap_or_else(|| Box::new(crate::settings::unknown::Battery)) + } + } +} diff --git a/backend/src/settings/detect/limits_worker.rs b/backend/src/settings/detect/limits_worker.rs new file mode 100644 index 0000000..0ee61a3 --- /dev/null +++ b/backend/src/settings/detect/limits_worker.rs @@ -0,0 +1,110 @@ +use std::thread::{self, JoinHandle}; +#[cfg(feature = "online")] +use std::time::Duration; + +use limits_core::json::Base; + +#[cfg(feature = "online")] +pub fn spawn() -> JoinHandle<()> { + thread::spawn(move || { + log::info!("limits_worker starting..."); + let sleep_dur = Duration::from_secs(60*60*24); // 1 day + let limits_path = super::utility::limits_path(); + loop { + thread::sleep(sleep_dur); + if (limits_path.exists() && limits_path.is_file()) || !limits_path.exists() { + // try to load limits from file, fallback to built-in default + let base = match std::fs::File::open(&limits_path) { + Ok(f) => { + match serde_json::from_reader(f) { + Ok(b) => b, + Err(e) => { + log::error!("Cannot parse {}: {}", limits_path.display(), e); + Base::default() + } + } + }, + Err(e) => { + log::error!("Cannot open {}: {}", limits_path.display(), e); + Base::default() + } + }; + if let Some(refresh) = &base.refresh { + // try to retrieve newer version + match ureq::get(refresh) + .call() { + Ok(response) => { + let json_res: std::io::Result = response.into_json(); + match json_res { + Ok(new_base) => { + match std::fs::File::create(&limits_path) { + Ok(f) => { + match serde_json::to_writer_pretty(f, &new_base) { + Ok(_) => log::info!("Successfully updated limits from `{}`, cached at {}", refresh, limits_path.display()), + Err(e) => log::error!("Failed to save limits json to file `{}`: {}", limits_path.display(), e), + } + }, + Err(e) => log::error!("Cannot create {}: {}", limits_path.display(), e) + } + }, + Err(e) => log::error!("Cannot parse response from `{}`: {}", refresh, e), + } + }, + Err(e) => log::warn!("Cannot download limits from `{}`: {}", refresh, e), + } + } else { + log::info!("limits_worker refresh is empty, terminating..."); + break; + } + } else if !limits_path.is_file() { + log::error!("Path for storing limits is not a file!"); + } + } + log::warn!("limits_worker completed!"); + }) +} + +#[cfg(not(feature = "online"))] +pub fn spawn() -> JoinHandle<()> { + thread::spawn(move || { + log::info!("limits_worker disabled..."); + }) +} + +pub fn get_limits_blocking() -> Base { + let limits_path = super::utility::limits_path(); + if limits_path.is_file() { + match std::fs::File::open(&limits_path) { + Ok(f) => { + match serde_json::from_reader(f) { + Ok(b) => b, + Err(e) => { + log::error!("Cannot parse {}: {}", limits_path.display(), e); + Base::default() + } + } + }, + Err(e) => { + log::error!("Cannot open {}: {}", limits_path.display(), e); + Base::default() + } + } + } else { + #[cfg(feature = "online")] + { + let refresh = Base::default().refresh.unwrap(); + match ureq::get(&refresh) // try to retrieve newer version + .call() { + Ok(response) => { + let json_res: std::io::Result = response.into_json(); + match json_res { + Ok(new_base) => return new_base, + Err(e) => log::error!("Cannot parse response from `{}`: {}", refresh, e) + } + }, + Err(e) => log::warn!("Cannot download limits from `{}`: {}", refresh, e), + } + } + Base::default() + } +} diff --git a/backend/src/settings/detect/mod.rs b/backend/src/settings/detect/mod.rs new file mode 100644 index 0000000..1bb27fc --- /dev/null +++ b/backend/src/settings/detect/mod.rs @@ -0,0 +1,5 @@ +mod auto_detect; +pub mod limits_worker; +mod utility; + +pub use auto_detect::{auto_detect_provider, auto_detect0}; diff --git a/backend/src/settings/detect/utility.rs b/backend/src/settings/detect/utility.rs new file mode 100644 index 0000000..16aec42 --- /dev/null +++ b/backend/src/settings/detect/utility.rs @@ -0,0 +1,3 @@ +pub fn limits_path() -> std::path::PathBuf { + crate::utility::settings_dir().join(crate::consts::LIMITS_FILE) +} diff --git a/backend/src/settings/driver.rs b/backend/src/settings/driver.rs index a9a5d09..7a2e498 100644 --- a/backend/src/settings/driver.rs +++ b/backend/src/settings/driver.rs @@ -1,44 +1,5 @@ use crate::persist::{DriverJson, SettingsJson}; -use super::{TGeneral, TCpus, TGpu, TBattery, SettingError, General}; - -/// Device detection logic -fn auto_detect() -> DriverJson { - let lscpu: String = match usdpl_back::api::files::read_single("/proc/cpuinfo") { - Ok(s) => s, - Err(_) => return DriverJson::Unknown, - }; - log::debug!("Read from /proc/cpuinfo:\n{}", lscpu); - let os_info: String = match usdpl_back::api::files::read_single("/etc/os-release") { - Ok(s) => s, - Err(_) => return DriverJson::Unknown, - }; - log::debug!("Read from /etc/os-release:\n{}", os_info); - if let Some(_) = lscpu.find("model name\t: AMD Custom APU 0405\n") { - // definitely a Steam Deck, check if it's overclocked - // TODO: this auto-detect doesn't work - // look for a file instead? - let max_freq: u64 = match usdpl_back::api::files::read_single("/sys/devices/system/cpu/cpu0/cpufreq/cpuinfo_max_freq") { - Ok(u) => u, - Err(_) => return DriverJson::SteamDeck, - }; - if max_freq == 2800000 { // default clock speed - DriverJson::SteamDeck - } else { - DriverJson::SteamDeckAdvance - } - } else if let Some(_) = lscpu.find("model name\t: AMD Ryzen") { - DriverJson::Generic - } else { - DriverJson::Unknown - } -} - -#[inline] -pub fn auto_detect_loud() -> DriverJson { - let provider = auto_detect(); - log::info!("Detected device automatically, compatible driver: {:?}", provider); - provider -} +use super::{TGeneral, TCpus, TGpu, TBattery, SettingError, General, auto_detect0}; pub struct Driver { pub general: Box, @@ -66,110 +27,58 @@ impl Driver { } fn version0(settings: SettingsJson, json_path: std::path::PathBuf) -> Result { - let provider = settings.provider.unwrap_or_else(auto_detect); - match provider { - DriverJson::SteamDeck => Ok(Self { - general: Box::new(General { - persistent: settings.persistent, - path: json_path, - name: settings.name, - driver: DriverJson::SteamDeck, + if let Some(provider) = &settings.provider { + match provider { + DriverJson::SteamDeck => Ok(Self { + general: Box::new(General { + persistent: settings.persistent, + path: json_path, + name: settings.name, + driver: DriverJson::SteamDeck, + }), + cpus: Box::new(super::steam_deck::Cpus::from_json(settings.cpus, settings.version)), + gpu: Box::new(super::steam_deck::Gpu::from_json(settings.gpu, settings.version)), + battery: Box::new(super::steam_deck::Battery::from_json(settings.battery, settings.version)), }), - cpus: Box::new(super::steam_deck::Cpus::from_json(settings.cpus, settings.version)), - gpu: Box::new(super::steam_deck::Gpu::from_json(settings.gpu, settings.version)), - battery: Box::new(super::steam_deck::Battery::from_json(settings.battery, settings.version)), - }), - DriverJson::SteamDeckAdvance => Ok(Self { - general: Box::new(General { - persistent: settings.persistent, - path: json_path, - name: settings.name, - driver: DriverJson::SteamDeckAdvance, + DriverJson::SteamDeckAdvance => Ok(Self { + general: Box::new(General { + persistent: settings.persistent, + path: json_path, + name: settings.name, + driver: DriverJson::SteamDeckAdvance, + }), + cpus: Box::new(super::steam_deck_adv::Cpus::from_json(settings.cpus, settings.version)), + gpu: Box::new(super::steam_deck_adv::Gpu::from_json(settings.gpu, settings.version)), + battery: Box::new(super::steam_deck::Battery::from_json(settings.battery, settings.version)), }), - cpus: Box::new(super::steam_deck_adv::Cpus::from_json(settings.cpus, settings.version)), - gpu: Box::new(super::steam_deck_adv::Gpu::from_json(settings.gpu, settings.version)), - battery: Box::new(super::steam_deck::Battery::from_json(settings.battery, settings.version)), - }), - DriverJson::Generic => Ok(Self { - general: Box::new(General { - persistent: settings.persistent, - path: json_path, - name: settings.name, - driver: DriverJson::Unknown, + DriverJson::Generic => Ok(Self { + general: Box::new(General { + persistent: settings.persistent, + path: json_path, + name: settings.name, + driver: DriverJson::Unknown, + }), + cpus: Box::new(super::generic::Cpus::from_json(settings.cpus, settings.version)), + gpu: Box::new(super::generic::Gpu::from_json(settings.gpu, settings.version)), + battery: Box::new(super::generic::Battery), }), - cpus: Box::new(super::generic::Cpus::from_json(settings.cpus, settings.version)), - gpu: Box::new(super::generic::Gpu::from_json(settings.gpu, settings.version)), - battery: Box::new(super::generic::Battery), - }), - DriverJson::Unknown => Ok(Self { - general: Box::new(General { - persistent: settings.persistent, - path: json_path, - name: settings.name, - driver: DriverJson::Unknown, - }), - cpus: Box::new(super::unknown::Cpus::from_json(settings.cpus, settings.version)), - gpu: Box::new(super::unknown::Gpu::from_json(settings.gpu, settings.version)), - battery: Box::new(super::unknown::Battery), - }), + DriverJson::Unknown => Ok(super::detect::auto_detect0(Some(settings), json_path)), + DriverJson::AutoDetect => Ok(super::detect::auto_detect0(Some(settings), json_path)), + } + } else { + Ok(super::detect::auto_detect0(Some(settings), json_path)) } } pub fn system_default(json_path: std::path::PathBuf) -> Self { - let provider = auto_detect(); - match provider { - DriverJson::SteamDeck => Self { - general: Box::new(General { - persistent: false, - path: json_path, - name: crate::consts::DEFAULT_SETTINGS_NAME.to_owned(), - driver: DriverJson::SteamDeck, - }), - cpus: Box::new(super::steam_deck::Cpus::system_default()), - gpu: Box::new(super::steam_deck::Gpu::system_default()), - battery: Box::new(super::steam_deck::Battery::system_default()), - }, - DriverJson::SteamDeckAdvance => Self { - general: Box::new(General { - persistent: false, - path: json_path, - name: crate::consts::DEFAULT_SETTINGS_NAME.to_owned(), - driver: DriverJson::SteamDeck, - }), - cpus: Box::new(super::steam_deck_adv::Cpus::system_default()), - gpu: Box::new(super::steam_deck_adv::Gpu::system_default()), - battery: Box::new(super::steam_deck::Battery::system_default()), - }, - DriverJson::Generic => Self { - general: Box::new(General { - persistent: false, - path: json_path, - name: crate::consts::DEFAULT_SETTINGS_NAME.to_owned(), - driver: DriverJson::Unknown, - }), - cpus: Box::new(super::generic::Cpus::system_default()), - gpu: Box::new(super::generic::Gpu::system_default()), - battery: Box::new(super::generic::Battery), - }, - DriverJson::Unknown => Self { - general: Box::new(General { - persistent: false, - path: json_path, - name: crate::consts::DEFAULT_SETTINGS_NAME.to_owned(), - driver: DriverJson::Unknown, - }), - cpus: Box::new(super::unknown::Cpus::system_default()), - gpu: Box::new(super::unknown::Gpu::system_default()), - battery: Box::new(super::unknown::Battery), - } - } + auto_detect0(None, json_path) } } // sshhhh, this function isn't here ;) #[inline] pub fn maybe_do_button() { - match auto_detect() { + match super::auto_detect_provider() { DriverJson::SteamDeck | DriverJson::SteamDeckAdvance => { let period = std::time::Duration::from_millis(500); for _ in 0..10 { @@ -185,5 +94,6 @@ pub fn maybe_do_button() { }, DriverJson::Generic => log::warn!("You need to come up with something fun on generic"), DriverJson::Unknown => log::warn!("Can't do button activities on unknown platform"), + DriverJson::AutoDetect => log::warn!("WTF, why is auto_detect detecting AutoDetect???") } } diff --git a/backend/src/settings/generic/battery.rs b/backend/src/settings/generic/battery.rs index 6b6ad6b..6eb99c2 100644 --- a/backend/src/settings/generic/battery.rs +++ b/backend/src/settings/generic/battery.rs @@ -38,6 +38,16 @@ impl Battery { Ok(val) => Ok(val / 1000.0), } } + + pub fn from_limits(_limits: limits_core::json::GenericBatteryLimit) -> Self { + // TODO + Self + } + + pub fn from_json_and_limits(_other: BatteryJson, _version: u64, _limits: limits_core::json::GenericBatteryLimit) -> Self { + // TODO + Self + } } impl OnSet for Battery { diff --git a/backend/src/settings/generic/cpu.rs b/backend/src/settings/generic/cpu.rs index 48d4b99..d29153e 100644 --- a/backend/src/settings/generic/cpu.rs +++ b/backend/src/settings/generic/cpu.rs @@ -128,6 +128,43 @@ impl Cpus { smt_capable: can_smt, } } + + pub fn from_limits(_limits: limits_core::json::GenericCpuLimit) -> Self { + // TODO + Self { + cpus: vec![], + smt: false, + smt_capable: false, + } + } + + pub fn from_json_and_limits(mut other: Vec, version: u64, _limits: limits_core::json::GenericCpuLimit) -> Self { + let (_, can_smt) = Self::system_smt_capabilities(); + let mut result = Vec::with_capacity(other.len()); + let max_cpus = Self::cpu_count(); + for (i, cpu) in other.drain(..).enumerate() { + // prevent having more CPUs than available + if let Some(max_cpus) = max_cpus { + if i == max_cpus { + break; + } + } + result.push(Cpu::from_json(cpu, version, i)); + } + if let Some(max_cpus) = max_cpus { + if result.len() != max_cpus { + let mut sys_cpus = Cpus::system_default(); + for i in result.len()..sys_cpus.cpus.len() { + result.push(sys_cpus.cpus.remove(i)); + } + } + } + Self { + cpus: result, + smt: true, + smt_capable: can_smt, + } + } } impl TCpus for Cpus { diff --git a/backend/src/settings/generic/gpu.rs b/backend/src/settings/generic/gpu.rs index 9733cc8..1782ac5 100644 --- a/backend/src/settings/generic/gpu.rs +++ b/backend/src/settings/generic/gpu.rs @@ -18,7 +18,20 @@ impl Gpu { } } - pub fn system_default() -> Self { + /*pub fn system_default() -> Self { + Self { + slow_memory: false, + } + }*/ + + pub fn from_limits(_limits: limits_core::json::GenericGpuLimit) -> Self { + // TODO + Self { + slow_memory: false, + } + } + + pub fn from_json_and_limits(_other: GpuJson, _version: u64, _limits: limits_core::json::GenericGpuLimit) -> Self { Self { slow_memory: false, } diff --git a/backend/src/settings/mod.rs b/backend/src/settings/mod.rs index c12cf12..68e5bd7 100644 --- a/backend/src/settings/mod.rs +++ b/backend/src/settings/mod.rs @@ -1,3 +1,4 @@ +mod detect; pub mod driver; mod error; mod general; @@ -9,6 +10,7 @@ pub mod steam_deck; pub mod steam_deck_adv; pub mod unknown; +pub use detect::{auto_detect0, auto_detect_provider, limits_worker::spawn as limits_worker_spawn}; pub use driver::Driver; pub use general::{SettingVariant, Settings, General}; pub use min_max::MinMax;