roflmuffin / CounterStrikeSharp

CounterStrikeSharp allows you to write server plugins in C# for Counter-Strike 2/Source2/CS2

Home Page:https://docs.cssharp.dev

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Hooking `GiveNamedItemFunc` (`HookMode.Post`) throws exception on Windows

ianlucas opened this issue · comments

Consider the sample plugin below.

using CounterStrikeSharp.API.Core;
using CounterStrikeSharp.API.Modules.Memory;
using Microsoft.Extensions.Logging;

namespace PlaygroundPlugin;

public class PlaygroundPlugin : BasePlugin
{
    public override string ModuleName => "Hello World Plugin";

    public override string ModuleVersion => "0.0.1";

    public override void Load(bool hotReload)
    {
        VirtualFunctions.GiveNamedItemFunc.Hook(hook =>
        {
            var itemServices = hook.GetParam<CCSPlayer_ItemServices>(0);
            var className = hook.GetParam<string>(1);
            var weapon = hook.GetReturn<CBasePlayerWeapon>();
            var pawn = itemServices.Pawn.Value;
            var playerName = "<unknown>";

            if (pawn.IsValid && pawn.Controller.IsValid && pawn.Controller.Value != null)
            {
                var player = new CCSPlayerController(pawn.Controller.Value.Handle);
                playerName = player.PlayerName;
            }

            Logger.LogInformation($"GiveNamedItem '{className}' (index {weapon.Index}) to player {playerName}.");        
            return HookResult.Continue;
        }, HookMode.Post);
    }
}

On Linux:

2024-03-13 19:38:03.231 +00:00 [INFO] plugin:Hello World Plugin GiveNamedItem 'weapon_p250' (index 341) to player Maximus.
2024-03-13 19:38:03.433 +00:00 [INFO] plugin:Hello World Plugin GiveNamedItem 'weapon_famas' (index 342) to player Kev.
2024-03-13 19:38:03.433 +00:00 [INFO] plugin:Hello World Plugin GiveNamedItem 'item_assaultsuit' (index 343) to player Kev.
2024-03-13 19:38:03.434 +00:00 [INFO] plugin:Hello World Plugin GiveNamedItem 'weapon_p250' (index 344) to player Kev.
2024-03-13 19:38:12.550 +00:00 [INFO] plugin:Hello World Plugin GiveNamedItem 'weapon_knife_t' (index 348) to player Dragomir.
2024-03-13 19:38:12.551 +00:00 [INFO] plugin:Hello World Plugin GiveNamedItem 'weapon_glock' (index 349) to player Dragomir.

On Windows:

16:33:44 [INFO] (plugin:Hello World Plugin) GiveNamedItem 'weapon_knife' (index 278) to player Crasswater.
16:33:44 [EROR] (cssharp:Core) Error invoking callback
System.Reflection.TargetInvocationException: Exception has been thrown by the target of an invocation.
 ---> System.AccessViolationException: Attempted to read or write protected memory. This is often an indication that other memory is corrupt.
   at System.Runtime.InteropServices.Marshal.ReadByte(IntPtr ptr, Int32 ofs)
   at CounterStrikeSharp.API.Core.ScriptContext.GetResult(Type type, Byte* ptr) in /home/runner/work/CounterStrikeSharp/CounterStrikeSharp/managed/CounterStrikeSharp.API/Core/ScriptContext.cs:line 451
   at CounterStrikeSharp.API.Core.ScriptContext.GetResult(Type type) in /home/runner/work/CounterStrikeSharp/CounterStrikeSharp/managed/CounterStrikeSharp.API/Core/ScriptContext.cs:line 379
   at CounterStrikeSharp.API.Core.NativeAPI.DynamicHookGetParam[T](IntPtr hook, Int32 datatype, Int32 paramindex) in /home/runner/work/CounterStrikeSharp/CounterStrikeSharp/managed/CounterStrikeSharp.API/Core/API.cs:line 240
   at CounterStrikeSharp.API.Modules.Memory.DynamicFunctions.DynamicHook.GetParam[T](Int32 index) in /home/runner/work/CounterStrikeSharp/CounterStrikeSharp/managed/CounterStrikeSharp.API/Modules/Memory/DynamicFunctions/DynamicHook.cs:line 14
   at PlaygroundPlugin.PlaygroundPlugin.<Load>b__4_0(DynamicHook hook) in C:\Users\ianlu\Projects\cs2-playground-plugin\PlaygroundPlugin.cs:line 18
   at InvokeStub_Func`2.Invoke(Object, Object, IntPtr*)
   at System.Reflection.MethodInvoker.Invoke(Object obj, IntPtr* args, BindingFlags invokeAttr)
   --- End of inner exception stack trace ---
   at System.Reflection.MethodInvoker.Invoke(Object obj, IntPtr* args, BindingFlags invokeAttr)
   at System.Reflection.RuntimeMethodInfo.Invoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture)
   at System.Delegate.DynamicInvokeImpl(Object[] args)
   at CounterStrikeSharp.API.Core.FunctionReference.<CreateWrappedCallback>b__18_0(fxScriptContext* context) in /home/runner/work/CounterStrikeSharp/CounterStrikeSharp/managed/CounterStrikeSharp.API/Core/FunctionReference.cs:line 100

As you can see, it works as expected on Linux, but on Windows it crashes sometimes (I'd say most of the time). Maybe type safety must be added around DynamicHook API as we can have access violation exceptions...?

DynamicHook API is not working well on windows rn