Advertisement
HydrantHunter

gateLiaison 1.5

Jun 4th, 2014
2,679
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 24.94 KB | None | 0 0
  1. --[[  LanteaCraft      ]]--
  2. --[[      and SGCraft  ]]--
  3. --[[    Gate Liaison   ]]--
  4. --[[      by Dog       ]]--
  5. --[[ aka HydrantHunter ]]--
  6. --[[  with help from   ]]--
  7. --[[  AfterLifeLochie  ]]--
  8. --[[ pastebin PLy9GAWt ]]--
  9. local gVer = "1.5.02"
  10. --[[
  11. Tested with/requires:
  12.   - Minecraft 1.7.10
  13.   - LanteaCraft-1.7.10-70 || SGCraft1.95-mc1.7.10
  14.   - ComputerCraft 1.73, 1.74, 1.75
  15.     - A computer (standard or advanced), 1 or more optional 3x Monitor Arrays (standard or advanced)
  16.       - or a wireless turtle (standard or advanced), no monitors
  17.     - A stargate with a CC adapter
  18.     - ccDHD running on an advanced computer with a wireless modem
  19. ]]--
  20. --# AUTOMATIC/STATIC CONFIGURATION (Part 1)
  21. local mon = { }
  22. local modem, gate, secureStatus, thisGate, incomingAddress, fuelGauge, doCommand, gateStateChange
  23. local lcGate, irisState, staticDrawn = false, false, false
  24. local gateStatus, dialAddress, modemSide, chevronNumber, maxFuel = "QRY", "none", "none", 0, 203842
  25. local gateSettings = {
  26.   rsSide = "front",
  27.   DHD = 99999,
  28. }
  29. --# Color Definitions
  30. local white = colors.white
  31. local silver = colors.lightGray
  32. local gray = colors.gray
  33. local black = colors.black
  34. local brown = colors.brown
  35. local yellow = colors.yellow
  36. local orange = colors.orange
  37. local red = colors.red
  38. local magenta = colors.magenta
  39. local purple = colors.purple
  40. local blue = colors.blue
  41. local sky = colors.lightBlue
  42. local cyan = colors.cyan
  43. local lime = colors.lime
  44. local green = colors.green
  45. if not term.isColor() then
  46.   silver = colors.white
  47.   gray = colors.black
  48.   brown = colors.white
  49.   yellow = colors.white
  50.   orange = colors.white
  51.   red = colors.white
  52.   magenta = colors.white
  53.   purple = colors.white
  54.   blue = colors.black
  55.   sky = colors.white
  56.   cyan = colors.white
  57.   lime = colors.white
  58.   green = colors.white
  59. end
  60. local mwhite = colors.white
  61. local msilver = colors.lightGray
  62. local mgray = colors.gray
  63. local mblack = colors.black
  64. local mbrown = colors.brown
  65. local myellow = colors.yellow
  66. local morange = colors.orange
  67. local mred = colors.red
  68. local mmagenta = colors.magenta
  69. local mpurple = colors.purple
  70. local mblue = colors.blue
  71. local msky = colors.lightBlue
  72. local mcyan = colors.cyan
  73. local mlime = colors.lime
  74. local mgreen = colors.green
  75. --# END AUTOMATIC/STATIC CONFIGURATION (Part 1)
  76.  
  77. local function shutDown()
  78.   rednet.close(modemSide)
  79.   if mon[1] then
  80.     for i = 1, #mon do
  81.       mon[i].setBackgroundColor(mblack)
  82.       mon[i].clear()
  83.     end
  84.   end
  85. end
  86.  
  87. local function ingestData()
  88.   local gateConfig = fs.open("/data/gateConfig", "r") or function() shutDown() error("ingestData(): Unable to open /data/gateConfig for reading", 0) end
  89.   gateSettings = textutils.unserialize(gateConfig.readAll())
  90.   gateConfig.close()
  91. end
  92.  
  93. local function saveData()
  94.   local gateConfig = fs.open("/data/gateConfig", "w") or function() shutDown() error("saveData(): Unable to open /data/gateConfig for writing", 0) end
  95.   gateConfig.write(textutils.serialize(gateSettings))
  96.   gateConfig.close()
  97. end
  98.  
  99. local function netSend()
  100.   local dataPack = {
  101.     program = "ccDHD",
  102.     thisGate = thisGate,
  103.     fuelGauge = fuelGauge,
  104.     gateStatus = gateStatus,
  105.     secureStatus = secureStatus,
  106.     dialAddress = dialAddress,
  107.     incomingAddress = incomingAddress,
  108.     chevronNumber = chevronNumber,
  109.     irisState = irisState,
  110.     lcGate = lcGate,
  111.   }
  112.   if not rednet.isOpen(modemSide) then
  113.     rednet.open(modemSide)
  114.   end
  115.   if gateSettings.DHD ~= 99999 then
  116.     rednet.send(gateSettings.DHD, dataPack)
  117.   end
  118. end
  119.  
  120. local function netReceive()
  121.   while true do
  122.     local id, message =  rednet.receive()
  123.     if id == gateSettings.DHD and type(message) == "table" then
  124.       if message.program == "ccDHD" then
  125.         doCommand(message.command)
  126.       elseif message.program == "pSync" and message.password then
  127.         if not lcGate then
  128.           gate.sendMessage(message.password)
  129.         end
  130.       end
  131.     end
  132.   end
  133. end
  134.  
  135. local function gateReceive()
  136.   while true do
  137.     local _, src, password = os.pullEvent("sgMessageReceived")
  138.     if gateSettings.DHD ~= 99999 then
  139.       rednet.send(gateSettings.DHD, password)
  140.     end
  141.   end
  142. end
  143.  
  144. local function makeLongName(name)
  145.   return #name ~= 7 and name or table.concat({ name:sub(1, 1), " ", name:sub(2, 2), " ", name:sub(3, 3), " ", name:sub(4, 4), " ", name:sub(5, 5), " ", name:sub(6, 6), " ", name:sub(7) })
  146. end
  147.  
  148. local function displayMarquee() --# Display the local address when there is no other information to display
  149.   if not mon[1] then return end
  150.   if secureStatus == "allclear" then
  151.     for i = 1, #mon do
  152.       mon[i].setBackgroundColor(mblack)
  153.       mon[i].clear()
  154.       mon[i].setCursorPos(1, 1)
  155.       mon[i].setTextColor(mcyan)
  156.       mon[i].write("Stargate")
  157.       mon[i].setTextColor(myellow)
  158.       mon[i].setCursorPos(4, 2)
  159.       mon[i].write(thisGate)
  160.     end
  161.   else
  162.     for i = 1, #mon do
  163.       mon[i].setBackgroundColor(mblack)
  164.       mon[i].clear()
  165.       mon[i].setCursorPos(1, 1)
  166.       mon[i].setTextColor(mred)
  167.       mon[i].write("!! LOCKDOWN !!")
  168.     end
  169.   end
  170. end
  171.  
  172. local function displayStatus(select)
  173.   if not mon[1] then return end
  174.   if select == "dial" or (select == "con" and not incomingAddress) then
  175.     local longAddress = makeLongName(dialAddress)
  176.     for i = 1, #mon do
  177.       mon[i].setCursorPos(1, 1)
  178.       mon[i].setTextColor(msky)
  179.       if select == "dial" then
  180.         mon[i].write("Dialing     ")
  181.         mon[i].setTextColor(mgray)
  182.       elseif select == "con" then
  183.         mon[i].write("Connected to")
  184.         mon[i].setTextColor(myellow)
  185.       end
  186.       mon[i].setCursorPos(#dialAddress - 5, 2)
  187.       mon[i].write(#dialAddress == 9 and dialAddress or longAddress)
  188.     end
  189.   elseif select == "incoming" or (select == "con" and incomingAddress) then
  190.     local longAddress = makeLongName(incomingAddress)
  191.     for i = 1, #mon do
  192.       mon[i].setTextColor(secureStatus == "allclear" and myellow or mred)
  193.       mon[i].setCursorPos(1, 1)
  194.       mon[i].write("Incoming from ")
  195.       mon[i].setTextColor(secureStatus == "allclear" and msky or morange)
  196.       if (lcGate and gate.isDialing()) or (not lcGate and gate.stargateState() == "Dialling") then
  197.         if lcGate then
  198.           mon[i].setCursorPos(4, 2)
  199.           mon[i].write(incomingAddress .. string.rep(" ", 13))
  200.         else
  201.           mon[i].setCursorPos(#incomingAddress - 5, 2)
  202.           if #incomingAddress == 7 then
  203.             mon[i].write(longAddress:sub(1, chevronNumber * 2))
  204.             mon[i].setTextColor(mgray)
  205.             mon[i].write(longAddress:sub((chevronNumber * 2) + 1, #longAddress))
  206.           else
  207.             mon[i].write(incomingAddress:sub(1, chevronNumber))
  208.             mon[i].setTextColor(mgray)
  209.             mon[i].write(incomingAddress:sub(chevronNumber + 1, #incomingAddress))
  210.           end
  211.         end
  212.       else
  213.         mon[i].setCursorPos(#incomingAddress - 5, 2)
  214.         mon[i].write(longAddress)
  215.       end
  216.     end
  217.   elseif select == "outgoing" then
  218.     local longAddress = makeLongName(dialAddress)
  219.     for i = 1, #mon do
  220.       mon[i].setCursorPos(#dialAddress - 5, 2)
  221.       mon[i].setTextColor(myellow)
  222.       if #dialAddress == 7 then
  223.         mon[i].write(longAddress:sub(1, chevronNumber * 2))
  224.       else
  225.         mon[i].write(dialAddress:sub(1, chevronNumber))
  226.       end
  227.     end
  228.   elseif select == "discon" then
  229.     for i = 1, #mon do
  230.       mon[i].clear()
  231.       mon[i].setCursorPos(1, 1)
  232.       mon[i].setTextColor(msky)
  233.       mon[i].write(gateStatus)
  234.     end
  235.   end
  236. end
  237.  
  238. local function drawElement(x, y, w, h, txtColor, bgColor, text)
  239.   if bgColor then term.setBackgroundColor(bgColor) end
  240.   local deText = text and tostring(text) or ""
  241.   if w > #deText or h > 1 then       --# We're drawing something more than text
  242.     local line = string.rep(" ", w)  --# Define one line of the 'element' (box/rectangle/line-seg)
  243.     for i = y, y + h - 1 do
  244.       term.setCursorPos(x, i)        --# Position cursor
  245.       term.write(line)               --# Draw 1 of h lines of the 'element' (box/rectangle/line-seg)
  246.     end
  247.   end
  248.   if deText ~= "" then
  249.     if txtColor then term.setTextColor(txtColor) end
  250.     w = math.max(w, #deText)         --# Ensure minimum length
  251.     local xW = (x + math.floor(w / 2)) - math.floor(#deText / 2) --# Center the text horizontally
  252.     local yH = y + math.floor(h / 2) --# Center the text vertically
  253.     term.setCursorPos(xW, yH)        --# Set the cursor position
  254.     term.write(deText)               --# Write the text
  255.   end
  256. end
  257.  
  258. local function terminalScreen()
  259.   local stColor, sbColor
  260.   --# Set the header color
  261.   if term.isColor() then
  262.     stColor = mon[1] and white or black
  263.     sbColor = mon[1] and blue or sky
  264.     if lcGate then
  265.       stColor = fuelGauge and stColor or white
  266.       sbColor = fuelGauge and sbColor or red
  267.     else
  268.       stColor = fuelGauge > math.floor(maxFuel * 0.05) and stColor or white
  269.       sbColor = fuelGauge > math.floor(maxFuel * 0.05) and sbColor or red
  270.     end
  271.   else
  272.     stColor = black
  273.     sbColor = white
  274.   end
  275.   --# Draw header (not 'static' - color changes based on fuel/monitor status)
  276.   local glHeaderTxt = " Gate Liaison" .. string.rep(" ", 12) .. "ver. " .. gVer .. " "
  277.   drawElement(2, 2, 1, 1, stColor, sbColor, glHeaderTxt)    --# Header
  278.   drawElement(2, 10, 37, 1, nil, nil, "")                   --# Footer
  279.   drawElement(3, 10, 1, 1, nil, nil, os.getComputerLabel()) --# Lowline
  280.   local cID = "cc # " .. tostring(os.getComputerID())
  281.   drawElement(38 - #cID, 10, 1, 1, stColor, sbColor, cID)
  282.   --# Static entries
  283.   if not staticDrawn then
  284.     drawElement(2, 3, 12, 7, nil, silver, "")               --# Labels' background
  285.     local readouts = { " Gate:", " State:", " Target:",  " Iris:", " Fuel:", " Status:", " Network:" }
  286.     for i = 1, 7 do
  287.       drawElement(2, i + 2, 1, 1, black, nil, readouts[i])
  288.     end
  289.     drawElement(17, 3, 1, 1, yellow, black, thisGate)
  290.     drawElement(17, 9, 1, 1, red, nil, "redNet         " .. gateSettings.DHD)
  291.     drawElement(26, 9, 1, 1, gray, nil, "ccDHD")
  292.     staticDrawn = true
  293.   end
  294.   --# Dynamic entries
  295.   local sTxtColor = blue
  296.   if gateStatus == "Disconnected" then
  297.     sTxtColor = green
  298.   elseif gateStatus == "Connected" then
  299.     sTxtColor = orange
  300.   elseif gateStatus == "Dialing" or gateStatus == "Disconnecting" then
  301.     sTxtColor = sky
  302.   end
  303.   if gateStatus == "Dialing" and dialAddress == "none" then
  304.     drawElement(17, 4, 1, 1, sTxtColor, black, incomingAddress and "Incoming" or "Incoming Connection")
  305.   elseif secureStatus == "lockdown" and not incomingAddress then
  306.     drawElement(17, 4, 1, 1, red, black, "!! LOCKDOWN !!")
  307.   else
  308.     drawElement(17, 4, 1, 1, sTxtColor, black, gateStatus .. string.rep(" ", 11))
  309.   end
  310.   drawElement(17, 5, 1, 1, brown, black, (dialAddress == "none" and incomingAddress) and incomingAddress .. string.rep(" ", 13) or dialAddress .. string.rep(" ", 5))
  311.   drawElement(17, 6, 1, 1, irisState and green or orange, black, irisState and "CLOSED" or "OPEN  ")
  312.   if lcGate then
  313.     drawElement(17, 7, 1, 1, fuelGauge and green or red, nil, fuelGauge and "YES  " or "NO   ")
  314.   else
  315.     drawElement(17, 7, 1, 1, fuelGauge > math.floor(maxFuel * 0.05) and green or orange, nil, tostring(math.floor((fuelGauge / maxFuel) * 100)))
  316.     term.setTextColor(silver)
  317.     term.write("%  ")
  318.   end
  319.   drawElement(17, 8, 1, 1, secureStatus == "allclear" and green or red, nil, secureStatus)
  320. end
  321.  
  322. local function updateStatus()
  323.   if lcGate then
  324.     irisState = rs.getOutput(gateSettings.rsSide)
  325.     fuelGauge = gate.hasFuel()
  326.   else
  327.     local iris = gate.irisState()
  328.     if iris == "Open" or iris == "Closing" or iris == "Offline" then
  329.       irisState = false
  330.     elseif iris == "Closed" or iris == "Opening" then
  331.       irisState = true
  332.     end
  333.     fuelGauge = gate.energyAvailable()
  334.   end
  335.   if incomingAddress or dialAddress ~= "none" then
  336.     if mon[1] then
  337.       if gateStatus == "Dialing" then
  338.         displayStatus(incomingAddress and "incoming" or "dial") --# incoming or outgoing
  339.       elseif gateStatus == "Connected" then
  340.         displayStatus("con")
  341.       end
  342.     end
  343.   end
  344.   if gateStatus == "Disconnected" then
  345.     displayMarquee()
  346.   elseif gateStatus == "Disconnecting" then
  347.     displayStatus("discon")
  348.   end
  349.   netSend()
  350.   terminalScreen()
  351. end
  352.  
  353. local function recordSessionData() --# Human readable log files (last gate & history)
  354.   local logAddress = incomingAddress or dialAddress
  355.   local callDirection = incomingAddress and "Inbound" or "Outbound"
  356.   local tTime = textutils.formatTime(os.time(), false)
  357.   local lastCall = fs.open("/data/gateLastCall", "w")
  358.   lastCall.writeLine(tostring(os.day()) .. " @ " .. tTime .. " <" .. callDirection .. "> " .. logAddress)
  359.   lastCall.close()
  360. end
  361.  
  362. local function irisControl(state)
  363.   if lcGate then
  364.     rs.setOutput(gateSettings.rsSide, state)
  365.   else
  366.     if state then
  367.       pcall(gate.closeIris)
  368.     else
  369.       pcall(gate.openIris)
  370.     end
  371.   end
  372. end
  373.  
  374. local function dialOut(targetAddress)
  375.   if secureStatus == "allclear" then
  376.     dialAddress = targetAddress
  377.     local dialGate, _ = pcall(gate.dial, dialAddress)
  378.     if dialGate then
  379.       gateStatus = "Dialing"
  380.       updateStatus()
  381.     end
  382.     return dialGate
  383.   else
  384.     return false
  385.   end
  386. end
  387.  
  388. local function hangUp()
  389.   if gateStatus == "Disconnected" then return true end
  390.   local onHook, _ = pcall(gate.disconnect)
  391.   if onHook then
  392.     gateStatus = "Disconnecting"
  393.     dialAddress = "none"
  394.     incomingAddress = nil
  395.     chevronNumber = 0
  396.   end
  397.   return onHook
  398. end
  399.  
  400. local function lockDown()
  401.   secureStatus = "lockdown"
  402.   irisControl(true)
  403.   return hangUp()
  404. end
  405.  
  406. do
  407.   local actions = {
  408.     lockdown = function()
  409.       lockDown()
  410.       updateStatus()
  411.     end,
  412.     allclear = function()
  413.       secureStatus = "allclear"
  414.       irisControl(false)
  415.       updateStatus()
  416.     end,
  417.     QRY = function()
  418.       updateStatus()
  419.     end,
  420.     endCall = function()
  421.       hangUp()
  422.       updateStatus()
  423.     end,
  424.     iCLOSE = function(_lcGate)
  425.       irisControl(true)
  426.       if _lcGate then updateStatus() end
  427.     end,
  428.     iOPEN = function(_lcGate, _secureStatus)
  429.       if _secureStatus == "allclear" then
  430.         irisControl(false)
  431.         if _lcGate then updateStatus() end
  432.       end
  433.     end,
  434.   }
  435.  
  436.   doCommand = function(thisCommand)
  437.     for cmd, func in pairs(actions) do
  438.       if thisCommand == cmd then
  439.         return func(lcGate, secureStatus)
  440.       end
  441.     end
  442.     if #thisCommand == 7 or #thisCommand == 9 then
  443.       if not dialOut(thisCommand) then
  444.         dialAddress = "none"
  445.       end
  446.     else
  447.       dialAddress = "none"
  448.     end
  449.     updateStatus()
  450.   end
  451. end
  452.  
  453. local function irisStateChange() --# SGCraft
  454.   while true do
  455.     local irisEvent, _, newState, oldState = os.pullEvent("sgIrisStateChange")
  456.     if newState == "Closed" or newState == "Open" or newState == "Offline" then
  457.       updateStatus()
  458.     end
  459.   end
  460. end
  461.  
  462. do
  463.   local states = {
  464.     Idle = "Disconnected",
  465.     Dialling = "Dialing",
  466.     Opening = "Dialing",
  467.     Connected = "Connected",
  468.     Closing = "Disconnecting",
  469.     Offline = "Disconnected",
  470.   }
  471.  
  472.   gateStateChange = function() --# SGCraft
  473.     while true do
  474.       local sgEvent, _, new_State, old_State = os.pullEvent("sgStargateStateChange")
  475.       gateStatus = states[new_State]
  476.       if gateStatus == "Disconnecting" or gateStatus == "Disconnected" then
  477.         dialAddress = "none"
  478.         incomingAddress = nil
  479.         chevronNumber = 0
  480.       end
  481.       if gateStatus ~= "Dialing" then updateStatus() end
  482.     end
  483.   end
  484. end
  485.  
  486. local function chevronEncoder() --# SGCraft
  487.   while true do
  488.     local sgEvent, _, chevron
  489.     sgEvent, _, chevronNumber, chevron = os.pullEvent("sgChevronEngaged")
  490.     if incomingAddress then
  491.       displayStatus("incoming")
  492.       drawElement(17, 5, 1, 1, cyan, black, incomingAddress:sub(1, chevronNumber))
  493.     else
  494.       displayStatus("outgoing")
  495.       drawElement(17, 5, 1, 1, cyan, black, dialAddress:sub(1, chevronNumber))
  496.     end
  497.     netSend()
  498.   end
  499. end
  500.  
  501. local function outgoingCall()   --# LanteaCraft & SGCraft
  502.   local sgEvent, _
  503.   while true do
  504.     if lcGate then
  505.       sgEvent, chevronNumber = os.pullEvent("sgChevronEncode")
  506.     else
  507.       sgEvent, _, dialAddress = os.pullEvent("sgDialOut")
  508.       chevronNumber = 1
  509.     end
  510.     if dialAddress ~= "none" then
  511.       displayStatus("outgoing")
  512.       drawElement(17, 5, 1, 1, cyan, black, dialAddress:sub(1, chevronNumber))
  513.       netSend()
  514.     end
  515.   end
  516. end
  517.  
  518. local function incomingCall()   --# LanteaCraft & SGCraft
  519.   while true do
  520.     local sgEvent, _, incomingChevron
  521.     if lcGate then
  522.       _, incomingChevron = os.pullEvent("sgIncoming")
  523.     else
  524.       sgEvent, _, incomingAddress = os.pullEvent("sgDialIn")
  525.     end
  526.     gateStatus = "Dialing"
  527.     if lcGate then
  528.       if not incomingChevron then
  529.         drawElement(17, 4, 1, 1, orange, black, "Incoming Connection")
  530.       else
  531.         incomingAddress = incomingAddress and incomingAddress .. incomingChevron or incomingChevron
  532.         drawElement(17, 4, 1, 1, orange, black, "Incoming     ")
  533.         drawElement(17, 5, 1, 1, brown, nil, incomingAddress .. string.rep(" ", 13))
  534.       end
  535.     else
  536.       if not incomingAddress then
  537.         drawElement(17, 4, 1, 1, orange, black, "Incoming Connection")
  538.       else
  539.         drawElement(17, 4, 1, 1, orange, black, "Incoming     ")
  540.         drawElement(17, 5, 1, 1, brown, nil, incomingAddress .. string.rep(" ", 13))
  541.       end
  542.     end
  543.     displayStatus("incoming")
  544.     netSend()
  545.   end
  546. end
  547.  
  548. local function callConnect()    --# LanteaCraft
  549.   while true do
  550.     os.pullEvent("sgWormholeOpening")
  551.     gateStatus = "Connected"
  552.     recordSessionData()
  553.     updateStatus()
  554.   end
  555. end
  556.  
  557. local function callDisconnect() --# LanteaCraft
  558.   while true do
  559.     os.pullEvent("sgWormholeClosing")
  560.     gateStatus = "Disconnecting"
  561.     dialAddress = "none"
  562.     incomingAddress = nil
  563.     chevronNumber = 0
  564.     updateStatus()
  565.   end
  566. end
  567.  
  568. local function gateIdle()       --# LanteaCraft
  569.   while true do
  570.     os.pullEvent("sgIdle")
  571.     gateStatus = "Disconnected"
  572.     dialAddress = "none"
  573.     incomingAddress = nil
  574.     chevronNumber = 0
  575.     updateStatus()
  576.   end
  577. end
  578.  
  579. local function charInput()
  580.   while true do
  581.     local _, char = os.pullEvent("char")
  582.     if string.lower(char) == "q" then
  583.       term.setBackgroundColor(colors.black)
  584.       term.clear()
  585.       drawElement(1, 1, 1, 1, white, nil, "gateLiaison is OFFLINE")
  586.       term.setCursorPos(1, 3)
  587.       return
  588.     end
  589.   end
  590. end
  591.  
  592. local function waitingAnimation() --# intentionally not using drawELement - much more efficient
  593.   while true do
  594.     for i = 5, 21 do
  595.       term.setCursorPos(i, 11)
  596.       term.setBackgroundColor(cyan)
  597.       term.write(" ")
  598.       term.setBackgroundColor(black)
  599.       term.setCursorPos(i - 1, 11)
  600.       term.write(" ")
  601.       sleep(0.04)
  602.     end
  603.     for i = 21, 5, -1 do
  604.       term.setCursorPos(i, 11)
  605.       term.setBackgroundColor(cyan)
  606.       term.write(" ")
  607.       term.setBackgroundColor(black)
  608.       term.setCursorPos(i + 1, 11)
  609.       term.write(" ")
  610.       sleep(0.04)
  611.     end
  612.   end
  613. end
  614.  
  615. local function waitingNet()
  616.   while true do
  617.     local id, message = rednet.receive()
  618.     if type(message) == "table" and message.program == "ccDHD" and message.command == "1stRun" then
  619.       gateSettings.DHD = id
  620.       netSend()
  621.       rednet.unhost("ccDHDSetup")
  622.       return
  623.     end
  624.   end
  625. end
  626.  
  627. local function firstRun()
  628.   local ccLabel = os.getComputerLabel() --# Set computer label
  629.   if ccLabel == nil or tostring(ccLabel) == "" or ccLabel == "Gate" then
  630.     os.setComputerLabel(thisGate .. " gate")
  631.   end
  632.   term.setBackgroundColor(black)
  633.   if lcGate then
  634.     term.clear()
  635.     drawElement(2, 2, 1, 1, white, black, "Please select a redstone output side") --# Select redstone output side
  636.     drawElement(2, 3, 1, 1, nil, nil, "(select an unused side if not using")
  637.     drawElement(2, 4, 1, 1, nil, nil, " redstone)")
  638.     for k, v in ipairs(rs.getSides()) do --# Draw side list
  639.       local sSides = tostring(k) .. " = " .. string.upper(v):sub(1, 1) .. v:sub(2)
  640.       drawElement(2, k + 5, #sSides, 1, nil, nil, sSides)
  641.     end
  642.     while true do                        --# Get rsSide user choice
  643.       term.setCursorPos(2, 13)
  644.       local getSide = tonumber(read())
  645.       if getSide ~= nil then
  646.         if getSide > 0 and getSide < 7 then
  647.           for k, v in ipairs(rs.getSides()) do
  648.             if getSide == k then
  649.               gateSettings.rsSide = v
  650.               break
  651.             end
  652.           end
  653.           break
  654.         end
  655.       end
  656.     end
  657.   end
  658.   term.clear()
  659.   drawElement(2, 2, 1, 1, nil, nil, "Please start ccDHD to complete setup.")
  660.   drawElement(2, 4, 1, 1, nil, nil, "gateLiaison will automatically start")
  661.   drawElement(2, 5, 1, 1, nil, nil, "after ccDHD is initialized.")
  662.   drawElement(2, 7, 1, 1, nil, nil, "This gate: " .. thisGate)
  663.   rednet.host("ccDHDSetup", thisGate)
  664.   drawElement(2, 9, 1, 1, silver, nil, "...waiting for ccDHD...")
  665.   parallel.waitForAny(waitingNet, waitingAnimation)
  666.   term.clear()
  667. end
  668.  
  669. --# AUTOMATIC/STATIC CONFIGURATION (Part 2)
  670. local function initError(device)
  671.   term.setBackgroundColor(black)
  672.   term.clear()
  673.   drawElement(1, 1, 1, 1, red, black, "No " .. device .. " detected!")
  674.   drawElement(1, 3, 1, 1, white, nil, "gateLiaison is OFFLINE")
  675.   term.setCursorPos(1, 5)
  676.   return false
  677. end
  678.  
  679. local function initGate()
  680.   gate = peripheral.find("stargate")
  681.   if not gate then return initError("Stargate") end
  682.   lcGate = pcall(gate.getAddress)
  683.   if lcGate then
  684.     thisGate = gate.getAddress()
  685.     fuelGauge = gate.hasFuel()
  686.     gateStatus = gate.isConnected() and "Connected" or "Disconnected"
  687.     gateStatus = gate.isDialing() and "Dialing" or gateStatus
  688.   else
  689.     thisGate = gate.localAddress()
  690.     fuelGauge = gate.energyAvailable()
  691.     local gateState, callDirection
  692.     gateState, chevronNumber, callDirection = gate.stargateState()
  693.     local states = {
  694.       Idle = "Disconnected",
  695.       Dialling = "Dialing",
  696.       Opening = "Connected",
  697.       Connected = "Connected",
  698.       Closing = "Disconnecting",
  699.       Offline = "Offline",
  700.     }
  701.     gateStatus = states[gateState]
  702.     if gateStatus == "Offline" then return initError("Stargate") end
  703.     if gateStatus == "Dialing" or gateStatus == "Connected" then
  704.       if callDirection == "Inbound" then
  705.         incomingAddress = gate.remoteAddress()
  706.       else
  707.         dialAddress = gate.remoteAddress()
  708.       end
  709.     end
  710.   end
  711.   return true
  712. end
  713.  
  714. local function initMe()
  715.   print("Init Gate...")
  716.   if not initGate() then return false end
  717.   print("Init Modem & Monitor...")
  718.   local bAndW = false      --# black and white monitor tracker
  719.   for _, side in ipairs(rs.getSides()) do
  720.     if peripheral.getType(side) == "modem" then
  721.       if peripheral.call(side, "isWireless") then
  722.         modemSide = side
  723.       else
  724.         local mPerps = peripheral.call(tostring(side), "getNamesRemote")
  725.         for _, name in ipairs(mPerps) do
  726.           if name:sub(1, 7) == "monitor" then
  727.             peripheral.call(name, "setTextScale", 1)
  728.             local tmX, tmY = peripheral.call(name, "getSize")
  729.             if tmX >= 29 then
  730.               mon[#mon + 1] = peripheral.wrap(name)
  731.               if not mon[#mon].isColor() then
  732.                 bAndW = true --# black and white monitor found
  733.               end
  734.             end
  735.           end
  736.         end
  737.       end
  738.     end
  739.   end
  740.   if modemSide == "none" then
  741.     return initError("Wireless Modem")
  742.   end
  743.   rednet.open(modemSide)
  744.   if bAndW then --# if a black and white monitor was found, reset monitor colors to black and white
  745.     msilver = colors.white
  746.     mgray = colors.black
  747.     mbrown = colors.white
  748.     myellow = colors.white
  749.     morange = colors.white
  750.     mred = colors.white
  751.     mmagenta = colors.white
  752.     mpurple = colors.white
  753.     mblue = colors.black
  754.     msky = colors.white
  755.     mcyan = colors.white
  756.     mlime = colors.white
  757.     mgreen = colors.white
  758.   end
  759.   --# Check for first time install
  760.   print("Inspect Environment...")
  761.   if not fs.exists("/data/gateConfig") then
  762.     print("First Run...")
  763.     if not fs.exists("/data") then fs.makeDir("/data") end
  764.     firstRun()
  765.     saveData()
  766.   else
  767.     print("Ingest Data...")
  768.     ingestData()
  769.   end
  770.   if mon[1] then
  771.     for i = 1, #mon do
  772.       mon[i].setBackgroundColor(mwhite)
  773.       mon[i].setTextColor(mblack)
  774.       mon[i].clear()
  775.       mon[i].setTextScale(2)
  776.       mon[i].setCursorPos(2, 1)
  777.       mon[i].write("gateLiaison")
  778.       mon[i].setCursorPos(2, 2)
  779.       mon[i].write("Initializing")
  780.     end
  781.   end
  782.   secureStatus = "allclear"
  783.   return true
  784. end
  785. --# END AUTOMATIC/STATIC CONFIGURATION (Part 2)
  786.  
  787. if not initMe() then return end
  788.  
  789. term.setBackgroundColor(black)
  790. term.clear()
  791. if mon[1] then
  792.   for i = 1, #mon do
  793.     mon[i].setBackgroundColor(black)
  794.     mon[i].clear()
  795.   end
  796. end
  797. updateStatus()
  798.  
  799. if lcGate then
  800.   parallel.waitForAny(netReceive, incomingCall, outgoingCall, callConnect, callDisconnect, gateIdle, charInput)
  801. else
  802.   parallel.waitForAny(gateReceive, netReceive, incomingCall, chevronEncoder, gateStateChange, irisStateChange, charInput)
  803. end
  804. shutDown()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement