Often, you want to not disclose information to the client. If you send the location of a secret to the client, a hacker can detect the location easily. So, you might want to send “all the information about an area” to the client, but not some fields. It can be awkward - do you keep two separate ‘area’ dictionaries - like area_server and area_client? Instead, I thought of labelling all properties with “s_” if they are server-only.
areaData = { -- Any fields starting with "s_" should not go to client.
title = "Cemetary",
s_key = {3,7} --client shouldn't know this location
}
-- remote function, called by client when it needs something from server. It passes name of query as pParams.q.
rf.OnServerInvoke = function(plr,pParams)
if pParams.q=="getAreaData" then
return areaData -- send the client all the information about the area (but will also include secret fields, that we don't want client to know yet).
end
So, I’ve labelled server-only fields with “s_” in the areaData dictionary. To filter them out before sending to client:
function retClientSafeDict(pDict)
if pDict==nil then return nil; end;
local lClientDict = deepCopy(pDict) -- a func to copy the dict. Next: REMOVE any properties that start with s_. (Don't want to do this on live dict, so we made a copy first)
local function recurse(pClientDict)
for propName,propVal in pairs(pClientDict) do
if typeof(propName)~="number" and propName:sub(1,2)=="s_" then -- Do not send to client. (if it was a number, it's a List member and doesn't have a 'name' to check just [1][2][3]etc)
pClientDict[propName] = nil
elseif type(propVal)=="table" then -- need to recurse and check each child
recurse(propVal)
end
end
end
recurse(lClientDict)
return lClientDict
end
Now, in my script that sends areaData to the client, it does this:
rf.OnServerInvoke = function(plr,pParams) -- remote function, called by client when it needs something from server
if pParams.q=="getAreaData" then
return retClientSafeDict(areaData) -- send the client area info (but WITHOUT the server-only data)
end
I no longer have to worry about ways of managing information about ‘areaData’ in a safe way. I just label properties in the dict with s_ and voila, they don’t routinely get sent to the client. It’s immediately been so useful, and means I can keep information more simple in code.