added Iris Password system

This commit is contained in:
2025-12-29 00:27:25 -05:00
parent dce10bb02e
commit f493405b48
4 changed files with 332 additions and 73 deletions

View File

@ -27,6 +27,19 @@ config.autoCloseIrisOnIncoming = true
config.irisCloseDelay = 0.1 -- seconds before closing iris on incoming
config.autoOpenIrisAfterDisconnect = true
-- Iris password (set to nil to disable remote password unlock)
config.irisPassword = "1234"
---------------------------------------------
-- MESSAGING
---------------------------------------------
-- Program version (sent to remote gates when connection established)
config.programVersion = "1.0"
-- Enable computer-to-computer messaging through stargate
config.enableMessaging = true
---------------------------------------------
-- SECURITY
---------------------------------------------

View File

@ -219,4 +219,74 @@ function display.showMainMenu()
display.drawIrisStatus()
end
---------------------------------------------
-- PASSWORD PROMPT
---------------------------------------------
function display.showPasswordPrompt()
mon.setBackgroundColor(colors.black)
mon.clear()
mon.setTextScale(1)
mon.setBackgroundColor(colors.blue)
mon.setCursorPos(7, 2)
mon.write("IRIS PASSWORD")
mon.setBackgroundColor(colors.black)
mon.setCursorPos(7, 5)
mon.write("Enter Code:")
-- Draw number pad (3x4 grid)
local oldterm = term.redirect(mon)
-- Numbers 1-9
local row = 7
for i = 1, 9 do
local col = 8 + ((i - 1) % 3) * 5
if (i - 1) % 3 == 0 and i > 1 then
row = row + 3
end
paintutils.drawFilledBox(col, row, col + 3, row + 2, colors.green)
mon.setCursorPos(col + 1, row + 1)
mon.write(tostring(i))
end
-- Bottom row: Clear (0), Zero, Enter
paintutils.drawFilledBox(8, 16, 11, 18, colors.red)
mon.setCursorPos(9, 17)
mon.write("CLR")
paintutils.drawFilledBox(13, 16, 16, 18, colors.green)
mon.setCursorPos(14, 17)
mon.write("0")
paintutils.drawFilledBox(18, 16, 21, 18, colors.blue)
mon.setCursorPos(18, 17)
mon.write("OK")
term.redirect(oldterm)
display.drawIrisStatus()
end
function display.updatePasswordDisplay(password)
mon.setBackgroundColor(colors.black)
mon.setCursorPos(7, 6)
mon.write(string.rep("*", #password) .. " ")
end
function display.showPasswordResult(success)
mon.setBackgroundColor(colors.black)
mon.setCursorPos(7, 10)
if success then
mon.setTextColor(colors.green)
mon.write("ACCESS GRANTED")
mon.setTextColor(colors.white)
else
mon.setTextColor(colors.red)
mon.write("ACCESS DENIED")
mon.setTextColor(colors.white)
end
sleep(2)
end
return display

View File

@ -128,20 +128,90 @@ local function Paratimeout()
return 2
end
local function GetMessage()
local _, _, message = os.pullEvent("stargate_message_received")
return message
end
local function HandlePasswordEntry()
-- Display password prompt
display.showPasswordPrompt()
local password = ""
local entering = true
while entering do
local x, y = GetClick()
-- Check number buttons (1-9)
if y >= 7 and y <= 15 then
local row = math.floor((y - 7) / 3)
local col = math.floor((x - 8) / 5)
if col >= 0 and col <= 2 and row >= 0 and row <= 2 then
local num = row * 3 + col + 1
if num >= 1 and num <= 9 then
password = password .. tostring(num)
display.updatePasswordDisplay(password)
end
end
end
-- Check bottom row buttons
if y >= 16 and y <= 18 then
if x >= 8 and x <= 11 then
-- Clear button
password = ""
display.updatePasswordDisplay(password)
elseif x >= 13 and x <= 16 then
-- Zero button
password = password .. "0"
display.updatePasswordDisplay(password)
elseif x >= 18 and x <= 21 then
-- OK button - submit password
entering = false
end
end
end
-- Send password attempt
utils.sendPasswordAttempt(password)
return password
end
local function HandleIncomingPasswordRequest(password)
-- Check if password matches
if config.irisPassword and password == config.irisPassword then
utils.log("Correct password received, opening iris")
utils.openIris()
utils.sendPasswordResponse(true)
return true
else
utils.log("Incorrect password received: " .. password)
utils.sendPasswordResponse(false)
return false
end
end
local function MonitorRemoteIris()
-- Continuously monitor remote iris state while connected
local lastIrisState = nil
while gate.isStargateConnected() do
sleep(2) -- Check every 2 seconds
sleep(0.5) -- Check every half second
if transceiver then
local remoteIrisState = transceiver.checkConnectedShielding()
-- Only update display if state changed
if remoteIrisState ~= lastIrisState then
if remoteIrisState and remoteIrisState > 0 then
-- Remote iris closed or closing
if remoteIrisState == 100 then
utils.log("ALERT: Remote iris fully closed during connection!")
else
utils.log("ALERT: Remote iris closing: " .. remoteIrisState .. "%")
utils.log("ALERT: Remote iris moving: " .. remoteIrisState .. "%")
end
mon.setBackgroundColor(colors.red)
@ -158,6 +228,16 @@ local function MonitorRemoteIris()
mon.setCursorPos(3, 10)
mon.write("Connection unsafe")
display.drawIrisStatus()
else
-- Remote iris is open (0 or nil)
if lastIrisState and lastIrisState > 0 then
-- Iris just opened
utils.log("Remote iris opened - connection safe")
end
display.showConnected(destAddressname, destAddress)
end
lastIrisState = remoteIrisState
end
end
end
@ -187,6 +267,10 @@ local function handleIncomingWormhole()
-- Show incoming connection status
display.showIncoming(addressString, allowed, reason)
-- Send version message to remote gate
sleep(0.5) -- Brief delay to ensure connection is stable
utils.sendVersionMessage()
-- Handle iris
if config.autoCloseIrisOnIncoming then
sleep(config.irisCloseDelay)
@ -201,16 +285,27 @@ local function handleIncomingWormhole()
disconnect = false
while (disconnect == false) do
-- parallel.waitForAny runs multiple functions at the same time and returns which one finished first
-- Here we're watching for 3 things simultaneously:
-- Here we're watching for 4 things simultaneously:
-- 1 = EntityRead (someone/something came through the gate)
-- 2 = DisconnectCheck (gate disconnected on its own)
-- 3 = GetMessage (received a message from remote gate)
-- ParaDisconnect (user clicked screen to manually disconnect)
-- Whichever happens first, that function returns and we handle it
local incomingcheck = parallel.waitForAny(EntityRead, DisconnectCheck, ParaDisconnect)
if (incomingcheck == 1) then
local result = parallel.waitForAny(EntityRead, DisconnectCheck, GetMessage, ParaDisconnect)
if (result == 1) then
display.showEntity(incomingEntityType, incomingEntityName, allowed)
incomingEntityType = ""
incomingEntityName = ""
elseif (result == 3) then
-- Received a message
local message = GetMessage()
utils.log("Received message: " .. message)
-- Check if it's a password attempt
if message:sub(1, 14) == "IRIS_PASSWORD:" then
local password = message:sub(15)
HandleIncomingPasswordRequest(password)
end
else
disconnect = true
end
@ -223,7 +318,7 @@ end
---------------------------------------------
local function dialGate(address)
tmp = deepCopy(address)
tmp = utils.deepCopy(address)
table.remove(tmp)
utils.log("Dialing: " .. gate.addressToString(tmp))
@ -352,7 +447,6 @@ local function selectCategory()
mon.write("no gates available")
sleep(5)
end
elseif (taby >= 2) and (taby <= 6) and ((tabx >= 16) and (tabx <= 27)) then
if #addresses.playerGates ~= 0 then
mon.setBackgroundColor(colors.black)
@ -371,7 +465,6 @@ local function selectCategory()
mon.write("no gates available")
sleep(5)
end
elseif (((taby >= 8) and (taby <= 12)) and ((tabx >= 2) and (tabx <= 13))) and (config.canAccessHazardGates == true) then
if (#addresses.hazardGates ~= 0) and (config.canAccessHazardGates == true) then
mon.setBackgroundColor(colors.black)
@ -390,7 +483,6 @@ local function selectCategory()
mon.write("no gates available")
sleep(5)
end
elseif (taby >= 17) and (tabx >= 23) then
state = false
totalstate = false
@ -409,12 +501,59 @@ local function handleOutgoingDial()
os.pullEvent("stargate_outgoing_wormhole")
-- Wait briefly for version message from remote gate
local remoteHasComputer = false
local function WaitForVersion()
sleep(1) -- Wait up to 1 second for version message
return nil
end
local result = parallel.waitForAny(GetMessage, WaitForVersion)
if result == 1 then
local message = GetMessage()
if message:sub(1, 6) == "SGCS_V" then
remoteHasComputer = true
local version = message:sub(7)
utils.log("Remote gate has control system version " .. version)
end
end
-- Check if remote iris is closed using transceiver
local remoteIrisState = nil
if transceiver then
remoteIrisState = transceiver.checkConnectedShielding()
end
-- If remote has computer + iris closed, offer password entry
if remoteHasComputer and remoteIrisState and remoteIrisState > 0 then
utils.log("Remote iris closed but computer detected - showing password prompt")
local password = HandlePasswordEntry()
-- Wait for response
local function WaitForResponse()
sleep(3) -- Wait up to 3 seconds for response
return nil
end
result = parallel.waitForAny(GetMessage, WaitForResponse)
if result == 1 then
local response = GetMessage()
if response == "IRIS_OPEN" then
display.showPasswordResult(true)
utils.log("Password accepted - iris opened")
elseif response == "IRIS_DENIED" then
display.showPasswordResult(false)
utils.log("Password rejected")
end
end
-- Re-check iris state after password attempt
if transceiver then
remoteIrisState = transceiver.checkConnectedShielding()
end
end
if remoteIrisState and remoteIrisState > 0 then
-- Remote iris is closed (partially or fully)
if remoteIrisState == 100 then

View File

@ -136,4 +136,41 @@ function utils.getIrisState()
return "NO IRIS"
end
---------------------------------------------
-- MESSAGING
---------------------------------------------
function utils.sendVersionMessage()
if config.enableMessaging then
local message = "SGCS_V" .. config.programVersion
gate.sendStargateMessage(message)
utils.log("Sent version message: " .. message)
return true
end
return false
end
function utils.sendPasswordResponse(success)
if config.enableMessaging then
if success then
gate.sendStargateMessage("IRIS_OPEN")
utils.log("Sent iris open confirmation")
else
gate.sendStargateMessage("IRIS_DENIED")
utils.log("Sent iris access denied")
end
return true
end
return false
end
function utils.sendPasswordAttempt(password)
if config.enableMessaging then
gate.sendStargateMessage("IRIS_PASSWORD:" .. password)
utils.log("Sent password attempt")
return true
end
return false
end
return utils