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
This commit is contained in:
parent
337db2a573
commit
f42b01c74b
BIN
advtrains.zip
BIN
advtrains.zip
Binary file not shown.
|
@ -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)
|
||||
|
|
|
@ -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,
|
||||
})
|
||||
|
||||
|
@ -99,15 +105,20 @@ minetest.register_entity("advtrains:couple", {
|
|||
|
||||
is_couple=true,
|
||||
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,
|
||||
})
|
||||
|
|
|
@ -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")
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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,
|
||||
})
|
||||
|
||||
|
|
|
@ -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:
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
|
||||
|
||||
|
||||
|
|
Loading…
Reference in New Issue