You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Rage MP C#服务器中实现带权限校验的事件回调处理

Rage MP C#服务器实现带权限校验的客户端事件

1. 定义自定义Authorized属性

先创建标记用的属性类,用于标记需要权限校验的事件方法:

[AttributeUsage(AttributeTargets.Method, Inherited = false, AllowMultiple = false)]
public sealed class AuthorizedAttribute : Attribute
{
    // 可扩展添加权限等级参数,比如:
    // public string RequiredRole { get; set; } = "Admin";
}

2. 实现全局事件中转处理器

因为NAPI.ClientEvent.Register仅支持传入MethodInfo,我们需要一个统一的处理方法,负责权限校验和目标方法调用:

public static class EventAuthorizationHandler
{
    private static readonly Dictionary<string, (MethodInfo TargetMethod, bool RequiresAuth, object ScriptInstance)> _eventMappings = new();

    // 初始化:扫描所有脚本类中的标记方法并完成注册
    public static void Initialize()
    {
        // 扫描所有继承自RageScript的类
        var scriptTypes = AppDomain.CurrentDomain.GetAssemblies()
            .SelectMany(asm => asm.GetTypes())
            .Where(t => typeof(RageScript).IsAssignableFrom(t) && !t.IsAbstract);

        foreach (var type in scriptTypes)
        {
            // 实例化脚本(符合Rage MP的脚本加载规则)
            var scriptInstance = Activator.CreateInstance(type);

            // 筛选带[EventHandler]标记的公开实例方法
            var eventMethods = type.GetMethods(BindingFlags.Public | BindingFlags.Instance)
                .Where(m => m.GetCustomAttribute<EventHandlerAttribute>() != null);

            foreach (var method in eventMethods)
            {
                var eventAttr = method.GetCustomAttribute<EventHandlerAttribute>();
                var eventName = eventAttr.Name;
                var requiresAuth = method.GetCustomAttribute<AuthorizedAttribute>() != null;

                // 注册事件到NAPI,指向统一处理方法
                NAPI.ClientEvent.Register(eventName, typeof(EventAuthorizationHandler).GetMethod(nameof(HandleClientEvent)));

                // 保存事件与目标方法、权限要求、脚本实例的映射
                _eventMappings[eventName] = (method, requiresAuth, scriptInstance);
            }
        }
    }

    // NAPI会调用此方法处理所有注册的客户端事件
    public static void HandleClientEvent(Player player, params object[] args)
    {
        var eventName = NAPI.CallContext.CurrentEventName;
        if (!_eventMappings.TryGetValue(eventName, out var mapping)) return;

        // 权限校验逻辑
        if (mapping.RequiresAuth && !IsPlayerAuthorized(player))
        {
            NAPI.Chat.SendChatMessageToPlayer(player, "~r~你没有权限执行该操作!");
            return;
        }

        // 调用目标事件方法
        try
        {
            // 拼接参数:第一个参数是Player,后面是客户端传递的参数
            var methodParams = new object[] { player }.Concat(args).ToArray();
            mapping.TargetMethod.Invoke(mapping.ScriptInstance, methodParams);
        }
        catch (Exception ex)
        {
            Console.WriteLine($"执行事件{eventName}时出错: {ex.Message}");
        }
    }

    // 自定义权限校验逻辑,根据业务需求实现
    private static bool IsPlayerAuthorized(Player player)
    {
        // 示例:检查玩家是否携带管理员标记
        return player.HasData("IsAdmin") && (bool)player.GetData("IsAdmin");
    }
}

3. 启动时初始化处理器

在服务器启动脚本中调用初始化方法,确保所有事件被正确注册:

public class ServerStartup : RageScript
{
    public override void Start()
    {
        EventAuthorizationHandler.Initialize();
        Console.WriteLine("权限校验事件处理器已完成初始化");
    }
}

4. 权限标记使用示例

按照你期望的方式标记事件方法即可:

namespace SomeScripts2
{
    class AdminEvents : RageScript
    {
        [EventHandler("create_vehicle")]
        [Authorized] // 未授权玩家触发此事件会被拦截
        public void OnCreateVehicle(Player player, string nameVehicle)
        {
            // 车辆创建逻辑示例
            var vehicleHash = NAPI.Util.GetHashKey(nameVehicle);
            var vehicle = NAPI.Vehicle.CreateVehicle(vehicleHash, player.Position, player.Heading, 0, 0);
            NAPI.Chat.SendChatMessageToPlayer(player, $"~g~已成功创建车辆: {nameVehicle}");
        }
    }
}

注意事项

  • 脚本实例缓存:初始化时已缓存每个脚本的实例,避免每次调用方法时重复创建,符合Rage MP的脚本生命周期规则。
  • 权限扩展:可在AuthorizedAttribute中添加RequiredRole等参数,在IsPlayerAuthorized中实现更细粒度的角色校验。
  • 异常处理:可根据需求扩展日志记录逻辑,便于排查事件调用错误。

内容的提问来源于stack exchange,提问作者Locker

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.14 17:45:27