From c30c3336c633da1f44d7144e282782fa4b38de09 Mon Sep 17 00:00:00 2001 From: Kazhnuz Date: Sat, 8 May 2021 12:54:07 +0200 Subject: [PATCH] feat: rework serialization Fixes #102 --- .../birb/classes/serializable/init.lua | 139 +++++++++++++++++ .../birb/classes/serializable/serializer.lua | 73 +++++++++ sonic-radiance.love/birb/core/options.lua | 51 ++----- .../game/abstractmobs/character/datas.lua | 30 ---- .../game/abstractmobs/character/init.lua | 6 +- .../game/abstractmobs/parent.lua | 6 +- sonic-radiance.love/game/characters.lua | 10 +- sonic-radiance.love/game/difficulty.lua | 12 +- sonic-radiance.love/game/init.lua | 142 ++++-------------- sonic-radiance.love/game/loot/init.lua | 22 +-- sonic-radiance.love/game/loot/pocket.lua | 12 +- sonic-radiance.love/game/metadata.lua | 83 ++++++++++ 12 files changed, 359 insertions(+), 227 deletions(-) create mode 100644 sonic-radiance.love/birb/classes/serializable/init.lua create mode 100644 sonic-radiance.love/birb/classes/serializable/serializer.lua create mode 100644 sonic-radiance.love/game/metadata.lua diff --git a/sonic-radiance.love/birb/classes/serializable/init.lua b/sonic-radiance.love/birb/classes/serializable/init.lua new file mode 100644 index 0000000..29c5306 --- /dev/null +++ b/sonic-radiance.love/birb/classes/serializable/init.lua @@ -0,0 +1,139 @@ +-- classes/serializable :: a serializable object, can give its field as data + +--[[ + Copyright © 2021 Kazhnuz + + Permission is hereby granted, free of charge, to any person obtaining a copy of + this software and associated documentation files (the "Software"), to deal in + the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: + + The above copyright notice and this permission notice shall be included in all + copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +]] + +local Serializable = Object:extend() + +function Serializable:new(serializeFields, listSerializable) + self.serializeFields = serializeFields + self.listSerializable = listSerializable +end + +function Serializable:getData() + local data = {} + -- We serialize all fields + if (self.serializeFields ~= nil) then + for _, key in ipairs(self.serializeFields) do + data[key] = self:wrapField(key) + end + end + -- We serialize all list of serializable + if (self.listSerializable ~= nil) then + for _, key in ipairs(self.listSerializable) do + data[key] = self:wrapList(key) + end + end + return data +end + +function Serializable:wrapField(key) + local serializedField = self[key] + if (serializedField ~= nil) then + if (type(serializedField) == "table" and serializedField.is ~= nil) then + if (serializedField:is(Serializable)) then + serializedField = serializedField:getData() + serializedField.isSerializable = true + end + end + self:print(key, serializedField, false) + return serializedField + end +end + +function Serializable:wrapList(key) + local serializedList = {} + serializedList.isListSerializable = true + for listKey, listElement in pairs(self[key]) do + serializedList[listKey] = listElement:getData() + end + self:print(key, serializedList, false) + return serializedList +end + +function Serializable:setData(data) + for key, value in pairs(data) do + if (key ~= "serializedField") then + self:unwrapField(key, value) + end + end + self:finishDeserialization() +end + +function Serializable:unwrapField(key, value) + local serializedField = value + if (serializedField ~= nil) then + if (type(serializedField) == "table") then + if (serializedField.isSerializable == true) then + self[key]:setData(serializedField) + elseif (serializedField.isListSerializable) then + self:unwrapList(key, serializedField) + else + self[key] = serializedField or self[key] + end + else + self[key] = serializedField or self[key] + self:print(key, serializedField, true) + end + end +end + +function Serializable:unwrapList(key, list) + if (list == nil) then + error("List " .. key .. " shouldn't be null in the save") + end + for listKey, listElement in pairs(list) do + if (listKey ~= "isListSerializable") then + self[key][listKey]:setData(listElement) + end + end + self:print(key, list, true) +end + +function Serializable:print(key, value, isLoading) + local loadString = "Loading " + if (isLoading == false) then + loadString = "Saving " + end + local valueString = value + if type(valueString) == "boolean" then + if valueString then + valueString = "true" + else + valueString = "false" + end + end + if (type(value) == "table") then + valueString = utils.table.toString(value) + end + loadString = loadString .. key .. " " .. ": " .. valueString + if (core ~= nil) then + core.debug:debug("serializable", loadString) + else + print("serializable", loadString) + end +end + +function Serializable:finishDeserialization() + -- Empty function callback +end + +return Serializable \ No newline at end of file diff --git a/sonic-radiance.love/birb/classes/serializable/serializer.lua b/sonic-radiance.love/birb/classes/serializable/serializer.lua new file mode 100644 index 0000000..24636b3 --- /dev/null +++ b/sonic-radiance.love/birb/classes/serializable/serializer.lua @@ -0,0 +1,73 @@ +-- classes/serializable/serializer :: a serializer, able to put stuff into a bin file + +--[[ + Copyright © 2021 Kazhnuz + + Permission is hereby granted, free of charge, to any person obtaining a copy of + this software and associated documentation files (the "Software"), to deal in + the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: + + The above copyright notice and this permission notice shall be included in all + copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +]] +local Serializable = require "birb.classes.serializable" +local Serializer = Serializable:extend() +local binser = require("birb.libs.binser") + +function Serializer:new(serializeFields, listSerializable) + Serializer.super.new(self, serializeFields, listSerializable) +end + +function Serializer:reset() + +end + +function Serializer:delete(filename) + local filepath = self:getFile(true, filename) + if utils.filesystem.exists(filename) then + love.filesystem.remove(filepath) + end +end + +function Serializer:deserialize(filename) + local filepath = self:getFile(true, filename) + if utils.filesystem.exists(filename) then + local loadedDatas = binser.readFile(filepath) + self:setData(loadedDatas[1]) + else + self:reset() + end +end + +function Serializer:serialize(filename) + local data = self:getData() + + local filepath = self:getFile(true, filename) + binser.writeFile(filepath, data) +end + +function Serializer:getFile(absolute, filename) + local dir = "" + if absolute then + dir = love.filesystem.getSaveDirectory() .. "/" + if (not utils.filesystem.exists(dir)) then + love.filesystem.createDirectory("") + end + end + + local filepath = dir .. filename + + return filepath +end + +return Serializer diff --git a/sonic-radiance.love/birb/core/options.lua b/sonic-radiance.love/birb/core/options.lua index 50f193b..5f6baf2 100644 --- a/sonic-radiance.love/birb/core/options.lua +++ b/sonic-radiance.love/birb/core/options.lua @@ -21,26 +21,30 @@ IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ]] - -local OptionsManager = Object:extend() - -local binser = require("birb.libs.binser") +local Serializer = require "birb.classes.serializable.serializer" +local OptionsManager = Serializer:extend() local TRANSLATION_PATH = "datas/languages/" +local OPTION_FILE = "options.data" + -- INIT FUNCTIONS -- Initialize and configure the game options function OptionsManager:new(controller) + OptionsManager.super.new(self, {"data"}) + self.controller = controller -- We begin by creating an empty data table before reading the data. - self.data = {} + self:reset() self:read() end function OptionsManager:reset() local conf = self.controller:getDefaultConf() -- Reset the option to the game defaults. + self.data = {} + self.data.video = {} self.data.video.crtfilter = (conf.window.crtfilter == true) self.data.video.resolution = conf.window.resolution or 1 @@ -62,20 +66,6 @@ end -- INFO FUNCTIONS -- Get informations from the option managers -function OptionsManager:getFile(absolute) - local dir = "" - if absolute then - dir = love.filesystem.getSaveDirectory() .. "/" - if not utils.filesystem.exists(dir) then - love.filesystem.createDirectory( "" ) - end - end - - local filepath = dir .. "options.data" - - return filepath -end - function OptionsManager:getInputDefaultData() local _path = "datas/inputs.lua" local datas = {} @@ -142,30 +132,11 @@ end -- FIXME: maybe subclass a special module for that ? function OptionsManager:write() - local data = self:getData() - - local filepath = self:getFile(true) - binser.writeFile(filepath, data) + self:serialize(OPTION_FILE) end function OptionsManager:read() - local filepath = self:getFile(true) - if utils.filesystem.exists("options.data") then - local loadedDatas = binser.readFile(filepath) - self.controller.debug:print("core/options", "data file found, loading it") - self:setData(loadedDatas[1]) - else - self:reset() - self.controller.debug:print("core/options", "no data file found, reseting data") - end -end - -function OptionsManager:getData(data) - return self.data -end - -function OptionsManager:setData(data) - self.data = data + self:deserialize(OPTION_FILE) end return OptionsManager diff --git a/sonic-radiance.love/game/abstractmobs/character/datas.lua b/sonic-radiance.love/game/abstractmobs/character/datas.lua index 5a8612e..009b5e9 100644 --- a/sonic-radiance.love/game/abstractmobs/character/datas.lua +++ b/sonic-radiance.love/game/abstractmobs/character/datas.lua @@ -8,34 +8,4 @@ function CharacterData:getCommonData() self.turns = self.data.turns end -function CharacterData:getData() - local data = {} - data.simplename = self.simplename - data.level = self.level - data.exp = self.exp - data.exp_next = self.exp_next - data.hp = self.hp - data.pp = self.pp - data.statuts = self.statuts - data.equip = self.equip - - return data -end - -function CharacterData:setData(data) - self.simplename = data.simplename - self:getCommonData() - - self.level = data.level - self.exp = data.exp - self.exp_next = data.exp_next - - self.hp = data.hp - self.pp = data.pp - self.statuts = data.statuts - - self.equip = data.equip - self:createStats() -end - return CharacterData diff --git a/sonic-radiance.love/game/abstractmobs/character/init.lua b/sonic-radiance.love/game/abstractmobs/character/init.lua index 47a18d2..468a3ee 100644 --- a/sonic-radiance.love/game/abstractmobs/character/init.lua +++ b/sonic-radiance.love/game/abstractmobs/character/init.lua @@ -12,7 +12,7 @@ AbstractCharacter:implement(CharacterEquip) function AbstractCharacter:new(name) self.simplename = name - self.super.new(self) + self.super.new(self, {"simplename", "level", "exp", "exp_next", "hp", "pp", "statuts", "equip"}) end function AbstractCharacter:initBasicElements() @@ -72,4 +72,8 @@ function AbstractCharacter:createSkills() return learnedlist end +function AbstractCharacter:finishDeserialization() + self:createStats() +end + return AbstractCharacter diff --git a/sonic-radiance.love/game/abstractmobs/parent.lua b/sonic-radiance.love/game/abstractmobs/parent.lua index e641128..999c892 100644 --- a/sonic-radiance.love/game/abstractmobs/parent.lua +++ b/sonic-radiance.love/game/abstractmobs/parent.lua @@ -1,11 +1,13 @@ -local AbstractMobParent = Object:extend() +local Serializable = require "birb.classes.serializable" +local AbstractMobParent = Serializable:extend() -function AbstractMobParent:new() +function AbstractMobParent:new(serializeFields, listSerializable) self:initBasicElements() self.stats = self:createStats() self.skills = self:createSkills() self.statuts = {} self:initLife() + AbstractMobParent.super.new(self, serializeFields, listSerializable) end function AbstractMobParent:initBasicElements() diff --git a/sonic-radiance.love/game/characters.lua b/sonic-radiance.love/game/characters.lua index cf79822..4cec041 100644 --- a/sonic-radiance.love/game/characters.lua +++ b/sonic-radiance.love/game/characters.lua @@ -22,7 +22,8 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ]] -local CharacterManager = Object:extend() +local Serializable = require "birb.classes.serializable" +local CharacterManager = Serializable:extend() local charutils = require "game.utils.characters" local AbstractCharacter = require "game.abstractmobs.character" @@ -35,6 +36,7 @@ function CharacterManager:new(controller) self.team = startdata.baseteam self.active = 1 self:init() + CharacterManager.super.new(self, {"team"}, {"list"}, {list = AbstractCharacter}) end function CharacterManager:init() @@ -80,11 +82,9 @@ end function CharacterManager:setData(data) local data = data self.team = data.team - self.list = {} for name, charData in pairs(data.list) do - local character = AbstractCharacter(name) - character:setData(charData) - self.list[name] = character + print(self.list[name]) + self.list[name]:setData(charData) end end diff --git a/sonic-radiance.love/game/difficulty.lua b/sonic-radiance.love/game/difficulty.lua index 7d64639..f98b386 100644 --- a/sonic-radiance.love/game/difficulty.lua +++ b/sonic-radiance.love/game/difficulty.lua @@ -1,4 +1,5 @@ -local Difficulty = Object:extend() +local Serializable = require "birb.classes.serializable" +local Difficulty = Serializable:extend() function Difficulty:new() self.toggles = {} @@ -8,6 +9,7 @@ function Difficulty:new() self.toggles.checkPointRegen = false self.toggles.levelUpHeal = false self.toggles.allDamage = true + Difficulty.super.new(self, {"toggles"}) end function Difficulty:toggle(toggleName) @@ -18,12 +20,4 @@ function Difficulty:get(toggleName) return self.toggles[toggleName] end -function Difficulty:getData() - return self.toggles -end - -function Difficulty:setData(toggles) - self.toggles = toggles -end - return Difficulty \ No newline at end of file diff --git a/sonic-radiance.love/game/init.lua b/sonic-radiance.love/game/init.lua index 8a58df5..3c62c6a 100644 --- a/sonic-radiance.love/game/init.lua +++ b/sonic-radiance.love/game/init.lua @@ -23,13 +23,16 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ]] -local Game = Object:extend() +local Serializer = require "birb.classes.serializable.serializer" + +local Game = Serializer:extend() local Characters = require "game.characters" local Ennemies = require "game.ennemies" local Skills = require "game.skills" local Loot = require "game.loot" local CBSCore = require "game.battle" local Difficulty = require "game.difficulty" +local Metadata = require "game.metadata" local binser = require "birb.libs.binser" @@ -38,11 +41,25 @@ local startdata = require "datas.gamedata.startdata" Game.utils = require "game.modules.utils" Game.gui = require "game.modules.gui" +local VAR_TO_SERIALIZE = { + "gametime", + "destroyedGizmo", + "variables", + "flags", + "position", + "actions", + "characters", + "loot", + "difficulty" +} + function Game:new() self.slot = -1 self.slotNumber = 3 self.version = core.conf.gameversion or "N/A" - self:resetData() + self:reset() + self.metadata = Metadata(self) + Game.super.new(self, VAR_TO_SERIALIZE) end function Game:initPosition() @@ -52,34 +69,6 @@ function Game:initPosition() self.position.area = startdata.position.area end -function Game:setData(data) - local data = data - self.gametime = data.gametime - self.destroyedGizmo = data.destroyedGizmo - self.variables = data.variables - self.flags = data.flags - self.position = data.position - self.actions = data.actions - self.characters:setData(data.characters) - self.loot:setData(data.loot) - self.difficulty:setData(data.difficulty) -end - -function Game:getData() - local data = {} - data.gametime = self.gametime - data.characters = self.characters:getData() - data.loot = self.loot:getData() - data.difficulty = self.difficulty:getData() - data.flags = self.flags - data.destroyedGizmo = self.destroyedGizmo - data.variables = self.variables - data.position = self.position - data.actions = self.actions - - return data -end - function Game:getMetadataFile(absolute) local dir = "" if absolute then @@ -95,50 +84,10 @@ function Game:getMetadataFile(absolute) end function Game:getMetadata() - local metadata = {} - local filepath = self:getMetadataFile(true) - if utils.filesystem.exists("metadata.save") then - metadata = binser.readFile(filepath)[1] - else - metadata = self:newMetadata() - end - return metadata + return self.metadata:get() end -function Game:newMetadata() - local metadata = {} - for i = 1, self.slotNumber, 1 do - local newMetadata = {} - newMetadata.exist = false - newMetadata.completion = 0 - newMetadata.gametime = 0 - newMetadata.team = {} - newMetadata.rings = 0 - newMetadata.emeralds = 0 - newMetadata.location = "" - table.insert(metadata, newMetadata) - end - return metadata -end - -function Game:writeMetadata(metadata) - local filepath = self:getMetadataFile(true) - binser.writeFile(filepath, metadata) -end - -function Game:addtoMetadata() - local metadata = self:getMetadata() - metadata[self.slot].exist = true - metadata[self.slot].completion = self.completion - metadata[self.slot].gametime = self.gametime - metadata[self.slot].team = self.characters.team - metadata[self.slot].rings = self.loot.rings - metadata[self.slot].emeralds = 0 - metadata[self.slot].location = self.mapName - self:writeMetadata(metadata) -end - -function Game:resetData() +function Game:reset() self.gametime = 0 self.characters = Characters(self) @@ -158,12 +107,6 @@ function Game:resetData() self.actions = startdata.actions end -function Game:removeFromMetadata() - local metadata = self:getMetadata() - metadata[self.slot].exist = false - self:writeMetadata(metadata) -end - function Game:reload() self:read(self.slot) end @@ -171,57 +114,32 @@ end function Game:read(save_id) self.slot = save_id if (self.slot > 0) then - local filepath = self:getSaveFile(self.slot, true) - if utils.filesystem.exists("save" .. self.slot .. ".save") then - local loadedDatas = binser.readFile(filepath) - - self:setData(loadedDatas[1]) - else - self:resetData() - end + self:deserialize(self:getSaveName()) end end function Game:deleteCurrentSave() if (self.slot > 0) then - - local filepath = self:getSaveFile(self.slot, false) - local success = love.filesystem.remove(filepath) - print(success) - self:removeFromMetadata() + self:delete(self:getSaveName()) + self.metadata:remove(self.slot) end end function Game:write() if (self.slot > 0) then - local data = self:getData() - - local filepath = self:getSaveFile(self.slot, true) - binser.writeFile(filepath, data) - self:addtoMetadata() + self:serialize(self:getSaveName()) + self.metadata:update() end end -function Game:getSaveFile(saveslot, absolute) - local dir = "" - if absolute then - dir = love.filesystem.getSaveDirectory() .. "/" - if not utils.filesystem.exists(dir) then - love.filesystem.createDirectory( "" ) - end - end - - local filepath = dir .. "save" .. saveslot .. ".save" - - return filepath +function Game:getSaveName(saveslot) + local saveslot = saveslot or self.slot + return "save" .. saveslot .. ".save" end function Game:resetSaves() for i=1, self.slotNumber do - local filepath = self:getSaveFile(i, true) - if utils.filesystem.exists("save" .. i .. ".save") then - love.filesystem.remove( "save" .. i .. ".save" ) - end + self:delete(self:getSaveName(i)) end end diff --git a/sonic-radiance.love/game/loot/init.lua b/sonic-radiance.love/game/loot/init.lua index 52c405f..e070609 100644 --- a/sonic-radiance.love/game/loot/init.lua +++ b/sonic-radiance.love/game/loot/init.lua @@ -1,4 +1,5 @@ -local LootManager = Object:extend() +local Serializable = require "birb.classes.serializable" +local LootManager = Serializable:extend() local Pocket = require "game.loot.pocket" local EffectManager = require "game.loot.effectManager" @@ -12,24 +13,7 @@ function LootManager:new(controller) self.effects = EffectManager() self:generatePockets() -end - -function LootManager:getData() - local data = {} - data.rings = self.rings - data.inventory = {} - for i, pocket in ipairs(self.inventory) do - data.inventory[i] = pocket:getData() - end - return data -end - -function LootManager:setData(data) - local data = data - self.rings = data.rings - for i, pocket in ipairs(self.inventory) do - pocket:setData(data.inventory[i]) - end + LootManager.super.new(self, {}, {"inventory"}) end function LootManager:generatePockets() diff --git a/sonic-radiance.love/game/loot/pocket.lua b/sonic-radiance.love/game/loot/pocket.lua index d3f0e5f..0dc0cb6 100644 --- a/sonic-radiance.love/game/loot/pocket.lua +++ b/sonic-radiance.love/game/loot/pocket.lua @@ -1,4 +1,5 @@ -local Pocket = Object:extend() +local Serializable = require "birb.classes.serializable" +local Pocket = Serializable:extend() function Pocket:new(pocketdata) self.name = pocketdata.name @@ -7,14 +8,7 @@ function Pocket:new(pocketdata) self.description = pocketdata.description self.isEquipement = pocketdata.isEquipement self.list = {} -end - -function Pocket:getData() - return self.list -end - -function Pocket:setData(data) - self.list = data + Pocket.super.new(self, {"list"}) end function Pocket:addItem(item, number) diff --git a/sonic-radiance.love/game/metadata.lua b/sonic-radiance.love/game/metadata.lua new file mode 100644 index 0000000..77aeef9 --- /dev/null +++ b/sonic-radiance.love/game/metadata.lua @@ -0,0 +1,83 @@ +-- game.metadata :: Basic metadata subsystem + +--[[ + Copyright © 2021 Kazhnuz + + Permission is hereby granted, free of charge, to any person obtaining a copy of + this software and associated documentation files (the "Software"), to deal in + the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: + + The above copyright notice and this permission notice shall be included in all + copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +]] + +local Serializer = require "birb.classes.serializable.serializer" +local Metadata = Serializer:extend() + +local META_FILE = "metadata.save" + +function Metadata:new(game) + self.game = game + self:reset() + Metadata.super.new(self, {"data"}) +end + +function Metadata:reset() + self.data = {} + for i = 1, self.game.slotNumber, 1 do + local newMetadata = {} + newMetadata.exist = false + newMetadata.completion = 0 + newMetadata.gametime = 0 + newMetadata.team = {} + newMetadata.rings = 0 + newMetadata.emeralds = 0 + newMetadata.location = "" + table.insert(self.data, newMetadata) + end +end + +function Metadata:update() + self:read() + if (self.data[self.game.slot] == nil) then + self.data[self.game.slot] = {} + end + self.data[self.game.slot].exist = true + self.data[self.game.slot].completion = self.game.completion + self.data[self.game.slot].gametime = self.game.gametime + self.data[self.game.slot].team = self.game.characters.team + self.data[self.game.slot].rings = self.game.loot.rings + self.data[self.game.slot].emeralds = 0 + self.data[self.game.slot].location = self.game.mapName + self:write() +end + +function Metadata:get() + self:read() + return self.data +end + +function Metadata:write() + self:serialize(META_FILE) +end + +function Metadata:read() + self:deserialize(META_FILE) +end + +function Metadata:remove(slot) + self.data[slot].exist = false + self:write() + end + +return Metadata