1
0
mirror of https://github.com/AR2000AR/openComputers_codes.git synced 2025-09-08 22:51:14 +02:00

[doorCtrl] refactoring

This commit is contained in:
2023-01-13 22:24:38 +01:00
parent 425240fcca
commit 6529af6ad8

View File

@@ -17,29 +17,36 @@ local text = require 'text'
local CONFIG_FILE = '/etc/doorCtrl.conf'
local LOG_FILE = '/tmp/doorCtrl.log'
local args,ops = shell.parse(...)
local event_touch
local event_term
local event_keyboard
local run = true
local args, ops = shell.parse(...)
--get the keys from a table
local function getKeys(sourceArray)
local keyset = {}
for k,v in pairs(sourceArray) do
table.insert(keyset,k)
for k, v in pairs(sourceArray) do
table.insert(keyset, k)
end
return keyset;
return keyset;
end
--save the config file
local function saveConfig(newConf)
local confFile = io.open('/etc/doorCtrl.conf','w')
local confFile = io.open('/etc/doorCtrl.conf', 'w')
assert(confFile, 'How did we get here !? (file could not be written')
confFile:write(serialization.serialize(newConf))
confFile:close()
end
--verbose out
local function verbose(...)
if(ops.v) then
print(...)
local lf = io.open(LOG_FILE,'a')
if (ops.v) then
print(...)
local lf = io.open(LOG_FILE, 'a')
assert(lf, 'How did we get here !? (file could not be written')
lf:write(...)
lf:close()
end
@@ -50,36 +57,39 @@ local function isValidSide(side)
return not (s == nil or s == "unknown")
end
function readPassword()
cursorPosX,cursorPosY = term.getCursor()
password = ""
garble = ""
event_t = event.listen("interrupted",function(...)
event.cancel(event_t)
event.cancel(keyboard_event)
local function readPassword()
local cursorPosX, cursorPosY = term.getCursor()
local password = ""
local garble = ""
local lastKey
event.listen("interrupted", function(...)
event.cancel(event_keyboard)
return false
end)
keyboard_event = event.listen("key_down",function(self,uuid,char,code,player)
if (char == 8) then
password = string.sub(password,1,-2)
garble = string.sub(garble,1,-2)
term.setCursor(cursorPosX,cursorPosY)
garble = garble.." "
event_keyboard = event.listen("key_down", function(self, uuid, char, code, player)
if (char == 8) then
password = string.sub(password, 1, -2)
garble = string.sub(garble, 1, -2)
term.setCursor(cursorPosX, cursorPosY)
garble = garble .. " "
term.write(garble)
garble = string.sub(garble,1,-2)
elseif(char ~= 13) then
password = password..string.char(char)
garble = garble.."*"
garble = string.sub(garble, 1, -2)
elseif (char ~= 13) then
password = password .. string.char(char)
garble = garble .. "*"
term.write("*")
end
lastKey = char
end)
lastKey = nil
while lastKey ~= 13 do
---@diagnostic disable-next-line: undefined-field
os.sleep()
end
event.cancel(keyboard_event)
event.cancel(event_keyboard)
return password
end
--Door class
local Door = class.newClass("Door")
Door.private = {}
@@ -88,67 +98,69 @@ Door.private.component = nil
Door.private.side = nil
Door.private.default = false
Door.private.inverted = false
Door.constructor = function(self,name,component,side,default,inverted)
Door.constructor = function(self, name, component, side, default, inverted)
self:setName(name)
self:setComponent(component)
self:setSide(side)
self:setDefault(default)
self:setInverted(inverted)
end
Door.setName = function (self,name) self.private.name = name end
Door.setName = function(self, name) self.private.name = name end
Door.getName = function(self) return self.private.name end
Door.setComponent = function (self,newComponent) self.private.component = component.proxy(newComponent) end
Door.setComponent = function(self, newComponent) self.private.component = component.proxy(newComponent) end
Door.getComponent = function(self) return self.private.component.address end
Door.setSide = function (self,side)
if(not tonumber(side)) then
self.private.side = sides[side]
Door.setSide = function(self, side)
if (not tonumber(side)) then
self.private.side = sides[side]
else
self.private.side = side
end
end
Door.getSide = function(self) return self.private.side end
Door.setDefault = function (self,default) self.private.default = default end
Door.setDefault = function(self, default) self.private.default = default end
Door.getDefault = function(self) return self.private.default end
Door.setInverted = function (self,inverted) self.private.inverted = inverted end
Door.setInverted = function(self, inverted) self.private.inverted = inverted end
Door.isInverted = function(self) return self.private.inverted end
Door.open = function (self)
Door.open = function(self)
local onLevel = 15
if(self:isInverted()) then onLevel = 0 end
self.private.component.setOutput(self:getSide(),onLevel)
if (self:isInverted()) then onLevel = 0 end
self.private.component.setOutput(self:getSide(), onLevel)
end
Door.close = function (self)
Door.close = function(self)
local offLevel = 0
if(self:isInverted()) then offLevel = 15 end
self.private.component.setOutput(self:getSide(),offLevel)
if (self:isInverted()) then offLevel = 15 end
self.private.component.setOutput(self:getSide(), offLevel)
end
Door.isOpen = function (self)
Door.isOpen = function(self)
verbose(self:getSide())
local isOn = (self.private.component.getOutput(self:getSide()) == 15)
if(self:isInverted()) then isOn = not isOn end
if (self:isInverted()) then isOn = not isOn end
return isOn
end
Door.isClosed = function(self) return not self:isOpen() end
Door.toggle = function(self)
if(self:isOpen()) then
self:close()
else
self:open()
end
Door.toggle = function(self)
if (self:isOpen()) then
self:close()
else
self:open()
end
end
Door.set = function(self,open) if(open) then self:open() else self:close() end end
Door.set = function(self, open) if (open) then self:open() else self:close() end end
-- get redstone io list
local redstoneIO = getKeys(component.list("redstone"))
-- load config
local configRaw = "{}"
if(filesystem.exists(CONFIG_FILE)) then
local confFile = io.open(CONFIG_FILE,'r')
if (filesystem.exists(CONFIG_FILE)) then
local confFile = io.open(CONFIG_FILE, 'r')
assert(confFile, "How did we failed to open a existing file ???")
configRaw = confFile:read('*a')
confFile:close()
else
local confFile = io.open(CONFIG_FILE,'w')
configRaw = serialization.serialize({doors={},adminCode="",whitelist={},applyDefault=true})
local confFile = io.open(CONFIG_FILE, 'w')
configRaw = serialization.serialize({doors = {}, adminCode = "", whitelist = {}, applyDefault = true})
assert(confFile, "How did we fail to create " .. CONFIG_FILE .. " ???")
confFile:write(configRaw)
confFile:close()
end
@@ -170,28 +182,29 @@ local config = serialization.unserialize(configRaw)
-- creating doors
local doors = {}
if(#config.doors > 0) then
if (#config.doors > 0) then
for i, val in ipairs(config.doors) do
table.insert(doors,Door(val.name,val.component,val.side,val.default,val.inv))
table.insert(doors, Door(val.name, val.component, val.side, val.default, val.inv))
end
end
print("Found "..#doors.." for "..#redstoneIO.." redstone I/O")
print("Found " .. #doors .. " for " .. #redstoneIO .. " redstone I/O")
---@diagnostic disable-next-line: undefined-field
os.sleep(2)
if(ops.config or ops.c) then
if (ops.config or ops.c) then
local run = true
--password check
local try = 0
if(config.adminCode ~= "") then
if (config.adminCode ~= "") then
while try < 3 do
io.write("Admin password :")
local password = readPassword()
if(password == config.adminCode) then break
else try = try+1
if (password == config.adminCode) then break
else try = try + 1
end
end
if(try >= 3) then
if (try >= 3) then
print("Too many wrong passwords")
os.exit(1)
end
@@ -201,28 +214,28 @@ if(ops.config or ops.c) then
term.clear()
--config mod
for i, door in ipairs(doors) do
print(i.." : "..door:getName().." "..string.sub(door:getComponent(),1,8).." default("..tostring(door:getDefault())..") Opened("..tostring(door:isOpen())..")")
print(i .. " : " .. door:getName() .. " " .. string.sub(door:getComponent(), 1, 8) .. " default(" .. tostring(door:getDefault()) .. ") Opened(" .. tostring(door:isOpen()) .. ")")
end
print("")
print("n : New door")
print("d : Apply default (current value : "..tostring(config.applyDefault)..")")
print("d : Apply default (current value : " .. tostring(config.applyDefault) .. ")")
print("s : Security")
print("q : Exit")
io.write(">")
local op = io.read()
if(tonumber(op)) then
if (tonumber(op)) then
op = tonumber(op)
if(op >= 1 and op <= #doors) then
if (op >= 1 and op <= #doors) then
local door = doors[op]
local doorID = op
while true do
term.clear()
print("Name : "..door:getName())
print("Component : "..door:getComponent())
print("Side : "..sides[door:getSide()])
print("Default : "..(door:getDefault() and "open" or "closed"))
print("Inverted : "..tostring(door:isInverted()))
print("Opened : "..tostring(door:isOpen()))
print("Name : " .. door:getName())
print("Component : " .. door:getComponent())
print("Side : " .. sides[door:getSide()])
print("Default : " .. (door:getDefault() and "open" or "closed"))
print("Inverted : " .. tostring(door:isInverted()))
print("Opened : " .. tostring(door:isOpen()))
print("")
print("r : Rename")
print("d : Default")
@@ -231,86 +244,87 @@ if(ops.config or ops.c) then
print("t : Toggle")
print("b : Back")
print("q : Exit")
io.write(">"..doorID..">")
io.write(">" .. doorID .. ">")
local op = io.read()
if(op == "r") then
io.write(">"..doorID..">r>["..door:getName().."]")
if (op == "r") then
io.write(">" .. doorID .. ">r>[" .. door:getName() .. "]")
local newName = io.read()
if(newName ~= "") then
if (newName ~= "") then
config.doors[doorID].name = newName
door:setName(newName)
saveConfig(config)
end
elseif(op == "d") then
elseif (op == "d") then
config.doors[doorID].default = not door:getDefault()
door:setDefault(not door:getDefault())
saveConfig(config)
elseif(op == "i") then
elseif (op == "i") then
config.doors[doorID].inv = not door:isInverted()
door:setInverted(not door:isInverted())
saveConfig(config)
elseif(op == "s") then
io.write(">"..doorID..">s>["..sides[door:getSide()].."]")
elseif (op == "s") then
io.write(">" .. doorID .. ">s>[" .. sides[door:getSide()] .. "]")
local newSide = io.read()
if(isValidSide(newSide)) then
if (isValidSide(newSide)) then
door:setSide(sides[newSide])
config.doors[doorID].side = sides[door:getSide()]
saveConfig(config)
end
elseif(op == "t") then door:toggle()
elseif(op == "b") then break
elseif(op == "q") then run = false break
elseif (op == "t") then door:toggle()
elseif (op == "b") then break
elseif (op == "q") then run = false break
end
end
end
elseif(op == "n") then
elseif (op == "n") then
for i, comp in ipairs(redstoneIO) do
print(i.." : "..comp)
print(i .. " : " .. comp)
end
local compNb = 0
while (compNb < 1 or compNb > #redstoneIO) do
io.write(">n>")
---@diagnostic disable-next-line: cast-local-type
compNb = tonumber(io.read());
end
local name = ""
print("chose a name")
while (name == "") do
io.write(">n>"..compNb..">")
io.write(">n>" .. compNb .. ">")
name = io.read();
end
print("chose a side")
local side = nil
while not isValidSide(side) do
io.write(">n>"..compNb..">"..name..">")
io.write(">n>" .. compNb .. ">" .. name .. ">")
side = io.read()
end
local door = Door(name,redstoneIO[compNb],side,false,false)
table.insert(doors,door)
table.insert(config.doors,{name=name,component=redstoneIO[compNb],side=sides[door:getSide()],default=false,inv=false})
local door = Door(name, redstoneIO[compNb], side, false, false)
table.insert(doors, door)
table.insert(config.doors, {name = name, component = redstoneIO[compNb], side = sides[door:getSide()], default = false, inv = false})
saveConfig(config)
elseif(op == "d") then
elseif (op == "d") then
config.applyDefault = not config.applyDefault
saveConfig(config)
elseif(op == "s") then
elseif (op == "s") then
while true do
term.clear()
print("Whiteliste : ")
for i, name in ipairs(config.whitelist) do
io.write(text.padRight(i.." : "..name,19))
if(i%4 == 0) then io.write("\n") end
io.write(text.padRight(i .. " : " .. name, 19))
if (i % 4 == 0) then io.write("\n") end
end
if(#config.whitelist %4 ~= 0) then io.write("\n") end
if (#config.whitelist % 4 ~= 0) then io.write("\n") end
print("")
if(#config.whitelist > 0) then
print(text.padRight("[1-"..#config.whitelist.."]",7)..": Remove user")
if (#config.whitelist > 0) then
print(text.padRight("[1-" .. #config.whitelist .. "]", 7) .. ": Remove user")
end
print("n : New user")
print("p : Change password ("..((config.adminCode ~= "") and "set" or "unset")..")")
print("p : Change password (" .. ((config.adminCode ~= "") and "set" or "unset") .. ")")
print("b : Back")
print("q : Exit")
io.write(">s>")
op = io.read()
if(op == "p") then
if (op == "p") then
print("Enter new password")
io.write(">s>p>")
local p1 = readPassword()
@@ -318,30 +332,30 @@ if(ops.config or ops.c) then
print("Confirm password")
io.write(">s>p>")
local p2 = readPassword()
if(p1 == p2) then
if (p1 == p2) then
config.adminCode = p1
saveConfig(config)
else
print("Password do not match. Abodring")
end
elseif(op == "n") then
elseif (op == "n") then
print("Enter user name")
io.write(">s>n>")
local name = io.read()
if(name ~= "") then
table.insert(config.whitelist,name)
if (name ~= "") then
table.insert(config.whitelist, name)
saveConfig(config)
else
print("No name given. Abording")
end
elseif(tonumber(op) and tonumber(op) > 1 and tonumber(op) <= #config.whitelist) then
table.remove(config.whitelist,tonumber(op))
elseif (tonumber(op) and tonumber(op) > 1 and tonumber(op) <= #config.whitelist) then
table.remove(config.whitelist, tonumber(op))
saveConfig(config)
elseif(op == "b") then break
elseif(op == "q") then run = false break
elseif (op == "b") then break
elseif (op == "q") then run = false break
end
end
elseif(op == "q") then
elseif (op == "q") then
run = false
end
end
@@ -356,31 +370,31 @@ else
end
event_touch = nil
event_term = event.listen("interrupted",closeGUI)
event_term = event.listen("interrupted", closeGUI)
local function buttonCallback(self,eventName,uuid,x,y,button,playerName)
local function buttonCallback(self, eventName, uuid, x, y, button, playerName)
local allowed = false
if(#config.whitelist > 0) then
for index,item in ipairs(config.whitelist) do
if(item == playerName) then allowed = true break end
if (#config.whitelist > 0) then
for index, item in ipairs(config.whitelist) do
if (item == playerName) then allowed = true break end
end
else
allowed = true
end
if(not allowed) then return end
if (not allowed) then return end
verbose(self.door:getName())
beep()
self.door:toggle()
if(self.door:isOpen()) then
if (self.door:isOpen()) then
self:setBackground(0x00ff00)
else
self:setBackground(0xff0000)
end
self:draw()
if(button == 1) then
event.timer(1, function ()
if (button == 1) then
event.timer(1, function()
self.door:toggle()
if(self.door:isOpen()) then
if (self.door:isOpen()) then
self:setBackground(0x00ff00)
else
self:setBackground(0xff0000)
@@ -390,12 +404,10 @@ else
end
end
--normal mod
--normal mode
local mainScreen = gui.Screen();
event_touch = event.listen("touch",function(...) mainScreen:trigger(...) end)
local background = gui.widget.Rectangle(1,1,80,25,0xc3c3c3)
event_touch = event.listen("touch", function(...) mainScreen:trigger(...) end)
local background = gui.widget.Rectangle(1, 1, 80, 25, 0xc3c3c3)
background:enable(false)
mainScreen:addChild(background)
@@ -404,17 +416,17 @@ else
local x = 2
local y = 3
for i,door in ipairs(doors) do
local doorText = gui.widget.Text(x,y,37,1,0xffffff,door:getName())
for i, door in ipairs(doors) do
local doorText = gui.widget.Text(x, y, 37, 1, 0xffffff, door:getName())
--calculate the position of the next button
if(i%2 == 1) then
if (i % 2 == 1) then
x = 42
else
x = 2
y = y+2
y = y + 2
end
if(config.applyDefault) then door:set(door:getDefault()) end
if(door:isOpen()) then
if (config.applyDefault) then door:set(door:getDefault()) end
if (door:isOpen()) then
doorText:setBackground(0x00ff00)
else
doorText:setBackground(0xff0000)
@@ -425,8 +437,8 @@ else
end
mainScreen:draw()
run = true
while run do
---@diagnostic disable-next-line: undefined-field
os.sleep()
end
closeGUI()