Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- -- Installation script for RailSignal components.
- -- By Andrew Lalis.
- local function tableLength(t)
- local c = 0
- for _ in pairs(t) do
- c = c + 1
- end
- return c
- end
- local function startsWith(str, s)
- return str:find(s, 1, true) == 1
- end
- local function printSep()
- local w, h = term.getSize()
- print(string.rep("-", w))
- end
- local function readNum()
- local num = nil
- repeat
- local s = io.read()
- if s ~= nil then num = tonumber(s) end
- if num == nil then print("Please enter a valid number.") end
- until num ~= nil
- return num
- end
- local function readStr(default)
- while true do
- local str = io.read()
- if str ~= nil and string.len(str) > 0 then
- return str
- elseif default ~= nil then
- return default
- end
- end
- repeat str = io.read() until str ~= nil
- return str
- end
- local function readBool()
- while true do
- local str = io.read()
- if str ~= nil and string.len(str) > 0 then
- str = string.upper(str)
- if str == "Y" or str == "YES" then return true end
- if str == "N" or str == "NO" then return false end
- end
- print("Please enter \"yes\" or \"no\".")
- end
- end
- local function readRedstoneSide()
- while true do
- local str = io.read()
- if str ~= nil and string.len(str) > 0 then
- str = string.lower(str)
- for _, side in pairs(redstone.getSides()) do
- if str == side then return side end
- end
- end
- print("Please enter a valid side: top, bottom, left, right, front or back.")
- end
- end
- local function choose(choices, required)
- if required == nil then required = true end
- local choiceCount = tableLength(choices)
- local i = 1
- local keys = {}
- for k, value in pairs(choices) do
- keys[i] = k
- i = i + 1
- end
- table.sort(keys)
- for k, v in pairs(keys) do
- local str = choices[v] or v
- print(k .. ") " .. str)
- end
- while true do
- local input = io.read()
- if input ~= nil and string.len(input) > 0 then
- local chosenIndex = tonumber(input)
- if chosenIndex == nil or chosenIndex < 1 or chosenIndex > choiceCount then
- print("Invalid choice. Please enter a number from 1 to " .. choiceCount .. ".")
- else
- return keys[chosenIndex]
- end
- elseif not required then
- return nil
- else
- print("Invalid input. Please enter a number from 1 to " .. choiceCount .. ".")
- end
- end
- end
- local function choosePeripheral(pType, excludeNames, required)
- -- Filter to only peripherals starting with the type, and aren't excluded.
- local filter = function(name, p)
- for _, v in pairs(excludeNames) do
- if v == name then return false end
- end
- return startsWith(name, pType)
- end
- local ps = {peripheral.find(pType, filter)}
- local choices = {}
- for k, v in pairs(ps) do
- choices[k] = peripheral.getName(v)
- end
- if tableLength(choices) == 0 then
- print("No valid peripherals of the type " .. pType .. " found. Please ensure they're connected to the network, then try again.")
- return nil
- end
- local choice = choose(choices, required)
- return ps[choice]
- end
- local function createSignalConfig(apiUrl, rsId, usedDetectors, usedMonitors)
- local signal = {}
- print("Enter the signal id.")
- signal["id"] = readNum()
- local resp = http.get(apiUrl .. "/railSystems/" .. rsId .. "/signals/" .. signal.id)
- if resp == nil or resp.getResponseCode() ~= 200 then
- print("Could not find signal with id " .. signal.id .. ".")
- return nil
- end
- local signalData = textutils.unserializeJSON(resp.readAll())
- print("Enter the redstone input side for this signal.")
- signal["redstoneInputSide"] = readRedstoneSide()
- print("Choose the detector for this signal.")
- local det = choosePeripheral("ir_augment_detector", usedDetectors)
- if det == nil then return nil end
- signal["detector"] = peripheral.getName(det)
- table.insert(usedDetectors, signal.detector)
- signal["branches"] = {}
- for k, con in pairs(signalData.branchConnections) do
- print("Choose the monitor that will display the status of the " .. con.direction .. " connection to branch \"" .. con.branch.name .. "\". Leave empty if this connection doesn't have a monitor.")
- local mon = choosePeripheral("monitor", usedMonitors, false)
- local monitorName = nil
- if mon ~= nil then
- monitorName = peripheral.getName(mon)
- table.insert(usedMonitors, monitorName)
- end
- local branch = {
- id = con.branch.id,
- direction = con.direction,
- monitor = monitorName
- }
- table.insert(signal.branches, branch)
- end
- return signal
- end
- -- SIGNAL INSTALL
- local function downloadSignalScript()
- local shouldDownload = true
- if fs.exists("sig.lua") then
- print("sig.lua already exists. Would you like to overwrite it?")
- if readBool() then
- fs.delete("sig.lua")
- else
- shouldDownload = false
- end
- end
- if shouldDownload then
- print("Downloading signal program...")
- local result = shell.execute("pastebin", "get", "erA3mSfd", "sig.lua")
- if not result then
- print("Error occurred while downloading.")
- return
- end
- end
- end
- local function buildSignalConfig(apiUrl, rsId)
- local config = {}
- config["apiUrl"] = apiUrl
- local wsUrlSuffix = apiUrl:sub(8) .. "/ws-signal"
- if startsWith(apiUrl, "https://") then
- config["wsUrl"] = "wss://" .. wsUrlSuffix
- else
- config["wsUrl"] = "ws://" .. wsUrlSuffix
- end
- config["wsHeader"] = "X-RailSignal-SignalId"
- config["rsId"] = rsId
- config["trainScanInterval"] = 0.5
- config["statusColors"] = {
- FREE = colors.lime,
- OCCUPIED = colors.red,
- ERROR = colors.blue,
- NONE = colors.white
- }
- config["paletteColors"] = {
- [colors.red] = 0xFF0000,
- [colors.lime] = 0x00FF00,
- [colors.blue] = 0x0000FF,
- [colors.white] = 0xFFFFFF
- }
- config["signals"] = {}
- return config
- end
- local function finalizeSignalConfig(config)
- if fs.exists("sig_config.tbl") then
- fs.delete("sig_config.tbl")
- end
- local f = io.open("sig_config.tbl", "w")
- if f == nil then
- print("Could not open sig_config.tbl to write configuration data.")
- return
- end
- f:write(textutils.serialize(config))
- f:close()
- print("Saved signal configuration.")
- if fs.exists("startup.lua") then
- fs.delete("startup.lua")
- end
- local f = io.open("startup.lua", "w")
- if f == nil then
- print("Could not open startup.lua to write startup script.")
- return
- end
- f:write("-- Run RailSignal signal script.\nshell.execute(\"sig\")\n")
- f:close()
- print("Created startup script.")
- print("Starting up signal now...")
- shell.execute("sig")
- end
- local function installSignal(apiUrl, rsId)
- print("Installing RailSignal signal system.")
- downloadSignalScript()
- local config = buildSignalConfig(apiUrl, rsId)
- print("How many signals will this computer manage?")
- local signalCount = choose({1, 2, 3, 4, 5})
- local usedDetectors = {}
- local usedMonitors = {}
- for i = 1, signalCount do
- printSep()
- print("Signal " .. i .. " / " .. signalCount .. ":")
- local signal = createSignalConfig(apiUrl, rsId, usedDetectors, usedMonitors)
- if signal == nil then
- print("Could not create configuration for this signal, would you like to quit?")
- if readBool() then
- return
- end
- else
- table.insert(config.signals, signal)
- end
- end
- printSep()
- finalizeSignalConfig(config)
- end
- -- MAIN SCRIPT
- print("RailSignal Installer")
- printSep()
- print("Please enter the URL of your RailSignal server. Please ensure that it's running during the entirety of the installation. For example, \"http://localhost:8080\" is a valid URL. Leave blank to use that URL.")
- local rsUrl = readStr("http://localhost:8080")
- local apiUrl = rsUrl .. "/api"
- local resp = http.get(apiUrl .. "/status")
- if resp == nil or resp.getResponseCode() ~= 200 then
- print("Could not connect to RailSignal API at " .. apiUrl .. "/status" .. " Please check that your RailSignal server is running and that your URL is correct.")
- return
- end
- print("Successfully connected to the RailSignal API at " .. apiUrl)
- printSep()
- print("Please enter the id of the rail system to install components to. If no rail system is configured yet, go to " .. rsUrl .. " to create one.")
- local rsId = readNum()
- local resp = http.get(apiUrl .. "/railSystems/" .. rsId)
- if resp == nil or resp.getResponseCode() ~= 200 then
- print("Could not find a rail system with id " .. rsId .. ". Please check that the system exists prior to running the installation.")
- return
- end
- local railSystem = textutils.unserializeJSON(resp.readAll())
- print("Will install for the rail system: " .. railSystem.name)
- printSep()
- print("What type of system would you like to install?")
- local c = choose({signal="Signal"})
- printSep()
- if c == "signal" then
- installSignal(apiUrl, rsId)
- end
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement