diff options
author | orwell96 <mono96.mml@gmail.com> | 2017-04-05 13:57:09 +0200 |
---|---|---|
committer | orwell96 <mono96.mml@gmail.com> | 2017-04-29 14:53:00 +0200 |
commit | f42b01c74bdc7e91d3def03125a0e24e6a3bb0d4 (patch) | |
tree | 58a7230e725eb15cf49eedb80254ae0fa88433d1 /advtrains | |
parent | 337db2a573ccaa1672e713855022e96106679803 (diff) | |
download | advtrains-f42b01c74bdc7e91d3def03125a0e24e6a3bb0d4.tar.gz advtrains-f42b01c74bdc7e91d3def03125a0e24e6a3bb0d4.tar.bz2 advtrains-f42b01c74bdc7e91d3def03125a0e24e6a3bb0d4.zip |
Add pcall wrapper to prevent server crashes when advtrains throws an error
Instead, read save files again and restore state before the crash
Rebased to latest commit
Diffstat (limited to 'advtrains')
-rw-r--r-- | advtrains/advtrains/atc.lua | 6 | ||||
-rw-r--r-- | advtrains/advtrains/couple.lua | 17 | ||||
-rw-r--r-- | advtrains/advtrains/init.lua | 30 | ||||
-rw-r--r-- | advtrains/advtrains/nodedb.lua | 6 | ||||
-rw-r--r-- | advtrains/advtrains/trackplacer.lua | 8 | ||||
-rw-r--r-- | advtrains/advtrains/trainlogic.lua | 9 | ||||
-rw-r--r-- | advtrains/advtrains/wagons.lua | 15 | ||||
-rw-r--r-- | advtrains/advtrains_luaautomation/interrupt.lua | 3 |
8 files changed, 93 insertions, 1 deletions
diff --git a/advtrains/advtrains/atc.lua b/advtrains/advtrains/atc.lua index 3925ffd..577f858 100644 --- a/advtrains/advtrains/atc.lua +++ b/advtrains/advtrains/atc.lua @@ -92,12 +92,17 @@ advtrains.register_tracks("default", { return { after_place_node=apn_func, after_dig_node=function(pos) + return advtrains.pcall(function() + advtrains.invalidate_all_paths() advtrains.ndb.clear(pos) local pts=minetest.pos_to_string(pos) atc.controllers[pts]=nil + end) end, on_receive_fields = function(pos, formname, fields, player) + return advtrains.pcall(function() + if advtrains.is_protected(pos, player:get_player_name()) then minetest.record_protection_violation(pos, player:get_player_name()) return @@ -135,6 +140,7 @@ advtrains.register_tracks("default", { atc.send_command(pos) end end + end) end, advtrains = { on_train_enter = function(pos, train_id) diff --git a/advtrains/advtrains/couple.lua b/advtrains/advtrains/couple.lua index eb1bc72..3693e84 100644 --- a/advtrains/advtrains/couple.lua +++ b/advtrains/advtrains/couple.lua @@ -31,6 +31,8 @@ minetest.register_entity("advtrains:discouple", { end, get_staticdata=function() return "DISCOUPLE" end, on_punch=function(self, player) + return advtrains.pcall(function() + --only if player owns at least one wagon next to this local own=player:get_player_name() if self.wagon.owner and self.wagon.owner==own and not self.wagon.lock_couples then @@ -54,8 +56,11 @@ minetest.register_entity("advtrains:discouple", { else minetest.chat_send_player(own, attrans("You need to own at least one neighboring wagon to destroy this couple.")) end + end) end, on_step=function(self, dtime) + return advtrains.pcall(function() + local t=os.clock() if not self.wagon then self.object:remove() @@ -77,6 +82,7 @@ minetest.register_entity("advtrains:discouple", { self.updatepct_timer=2 end atprintbm("discouple_step", t) + end) end, }) @@ -98,16 +104,21 @@ minetest.register_entity("advtrains:couple", { initial_sprite_basepos = {x=0, y=0}, is_couple=true, - on_activate=function(self, staticdata) + on_activate=function(self, staticdata) + return advtrains.pcall(function() + if staticdata=="COUPLE" then --couple entities have no right to exist further... atprint("Couple loaded from staticdata, destroying") self.object:remove() return end + end) end, get_staticdata=function(self) return "COUPLE" end, on_rightclick=function(self, clicker) + return advtrains.pcall(function() + if not self.train_id_1 or not self.train_id_2 then return end local id1, id2=self.train_id_1, self.train_id_2 @@ -128,8 +139,11 @@ minetest.register_entity("advtrains:couple", { end atprint("Coupled trains", id1, id2) self.object:remove() + end) end, on_step=function(self, dtime) + return advtrains.pcall(function() + local t=os.clock() if not self.train_id_1 or not self.train_id_2 then atprint("Couple: train ids not set!") self.object:remove() return end local train1=advtrains.trains[self.train_id_1] @@ -167,5 +181,6 @@ minetest.register_entity("advtrains:couple", { end end atprintbm("couple step", t) + end) end, }) diff --git a/advtrains/advtrains/init.lua b/advtrains/advtrains/init.lua index 970bbb6..9b7f31f 100644 --- a/advtrains/advtrains/init.lua +++ b/advtrains/advtrains/init.lua @@ -9,6 +9,29 @@ end advtrains = {trains={}, wagon_save={}, player_to_train_mapping={}} +--pcall +local no_action=true +function advtrains.pcall(fun) + if no_action then return end + + local succ, err, return1, return2, return3, return4=pcall(fun) + if not succ then + atwarn("Lua Error occured: ", err) + atwarn("Restoring saved state in 1 second...") + no_action=true + --read last save state and continue, as if server was restarted + for aoi, le in pairs(minetest.luaentities) do + if le.is_wagon then + le.object:remove() + end + end + minetest.after(1, advtrains.load) + else + return err, return1, return2, return3, return4 + end +end + + advtrains.modpath = minetest.get_modpath("advtrains") function advtrains.print_concat_table(a) @@ -94,6 +117,9 @@ dofile(advtrains.modpath.."/craft_items.lua") --load/save advtrains.fpath=minetest.get_worldpath().."/advtrains" + +function advtrains.load() + local file, err = io.open(advtrains.fpath, "r") if not file then minetest.log("error", " Failed to read advtrains save data from file "..advtrains.fpath..": "..(err or "Unknown Error")) @@ -142,6 +168,10 @@ else end file:close() end +no_action=false + +end +advtrains.load() advtrains.save = function() --atprint("saving") diff --git a/advtrains/advtrains/nodedb.lua b/advtrains/advtrains/nodedb.lua index ddd1a67..2fb3656 100644 --- a/advtrains/advtrains/nodedb.lua +++ b/advtrains/advtrains/nodedb.lua @@ -203,6 +203,8 @@ minetest.register_abm({ nodenames = {"group:save_in_nodedb"}, run_at_every_load = true, action = 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. @@ -227,14 +229,18 @@ minetest.register_abm({ atprint("nodedb: ", pos, "not in database") ndb.update(pos, node) end + end) end, interval=10, chance=1, }) minetest.register_on_dignode(function(pos, oldnode, digger) +return advtrains.pcall(function() + ndb.clear(pos) end) +end) function ndb.get_nodes() return ndb_nodes diff --git a/advtrains/advtrains/trackplacer.lua b/advtrains/advtrains/trackplacer.lua index e039800..5f9bdf7 100644 --- a/advtrains/advtrains/trackplacer.lua +++ b/advtrains/advtrains/trackplacer.lua @@ -187,6 +187,8 @@ function tp.register_track_placer(nnprefix, imgprefix, dispname) wield_image = imgprefix.."_placer.png", groups={}, on_place = function(itemstack, placer, pointed_thing) + return advtrains.pcall(function() + local name = placer:get_player_name() if not name then return itemstack @@ -207,6 +209,7 @@ function tp.register_track_placer(nnprefix, imgprefix, dispname) end end return itemstack + end) end, }) end @@ -220,6 +223,7 @@ minetest.register_craftitem("advtrains:trackworker",{ wield_image = "advtrains_trackworker.png", stack_max = 1, on_place = function(itemstack, placer, pointed_thing) + return advtrains.pcall(function() local name = placer:get_player_name() if not name then return @@ -260,8 +264,11 @@ minetest.register_craftitem("advtrains:trackworker",{ advtrains.ndb.swap_node(pos, {name=nnprefix.."_"..suffix..modext[modpos+1], param2=node.param2}) end end + end) end, on_use=function(itemstack, user, pointed_thing) + return advtrains.pcall(function() + local name = user:get_player_name() if not name then return @@ -292,6 +299,7 @@ minetest.register_craftitem("advtrains:trackworker",{ else atprint(name, dump(tp.tracks)) end + end) end, }) diff --git a/advtrains/advtrains/trainlogic.lua b/advtrains/advtrains/trainlogic.lua index d9edd6d..0caea0b 100644 --- a/advtrains/advtrains/trainlogic.lua +++ b/advtrains/advtrains/trainlogic.lua @@ -40,6 +40,8 @@ advtrains.save_interval=10 advtrains.save_timer=advtrains.save_interval minetest.register_globalstep(function(dtime_mt) +return advtrains.pcall(function() + --limit dtime: if trains move too far in one step, automation may cause stuck and wrongly braking trains local dtime=dtime_mt if dtime>0.2 then @@ -81,8 +83,11 @@ minetest.register_globalstep(function(dtime_mt) atprintbm("trainsteps", t) endstep() end) +end) minetest.register_on_joinplayer(function(player) +return advtrains.pcall(function() + local pname=player:get_player_name() local id=advtrains.player_to_train_mapping[pname] if id then @@ -101,8 +106,11 @@ minetest.register_on_joinplayer(function(player) end end end) +end) minetest.register_on_dieplayer(function(player) +return advtrains.pcall(function() + local pname=player:get_player_name() local id=advtrains.player_to_train_mapping[pname] if id then @@ -117,6 +125,7 @@ minetest.register_on_dieplayer(function(player) end end end) +end) --[[ train step structure: diff --git a/advtrains/advtrains/wagons.lua b/advtrains/advtrains/wagons.lua index 15a0ec7..2ceea86 100644 --- a/advtrains/advtrains/wagons.lua +++ b/advtrains/advtrains/wagons.lua @@ -50,6 +50,7 @@ function wagon:on_activate(sd_uid, dtime_s) end
function wagon:get_staticdata()
+return advtrains.pcall(function()
if not self:ensure_init() then return end
atprint("[wagon "..((self.unique_id and self.unique_id~="" and self.unique_id) or "no-id").."]: saving to wagon_save")
--serialize inventory, if it has one
@@ -63,6 +64,7 @@ function wagon:get_staticdata() advtrains.wagon_save[self.unique_id].name=nil
advtrains.wagon_save[self.unique_id].object=nil
return self.unique_id
+end)
end
--returns: uid of wagon
function wagon:init_new_instance(train_id, properties)
@@ -147,6 +149,7 @@ end -- Remove the wagon
function wagon:on_punch(puncher, time_from_last_punch, tool_capabilities, direction)
+return advtrains.pcall(function()
if not self:ensure_init() then return end
if not puncher or not puncher:is_player() then
return
@@ -177,6 +180,7 @@ function wagon:on_punch(puncher, time_from_last_punch, tool_capabilities, direct inv:add_item("main", item)
end
end
+end)
end
function wagon:destroy()
--some rules:
@@ -211,6 +215,8 @@ end function wagon:on_step(dtime)
+return advtrains.pcall(function()
+
if not self:ensure_init() then return end
local t=os.clock()
@@ -465,6 +471,7 @@ function wagon:on_step(dtime) self.old_acceleration_vector=accelerationvec
self.old_yaw=yaw
atprintbm("wagon step", t)
+end)
end
function advtrains.get_real_path_index(train, pit)
@@ -485,6 +492,8 @@ function advtrains.get_real_path_index(train, pit) end
function wagon:on_rightclick(clicker)
+return advtrains.pcall(function()
+
if not self:ensure_init() then return end
if not clicker or not clicker:is_player() then
return
@@ -564,6 +573,7 @@ function wagon:on_rightclick(clicker) self:show_get_on_form(pname)
end
end
+end)
end
function wagon:get_on(clicker, seatno)
@@ -708,6 +718,8 @@ function wagon:show_wagon_properties(pname) minetest.show_formspec(pname, "advtrains_prop_"..self.unique_id, form)
end
minetest.register_on_player_receive_fields(function(player, formname, fields)
+return advtrains.pcall(function()
+
local uid=string.match(formname, "^advtrains_geton_(.+)$")
if uid then
for _,wagon in pairs(minetest.luaentities) do
@@ -780,6 +792,7 @@ minetest.register_on_player_receive_fields(function(player, formname, fields) end
end
end)
+end)
function wagon:seating_from_key_helper(pname, fields, no)
local sgr=self.seats[no].group
for _,access in ipairs(self.seat_groups[sgr].access_to) do
@@ -841,6 +854,7 @@ function advtrains.register_wagon(sysname, prototype, desc, inv_img) stack_max = 1,
on_place = function(itemstack, placer, pointed_thing)
+ return advtrains.pcall(function()
if not pointed_thing.type == "node" then
return
end
@@ -876,6 +890,7 @@ function advtrains.register_wagon(sysname, prototype, desc, inv_img) end
return itemstack
+ end)
end,
})
end
diff --git a/advtrains/advtrains_luaautomation/interrupt.lua b/advtrains/advtrains_luaautomation/interrupt.lua index 4d59db5..b8fc879 100644 --- a/advtrains/advtrains_luaautomation/interrupt.lua +++ b/advtrains/advtrains_luaautomation/interrupt.lua @@ -22,6 +22,8 @@ function iq.add(t, pos, evtdata) end minetest.register_globalstep(function(dtime) +return advtrains.pcall(function() + if run then timer=timer + math.min(dtime, 0.2) for i=1,#queue do @@ -42,6 +44,7 @@ minetest.register_globalstep(function(dtime) end end end) +end) |