Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- --PeachMaster's MTC and Digital Interlocking System: A system for MTC and W-MTC, but this one is for standard MTC
- --Hi! you are not supposted to access this file. get out debil cyka blyat
- --...unless you know what you're doing. I mean, why are you doing this? This file isn't really for editing.
- --You get what you get and you don't throw a fit. That's what my kindergarden teacher said.
- -- Menu API provided by cyanisaac and ProjectB, licensed under the MIT license.
- --JSON API provided by ElvishJerricco.
- --Initalize all the things!
- --Initalize signalblocks
- --TrainControl 1.1
- --Use one channel instead of multiple for signal communications
- local sbraw = fs.open("signalDatabase", "r")
- local cdraw = fs.open("computerdatabase", "r")
- local sraw = fs.open("system", "r")
- local craw = fs.open("config", "r")
- os.loadAPI("menu")
- local signalBlocks = textutils.unserialise(sbraw.readAll())
- local system = sraw.readAll()
- local computerDatabase = textutils.unserialise(cdraw.readAll())
- local config
- local clientsDoneInSelfTest = {}
- local radio = peripheral.find("pdmInstructionRadio")
- local sendQueue
- local bundledIO = peripheral.find("bio")
- local lastBundledCable = 0
- sbraw.close()
- sraw.close()
- cdraw.close()
- local modem = peripheral.find("modem")
- if modem == nil then
- error("TrainControl cannot continue because a modem has not been found.")
- end
- if fs.exists("menu") == false then
- print("Downloading menu API..stand by..")
- shell.run("pastebin get UK4ATXvH menu")
- sleep(1)
- end
- if fs.exists("json") == false then
- print("Downloading JSON API..stand by..")
- shell.run("pastebin get 4nRg9CHU json")
- sleep(1)
- end
- if fs.exists("encrypt") == false then
- print("Downloading encryption API...stand by..")
- shell.run("pastebin get WRTfH0yx encrypt")
- sleep(1)
- end
- os.loadAPI("menu")
- os.loadAPI("json")
- os.loadAPI("encrypt")
- --Oh yeah, don't forget about the main functions.
- local function setup()
- local madeConfig = {}
- term.clear()
- term.setCursorPos(1,1)
- print("Please set a name for this system for identification (ex. railroad/divison name): ")
- local systemName = read()
- madeConfig["SystemName"] = systemName
- menu.doInfoScreen("Welcome to TrainControl!", "Hi, Welcome! This will help you set up the program to get your trains running safely.")
- local theMenu = {"Modem using Rednet (most recommended)", "Bundled Redstone (requires FirePeripherals for 1.7.10)", "Redstone (least recommended, don't use it)"}
- madeConfig["SignalConnectionType"] = menu.doMenu("TrainControl Setup | Signal Connection Type", theMenu)
- theMenu = {"MTC", "W-MTC", "Don't use it"}
- madeConfig["UseMTC"] = menu.doMenu("TrainControl Setup | MTC Type", theMenu)
- while true do
- term.clear()
- term.setCursorPos(1,1)
- 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.")
- local ModemChannel = read()
- local hmm = tonumber(ModemChannel)
- if hmm ~= nil then
- if hmm > 65535 then
- print("That was not a valid channel. Channels cannot as be higher than 65535.")
- else
- madeConfig["ModemChannel"] = hmm
- break
- end
- else
- print("That was not a valid channel. Channels must be numbers and as high as 65535.")
- end
- end
- term.clear()
- term.setCursorPos(1,1)
- 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.")
- local terminalChannel = read()
- madeConfig["TerminalChannel"] = terminalChannel
- term.clear()
- term.setCursorPos(1,1)
- menu.doInfoScreen("Setup Complete!", "TrainControl will start after you press ENTER.")
- print(textutils.serialise(madeConfig))
- config = madeConfig
- local writeConfig = fs.open("config", "w")
- writeConfig.write(textutils.serialise(config))
- writeConfig.close()
- sleep(2)
- end
- local function getSomethingFromTable(theTable, thingWanted) -- A workaround to crappy CC/Lua. >:(
- for k, v in pairs(theTable) do
- if k == thingWanted then
- return v
- end
- end
- end
- local function saveTableFile(path, watchuwant) -- Quicker way to do things w o a h
- local handle = fs.open(path, "w")
- handle.write(textutils.serialise(whatchuwant))
- handle.close()
- end
- local function loadTableFile(path) -- Quiciker way to do things w o a h
- local handle = fs.open(path, "r")
- local thing = textutils.unserialise(handle.readAll())
- handle.close()
- return thing
- end
- local function doEncrypt(thing1)
- -- local ok = encrypt.encrypt(thing1, "kgkg499tgi34ikg39koowklfow0o349")
- --return ok
- return thing1
- end
- local function doDecrypt(thing)
- -- local ok = encrypt.decrypt(thing, "kgkg499tgi34ikg39koowklfow0o349")
- -- return ok
- return thing
- end
- local function controlSignals()
- --Signal status meanings:
- --1 = Unoccupied, green
- --2 = Unoccupied, yellow (train in next block so use caution)
- --3 = Occupied, train is in it.
- --Reload the signaldatabase, just in case anything was changed.
- signalDatabase = loadTableFile("signalDatabase")
- if config.SignalConnectionType == 1 then
- --Connection type is Modem based, so do everything modem related here.
- local event, side, sendChannel, replyChannel, message, distance = os.pullEvent()
- if event == "modem_message" then
- local response = doDecrypt(message)
- if response.funct == "blockOccupied" then
- signalBlocks[response.source].status = 3
- if getSomethingFromTable(signalBlocks[response.source], "prev") ~= "none" then
- local previousSignal = getSomethingFromTable(signalBlocks[response.source], "prev")
- if getSomethingFromTable(signalBlocks[response.source], "prev").status ~= 3 then signalBlocks[previousSignal].status = 2 end
- print("Sending a signal update to the previous signal.")
- modem.transmit(config["ModemChannel"], config["ModemChannel"], doEncrypt({funct = "updateSignalStatus", signalStatus = getSomethingFromTable(signalBlocks, previousSignal).status, to = getSomethingFromTable(signalBlocks, previousSignal).name}))
- end
- print(response.source.." is occupied. ")
- end
- if response.funct == "blockReleased" then
- print(response.source)
- signalBlocks[response.source].status = 1
- print(response.source.." is released.")
- if getSomethingFromTable(signalBlocks[response.source], "prev") ~= "none" then
- local previousSignal = getSomethingFromTable(signalBlocks[response.source], "prev")
- if getSomethingFromTable(signalBlocks[response.source], "prev").status ~= 3 then signalBlocks[previousSignal].status = 1 end
- print("Sending signalupdate to the previous signal.")
- modem.transmit(config["ModemChannel"], config["ModemChannel"], doEncrypt({funct = "updateSignalStatus", signalStatus = getSomethingFromTable(signalBlocks, previousSignal).status, to = getSomethingFromTable(signalBlocks, previousSignal).name}))
- end
- end
- if getSomethingFromTable(signalBlocks[response.source], "next") ~= "none" and signalBlocks[response.source].occupiedBy ~= nil and config["UseMTC"] == 2 then
- local nextSignal = getSomethingFromTable(signalBlocks[response.source], "next")
- print("Sending a signal update for W-MTC to the previous signal. ")
- modem.transmit(config["ModemChannel"], config["ModemChannel"], doEncrypt({funct = "updateSignalStatus", signalStatus = getSomethingFromTable(signalBlocks, nextSignal).status, to = getSomethingFromTable(signalBlocks, previousSignal).name, isWMTCOkay = true}))
- else
- modem.transmit(config["ModemChannel"], config["ModemChannel"], doEncrypt({funct = "updateSignalStatus", signalStatus = getSomethingFromTable(signalBlocks, nextSignal).status, to = getSomethingFromTable(signalBlocks, previousSignal).name, isWMTCOkay = false}))
- end
- if response.funct == "switchOccupied" then
- print(response.source.. " is occupied!")
- signalBlocks[response.source].status = 1
- end
- if response.funct == "switchReleased" then
- print(response.source.. "is released!")
- signalBlocks[response.source].status = 0
- end
- if response.funct == "setSwitchStatus" then
- --owo
- modem.transmit(getSomethingFromTable(tonumber(config["ModemChannel"]), tonumber(config["ModemChannel"]), encrypt(textutils.serialise({funct = "updateSwitchStatus", switchStatus = response.switchStatus}))))
- end
- --Alright, we got that, now send it to the signals.
- if response.source ~= "Terminal" then
- 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}))
- end
- if config["UseMTC"] == 2 then
- --Alright..W-MTC on..generate a MTC data packet.
- local speedLimit1
- local nextSpeedLimit1
- local speedChange1
- local changeX
- local changeY
- local changeZ
- local endSoon1
- local xStopPoint
- local yStopPoint
- local zStopPoint
- local mtcStats
- local nextSignal = getSomethingFromTable(signalBlocks[response.source], "next")
- if getSomethingFromTable(signalBlocks[nextSignal], "status") == 3 then
- speedLimit = getSomethingFromTable(signalBlocks[response.source], "yellowSpeedLimit")
- endSoon = true
- xStopPoint = getSomethingFromTable(signalBlocks[nextSignal], "positionX")
- yStopPoint = getSomethingFromTable(signalBlocks[nextSignal], "positionY")
- zStopPoint = getSomethingFromTable(signalBlocks[nextSignal], "positionZ")
- end
- if getSomethingFromTable(signalBlocks[nextSignal], "status") == 2 then
- nextSpeedLimit = getSomethingFromTable(signalBlocks[response.source], "yellowSpeedLimit")
- speedChange = true
- changeX = getSomethingFromTable(signalBlocks[nextSignal], "positionX")
- changeY = getSomethingFromTable(signalBlocks[nextSignal], "positionY")
- changeZ = getSomethingFromTable(signalBlocks[nextSignal], "positionZ")
- end
- --Alright..generate the JSON.
- local send = {speedLimit = speedLimit1, nextSpeedLimit = nextSpeedLimit1, speedChange = speedChange1, endSoon = endSoon1}
- if endSoon1 then
- send["xStopPoint"] = xStopPoint
- send["yStopPoint"] = yStopPoint
- send["zStopPoint"] = zStopPoint
- end
- if getSomethingFromTable(signalBlocks[response.source], "next") == "none" then
- mtcStat = 2
- send["mtcStatus"] = mtcStat
- end
- if speedChange1 then
- send["nextSpeedLimitChangeX"] = changeX
- send["nextSpeedLimitChangeY"] = changeY
- send["nextSpeedLimitChangeZ"] = changeZ
- end
- --Is it done? Okay, print it just in case.
- print(textutils.serialise(send))
- --Okay, it's finally done, put it into the queue.
- if signalBlocks[response.source].occupiedBy ~= nil then
- signalBlocks[response.source].sendTo = {funct = "sendToTrain", sendTo = signalBlocks[response.source].occupiedBy, send1 = send}
- end
- end
- --Also, finally, save it to the file so it can be used later.
- -- saveTableFile("signaldatabase", signalDatabase)
- if response.funct == "radio_message" then
- --Okay, it came from a train. Let's check it out.
- local response1 = response.message
- print(textutils.serialise(response1))
- if response1.funct == "attemptConnection" then
- --Attempting..alright..welcome!
- --Give temp data, actual limits will be sent on the next update
- local send = {funct = "startlevel2", speedLimit = 60, nextSpeedLimit = 0, speedChange = false, stationStopSoon = false, mtcStatus = 1 }
- end
- if response1.funct == "update" then
- --Great, an update! There may have been something you have missed, so I'm going to send it to you.
- signalBlocks[response.signalBlock].occupiedBy = response.sendChannel
- if signalBlocks[response.signalBlock].sendTo ~= nil then
- modem.transmit(signalBlock[response.signalBlock].wirelessRadioChannel, modem["ModemChannel"], signalBlocks[response.source].sendTo)
- end
- end
- if response1.funct == "disconnect" then
- end
- end
- end
- --No? it's not a modem message? Then maybe it's something else.
- elseif config.SignalConnectionType == 2 then
- local event, input, id = os.pullEvent("redstone")
- --Input is raw color.
- --Green signal output is combined with green
- --Yellow signal output is combined with yellow
- --Red signal output is combined with red
- --Alright..let's see what signal is occupied.
- --[[ if response.funct == "blockOccupied" then
- signalBlocks[response.source].status = 3
- if getSomethingFromTable(signalBlocks[response.source], "prev") ~= "none" then
- local previousSignal = getSomethingFromTable(signalBlocks[response.source], "prev")
- if getSomethingFromTable(signalBlocks[response.source], "prev").status ~= 3 then signalBlocks[previousSignal].status = 2 end
- print("Sending a signal update to the previous signal.")
- modem.transmit(config["ModemChannel"], config["ModemChannel"], doEncrypt({funct = "updateSignalStatus", signalStatus = getSomethingFromTable(signalBlocks, previousSignal).status, to = getSomethingFromTable(signalBlocks, previousSignal).name}))
- end
- print(response.source.." is occupied. ")
- end
- ]]
- if lastBundledCable < input then
- --Someone added
- connectionRemoved = colors.subtract(lastBundledCable, input)
- end
- local connectionRemoved
- signalBlocks[input].status = 3
- print(getSomethingFromTable(signalBlocks[input], "name").." is occupied.")
- bundledIO.setBundledOutput(colors.combine(input, colors.red))
- if getSomethingFromTable(signalBlocks[input], "prev") ~= "none" and getSomethingFromTable(signalBlocks[input], "prev") ~= nil and getSomethingFromTable(getSomethingFromTable(signalBlocks[input], "prev"), "status") ~= 3 then
- --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
- getSomethingFromTable(signalBlocks[input], "prev").status = 2
- --Now that it's set, let's set the colors right.
- print("Setting the correct aspect to the previous signal.")
- bundledIO.setBundledOutput(colors.combine(getSomethingFromTable(signalBlocks[input], "prev").color, colors.yellow))
- end
- if connectionRemoved then
- if getSomethingFromTable(signalBlocks[input], "prev") ~= "none" and getSomethingFromTable(signalBlocks[input], "prev") ~= nil and getSomethingFromTable(getSomethingFromTable(signalBlocks[input], "prev"), "status") ~= 3 then
- --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
- getSomethingFromTable(signalBlocks[input], "prev").status = 1
- --Now that it's set, let's set the colors right.
- print("Setting the correct aspect to the previous signal.")
- bundledIO.setBundledOutput(colors.combine(getSomethingFromTable(signalBlocks[input], "prev").color, colors.yellow))
- end
- end
- end
- end
- local function starts_with(str, start)
- return str:sub(1, #start) == start
- end
- local function ends_with(str, ending)
- return ending == "" or str:sub(-#ending) == ending
- end
- local function powerUpSelfTest()
- --Okay, host the system via rednet.
- --...test for all of them.
- if config.SignalConnectionType == 1 then
- --rednet.send(72, {71, "test", "test!!!"})
- for key,value in pairs( computerDatabase ) do
- local send = doEncrypt({funct = "attemptConnection", to = key})
- print("Attempting connection to "..key)
- modem.transmit(tonumber(config["ModemChannel"]), tonumber(config["ModemChannel"]), send)
- --Wait for a response, but also there's a timeout.
- local timeout = os.startTimer(15)
- while true do
- local event = {os.pullEvent()}
- if event[1] == "modem_message" then
- --Decode the response.
- local response = doDecrypt(event[5])
- if response.funct == "ok" then
- print("Connection to "..response.source.."is okay.")
- table.insert(clientsDoneInSelfTest, response.source)
- break
- end
- elseif event[1] == "timer" and event[2] == timeout then
- print("Connection to "..key.." aborted because it took too long.")
- return false
- end
- end
- end
- end
- return true
- end
- ---..initalized? Great! now print stuff.
- term.setCursorPos(1,1)
- print(fs.exists("config") )
- if fs.exists("config") then
- local craw = fs.open("config", "r")
- local theconfig = textutils.unserialise(craw.readAll())
- config = theconfig
- craw.close()
- else
- setup()
- end
- term.clear()
- term.setTextColor(colors.green)
- print("PeachMaster's MTC and Digital Interlocking System")
- textutils.slowPrint("TrainControl 1.1", 15)
- print("This copy is for: "..getSomethingFromTable(config, "SystemName"))
- term.setTextColor(colors.white)
- modem.open(tonumber(config["ModemChannel"]))
- modem.open(tonumber(config["TerminalChannel"]))
- if powerUpSelfTest() then
- print("Power Up Self Test completed succesfully!")
- while true do
- controlSignals()
- end
- else
- end
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement