party_redo/party_api/PartyManager.lua

174 lines
5.7 KiB
Lua

-- TODO: remove once the next luacheck release is out
local core = minetest
-- Very simple PartyManager which can only do the basics
-- handles storing/accessing the data
-- mostly used as a superclass
-- storage_ref keys:
-- - "player_" .. playername = partyname
-- - "party_" .. partyname = all data except the members
-- - "members_" .. partyname = {membername = "metadata"}: members of a party. matadata is another serialized string
-- TODO: debug speed
local serialize = core.serialize
local deserialize = core.deserialize
-- local serialize = core.serialize
-- local deserialize = core.deserialize
local PartyManager = {}
local metatable = {
__index = PartyManager
}
PartyManager.listPartys = function (self)
local json_partys = self.storage_ref:get_string("partylist")
return deserialize(json_partys)
end
PartyManager.getPlayersParty = function (self, playername)
-- prefix needed to prevent malicious playernames from overriding other modstorage data
return self.storage_ref:get_string("player_" .. playername)
end
PartyManager.getParty = function (self, partyname)
local json_data = self.storage_ref:get_string("party_" .. partyname)
local json_members = self.storage_ref:get_string("members_" .. partyname)
if json_data == "" then return false, "Party does not exist" end
if json_members == "" then return false, "corrupted database" end -- TODO: error out!
local data = deserialize(json_data)
local members = deserialize(json_members)
return self.party_class.load(partyname, data, members)
end
PartyManager.setParty = function (self, party)
local partyname = party:getName()
local data = party:getData()
local members = party:getMembers()
local json_data = serialize(data)
local json_members = serialize(members)
self.storage_ref:set_string("party_" .. partyname, json_data)
self.storage_ref:set_string("members_" .. partyname, json_members)
end
PartyManager.createParty = function (self, partyname, ...)
-- getParty might be unreliable in case of a broken db
if self.storage_ref:get_string("party_" .. partyname) ~= "" then
return false, "such a party already exists"
end
local party, error = self.party_class.create(partyname, ...)
if not party then return false, error end
self:setParty(party)
local json_partys = self.storage_ref:get_string("partylist")
local party_list = deserialize(json_partys)
table.insert(party_list, partyname)
json_partys = serialize(party_list)
self.storage_ref:set_string("partylist", json_partys)
return "OK"
end
PartyManager.deleteParty = function (self, partyname)
local party, error = self:getParty(partyname)
if not party then return false, error end
local sucess, error = party:delete()
if not sucess then return false, error end
local members = party:getMembers()
for member, _ in pairs(members) do
self.storage_ref:set_string("player_" .. member, "")
end
self.storage_ref:set_string("party_" .. partyname, "")
self.storage_ref:set_string("members_" .. partyname, "")
local json_partys = self.storage_ref:get_string("partylist")
local party_list = deserialize(json_partys)
local index = table.indexof(party_list, partyname)
table.remove(party_list, index)
json_partys = serialize(party_list)
self.storage_ref:set_string("partylist", json_partys)
return "OK"
end
PartyManager.renameParty = function (self, oldname, newname)
-- getParty might be unreliable in case of a broken db
if self.storage_ref:get_string("party_" .. newname) ~= "" then
return false, "such a party already exists"
end
local party, error = self:getParty(oldname)
if not party then return false, error end
local sucess, error = party:rename(newname)
if not sucess then return false, error end
for member, _ in pairs(party:getMembers()) do
self.storage_ref:set_string("player_" .. member, newname)
end
self:setParty(party)
local json_partys = self.storage_ref:get_string("partylist")
local party_list = deserialize(json_partys)
local index = table.indexof(party_list, oldname)
party_list[index] = newname
json_partys = serialize(party_list)
self.storage_ref:set_string("partylist", json_partys)
self.storage_ref:set_string("party_" .. oldname, "")
self.storage_ref:set_string("members_" .. oldname, "")
return "OK"
end
PartyManager.join = function (self, playername, partyname)
if self:getPlayersParty(playername) ~= "" then
return false, playername .. " is already in a party"
end
local party, error = self:getParty(partyname)
if not party then return false, error end
local sucess, error = party:join(playername)
if not sucess then return false, error end
self:setParty(party)
self.storage_ref:set_string("player_" .. playername, partyname)
return "OK"
end
PartyManager.leave = function (self, playername)
local partyname = self:getPlayersParty(playername)
local party, error = self:getParty(partyname)
if not party then return false, error end
local sucess, error = party:leave(playername)
if not sucess then return false, error end
self:setParty(party)
self.storage_ref:set_string("player_" .. playername, "")
return "OK"
end
-- -----------------------------------------------------------------------------------------------------------------
local call = function (_, kwargs)
if kwargs.storage_ref:get_string("partylist") == "" then
kwargs.storage_ref:set_string("partylist", serialize({}))
end
return setmetatable({
storage_ref = kwargs.storage_ref,
party_class = kwargs.party_class,
}, metatable)
end
return setmetatable({}, {
__call = call,
__index = PartyManager,
})