Skip to content

Commit

Permalink
Merge feat(mono-rt2): add NuiEvent attribute (pr-2463)
Browse files Browse the repository at this point in the history
 - b29e70d feat(mono-rt2): add NuiCallback attribute
  • Loading branch information
thorium-cfx committed Apr 26, 2024
2 parents 1549555 + b29e70d commit e342af6
Show file tree
Hide file tree
Showing 3 changed files with 151 additions and 4 deletions.
26 changes: 26 additions & 0 deletions code/client/clrcore-v2/Attributes.cs
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,32 @@ public EventHandlerAttribute(string name, Binding binding = Binding.All)
Binding = binding;
}
}

#if !IS_FXSERVER
/// <summary>
/// Register this method to listen for the given <see cref="CallbackName"/> when this <see cref="BaseScript"/> is loaded
/// if <see cref="IsRawCallback"/> is specified this will use a raw NUI callback instead
/// </summary>
/// <remarks>Only works on <see cref="BaseScript"/> inherited class methods</remarks>
#else
/// <summary>Does nothing on server side</summary>
[EditorBrowsable(EditorBrowsableState.Never)]
#endif
[AttributeUsage(AttributeTargets.Method, AllowMultiple = true)]
public class NuiCallbackAttribute : Attribute
{
public string CallbackName { get; }
public bool IsRawCallback { get; }
public NuiCallbackAttribute(string callbackName, bool isRawCallback = false)
{
CallbackName = callbackName;
if (isRawCallback)
{
throw new NotImplementedException("Raw Nui Callbacks are not currently implemented");
}
IsRawCallback = isRawCallback;
}
}

/// <summary>
/// Register this method to listen for the given <see cref="Export"/> when this <see cref="BaseScript"/> is loaded
Expand Down
98 changes: 98 additions & 0 deletions code/client/clrcore-v2/BaseScript.cs
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,8 @@ protected event Func<Coroutine> Tick
}

private readonly List<KeyValuePair<int, DynFunc>> m_commands = new List<KeyValuePair<int, DynFunc>>();

private readonly Dictionary<string, DynFunc> m_nuiCallbacks = new Dictionary<string, DynFunc>();

#if REMOTE_FUNCTION_ENABLED
private readonly List<RemoteHandler> m_persistentFunctions = new List<RemoteHandler>();
Expand Down Expand Up @@ -100,6 +102,9 @@ internal void Initialize()
case KeyMapAttribute keyMap:
RegisterKeyMap(keyMap.Command, keyMap.Description, keyMap.InputMapper, keyMap.InputParameter, Func.CreateCommand(this, method, keyMap.RemapParameters));
break;
case NuiCallbackAttribute nuiCallback:
RegisterNuiCallback(nuiCallback.CallbackName, Func.Create(this, method));
break;
#endif
case ExportAttribute export:
Exports.Add(export.Export, Func.Create(this, method), export.Binding);
Expand Down Expand Up @@ -140,6 +145,11 @@ public void Enable()
ReferenceFunctionManager.SetDelegate(m_commands[i].Key, m_commands[i].Value);
}

foreach (var nuiCallback in m_nuiCallbacks)
{
Native.CoreNatives.RegisterNuiCallback(nuiCallback.Key, nuiCallback.Value);
}

EventHandlers.Enable();
Exports.Enable();

Expand Down Expand Up @@ -171,6 +181,11 @@ public void Disable()
{
ReferenceFunctionManager.SetDelegate(m_commands[i].Key, (_0, _1) => null);
}

foreach (var nuiCallback in m_nuiCallbacks)
{
Native.CoreNatives.RemoveNuiCallback(nuiCallback.Key);
}

EventHandlers.Disable();
Exports.Disable();
Expand Down Expand Up @@ -283,7 +298,90 @@ internal void RegisterKeyMap(string command, string description, string inputMap
m_commands.Add(new KeyValuePair<int, DynFunc>(ReferenceFunctionManager.CreateCommand(command, dynFunc, false), dynFunc));
#endif
}

#endregion

#region NUI Callback registration

internal void RegisterNuiCallback(string callbackName, DynFunc dynFunc)
{
#if IS_FXSERVER
throw new NotImplementedException();
#endif
m_nuiCallbacks.Add(callbackName, dynFunc);
Native.CoreNatives.RegisterNuiCallback(callbackName, dynFunc);
}

/// <summary>
/// Registers the NUI callback and binds it to the the <see cref="BaseScript"/>
/// </summary>
/// <param name="callbackName">the NUI callback to add</param>
/// <param name="delegateFn">The function to bind the callback to, the callback will be invoked with an ExpandoObject containing the data and a <see cref="Callback"/> </param>
#if IS_FXSERVER
/// <summary>Does nothing on server side</summary>
[EditorBrowsable(EditorBrowsableState.Never)]
#endif
public void RegisterNuiCallback(string callbackName, Delegate delegateFn)
{
#if IS_FXSERVER
throw new NotImplementedException();
#endif
DynFunc dynFunc = Func.Create(delegateFn);
m_nuiCallbacks.Add(callbackName, dynFunc);
Native.CoreNatives.RegisterNuiCallback(callbackName, dynFunc);
}

