Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- --@version 1.2
- local version = 1.2
- local ht_up = http.get("https://pastebin.com/raw/p94WHguU")
- local up_A = ht_up.readLine()
- local up_B = ht_up.readAll()
- local up = up_A .. up_B
- ht_up.close()
- local their_version = tonumber(up_A:sub(12))
- if (their_version > version) then
- local fi_up = fs.open(shell.getRunningProgram(), "w")
- fi_up.write(up)
- fi_up.close()
- shell.run(shell.getRunningProgram())
- return
- end
- --stack trace builder by apemanzilla
- local function buildStackTrace(rootErr)
- local trace = {}
- local i, hitEnd, _, e = 4, false
- repeat
- _, e =
- pcall(
- function()
- error("<tracemarker>", i)
- end
- )
- i = i + 1
- if e == "xpcall: <tracemarker>" or e == "pcall: <tracemarker>" then
- hitEnd = true
- break
- end
- table.insert(trace, e)
- until i > 10
- table.remove(trace)
- table.remove(trace, 1)
- if rootErr:match("^" .. trace[1]:match("^(.-:%d+)")) then
- table.remove(trace, 1)
- end
- local out = {}
- table.insert(out, rootErr)
- for i, v in ipairs(trace) do
- table.insert(out, " at " .. v:match("^(.-:%d+)"))
- end
- if not hitEnd then
- table.insert(out, " ...")
- end
- return table.concat(out, "\n")
- end
- local ok, err =
- xpcall(
- function()
- ---------------------------------
- -- BLITWRAP BY ELDIDIDESTROYER --
- ---------------------------------
- local explode = function(div, str, replstr, includeDiv)
- if (div == "") then
- return false
- end
- local pos, arr = 0, {}
- for st, sp in function()
- return string.find(str, div, pos, false)
- end do
- table.insert(arr, string.sub(replstr or str, pos, st - 1 + (includeDiv and #div or 0)))
- pos = sp + 1
- end
- table.insert(arr, string.sub(replstr or str, pos))
- return arr
- end
- local blitwrap = function(char, text, back, noWrite)
- local cWords = explode(" ", char, nil, true)
- local tWords = explode(" ", char, text, true)
- local bWords = explode(" ", char, back, true)
- local ox, oy = term.getCursorPos()
- local cx, cy, ty = ox, oy, 1
- local scr_x, scr_y = term.getSize()
- local output = {}
- for a = 1, #cWords do
- if ((cx + #cWords[a]) > scr_x) then
- cx = 1
- if (cy == scr_y) then
- term.scroll(1)
- end
- cy = math.min(cy + 1, scr_y)
- ty = ty + 1
- end
- if not noWrite then
- term.setCursorPos(cx, cy)
- term.blit(cWords[a], tWords[a], bWords[a])
- end
- cx = cx + #cWords[a]
- output[ty] = output[ty] or {"", "", ""}
- output[ty][1] = output[ty][1] .. cWords[a]
- output[ty][2] = output[ty][2] .. tWords[a]
- output[ty][3] = output[ty][3] .. bWords[a]
- end
- return output
- end
- ------------------
- -- BLITWRAP END --
- ------------------
- local pingdata_channel = 895
- local connect_channel = 885
- local d = false
- local mod = nil
- local our_rids = {}
- for k, v in pairs(peripheral.getNames()) do
- if peripheral.getType(v) == "modem" then
- rednet.open(v)
- mod = peripheral.wrap(v)
- d = true
- end
- end
- if not d or not mod then
- error("A modem is required!")
- end
- local dump_log = {}
- local function download_file(url, target)
- local ht = http.get(url)
- local data = ht.readAll()
- ht.close()
- local file = fs.open(target, "w")
- file.write(data)
- file.close()
- end
- local function read_file(target)
- local file = fs.open(target, "r")
- local data = file.readAll()
- file.close()
- return data
- end
- local function isOurRid(id)
- for k, v in pairs(our_rids) do
- if v == id then
- return true
- end
- end
- return false
- end
- local servers = {}
- local serber = nil
- local truelog = {}
- --------------
- -- UI stuff --
- --------------
- local s_offset = 0
- local current_server = 1
- local chat_win = nil
- local type_win = nil
- local chat_w, chat_h
- local function cwrite(t, str, y)
- local w, h = t.getSize()
- t.setCursorPos(math.floor((w / 2) - (str:len() / 2)), y or (h / 2))
- t.write(str)
- end
- local function setup_win()
- local tn = term.native()
- local w, h = tn.getSize()
- chat_win = window.create(tn, 1, 1, w, h - 1, true)
- chat_win.setCursorBlink(false)
- chat_win.setBackgroundColor(colors.black)
- chat_win.setTextColor(colors.white)
- chat_win.clear()
- chat_w, chat_h = chat_win.getSize()
- type_win = window.create(tn, 1, h, w, 1, true)
- type_win.setBackgroundColor(colors.black)
- type_win.setTextColor(colors.lightGray)
- type_win.clear()
- term.redirect(type_win)
- end
- local function kill(terminated)
- if (type(term.native) == "function") then
- term = m
- term.redirect(term.native())
- term = term.native()
- else
- term.redirect(term)
- end
- term.setBackgroundColor(colors.black)
- term.setTextColor(colors.white)
- term.clear()
- chat_win = nil
- type_win = nil
- if (serber and serber.cid) then
- ringnet.sendData(
- serber.cid,
- textutils.serialize(
- {
- type = "CHAT_LOGOUT"
- }
- )
- )
- end
- end
- local function writeRight(text, y)
- local w, h = term.getSize()
- term.setCursorPos(w - #text, y)
- term.write(text)
- end
- local function draw_list()
- if #servers < 1 then
- error("No servers found.", 0)
- end
- term.setBackgroundColor(colors.black)
- term.clear()
- for i = 1, #servers do
- local serv = servers[i]
- if i == current_server then
- term.setBackgroundColor(colors.white)
- term.setTextColor(colors.black)
- else
- term.setBackgroundColor(colors.black)
- term.setTextColor(colors.white)
- end
- term.setCursorPos(1, i)
- term.clearLine()
- term.write(serv.name)
- writeRight(tostring(serv.fingerprint):sub(1, 8), i)
- end
- local _w, _h = term.getSize()
- term.setBackgroundColor(colors.black)
- term.setTextColor(colors.white)
- cwrite(term, "Press Enter to join a server.", _h)
- end
- local function draw_chat()
- chat_win.setBackgroundColor(colors.black)
- chat_win.setTextColor(colors.white)
- chat_win.clear()
- for y = 1, chat_h do
- local o = truelog[(#truelog + s_offset - chat_h) + y]
- if (type(o) == "table") then
- chat_win.setCursorPos(1, y)
- chat_win.blit(o[1], o[2], o[3])
- end
- y = y + 1
- end
- end
- --------------
- -- UI End --
- --------------
- -- API Loading
- local function getAPI(name, url)
- local apiloc = "/" .. name
- if (not fs.exists(apiloc)) then
- local newapiloc = shell and shell.resolveProgram(name) or nil
- if type(newapiloc) ~= "string" then
- download_file(url, apiloc)
- else
- apiloc = newapiloc
- end
- end
- return apiloc
- end
- local ringnet = require(getAPI("ringnet", "https://pastebin.com/raw/tUe94t9J"))
- getAPI("aeslua", "https://git.io/aeslua")
- os.loadAPI("aeslua")
- ringnet.openChannel(pingdata_channel)
- ringnet.openChannel(connect_channel)
- local tid = nil
- term.setBackgroundColor(colors.black)
- term.setTextColor(colors.white)
- term.clear()
- cwrite(term, "Scanning for servers...")
- local rid = math.random(100000, 999999)
- table.insert(our_rids, rid)
- mod.transmit(
- pingdata_channel,
- pingdata_channel,
- textutils.serialize(
- {
- type = "SERVER_DATA",
- rid = rid
- }
- )
- )
- parallel.waitForAll(
- ringnet.connectionHandler,
- function()
- sleep(1.75)
- os.queueEvent("timer_chat")
- return
- end,
- function()
- local mode = 1
- local timer_tripped = false
- while true do
- local ev = {os.pullEvent()}
- table.insert(dump_log, {mode, ev[1]})
- if (ev[1] == "modem_message" and not timer_tripped) then
- local mes = ev[5]
- if (type(mes) == "string") then
- mes = textutils.unserialize(mes)
- end
- if
- (mes.type == "SERVER_RETURNDATA" and isOurRid(mes.to) and type(mes.hid) == "string" and string.len(mes.hid) == 8)
- then
- --print("Server! Name: " .. tostring(mes.name) .. " | Fingerprint: " .. tostring(mes.fingerprint):sub(1, 12))
- table.insert(
- servers,
- {
- name = mes.name,
- fingerprint = mes.fingerprint,
- hid = mes.hid,
- locked = mes.locked or false
- }
- )
- end
- elseif (mode == 1 and ev[1] == "timer_chat") then
- mode = 2
- timer_tripped = true
- draw_list()
- elseif (mode == 2 and ev[1] == "key") then
- if (ev[2] == 208 or ev[2] == 205) then
- current_server = current_server + 1
- if (current_server > #servers) then
- current_server = 1
- end
- elseif (ev[2] == 200 or ev[2] == 203) then
- current_server = current_server - 1
- if (current_server < 1) then
- current_server = #servers
- end
- elseif (ev[2] == 28) then
- mode = 3
- serber = servers[current_server]
- print(serber.hid)
- end
- if (ev[2] ~= 28) then
- draw_list()
- end
- elseif (mode == 3) then
- ringnet.openTunnel(serber.hid, connect_channel)
- mode = 4
- elseif (mode == 4 and ev[1] == "tunnel_finish" and ev[3] == serber.hid) then
- --elseif (mode == 5 and ev[1] == "mouse_scroll") then
- -- s_offset = (s_offset) + ev[2]
- -- s_offset = math.min(math.max(s_offset, 0), #truelog)
- -- draw_chat()
- serber.cid = ev[2]
- setup_win()
- mode = 5
- elseif (mode == 5 and ev[1] == "secure_receive" and ev[2] == serber.cid) then
- local cid = ev[2]
- local data = ev[3]
- if (serber.password) then
- data = aeslua.decrypt(serber.password, data, aeslua.AES128, aeslua.CFBMODE)
- end
- if (type(data) == "string") then
- data = textutils.unserialize(data)
- end
- if (type(data) == "table") then
- table.insert(dump_log, textutils.serialize(data))
- if (data.type == "CHAT_LOG" and type(data.log) == "table") then
- truelog = {}
- for i = 1, #data.log do
- local a = data.log[i]
- if ((type(a.name) == "string" or a.raw == true) and type(a.mes) == "string") then
- if not a.raw then
- local prefix = (a.name .. ": ")
- local dje = (a.mes)
- local combined = (prefix .. dje)
- local output =
- blitwrap(combined, (string.rep("0", #prefix) .. string.rep("8", #dje)), string.rep("f", #combined), true)
- for k, v in pairs(output) do
- table.insert(truelog, v)
- end
- else
- local output = blitwrap(a.mes, string.rep("8", #a.mes), string.rep("f", #a.mes), true)
- for k, v in pairs(output) do
- table.insert(truelog, v)
- end
- end
- end
- end
- local k = fs.open("/.TESTDUMP", "w")
- k.write(textutils.serialize(truelog))
- k.close()
- draw_chat()
- end
- end
- end
- end
- end,
- function()
- local named = false
- local still_locked = true
- while true do
- if (type_win ~= nil) then
- if not (serber.locked) then
- still_locked = false
- end
- type_win.setBackgroundColor(colors.black)
- type_win.setTextColor(colors.lightGray)
- type_win.clear()
- term.redirect(type_win)
- if (serber.locked and still_locked and not named) then
- cwrite(chat_win, "Please enter this server's password")
- elseif (not still_locked and not named) then
- cwrite(chat_win, "Please type the name you want below")
- end
- local a = tostring(read())
- if a == "_EXIT" then
- kill()
- error("Exited.", 0)
- elseif (serber.locked and still_locked) then
- if (aeslua.decrypt(a, serber.locked, aeslua.AES128, aeslua.CFBMODE) == "_A_COMMON_ENCRYPTION_STRING") then
- still_locked = false
- serber.password = a
- end
- elseif (not still_locked) then
- if named then
- if a:lower() == "/exit" or a:lower() == "/logout" then
- ringnet.sendData(
- serber.cid,
- textutils.serialize(
- {
- type = "CHAT_LOGOUT"
- }
- )
- )
- sleep(1.5)
- kill()
- error()
- elseif a:lower() == "/forceupdate" or a:lower() == "/update" then
- ringnet.sendData(
- serber.cid,
- textutils.serialize(
- {
- type = "CHAT_FORCEUPDATE"
- }
- )
- )
- else
- ringnet.sendData(
- serber.cid,
- textutils.serialize(
- {
- type = "CHAT_CHAT",
- message = a
- }
- )
- )
- end
- else
- ringnet.sendData(
- serber.cid,
- textutils.serialize(
- {
- type = "CHAT_LOGIN",
- name = a
- }
- )
- )
- chat_win.setBackgroundColor(colors.black)
- chat_win.setTextColor(colors.white)
- chat_win.clear()
- named = true
- end
- end
- end
- sleep(0.1)
- end
- end
- )
- end,
- function(err)
- term.redirect(term.native and term.native() or term.current())
- local stack = buildStackTrace(err)
- printError("\nRingchat has crashed! Stack trace:")
- printError(stack)
- local file = fs.open("/chat.err", "w")
- file.write(tostring(stack))
- file.close()
- end
- )
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement