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
|
||||
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 STATION_BROADCAST_CHANNEL = 45451
|
||||
|
|
Loading…
Reference in New Issue