-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathsession.lua
More file actions
100 lines (87 loc) · 2.92 KB
/
Copy pathsession.lua
File metadata and controls
100 lines (87 loc) · 2.92 KB
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
-- session.lua
minetest.log("action", "[Session] Loaded session.lua")
local session_table = {}
local Session = {}
Session.__index = Session
function Session.fetch(playername)
assert(playername, "Session.get: playername required")
local sess = session_table[playername]
if not sess then
minetest.log("action", "[Session.get] Session at creation: " .. tostring(Session))
minetest.log("action", "[Session.get] Session.touch at creation: " .. tostring(Session.touch))
sess = setmetatable({
state = {},
form_data = {},
created_at = os.time(),
last_access = os.time(),
playername = playername,
}, Session)
session_table[playername] = sess
minetest.log("action", "[Session.get] sess metatable: " .. tostring(getmetatable(sess)))
minetest.log("action", "[Session.get] sess.touch after metatable: " .. tostring(sess.touch))
end
return sess
end
function Session.destroy(playername)
assert(playername, "Session.destroy: playername required")
session_table[playername] = nil
end
-- Update last_access whenever real interaction occurs
function Session:touch()
self.last_access = os.time()
end
function Session:get(key)
minetest.log("action", ("[Session:get] player='%s' key='%s' self=%s"):format(
tostring(self.playername), tostring(key), tostring(self)
))
if not self or type(self) ~= "table" or not self.touch then
minetest.log("error", "[Session:get] Invalid self! Likely called with dot, not colon. Stack:\n" .. debug.traceback())
error("[Session:get] Method called incorrectly (should use colon): sess:get(key)")
end
self:touch()
local val = self.state[key]
minetest.log("action", ("[Session:get] player='%s' key='%s' => %s"):format(
tostring(self.playername), tostring(key), tostring(val)
))
return val
end
function Session:set(key, value)
self:touch()
self.state[key] = value
end
-- Combined get/set method, similar to PHP's Session IO sugar
function Session:io(key, value)
if value ~= nil then
self:set(key, value)
return value -- Only touch once
else
return self:get(key)
end
end
function Session:get_form_data(form)
self:touch()
return self.form_data[form]
end
function Session:set_form_data(form, data)
self:touch()
self.form_data[form] = data
end
-- Optional: Expire sessions that are too old/inactive (GC utility)
function Session.expire_inactive(threshold_seconds)
local now = os.time()
for pname, sess in pairs(session_table) do
if sess.last_access and now - sess.last_access > threshold_seconds then
session_table[pname] = nil
minetest.log("action", ("[Session] Expired session for player '%s'"):format(pname))
end
end
end
-- Optional: Enumerate sessions (for admin/debug)
function Session.list()
local out = {}
for pname, sess in pairs(session_table) do
table.insert(out, {playername = pname, last_access = sess.last_access, created_at = sess.created_at})
end
return out
end
return Session