diff options
| author | WerWolv <werwolv98@gmail.com> | 2022-03-31 08:31:03 +0200 |
|---|---|---|
| committer | WerWolv <werwolv98@gmail.com> | 2022-03-31 08:31:03 +0200 |
| commit | a38e03094b49fdc44389d4a558e55108d6db827a (patch) | |
| tree | 74eb1e11de56d1593d651ed623a959d715e81f30 /src | |
| parent | 807acfa8b464584b76567e9c006a6a4c81589645 (diff) | |
| download | decky-loader-a38e03094b49fdc44389d4a558e55108d6db827a.tar.gz decky-loader-a38e03094b49fdc44389d4a558e55108d6db827a.zip | |
sys: Added initial code injection logic
Diffstat (limited to 'src')
| -rw-r--r-- | src/main.rs | 120 | ||||
| -rw-r--r-- | src/plugin_page.js | 26 |
2 files changed, 146 insertions, 0 deletions
diff --git a/src/main.rs b/src/main.rs new file mode 100644 index 00000000..90d23a26 --- /dev/null +++ b/src/main.rs @@ -0,0 +1,120 @@ +use std::fmt::{Debug, Display, Formatter}; +use hyper::{Client, Uri}; +use hyper::body::Buf; +use serde::{ Serialize, Deserialize }; +use serde_json; +use tungstenite::Message; + +type TokioResult<T> = std::result::Result<T, Box<dyn std::error::Error + Send + Sync>>; + +enum AppError { + ContentNotFound +} + +impl Debug for AppError { + fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { + let message = match self { + AppError::ContentNotFound => "Content not found" + }; + + write!(f, "{}", message) + } +} + +impl Display for AppError { + fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { + write!(f, "{}", self) + } +} + +unsafe impl Send for AppError { } +unsafe impl Sync for AppError { } + +impl std::error::Error for AppError { } + +#[allow(non_snake_case)] +#[allow(dead_code)] +#[derive(Deserialize)] +struct WebContent { + description: String, + devtoolsFrontendUrl: String, + id: String, + title: String, + r#type: String, + url: String, + webSocketDebuggerUrl: String +} + +#[allow(non_snake_case)] +#[allow(dead_code)] +#[derive(Serialize)] +struct DebuggerCommandParams { + expression: String, + userGesture: bool +} + +#[allow(non_snake_case)] +#[allow(dead_code)] +#[derive(Serialize)] +struct DebuggerCommand { + id: u32, + method: String, + params: DebuggerCommandParams +} + +async fn get_web_content(url: Uri) -> TokioResult<Vec<WebContent>> { + let client = Client::new(); + let response = client.get(url).await?; + let body = hyper::body::aggregate(response).await?; + + let data = String::from(std::str::from_utf8(body.chunk())?); + + Ok(serde_json::from_str(data.as_str())?) +} + +#[tokio::main] +async fn main() -> TokioResult<()> { + let url = "http://127.0.0.1:8080/json".parse::<hyper::Uri>().unwrap(); + + let contents = get_web_content(url).await?; + + println!("Available Content:"); + for content in &contents { + println!(" {}", content.title); + } + + let mut quick_access_debug_url: Option<String> = None; + for content in &contents { + if content.title == "QuickAccess" { + quick_access_debug_url = Some(content.webSocketDebuggerUrl.clone()); + } + } + + if let Some(url) = quick_access_debug_url { + + let (mut socket, _) = tungstenite::connect(url)?; + + let command = DebuggerCommand { + id: 1, + method: String::from("Runtime.evaluate"), + params: DebuggerCommandParams { + expression: String::from(include_str!("plugin_page.js")), + userGesture: true + } + }; + + socket.write_message(Message::Text(serde_json::to_string(&command)?))?; + + let response = socket.read_message()?; + + println!("{}", response); + + socket.close(None)?; + + } else { + return Err(AppError::ContentNotFound.into()); + } + + + Ok(()) +}
\ No newline at end of file diff --git a/src/plugin_page.js b/src/plugin_page.js new file mode 100644 index 00000000..50dc419c --- /dev/null +++ b/src/plugin_page.js @@ -0,0 +1,26 @@ +(function () { + const PLUGIN_ICON = ` + <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-plugin" viewBox="0 0 16 16"> + <path fill-rule="evenodd" d="M1 8a7 7 0 1 1 2.898 5.673c-.167-.121-.216-.406-.002-.62l1.8-1.8a3.5 3.5 0 0 0 + 4.572-.328l1.414-1.415a.5.5 0 0 0 0-.707l-.707-.707 1.559-1.563a.5.5 0 1 0-.708-.706l-1.559 1.562-1.414-1.414 + 1.56-1.562a.5.5 0 1 0-.707-.706l-1.56 1.56-.707-.706a.5.5 0 0 0-.707 0L5.318 5.975a3.5 3.5 0 0 0-.328 + 4.571l-1.8 1.8c-.58.58-.62 1.6.121 2.137A8 8 0 1 0 0 8a.5.5 0 0 0 1 0Z"/> + </svg> + `; + + function inject() { + let tabs = document.getElementsByClassName("quickaccessmenu_TabContentColumn_2z5NL Panel Focusable")[0]; + tabs.children[tabs.children.length - 1].innerHTML = PLUGIN_ICON; + + let pages = document.getElementsByClassName("quickaccessmenu_AllTabContents_2yKG4 quickaccessmenu_Down_3rR0o")[0]; + let pluginPage = pages.children[pages.children.length - 1]; + pluginPage.innerHTML = "Hello from Rust!"; + } + + let injector = setInterval(function () { + if (document.hasFocus()) { + inject(); + clearInterval(injector); + } + }, 100); +})();
\ No newline at end of file |
