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 | |
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
-rw-r--r-- | advtrains.zip | bin | 4991936 -> 4992304 bytes | |||
-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 |
9 files changed, 93 insertions, 1 deletions
diff --git a/advtrains.zip b/advtrains.zip Binary files differindex 02ab8b1..eb47749 100644 --- a/advtrains.zip +++ b/advtrains.zip 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) |