-
Notifications
You must be signed in to change notification settings - Fork 1
feat: introduce legacy patcher system and mod management API with frontend integration #73
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
…ntend integration
| let settings = settings | ||
| .0 | ||
| .lock() | ||
| .map_err(|e| AppError::InternalState(e.to_string()))? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Instead of doing map_err we should implement a new AppError variant for when the Mutex lock fails.
| #[error("Failed to begin hook")] | ||
| HookFailed, | ||
| #[error("Hook initialization timed out")] | ||
| HookTimeout, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Don't remove this, it's for the new patcher
| match run_patcher_loop( | ||
| &dll_path, | ||
| &config_path, | ||
| &overlay_root_for_thread, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
config_path in new patcher is the equivalent of the overlay path, we need to make the backend implementation abstract enough so that it can support the current (legacy) patcher and the new one as well.
| let tid = loop { | ||
| if stop_flag.load(Ordering::SeqCst) { | ||
| return Err(PatcherLoopError::Stopped); | ||
| } | ||
| match api.find() { | ||
| Some(tid) => break tid.get(), | ||
| None => api.sleep(100), | ||
| } | ||
| }; | ||
|
|
||
| tracing::info!("Found League process, thread id: {}", tid); | ||
|
|
||
| let count_before = api.hook_count(); | ||
| let hook = api.hook_begin(tid); | ||
| if hook == 0 { | ||
| return Err(PatcherLoopError::HookFailed); | ||
| } | ||
|
|
||
| let mut time_remaining = timeout_ms as i64; | ||
| loop { | ||
| if stop_flag.load(Ordering::SeqCst) { | ||
| api.hook_end(tid, hook); | ||
| return Err(PatcherLoopError::Stopped); | ||
| } | ||
|
|
||
| if time_remaining <= 0 { | ||
| api.hook_end(tid, hook); | ||
| return Err(PatcherLoopError::HookTimeout); | ||
| } | ||
|
|
||
| api.hook_continue(tid, hook); | ||
| api.sleep(HOOK_STEP_MS); | ||
|
|
||
| if api.hook_count() != count_before { | ||
| tracing::info!("Hooks applied successfully"); | ||
| api.hook_end(tid, hook); | ||
| break; | ||
| tracing::info!("Waiting for game to start (polling cslol_find)..."); | ||
| let mut last_wait_log = Instant::now(); | ||
| let tid = loop { | ||
| if stop_flag.load(Ordering::SeqCst) { | ||
| return Err(PatcherLoopError::Stopped); | ||
| } | ||
| match api.find() { | ||
| Some(tid) => break tid.get(), | ||
| None => { | ||
| if last_wait_log.elapsed() >= Duration::from_secs(5) { | ||
| tracing::info!("Still waiting for game process..."); | ||
| last_wait_log = Instant::now(); | ||
| } | ||
| api.sleep(100); | ||
| } | ||
| } | ||
| }; | ||
|
|
||
| tracing::info!("Game found (thread id: {})", tid); | ||
|
|
||
| tracing::info!( | ||
| "Applying hook (timeout_ms={}, step_ms={})...", | ||
| timeout_ms, | ||
| HOOK_STEP_MS | ||
| ); | ||
| api.hook(tid, timeout_ms, HOOK_STEP_MS)?; | ||
| tracing::info!("Hook applied, waiting for game to exit..."); | ||
|
|
||
| while !stop_flag.load(Ordering::SeqCst) { | ||
| match api.find() { | ||
| Some(current) if current.get() == tid => { | ||
| while let Some(msg) = api.log_pull() { | ||
| tracing::info!("[cslol] {}", msg); | ||
| } | ||
| api.sleep(1000); | ||
| } | ||
| _ => break, | ||
| } | ||
| } | ||
|
|
||
| time_remaining -= HOOK_STEP_MS as i64; | ||
| tracing::info!("Game exited, returning to wait loop"); | ||
| } | ||
|
|
||
| tracing::info!("Hook session completed"); | ||
| Ok(()) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do not remove the new patcher hook routine implementation, instead move this code from the command file into the relevant patcher module and make it abstract at the point of calling - this file, so we support multiple patcher implementations.
| Ok(Self { | ||
| cslol_init: *lib | ||
| .get(b"cslol_init") | ||
| .map_err(|e| PatcherError::MissingSymbol { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We can just use the ? operator here
No description provided.