/// <summary>
/// Unregisters the NUI callback from the <see cref="BaseScript"/>
/// </summary>
/// <param name="callbackName">the NUI callback to remove</param>
#if IS_FXSERVER
/// <summary>Does nothing on server side</summary>
[EditorBrowsable(EditorBrowsableState.Never)]
#endif
public void UnregisterNuiCallback(string callbackName)
{
#if IS_FXSERVER
throw new NotImplementedException();
#endif
m_nuiCallbacks.Remove(callbackName);
Native.CoreNatives.RemoveNuiCallback(callbackName);
}

/// <summary>
/// Registers a NUI callback to the specified <paramref name="callbackName"/>
/// </summary>
/// <param name="callbackName">the event that the callback will bind to</param>
/// <param name="delegateFn">The function to bind the callback to, the callback will be invoked with an ExpandoObject containing the data and a <see cref="Callback"/> </param>
#if IS_FXSERVER
/// <summary>Does nothing on server side</summary>
[EditorBrowsable(EditorBrowsableState.Never)]
#endif
public static void AddNuiCallback(string callbackName, Delegate delegateFn)
{
#if IS_FXSERVER
throw new NotImplementedException();
#endif
Native.CoreNatives.RegisterNuiCallback(callbackName, delegateFn);
}

/// <summary>
/// Removes the NUI callback for the specified <paramref namem="callbackName"/>
/// </summary>
/// <param name="callbackName">the callback event that will be removed</param>
#if IS_FXSERVER
/// <summary>Does nothing on server side</summary>
[EditorBrowsable(EditorBrowsableState.Never)]
#endif
public static void RemoveNuiCallback(string callbackName)
{
#if IS_FXSERVER
throw new NotImplementedException();
#else
Native.CoreNatives.RemoveNuiCallback(callbackName);
#endif
}

#endregion

#region Script loading
Expand Down
31 changes: 27 additions & 4 deletions code/client/clrcore-v2/Native/Native.cs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@ internal static class CoreNatives
private static UIntPtr s_0x637f4c75;
private static UIntPtr s_0x8d50e33a;
private static UIntPtr s_0x91310870;
private static UIntPtr s_registerNuiCallback; // 0xc59b980c
private static UIntPtr s_unregisterRawNuiCallback; // 0x7fb46432
#if IS_FXSERVER
private static UIntPtr s_0x2f7a49e6;
private static UIntPtr s_0x70b35890;
Expand All @@ -34,12 +36,23 @@ internal static unsafe void RegisterResourceAsEventHandler(CString eventName)
}

[SecuritySafeCritical]
internal static unsafe void RegisterCommand(CString commandName, InFunc handler, bool restricted)
internal static unsafe void RegisterNuiCallback(CString callbackName, InFunc handler)
{
fixed (byte* p_commandName = commandName?.value, p_handler = &handler.value[0])
fixed (byte* p_callbackType = callbackName?.value, p_handler = &handler.value[0])
{
ulong* __data = stackalloc ulong[] { (ulong)p_commandName, (ulong)p_handler, N64.Val(restricted) };
ScriptContext.InvokeNative(ref s_0x5fa79b0f, 0x5fa79b0f, __data, 3); // REGISTER_COMMAND
ulong* __data = stackalloc ulong[] { (ulong)p_callbackType, (ulong)p_handler };
ScriptContext.InvokeNative(ref s_registerNuiCallback, 0xc59b980c, __data, 2); // REGISTER_NUI_CALLBACK
}
}


[SecuritySafeCritical]
internal static unsafe void RemoveNuiCallback(CString callbackName)
{
fixed (byte* p_callbackType = callbackName?.value)
{
ulong* __data = stackalloc ulong[] { (ulong)p_callbackType };
ScriptContext.InvokeNative(ref s_unregisterRawNuiCallback, 0x7fb46432, __data, 1); // UNREGISTER_RAW_NUI_CALLBACK
}
}

Expand All @@ -55,6 +68,16 @@ public static unsafe void RegisterKeyMapping(CString commandString, CString desc
ScriptContext.InvokeNative(ref s_0xd7664fd1, 0xd7664fd1, __data, 4);
}
}

[SecuritySafeCritical]
internal static unsafe void RegisterCommand(CString commandName, InFunc handler, bool restricted)
{
fixed (byte* p_commandName = commandName?.value, p_handler = &handler.value[0])
{
ulong* __data = stackalloc ulong[] { (ulong)p_commandName, (ulong)p_handler, N64.Val(restricted) };
ScriptContext.InvokeNative(ref s_0x5fa79b0f, 0x5fa79b0f, __data, 3); // REGISTER_COMMAND
}
}

[SecuritySafeCritical]
internal static unsafe object GetStateBagValue(CString bagName, CString key)
Expand Down

0 comments on commit e342af6

Please sign in to comment.