From fd520efce602f304b0f82f715cf645a466aa62dd Mon Sep 17 00:00:00 2001 From: flux <25628292+fluxionary@users.noreply.github.com> Date: Sun, 14 May 2023 11:35:03 -0700 Subject: [PATCH] fixes to copying coordinates from chat --- init.lua | 104 +++++++++++++++++++++++++++---------------------------- mod.conf | 1 - 2 files changed, 52 insertions(+), 53 deletions(-) diff --git a/init.lua b/init.lua index 0dee351..452af22 100644 --- a/init.lua +++ b/init.lua @@ -509,18 +509,18 @@ local last_coords_log_limit = 5 -- how many to keep -- Stores personal points for players local last_coords_log_personal = {} -local function add_coords_log(pos, name, message) - table.insert(last_coords_log, 1, {pos=pos, name=name, message=message}) +local function add_coords_log(pos, message) + table.insert(last_coords_log, 1, {pos=pos, message=message, timestamp=os.clock()}) last_coords_log[last_coords_log_limit] = nil end -local function add_coords_log_personal(playername, pos, name, message) +local function add_coords_log_personal(playername, pos, message) if not last_coords_log_personal[playername] then last_coords_log_personal[playername] = {} end local personal = last_coords_log_personal[playername] - table.insert(personal, 1, {pos=pos, name=name, message=message}) + table.insert(personal, 1, {pos=pos, message=message, timestamp=os.clock()}) personal[last_coords_log_limit] = nil end @@ -528,55 +528,67 @@ end -- Trying to mach any three integer numbers separated at least by -- spaces or punctuation. --local FUZZY_COORD_PATTERN = ".-(%d+)%D?[%s.,:;]%D?(%d+)%D?[%s.,:;]%D?(%d+)" -local FUZZY_COORD_PATTERN = ".-(%d+)[^.%d]?[%s,:;]%D?(%d+)[^.%d]?[%s,:;]%D?(%d+)" +local FUZZY_COORD_PATTERN = "(%-?%d+)[^.%d]?[%s,:;]%D?(%-?%d+)[^.%d]?[%s,:;]%D?(%-?%d+)" --- "usafe" means it may throw errors, use pcall() -local function fuzzy_parse_coords_unsafe(str) +local function fuzzy_parse_coords(str) -- find any 3 numbers in a string separated by punctuarion/spaces local x,y,z = str:match(FUZZY_COORD_PATTERN) - x = clamp(tonumber(x), -32000, 32000) - y = clamp(tonumber(y), -32000, 32000) - z = clamp(tonumber(z), -32000, 32000) - return {x=x,y=y,z=z} + x = tonumber(x) + y = tonumber(y) + z = tonumber(z) + if x and y and z then + return vector.new( + clamp(tonumber(x), -30912, 30927), + clamp(tonumber(y), -30912, 30927), + clamp(tonumber(z), -30912, 30927) + ) + end end _format_recent_dropbox = function(playername) + local logs = table.copy(last_coords_log) + table.insert_all(logs, last_coords_log_personal[playername] or {}) + table.sort(logs, function(a, b) return a.timestamp > b.timestamp end) + local out = {} - for k,v in ipairs(last_coords_log) do - local item = string.format("%d,%d,%d | %s> %s", + for _, v in ipairs(logs) do + local item = string.format("%d,%d,%d | %s", v.pos.x, v.pos.y, v.pos.z, - v.name, v.message:sub(1,50)) table.insert(out, minetest.formspec_escape(item)) end - if last_coords_log_personal[playername] then - table.insert(out, '------------------------------ Your personal points: ------------------------------') - for k,v in ipairs(last_coords_log_personal[playername]) do - local item = string.format("%d,%d,%d | %s> %s", - v.pos.x, v.pos.y, v.pos.z, - v.name, - v.message:sub(1,50)) - table.insert(out, minetest.formspec_escape(item)) - end - end - return table.concat(out,",") end -local function scan_chat_for_coords(name, message) - local success, coords = pcall(fuzzy_parse_coords_unsafe, message) - if success then - add_coords_log(coords, name, message) +local function scan_chat_for_coords(message) + local coords = fuzzy_parse_coords(message) + if coords then + add_coords_log(coords, message) end - return nil -- do not handle messages, just check them end +local old_chat_send_all = minetest.chat_send_all +function minetest.chat_send_all(text) + scan_chat_for_coords(text) + return old_chat_send_all(text) +end -minetest.register_on_chat_message(scan_chat_for_coords) +local function scan_player_chat_for_coords(name, message) + local coords = fuzzy_parse_coords(message) + if coords then + add_coords_log_personal(name, coords, message) + end +end + +local old_chat_send_player = minetest.chat_send_player +function minetest.chat_send_player(name, text) + scan_player_chat_for_coords(name, text) + return old_chat_send_player(name, text) +end -------------------------------------------------------------------------------- @@ -591,22 +603,20 @@ end -- A hook for "fake" global chat messages, that don't trigger the -- on_chat_message hooks. -function waypoint_compass.process_message(name, message) - name = name or "none" - message = message or "" - scan_chat_for_coords(name, message) +function waypoint_compass.process_message(message) + scan_chat_for_coords(message) end -- Add a custom point to global list (name/message can be any strings) -- `pos` is table like {x=1,y=2,z=2} -function waypoint_compass.add_point_to_recent_global(pos, name, message) - local success, ret = pcall(add_coords_log, pos, name, message) +function waypoint_compass.add_point_to_recent_global(pos, message) + local success, ret = pcall(add_coords_log, pos, message) if not success then minetest.log( string.format( "error [MOD] waypoint_compass: Failed add_point_to_recent_global(%s %s %s)", - pos, name, message)) + pos, message)) end return success end @@ -614,30 +624,20 @@ end -- Add a custom point to personal player's list (name/message can be any strings) -- `pos` is table like {x=1,y=2,z=2} -function waypoint_compass.add_point_to_recent_personal(playername, pos, name, message) - local success, ret = pcall(add_coords_log_personal, playername, pos, name, message) +function waypoint_compass.add_point_to_recent_personal(playername, pos, message) + local success, ret = pcall(add_coords_log_personal, playername, pos, message) if not success then minetest.log( string.format( "error [MOD] waypoint_compass: Failed add_point_to_recent_personal(%s %s %s %s)", - playername, pos, name, message)) + playername, pos, message)) end return success end -- -- Usage example: --- waypoint_compass.add_point_to_recent_personal('singleplayer', {x=0,y=1,z=2}, "death", "from lava") - -if waypoint_announce and waypoint_announce.post_announcement_hooks then - local _announcement_callback = function(announcer_name, message, pointed_pos) - waypoint_compass.add_point_to_recent_global(pointed_pos, announcer_name, message) - end - - local hooks = waypoint_announce.post_announcement_hooks - hooks["waypoint_compass"] = _announcement_callback -end +-- waypoint_compass.add_point_to_recent_personal('singleplayer', {x=0,y=1,z=2}, "death from lava") return waypoint_compass - diff --git a/mod.conf b/mod.conf index 90a0f20..15df5d5 100755 --- a/mod.conf +++ b/mod.conf @@ -1,4 +1,3 @@ name = waypoint_compass description = Item that shows where is specific point in the world depends = -optional_depends = waypoint_announce