divided everything

This commit is contained in:
2025-12-28 23:51:01 -05:00
parent 39fe8bdc6c
commit 91c7cc2113
8 changed files with 1711 additions and 13 deletions

View File

@ -0,0 +1,427 @@
--[[
Stargate Control System - Main Entry Point
For Stargate Journey Mod - AllTheMods 9
Comprehensive control program featuring:
- Full dialing system with touch screen interface
- Automatic iris control with security features
- Incoming/outgoing wormhole management
- Address book with categories
- Entity tracking and logging
- Whitelist/blacklist security
]]
---------------------------------------------
-- LOAD MODULES
---------------------------------------------
local config = require("config")
local addresses = require("addresses")
local utils = require("utils")
local display = require("display")
---------------------------------------------
-- INITIALIZATION
---------------------------------------------
-- Find and initialize peripherals
local mon = peripheral.find("monitor")
local gate = peripheral.find("advanced_crystal_interface")
or peripheral.find("crystal_interface")
or peripheral.find("basic_interface")
if gate == nil then
error("Stargate interface not found! Please connect an interface.")
end
if mon == nil then
error("Monitor not found! Please connect a monitor.")
end
-- Check iris availability
if gate.getIris() == nil then
print("Config has Iris enabled, but there is no iris! Disabling Iris")
config.irisEnabled = false
end
-- Initialize modules
utils.init(config, gate)
display.init(mon, config, addresses, utils)
-- Ensure gate starts disconnected
gate.disconnectStargate()
-- Ensure iris starts open
if config.irisEnabled then
gate.openIris()
end
---------------------------------------------
-- GLOBAL STATE
---------------------------------------------
local dialing = false
local totalstate = nil
local disconnect = false
local incomingAddress = {}
local incomingEntityType = ""
local incomingEntityName = ""
local destAddress = {}
local destAddressname = ""
local selx, sely = 0, 0
local y = 0
---------------------------------------------
-- EVENT HANDLERS
---------------------------------------------
local function GetClick()
mon.setTextScale(1)
local event, _, xPos, yPos = os.pullEvent("monitor_touch")
return xPos, yPos
end
local function GetActivation()
_, _, incomingAddress = os.pullEvent("stargate_incoming_wormhole")
utils.log("Incoming wormhole: " .. gate.addressToString(incomingAddress))
return 1
end
local function ParaDisconnect()
local dx, dy = 0, 0
_, _, dx, dy = os.pullEvent("monitor_touch")
if (dx ~= 0) and (dy ~= 0) then
gate.disconnectStargate()
redstone.setOutput("top", false)
utils.log("Manual disconnect triggered")
end
return 1
end
local function EntityRead()
sleep(0.1)
_, _, incomingEntityType, incomingEntityName, _ = os.pullEvent("stargate_reconstructing_entity")
utils.log("Entity reconstructed: " .. incomingEntityName .. " (" .. incomingEntityType .. ")")
return 1
end
local function DisconnectCheck()
local _, _, disCode = os.pullEvent("stargate_disconnected")
redstone.setOutput("top", false)
utils.log("Stargate disconnected (code: " .. tostring(disCode) .. ")")
if config.autoOpenIrisAfterDisconnect then
utils.openIris()
end
return 2
end
local function Paratimeout()
sleep(300)
return 2
end
---------------------------------------------
-- INCOMING WORMHOLE HANDLER
---------------------------------------------
local function handleIncomingWormhole()
mon.setBackgroundColor(colors.black)
mon.clear()
mon.setBackgroundColor(colors.red)
mon.setTextScale(1)
mon.setCursorPos(9, 4)
mon.write("INCOMING")
incomingAddress = utils.addressToTable(incomingAddress)
-- Check security
local allowed, reason = utils.isAddressAllowed(incomingAddress)
local addressString = gate.addressToString(incomingAddress) or "Unknown"
utils.log("Incoming wormhole from: " .. addressString .. " " .. reason)
-- Show incoming connection status
display.showIncoming(addressString, allowed, reason)
-- Handle iris
if config.autoCloseIrisOnIncoming then
sleep(config.irisCloseDelay)
if allowed then
utils.openIris()
else
utils.closeIris()
end
end
-- Monitor for entities
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:
-- 1 = EntityRead (someone/something came through the gate)
-- 2 = DisconnectCheck (gate disconnected on its own)
-- 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
display.showEntity(incomingEntityType, incomingEntityName, allowed)
incomingEntityType = ""
incomingEntityName = ""
else
disconnect = true
end
end
disconnect = false
end
---------------------------------------------
-- DIALING FUNCTIONS
---------------------------------------------
local function dialGate(address)
utils.log("Dialing: " .. gate.addressToString(address))
local gateType = gate.getStargateType()
-- Manual Milky Way dialing with ring rotation
if gateType == "sgjourney:milky_way_stargate" and config.manualDial == true then
local addressLength = #address
if addressLength == 8 then
gate.setChevronConfiguration({ 1, 2, 3, 4, 6, 7, 8, 5 })
elseif addressLength == 9 then
gate.setChevronConfiguration({ 1, 2, 3, 4, 5, 6, 7, 8 })
end
local start = gate.getChevronsEngaged() + 1
for chevron = start, addressLength, 1 do
local symbol = address[chevron]
if chevron % 2 == 0 then
gate.rotateClockwise(symbol)
else
gate.rotateAntiClockwise(symbol)
end
while (not gate.isCurrentSymbol(symbol)) do
sleep(0)
end
gate.openChevron()
sleep(1)
gate.closeChevron()
sleep(0.5)
display.showDialing(chevron, symbol, gateType)
end
else
-- Automatic dialing for other gate types
if gateType ~= "sgjourney:universe_stargate" then
local addressLength = #address
if addressLength == 8 then
gate.setChevronConfiguration({ 1, 2, 3, 4, 6, 7, 8, 5 })
elseif addressLength == 9 then
gate.setChevronConfiguration({ 1, 2, 3, 4, 5, 6, 7, 8 })
end
end
local start = gate.getChevronsEngaged() + 1
for chevron = start, #address, 1 do
local symbol = address[chevron]
gate.engageSymbol(symbol)
sleep(config.gatespeed)
display.showDialing(chevron, symbol, gateType)
if (symbol) ~= 0 then
if (gateType == "sgjourney:universe_stargate") or (gateType == "sgjourney:pegasus_stargate") then
os.pullEvent("stargate_chevron_engaged")
end
else
if gateType == "sgjourney:universe_stargate" then
os.pullEvent("stargate_chevron_engaged")
redstone.setOutput("top", true)
elseif (gateType == "sgjourney:pegasus_stargate") then
os.pullEvent("stargate_chevron_engaged")
end
end
end
end
end
local function selectGateFromList()
local selecting = true
while dialing == false and selecting == true do
selx, sely = GetClick()
local buttonXY, computerAddresses, computerNames = display.getButtonData()
for i = 1, #buttonXY do
if (sely == buttonXY[i][3]) and ((selx >= buttonXY[i][1]) and (selx <= buttonXY[i][2])) then
dialGate(computerAddresses[i])
destAddressname = computerNames[i]
destAddress = computerAddresses[i]
dialing = true
sely = 0
selx = 0
elseif sely >= 17 and selx >= 23 then
selecting = false
sely = 0
selx = 0
end
end
end
display.clearButtonData()
return dialing
end
local function selectCategory()
local state = true
while state == true do
display.selectionTabs()
local tabx, taby = GetClick()
y = 2
local count = 0
if (taby >= 2) and (taby <= 6) and ((tabx >= 2) and (tabx <= 13)) then
if #addresses.MainGates ~= 0 then
mon.setBackgroundColor(colors.black)
mon.clear()
mon.setBackgroundColor(colors.purple)
count, y = display.screenWrite(addresses.MainGates, count, y)
local returnstate = selectGateFromList()
if returnstate == true then
state = false
end
display.clearButtonData()
else
mon.setCursorPos(9, 7)
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)
mon.clear()
mon.setBackgroundColor(colors.green)
count, y = display.screenWrite(addresses.playerGates, count, y)
local returnstate = selectGateFromList()
if returnstate == true then
state = false
end
display.clearButtonData()
else
mon.setCursorPos(9, 7)
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)
mon.clear()
mon.setBackgroundColor(colors.red)
count, y = display.screenWrite(addresses.hazardGates, count, y)
local returnstate = selectGateFromList()
if returnstate == true then
state = false
end
display.clearButtonData()
else
mon.setCursorPos(9, 7)
mon.write("no gates available")
sleep(5)
end
elseif (taby >= 17) and (tabx >= 23) then
state = false
totalstate = false
end
end
return 1
end
local function handleOutgoingDial()
totalstate = true
local PDO = 0
-- parallel.waitForAny runs functions simultaneously and returns which finished first
-- Here we're waiting for either:
-- 1 = selectCategory (user selected a gate to dial)
-- 2 = Paratimeout (5 minutes passed with no selection)
-- This prevents the gate from staying on the selection screen forever
PDO = parallel.waitForAny(selectCategory, Paratimeout)
if (PDO == 1) and totalstate == true then
sleep(1)
os.pullEvent("stargate_outgoing_wormhole")
display.showConnected(destAddressname, destAddress)
if (gate.isStargateConnected() == true) then
-- parallel.waitForAny runs functions at the same time, returns which finished first
-- While the wormhole is open, we wait for:
-- DisconnectCheck = gate disconnects naturally (timeout or remote disconnect)
-- ParaDisconnect = user manually clicks screen to disconnect
-- Paratimeout = safety timeout (5 minutes)
-- Whichever happens first ends the connection
PDO = parallel.waitForAny(DisconnectCheck, ParaDisconnect, Paratimeout)
dialing = false
end
end
display.clearButtonData()
destAddress = {}
destAddressname = ""
end
---------------------------------------------
-- MAIN MENU
---------------------------------------------
local function mainMenu()
while true do
display.showMainMenu()
-- parallel.waitForAny runs multiple functions simultaneously, returns which completes first
-- The main menu waits for any of these events:
-- 1 = GetClick (user touched the monitor anywhere - assumes they want to dial out)
-- 2 = GetActivation (incoming wormhole detected with address)
-- Note: We don't wait for CheveronActivation here because it fires at the same time
-- as the incoming wormhole event, causing a race condition where we might miss the address
local answer = parallel.waitForAny(GetClick, GetActivation)
if (answer == 1) then
handleOutgoingDial()
else
handleIncomingWormhole()
end
end
end
---------------------------------------------
-- STARTUP
---------------------------------------------
utils.log("=== Stargate Control System Starting ===")
utils.log("Gate Type: " .. gate.getStargateType())
utils.log("Iris Available: " .. tostring(config.irisEnabled))
-- Start the main menu
mainMenu()