Files
opus-apps/gps/gpsServer.lua
2019-01-05 01:50:58 -05:00

143 lines
3.6 KiB
Lua

local Config = require('config')
local GPS = require('gps')
local Util = require('util')
local args = { ... }
local gps = _G.gps
local os = _G.os
local peripheral = _G.peripheral
local term = _G.term
local turtle = _G.turtle
local vector = _G.vector
local WIRED_MODEM = 'computercraft:wired_modem_full'
local CABLE = 'computercraft:cable'
local ENDER_MODEM = 'computercraft:advanced_modem'
local positions = { }
local function build()
if not turtle.has(WIRED_MODEM, 8) or
not turtle.has(CABLE, 4) or
not turtle.has(ENDER_MODEM, 4) then
error([[Place into inventory:
* 8 Wired modem (blocks)
* 4 Network cables
* 4 Ender modems]])
end
local blocks = {
{ x = 1, y = 0, z = 0, b = WIRED_MODEM },
{ x = 2, y = 0, z = 0, b = CABLE },
{ x = 2, y = 1, z = 0, b = CABLE },
{ x = 2, y = 2, z = 0, b = WIRED_MODEM },
{ x = 2, y = 3, z = 0, b = ENDER_MODEM },
{ x = -1, y = 0, z = 0, b = WIRED_MODEM },
{ x = -2, y = 0, z = 0, b = CABLE },
{ x = -2, y = 1, z = 0, b = CABLE },
{ x = -2, y = 2, z = 0, b = WIRED_MODEM },
{ x = -2, y = 3, z = 0, b = ENDER_MODEM },
{ x = 0, y = 0, z = 1, b = WIRED_MODEM },
{ x = 0, y = 0, z = 2, b = WIRED_MODEM },
{ x = 0, y = 1, z = 2, b = ENDER_MODEM },
{ x = 0, y = 0, z = -1, b = WIRED_MODEM },
{ x = 0, y = 0, z = -2, b = WIRED_MODEM },
{ x = 0, y = 1, z = -2, b = ENDER_MODEM },
}
for _,v in ipairs(blocks) do
turtle.placeDownAt(v, v.b)
end
end
local function memoize(t, k, fn)
local e = t[k]
if not e then
e = fn()
t[k] = e
end
return e
end
local function server()
local modems = Config.load('gpsServer')
local computers = { }
if Util.empty(modems) then
error('Missing usr/config/gpsServer configuration file')
end
for k, modem in pairs(modems) do
Util.merge(modem, peripheral.wrap(k))
modem.open(gps.CHANNEL_GPS)
end
while true do
local e, p1, p2, p3, p4, p5 = os.pullEvent( "modem_message" )
if e == "modem_message" then
-- We received a message from a modem
local side, channel, computerId, sMessage, distance = p1, p2, p3, p4, p5
if channel == gps.CHANNEL_GPS and sMessage == "PING" and distance then
-- We received a ping message on the GPS channel, send a response
local modem = modems[side]
if modem then
local computer = memoize(computers, computerId, function() return { } end)
table.insert(computer, {
position = vector.new(modem.x, modem.y, modem.z), distance = distance
})
if #computer == 4 then
local pt = GPS.trilaterate(computer)
if pt then
positions[computerId] = pt
term.clear()
for k,v in pairs(positions) do
Util.print('ID: %d: %s %s %s', k, v.x, v.y, v.z)
end
end
computers[computerId] = nil
end
for _, modem in pairs(modems) do
modem.transmit( computerId, gps.CHANNEL_GPS, { modem.x, modem.y, modem.z })
end
end
end
end
end
end
if args[1] == 'build' then
local y = tonumber(args[2] or 0)
turtle.setPoint({ x = 0, y = -y, z = 0, heading = 0 })
build()
turtle._goto({ x = 0, y = 0, z = 0, heading = 0 })
print('Activate all modems')
print('Press enter when ready')
_G.read()
local modems = { }
peripheral.find('modem', function(name, modem)
if modem.isWireless() then
modems[name] = { x = 0, y = 0, z = 0 }
end
end)
Config.update('gpsServer', modems)
print([[
Configuration file usr/config/gpsServer created.
Add coordinates for each modem.
Use the position of the wired modem below the wireless modem]])
elseif args[1] == 'server' then
server()
else
error('Syntax: gps [build|server]')
end