mirror of
https://github.com/littensy/charm.git
synced 2026-10-21 03:36:11 +00:00
refactor: simplify charm sync validation
This commit is contained in:
parent
7bb6edb403
commit
dffeb35933
7 changed files with 48 additions and 74 deletions
|
|
@ -1,66 +1,50 @@
|
|||
local SAFE_KEYS = { string = true, number = true }
|
||||
local UNSAFE_VALUES = { ["function"] = true, thread = true }
|
||||
|
||||
local function isTableUnsafe(object: { [any]: any })
|
||||
local key = next(object)
|
||||
|
||||
if key == nil then
|
||||
-- An empty table is always safe
|
||||
return false
|
||||
end
|
||||
|
||||
local keyType = type(key)
|
||||
local keyCount = 0
|
||||
local maxKey = 0
|
||||
|
||||
-- Keys must either be all strings or all numbers
|
||||
-- Keys must all be the same type
|
||||
for key in object do
|
||||
if type(key) ~= keyType then
|
||||
return true
|
||||
elseif keyType == "number" and key > maxKey then
|
||||
maxKey = key
|
||||
end
|
||||
keyCount += 1
|
||||
end
|
||||
|
||||
-- Array keys must be sequential
|
||||
if keyType == "number" and keyCount > #object then
|
||||
if keyType == "number" and maxKey > #object then
|
||||
return true
|
||||
end
|
||||
|
||||
return false
|
||||
end
|
||||
|
||||
--- Validates a value to ensure it can be synced over a remote event.
|
||||
--- Throws an error if the value is a table that cannot be synced via
|
||||
--- RemoteEvents or RemoteFunctions. This only aims to catch common mistakes
|
||||
--- with remote argument limitations, such as sparse arrays or mixed tables.
|
||||
---
|
||||
--- @param value The value to validate.
|
||||
--- @param key The key of the value in the table.
|
||||
--- @param value The table value.
|
||||
--- @param key The key of the value.
|
||||
--- @error Throws an error if the value cannot be synced.
|
||||
local function validate(value: any, key: any)
|
||||
local typeKey = type(key)
|
||||
local typeValue = type(value)
|
||||
|
||||
if not SAFE_KEYS[typeKey] then
|
||||
error(`Invalid key type '{typeKey}' at key '{key}'`)
|
||||
elseif UNSAFE_VALUES[typeValue] then
|
||||
error(`Invalid value type '{typeValue}' at key '{key}'`)
|
||||
elseif typeValue == "table" then
|
||||
if getmetatable(value) ~= nil then
|
||||
error(`Cannot sync tables with metatables! Got {value} at key '{key}'`)
|
||||
elseif isTableUnsafe(value) then
|
||||
error(
|
||||
`Cannot sync tables unsupported by remote events! The table was found at the key '{key}'.\n\n`
|
||||
.. "This can be for the following reasons:\n"
|
||||
.. "1. The object is an array with non-sequential keys\n"
|
||||
.. "2. The object is a dictionary with mixed key types (e.g. string and number)\n\n"
|
||||
.. "Read more: https://create.roblox.com/docs/scripting/events/remote#argument-limitations"
|
||||
)
|
||||
end
|
||||
end
|
||||
|
||||
if typeKey == "number" then
|
||||
if key == math.huge or key == -math.huge then
|
||||
error("Cannot sync infinity as key")
|
||||
elseif key ~= math.floor(key) then
|
||||
error("Cannot sync non-integer number as key")
|
||||
local function validate(value: { [any]: any })
|
||||
if isTableUnsafe(value) then
|
||||
-- Silence warnings during testing
|
||||
if game then
|
||||
warn("Cannot sync table:", value)
|
||||
end
|
||||
error(
|
||||
`Cannot sync tables unsupported by remote events! See the warning above for more info.\n\n`
|
||||
.. "This can be for the following reasons:\n"
|
||||
.. "1. The table is a sparse array with non-sequential indices\n"
|
||||
.. "2. The table is a mixed table (not all keys have the same type)\n\n"
|
||||
.. "Read more: https://create.roblox.com/docs/scripting/events/remote#argument-limitations"
|
||||
)
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue