diff --git a/advtrains/advtrains/helpers.lua b/advtrains/advtrains/helpers.lua index a2b9b16..039b4f0 100644 --- a/advtrains/advtrains/helpers.lua +++ b/advtrains/advtrains/helpers.lua @@ -170,12 +170,6 @@ function advtrains.minAngleDiffRad(r1, r2) return try3 end end -function advtrains.dumppath(path) - if not path then atprint("dumppath: no path(nil)") return end - local min=advtrains.minN(path) - local max=advtrains.maxN(path) - for i=min, max do atprint("["..i.."] "..(path[i] and minetest.pos_to_string(path[i]) or "nil")) end -end function advtrains.merge_tables(a, ...) local new={} diff --git a/advtrains/advtrains/init.lua b/advtrains/advtrains/init.lua index 2bdf39c..bbb8713 100644 --- a/advtrains/advtrains/init.lua +++ b/advtrains/advtrains/init.lua @@ -43,7 +43,7 @@ advtrains.modpath = minetest.get_modpath("advtrains") function advtrains.print_concat_table(a) local str="" local stra="" - for i=1,10 do + for i=1,20 do t=a[i] if t==nil then stra=stra.."nil " @@ -70,23 +70,20 @@ function advtrains.print_concat_table(a) end return str end + atprint=function() end -if minetest.setting_getbool("advtrains_debug") then - atprint=function(t, ...) - local context=advtrains.atprint_context_tid - if not context then context="" end - --if context~="4527" then return end - local text=advtrains.print_concat_table({t, ...}) - minetest.log("action", "[advtrains]"..context..">"..text) - minetest.chat_send_all("[advtrains]"..context..">"..text) - end +atlog=function(t, ...) + local context=advtrains.atprint_context_tid + if not context then return end + local text=advtrains.print_concat_table({t, ...}) + minetest.log("action", text) end atwarn=function(t, ...) local text=advtrains.print_concat_table({t, ...}) minetest.log("warning", "[advtrains]"..text) minetest.chat_send_all("[advtrains] -!- "..text) end -sid=function(id) return string.sub(id, -4) end +sid=function(id) return string.sub(id, -6) end dofile(advtrains.modpath.."/helpers.lua"); --dofile(advtrains.modpath.."/debugitems.lua"); @@ -106,6 +103,7 @@ advtrains.meseconrules = {x=0, y=-1, z=-1}, {x=0, y=-2, z=0}} + dofile(advtrains.modpath.."/trainlogic.lua") dofile(advtrains.modpath.."/trainhud.lua") dofile(advtrains.modpath.."/trackplacer.lua") @@ -309,7 +307,7 @@ function advtrains.load() end init_load=true no_action=false - atprint("[load_all]Loaded advtrains save files") + atlog("[load_all]Loaded advtrains save files") end --## MAIN SAVE ROUTINE ## @@ -324,6 +322,6 @@ function advtrains.save() if atlatc then atlatc.save() end - atprint("[save_all]Saved advtrains save files") + atlog("[save_all]Saved advtrains save files") end minetest.register_on_shutdown(advtrains.save) diff --git a/advtrains/advtrains/nodedb.lua b/advtrains/advtrains/nodedb.lua index 5a193bd..4ab551d 100644 --- a/advtrains/advtrains/nodedb.lua +++ b/advtrains/advtrains/nodedb.lua @@ -52,40 +52,38 @@ local function ndbset(x,y,z,v) end +local path=minetest.get_worldpath().."/advtrains_ndb2" --load --nodeids get loaded by advtrains init.lua and passed here function ndb.load_data(data) ndb_nodeids = data and data.nodeids or {} -end - -local path=minetest.get_worldpath().."/advtrains_ndb2" - -local file, err = io.open(path, "r") -if not file then - atprint("load ndb failed: ", err or "Unknown Error") -else - 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 - 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) - hst_y=file:read(2) - hst_x=file:read(2) - cid=file:read(2) + local file, err = io.open(path, "r") + if not file then + atwarn("Couldn't load the node database: ", err or "Unknown Error") + else + 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 + 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) + hst_y=file:read(2) + hst_x=file:read(2) + cid=file:read(2) + end + atlog("nodedb: read", cnt, "nodes.") + file:close() end - atprint("nodedb: read", cnt, "nodes.") - file:close() end --save function ndb.save_data() local file, err = io.open(path, "w") if not file then - atprint("save ndb failed: ", err or "Unknown Error") + atwarn("Couldn't save the node database: ", err or "Unknown Error") else for y, ny in pairs(ndb_nodes) do for x, nx in pairs(ny) do @@ -197,57 +195,45 @@ function advtrains.get_rail_info_at(pos, drives_on) return true, conn1, conn2, rely1, rely2, railheight end -ndb.run_lbm = function(pos, nodep) - return advtrains.pcall(function() - local node=nodep - if not node then - node=minetest.get_node_or_nil(pos) - if not node then - --this is defintely not loaded - return nil +ndb.run_lbm = function(pos, node) + return advtrains.pcall(function() + local cid=ndbget(pos.x, pos.y, pos.z) + if cid then + --if in database, detect changes and apply. + local nodeid = ndb_nodeids[u14b(cid)] + local param2 = l2b(cid) + if not nodeid then + --something went wrong + atwarn("Node Database corruption, couldn't determine node to set at", pos) + ndb.update(pos, node) + else + if (nodeid~=node.name or param2~=node.param2) then + atprint("nodedb: lbm replaced", pos, "with nodeid", nodeid, "param2", param2, "cid is", cid) + minetest.swap_node(pos, {name=nodeid, param2 = param2}) + local ndef=minetest.registered_nodes[nodeid] + if ndef and ndef.on_updated_from_nodedb then + ndef.on_updated_from_nodedb(pos, node) end + return true end - local cid=ndbget(pos.x, pos.y, pos.z) - if cid then - --if in database, detect changes and apply. - local nodeid = ndb_nodeids[u14b(cid)] - local param2 = l2b(cid) - if not nodeid then - --something went wrong - atprint("nodedb: lbm nid not found", pos, "with nid", u14b(cid), "param2", param2, "cid is", cid) - ndb.update(pos, node) - else - if (nodeid~=node.name or param2~=node.param2) then - local ori_ndef=minetest.registered_nodes[node.name] - if ori_ndef and ori_ndef.groups.save_in_nodedb then --check if this node has been worldedited, and don't replace then - atprint("nodedb: lbm replaced", pos, "with nodeid", nodeid, "param2", param2, "cid is", cid) - minetest.swap_node(pos, {name=nodeid, param2 = param2}) - local ndef=minetest.registered_nodes[nodeid] - if ndef and ndef.on_updated_from_nodedb then - ndef.on_updated_from_nodedb(pos, node) - end - return true - else - ndb.clear(pos) - end - end - end - else - --if not in database, take it. - atprint("nodedb: ", pos, "not in database") - ndb.update(pos, node) - end - return false - end) - end + end + else + --if not in database, take it. + atlog("Node Database:", pos, "was not found in the database, have you used worldedit?") + ndb.update(pos, node) + end + return false + end) +end -minetest.register_abm({ +minetest.register_lbm({ name = "advtrains:nodedb_on_load_update", nodenames = {"group:save_in_nodedb"}, run_at_every_load = true, + run_on_every_load = true, action = ndb.run_lbm, - interval=10, + interval=30, chance=1, }) @@ -258,8 +244,20 @@ ndb.restore_all = function() for y, ny in pairs(ndb_nodes) do for x, nx in pairs(ny) do for z, _ in pairs(nx) do - if ndb.run_lbm({x=x, y=y, z=z}) then - cnt=cnt+1 + local pos={x=x, y=y, z=z} + local node=minetest.get_node_or_nil(pos) + if node then + local ori_ndef=minetest.registered_nodes[node.name] + local ndbnode=ndb.get_node(pos) + if ori_ndef and ori_ndef.groups.save_in_nodedb then --check if this node has been worldedited, and don't replace then + if (ndbnode.name~=node.name or ndbnode.param2~=node.param2) then + minetest.swap_node(pos, ndbnode) + atwarn("Replaced",node.name,"@",pos,"with",ndbnode.name) + end + else + ndb.clear(pos) + atwarn("Found ghost node (former",ndbnode.name,") @",pos,"deleting") + end end end end @@ -283,3 +281,20 @@ end advtrains.ndb=ndb +local ptime + +minetest.register_chatcommand("at_restore_ndb", + { + params = "", -- Short parameter description + description = "Write node db back to map", -- Full description + privs = {train_operator=true, worldedit=true}, -- Require the "privs" privilege to run + func = function(name, param) + if !minetest.check_player_privs(name, {server=true}) and os.time() < ptime+30 then + return false, "Please wait at least 30s from the previous execution of /at_restore_ndb!" + end + ndb.restore_all() + ptime=os.time() + return true + end, + }) + diff --git a/advtrains/advtrains/trainlogic.lua b/advtrains/advtrains/trainlogic.lua index 8614c79..f307026 100644 --- a/advtrains/advtrains/trainlogic.lua +++ b/advtrains/advtrains/trainlogic.lua @@ -193,6 +193,9 @@ function advtrains.train_step_a(id, train, dtime) train.path_dist[-1]=vector.distance(train.last_pos, train.last_pos_prev) train.path_extent_min=-1 train.path_extent_max=0 + train.min_index_on_track=-1 + train.max_index_on_track=0 + --[[ Bugfix for trains randomly ignoring ATC rails: - Paths have been invalidated. 1 gets executed and ensures an initial path @@ -355,7 +358,7 @@ function advtrains.train_step_a(id, train, dtime) local path_pregen_keep=20 local offtrack_keep=4 local gen_front_keep= path_pregen_keep - local gen_back_keep= - train.trainlen - path_pregen_keep + local gen_back_keep= math.floor(- train.trainlen - path_pregen_keep) local delete_min=math.min(train.max_index_on_track - offtrack_keep, math.floor(train.index)+gen_back_keep) local delete_max=math.max(train.min_index_on_track + offtrack_keep, math.floor(train.index)+gen_front_keep) @@ -483,13 +486,13 @@ function advtrains.pathpredict(id, train, regular) local maxn=train.path_extent_max or 0 while maxn < gen_front do--pregenerate local conway - if train.max_index_on_track == train.path_extent_max then + if train.max_index_on_track == maxn then atprint("maxn conway for ",maxn,train.path[maxn],maxn-1,train.path[maxn-1]) conway=advtrains.conway(train.path[maxn], train.path[maxn-1], train.drives_on) end if conway then train.path[maxn+1]=conway - train.max_index_on_track=maxn + train.max_index_on_track=maxn+1 else --do as if nothing has happened and preceed with path --but do not update max_index_on_track @@ -504,13 +507,13 @@ function advtrains.pathpredict(id, train, regular) local minn=train.path_extent_min or -1 while minn > gen_back do local conway - if train.min_index_on_track == train.path_extent_min then + if train.min_index_on_track == minn then atprint("minn conway for ",minn,train.path[minn],minn+1,train.path[minn+1]) conway=advtrains.conway(train.path[minn], train.path[minn+1], train.drives_on) end if conway then train.path[minn-1]=conway - train.min_index_on_track=minn + train.min_index_on_track=minn-1 else --do as if nothing has happened and preceed with path --but do not update min_index_on_track