Added installer and start of central server
This commit is contained in:
parent
71d24820ed
commit
8c5c425a4f
|
@ -0,0 +1,101 @@
|
||||||
|
--[[
|
||||||
|
A central server to coordinate a rail network. This central server keeps a
|
||||||
|
graph of the entire network, and handles requests to find paths to route
|
||||||
|
traffic through.
|
||||||
|
]]--
|
||||||
|
|
||||||
|
local RECEIVE_CHANNEL = 45453
|
||||||
|
|
||||||
|
local modem = peripheral.wrap("top") or error("Missing top modem")
|
||||||
|
modem.open(RECEIVE_CHANNEL)
|
||||||
|
|
||||||
|
local loadGraph()
|
||||||
|
local g = nil
|
||||||
|
local f = io.open("network_graph.tbl", "r")
|
||||||
|
g = textutils.unserialize(f:read("*a"))
|
||||||
|
f:close()
|
||||||
|
--return g
|
||||||
|
return {
|
||||||
|
nodes = {
|
||||||
|
{
|
||||||
|
id = "Junction-HandieVale",
|
||||||
|
connections = {
|
||||||
|
{from = "handievale", to = "N1"},
|
||||||
|
{from = "N1", to = "handievale"},
|
||||||
|
{from = "handievale", to = "W1"},
|
||||||
|
{from = "W1", to = "handievale"},
|
||||||
|
{from = "N1", to = "W1"},
|
||||||
|
{from = "W1", to = "N1"}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id = "Junction-Middlecross",
|
||||||
|
connections = {
|
||||||
|
{from = "W1", to = "W2"},
|
||||||
|
{from = "W2", to = "W1"},
|
||||||
|
{from = "N2", to = "S1"},
|
||||||
|
{from = "S1", to = "N2"}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
edges = {
|
||||||
|
{
|
||||||
|
{id = "handievale", length = 16},
|
||||||
|
{id = "N1", length = -1},
|
||||||
|
{id = "W1", length = 300},
|
||||||
|
{id = "N2", length = 600},
|
||||||
|
{id = "E1", length = 75},
|
||||||
|
{id = "end", length = 60},
|
||||||
|
{id = "W2", length = -1},
|
||||||
|
{id = "S1", length = -1}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
|
local findNodeById(graph, nodeId)
|
||||||
|
for _, node in pairs(graph.nodes) do
|
||||||
|
if node.id == nodeId then return node end
|
||||||
|
end
|
||||||
|
return nil
|
||||||
|
end
|
||||||
|
|
||||||
|
local findEdgeById(graph, edgeId)
|
||||||
|
for _, edge in pairs(graph.edges) do
|
||||||
|
if edge.id == edgeId then return edge end
|
||||||
|
end
|
||||||
|
return nil
|
||||||
|
end
|
||||||
|
|
||||||
|
local findNextEdges(graph, edgeId)
|
||||||
|
local edges = {}
|
||||||
|
for _, node in pairs(graph.nodes) do
|
||||||
|
for _, connection in pairs(node.connections) do
|
||||||
|
if connection.from == edgeId then
|
||||||
|
table.insert(edges, findEdgeById(connection.to))
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
return edges
|
||||||
|
end
|
||||||
|
|
||||||
|
local findPath(graph, nodeA, nodeB)
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
local handleRequest(graph, replyChannel, msg)
|
||||||
|
if msg.command == "ROUTE" then
|
||||||
|
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
local function handleRequests(graph)
|
||||||
|
while true do
|
||||||
|
local event, side, channel, replyChannel, msg, dist = os.pullEvent("modem_message")
|
||||||
|
if channel == RECEIVE_CHANNEL then
|
||||||
|
handleRequest(graph, replyChannel, msg)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
handleRequests(loadGraph())
|
|
@ -0,0 +1,180 @@
|
||||||
|
--[[
|
||||||
|
A general-purpose installation script that can be run on any cc-rail-router
|
||||||
|
hardware to set it up for its purpose.
|
||||||
|
]]--
|
||||||
|
|
||||||
|
local function clearScreen()
|
||||||
|
if term.isColor() then
|
||||||
|
term.setTextColor(colors.white)
|
||||||
|
term.setBackgroundColor(colors.black)
|
||||||
|
end
|
||||||
|
term.clear()
|
||||||
|
term.setCursorPos(1, 1)
|
||||||
|
end
|
||||||
|
|
||||||
|
local function promptAnyKey()
|
||||||
|
print("Press any key to continue.")
|
||||||
|
os.pullEvent("key")
|
||||||
|
end
|
||||||
|
|
||||||
|
local function readString(prompt, allowEmpty)
|
||||||
|
if allowEmpty == nil then allowEmpty = true end
|
||||||
|
local txt = nil
|
||||||
|
repeat
|
||||||
|
clearScreen()
|
||||||
|
print(prompt)
|
||||||
|
local x, y = term.getCursorPos()
|
||||||
|
term.setCursorPos(1, y + 2)
|
||||||
|
term.setCursorBlink(true)
|
||||||
|
txt = io.read()
|
||||||
|
term.setCursorBlink(false)
|
||||||
|
if not allowEmpty and (not txt or #txt == 0) then
|
||||||
|
term.setCursorPos(1, y + 4)
|
||||||
|
print("Empty input not allowed.")
|
||||||
|
os.sleep(2)
|
||||||
|
end
|
||||||
|
until (txt ~= nil and #txt > 0) or allowEmpty
|
||||||
|
return txt
|
||||||
|
end
|
||||||
|
|
||||||
|
local function readNumber(prompt, minVal, maxVal, defaultVal)
|
||||||
|
local num = nil
|
||||||
|
while num == nil or num < minVal or num > maxVal do
|
||||||
|
local txt = readString(prompt, defaultVal ~= nil)
|
||||||
|
if not txt or #txt == 0 then return defaultVal end
|
||||||
|
num = tonumber(txt)
|
||||||
|
if num == nil or num < minVal or num > maxVal then
|
||||||
|
print("Invalid number input. Should be between "..minVal.." and "..maxVal..".")
|
||||||
|
os.sleep(2)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
return num
|
||||||
|
end
|
||||||
|
|
||||||
|
local function readChoice(prompt, choices, defaultChoice)
|
||||||
|
while true do
|
||||||
|
clearScreen()
|
||||||
|
print(prompt)
|
||||||
|
for i, choice in pairs(choices) do
|
||||||
|
print(i..". "..choice)
|
||||||
|
end
|
||||||
|
local x, y = term.getCursorPos()
|
||||||
|
term.setCursorPos(1, y + 2)
|
||||||
|
local txt = io.read()
|
||||||
|
if (not txt or #txt == 0) and defaultChoice ~= nil then
|
||||||
|
return defaultChoice
|
||||||
|
end
|
||||||
|
local txtNum = tonumber(txt)
|
||||||
|
if txtNum then
|
||||||
|
if txtNum < 1 or txtNum > #choices then
|
||||||
|
print("Invalid numeric choice. Should be between 1 and "..#choices..".")
|
||||||
|
os.sleep(2)
|
||||||
|
else
|
||||||
|
return choices[txtNum]
|
||||||
|
end
|
||||||
|
else
|
||||||
|
for i, choice in pairs(choices) do
|
||||||
|
if choice == txt then
|
||||||
|
return choice
|
||||||
|
end
|
||||||
|
end
|
||||||
|
print("Invalid choice. Please choose one of the options.")
|
||||||
|
os.sleep(2)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
local function waitForPeripheralAttach(side)
|
||||||
|
while true do
|
||||||
|
local event, s = os.pullEvent("peripheral")
|
||||||
|
if side == nil or s == side then return s end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
local function waitForPeripheralDetach(side)
|
||||||
|
while true do
|
||||||
|
local event, s = os.pullEvent("peripheral_detach")
|
||||||
|
if side == nil or s == side then return s end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
local function waitForModemPresent(side, wireless)
|
||||||
|
while true do
|
||||||
|
local modem = peripheral.wrap(side)
|
||||||
|
if modem == nil then
|
||||||
|
print("Please attach modem to side "..side..".")
|
||||||
|
promptAnyKey()
|
||||||
|
elseif not modem.isWireless or modem.isWireless() ~= wireless then
|
||||||
|
local name = "modem"
|
||||||
|
if wireless then name = "wireless " .. name end
|
||||||
|
print("The peripheral on side "..side.." is not a compatible "..name..". Please detach this peripheral and add the correct one now.")
|
||||||
|
promptAnyKey()
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
local function saveTable(filename, table)
|
||||||
|
local f = io.open(filename, "w")
|
||||||
|
f:write(textutils.serialize(table))
|
||||||
|
f:close()
|
||||||
|
end
|
||||||
|
|
||||||
|
local function createStartupScript(program)
|
||||||
|
local sf = io.open("startup.lua", "w")
|
||||||
|
sf:write("shell.execute(\""..program.."\")\n")
|
||||||
|
sf:close()
|
||||||
|
end
|
||||||
|
|
||||||
|
local function installStation()
|
||||||
|
clearScreen()
|
||||||
|
print("Installing station beacon software.")
|
||||||
|
os.sleep(1)
|
||||||
|
waitForModemPresent("top", true)
|
||||||
|
local config = {}
|
||||||
|
config.name = readString("Enter the station's codename.", false)
|
||||||
|
config.displayName = readString("Enter the station's display name.", false)
|
||||||
|
config.range = readNumber("Enter the broadcast range for this station, in blocks.", 4, 64)
|
||||||
|
clearScreen()
|
||||||
|
saveTable("station_config.tbl", config)
|
||||||
|
print("Saved station configuration to station_config.tbl.")
|
||||||
|
if fs.exists("station.lua") then
|
||||||
|
print("Deleting existing station.lua.")
|
||||||
|
fs.delete("station.lua")
|
||||||
|
end
|
||||||
|
shell.execute("wget", "https://github.com/andrewlalis/cc-rail-router/raw/main/station.lua", "station.lua")
|
||||||
|
print("Downloaded station.lua.")
|
||||||
|
createStartupScript("station.lua")
|
||||||
|
end
|
||||||
|
|
||||||
|
local function installSwitch()
|
||||||
|
clearScreen()
|
||||||
|
print("Installing switch controller software.")
|
||||||
|
os.sleep(1)
|
||||||
|
waitForModemPresent("top", true)
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
local function installRouter()
|
||||||
|
clearScreen()
|
||||||
|
print("Installing handheld router software.")
|
||||||
|
os.sleep(1)
|
||||||
|
waitForModemPresent("back", true)
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
clearScreen()
|
||||||
|
print("Rail Software Installation Wizard")
|
||||||
|
os.sleep(2)
|
||||||
|
local choice = readChoice(
|
||||||
|
"What type of software would you like to install?",
|
||||||
|
{"Station Beacon", "Switch Controller", "Handheld Router", "Exit"}
|
||||||
|
)
|
||||||
|
if choice == "Station Beacon" then
|
||||||
|
installStation()
|
||||||
|
elseif choice == "Switch Controller" then
|
||||||
|
installSwitch()
|
||||||
|
elseif choice == "Handheld Router" then
|
||||||
|
installRouter()
|
||||||
|
else
|
||||||
|
print("Exiting.")
|
||||||
|
end
|
|
@ -1,6 +1,7 @@
|
||||||
--[[
|
--[[
|
||||||
This program should be installed on a portable computer with a wireless
|
This program should be installed on a portable computer with a wireless
|
||||||
modem, to act as a routing beacon in conjunction with managed switches.
|
modem, to act as a routing beacon in conjunction with managed switches.
|
||||||
|
It also serves as the GUI that users of the system interact with.
|
||||||
]]--
|
]]--
|
||||||
local SWITCH_CHANNEL = 45450
|
local SWITCH_CHANNEL = 45450
|
||||||
local STATION_BROADCAST_CHANNEL = 45451
|
local STATION_BROADCAST_CHANNEL = 45451
|
||||||
|
|
Loading…
Reference in New Issue