From 105e65e6ba1f6e61b9cc7fca189097764bb659c3 Mon Sep 17 00:00:00 2001 From: cheapie Date: Tue, 14 May 2024 21:10:10 -0500 Subject: Add multi-car digilines I/O module Supports all commands the normal digilines I/O module does, but with the addition of a 'carid' parameter that specifies the controller or dispatcher to execute the command on. Requires 'server' or 'protection_bypass' privs to place or configure as it can be used to change security settings on another player's elevator. --- digilines.lua | 339 ++++++++++++++++----------- textures/celevator_digilinesio_multi_top.png | Bin 0 -> 9636 bytes 2 files changed, 201 insertions(+), 138 deletions(-) create mode 100644 textures/celevator_digilinesio_multi_top.png diff --git a/digilines.lua b/digilines.lua index 1cdfd3f..9685adb 100644 --- a/digilines.lua +++ b/digilines.lua @@ -1,3 +1,147 @@ +local function handledigilines(pos,node,channel,msg) + local multi = node.name == "celevator:digilines_multi_io" + if msg == "GET" then msg = {command = "GET"} end + if type(msg) ~= "table" or type(msg.command) ~= "string" then return end + local meta = minetest.get_meta(pos) + local setchannel = meta:get_string("channel") + if setchannel ~= channel then return end + if multi and type(msg.carid) ~= "number" then return end + local carid = multi and msg.carid or meta:get_int("carid") + if carid == 0 then return end + local dmode = meta:get_int("dispatcher") == 1 + local carinfo = minetest.deserialize(celevator.storage:get_string(string.format("car%d",carid))) or {} + if multi then + dmode = carinfo.dispatcherpos + end + msg.command = string.lower(msg.command) + if dmode then + if not carinfo.dispatcherpos then return end + if not celevator.dispatcher.isdispatcher(carinfo.dispatcherpos) then return end + if msg.command == "get" then + local mem = minetest.deserialize(minetest.get_meta(carinfo.dispatcherpos):get_string("mem")) + if not mem then return end + local ret = { + upcalls = {}, + downcalls = {}, + fireserviceled = mem.fs1led, + } + for floor in pairs(mem.upcalls) do + ret.upcalls[floor] = { + eta = mem.upeta[floor] + } + if mem.assignedup[floor] then + for k,v in ipairs(mem.params.carids) do + if v == mem.assignedup[floor] then + ret.upcalls[floor].assignedcar = k + end + end + end + end + for floor in pairs(mem.dncalls) do + ret.downcalls[floor] = { + eta = mem.dneta[floor] + } + if mem.assigneddn[floor] then + for k,v in ipairs(mem.params.carids) do + if v == mem.assigneddn[floor] then + ret.downcalls[floor].assignedcar = k + end + end + end + end + digilines.receptor_send(pos,digilines.rules.default,channel,ret) + elseif msg.command == "upcall" and type(msg.floor) == "number" then + celevator.dispatcher.run(carinfo.dispatcherpos,{ + type = "remotemsg", + channel = "upcall", + msg = msg.floor, + }) + elseif msg.command == "downcall" and type(msg.floor) == "number" then + celevator.dispatcher.run(carinfo.dispatcherpos,{ + type = "remotemsg", + channel = "dncall", + msg = msg.floor, + }) + end + else + if not carinfo.controllerpos then return end + if not celevator.controller.iscontroller(carinfo.controllerpos) then return end + if msg.command == "get" then + local mem = minetest.deserialize(minetest.get_meta(carinfo.controllerpos):get_string("mem")) + if not mem then return end + local ret = { + carstate = mem.carstate, + doorstate = mem.doorstate, + carcalls = mem.carcalls, + upcalls = mem.upcalls, + swingupcalls = mem.swingupcalls, + groupupcalls = mem.groupupcalls, + downcalls = mem.dncalls, + swingdowncalls = mem.swingdncalls, + groupdowncalls = mem.groupdncalls, + fireserviceled = mem.fs1led, + switches = { + stop = mem.controllerstopsw, + machineroominspection = mem.controllerinspectsw, + cartopinspection = mem.cartopinspectsw, + capture = mem.capturesw, + test = mem.testsw, + fireservice1 = mem.fs1switch, + fireservice2 = mem.fs2sw, + indpedendent = mem.indsw, + light = mem.lightsw, + fan = mem.fansw, + }, + parameters = mem.params, + drivestatus = mem.drive.status, + direction = mem.direction, + } + digilines.receptor_send(pos,digilines.rules.default,channel,ret) + elseif msg.command == "carcall" and type(msg.floor) == "number" then + celevator.controller.run(carinfo.controllerpos,{ + type = "remotemsg", + channel = "carcall", + msg = msg.floor, + }) + elseif msg.command == "upcall" and type(msg.floor) == "number" then + celevator.controller.run(carinfo.controllerpos,{ + type = "remotemsg", + channel = "upcall", + msg = msg.floor, + }) + elseif msg.command == "downcall" and type(msg.floor) == "number" then + celevator.controller.run(carinfo.controllerpos,{ + type = "remotemsg", + channel = "dncall", + msg = msg.floor, + }) + elseif msg.command == "swingupcall" and type(msg.floor) == "number" then + celevator.controller.run(carinfo.controllerpos,{ + type = "remotemsg", + channel = "swingupcall", + msg = msg.floor, + }) + elseif msg.command == "swingdowncall" and type(msg.floor) == "number" then + celevator.controller.run(carinfo.controllerpos,{ + type = "remotemsg", + channel = "swingdncall", + msg = msg.floor, + }) + elseif msg.command == "security" and type(msg.floor) == "number" then + if msg.mode == "deny" or msg.mode == "auth" or not msg.mode then + celevator.controller.run(carinfo.controllerpos,{ + type = "remotemsg", + channel = "security", + msg = { + floor = msg.floor, + mode = msg.mode, + }, + }) + end + end + end +end + minetest.register_node("celevator:digilines_io",{ description = "Elevator Digilines Input/Output", tiles = { @@ -19,144 +163,7 @@ minetest.register_node("celevator:digilines_io",{ digilines = { receptor = {}, effector = { - action = function(pos,_,channel,msg) - if msg == "GET" then msg = {command = "GET"} end - if type(msg) ~= "table" or type(msg.command) ~= "string" then return end - local meta = minetest.get_meta(pos) - local setchannel = meta:get_string("channel") - if setchannel ~= channel then return end - local carid = meta:get_int("carid") - if carid == 0 then return end - local dmode = meta:get_int("dispatcher") == 1 - local carinfo = minetest.deserialize(celevator.storage:get_string(string.format("car%d",carid))) or {} - msg.command = string.lower(msg.command) - if dmode then - if not carinfo.dispatcherpos then return end - if not celevator.dispatcher.isdispatcher(carinfo.dispatcherpos) then return end - if msg.command == "get" then - local mem = minetest.deserialize(minetest.get_meta(carinfo.dispatcherpos):get_string("mem")) - if not mem then return end - local ret = { - upcalls = {}, - downcalls = {}, - fireserviceled = mem.fs1led, - } - for floor in pairs(mem.upcalls) do - ret.upcalls[floor] = { - eta = mem.upeta[floor] - } - if mem.assignedup[floor] then - for k,v in ipairs(mem.params.carids) do - if v == mem.assignedup[floor] then - ret.upcalls[floor].assignedcar = k - end - end - end - end - for floor in pairs(mem.dncalls) do - ret.downcalls[floor] = { - eta = mem.dneta[floor] - } - if mem.assigneddn[floor] then - for k,v in ipairs(mem.params.carids) do - if v == mem.assigneddn[floor] then - ret.downcalls[floor].assignedcar = k - end - end - end - end - digilines.receptor_send(pos,digilines.rules.default,channel,ret) - elseif msg.command == "upcall" and type(msg.floor) == "number" then - celevator.dispatcher.run(carinfo.dispatcherpos,{ - type = "remotemsg", - channel = "upcall", - msg = msg.floor, - }) - elseif msg.command == "downcall" and type(msg.floor) == "number" then - celevator.dispatcher.run(carinfo.dispatcherpos,{ - type = "remotemsg", - channel = "dncall", - msg = msg.floor, - }) - end - else - if not carinfo.controllerpos then return end - if not celevator.controller.iscontroller(carinfo.controllerpos) then return end - if msg.command == "get" then - local mem = minetest.deserialize(minetest.get_meta(carinfo.controllerpos):get_string("mem")) - if not mem then return end - local ret = { - carstate = mem.carstate, - doorstate = mem.doorstate, - carcalls = mem.carcalls, - upcalls = mem.upcalls, - swingupcalls = mem.swingupcalls, - groupupcalls = mem.groupupcalls, - downcalls = mem.dncalls, - swingdowncalls = mem.swingdncalls, - groupdowncalls = mem.groupdncalls, - fireserviceled = mem.fs1led, - switches = { - stop = mem.controllerstopsw, - machineroominspection = mem.controllerinspectsw, - cartopinspection = mem.cartopinspectsw, - capture = mem.capturesw, - test = mem.testsw, - fireservice1 = mem.fs1switch, - fireservice2 = mem.fs2sw, - indpedendent = mem.indsw, - light = mem.lightsw, - fan = mem.fansw, - }, - parameters = mem.params, - drivestatus = mem.drive.status, - direction = mem.direction, - } - digilines.receptor_send(pos,digilines.rules.default,channel,ret) - elseif msg.command == "carcall" and type(msg.floor) == "number" then - celevator.controller.run(carinfo.controllerpos,{ - type = "remotemsg", - channel = "carcall", - msg = msg.floor, - }) - elseif msg.command == "upcall" and type(msg.floor) == "number" then - celevator.controller.run(carinfo.controllerpos,{ - type = "remotemsg", - channel = "upcall", - msg = msg.floor, - }) - elseif msg.command == "downcall" and type(msg.floor) == "number" then - celevator.controller.run(carinfo.controllerpos,{ - type = "remotemsg", - channel = "dncall", - msg = msg.floor, - }) - elseif msg.command == "swingupcall" and type(msg.floor) == "number" then - celevator.controller.run(carinfo.controllerpos,{ - type = "remotemsg", - channel = "swingupcall", - msg = msg.floor, - }) - elseif msg.command == "swingdowncall" and type(msg.floor) == "number" then - celevator.controller.run(carinfo.controllerpos,{ - type = "remotemsg", - channel = "swingdncall", - msg = msg.floor, - }) - elseif msg.command == "security" and type(msg.floor) == "number" then - if msg.mode == "deny" or msg.mode == "auth" or not msg.mode then - celevator.controller.run(carinfo.controllerpos,{ - type = "remotemsg", - channel = "security", - msg = { - floor = msg.floor, - mode = msg.mode, - }, - }) - end - end - end - end, + action = handledigilines, }, }, after_place_node = function(pos) @@ -212,3 +219,59 @@ minetest.register_node("celevator:digilines_io",{ meta:set_string("infotext",infotext) end, }) + +minetest.register_node("celevator:digilines_multi_io",{ + description = "Elevator Digilines Multi-Car Input/Output", + tiles = { + "celevator_digilinesio_multi_top.png", + "celevator_cabinet_sides.png", + }, + groups = { + dig_immediate = 2, + not_in_creative_inventory = 1, + }, + paramtype = "light", + drawtype = "nodebox", + node_box = { + type = "fixed", + fixed = { + {-0.5,-0.5,-0.5,0.5,-0.47,0.5}, + {-0.438,-0.47,-0.438,0.438,-0.42,0.438}, + }, + }, + digilines = { + receptor = {}, + effector = { + action = handledigilines, + }, + }, + after_place_node = function(pos,player) + local name = player:get_player_name() + if not (minetest.check_player_privs(name,{protection_bypass=true}) or minetest.check_player_privs(name,{server=true})) then + if player:is_player() then + minetest.chat_send_player(name,"You need either the 'protection_bypass' or 'server' privilege to use this.") + minetest.record_protection_violation(pos,name) + end + minetest.remove_node(pos) + return + end + local meta = minetest.get_meta(pos) + local fs = "formspec_version[7]size[8,4.5]" + fs = fs.."field[0.5,0.5;7,1;channel;Channel;${channel}]" + fs = fs.."button_exit[2.5,2;3,1;save;Save]" + meta:set_string("formspec",fs) + end, + on_receive_fields = function(pos,_,fields,player) + local meta = minetest.get_meta(pos) + if not fields.save then return end + local name = player:get_player_name() + if not (minetest.check_player_privs(name,{protection_bypass=true}) or minetest.check_player_privs(name,{server=true})) then + if player:is_player() then + minetest.chat_send_player(name,"You need either the 'protection_bypass' or 'server' privilege to use this.") + minetest.record_protection_violation(pos,name) + end + return + end + meta:set_string("channel",fields.channel) + end, +}) diff --git a/textures/celevator_digilinesio_multi_top.png b/textures/celevator_digilinesio_multi_top.png new file mode 100644 index 0000000..9faa80e Binary files /dev/null and b/textures/celevator_digilinesio_multi_top.png differ -- cgit v1.2.3