Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- local cChannel = 15150
- local tArgs = {...}
- local function transmit(channel, reply, message)
- local modem = peripheral.find("modem")
- if modem then
- modem.transmit(channel, reply, message)
- end
- end
- local function openChannel(channel)
- for i,v in pairs(peripheral.getNames()) do
- if peripheral.getType(v) == "modem" then
- peripheral.call(v, "open", channel)
- end
- end
- transmit(cChannel, 0, {
- openChannel = true;
- channel = channel;
- })
- end
- local function closeChannel(channel)
- for i,v in pairs(peripheral.getNames()) do
- if peripheral.getType(v) == "modem" then
- peripheral.call(v, "close", channel)
- end
- end
- transmit(cChannel, 0, {
- closeChannel = true;
- channel = channel;
- })
- end
- local function update(what)
- what = what or "all"
- if what == "gps" or what == "all" then
- local res = http.get("http://pastebin.com/raw/MNBLDRZK")
- transmit(cChannel, 0, {
- update = true;
- source = res.readAll();
- })
- print("updated gps")
- end
- if what == "client" or what == "all" then
- local file = fs.open(shell.getRunningProgram(), "w")
- local res = http.get("http://pastebin.com/raw/ehejuAyW")
- file.write(res.readAll())
- file.close()
- print("updated client")
- end
- if what == "api" or what == "all" then
- local file = fs.open("/gapi", "w")
- local res = http.get("http://pastebin.com/raw/5BRyXSRg")
- file.write(res.readAll())
- file.close()
- print("updated api")
- end
- end
- local function closeAll()
- for i,v in pairs(peripheral.getNames()) do
- if peripheral.getType(v) == "modem" then
- peripheral.call(v, "closeAll")
- end
- end
- transmit(cChannel, 0, {
- closeAll = true;
- })
- end
- local function transmitRequest(channel, reply, id)
- transmit(cChannel, 0, {
- getDistance = true;
- channel = channel;
- reply = reply;
- id = id;
- })
- end
- for i,v in pairs(peripheral.getNames()) do
- if peripheral.getType(v) == "modem" then
- peripheral.call(v, "open", cChannel)
- end
- end
- local defaultColor = colors.white
- local function log(...)
- local str = ""
- local text = {...}
- term.setTextColor(defaultColor)
- for _,val in ipairs(text) do
- if type(val) == "number" then
- term.setTextColor(val)
- else
- str = str .. tostring(val)
- write(val)
- end
- end
- term.setTextColor(defaultColor)
- local file = fs.open("log", "a")
- file.writeLine(str)
- file.close()
- end
- os.loadAPI("gapi")
- if tArgs[1] == "open" then
- local channel = tonumber(tArgs[2] or rednet.CHANNEL_BROADCAST) or rednet.CHANNEL_BROADCAST
- local file = fs.open("channels", "r")
- local chans = {}
- if file then
- chans = textutils.unserialize(file.readAll())
- if type(chans) ~= "table" then
- chans = {}
- end
- file.close()
- end
- table.insert(chans, channel)
- file = fs.open("channels", "w")
- file.write(textutils.serialize(chans))
- file.close()
- return
- elseif tArgs[1] == "close" then
- local channel = tonumber(tArgs[2] or rednet.CHANNEL_BROADCAST) or rednet.CHANNEL_BROADCAST
- closeChannel(channel)
- local file = fs.open("channels", "r")
- local chans = {}
- if file then
- chans = textutils.unserialize(file.readAll())
- if type(chans) ~= "table" then
- chans = {}
- end
- file.close()
- end
- local toRemove = {}
- for i, chan in ipairs(chans) do
- if chans[i] == channel then
- table.insert(toRemove, 1, i)
- end
- end
- for _,i in ipairs(toRemove) do
- table.remove(chans, i)
- end
- file = fs.open("channels", "w")
- file.write(textutils.serialize(chans))
- file.close()
- return
- elseif tArgs[1] == "closeAll" then
- closeAll()
- file = fs.open("channels", "w")
- file.write(textutils.serialize("{}"))
- file.close()
- return
- elseif tArgs[1] == "update" then
- update(tArgs[2])
- return
- end
- local replies = {}
- local repeated = {}
- local queue = {}
- local p1, p2
- local wId
- local timer
- local running = true
- local chatNicks = {}
- local protocolHandlers = {
- ["dns"] = function(channel, reply, message)
- local msg = message.message
- local str
- if type(msg) == "table" then
- if msg.sType == "lookup" then
- str = "(lookup) protocol: " .. tostring(msg.sProtocol) .. ". hostname: " .. tostring(msg.sHostname)
- elseif msg.sType == "lookup response" then
- str = "(lookup response) protocol: " .. tostring(msg.sProtocol) .. ". hostname: " .. tostring(msg.sHostname)
- else
- str = textutils.serialize(msg)
- end
- end
- log(colors.blue, tostring(reply), colors.white, " -> ", colors.red, tostring(channel), colors.white, " -> ", colors.green, tostring(message.nRecipient), colors.cyan, " (dns) ", colors.white, str)
- end;
- ["chat"] = function(channel, reply, message)
- local msg = message.message
- local str = ""
- if type(msg) == "table" then
- if msg.sType == "ping to client" then
- return true
- -- str = "ping to client (user id " .. msg.nUserID .. ")"
- elseif msg.sType == "pong to client" then
- return true
- -- str = "pong to client (user id " .. msg.nUserID .. ")"
- elseif msg.sType == "ping to server" then
- return true
- -- str = "ping to server (user id " .. msg.nUserID .. ")"
- elseif msg.sType == "pong to server" then
- return true
- -- str = "pong to server (user id " .. msg.nUserID .. ")"
- elseif msg.sType == "text" then
- str = msg.sText
- elseif msg.sType == "chat" and msg.sText then
- if chatNicks[message.nRecipient] and chatNicks[message.nRecipient][msg.nUserID] then
- str = "(" .. chatNicks[message.nRecipient][msg.nUserID] .. ") "
- end
- str = str .. msg.sText
- elseif msg.sType == "kick" then
- if chatNicks[message.nRecipient] and chatNicks[message.nRecipient][msg.nUserID] then
- str = "(" .. chatNicks[message.nRecipient][msg.nUserID] .. ") "
- end
- str = str .. "kick (user id " .. tostring(msg.nUserID) .. ")"
- elseif msg.sType == "logout" then
- if chatNicks[message.nRecipient] and chatNicks[message.nRecipient][msg.nUserID] then
- str = "(" .. chatNicks[message.nRecipient][msg.nUserID] .. ") "
- chatNicks[message.nRecipient][msg.nUserID] = nil
- end
- str = str .. "logout (user id " .. tostring(msg.nUserID) .. ")"
- elseif msg.sType == "login" then
- if not chatNicks[message.nRecipient] then
- chatNicks[message.nRecipient] = {}
- end
- chatNicks[message.nRecipient][msg.nUserID] = msg.sUsername
- str = "login " .. msg.sUsername .. " (user id " .. msg.nUserID .. ")"
- else
- str = textutils.serialize(msg)
- end
- end
- log(colors.blue, tostring(reply), colors.white, " -> ", colors.red, tostring(channel), colors.white, " -> ", colors.green, tostring(message.nRecipient), colors.cyan, " (chat) ", colors.white, str)
- end;
- }
- local function requestPos(channel, reply)
- p1, p2 = nil, nil
- wId = math.random()
- replies = {}
- transmitRequest(channel, reply, wId)
- timer = os.startTimer(1)
- end
- local function discardPos(channel, reply)
- transmit(cChannel, 0, {
- discard = true;
- channel = channel;
- reply = reply;
- })
- end
- local function handleMessage(channel, reply, message)
- local logged = false
- if type(message) == "table" then
- if message.nRecipient and message.message and message.nMessageID then -- rednet
- if not repeated[message.nMessageID] or repeated[message.nMessageID] <= os.clock() - 3 then
- repeated[message.nMessageID] = os.clock()
- if message.sProtocol and protocolHandlers[message.sProtocol] then
- if not protocolHandlers[message.sProtocol](channel, reply, message) then
- requestPos(channel, reply)
- else
- discardPos(channel, reply)
- end
- elseif channel == 65535 then -- broadcast
- log(colors.blue, tostring(reply), colors.white, " -> ", colors.red, tostring(channel), colors.white, " -> ", colors.green, tostring(message.nRecipient), colors.cyan, " (broadcast) ", colors.white, textutils.serialize(message.message))
- requestPos(channel, reply)
- elseif channel == 65533 then -- repeater
- log(colors.blue, tostring(reply), colors.white, " -> ", colors.red, tostring(channel), colors.white, " -> ", colors.green, tostring(message.nRecipient), colors.cyan, " (repeat) ", colors.white, "(hidden)") -- .. textutils.serialize(message.message))
- requestPos(channel, reply)
- else
- log(colors.blue, tostring(reply), colors.white, " -> ", colors.red, tostring(channel), colors.white, " -> ", colors.green, tostring(message.nRecipient), colors.cyan, " (send) ", colors.white, textutils.serialize(message.message))
- requestPos(channel, reply)
- end
- else
- discardPos(channel, reply)
- end
- logged = true
- elseif #message == 3 and reply == 65534 then -- gps
- log(colors.blue, tostring(reply), colors.white, " -> ", colors.red, tostring(channel), colors.cyan, " (gps) ", colors.white, "(" .. message[1] .. ", " .. message[2] .. ", " .. message[3] .. ")")
- logged = true
- requestPos(channel, reply)
- end
- elseif channel == 65534 and message == "PING" then
- log(colors.blue, tostring(reply), colors.white, " -> ", colors.red, tostring(channel), colors.cyan, " (gps) ", colors.white, message)
- logged = true
- requestPos(channel, reply)
- end
- if not logged then
- log(colors.blue, tostring(reply), colors.white, " -> ", colors.red, tostring(channel), colors.white, " " .. textutils.serialize(message))
- requestPos(channel, reply)
- end
- end
- local function locationFound(p)
- log(colors.orange, " (" .. p:tostring() .. ")\n")
- p1, p2 = nil, nil
- replies = {}
- timer = nil
- wId = nil
- end
- local monitor = peripheral.find("monitor")
- if monitor then
- term.redirect(monitor)
- monitor.setTextScale(0.5)
- end
- term.setBackgroundColor(colors.gray)
- term.clear()
- term.setCursorPos(1, 1)
- transmit(cChannel, 0, {
- clear = true;
- })
- local channels
- do
- channels = {}
- local file = fs.open("channels", "r")
- if file then
- channels = textutils.unserialize(file.readAll())
- if type(channels) ~= "table" then
- channels = {}
- end
- file.close()
- end
- for _, channel in ipairs(channels) do
- openChannel(channel)
- end
- end
- log("Started sniffer\n")
- while running do
- local success, err = pcall(function()
- if #queue ~= 0 and not timer then
- handleMessage(table.unpack(queue[1]))
- table.remove(queue, 1)
- end
- local event, side, channel, reply, message, distance = os.pullEventRaw()
- if event == "modem_message" then
- if channel == cChannel and reply == 1 and type(message) == "table" then
- if message[3] == wId then
- table.insert(replies, {
- vPosition = vector.new(message[1][1], message[1][2], message[1][3]);
- nDistance = message[2];
- })
- if not p1 and #replies >= 3 then
- p1, p2 = gapi.trilaterate(replies[1], replies[2], replies[#replies])
- if p1 and not p2 then
- locationFound(p1)
- elseif p1 and p2 then
- table.remove(replies, 1)
- table.remove(replies, 1)
- table.remove(replies, #replies)
- local toRemove = {}
- if #replies ~= 0 then
- for i, reply in ipairs(replies) do
- p1, p2 = gapi.narrow(p1, p2, reply)
- if not p2 then
- locationFound(p1)
- break
- end
- end
- end
- replies = {}
- end
- elseif p1 and p2 then
- p1, p2 = gapi.narrow(p1, p2, replies[1])
- table.remove(replies, 1)
- if not p2 then
- locationFound(p1)
- end
- end
- end
- else
- if not timer then
- handleMessage(channel, reply, message)
- else
- table.insert(queue, {channel, reply, message})
- end
- end
- elseif event == "timer" and side == timer then
- if p1 then
- log(colors.orange, " (" .. p1:tostring() .. ") or (" .. p2:tostring() .. ")\n")
- else
- log(colors.orange, " Could not determine position\n")
- end
- timer = nil
- if #queue ~= 0 then
- handleMessage(table.unpack(queue[1]))
- table.remove(queue, 1)
- end
- elseif event == "key" then
- if side == keys.q then
- os.pullEvent("char")
- running = false
- end
- elseif event == "peripheral" then
- if peripheral.getType(side) == "modem" then
- for _,channel in pairs(channels) do
- peripheral.call(side, "open", channel)
- end
- peripheral.call(side, "open", cChannel)
- end
- end
- end)
- if not success then
- log(colors.red, "Error: " .. err .. "\n")
- end
- end
Add Comment
Please, Sign In to add comment