1
1
local S = minetest .get_translator (" pipeworks" )
2
- local filename = minetest .get_worldpath () .. " /teleport_tubes"
2
+ local filename = minetest .get_worldpath () .. " /teleport_tubes" -- Only used for backward-compat
3
+ local storage = minetest .get_mod_storage ()
3
4
4
5
local tp_tube_db = nil -- nil forces a read
5
- local tp_tube_db_version = 2 .0
6
+ local tp_tube_db_version = 3 .0
6
7
7
8
-- cached rceiver list: hash(pos) => {receivers}
8
9
local cache = {}
@@ -12,47 +13,78 @@ local function hash(pos)
12
13
end
13
14
14
15
local function save_tube_db ()
15
- local file , err = io.open (filename , " w" )
16
- if file then
17
- tp_tube_db .version = tp_tube_db_version
18
- file :write (minetest .serialize (tp_tube_db ))
19
- tp_tube_db .version = nil
20
- io.close (file )
21
- else
22
- error (err )
16
+ -- reset tp-tube cache
17
+ cache = {}
18
+
19
+ local fields = {version = tp_tube_db_version }
20
+ for key , val in pairs (tp_tube_db ) do
21
+ fields [key ] = minetest .serialize (val )
23
22
end
23
+ storage :from_table ({fields = fields })
24
+ end
25
+
26
+ local function save_tube_db_entry (hash )
24
27
-- reset tp-tube cache
25
28
cache = {}
29
+
30
+ local val = tp_tube_db [hash ]
31
+ storage :set_string (hash , val and minetest .serialize (val ) or " " )
26
32
end
27
33
28
34
local function migrate_tube_db ()
35
+ local old_version = tp_tube_db .version or 0
36
+ tp_tube_db .version = nil
37
+ if old_version < 2.0 then
29
38
local tmp_db = {}
30
- tp_tube_db .version = nil
31
39
for _ , val in pairs (tp_tube_db ) do
32
40
if (val .channel ~= " " ) then -- skip unconfigured tubes
33
41
tmp_db [hash (val )] = val
34
42
end
35
43
end
36
44
tp_tube_db = tmp_db
37
- save_tube_db ()
45
+ end
46
+ save_tube_db ()
38
47
end
39
48
40
49
local function read_tube_db ()
41
- local file = io.open (filename , " r" )
42
- if file ~= nil then
50
+ local file = not storage :contains (" version" ) and io.open (filename , " r" )
51
+ if not file then
52
+ tp_tube_db = {}
53
+
54
+ for key , val in pairs (storage :to_table ().fields ) do
55
+ if tonumber (key ) then
56
+ tp_tube_db [key ] = minetest .deserialize (val )
57
+ elseif key == " version" then
58
+ tp_tube_db .version = tonumber (val )
59
+ else
60
+ error (" Unknown field in teleport tube DB: " .. key )
61
+ end
62
+ end
63
+
64
+ if tp_tube_db .version == nil then
65
+ tp_tube_db .version = tp_tube_db_version
66
+ storage :set_string (" version" , tp_tube_db .version )
67
+ elseif tp_tube_db .version > tp_tube_db_version then
68
+ error (" Cannot read teleport tube DB of version " .. tp_tube_db .version )
69
+ end
70
+ else
43
71
local file_content = file :read (" *all" )
44
72
io.close (file )
45
73
74
+ pipeworks .logger (" Moving teleport tube DB into mod storage from " .. filename )
75
+
46
76
if file_content and file_content ~= " " then
47
77
tp_tube_db = minetest .deserialize (file_content )
48
- if (not tp_tube_db .version or tonumber (tp_tube_db .version ) < tp_tube_db_version ) then
49
- migrate_tube_db ()
50
- end
51
- tp_tube_db .version = nil -- we add it back when saving
52
- return tp_tube_db -- we read sucessfully
78
+ else
79
+ tp_tube_db = {version = 2.0 }
53
80
end
54
81
end
55
- tp_tube_db = {}
82
+
83
+ if (not tp_tube_db .version or tonumber (tp_tube_db .version ) < tp_tube_db_version ) then
84
+ migrate_tube_db ()
85
+ end
86
+ tp_tube_db .version = nil
87
+
56
88
return tp_tube_db
57
89
end
58
90
@@ -69,7 +101,7 @@ local function set_tube(pos, channel, can_receive)
69
101
if tube then
70
102
tube .channel = channel
71
103
tube .cr = can_receive
72
- save_tube_db ( )
104
+ save_tube_db_entry ( hash )
73
105
return
74
106
end
75
107
@@ -88,13 +120,14 @@ local function set_tube(pos, channel, can_receive)
88
120
end
89
121
90
122
tp_tube_db [hash ] = {x = pos .x ,y = pos .y ,z = pos .z ,channel = channel ,cr = can_receive }
91
- save_tube_db ( )
123
+ save_tube_db_entry ( hash )
92
124
end
93
125
94
126
local function remove_tube (pos )
95
127
local tubes = tp_tube_db or read_tube_db ()
96
- tubes [hash (pos )] = nil
97
- save_tube_db ()
128
+ local hash = hash (pos )
129
+ tubes [hash ] = nil
130
+ save_tube_db_entry (hash )
98
131
end
99
132
100
133
local function read_node_with_vm (pos )
@@ -114,7 +147,6 @@ local function get_receivers(pos, channel)
114
147
115
148
local tubes = tp_tube_db or read_tube_db ()
116
149
local receivers = {}
117
- local dirty = false
118
150
for key , val in pairs (tubes ) do
119
151
-- skip all non-receivers and the tube that it came from as early as possible, as this is called often
120
152
if (val .cr == 1 and val .channel == channel and (val .x ~= pos .x or val .y ~= pos .y or val .z ~= pos .z )) then
@@ -125,13 +157,10 @@ local function get_receivers(pos, channel)
125
157
table.insert (receivers , val )
126
158
else
127
159
tp_tube_db [key ] = nil
128
- dirty = true
160
+ save_tube_db_entry ( key )
129
161
end
130
162
end
131
163
end
132
- if dirty then
133
- save_tube_db ()
134
- end
135
164
-- cache the result for next time
136
165
cache [hash ] = receivers
137
166
return receivers
290
319
pipeworks .tptube = {
291
320
hash = hash ,
292
321
save_tube_db = save_tube_db ,
322
+ save_tube_db_entry = save_tube_db_entry ,
293
323
get_db = function () return tp_tube_db or read_tube_db () end ,
294
324
set_tube = set_tube ,
295
325
update_meta = update_meta ,
0 commit comments