Advertisement
Guest User

startup

a guest
Jan 19th, 2020
92
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 18.41 KB | None | 0 0
  1. --PeachMaster's MTC and Digital Interlocking System: A system for MTC and W-MTC, but this one is for standard MTC
  2. --Hi! you are not supposted to access this file. get out debil cyka blyat
  3. --...unless you know what you're doing. I mean, why are you doing this? This file isn't really for editing.
  4. --You get what you get and you don't throw a fit. That's what my kindergarden teacher said.
  5.  
  6. -- Menu API provided by cyanisaac and ProjectB, licensed under the MIT license.
  7. --JSON API provided by ElvishJerricco.
  8. --Initalize all the things!
  9. --Initalize signalblocks
  10. --TrainControl 1.1
  11. --Use one channel instead of multiple for signal communications
  12. local sbraw = fs.open("signalDatabase", "r")
  13. local cdraw = fs.open("computerdatabase", "r")
  14. local sraw = fs.open("system", "r")
  15. local craw = fs.open("config", "r")
  16. os.loadAPI("menu")
  17. local signalBlocks = textutils.unserialise(sbraw.readAll())
  18. local system = sraw.readAll()
  19. local computerDatabase = textutils.unserialise(cdraw.readAll())
  20. local config
  21. local clientsDoneInSelfTest = {}
  22. local radio = peripheral.find("pdmInstructionRadio")
  23. local sendQueue
  24. local bundledIO = peripheral.find("bio")
  25. local lastBundledCable = 0
  26. sbraw.close()
  27. sraw.close()
  28. cdraw.close()
  29. local modem = peripheral.find("modem")
  30. if modem == nil then
  31. error("TrainControl cannot continue because a modem has not been found.")
  32. end
  33.  
  34. if fs.exists("menu") == false  then
  35. print("Downloading menu API..stand by..")
  36. shell.run("pastebin get UK4ATXvH menu")
  37. sleep(1)
  38. end
  39.  
  40. if fs.exists("json") == false then
  41.     print("Downloading JSON API..stand by..")
  42. shell.run("pastebin get 4nRg9CHU json")
  43. sleep(1)
  44. end
  45.  
  46. if fs.exists("encrypt") == false then
  47.     print("Downloading encryption API...stand by..")
  48.     shell.run("pastebin get WRTfH0yx encrypt")
  49.     sleep(1)
  50. end
  51.  
  52.  
  53.  
  54.  
  55. os.loadAPI("menu")
  56. os.loadAPI("json")
  57. os.loadAPI("encrypt")
  58.  
  59.  
  60. --Oh yeah, don't forget about the main functions.
  61.  
  62. local function setup()
  63.     local madeConfig = {}
  64.     term.clear()
  65.     term.setCursorPos(1,1)
  66.     print("Please set a name for this system for identification (ex. railroad/divison name): ")
  67.     local systemName = read()
  68.     madeConfig["SystemName"] = systemName
  69.     menu.doInfoScreen("Welcome to TrainControl!", "Hi, Welcome! This will help you set up the program to get your trains running safely.")
  70.     local theMenu = {"Modem using Rednet (most recommended)", "Bundled Redstone (requires FirePeripherals for 1.7.10)", "Redstone (least recommended, don't use it)"}
  71.     madeConfig["SignalConnectionType"] = menu.doMenu("TrainControl Setup | Signal Connection Type", theMenu)
  72.     theMenu = {"MTC", "W-MTC", "Don't use it"}
  73.     madeConfig["UseMTC"] = menu.doMenu("TrainControl Setup | MTC Type", theMenu)
  74.  
  75.     while true do
  76.     term.clear()
  77.     term.setCursorPos(1,1)
  78.  
  79.     print("Please define a channel for Modem communications. It doesn't really matter which one you choose, as long as it's not being used for something else.")
  80.     local ModemChannel = read()
  81.     local hmm = tonumber(ModemChannel)
  82.     if hmm ~= nil then
  83.        
  84.         if hmm > 65535 then
  85.  
  86.             print("That was not a valid channel. Channels cannot as be higher than 65535.")  
  87.         else
  88.             madeConfig["ModemChannel"] = hmm
  89.             break
  90.         end
  91.        
  92.     else
  93.         print("That was not a valid channel. Channels must be numbers and as high as 65535.")
  94.     end
  95. end
  96.  
  97.     term.clear()
  98.     term.setCursorPos(1,1)
  99.     print("Please define a channel for Terminal communications. It doesn't really matter which one you choose, as long as it's not being used for something else.")
  100.     local terminalChannel = read()
  101.     madeConfig["TerminalChannel"] = terminalChannel
  102.  
  103.     term.clear()
  104.     term.setCursorPos(1,1)
  105.  
  106.  
  107.    
  108.     menu.doInfoScreen("Setup Complete!", "TrainControl will start after you press ENTER.")
  109.     print(textutils.serialise(madeConfig))
  110.     config = madeConfig
  111.     local writeConfig = fs.open("config", "w")
  112.     writeConfig.write(textutils.serialise(config))
  113.     writeConfig.close()
  114.     sleep(2)
  115.  
  116.  
  117. end
  118.  
  119. local function getSomethingFromTable(theTable, thingWanted) -- A workaround to crappy CC/Lua. >:(
  120.     for k, v in pairs(theTable) do
  121.         if k == thingWanted then
  122.             return v
  123.         end
  124.       end
  125. end
  126.  
  127. local function saveTableFile(path, watchuwant) -- Quicker way to do things w o a h
  128.     local handle = fs.open(path, "w")
  129.     handle.write(textutils.serialise(whatchuwant))
  130.     handle.close()
  131. end
  132.  
  133. local function loadTableFile(path) -- Quiciker way to do things w o a h
  134.     local handle = fs.open(path, "r")
  135.     local thing = textutils.unserialise(handle.readAll())
  136.     handle.close()
  137.     return thing
  138. end
  139.  
  140.  
  141. local function doEncrypt(thing1)
  142.  
  143.    -- local ok = encrypt.encrypt(thing1, "kgkg499tgi34ikg39koowklfow0o349")
  144.     --return ok
  145.     return thing1
  146. end
  147.  
  148. local function doDecrypt(thing)
  149.    -- local ok = encrypt.decrypt(thing, "kgkg499tgi34ikg39koowklfow0o349")
  150.    -- return ok
  151.    return thing
  152. end
  153.  
  154.  
  155. local function controlSignals()
  156.     --Signal status meanings:
  157.     --1 = Unoccupied, green
  158.     --2 = Unoccupied, yellow (train in next block so use caution)
  159.     --3 = Occupied, train is in it.
  160.  
  161.     --Reload the signaldatabase, just in case anything was changed.
  162.     signalDatabase = loadTableFile("signalDatabase")
  163.     if config.SignalConnectionType == 1 then
  164.        
  165.         --Connection type is Modem based, so do everything modem related here.
  166.         local event, side, sendChannel, replyChannel, message, distance = os.pullEvent()
  167.  
  168.         if event == "modem_message" then
  169.         local response = doDecrypt(message)
  170.  
  171.         if response.funct == "blockOccupied" then
  172.               signalBlocks[response.source].status = 3
  173.              
  174.               if getSomethingFromTable(signalBlocks[response.source], "prev") ~= "none" then
  175.                 local previousSignal = getSomethingFromTable(signalBlocks[response.source], "prev")
  176.  
  177.                 if getSomethingFromTable(signalBlocks[response.source], "prev").status ~= 3 then signalBlocks[previousSignal].status = 2 end
  178.                 print("Sending a signal update to the previous signal.")
  179.                 modem.transmit(config["ModemChannel"], config["ModemChannel"], doEncrypt({funct = "updateSignalStatus", signalStatus = getSomethingFromTable(signalBlocks, previousSignal).status, to = getSomethingFromTable(signalBlocks, previousSignal).name}))
  180.               end
  181.  
  182.               print(response.source.." is occupied. ")
  183.  
  184.         end
  185.         if response.funct == "blockReleased" then
  186.             print(response.source)
  187.             signalBlocks[response.source].status = 1
  188.             print(response.source.." is released.")
  189.            
  190.             if getSomethingFromTable(signalBlocks[response.source], "prev") ~= "none" then
  191.                 local previousSignal = getSomethingFromTable(signalBlocks[response.source], "prev")
  192.                 if getSomethingFromTable(signalBlocks[response.source], "prev").status ~= 3 then signalBlocks[previousSignal].status = 1 end
  193.                 print("Sending signalupdate to the previous signal.")
  194.                 modem.transmit(config["ModemChannel"], config["ModemChannel"],  doEncrypt({funct = "updateSignalStatus", signalStatus = getSomethingFromTable(signalBlocks, previousSignal).status, to = getSomethingFromTable(signalBlocks, previousSignal).name}))
  195.               end
  196.  
  197.         end
  198.         if getSomethingFromTable(signalBlocks[response.source], "next") ~= "none" and signalBlocks[response.source].occupiedBy ~= nil and config["UseMTC"] == 2 then
  199.             local nextSignal = getSomethingFromTable(signalBlocks[response.source], "next")
  200.             print("Sending a signal update for W-MTC to the previous signal. ")
  201.             modem.transmit(config["ModemChannel"], config["ModemChannel"],  doEncrypt({funct = "updateSignalStatus", signalStatus = getSomethingFromTable(signalBlocks, nextSignal).status, to = getSomethingFromTable(signalBlocks, previousSignal).name, isWMTCOkay = true}))
  202.         else
  203.             modem.transmit(config["ModemChannel"], config["ModemChannel"],  doEncrypt({funct = "updateSignalStatus", signalStatus = getSomethingFromTable(signalBlocks, nextSignal).status, to = getSomethingFromTable(signalBlocks, previousSignal).name, isWMTCOkay = false}))
  204.           end
  205.  
  206.         if response.funct == "switchOccupied" then
  207.             print(response.source.. " is occupied!")
  208.             signalBlocks[response.source].status = 1
  209.            
  210.            
  211.         end
  212.  
  213.         if response.funct == "switchReleased" then
  214.             print(response.source.. "is released!")
  215.             signalBlocks[response.source].status = 0
  216.         end
  217.  
  218.         if response.funct == "setSwitchStatus" then
  219.             --owo
  220.             modem.transmit(getSomethingFromTable(tonumber(config["ModemChannel"]), tonumber(config["ModemChannel"]), encrypt(textutils.serialise({funct = "updateSwitchStatus", switchStatus = response.switchStatus}))))
  221.         end
  222.  
  223.         --Alright, we got that, now send it to the signals.
  224.         if response.source ~= "Terminal" then
  225.         modem.transmit(config["ModemChannel"], config["ModemChannel"], doEncrypt({funct = "updateSignalStatus", signalStatus = getSomethingFromTable(signalBlocks, response.source).status, to = getSomethingFromTable(signalBlocks, response.source).name, isWMTCOkay = getSomethingFromTable(signalBlocks, response.source).isWMTCOkay}))
  226.         end
  227.         if config["UseMTC"] == 2 then
  228.             --Alright..W-MTC on..generate a MTC data packet.
  229.             local speedLimit1
  230.             local nextSpeedLimit1
  231.             local speedChange1
  232.             local changeX
  233.             local changeY
  234.             local changeZ
  235.             local endSoon1
  236.             local xStopPoint
  237.             local yStopPoint
  238.             local zStopPoint
  239.             local mtcStats
  240.             local nextSignal = getSomethingFromTable(signalBlocks[response.source], "next")
  241.             if getSomethingFromTable(signalBlocks[nextSignal], "status") == 3 then
  242.                 speedLimit = getSomethingFromTable(signalBlocks[response.source], "yellowSpeedLimit")
  243.                 endSoon = true
  244.                 xStopPoint = getSomethingFromTable(signalBlocks[nextSignal], "positionX")
  245.                 yStopPoint = getSomethingFromTable(signalBlocks[nextSignal], "positionY")
  246.                 zStopPoint = getSomethingFromTable(signalBlocks[nextSignal], "positionZ")
  247.             end
  248.             if getSomethingFromTable(signalBlocks[nextSignal], "status") == 2 then
  249.                 nextSpeedLimit =  getSomethingFromTable(signalBlocks[response.source], "yellowSpeedLimit")
  250.                 speedChange = true
  251.                 changeX = getSomethingFromTable(signalBlocks[nextSignal], "positionX")
  252.                 changeY = getSomethingFromTable(signalBlocks[nextSignal], "positionY")
  253.                 changeZ = getSomethingFromTable(signalBlocks[nextSignal], "positionZ")
  254.             end
  255.  
  256.             --Alright..generate the JSON.
  257.             local send = {speedLimit = speedLimit1, nextSpeedLimit = nextSpeedLimit1, speedChange = speedChange1, endSoon = endSoon1}
  258.  
  259.             if endSoon1 then
  260.                 send["xStopPoint"] = xStopPoint
  261.                 send["yStopPoint"] = yStopPoint
  262.                 send["zStopPoint"] = zStopPoint
  263.             end
  264.  
  265.             if getSomethingFromTable(signalBlocks[response.source], "next") == "none" then
  266.                 mtcStat = 2
  267.                 send["mtcStatus"] = mtcStat
  268.             end
  269.  
  270.             if speedChange1 then
  271.                 send["nextSpeedLimitChangeX"] = changeX
  272.                 send["nextSpeedLimitChangeY"] = changeY
  273.                 send["nextSpeedLimitChangeZ"] = changeZ
  274.             end
  275.             --Is it done? Okay, print it just in case.
  276.             print(textutils.serialise(send))
  277.             --Okay, it's finally done, put it into the queue.
  278.             if signalBlocks[response.source].occupiedBy ~= nil then
  279.          
  280.           signalBlocks[response.source].sendTo = {funct = "sendToTrain", sendTo = signalBlocks[response.source].occupiedBy, send1 = send}
  281.            end
  282.         end
  283.         --Also, finally, save it to the file so it can be used later.
  284.      --   saveTableFile("signaldatabase", signalDatabase)
  285.          if response.funct == "radio_message" then
  286.         --Okay, it came from a train. Let's check it out.
  287.         local response1 = response.message
  288.         print(textutils.serialise(response1))
  289.         if response1.funct == "attemptConnection" then
  290.             --Attempting..alright..welcome!
  291.             --Give temp data, actual limits will be sent on the next update
  292.             local send = {funct = "startlevel2", speedLimit = 60, nextSpeedLimit = 0, speedChange = false, stationStopSoon = false, mtcStatus = 1 }
  293.            
  294.         end
  295.  
  296.         if response1.funct == "update" then
  297.             --Great, an update! There may have been something you have missed, so I'm going to send it to you.
  298.            signalBlocks[response.signalBlock].occupiedBy = response.sendChannel  
  299.            
  300.            if signalBlocks[response.signalBlock].sendTo ~= nil then
  301.             modem.transmit(signalBlock[response.signalBlock].wirelessRadioChannel, modem["ModemChannel"],  signalBlocks[response.source].sendTo)
  302.            end
  303.  
  304.         end
  305.  
  306.         if response1.funct == "disconnect" then
  307.  
  308.         end
  309.  
  310.  
  311.     end
  312.  
  313.     end
  314.  
  315. --No? it's not a modem message? Then maybe it's something else.
  316. elseif config.SignalConnectionType == 2 then
  317.     local event, input, id = os.pullEvent("redstone")
  318. --Input is raw color.
  319. --Green signal output is combined with green
  320. --Yellow signal output is combined with yellow
  321. --Red signal output is combined with red
  322.  
  323.  
  324.     --Alright..let's see what signal is occupied.
  325.    --[[  if response.funct == "blockOccupied" then
  326.         signalBlocks[response.source].status = 3
  327.        
  328.         if getSomethingFromTable(signalBlocks[response.source], "prev") ~= "none" then
  329.           local previousSignal = getSomethingFromTable(signalBlocks[response.source], "prev")
  330.  
  331.           if getSomethingFromTable(signalBlocks[response.source], "prev").status ~= 3 then signalBlocks[previousSignal].status = 2 end
  332.           print("Sending a signal update to the previous signal.")
  333.           modem.transmit(config["ModemChannel"], config["ModemChannel"], doEncrypt({funct = "updateSignalStatus", signalStatus = getSomethingFromTable(signalBlocks, previousSignal).status, to = getSomethingFromTable(signalBlocks, previousSignal).name}))
  334.         end
  335.  
  336.         print(response.source.." is occupied. ")
  337.  
  338.   end
  339. ]]
  340.   if lastBundledCable < input then
  341.     --Someone added
  342.     connectionRemoved = colors.subtract(lastBundledCable, input)
  343.   end
  344.  
  345.   local connectionRemoved
  346.  
  347.   signalBlocks[input].status = 3
  348.   print(getSomethingFromTable(signalBlocks[input], "name").." is occupied.")
  349.   bundledIO.setBundledOutput(colors.combine(input, colors.red))
  350.   if getSomethingFromTable(signalBlocks[input], "prev") ~= "none" and getSomethingFromTable(signalBlocks[input], "prev") ~= nil and getSomethingFromTable(getSomethingFromTable(signalBlocks[input], "prev"), "status") ~= 3  then
  351.    
  352.     --Get the previous signal. Let's set that one to yellow, unless it is already occupied, then don't. Also check if it isn't nil for dumb reasons
  353.    
  354.     getSomethingFromTable(signalBlocks[input], "prev").status = 2
  355.     --Now that it's set, let's set the colors right.
  356.     print("Setting the correct aspect to the previous signal.")
  357.     bundledIO.setBundledOutput(colors.combine(getSomethingFromTable(signalBlocks[input], "prev").color, colors.yellow))
  358.  
  359. end
  360.  
  361. if connectionRemoved then
  362. if getSomethingFromTable(signalBlocks[input], "prev") ~= "none" and getSomethingFromTable(signalBlocks[input], "prev") ~= nil and getSomethingFromTable(getSomethingFromTable(signalBlocks[input], "prev"), "status") ~= 3  then
  363.    
  364.     --Get the previous signal. Let's set that one to green, unless it is already occupied, then don't. Also check if it isn't nil for dumb reasons
  365.    
  366.     getSomethingFromTable(signalBlocks[input], "prev").status = 1
  367.     --Now that it's set, let's set the colors right.
  368.     print("Setting the correct aspect to the previous signal.")
  369.     bundledIO.setBundledOutput(colors.combine(getSomethingFromTable(signalBlocks[input], "prev").color, colors.yellow))
  370.  
  371. end
  372.  
  373. end
  374.  
  375. end
  376.  
  377. end
  378.  
  379. local function starts_with(str, start)
  380.     return str:sub(1, #start) == start
  381.  end
  382.  
  383.  local function ends_with(str, ending)
  384.     return ending == "" or str:sub(-#ending) == ending
  385.  end
  386.  
  387. local function powerUpSelfTest()
  388.  
  389.  
  390. --Okay, host the system via rednet.
  391.    
  392. --...test for all of them.
  393. if config.SignalConnectionType == 1 then
  394.    --rednet.send(72, {71, "test", "test!!!"})
  395.    
  396.     for key,value in pairs( computerDatabase ) do
  397.         local send = doEncrypt({funct = "attemptConnection", to = key})
  398.         print("Attempting connection to "..key)
  399.         modem.transmit(tonumber(config["ModemChannel"]), tonumber(config["ModemChannel"]), send)
  400.        
  401.         --Wait for a response, but also there's a timeout.
  402.         local timeout = os.startTimer(15)
  403.         while true do
  404.             local event = {os.pullEvent()}
  405.             if event[1] == "modem_message" then
  406.             --Decode the response.
  407.             local response = doDecrypt(event[5])
  408.             if response.funct == "ok" then
  409.               print("Connection to "..response.source.."is okay.")
  410.               table.insert(clientsDoneInSelfTest, response.source)
  411.              break
  412.             end
  413.             elseif event[1] == "timer" and event[2] == timeout then
  414.             print("Connection to "..key.." aborted because it took too long.")
  415.  
  416.                 return false
  417.             end
  418.  
  419.         end
  420.  
  421.     end
  422.        
  423. end
  424.     return true
  425. end
  426.  
  427.  
  428.  
  429.  
  430.  
  431.  
  432.  
  433. ---..initalized? Great! now print stuff.
  434. term.setCursorPos(1,1)
  435. print(fs.exists("config") )
  436. if fs.exists("config") then
  437. local craw = fs.open("config", "r")
  438. local theconfig = textutils.unserialise(craw.readAll())
  439. config = theconfig
  440. craw.close()
  441. else
  442. setup()
  443. end
  444. term.clear()
  445. term.setTextColor(colors.green)
  446. print("PeachMaster's MTC and Digital Interlocking System")
  447. textutils.slowPrint("TrainControl 1.1", 15)
  448. print("This copy is for: "..getSomethingFromTable(config, "SystemName"))
  449. term.setTextColor(colors.white)
  450. modem.open(tonumber(config["ModemChannel"]))
  451. modem.open(tonumber(config["TerminalChannel"]))
  452. if powerUpSelfTest() then
  453.     print("Power Up Self Test completed succesfully!")
  454.     while true do
  455.     controlSignals()    
  456.     end
  457.  
  458. else
  459.  
  460. end
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement