From faf8d88167f065ba3b2829badef14a31c4574971 Mon Sep 17 00:00:00 2001 From: Gael-de-Sailly Date: Wed, 12 May 2021 11:17:41 +0200 Subject: Updated to be compatible with new advtrains file structure May be hacky, but works. --- nodedb.lua | 83 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 78 insertions(+), 5 deletions(-) (limited to 'nodedb.lua') 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) -- cgit v1.2.3