mcpField
R
roblox-remote-events

roblox-remote-events

github.com/sentinelcore开发29584 次安装35 周前更新
代码仓库

关于 roblox-remote-events

面向 Roblox 开发者的 Remote Events 与 Functions 技能,说明客户端和服务器之间的通信方式及部署位置,并强调服务端校验与安全防护。

主要功能

  1. 01对比 RemoteEvent、RemoteFunction 与 UnreliableRemoteEvent
  2. 02说明 Remote 的存放位置与创建顺序
  3. 03提供客户端和服务器的调用示例
  4. 04总结参数校验、限流与防重放方法

适用场景

  1. 01选择适合通知、请求返回或高频同步的 Remote 类型
  2. 02搭建客户端与服务器间的消息传递
  3. 03检查 Remote 处理逻辑中的安全风险

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/sentinelcore/roblox-skills --skill roblox-remote-events

安装后在 Claude Code 中输入/roblox-remote-events确认已加载。

详细介绍

Roblox 远程事件与函数

RemoteEvent 与 RemoteFunction

类型方向是否返回值?使用场景
RemoteEvent任意方向否(发送后不等待)通知服务器玩家执行了操作、广播状态
RemoteFunction客户端→服务器是(调用方会挂起)客户端需要获取返回结果(例如获取背包)
UnreliableRemoteEvent任意方向否高频更新且允许丢包的场景

默认使用 RemoteEvent。 避免使用服务器→客户端的 RemoteFunction——利用漏洞的玩家可以冻结回调,导致服务器线程无限期阻塞。


Remotes 的存放位置

始终将 Remotes 存放在 ReplicatedStorage 中。由服务器 Script 创建,并确保它在任何 LocalScript 运行之前执行。

ReplicatedStorage/
  Remotes/
    DealDamage        (RemoteEvent)
    GetInventory      (RemoteFunction)
    SyncPosition      (UnreliableRemoteEvent)
-- Script in ServerScriptService
local folder = Instance.new("Folder")
folder.Name = "Remotes"
folder.Parent = game:GetService("ReplicatedStorage")

local function make(class, name)
    local r = Instance.new(class)
    r.Name = name
    r.Parent = folder
    return r
end

make("RemoteEvent",           "DealDamage")
make("RemoteFunction",        "GetInventory")
make("UnreliableRemoteEvent", "SyncPosition")

触发模式

客户端 → 服务器(FireServer)
-- LocalScript
local DealDamage = game:GetService("ReplicatedStorage").Remotes:WaitForChild("DealDamage")
DealDamage:FireServer({ targetId = 12345, amount = 50 })
-- First arg on server is always the firing Player (injected automatically, cannot be spoofed)
-- Script (server) — VALIDATE everything in the payload
DealDamage.OnServerEvent:Connect(function(player, data)
    -- player identity is trustworthy; data contents are not
end)
服务器 → 单个客户端
local Notify = game:GetService("ReplicatedStorage").Remotes:WaitForChild("Notify")
Notify:FireClient(player, { message = "Welcome!" })
-- LocalScript
Notify.OnClientEvent:Connect(function(data)
    print(data.message)
end)
服务器 → 所有客户端
AnnounceEvent:FireAllClients({ text = "Game starting in 10 seconds!" })
RemoteFunction(客户端调用,服务器返回)
-- Script (server)
GetInventory.OnServerInvoke = function(player)
    return getPlayerInventory(player.UserId)
end
-- LocalScript
local inventory = GetInventory:InvokeServer()  -- yields until server returns
UnreliableRemoteEvent(高频同步)
-- LocalScript
RunService.Heartbeat:Connect(function()
    SyncPosition:FireServer(character.HumanoidRootPart.CFrame)
end)
-- Script (server) — still validate
SyncPosition.OnServerEvent:Connect(function(player, cframe)
    if typeof(cframe) ~= "CFrame" then return end
    -- apply with sanity bounds check
end)

关键:服务器端安全

客户端不可信。将每个参数都视为不可信输入。

local MAX_DAMAGE = 100
local COOLDOWNS = {}
local COOLDOWN_SECONDS = 0.5

DealDamage.OnServerEvent:Connect(function(player, data)
    -- 1. Rate limit
    local now = tick()
    if COOLDOWNS[player.UserId] and now - COOLDOWNS[player.UserId] < COOLDOWN_SECONDS then
        return
    end
    COOLDOWNS[player.UserId] = now

    -- 2. Type checks
    if type(data) ~= "table" then return end
    if type(data.targetId) ~= "number" then return end
    if type(data.amount) ~= "number" then return end

    -- 3. Range clamp
    local amount = math.clamp(data.amount, 0, MAX_DAMAGE)

    -- 4. Server-side weapon lookup — never trust client-provided Instance
    local weapon = getEquippedWeapon(player)
    if not weapon then return end

    -- 5. Server-side target lookup
    local target = getPlayerByUserId(data.targetId)
    if not target then return end

    applyDamage(target, amount, player)
end)

攻击模式与防御措施

攻击攻击者的操作防御措施
参数注入发送意外类型的数据,导致处理程序崩溃检查所有参数的类型
伤害放大发送 amount = math.huge将数值限制在合理上限内
Remote 滥用每秒触发数千次为每位玩家设置冷却时间
伪造目标发送另一位玩家的 UserId由服务器根据自身状态确定目标
无限等待OnClientEvent 回调始终不返回避免使用服务器→客户端的 RemoteFunction
重复操作重放有效请求,以便重复购买执行操作前检查状态/消耗令牌

快速参考

FireServer(args)            LocalScript → server
FireClient(player, args)    server → one client
FireAllClients(args)        server → every client
InvokeServer(args)          LocalScript → server, waits for return
OnServerEvent               server-side listener for FireServer
OnClientEvent               client-side listener for FireClient/FireAllClients
OnServerInvoke              server-side function assigned for InvokeServer

常见错误

错误修正方法
在 LocalScript 中使用 OnServerEvent客户端使用 OnClientEvent;OnServerEvent 仅供服务器使用
将 Remotes 放在 ServerStorage 中移至 ReplicatedStorage
除玩家身份外,信任载荷中的其他内容验证载荷中的每个字段
使用服务器→客户端的 RemoteFunction使用 RemoteEvent;冻结的客户端会阻塞服务器线程
在 LocalScript 中未使用 WaitForChildRemotes 可能尚不存在;始终使用 WaitForChild
多次赋值给 OnServerInvoke只有最后一次赋值生效;将其放在同一处
在紧密循环中触发且不做限流使用 UnreliableRemoteEvent 或累积时间增量

评论

支持 Markdown