Skip to content

Commit

Permalink
Improvements (#17)
Browse files Browse the repository at this point in the history
* optimized read from tcpstream

* cargo clippy 'd

* Make sure the loader only load bepinex_gui.exe that has a major version 3 in its file info

* bump ver
  • Loading branch information
xiaoxiao921 authored Jun 6, 2023
1 parent 7515455 commit 571e8d8
Show file tree
Hide file tree
Showing 28 changed files with 276 additions and 307 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@

namespace BepInEx.GUI.Loader;

internal static class Patcher
internal static class EntryPoint
{
public static IEnumerable<string> TargetDLLs { get; } = Array.Empty<string>();

Expand Down Expand Up @@ -69,8 +69,12 @@ private static string FindGUIExecutable()

if (fileName == $"{GuiFileName}.exe")
{
Log.Info($"Found bepinex_gui executable in {filePath}");
return filePath;
var versInfo = FileVersionInfo.GetVersionInfo(filePath);
if (versInfo.FileMajorPart == 3)
{
Log.Info($"Found bepinex_gui v3 executable in {filePath}");
return filePath;
}
}
}

Expand Down
2 changes: 1 addition & 1 deletion Thunderstore/manifest.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "BepInEx_GUI",
"version_number": "3.0.1",
"version_number": "3.0.2",
"website_url": "https://github.com/risk-of-thunder/BepInEx.GUI",
"description": "Graphical User Interface meant to replace the regular console host that is used by BepInEx when the config setting is enabled.",
"dependencies": []
Expand Down
2 changes: 1 addition & 1 deletion bepinex_gui/Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion bepinex_gui/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "bepinex_gui"
version = "3.0.1"
version = "3.0.2"
authors = ["Risk of Thunder"]
license = "MIT"
description = "Graphical User Interface meant to replace the regular console host that is used by BepInEx"
Expand Down
2 changes: 1 addition & 1 deletion bepinex_gui/src/app.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ use crate::data::bepinex_mod::BepInExMod;
use crate::views::disclaimer::Disclaimer;
use crate::{theme, views};

pub(crate) const NAME: &str = "BepInExGUI";
pub const NAME: &str = "BepInExGUI";

pub struct BepInExGUI {
pub app_launch_config: AppLaunchConfig,
Expand Down
17 changes: 11 additions & 6 deletions bepinex_gui/src/backend/file_explorer_utils.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,8 @@
use std::{os::windows::process::CommandExt, path::PathBuf, process::Command};
use std::{
os::windows::process::CommandExt,
path::{Path, PathBuf},
process::Command,
};

pub fn open_path_in_explorer(file: &PathBuf) {
if let Err(e) = (|| {
Expand All @@ -21,22 +25,23 @@ pub fn open_path_in_explorer(file: &PathBuf) {
}
}

pub fn highlight_path_in_explorer(file: &std::path::PathBuf) {
pub fn highlight_path_in_explorer(file: &Path) {
if let Err(e) = (|| {
#[cfg(target_os = "windows")]
{
if let Some(s) = file.to_str() {
let mut s = s.replace("/", r#"\"#);
s.push_str("\"");
let mut s = s.replace('/', r#"\"#);
s.push('\"');
let s = s.as_str();

return Command::new("explorer")
.raw_arg("/select,\"".to_string() + s)
.spawn();
} else {
return Err(std::io::Error::new(
Err(std::io::Error::new(
std::io::ErrorKind::Other,
"Can't convert PathBuf to_str",
));
))
}
}

Expand Down
2 changes: 1 addition & 1 deletion bepinex_gui/src/backend/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ impl BepInExGUI {
// Ideally this would be done in a init function, not constantly checked in an update function
// L from eframe
if !self.is_window_title_set {
frame.set_window_title(&self.app_launch_config.window_title());
frame.set_window_title(self.app_launch_config.window_title());
self.is_window_title_set = true;
}

Expand Down
38 changes: 12 additions & 26 deletions bepinex_gui/src/backend/network/packet_protocol.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ use std::net::TcpStream;

use crate::data::bepinex_log::LogLevel;

pub(crate) fn read_packet_length(tcp_stream: &mut TcpStream) -> Result<usize, std::io::Error> {
pub fn read_packet_length(tcp_stream: &mut TcpStream) -> Result<usize, std::io::Error> {
const HEADER_SIZE: usize = size_of::<u32>();

let mut received_bytes = read_packet_internal(tcp_stream, HEADER_SIZE)?;
Expand All @@ -18,9 +18,7 @@ pub(crate) fn read_packet_length(tcp_stream: &mut TcpStream) -> Result<usize, st
Ok(packet_length)
}

pub(crate) fn read_packet_log_level(
tcp_stream: &mut TcpStream,
) -> Result<LogLevel, std::io::Error> {
pub fn read_packet_log_level(tcp_stream: &mut TcpStream) -> Result<LogLevel, std::io::Error> {
unsafe {
let mut received_bytes = read_packet_internal(tcp_stream, size_of::<i32>())?;

Expand All @@ -32,7 +30,7 @@ pub(crate) fn read_packet_log_level(
}
}

pub(crate) fn read_packet(
pub fn read_packet(
tcp_stream: &mut TcpStream,
size_to_read: usize,
) -> Result<Vec<u8>, std::io::Error> {
Expand All @@ -47,30 +45,18 @@ fn read_packet_internal(
) -> Result<Vec<u8>, std::io::Error> {
const BUFFER_SIZE: usize = 4096;

let mut packet_bytes: Vec<u8> = vec![];
let mut read_stream_buffer = vec![0u8; size_to_read];
let mut packet_bytes = Vec::with_capacity(size_to_read);
let mut remaining_size_to_read = size_to_read;

loop {
read_stream_buffer.clear();
read_stream_buffer.resize(
if remaining_size_to_read > BUFFER_SIZE {
BUFFER_SIZE
} else {
remaining_size_to_read
},
0,
);
while remaining_size_to_read > 0 {
let bytes_read = BUFFER_SIZE.min(remaining_size_to_read);

match tcp_stream.read(&mut read_stream_buffer) {
Ok(bytes_read) => {
packet_bytes.extend_from_slice(&read_stream_buffer[..bytes_read]);
let mut read_stream_buffer = vec![0u8; bytes_read];

match tcp_stream.read_exact(&mut read_stream_buffer) {
Ok(_) => {
packet_bytes.extend_from_slice(&read_stream_buffer);
remaining_size_to_read -= bytes_read;

if remaining_size_to_read <= 0 {
break;
}
}
Err(err) => return Err(err),
}
Expand All @@ -79,6 +65,6 @@ fn read_packet_internal(
Ok(packet_bytes)
}

pub(crate) fn packet_bytes_to_utf8_string(packet_bytes: &Vec<u8>) -> String {
unsafe { std::str::from_utf8_unchecked(&packet_bytes).to_string() }
pub fn packet_bytes_to_utf8_string(packet_bytes: &[u8]) -> String {
unsafe { std::str::from_utf8_unchecked(packet_bytes).to_string() }
}
13 changes: 8 additions & 5 deletions bepinex_gui/src/backend/panic_handler.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,13 @@ use std::panic;

pub fn init() {
panic::set_hook(Box::new(|panic_info| {
if let Some(s) = panic_info.payload().downcast_ref::<&str>() {
tracing::error!("panic occurred: {s:?}");
} else {
tracing::error!("panic occurred");
}
panic_info.payload().downcast_ref::<&str>().map_or_else(
|| {
tracing::error!("panic occurred");
},
|s| {
tracing::error!("panic occurred: {s:?}");
},
)
}));
}
36 changes: 18 additions & 18 deletions bepinex_gui/src/backend/process/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,20 +23,22 @@ use winapi::{
};

#[cfg(windows)]
pub(crate) fn for_each_thread(target_process_id: Pid, callback: impl Fn(HANDLE)) -> bool {
pub fn for_each_thread(target_process_id: Pid, callback: impl Fn(HANDLE)) -> bool {
use sysinfo::PidExt;
use winapi::um::winnt::THREAD_SUSPEND_RESUME;

unsafe {
let sys = sysinfo::System::new_all();

if let Some(_) = sys.process(target_process_id) {
if sys.process(target_process_id).is_some() {
let thread_snapshot =
winapi::um::tlhelp32::CreateToolhelp32Snapshot(TH32CS_SNAPTHREAD, 0);

let mut te32: THREADENTRY32 = Default::default();
te32.dwSize = size_of::<THREADENTRY32>() as DWORD;
let te32_ptr = std::mem::transmute(&te32);
let mut te32: THREADENTRY32 = THREADENTRY32 {
dwSize: size_of::<THREADENTRY32>() as DWORD,
..Default::default()
};
let te32_ptr = std::ptr::addr_of_mut!(te32);

if winapi::um::tlhelp32::Thread32First(thread_snapshot, te32_ptr) == 0 {
tracing::error!("Thread32First fail");
Expand All @@ -51,7 +53,7 @@ pub(crate) fn for_each_thread(target_process_id: Pid, callback: impl Fn(HANDLE))
te32.th32ThreadID,
);

if open_thread_handle == std::ptr::null_mut() {
if open_thread_handle.is_null() {
tracing::error!("OpenThread Failed");
break;
}
Expand All @@ -71,40 +73,40 @@ pub(crate) fn for_each_thread(target_process_id: Pid, callback: impl Fn(HANDLE))
return true;
}

return false;
false
}
}

#[cfg(not(windows))]
pub(crate) fn for_each_thread() {
pub fn for_each_thread() {
// todo
}

#[cfg(windows)]
pub(crate) fn resume(target_process_id: Pid) -> bool {
pub fn resume(target_process_id: Pid) -> bool {
for_each_thread(target_process_id, |thread_handle| unsafe {
winapi::um::processthreadsapi::ResumeThread(thread_handle);
})
}

#[cfg(not(windows))]
pub(crate) fn resume(target_process_id: Pid) -> bool {
pub fn resume(target_process_id: Pid) -> bool {
// todo
}

#[cfg(windows)]
pub(crate) fn suspend(target_process_id: Pid) -> bool {
pub fn suspend(target_process_id: Pid) -> bool {
for_each_thread(target_process_id, |thread_handle| unsafe {
winapi::um::processthreadsapi::SuspendThread(thread_handle);
})
}

#[cfg(not(windows))]
pub(crate) fn suspend(target_process_id: Pid) -> bool {
pub fn suspend(target_process_id: Pid) -> bool {
// todo
}

pub(crate) fn spawn_thread_is_process_dead(
pub fn spawn_thread_is_process_dead(
target_process_id: Pid,
should_check: Arc<AtomicBool>,
out_true_when_process_is_dead: Arc<AtomicBool>,
Expand Down Expand Up @@ -135,13 +137,11 @@ pub fn kill(target_process_id: Pid, callback: impl FnOnce()) {
}

#[cfg(windows)]
pub(crate) fn spawn_thread_check_if_process_is_hung(
callback: impl Fn() + std::marker::Send + 'static,
) {
pub fn spawn_thread_check_if_process_is_hung(callback: impl Fn() + std::marker::Send + 'static) {
thread::spawn(move || -> io::Result<()> {
unsafe {
static mut CURRENT_PROCESS_ID: u32 = 0;
CURRENT_PROCESS_ID = GetCurrentProcessId() as u32;
CURRENT_PROCESS_ID = GetCurrentProcessId();

static mut GOT_RESULT: bool = false;

Expand All @@ -155,7 +155,7 @@ pub(crate) fn spawn_thread_check_if_process_is_hung(
}

let mut proc_id: DWORD = 0 as DWORD;
let _ = GetWindowThreadProcessId(window, &mut proc_id as *mut DWORD);
let _ = GetWindowThreadProcessId(window, std::ptr::addr_of_mut!(proc_id));
if proc_id == CURRENT_PROCESS_ID {
WINDOW_HANDLE = window;
}
Expand Down
2 changes: 1 addition & 1 deletion bepinex_gui/src/backend/reset_app_if_window_hang.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ use super::process;
// the gui window not respond
// bandaid fix that call winapi for checking if the window hung
// and reset the process with a cleaned settings file if so
pub(crate) fn spawn_thread() {
pub fn spawn_thread() {
process::spawn_thread_check_if_process_is_hung(|| {
if let Some(app_ron_file_path) = config::get_app_ron_file_full_path() {
let current_exe =
Expand Down
8 changes: 4 additions & 4 deletions bepinex_gui/src/backend/thunderstore/api.rs
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ fn find_modding_discord_from_target_process_name(
let json = reqwest::blocking::get(URL).and_then(|resp| resp.text())?;

let communities = serde_json::from_str::<Communities>(&json)
.and_then(|c| Ok(c.results))?
.map(|c| c.results)?
.ok_or("no communities.results")?;

let sys = sysinfo::System::new_all();
Expand All @@ -45,7 +45,7 @@ fn find_modding_discord_from_target_process_name(

let proc_name_osstring = Path::new(&proc.name().to_lowercase())
.file_stem()
.and_then(|s| Some(s.to_os_string()))
.map(|s| s.to_os_string())
.ok_or("failed getting proc name from proc")?
.into_string();

Expand All @@ -58,7 +58,7 @@ fn find_modding_discord_from_target_process_name(
for community in communities {
let community_name_lower = community
.name
.and_then(|n| Some(n.to_lowercase().to_string()))
.map(|n| n.to_lowercase())
.ok_or("failed lowercasing")?;

if proc_name.contains(&community_name_lower) || community_name_lower.contains(&proc_name) {
Expand All @@ -69,7 +69,7 @@ fn find_modding_discord_from_target_process_name(
}
}

Err(format!("No community matching target process name {}", proc_name).into())
Err(format!("No community matching target process name {proc_name}").into())
}

pub fn open_modding_discord(target_process_id: Pid) {
Expand Down
Loading

0 comments on commit 571e8d8

Please sign in to comment.