Skip to content

Conversation

@khanghugo
Copy link
Contributor

@khanghugo khanghugo commented Jan 6, 2026

Make it easier for people to use just bxt-rs.

One incidental good usage of BunnymodXT is that it always "focuses" on the game when the game is not in focus, meaning no FPS drop. BXT also allows launching multiple instances. With those two combined, a streaming setup containing multiple views of the game.

This should be included in bxt-rs as some of the more features (for spectating) I recently developed for are only on bxt-rs.

@YaLTeR
Copy link
Owner

YaLTeR commented Jan 6, 2026

Isn't this function called for every single hooked pointer? Doesn't seem appropriate to do this here

@khanghugo
Copy link
Contributor Author

You are absolutely right -- your assertion correctly points out implementation inefficiency from my part!

Anyway, fixed. Interesting that OpenMutexA() does not work if freeing mutex happens once outside the pointer hooking function. Though I do know that OpenMutexW() exists because it is the first google result when I look up "OpenMutexA". And that works.

let mutex = OpenMutexW(
SYNCHRONIZE,
0,
to_wide("ValveHalfLifeLauncherMutex").as_ptr(),
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pretty sure this will drop the Vec before it gets passed into a function, leading to a use after free

Also while we're at it could you extract all this into a separate function

Copy link
Contributor Author

@khanghugo khanghugo Jan 7, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmmmmm, I thought compiler would just create a constant string during compilation. rust-analyzer didn't complain and it works. This code is copied from my other project and that also works.

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I mean maybe it could be optimized but here you're allocating a new Vec<> that you're returning from a function, getting its .as_ptr(), then instantly dropping the Vec, and passing the now-stale ptr into the function. If you try that with CString::new() I think they even added a warning/error for this

@YaLTeR
Copy link
Owner

YaLTeR commented Jan 7, 2026

Interesting that OpenMutexA() does not work if freeing mutex happens once outside the pointer hooking function.

But BXT uses A? https://github.com/YaLTeR/BunnymodXT/blob/eec19bf169f77b813724118c9c4b009fdecb4077/BunnymodXT/helper_functions.hpp#L23

@khanghugo
Copy link
Contributor Author

Yes it does. I am still not sure why but when I use OpenMutexA() inside the loop, it works. When I use it outside the loop, it no works. OpenMutexW() however works in that case. I decide to stop my investigation once it works.
That is on Linux. I had to willingly boot up Windows for testing and the same behavior exhibits.

@YaLTeR YaLTeR merged commit 6ab51ed into YaLTeR:master Jan 7, 2026
13 checks passed
@YaLTeR
Copy link
Owner

YaLTeR commented Jan 7, 2026

Weird and unfortunate to have that vector but alright ty

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants