From 224d5cbfd3a0403e40eef6604f418bc65e26423d Mon Sep 17 00:00:00 2001 From: orwell96 Date: Sun, 12 Aug 2018 17:23:52 +0200 Subject: [PATCH] Add 'interlocking' privilege and add security checks --- advtrains_interlocking/init.lua | 2 + advtrains_interlocking/route_prog.lua | 21 ++++++--- advtrains_interlocking/tcb_ts_ui.lua | 66 ++++++++++++++++++++++----- 3 files changed, 70 insertions(+), 19 deletions(-) diff --git a/advtrains_interlocking/init.lua b/advtrains_interlocking/init.lua index a67ea0f..19501b6 100644 --- a/advtrains_interlocking/init.lua +++ b/advtrains_interlocking/init.lua @@ -12,3 +12,5 @@ dofile(modpath.."train_related.lua") dofile(modpath.."route_prog.lua") dofile(modpath.."routesetting.lua") dofile(modpath.."tcb_ts_ui.lua") + +minetest.register_privilege("interlocking", {description = "Can set up track sections, routes and signals.", give_to_singleplayer = true}) diff --git a/advtrains_interlocking/route_prog.lua b/advtrains_interlocking/route_prog.lua index fb12548..15c2b6b 100644 --- a/advtrains_interlocking/route_prog.lua +++ b/advtrains_interlocking/route_prog.lua @@ -178,6 +178,10 @@ end local player_rte_prog = {} function advtrains.interlocking.init_route_prog(pname, sigd) + if not minetest.check_player_privs(pname, "interlocking") then + minetest.chat_send_player(pname, "Insufficient privileges to use this!") + return + end player_rte_prog[pname] = { origin = sigd, route = { @@ -204,6 +208,9 @@ end -- Central route programming punch callback minetest.register_on_punchnode(function(pos, node, player, pointed_thing) local pname = player:get_player_name() + if not minetest.check_player_privs(pname, "interlocking") then + return + end local rp = player_rte_prog[pname] if rp then -- determine what the punched node is @@ -275,7 +282,7 @@ minetest.register_chatcommand("at_rp_set", { params = "", -- Short parameter description description = "Completes route programming procedure", -- Full description - privs = {}, -- TODO + privs = {interlocking = true}, -- TODO func = function(pname, param) return advtrains.pcall(function() if param=="" then @@ -299,7 +306,7 @@ minetest.register_chatcommand("at_rp_set", player_rte_prog[pname] = nil return true, "Successfully programmed route" end - return false, "You were not programming a route!" + return false, "You are not programming a route!" end) end, }) @@ -308,7 +315,7 @@ minetest.register_chatcommand("at_rp_back", { params = "", -- Short parameter description description = "Remove last route segment", -- Full description - privs = {}, -- Require the "privs" privilege to run + privs = {interlocking = true}, -- Require the "privs" privilege to run func = function(pname, param) return advtrains.pcall(function() local rp = player_rte_prog[pname] @@ -320,7 +327,7 @@ minetest.register_chatcommand("at_rp_back", advtrains.interlocking.visualize_route(rp.origin, rp.route, "prog_"..pname) return true, "Route section "..(#rp.route.tcbpath+1).." removed." end - return false, "You were not programming a route!" + return false, "You are not programming a route!" end) end, }) @@ -328,7 +335,7 @@ minetest.register_chatcommand("at_rp_mark", { params = "", -- Short parameter description description = "Re-set route programming markers", -- Full description - privs = {}, -- TODO + privs = {interlocking = true}, -- TODO func = function(pname, param) return advtrains.pcall(function() local rp = player_rte_prog[pname] @@ -336,7 +343,7 @@ minetest.register_chatcommand("at_rp_mark", advtrains.interlocking.visualize_route(rp.origin, rp.route, "prog_"..pname) return true, "Redrawn route markers" end - return false, "You were not programming a route!" + return false, "You are not programming a route!" end) end, }) @@ -344,7 +351,7 @@ minetest.register_chatcommand("at_rp_discard", { params = "", -- Short parameter description description = "Discards the currently programmed route", -- Full description - privs = {}, -- Require the "privs" privilege to run + privs = {interlocking = true}, -- Require the "privs" privilege to run func = function(pname, param) return advtrains.pcall(function() player_rte_prog[pname] = nil diff --git a/advtrains_interlocking/tcb_ts_ui.lua b/advtrains_interlocking/tcb_ts_ui.lua index 3b9a3ac..5302b86 100644 --- a/advtrains_interlocking/tcb_ts_ui.lua +++ b/advtrains_interlocking/tcb_ts_ui.lua @@ -17,7 +17,7 @@ minetest.register_node("advtrains_interlocking:tcb_node", { drawtype = "mesh", paramtype="light", paramtype2="facedir", - walkable = true, + walkable = false, selection_box = { type = "fixed", fixed = {-1/6, -1/2, -1/6, 1/6, 1/4, 1/6}, @@ -37,9 +37,14 @@ minetest.register_node("advtrains_interlocking:tcb_node", { meta:set_string("infotext", "Unconfigured Track Circuit Break, right-click to assign.") end, on_rightclick = function(pos, node, player) + local pname = player:get_player_name() + if not minetest.check_player_privs(pname, "interlocking") then + minetest.chat_send_player(pname, "Insufficient privileges to use this!") + return + end + local meta = minetest.get_meta(pos) local tcbpts = meta:get_string("tcb_pos") - local pname = player:get_player_name() if tcbpts ~= "" then local tcbpos = minetest.string_to_pos(tcbpts) advtrains.interlocking.show_tcb_form(tcbpos, pname) @@ -60,11 +65,17 @@ minetest.register_node("advtrains_interlocking:tcb_node", { -- end --end, can_dig = function(pos, player) + local pname = player:get_player_name() + -- Those markers can only be dug when all adjacent TS's are set -- as EOI. local meta = minetest.get_meta(pos) local tcbpts = meta:get_string("tcb_pos") if tcbpts ~= "" then + if not minetest.check_player_privs(pname, "interlocking") then + minetest.chat_send_player(pname, "Insufficient privileges to use this!") + return + end local tcbpos = minetest.string_to_pos(tcbpts) local tcb = ildb.get_tcb(tcbpos) if not tcb then return true end @@ -88,6 +99,9 @@ minetest.register_node("advtrains_interlocking:tcb_node", { minetest.register_on_punchnode(function(pos, node, player, pointed_thing) local pname = player:get_player_name() + if not minetest.check_player_privs(pname, "interlocking") then + return + end -- TCB assignment local tcbnpos = players_assign_tcb[pname] if tcbnpos then @@ -175,6 +189,10 @@ end function advtrains.interlocking.show_tcb_form(pos, pname) + if not minetest.check_player_privs(pname, "interlocking") then + minetest.chat_send_player(pname, "Insufficient privileges to use this!") + return + end local tcb = ildb.get_tcb(pos) if not tcb then return end @@ -195,6 +213,9 @@ end minetest.register_on_player_receive_fields(function(player, formname, fields) local pname = player:get_player_name() + if not minetest.check_player_privs(pname, "interlocking") then + return + end local pts = string.match(formname, "^at_il_tcbconfig_(.+)$") local pos if pts then @@ -268,6 +289,10 @@ end) local ts_pselidx = {} function advtrains.interlocking.show_ts_form(ts_id, pname, sel_tcb) + if not minetest.check_player_privs(pname, "interlocking") then + minetest.chat_send_player(pname, "Insufficient privileges to use this!") + return + end local ts = ildb.get_ts(ts_id) if not ts_id then return end @@ -324,6 +349,9 @@ end minetest.register_on_player_receive_fields(function(player, formname, fields) local pname = player:get_player_name() + if not minetest.check_player_privs(pname, "interlocking") then + return + end -- independent of the formspec, clear this whenever some formspec event happens local tpsi = ts_pselidx[pname] ts_pselidx[pname] = nil @@ -444,6 +472,11 @@ end local sig_pselidx = {} function advtrains.interlocking.show_signalling_form(sigd, pname, sel_rte) + if not minetest.check_player_privs(pname, "train_operator") then + minetest.chat_send_player(pname, "Insufficient privileges to use this!") + return + end + local hasprivs = minetest.check_player_privs(pname, "interlocking") local tcbs = ildb.get_tcbs(sigd) if not tcbs.signal then return end @@ -489,12 +522,15 @@ function advtrains.interlocking.show_signalling_form(sigd, pname, sel_rte) if sel_rte then form = form.."button[0.5,6; 5,1;setroute;Set Route]" form = form.."button[0.5,7;2,1;dsproute;Show]" - form = form.."button[2.5,7;1,1;delroute;Delete]" - form = form.."button[3.5,7;2,1;renroute;Rename]" + if hasprivs then + form = form.."button[2.5,7;1,1;delroute;Delete]" + form = form.."button[3.5,7;2,1;renroute;Rename]" + end + end + if hasprivs then + form = form.."button[0.5,8;2.5,1;newroute;New Route]" + form = form.."button[ 3,8;2.5,1;unassign;Unassign Signal]" end - form = form.."button[0.5,8;2.5,1;newroute;New Route]" - form = form.."button[ 3,8;2.5,1;unassign;Unassign Signal]" - end sig_pselidx[pname] = sel_rte minetest.show_formspec(pname, "at_il_signalling_"..minetest.pos_to_string(sigd.p).."_"..sigd.s, form) @@ -503,6 +539,10 @@ end minetest.register_on_player_receive_fields(function(player, formname, fields) local pname = player:get_player_name() + if not minetest.check_player_privs(pname, "train_operator") then + return + end + local hasprivs = minetest.check_player_privs(pname, "interlocking") -- independent of the formspec, clear this whenever some formspec event happens local tpsi = sig_pselidx[pname] @@ -527,7 +567,7 @@ minetest.register_on_player_receive_fields(function(player, formname, fields) elseif tpsi then sel_rte = tpsi end - if fields.setname and fields.name then + if fields.setname and fields.name and hasprivs then tcbs.signal_name = fields.name end if tcbs.routeset and fields.cancelroute then @@ -535,7 +575,7 @@ minetest.register_on_player_receive_fields(function(player, formname, fields) ilrs.update_route(sigd, tcbs, nil, true) end if not tcbs.routeset then - if fields.newroute then + if fields.newroute and hasprivs then advtrains.interlocking.init_route_prog(pname, sigd) minetest.close_formspec(pname, formname) return @@ -549,19 +589,19 @@ minetest.register_on_player_receive_fields(function(player, formname, fields) advtrains.interlocking.visualize_route(sigd, tcbs.routes[sel_rte], "disp_"..t) minetest.after(10, function() advtrains.interlocking.clear_visu_context("disp_"..t) end) end - if fields.renroute then + if fields.renroute and hasprivs then local rte = tcbs.routes[sel_rte] minetest.show_formspec(pname, formname.."_renroute_"..sel_rte, "field[name;Enter new route name;"..rte.name.."]") return end - if fields.delroute then + if fields.delroute and hasprivs then table.remove(tcbs.routes, sel_rte) sel_rte = nil end end end - if fields.unassign then + if fields.unassign and hasprivs then -- unassigning the signal from the tcbs -- only when no route is set. -- Routes and name remain saved, in case the player wants to reassign a new signal @@ -586,6 +626,8 @@ minetest.register_on_player_receive_fields(function(player, formname, fields) return end + + if not hasprivs then return end -- rename route local rind, rte_id pts, connids, rind = string.match(formname, "^at_il_signalling_([^_]+)_(%d)_renroute_(%d+)$")