Advertisement
drpepper240

GPC Client 0.70e

Jul 12th, 2014
295
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 13.36 KB | None | 0 0
  1. --computercraft
  2. --peripheral controller client by drPepper
  3.  
  4. -- "THE BEER-WARE LICENSE"
  5. -- drPepper@KOPROKUBACH wrote this file. As long as you retain this notice you
  6. -- can do whatever you want with this stuff. If we meet some day, in-game or IRL,
  7. -- and you think this stuff is worth it, you can give me a beer in return
  8.  
  9. --How this should be used:
  10. --one controller - one function, computers are cheap. Do not use single computer to control air generators, lighting and doors/airlocks simultaneously
  11. --one zone - one controller. Wire all air generators in a room to a single controller, then call it AGBRIDGE or something
  12. --ID shoud be 3 chars or longer
  13. --ID should not be equal to controller type
  14.  
  15. VERSION_STRING = "0.70e"
  16.  
  17. --              SUPPORTED TYPES:
  18. T_perTypes = {[1] = "AIRLOCK", [2] = "P_LEM", [3] = "CONTROLLER"}
  19.  
  20.  
  21. --settings
  22. T_data = {}
  23. T_data.settings = {}
  24.  
  25. --default values, can be changed during installation or by editing "data" file
  26.  
  27. T_data.modemSide = nil
  28. T_data.channelSend = 210
  29. T_data.channelReceive = 211
  30. T_data.pastebin = "s84FS5Js"                --pastebin entry for self-update
  31. T_data.state = colors.green                 --default state
  32. T_data.overridden = false                   --override mode
  33. T_data.debugLvl = 0                         --debug level
  34. T_data.perSide = nil                        --peripheral side
  35. T_data.controllerType = "DEFAULT_TYPE"      --controller type
  36. T_data.rsis = nil                           --RS input side
  37. T_data.rsos = nil                           --RS output side
  38. T_data.rsoss = nil                          --RS output secondary side
  39. T_data.rssc = colors.red                    --redstone signal color code
  40. T_data.displayText = " "                    --text to display on display
  41. T_data.laserFreq = 1488                     --default laser frequency
  42.  
  43. --attempts to wrap peripheral
  44. WRAP_ATTEMPTS = 5
  45. --savedata filename
  46. TDATA_FILENAME = "data"
  47.  
  48. modem = nil
  49. label = nil
  50. per = nil
  51.  
  52. --L_EM and everything which can obtain its own coordinates
  53. --assuming coordinates can't change without client restart
  54. gx, gy, gz = nil, nil, nil
  55.  
  56.  
  57.  
  58. --debug messages
  59. function PrintDbg(message, level)
  60.     if level == nil then
  61.         level = 2
  62.     end
  63.     if (level <= T_data.debugLvl) then
  64.         print("D:"..message)
  65.     end
  66. end
  67.  
  68.  
  69. --serializes given table to a file using given or default name (if no given)
  70. function WriteResume()
  71.     PrintDbg("entering WriteResume()", 2)
  72.     local file = fs.open(TDATA_FILENAME,"w")
  73.     local sT = textutils.serialize(T_data)
  74.     file.write(sT)
  75.     file.close()
  76.     return
  77. end
  78.  
  79.  
  80. function ReadResume()
  81.     PrintDbg("entering ReadResume()", 2)
  82.     if not fs.exists(TDATA_FILENAME) then
  83.         PrintDbg("Trying to resume without resume file", 1)
  84.         sleep(1)
  85.         SettingsDialogue()
  86.         os.reboot()
  87.     end
  88.     local file = fs.open(TDATA_FILENAME,"r")
  89.     local sT = file.readAll()
  90.     T_data = textutils.unserialize(sT)
  91.     file.close()
  92.     return
  93. end
  94.  
  95.  
  96. --console dialogue to set all settings
  97. function SettingsDialogue()
  98.     term.clear()
  99.     term.setCursorPos(1,1)
  100.  
  101.     print("Controller type(enter to abort):")
  102.     --listing all available types
  103.     for i=1, #T_perTypes do
  104.         write(tostring(i).." - "..tostring(T_perTypes[i])..", ")
  105.     end
  106.    
  107.     local typeString = tostring(T_perTypes[tonumber(read())])
  108.    
  109.     if string.len(typeString) < 1 then
  110.         print("Aborting...")
  111.         sleep(2)
  112.         os.reboot()
  113.     else
  114.         T_data.controllerType = typeString
  115.     end
  116.  
  117.     --generic settings
  118.     print("Modem side (enter to skip):")
  119.     T_data.modemSide = tostring(read())
  120.     if string.len(T_data.modemSide) < 1 then T_data.modemSide = nil end
  121.    
  122.     --type-dependent settings TODO 
  123.     if string.sub(typeString, 1, 2) == "P_" then
  124.         --PERIPHERAL
  125.         print("Peripheral side (enter to skip):")
  126.         T_data.perSide = tostring(read())
  127.         if string.len(T_data.perSide) < 1 then T_data.perSide = nil end
  128.     else
  129.         --NOT PERIPHERAL
  130.         print("Monitor side (enter to skip):")
  131.         T_data.monitorSide = tostring(read())
  132.         if string.len(T_data.monitorSide) < 1 then T_data.monitorSide = nil end
  133.        
  134.         print("Redstone input side (enter to skip):")
  135.         T_data.rsis = tostring(read())
  136.         if string.len(T_data.rsis) < 1 then T_data.rsis = nil end
  137.        
  138.         print("Redstone output side (enter to skip):")
  139.         T_data.rsos = tostring(read())
  140.         if string.len(T_data.rsos) < 1 then T_data.rsos = nil end
  141.        
  142.         print("Display text (enter to skip):")
  143.         T_data.displayText = tostring(read())
  144.         if string.len(T_data.displayText) < 1 then T_data.displayText = "" end
  145.        
  146.         if string.sub(typeString, 1, 7) == "AIRLOCK" then
  147.             --AIRLOCK
  148.             print("Secondary monitor side (enter to skip):")
  149.             T_data.monitorSideSecondary = tostring(read())
  150.             if string.len(T_data.monitorSideSecondary) < 1 then
  151.                 T_data.monitorSideSecondary = nil
  152.             end
  153.            
  154.             print("Secondary redstone output side (enter to skip):")
  155.             T_data.rsoss = tostring(read())
  156.             if string.len(T_data.rsoss) < 1 then T_data.rsoss = nil end
  157.         else
  158.             --NOT AIRLOCK
  159.         end
  160.        
  161.         --sets rsoutput to true after going to state depicted by this color
  162.         print("Redstone signal color: green instead of red? (y/n):")
  163.         local answer = tostring(read())
  164.         if answer == "y" then
  165.             T_data.rssc = colors.green
  166.         elseif answer == "n" then
  167.             T_data.rssc = colors.red
  168.         else
  169.             T_data.rssc = colors.red
  170.         end
  171.     end
  172.  
  173.     print("Controller ID (enter to abort):")
  174.     local idString = tostring(read())
  175.     if string.len(idString) < 3 then
  176.         print("Aborting...")
  177.         sleep(2)
  178.         os.reboot()
  179.     else
  180.         os.setComputerLabel(idString)
  181.         WriteResume()
  182.         return
  183.     end
  184. end
  185.  
  186.  
  187. function openChannel(modem, n)
  188.     PrintDbg("entering openChannel()", 2)
  189.     if modem == nil then
  190.         PrintDbg("Can't open: no modem present", 0)
  191.         return
  192.     end
  193.     modem.open(n)
  194.     while modem.isOpen(n)== false do
  195.         PrintDbg("opening channel "..tostring(n).."...\n", 1)
  196.         sleep(1)
  197.         modem.open(n)
  198.     end
  199. end
  200.  
  201.  
  202. function GetRSInput()
  203.     PrintDbg("entering GetRSInput()", 2)
  204.     if T_data.rsis == nil then
  205.         PrintDbg("No RS input side", 2)
  206.         return
  207.     end
  208.     --checking input side for state changes
  209.     local signal = rs.getInput(T_data.rsis)
  210.     PrintDbg("got "..tostring(signal).." at "..T_data.rsis, 2)
  211.     if signal ~= ( T_data.rssc == T_data.state ) then
  212.         if T_data.state == colors.green then
  213.             T_data.state = colors.red
  214.         elseif T_data.state == colors.red then
  215.             T_data.state = colors.green
  216.         end
  217.  
  218.         WriteResume()
  219.         SendReportPacket()
  220.     end
  221. end
  222.  
  223.  
  224. function SetRSOutput()
  225.     PrintDbg("entering SetRSOutput()", 2)
  226.     if T_data.rsos == nil then
  227.         PrintDbg("No RS output side", 2)
  228.         SendReportPacket()
  229.         return
  230.     elseif T_data.rssc == nil then
  231.         PrintDbg("Can't find RS output state color", 0)
  232.         return
  233.     else
  234.         rs.setOutput(T_data.rsos, T_data.rssc == T_data.state)
  235.         PrintDbg("set "..tostring(T_data.rssc == T_data.state).." at "..T_data.rsos, 2)
  236.         if T_data.rsoss ~= nil then
  237.             rs.setOutput(T_data.rsoss, T_data.rssc == T_data.state)
  238.             PrintDbg("set "..tostring(T_data.rssc == T_data.state).." at "..T_data.rsoss, 2)
  239.         end
  240.        
  241.         if monitor ~= nil then
  242.             monitor.setBackgroundColor(T_data.state)
  243.             monitor.clear()
  244.             monitor.setTextColor(colors.black)
  245.             monitor.setCursorPos(1,3)
  246.             monitor.write(T_data.displayText)
  247.         end
  248.        
  249.         if monitorSecondary ~= nil then
  250.             monitorSecondary.setBackgroundColor(T_data.state)
  251.             monitorSecondary.clear()
  252.             monitorSecondary.setTextColor(colors.black)
  253.             monitorSecondary.setCursorPos(1,3)
  254.             monitorSecondary.write(T_data.displayText)
  255.         end
  256.     end
  257.     SendReportPacket()
  258. end
  259.  
  260.  
  261. function SendReportPacket()
  262.     PrintDbg("entering SendReportPacket()", 2)
  263.     local packetT =
  264.     {
  265.         sender = label,
  266.         controllerType = T_data.controllerType,
  267.         state = T_data.state,
  268.         version = VERSION_STRING,
  269.         override = T_data.overridden
  270.     }
  271.     if string.sub(T_data.controllerType, 1, 5) == "P_LEM" then
  272.         pExdCommand = "pos"
  273.         packetT.p1, packetT.p2, packetT.p3 = gx, gy, gz
  274.     end
  275.     SendPacket(packetT)
  276. end
  277.  
  278.  
  279. function SendPacket(packetT)
  280.     PrintDbg("entering SendPacket()", 2)
  281.     if modem == nil then
  282.         PrintDbg("Can't send: no modem present", 0)
  283.         return
  284.     end
  285.     local packet = textutils.serialize(packetT)
  286.     modem.transmit(T_data.channelSend, T_data.channelReceive, packet)
  287. end
  288.  
  289.  
  290. --main operation
  291. label = os.getComputerLabel()
  292.  
  293. if (label == 0) then
  294.     PrintDbg("Assign this controller a unique label", 0)
  295.     return
  296. end
  297.  
  298. ReadResume()
  299.  
  300. GetRSInput()
  301. SetRSOutput()
  302.  
  303. WriteResume()
  304.  
  305. --opening
  306. local i = 1
  307. modem = peripheral.wrap(T_data.modemSide)
  308. while modem==nil and i < WRAP_ATTEMPTS do
  309.     PrintDbg("wrapping modem...\n", 1)
  310.     sleep(1)
  311.     modem = peripheral.wrap(T_data.modemSide)
  312.     i = i + 1
  313. end
  314.  
  315.  
  316.  
  317. if string.sub(T_data.controllerType, 1, 5) == "P_LEM" then
  318.     peripheral.call(T_data.perSide, "freq", T_data.laserFreq)
  319.     gx, gy, gz = peripheral.call(T_data.perSide, "pos")
  320. end
  321.  
  322.  
  323. i = 1
  324.  
  325. if T_data.monitorSide ~= nil then
  326.     monitor = peripheral.wrap(T_data.monitorSide)
  327.     while monitor==nil and i < WRAP_ATTEMPTS do
  328.         PrintDbg("wrapping monitor...\n", 1)
  329.         sleep(1)
  330.         monitor = peripheral.wrap(T_data.monitorSide)
  331.         i = i + 1
  332.     end
  333. end
  334.  
  335. i = 1
  336.  
  337. if T_data.monitorSideSecondary ~= nil then
  338.     monitorSecondary = peripheral.wrap(T_data.monitorSideSecondary)
  339.     while monitorSecondary==nil and i < WRAP_ATTEMPTS do
  340.         PrintDbg("wrapping secondary monitor...\n", 1)
  341.         sleep(1)
  342.         monitorSecondary = peripheral.wrap(T_data.monitorSideSecondary)
  343.         i = i + 1
  344.     end
  345. end
  346.  
  347. GetRSInput()
  348. SetRSOutput()
  349.  
  350. openChannel(modem, T_data.channelReceive)
  351.  
  352.  
  353. --main loop
  354. while true do
  355.     local event, p1, p2, p3, p4, p5 = os.pullEvent()
  356.     --key pressed
  357.     if event == "key" then
  358.         if p1 == 22 then
  359.             --Update
  360.             shell.run("rm", "startup")
  361.             shell.run("pastebin", "get "..T_data.pastebin.." startup")
  362.             os.reboot()
  363.         elseif p1 == 20 and T_data.overridden == false then
  364.             --Toggle
  365.             if T_data.state == colors.green then
  366.                 T_data.state = colors.red
  367.             elseif T_data.state == colors.red then
  368.                 T_data.state = colors.green
  369.             end
  370.             WriteResume()
  371.             SetRSOutput()
  372.         elseif p1 == 41 and T_data.overridden == false then
  373.             --re-set
  374.             fs.delete("data")
  375.             os.reboot()
  376.         end
  377.     elseif event == "modem_message" then
  378.         PrintDbg("Modem message received", 2)
  379.         local packet = textutils.unserialize(p4)
  380.         if packet.target ~= nil or packet.command ~= nil then
  381.             if (packet.target == label or packet.target == "BROADCAST" or packet.target == T_data.controllerType) then
  382.                 if packet.command == "SET STATE" then
  383.                     if packet.state == nil then
  384.                         PrintDbg("No state provided", 1)
  385.                     else
  386.                         T_data.state = packet.state
  387.                         WriteResume()
  388.                         SetRSOutput()
  389.                         PrintDbg("State set: "..tostring(packet.state), 2)                     
  390.                     end
  391.                 elseif packet.command == "OVERRIDE" then
  392.                     if T_data.overridden == false then
  393.                         T_data.overridden = true
  394.                     end
  395.                     WriteResume()
  396.                     SendReportPacket()
  397.                 elseif packet.command == "OVERRIDE OFF" then
  398.                     if T_data.overridden == true then
  399.                         T_data.overridden = false
  400.                     end
  401.                     WriteResume()
  402.                     SendReportPacket()
  403.                 elseif packet.command == "PEXECUTE" and string.sub(T_data.controllerType, 1, 2) == "P_" then
  404.                     --Peripheral command
  405.                     if T_data.perSide == nil or packet.pCommand == nil then
  406.                         PrintDbg("peripheral command error", 1)
  407.                         --TODO list of commands to be executed in "green" state only
  408.                     else
  409.                         --Preparing a packet to return
  410.                         rePacketT = {
  411.                             sender = label,
  412.                             controllerType = T_data.controllerType,
  413.                             state = T_data.state,
  414.                             version = VERSION_STRING,
  415.                             override = T_data.overridden,
  416.                             pExdCommand = packet.pCommand
  417.                         }
  418.                         --max 6 returnable params are allowed
  419.                         if packet.delay ~= nil then
  420.                             PrintDbg("Sleep delay:"..tonumber(packet.delay), 2)
  421.                             sleep(tonumber(packet.delay))
  422.                         end
  423.                         PrintDbg("Peripheral command:"..packet.pCommand..", params:"..tostring(packet.p1)..";"..tostring(packet.p2)..";"..tostring(packet.p3)..";"..tostring(packet.p4)..";"..tostring(packet.p5), 2)
  424.                         if packet.p5 ~= nil then
  425.                             rePacketT.p1, rePacketT.p2, rePacketT.p3, rePacketT.p4, rePacketT.p5, rePacketT.p6 = peripheral.call(T_data.perSide, packet.pCommand, packet.p1, packet.p2, packet.p3, packet.p4, packet.p5)
  426.                         elseif packet.p4 ~= nil then
  427.                             rePacketT.p1, rePacketT.p2, rePacketT.p3, rePacketT.p4, rePacketT.p5, rePacketT.p6 = peripheral.call(T_data.perSide, packet.pCommand, packet.p1, packet.p2, packet.p3, packet.p4)
  428.                         elseif packet.p3 ~= nil then
  429.                             rePacketT.p1, rePacketT.p2, rePacketT.p3, rePacketT.p4, rePacketT.p5, rePacketT.p6 = peripheral.call(T_data.perSide, packet.pCommand, packet.p1, packet.p2, packet.p3)
  430.                         elseif packet.p2 ~= nil then
  431.                             rePacketT.p1, rePacketT.p2, rePacketT.p3, rePacketT.p4, rePacketT.p5, rePacketT.p6 = peripheral.call(T_data.perSide, packet.pCommand, packet.p1, packet.p2)
  432.                         elseif packet.p1 ~= nil then
  433.                             rePacketT.p1, rePacketT.p2, rePacketT.p3, rePacketT.p4, rePacketT.p5, rePacketT.p6 = peripheral.call(T_data.perSide, packet.pCommand, packet.p1)
  434.                         else
  435.                             rePacketT.p1, rePacketT.p2, rePacketT.p3, rePacketT.p4, rePacketT.p5, rePacketT.p6 = peripheral.call(T_data.perSide, packet.pCommand)
  436.                         end
  437.                         SendPacket(rePacketT)
  438.                     end
  439.                 elseif packet.command == "REPORT" then
  440.                     SendReportPacket()
  441.                 elseif packet.command == "UPDATE" then
  442.                     shell.run("rm", "startup")
  443.                     shell.run("pastebin", "get "..T_data.pastebin.." startup")
  444.                     os.reboot()
  445.                 end
  446.             end
  447.         end
  448.     elseif event == "monitor_touch" and T_data.overridden == false then
  449.         --Toggle
  450.         if T_data.state == colors.green then
  451.             T_data.state = colors.red
  452.         elseif T_data.state == colors.red then
  453.             T_data.state = colors.green
  454.         end
  455.         WriteResume()
  456.         SetRSOutput()
  457.     elseif event == "redstone" then
  458.         GetRSInput()
  459.     end
  460. end
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement