I implemented a slightly different solution for my
plugin.
Basically, before I call Turbine.PluginData.Save(), I serialize my settings table (and subtables) into a string. The string is simply a snippet of Lua code that, when executed, returns my settings table. Then I save that single string with Turbine.PluginData.Save().
After I get the string back from Turbine.PluginData.Load(), I use the built-in loadstring() function to parse it back into a table.
Vindar's fix didn't work for me, because my settings table contains tables that look like this:
Code:
t = { "a", "b", "c" }
and Vindar's loader was returning them like this:
Code:
t = {
["1"] = "a",
["2"] = "b",
["3"] = "c"
}
Unfortunately, there is a difference.
I hacked Vindar's code for a while, but I couldn't get it to work. So I implemented my alternative. Here's the source code:
Code:
function SaveSettings(settings)
-- Serialize (workaround for Turbine localization bug)
local saveStr = "return " .. Serialize(settings);
Turbine.PluginData.Save(Turbine.DataScope.Character, "Stuff", saveStr, function()
-- Finished saving
end);
end
function LoadSettings()
Turbine.PluginData.Load(Turbine.DataScope.Character, "Stuff", function(saveStr)
if (saveStr) then
-- Unserialize (workaround for Turbine localization bug)
settings = assert(loadstring(saveStr))();
if (not settings) then
Turbine.Shell.WriteLine("Failed to parse Stuff.plugindata!");
end
end
end);
end
function Serialize(obj)
if (type(obj) == "nil") then
return "nil";
elseif (type(obj) == "boolean") then
if (obj) then
return "true";
else
return "false";
end
elseif (type(obj) == "number") then
local text = tostring(obj);
-- Change floating-point numbers to English format
return string.gsub(text, ",", ".");
elseif (type(obj) == "string") then
return string.format("%q", obj);
elseif (type(obj) == "table") then
local text = "{";
for i, v in pairs(obj) do
local index = Serialize(i);
local value = Serialize(v);
if (value ~= nil) then
local item = "[" .. index .. "]=" .. value .. ",";
text = text .. item;
end
end
text = string.gsub(text, ",$", "");
text = text .. "}";
return text;
else
return nil;
end
end
You may notice the only escaping I'm doing for strings is replacing " with \" and \ with \\. I'm not sure if there's anything else I need to do, such as for strange foreign characters. Can anyone advise me?