Skip to content

Conversation

@ELDment
Copy link
Contributor

@ELDment ELDment commented Sep 3, 2025

Assume we have:

private MemoryFunctionVoid<nint, uint> func = new("48 8B C4 53 55 57 48 81 EC ? ? ? ? 0F B6 A9");

We created a hook for this function:

func.Hook((h) => {
    // (possibly modify parameters)
    return HookResult.Changed;
}, HookMode.Pre);

However, at some point, we may need to invoke func without any modifications to its parameters (i.e., bypassing the hook):

func.Invoke(a, b);

This type of requirement is common, but previously, it could not be achieved using the CSS framework itself.
Without a bypass mechanism, the above Invoke call would still be intercepted by the hook, potentially modifying the parameters, which contradicts the requirement

We have now implemented a bypass hook feature. By simply passing a bool parameter, you can easily bypass the hook:

func.Invoke(a, b, true);

btw: This update is fully backward compatible (the default value of bool bypass is set to false). Even plugins built with older versions of CSS using Hook/Invoke will continue to work without issues

@ELDment ELDment requested a review from roflmuffin as a code owner September 3, 2025 08:27
@roflmuffin
Copy link
Owner

Thanks for the PR. Unfortunately adding optional parameters to a method is actually a breaking change if a plugin is not recompiled against latest API. Sadly the only way around this to create an entirely new method with the new parameter added.

@ELDment
Copy link
Contributor Author

ELDment commented Sep 8, 2025

Thanks for the PR. Unfortunately adding optional parameters to a method is actually a breaking change if a plugin is not recompiled against latest API. Sadly the only way around this to create an entirely new method with the new parameter added.

Testing Results:

The server is using CounterStrikeSharp.API.dll built from the current PR, while the test library was compiled with v1.0.338

The Invoke functionality works without errors, confirming that the current implementation approach is viable

btw: I simply overloaded all the relevant functions, which does create some code redundancy. If refactoring is needed to reduce duplication, please let me know and I will refactor the implementation


@roflmuffin

@roflmuffin
Copy link
Owner

roflmuffin commented Sep 8, 2025

Thanks for the PR. Unfortunately adding optional parameters to a method is actually a breaking change if a plugin is not recompiled against latest API. Sadly the only way around this to create an entirely new method with the new parameter added.

Testing Results:

The server is using CounterStrikeSharp.API.dll built from the current PR, while the test library was compiled with v1.0.338

The Invoke functionality works without errors, confirming that the current implementation approach is viable

btw: I simply overloaded all the relevant functions, which does create some code redundancy. If refactoring is needed to reduce duplication, please let me know and I will refactor the implementation

@roflmuffin

https://stackoverflow.com/a/23517490

@ELDment
Copy link
Contributor Author

ELDment commented Sep 8, 2025

Thanks for the PR. Unfortunately adding optional parameters to a method is actually a breaking change if a plugin is not recompiled against latest API. Sadly the only way around this to create an entirely new method with the new parameter added.

Testing Results:

The server is using CounterStrikeSharp.API.dll built from the current PR, while the test library was compiled with v1.0.338
The Invoke functionality works without errors, confirming that the current implementation approach is viable
btw: I simply overloaded all the relevant functions, which does create some code redundancy. If refactoring is needed to reduce duplication, please let me know and I will refactor the implementation
@roflmuffin

https://stackoverflow.com/a/23517490

You're absolutely right about the potential issues with default parameters. Initially, I did consider using default parameters, but after your feedback, I switched to method overloading instead:

public TResult Invoke(T1 arg1)                    // Method 1
public TResult Invoke(T1 arg1, bool bypasshook)   // Method 2


This approach generates two separate methods in the compiled assembly, ensuring full backward compatibility without requiring recompilation of existing code

@roflmuffin roflmuffin enabled auto-merge (squash) September 8, 2025 06:11
@roflmuffin roflmuffin merged commit 1ca8ff2 into roflmuffin:main Sep 8, 2025
6 checks passed
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