Skip to content

Commit

Permalink
Truncate long area names, store previous owner separately
Browse files Browse the repository at this point in the history
  • Loading branch information
luk3yx committed Oct 30, 2024
1 parent a79d56b commit b332106
Show file tree
Hide file tree
Showing 5 changed files with 70 additions and 6 deletions.
11 changes: 9 additions & 2 deletions chatcommands.lua
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
local S = areas.S

local sub8 = utf8.sub
local anticurse_exists = minetest.global_exists("chat_anticurse")

minetest.register_chatcommand("protect", {
Expand All @@ -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)..
Expand Down Expand Up @@ -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..
Expand All @@ -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,
Expand Down Expand Up @@ -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.")
Expand Down Expand Up @@ -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).",
Expand Down
13 changes: 11 additions & 2 deletions hud.lua
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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)
Expand Down
46 changes: 45 additions & 1 deletion internal.lua
Original file line number Diff line number Diff line change
Expand Up @@ -9,14 +9,50 @@ 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
end
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 <name>)" 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 <player>)\" 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")
Expand All @@ -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)
Expand All @@ -38,6 +79,9 @@ function areas:load()
tostring(err))
end
file:close()
if need_migration then
migrate_by_strings(self)
end
self:populateStore()
end

Expand Down
3 changes: 2 additions & 1 deletion settings.lua
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down
3 changes: 3 additions & 0 deletions settingtypes.txt
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down

0 comments on commit b332106

Please sign in to comment.