summaryrefslogtreecommitdiff
path: root/nodedb.lua
diff options
context:
space:
mode:
Diffstat (limited to 'nodedb.lua')
-rw-r--r--nodedb.lua83
1 files changed, 78 insertions, 5 deletions
diff --git a/nodedb.lua b/nodedb.lua
index de582f0..6f852d6 100644
--- a/nodedb.lua
+++ b/nodedb.lua
@@ -31,6 +31,7 @@ local ndb={}
--local variables for performance
local ndb_nodeids={}
local ndb_nodes={}
+local ndb_ver
local function ndbget(x,y,z)
local ny=ndb_nodes[y]
@@ -52,22 +53,39 @@ local function ndbset(x,y,z,v)
ndb_nodes[y][x][z]=v
end
+-- load/save
-local path="advtrains_ndb2"
---load
+local path_pre_v4=datapath.."advtrains_ndb2"
+--load pre_v4 format
--nodeids get loaded by advtrains init.lua and passed here
-function ndb.load_data(data)
+function ndb.load_data_pre_v4(data)
+ print("nodedb: Loading pre v4 format")
+
ndb_nodeids = data and data.nodeids or {}
- local file, err = io.open(datapath..path, "rb")
+ ndb_ver = data and data.ver or 0
+ if ndb_ver < 1 then
+ for k,v in pairs(ndb_nodeids) do
+ if v == "advtrains:dtrack_xing4590_st" then
+ cidDepr = k
+ elseif v == "advtrains:dtrack_xing90plusx_45l" then
+ cidNew = k
+ end
+ end
+ end
+ local file, err = io.open(path_pre_v4, "rb")
if not file then
print("Couldn't load the node database: ", err or "Unknown Error")
else
+ -- Note: code duplication because of weird coordinate order in ndb2 format (z,y,x)
local cnt=0
local hst_z=file:read(2)
local hst_y=file:read(2)
local hst_x=file:read(2)
local cid=file:read(2)
while hst_z and hst_y and hst_x and cid and #hst_z==2 and #hst_y==2 and #hst_x==2 and #cid==2 do
+ if (ndb_ver < 1 and cid == cidDepr) then
+ cid = cidNew
+ end
ndbset(bytes_to_int(hst_x), bytes_to_int(hst_y), bytes_to_int(hst_z), bytes_to_int(cid))
cnt=cnt+1
hst_z=file:read(2)
@@ -75,12 +93,66 @@ function ndb.load_data(data)
hst_x=file:read(2)
cid=file:read(2)
end
- print("nodedb: read", cnt, "nodes.")
+ print("nodedb (ndb2 format): read", cnt, "nodes.")
ndb_nodes_total = cnt
file:close()
end
+ ndb_ver = 1
+end
+
+-- the new ndb file format is backported from cellworld, and stores the cids also in the ndb file.
+-- These functions have the form of a serialize_lib atomic load/save callback and are called from avt_save/avt_load.
+function ndb.load_callback(file)
+ -- read version
+ local vers_byte = file:read(1)
+ local version = string.byte(vers_byte)
+ if version~=1 then
+ file:close()
+ error("Doesn't support v4 nodedb file of version "..version)
+ end
+
+ -- read cid mappings
+ local nstr_byte = file:read(2)
+ local nstr = bytes_to_int(nstr_byte)
+ for i = 1,nstr do
+ local stid_byte = file:read(2)
+ local stid = bytes_to_int(stid_byte)
+ local stna = file:read("*l")
+ --atdebug("content id:", stid, "->", stna)
+ ndb_nodeids[stid] = stna
+ end
+ print("[nodedb] read", nstr, "node content ids.")
+
+ -- read nodes
+ local cnt=0
+ local hst_x=file:read(2)
+ local hst_y=file:read(2)
+ local hst_z=file:read(2)
+ local cid=file:read(2)
+ local cidi
+ while hst_z and hst_y and hst_x and cid and #hst_z==2 and #hst_y==2 and #hst_x==2 and #cid==2 do
+ cidi = bytes_to_int(cid)
+ -- prevent file corruption already here
+ if not ndb_nodeids[u14b(cidi)] then
+ -- clear the ndb data, to reinitialize it
+ -- in strict loading mode, doesn't matter as starting will be interrupted anyway
+ ndb_nodeids = {}
+ ndb_nodes = {}
+ error("NDB file is corrupted (found entry with invalid cid)")
+ end
+ ndbset(bytes_to_int(hst_x), bytes_to_int(hst_y), bytes_to_int(hst_z), cidi)
+ cnt=cnt+1
+ hst_x=file:read(2)
+ hst_y=file:read(2)
+ hst_z=file:read(2)
+ cid=file:read(2)
+ end
+ print("[nodedb] read", cnt, "nodes.")
+ ndb_nodes_total = cnt
+ file:close()
end
+
--function to get node. track database is not helpful here.
function ndb.get_node_or_nil(pos)
-- FIX for bug found on linuxworks server:
@@ -124,6 +196,7 @@ end
--false if it's not a rail or the train does not drive on this rail, but it is loaded or
--nil if the node is neither loaded nor in trackdb
--the distraction between false and nil will be needed only in special cases.(train initpos)
+advtrains = advtrains or {}
function advtrains.get_rail_info_at(pos)
local rdp=advtrains.round_vector_floor_y(pos)