--[[ Event Handlers All event handling functions for the stargate control system ]] local handlers = {} -- Module references (set by init) local config, gate, mon, utils, display, events, transceiver -- State variables local state = { incomingAddress = {}, incomingEntityType = "", incomingEntityName = "", lastReceivedMessage = nil, enteringPassword = false, remoteHasComputer = false, remotePasswordRequired = false, destAddress = {}, destAddressname = "", lastGDOCode = nil, lastGDOMatches = false } function handlers.init(cfg, gateInterface, monitor, utilsModule, displayModule, eventsModule, transceiverPeripheral) config = cfg gate = gateInterface mon = monitor utils = utilsModule display = displayModule events = eventsModule transceiver = transceiverPeripheral end function handlers.getState() return state end --------------------------------------------- -- CLICK HANDLER (Priority-based) --------------------------------------------- function handlers.handleDefaultClick(eventType, side, x, y) -- Default handler that returns click coordinates -- This has the lowest priority, so other handlers can intercept first return { x = x, y = y } end --------------------------------------------- -- PASSWORD INPUT HANDLER (Highest Priority) --------------------------------------------- function handlers.handlePasswordInput() display.showPasswordPrompt() local password = "" state.enteringPassword = true -- Wait for password submission - handle events directly without the event system while state.enteringPassword do -- Check if iris has opened (via GDO or other means) if config.irisEnabled and transceiver then local remoteIrisState = transceiver.checkConnectedShielding() if not remoteIrisState or remoteIrisState == 0 then -- Iris opened! Exit password prompt utils.log("Remote iris opened, canceling password prompt") state.enteringPassword = false return "IRIS_OPENED" end end -- Wait for event with timeout local event = { os.pullEvent() } local eventType = event[1] -- Handle GDO events if eventType == "transceiver_transmission_received" then -- Pass to GDO handler handlers.handleGDOTransmission(table.unpack(event)) -- Continue loop to check iris state elseif eventType == "stargate_message_received" then -- Pass to message handler handlers.handleMessage(table.unpack(event)) -- Check if iris opened if state.lastReceivedMessage == "IRIS_OPEN" then state.lastReceivedMessage = nil state.enteringPassword = false return "IRIS_OPENED" end elseif eventType == "monitor_touch" then local x, y = event[3], event[4] -- 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 state.enteringPassword = false end end end end -- If we got here with a password, send it if password ~= "" then utils.sendPasswordAttempt(password) return password end return nil end --------------------------------------------- -- IRIS STATUS CLICK HANDLER (Toggle) --------------------------------------------- function handlers.handleIrisToggle(eventType, side, x, y) -- Only process if not entering password (password handler has higher priority) if state.enteringPassword then return nil end -- Only process if iris is enabled if not config.irisEnabled then return nil end -- Check if clicking on iris status area (bottom-left corner where "IRIS: STATUS" appears) -- The iris status is at position (1, 19) and extends roughly 15-20 characters if y == 19 and x >= 1 and x <= 20 then local irisState = utils.getIrisState() -- Toggle based on current state if irisState == "OPEN" then utils.closeIris() display.drawIrisStatus() return "iris_closed" elseif irisState == "CLOSED" then utils.openIris() display.drawIrisStatus() return "iris_opened" end -- If MOVING or NO IRIS, do nothing end return nil -- Not an iris status click end --------------------------------------------- -- DISCONNECT BUTTON HANDLER --------------------------------------------- function handlers.handleDisconnectButton(eventType, side, x, y) -- Only process if not entering password (password handler has higher priority) if state.enteringPassword then return nil end -- Only process if stargate is actually connected if not gate.isStargateConnected() then return nil end -- Check if clicking disconnect button (bottom-right corner) if y >= 17 and y <= 19 and x >= 20 and x <= 28 then gate.disconnectStargate() redstone.setOutput("top", false) utils.log("Manual disconnect triggered") return "disconnect" end return nil -- Not a disconnect button click end --------------------------------------------- -- ACTIVATION HANDLER --------------------------------------------- function handlers.handleActivation(eventType, side, address) state.incomingAddress = address utils.log("Incoming wormhole: " .. gate.addressToString(address)) return "activation" end --------------------------------------------- -- ENTITY READ HANDLER --------------------------------------------- function handlers.handleEntityRead(eventType, side, entityType, entityName, ...) sleep(0.1) state.incomingEntityType = entityType state.incomingEntityName = entityName utils.log("Entity reconstructed: " .. entityName .. " (" .. entityType .. ")") return "entity" end --------------------------------------------- -- DISCONNECT CHECK HANDLER --------------------------------------------- function handlers.handleDisconnect(eventType, side, disCode) redstone.setOutput("top", false) utils.log("Stargate disconnected (code: " .. tostring(disCode) .. ")") -- Set iris to default state if config.irisClosedByDefault then utils.closeIris() else utils.openIris() end return "disconnected" end --------------------------------------------- -- MESSAGE HANDLER --------------------------------------------- function handlers.handleMessage(eventType, side, message) state.lastReceivedMessage = message utils.debug("Message Received: " .. message) return "message_received" end --------------------------------------------- -- GDO TRANSMISSION HANDLER --------------------------------------------- function handlers.handleGDOTransmission(eventType, side, frequency, idc, matches) state.lastGDOCode = idc state.lastGDOMatches = matches utils.log("GDO transmission received: IDC=" .. tostring(idc) .. ", matches=" .. tostring(matches)) utils.debug("GDO received: IDC=" .. tostring(idc) .. ", matches=" .. tostring(matches)) -- If matches configured IDC and gate is connected, open iris if matches and gate.isStargateConnected() and config.irisEnabled then utils.log("Valid GDO code received - opening iris") utils.debug("Valid GDO - opening iris") utils.openIris() end return "gdo_received" end --------------------------------------------- -- SETUP EVENT HANDLERS --------------------------------------------- function handlers.setupConnectionHandlers() -- Clear any existing handlers events.clearHandlers() -- Register all handlers with their priorities events.registerHandler("monitor_touch", handlers.handleIrisToggle, events.PRIORITY.DISCONNECT_BUTTON) -- Same priority as disconnect events.registerHandler("monitor_touch", handlers.handleDisconnectButton, events.PRIORITY.DISCONNECT_BUTTON) events.registerHandler("monitor_touch", handlers.handleDefaultClick, events.PRIORITY.DEFAULT) -- Lowest priority - returns coordinates events.registerHandler("stargate_incoming_wormhole", handlers.handleActivation, events.PRIORITY.ACTIVATION) events.registerHandler("stargate_reconstructing_entity", handlers.handleEntityRead, events.PRIORITY.ENTITY_READ) events.registerHandler("stargate_disconnected", handlers.handleDisconnect, events.PRIORITY.DISCONNECT_CHECK) events.registerHandler("stargate_message_received", handlers.handleMessage, events.PRIORITY.MESSAGE) events.registerHandler("transceiver_transmission_received", handlers.handleGDOTransmission, events.PRIORITY.MESSAGE) end return handlers