-
Notifications
You must be signed in to change notification settings - Fork 7
/
Copy pathutil.lua
115 lines (106 loc) · 2.96 KB
/
util.lua
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
bls.util = {}
function bls.util.pairs_by_keys(t, f)
-- iterate a table, sorted on keys
local a = {}
for n in pairs(t) do
table.insert(a, n)
end
table.sort(a, f)
local i = 0
return function()
i = i + 1
if a[i] == nil then
return nil
else
return a[i], t[a[i]]
end
end
end
function bls.util.most_common_in_table(t)
-- find the mode
local counts = {}
for _, item in ipairs(t) do
counts[item] = (counts[item] or 0) + 1
end
local most_common
local count = 0
for item, item_count in pairs(counts) do
if item_count > count then
most_common = item
count = item_count
end
end
return most_common
end
function bls.util.safe(func, rv_on_fail)
-- wrap a function w/ logic to avoid crashing the game
return function(...)
local rvs = {xpcall(func, debug.traceback, ...)}
if rvs[1] then
table.remove(rvs, 1)
return unpack(rvs)
else
bls.log("error", "Caught error: %s", rvs[2])
return rv_on_fail
end
end
end
function bls.util.nformat(s, tab)
--[[
format a string w/ named parameters
e.g. nformat("%(foo)s %(bar)s", {bar="dogs", foo="cats"}) == "cats dogs"
]]--
return (
s:gsub(
"%%%(([%a%w_]+)%)([-0-9%.]*[cdeEfgGiouxXsq])",
function(k, fmt)
return tab[k] and ("%" .. fmt):format(tab[k]) or
"%(" .. k .. ")" .. fmt
end
)
)
end
function bls.util.tables_equal(t1, t2, ignore_mt)
local ty1 = type(t1)
local ty2 = type(t2)
if ty1 ~= ty2 then
return false
end
-- non-table types can be directly compared
if ty1 ~= 'table' and ty2 ~= 'table' then
return t1 == t2
end
-- as well as tables which have the metamethod __eq
local mt = getmetatable(t1)
if not ignore_mt and mt and mt.__eq then
return t1 == t2
end
for k1, v1 in pairs(t1) do
local v2 = t2[k1]
if v2 == nil or not bls.util.tables_equal(v1, v2) then
return false
end
end
for k2, v2 in pairs(t2) do
local v1 = t1[k2]
if v1 == nil or not bls.util.tables_equal(v1, v2) then
return false
end
end
return true
end
-- Get player by name, case insensitive, cleans whitespace
function bls.util.get_player_by_name(given_player_name)
local found_player = minetest.get_player_by_name(given_player_name)
if found_player then return found_player end
local clean_player_name = given_player_name:gsub("%s+", "")
if clean_player_name == "" then
return
end
local lower_player_name = clean_player_name:lower()
for _, connected_player in ipairs(minetest.get_connected_players()) do
if connected_player:get_player_name():lower() == lower_player_name then
return connected_player
end
end
end