From c076c628418e22aeabef2f6e2fdb4bcce3ac7cf4 Mon Sep 17 00:00:00 2001 From: Athozus Date: Sun, 31 Mar 2024 20:39:30 +0200 Subject: [PATCH] Add repairing storage script in migrate.lua --- migrate.lua | 101 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 101 insertions(+) diff --git a/migrate.lua b/migrate.lua index 0266e63..331f327 100644 --- a/migrate.lua +++ b/migrate.lua @@ -80,6 +80,104 @@ local function migrate_v2_to_v3() end) end +local function search_box(playername, box, uuid) + local e = mail.get_storage_entry(playername) + for _, m in ipairs(e[box]) do + if m.id == uuid then + return { time = m.time, from = m.from, to = m.to, cc = m.cc, bcc = m.bcc, subject = m.subject, body = m.body } end + end + return false +end + +local function is_uuid_existing(uuid) + for _, k in ipairs(mail.storage:get_keys()) do + if string.sub(k,1,5) ~= "mail/" then + goto continue + end + local p = string.sub(k, 6) + local result + local boxes = {"inbox", "outbox", "drafts", "trash"} + for _, b in ipairs(boxes) do + result = search_box(p, b, uuid) + if result then return result end + end + ::continue:: + end + return false +end + +local function are_message_sames(a, b) + return a.time == b.time + and a.from == b.from + and a.to == b.to + and a.cc == b.cc + and a.bcc == b.bcc + and a.subject == b.subject + and a.body == b.body +end + +local function repair_box(playername, box) + local e = mail.get_storage_entry(playername) + for _, m in ipairs(e[box]) do + local uuid = m.id + local exists = is_uuid_existing(uuid) + if not exists then + goto continue + elseif are_message_sames(exists, m) then + -- same message, continue + goto continue + else + local new_uuid = mail.new_uuid() -- generates a new uuid to replace doublons + for _, k in ipairs(mail.storage:get_keys()) do + if string.sub(k,1,5) ~= "mail/" then + goto continue_r + end + local p = string.sub(k, 6) + local er = mail.get_storage_entry(p) + for _, r in ipairs(er.inbox) do + if r.id == uuid and not are_message_sames(m, r) then + r.id = new_uuid + end + end + for _, r in ipairs(er.outbox) do + if r.id == uuid and not are_message_sames(m, r) then + r.id = new_uuid + end + end + for _, r in ipairs(er.drafts) do + if r.id == uuid and not are_message_sames(m, r) then + r.id = new_uuid + end + end + for _, r in ipairs(er.trash) do + if r.id == uuid and not are_message_sames(m, r) then + r.id = new_uuid + end + end + mail.set_storage_entry(p, er) + ::continue_r:: + end + end + ::continue:: + end +end + +-- repair database for uuid doublons +local function repair_storage() + -- iterate through players + for _, k in ipairs(mail.storage:get_keys()) do + if string.sub(k,1,5) ~= "mail/" then + goto continue + end + local p = string.sub(k, 6) + repair_box(p, "inbox") + repair_box(p, "outbox") + repair_box(p, "drafts") + repair_box(p, "trash") + ::continue:: + end +end + function mail.migrate() -- check for v2 storage first, v1-migration might have set the v3-flag already local version = mail.storage:get_int(STORAGE_VERSION_KEY) @@ -96,4 +194,7 @@ function mail.migrate() migrate_v1_to_v3() mail.storage:set_int(STORAGE_VERSION_KEY, 3) end + + -- repair storage for uuid doublons + repair_storage() end