From b332106974b7618b42539143ca8cec6e844b5aee Mon Sep 17 00:00:00 2001 From: luk3yx Date: Wed, 30 Oct 2024 13:47:58 +1300 Subject: [PATCH] Truncate long area names, store previous owner separately --- chatcommands.lua | 11 +++++++++-- hud.lua | 13 +++++++++++-- internal.lua | 46 +++++++++++++++++++++++++++++++++++++++++++++- settings.lua | 3 ++- settingtypes.txt | 3 +++ 5 files changed, 70 insertions(+), 6 deletions(-) diff --git a/chatcommands.lua b/chatcommands.lua index 616c502..6bc8f89 100644 --- a/chatcommands.lua +++ b/chatcommands.lua @@ -1,5 +1,6 @@ local S = areas.S +local sub8 = utf8.sub local anticurse_exists = minetest.global_exists("chat_anticurse") minetest.register_chatcommand("protect", { @@ -22,6 +23,8 @@ minetest.register_chatcommand("protect", { end end + param = sub8(param, 1, areas.config.max_area_name_length) + minetest.log("action", "/protect invoked, owner="..name.. " AreaName="..param.. " StartPos="..minetest.pos_to_string(pos1).. @@ -112,6 +115,8 @@ minetest.register_chatcommand("add_owner", { end end + areaName = sub8(param, 1, areas.config.max_area_name_length) + minetest.log("action", name.." runs /add_owner. Owner = "..ownerName.. " AreaName = "..areaName.." ParentID = "..pid.. " StartPos = "..pos1.x..","..pos1.y..","..pos1.z.. @@ -125,7 +130,7 @@ minetest.register_chatcommand("add_owner", { end local id = areas:add(ownerName, areaName, pos1, pos2, pid) - areas.areas[id].name = areaName .. " " .. S("(by @1)", name) + areas.areas[id].prev_owner = name areas:save() minetest.chat_send_player(ownerName, @@ -161,6 +166,8 @@ minetest.register_chatcommand("rename_area", { end end + newName = sub8(newName, 1, areas.config.max_area_name_length) + areas.areas[id].name = newName areas:save() return true, S("Area renamed.") @@ -302,7 +309,7 @@ minetest.register_chatcommand("change_owner", { .." or is not owned by you.", id) end areas.areas[id].owner = newOwner - areas.areas[id].name = areas.areas[id].name .. " " .. S("(by @1)", name) + areas.areas[id].prev_owner = name areas:save() minetest.chat_send_player(newOwner, S("@1 has given you control over the area \"@2\" (ID @3).", diff --git a/hud.lua b/hud.lua index 442c5c9..817350c 100644 --- a/hud.lua +++ b/hud.lua @@ -6,10 +6,19 @@ areas.hud = {} local vround = vector.round local tconcat, tinsert = table.concat, table.insert +local sub8 = utf8.sub local creative_mode = minetest.settings:get_bool("creative_mode") +local function trim_area_name(name) + return sub8(name, 1, areas.config.max_area_name_length) +end + local function createAreaString(area, id) - local parts = {"🛡️ ", area.name, " [", id, "] (", area.owner, ")"} + local parts = {"🛡️ ", trim_area_name(area.name), " [", id, "] (", area.owner, ")"} + if area.prev_owner then + tinsert(parts, 3, " " .. S("(by @1)", area.prev_owner)) + end + if area.open then tinsert(parts, " [" .. S("Open") .. "]") end @@ -25,7 +34,7 @@ local function createAreaString(area, id) end end - return tconcat(parts):trim() + return tconcat(parts) end local function updateHud(player, name, pos) diff --git a/internal.lua b/internal.lua index 82d8a82..2b44024 100644 --- a/internal.lua +++ b/internal.lua @@ -9,7 +9,10 @@ end -- Save the areas table to a file function areas:save() - local datastr = minetest.write_json(self.areas, true) + -- HACK: Add the version code at the end so that areas can be downgraded + -- without issue, minetest.parse_json ignores extra data at the end of the + -- string. + local datastr = minetest.write_json(self.areas, true) .. "\nv2" if not datastr then minetest.log("error", "[areas] Failed to serialize area data!") return @@ -17,6 +20,39 @@ function areas:save() return minetest.safe_file_write(self.config.filename, datastr) end +local function migrate_by_strings(self) + local t1 = core.get_us_time() + local migrated = 0 + for _, area in pairs(self.areas) do + -- Search without a pattern (the "true" argument) as it is much faster + local position = area.name:find("\27(T@areas)", 1, true) + if position then + -- Parse the "(by )" suffix and store in the "prev_owner" field + if not area.prev_owner then + area.prev_owner = area.name:match("\27%(T@areas%)%(by \27F([A-Za-z0-9_%-]-)\27E%)\27E$") + end + + -- Remove the translation escape sequence from the area name + area.name = area.name:sub(1, position - 1):gsub(" $", "") + + migrated = migrated + 1 + end + + -- Remove broken by strings + position = area.name:find(" (by ", 1, true) + if position then + area.name = area.name:sub(1, position - 1) + end + end + + -- No need to bother saving the database, if it doesn't get saved this + -- migration will just get run again on the next restart + if migrated > 0 then + minetest.log("action", "[areas] Migrated " .. migrated .. + " \"(by )\" strings in area names") + end +end + -- Load the areas table from the save file function areas:load() local file, err = io.open(self.config.filename, "r") @@ -25,7 +61,12 @@ function areas:load() return err end local data = file:read("*a") + local need_migration = true if data:sub(1, 1) == "[" then + if data:sub(-3) == "\nv2" then + data = data:sub(1, -4) + need_migration = false + end self.areas, err = minetest.parse_json(data) else self.areas, err = minetest.deserialize(data) @@ -38,6 +79,9 @@ function areas:load() tostring(err)) end file:close() + if need_migration then + migrate_by_strings(self) + end self:populateStore() end diff --git a/settings.lua b/settings.lua index 01edc63..aaa6e2b 100644 --- a/settings.lua +++ b/settings.lua @@ -27,8 +27,9 @@ end -- Settings -- -------------- -setting("string", "filename", world_path.."/areas.dat") +setting("string", "filename", world_path.."/areas.dat") setting("boolean", "pvp_by_default", false) +setting("number", "max_area_name_length", 40) -- Allow players with a privilege create their own areas -- within the maximum size and number. diff --git a/settingtypes.txt b/settingtypes.txt index cbf9b6b..7873092 100644 --- a/settingtypes.txt +++ b/settingtypes.txt @@ -6,6 +6,9 @@ # Turn on PvP everywhere areas.pvp_by_default (PvP by default) bool false +# Maximum length of the area name +max_area_name_length (max area name length) int 40 + # Allow players with a privilege create their own areas using /protect # within the specified size and amount limits. areas.self_protection (Self protection) bool false