local part1 = Instance.new("Part")
local part2 = part1:Clone()
local part3 = part1:Clone()
local parts = {}
local function createProperty(part, colorType, state)
parts[part] = {
colorType = colorType,
state = state
-- and other
}
end
createProperty(part1, "red", 1)
createProperty(part2, "blue", 2)
createProperty(part3, "green", 3)
for part, props in pairs(parts) do -- error - Cannot convert mixed or non-array tables: keys must be strings
end
I have read that I canāt save server properties for parts in partās values because some client can change it.
Maybe, Can I get some unique ID of part?
I send event from client with part
Local script
event:FireServer(part)
Server script
event.OnServerEvent:Connect(function(player, part)
-- I can get property about the part
local prop = parts[part]
-- but I think it wrong way, because I get an error in 'for' loop
end)
How can I recognize the part and get properties from table about the part?
First off, Iām on mobile and itās 2 AM, so I might not be as clear or as accurate as I usually am, but I will take a go at it.
The first problem I see with your scripts is that youāre inserting a table into another table without a key. Everything needs a key in order to retrieve that table. In order to fix this, you will need to create a key and then store the table inside of it. This is how you would do so.
local function createProperty(part, colorType, state)
table.insert(parts, (part.Name)) --You can change this to something more precise, but has to be a string or number.
parts[part.Name] = {
["colorType"] = colorType; --Adding string keys
["state"] = state; --Adding string keys
}
end
Another thing I saw was how you stored you values in the table. You must use a key to store these values. I already went ahead and created the keys, but keep in mind that you have to use these ā[ā brackets to start and enclose a STRING key.
Run a for loop through the table and check the matching property whether they match with the input. Since itās a dictionary in a dictionary, you can check by the key of each part inside.
Furthermore, why is there OnClientEvent on server? It should be OnServerEvent if the client fired RemoteEvent:FireServer().
Furthermore, why is there OnClientEvent on server? It should be OnServerEvent if the client fired RemoteEvent:FireServer() .
Sorry, It was just copy paste
Run a for loop through the table and check the matching property whether they match with the input. Since itās a dictionary in a dictionary, you can check by the key of each part inside.
Also, keys in a dictionary donāt need to be in brackets.
mytable = { hello = 4, goodbye = 3}
However, I would put the keys inside brackets. They may otherwise be messed up by your function arguments of part, colorType, and state.
Now itās time for
-- error - Cannot convert mixed or non-array tables: keys must be strings
Are you sending the parts table to the client/server using a remove event? If so, all the keys of your table must be strings, or if using numbered keys, there cannot be any āgapsā in the table. You may also have issues if the keys are parts. Iāve never tried that.
okay: {2, 4, 5, 9}
okay: {hello = 5, bob = 3}
not okay: {2, 4, 5, nil, 9}
not okay: {2, 4, 5, bob = 4}
Are you sending the parts table to the client/server using a remove event? If so, all the keys of your table must be strings, or if using numbered keys, there cannot be any āgapsā in the table. You may also have issues if the keys are parts. Iāve never tried that.
Ok
Server script
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local event = ReplicatedStorage.RemoteEvent
local HttpService = game:GetService("HttpService")
local props = {}
local function createPart()
local part = Instance.new("Part")
local id = Instance.new("StringValue", part)
id.Name = "ID"
id.Value = HttpService:GenerateGUID(false)
return part
end
local function createProperty(partID, colorType, state)
props[partID] = {
["colorType"] = colorType;
["state"] = state;
-- etc
}
end
local part = createPart()
createProperty(part.ID.Value, "red", 1)
part = createPart()
createProperty(part.ID.Value, "blue", 2)
part = createPart()
createProperty(part.ID.Value, "green", 3)
event.OnServerEvent:Connect(function(player, part)
local prop = props[part.ID.Value]
end)
Client local script
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local event = ReplicatedStorage:WaitForChild("RemoteEvent")
...
event:FireServer(part.ID.Value)
I have string unique keys and I am happy
But I read that the client can change part.ID.Value by exploit
or Am I mistaken?
local event = game.ReplicatedStorage.TestEvent
local part = Instance.new("Part")
local id = Instance.new("StringValue", part)
id.Name = "ID"
id.Value = "Test"
part.Parent = workspace
print(part.Name) -- Part
print(part.ID.Value) -- Test
event.OnServerEvent:Connect(function(player)
print(part.Name) -- Part
print(part.ID.Value) -- Test
end)
Client local script (tool)
local tool = script.Parent
local event = game.ReplicatedStorage.TestEvent;
tool.Equipped:Connect(function()
local p = workspace.Part
print(p.Name) -- Part
print(p.ID.Value) -- Test
p.Name = "NewName"
p.ID.Value = "NewValue"
print(p.Name) -- NewName
print(p.ID.Value) -- NewValue
event:FireServer()
end)