summaryrefslogtreecommitdiff
path: root/xban2/gui.lua
blob: fb0c1df14f814557f8a60c4e7d85d7c70c3f4540 (plain)
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
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134

local FORMNAME = "xban2:main"
local MAXLISTSIZE = 100

local strfind, format = string.find, string.format

local ESC = minetest.formspec_escape

local function make_list(filter)
	filter = filter or ""
	local list, n, dropped = { }, 0, false
	for k in pairs(minetest.auth_table) do
		if strfind(k, filter, 1, true) then
			if n >= MAXLISTSIZE then
				dropped = true
				break
			end
			n=n+1 list[n] = k
		end
	end
	table.sort(list)
	return list, dropped
end

local states = { }

local function get_state(name)
	local state = states[name]
	if not state then
		state = { index=1, filter="" }
		states[name] = state
		state.list, state.dropped = make_list()
	end
	return state
end

local function get_record_simple(name)
	local e = xban.find_entry(name)
	if not e then
		return nil, ("No entry for `%s'"):format(name)
	elseif (not e.record) or (#e.record == 0) then
		return nil, ("`%s' has no ban records"):format(name)
	end
	local record = { }
	for _, rec in ipairs(e.record) do
		local msg = (os.date("%Y-%m-%d %H:%M:%S", rec.time).." | "
				..(rec.reason or "No reason given."))
		table.insert(record, msg)
	end
	return record, e.record
end

local function make_fs(name)
	local state = get_state(name)
	local list, filter = state.list, state.filter
	local pli, ei = state.player_index or 1, state.entry_index or 0
	if pli > #list then
		pli = #list
	end
	local fs = {
		"size[16,12]",
		"label[0,-.1;Filter]",
		"field[1.5,0;12.8,1;filter;;"..ESC(filter).."]",
		"button[14,-.3;2,1;search;Search]",
	}
	local fsn = #fs
	fsn=fsn+1 fs[fsn] = format("textlist[0,.8;4,9.3;player;%s;%d;0]",
			table.concat(list, ","), pli)
	local record_name = list[pli]
	if record_name then
		local record, e = get_record_simple(record_name)
		if record then
			for i, r in ipairs(record) do
				record[i] = ESC(r)
			end
			fsn=fsn+1 fs[fsn] = format(
					"textlist[4.2,.8;11.7,9.3;entry;%s;%d;0]",
					table.concat(record, ","), ei)
			local rec = e[ei]
			if rec then
				fsn=fsn+1 fs[fsn] = format("label[0,10.3;%s]",
						ESC("Source: "..(rec.source or "<none>")
							.."\nTime: "..os.date("%c", rec.time)
							.."\n"..(rec.expires and
								os.date("%c", rec.expires) or "")),
						pli)
			end
		else
			fsn=fsn+1 fs[fsn] = "textlist[4.2,.8;11.7,9.3;err;"..ESC(e)..";0]"
			fsn=fsn+1 fs[fsn] = "label[0,10.3;"..ESC(e).."]"
		end
	else
		local e = "No entry matches the query."
		fsn=fsn+1 fs[fsn] = "textlist[4.2,.8;11.7,9.3;err;"..ESC(e)..";0]"
		fsn=fsn+1 fs[fsn] = "label[0,10.3;"..ESC(e).."]"
	end
	return table.concat(fs)
end

minetest.register_on_player_receive_fields(function(player, formname, fields)
	if formname ~= FORMNAME then return end
	local name = player:get_player_name()
	local state = get_state(name)
	if fields.player then
		local t = minetest.explode_textlist_event(fields.player)
		if (t.type == "CHG") or (t.type == "DCL") then
			state.player_index = t.index
			minetest.show_formspec(name, FORMNAME, make_fs(name))
		end
		return
	end
	if fields.entry then
		local t = minetest.explode_textlist_event(fields.entry)
		if (t.type == "CHG") or (t.type == "DCL") then
			state.entry_index = t.index
			minetest.show_formspec(name, FORMNAME, make_fs(name))
		end
		return
	end
	if fields.search then
		local filter = fields.filter or ""
		state.filter = filter
		state.list = make_list(filter)
		minetest.show_formspec(name, FORMNAME, make_fs(name))
	end
end)

minetest.register_chatcommand("xban_gui", {
	description = "Show XBan GUI",
	params = "",
	func = function(name, params)
		minetest.show_formspec(name, FORMNAME, make_fs(name))
	end,
})