Skip to content

Commit

Permalink
update for new lunar launcher
Browse files Browse the repository at this point in the history
  • Loading branch information
Nilsen84 committed Aug 13, 2023
1 parent 579ae4f commit 8848cd1
Show file tree
Hide file tree
Showing 3 changed files with 50 additions and 25 deletions.
24 changes: 21 additions & 3 deletions src/chrome_debugger.rs
Original file line number Diff line number Diff line change
@@ -1,33 +1,51 @@
use std::error::Error;
use std::io::{BufRead, BufReader, Read, Write};
use std::net::{Ipv4Addr, TcpStream};
use std::str::FromStr;
use serde::Deserialize;
use serde_json::json;
use tungstenite::{Message, WebSocket};
use tungstenite::error::UrlError;
use tungstenite::http::Uri;

pub struct ChromeDebugger {
id: u32,
ws: WebSocket<TcpStream>
}

impl ChromeDebugger {
pub fn connect(port: u16) -> Result<ChromeDebugger, Box<dyn Error>> {
pub fn connect_port(port: u16) -> Result<ChromeDebugger, Box<dyn Error>> {
let mut stream = TcpStream::connect((Ipv4Addr::LOCALHOST, port))?;
let ws_url = get_websocket_url(&mut stream)?;

Ok(Self {
id: 1,
ws: tungstenite::client(ws_url, stream)?.0
})
}

pub fn connect_url(uri: impl AsRef<str>) -> Result<ChromeDebugger, Box<dyn Error>> {
let url = Uri::from_str(uri.as_ref())?;
let host = url.host().ok_or(tungstenite::Error::Url(UrlError::NoHostName))?;
let stream = TcpStream::connect((host, url.port_u16().unwrap_or(80)))?;

Ok(Self {
id: 1,
ws: tungstenite::client(&url, stream)?.0
})
}

pub fn send(&mut self, method: &str, params: serde_json::Value) -> Result<(), Box<dyn Error>> {
self.ws.write(Message::Text(
self.ws.send(Message::Text(
serde_json::to_string(&json!({
"id": 1,
"id": self.id,
"method": method,
"params": params
}))?
))?;

self.id += 1;

if cfg!(debug_assertions) {
println!("{}", self.ws.read()?);
}
Expand Down
47 changes: 28 additions & 19 deletions src/main.rs
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
#![feature(try_blocks)]
#![allow(dead_code)]

use std::{env, io};
use std::{env, io, thread};
use std::error::Error;
use std::io::{BufRead, BufReader, ErrorKind};
use std::net::{Ipv4Addr, TcpListener};
use std::path::Path;
use std::path::{Path};
use std::process::{Child, Command, Stdio};
use std::string::String;
use std::thread::sleep;
use std::time::Duration;

use serde_json::json;
Expand All @@ -30,26 +30,31 @@ fn find_lunar_executable() -> Result<String, String> {
format!(r"{localappdata}\Programs\lunarclient\Lunar Client.exe")
]
}
"macos" => vec!["/Applications/Lunar Client.app/Contents/MacOS/Lunar Client".into()],
"macos" => vec![
"/Applications/Lunar Client.app/Contents/MacOS/Lunar Client".into(),
format!(
"{}/Applications/Lunar Client.app/Contents/MacOS/Lunar Client",
env::var("HOME").or(Err("$HOME not defined"))?
)
],
"linux" => vec!["/usr/bin/lunarclient".into()],
_ => Err("unsupported os")?
};

paths.iter()
.find(|p| Path::new(p).exists())
.ok_or(format!("searched in the following locations: [{}]", paths.join(", ")))
.map(|p| p.clone())
}

fn wait_for_devtools_server(cmd: &mut Child) -> io::Result<()> {
let reader = BufReader::new(cmd.stderr.take().unwrap());
fn wait_for_websocket_url(child: &mut Child) -> io::Result<String> {
let reader = BufReader::new(child.stderr.take().unwrap());
for line in reader.lines() {
if line?.starts_with("DevTools listening on ") {
return Ok(())
if let Some(url) = line?.strip_prefix("Debugger listening on ") {
return Ok(url.into())
}
}

Err(io::Error::new(ErrorKind::UnexpectedEof, "'DevTools listening on ' was never printed"))
Err(io::Error::new(ErrorKind::UnexpectedEof, "'Debugger listening on ' was never printed"))
}

fn run() -> Result<(), Box<dyn Error>> {
Expand All @@ -62,19 +67,22 @@ fn run() -> Result<(), Box<dyn Error>> {

let port = free_port()?;

let mut cp = Command::new(lunar_exe)
.arg(format!("--remote-debugging-port={}", port))
let mut cp = Command::new(&lunar_exe)
.arg(format!("--inspect={}", port))
.stdin(Stdio::null())
.stderr(Stdio::piped())
.spawn()
.map_err(|e| format!("failed to start lunar: {}", e))?;

let res = try {
wait_for_devtools_server(&mut cp)?;
// on windows the launcher gets stuck on a black screen if you inject code too early
// no idea why
sleep(Duration::from_millis(1000));
let url = wait_for_websocket_url(&mut cp)?;

println!("[LLI] Connecting to {}", url);
let mut debugger = ChromeDebugger::connect_url(url)
.map_err(|e| format!("failed to connect debugger: {}", e))?;

let mut debugger = ChromeDebugger::connect(port).map_err(|e| format!("failed to connect debugger: {}", e))?;
// otherwise you get "ReferenceError: require is not defined"
thread::sleep(Duration::from_millis(1000));

let payload = format!(
"{}({})",
Expand All @@ -83,7 +91,8 @@ fn run() -> Result<(), Box<dyn Error>> {
);

debugger.send("Runtime.evaluate", json!({
"expression": payload
"expression": payload,
"includeCommandLineAPI": true
}))?;
};

Expand Down
4 changes: 1 addition & 3 deletions src/payload.js
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,4 @@
opts
);
}

require('electron').remote.getCurrentWindow().webContents.removeAllListeners('devtools-opened')
})
})

0 comments on commit 8848cd1

Please sign in to comment.