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:
@@ -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()
|
||||
|
Reference in New Issue
Block a user