• There is NO official Otland's Discord server and NO official Otland's server list. The Otland's Staff does not manage any Discord server or server list. Moderators or administrator of any Discord server or server lists have NO connection to the Otland's Staff. Do not get scammed!

Lua [TFS 1.1] setStorageValue doesn't allow strings, what should I use?

Solus

New Member
Joined
Jul 12, 2010
Messages
10
Reaction score
4
In previous versions of OT, setStorageValue (or more accurately setPlayerStorageValue) allowed you to use a string. Now in TFS 1.1, it appears that it only accepts an int32_t.

Is there an alternative to setStorageValue for strings? I want to store an array of numbers with some metadata split on ";"
 
Since storages are int(11) in the database, strings can't be set to it even manually. if you must, I suggest creating a custom field on the player table in the database and store the information to that as a string. You can create a lua function that uses a database query to retrieve, sort and return the information as a lua table.
 
Do you have any idea why they made this change? In 2009-2012 TFS was still using ScriptEnvironment::setStorage() and getStorage() calls, which supported a string as a parameter. This seems like a strange refactor choice.
 
I imagine it was resource heavy having different types, or some other excuse like that :p let me know if you need any help with the functionality if you plan to do it the way I mentioned above
 
I'm probably just going to add a second storage system for strings. I have at least a dozen scripts I want to port over that made heavy used of strings to utilize arrays and other data structures.
 
I believe storage string values was never implemented in TFS 0.2, which now is 1.x. 0.3/4 distros are discontinued and the main distro lineup skipped them altogether.
@Evil Hero probably have just what you are looking for, I believe he just saves those storages in a lua file.

This also solves the issue with global storages not being present on TFS 1.x
 
I believe global storages no longer store in the database and are only kept while the server is online. They're held in memory and cleared once the server shuts down.
 
Here is what you guys have asked for, this system allows to store numbers / strings / tables and booleans as a data type.
It is done for both global and player storages.
You have to create a folder called "storages" inside the "data" folder.
Create a file called "storages.lua" inside the "data" folder and insert the following in it:
Code:
globalStorages = {}
playerStorages = {}

function table.serialize(t, depth) -- credits Summ, I've just tweaked it some.
   local depth = depth or 0
   local ret, first = '\n' .. ('  '):rep(depth) .. '{\n', true
   for k, v in pairs(t) do
     if not first then
       ret = ret .. ',\n'
     end
     
     ret = ret .. ('  '):rep(depth + 1)
   
     if type(k) == 'number' then
       ret = ret .. '[' .. k .. '] = '
     elseif type(k) == 'string' and t[k] ~= nil then
       ret = ret .. '["' .. tostring(k):gsub('"', '\\"') .. '"] = '
     else
       error('Unhandled key type')
     end

     if type(v) == 'number' then
       ret = ret .. v
     elseif type(v) == 'string' then
       ret = ret .. '"'.. v ..'"'
     elseif type(v) == 'table' then
       ret = ret .. table.serialize(v, depth + 1)
     elseif type(v) == 'boolean' or type(v) == 'nil' then
       ret = ret .. (v == true and 'true' or v == false and 'false' or 'nil')
     else
       error('Unhandled value type')
     end
     first = false
   end
   ret = ret .. '\n' .. ('  '):rep(depth) .. '}'
 
   return ret
end

function saveGlobalStorages()
   local file = io.open("data/storages/global.lua", "w")
   file:write('globalStorages =' .. table.serialize(globalStorages))
   file:close()
end

function loadGlobalStorages()
   dofile("data/storages/global.lua")
end

function isGlobalStorageDataInUse(key)
   return getGlobalStorageData(key) and true or false
end

function getGlobalStorageData(key)
   if globalStorages[key] ~= nil then
     local value = globalStorages[key]
     if type(value) == "number" then
       return tonumber(value)
     elseif type(value) == "string" then
       return tostring(value)
     else
       return value
     end
   else
     return false
   end
end

function setGlobalStorageData(key, value, asType)
   if asType == "number" then
     globalStorages[key] = tonumber(value)
   elseif asType == "string" then
     globalStorages[key] = tostring(value)
   elseif type(value) == "table" or type(value) == "boolean" then
     globalStorages[key] = value
   else
     print("cannot set a non table value without a definition")
   end
end

function savePlayerStorages()
   local file = io.open("data/storages/players.lua", "w")
   file:write('playerStorages =' .. table.serialize(playerStorages))
   file:close()
end

function loadPlayerStorages()
   dofile("data/storages/players.lua")
end

function isPlayerStorageDataInUse(player, key)
   if type(player) == "userdata" then
     player = player:getName()
   end
   return getPlayerStorageData(player, key) and true or false
end

function getPlayerStorageData(player, key)
   if type(player) == "userdata" then
     player = player:getName()
   end
   if playerStorages[player][key] ~= nil then
     local value = playerStorages[player][key]
     if type(value) == "number" then
       return tonumber(value)
     elseif type(value) == "string" then
       return tostring(value)
     else
       return value
     end
   else
     return false
   end
end

function setPlayerStorageData(player --[[this can be either userdata or playername]], key, value, asType)
   if type(player) == "userdata" then
     player = player:getName()
   end
   if playerStorages[player] == nil then
     playerStorages[player] = {}
   end
   if asType == "number" then
     playerStorages[player][key] = tonumber(value)
   elseif asType == "string" then
     playerStorages[player][key] = tostring(value)
   elseif type(value) == "table" or type(value) == "boolean" then
     playerStorages[player][key] = value
   else
     print("cannot set a non table value without a definition")
   end
end

globalevents/startup.lua:
before the last end.
Code:
loadGlobalStorages()
loadPlayerStorages()

globalevents/shutdown.lua:
before the last end.
Code:
saveGlobalStorages()
savePlayerStorages()

data/global.lua:
at top.
Code:
dofile('data/storages.lua')

You could also save the storages on server save instead of onShutdown() but that's completly up to you guys.
 
Back
Top