Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- local component = require("component")
- local event = require("event")
- local term = require("term")
- local internet = component.internet
- local computer = require("computer")
- local keyboard = require("keyboard")
- local gpu = component.gpu
- local IAC = string.char(255)
- local DONT = string.char(254)
- local DO = string.char(253)
- local WONT = string.char(252)
- local WILL = string.char(251)
- local SB = string.char(250)
- local SE = string.char(240)
- local GA = string.char(249)
- local EL = string.char(248)
- local EC = string.char(247)
- local AYT = string.char(246)
- local AO = string.char(245)
- local IP = string.char(244)
- local BREAK = string.char(243)
- local DM = string.char(242)
- local NOP = string.char(241)
- local ECHO = string.char(1)
- local SUPPRESS_GO_AHEAD = string.char(3)
- local TERMINAL_TYPE = string.char(24)
- local NAWS = string.char(31)
- local localEcho = true
- local function handleTelnetCommand(connection, cmd)
- if cmd:sub(1, 1) == IAC then
- if cmd:len() == 2 then
- local command = cmd:sub(2, 2)
- if command == GA then
- elseif command == EL then
- io.write("\27[2K")
- elseif command == EC then
- io.write("\b \b")
- elseif command == AYT then
- connection.write("\r\nYes, I'm here\r\n")
- elseif command == AO then
- io.write("\r\nOutput aborted\r\n")
- elseif command == IP then
- io.write("\r\nProcess interrupted\r\n")
- elseif command == BREAK then
- io.write("\r\nBreak received\r\n")
- elseif command == DM then
- elseif command == NOP then
- end
- elseif cmd:len() == 3 then
- local command = cmd:sub(2, 2)
- local option = cmd:sub(3, 3)
- if command == DO then
- if option == TERMINAL_TYPE then
- connection.write(IAC .. WILL .. TERMINAL_TYPE)
- elseif option == NAWS then
- local w, h = gpu.getResolution()
- connection.write(IAC .. WILL .. NAWS)
- connection.write(IAC .. SB .. NAWS .. string.char(math.floor(w / 256)) .. string.char(w % 256) .. string.char(math.floor(h / 256)) .. string.char(h % 256) .. IAC .. SE)
- else
- connection.write(IAC .. WONT .. option)
- end
- elseif command == WILL then
- if option == ECHO then
- localEcho = false
- connection.write(IAC .. DO .. option)
- elseif option == SUPPRESS_GO_AHEAD then
- connection.write(IAC .. DO .. option)
- else
- connection.write(IAC .. DONT .. option)
- end
- elseif command == WONT then
- if option == ECHO then
- localEcho = true
- end
- elseif command == SB then
- local subnegotiation = cmd:sub(4, -2)
- if option == TERMINAL_TYPE then
- connection.write(IAC .. SB .. TERMINAL_TYPE .. "\0" .. "ANSI-BBS" .. IAC .. SE)
- elseif option == NAWS then
- local w, h = gpu.getResolution()
- connection.write(IAC .. SB .. NAWS .. string.char(math.floor(w / 256)) .. string.char(w % 256) .. string.char(math.floor(h / 256)) .. string.char(h % 256) .. IAC .. SE)
- end
- end
- end
- return true
- end
- return false
- end
- local function handleANSI(str)
- local i = 1
- while i <= #str do
- local c = str:sub(i, i)
- if c == "\27" then
- local seq, cmd = str:match("\27%[([%d;]*)([A-Za-z])", i)
- if seq and cmd then
- local params = {}
- for param in seq:gmatch("%d+") do
- table.insert(params, tonumber(param))
- end
- if #params == 0 then
- params = {1}
- end
- if cmd == "H" or cmd == "f" then
- local x, y = params[2] or 1, params[1] or 1
- term.setCursor(x, y)
- elseif cmd == "J" then
- if params[1] == 2 then
- term.clear()
- elseif params[1] == 0 then
- term.clearLine()
- end
- elseif cmd == "K" then
- term.clearLine()
- elseif cmd == "A" then
- local x, y = term.getCursor()
- term.setCursor(x, y - (params[1] or 1))
- elseif cmd == "B" then
- local x, y = term.getCursor()
- term.setCursor(x, y + (params[1] or 1))
- elseif cmd == "C" then
- local x, y = term.getCursor()
- term.setCursor(x + (params[1] or 1), y)
- elseif cmd == "D" then
- local x, y = term.getCursor()
- term.setCursor(x - (params[1] or 1), y)
- elseif cmd == "m" then
- for _, param in ipairs(params) do
- if param == 0 then
- gpu.setForeground(0xFFFFFF)
- gpu.setBackground(0x000000)
- elseif param == 1 then
- elseif param >= 30 and param <= 37 then
- local colors = {
- 0x000000, 0xFF0000, 0x00FF00, 0xFFFF00,
- 0x0000FF, 0xFF00FF, 0x00FFFF, 0xFFFFFF
- }
- gpu.setForeground(colors[param - 29])
- elseif param >= 40 and param <= 47 then
- local colors = {
- 0x000000, 0xFF0000, 0x00FF00, 0xFFFF00,
- 0x0000FF, 0xFF00FF, 0x00FFFF, 0xFFFFFF
- }
- gpu.setBackground(colors[param - 39])
- end
- end
- end
- i = i + #seq + 3
- else
- io.write(c)
- i = i + 1
- end
- else
- io.write(c)
- i = i + 1
- end
- end
- end
- local function connectTelnet(host, port)
- local connection = internet.connect(host, port)
- if not connection then
- print("Failed to connect to " .. host .. ":" .. port)
- return
- end
- print("Connecting to " .. host .. ":" .. port)
- local timeout = 10
- local start = computer.uptime()
- while not connection.finishConnect() do
- if computer.uptime() - start > timeout then
- print("Connection timed out")
- connection.close()
- return
- end
- os.sleep(0.1)
- end
- term.clear()
- print("Connected!")
- local buffer = ""
- while true do
- local data = connection.read(1024)
- if data then
- buffer = buffer .. data
- while true do
- local cmdStart, cmdEnd = buffer:find(IAC .. ".?.?")
- if cmdStart then
- local cmd = buffer:sub(cmdStart, cmdEnd)
- if handleTelnetCommand(connection, cmd) then
- buffer = buffer:sub(1, cmdStart - 1) .. buffer:sub(cmdEnd + 1)
- else
- break
- end
- else
- break
- end
- end
- if #buffer > 0 then
- handleANSI(buffer)
- io.flush()
- buffer = ""
- end
- end
- local e = {event.pull(0.05)}
- if e[1] == "key_down" then
- local char, code = e[3], e[4]
- if keyboard.isControlDown() and keyboard.isAltDown() and char == 46 then
- print("\nDisconnecting...")
- break
- elseif keyboard.isControlDown() then
- if char >= 1 and char <= 26 then
- connection.write(string.char(char))
- if localEcho then
- io.write("^" .. string.char(char + 64))
- end
- end
- elseif code == 28 then
- connection.write("\r\n")
- if localEcho then
- io.write("\r\n")
- end
- elseif code == 14 then
- connection.write("\b")
- if localEcho then
- local x, y = term.getCursor()
- if x > 1 then
- term.setCursor(x - 1, y)
- term.write(" ")
- term.setCursor(x - 1, y)
- end
- end
- else
- connection.write(string.char(char))
- if localEcho then
- io.write(string.char(char))
- end
- end
- io.flush()
- end
- end
- connection.close()
- print("Disconnected. Press any key to exit.")
- event.pull("key_down")
- end
- local function displayLogo()
- local maxResolution = {gpu.getResolution()}
- local tier = (maxResolution[1] >= 160 and maxResolution[2] >= 50) and 3 or (maxResolution[1] >= 80 and maxResolution[2] >= 25) and 2 or 1
- term.clear()
- if tier == 1 then
- print([[
- ░█▀█░█▀▀░░░░░▀█▀░█▀▀░█░░░█▀█░█▀▀░▀█▀
- ░█░█░█░░░▄▄▄░░█░░█▀▀░█░░░█░█░█▀▀░░█░
- ░▀▀▀░▀▀▀░░░░░░▀░░▀▀▀░▀▀▀░▀░▀░▀▀▀░░▀░
- ]])
- else
- print([[
- ________________ ___________________________ __________________
- __ __ \_ ____/ ___ __/__ ____/__ /___ | / /__ ____/__ __/
- _ / / / / _________ / __ __/ __ / __ |/ /__ __/ __ /
- / /_/ // /___/_____/ / _ /___ _ /___ /| / _ /___ _ /
- \____/ \____/ /_/ /_____/ /_____/_/ |_/ /_____/ /_/
- ]])
- end
- print("OC-TELNET Client made by nonogamer9")
- end
- while true do
- displayLogo()
- print("Enter the host and port to connect (e.g., example.com 23):")
- print("Or type 'exit' to quit the program.")
- local input = io.read()
- if input:lower() == "exit" then
- break
- end
- local host, port = input:match("(%S+)%s+(%d+)")
- if host and port then
- connectTelnet(host, tonumber(port))
- else
- print("Invalid input. Please provide a host and port.")
- os.sleep(2)
- end
- end
- print("Thank you for using OC-TELNET. Goodbye!")
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement