Advertisement
nonogamer9

OC-TELNET 2 : A Better Telnet Client For OpenComputers

Jan 30th, 2025 (edited)
72
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 9.77 KB | Software | 0 0
  1. local component = require("component")
  2. local event = require("event")
  3. local term = require("term")
  4. local unicode = require("unicode")
  5. local serialization = require("serialization")
  6. local shell = require("shell")
  7. local fs = require("filesystem")
  8. local gpu = component.gpu
  9. local keyboard = require("keyboard")
  10.  
  11. local internet = component.list("internet")()
  12. local inet = component.proxy(internet)
  13.  
  14. if not inet then
  15.   error("Internet Card not found. Please install an Internet Card.")
  16. end
  17.  
  18. local IAC, DONT, DO, WONT, WILL = string.char(255), string.char(254), string.char(253), string.char(252), string.char(251)
  19. local SB, SE = string.char(250), string.char(240)
  20. local NOP, DM, BRK, IP, AO, AYT, EC, EL, GA = string.char(241), string.char(242), string.char(243), string.char(244), string.char(245), string.char(246), string.char(247), string.char(248), string.char(249)
  21.  
  22. local ECHO, SUPPRESS_GO_AHEAD, STATUS, TIMING_MARK = string.char(1), string.char(3), string.char(5), string.char(6)
  23. local TERMINAL_TYPE, WINDOW_SIZE, TERMINAL_SPEED = string.char(24), string.char(31), string.char(32)
  24. local REMOTE_FLOW_CONTROL, LINEMODE, ENVIRONMENT = string.char(33), string.char(34), string.char(36)
  25.  
  26. local config = {
  27.   default_host = "localhost",
  28.   default_port = 23,
  29.   log_file = "/home/telnet.log",
  30.   color_enabled = true
  31. }
  32.  
  33. local function load_config()
  34.   local config_path = "/home/telnet_config.lua"
  35.   if fs.exists(config_path) then
  36.     local file = io.open(config_path, "r")
  37.     local content = file:read("*all")
  38.     file:close()
  39.     local loaded_config = serialization.unserialize(content)
  40.     for k, v in pairs(loaded_config) do
  41.       config[k] = v
  42.     end
  43.   end
  44. end
  45.  
  46. local function save_config()
  47.   local config_path = "/home/telnet_config.lua"
  48.   local file = io.open(config_path, "w")
  49.   file:write(serialization.serialize(config))
  50.   file:close()
  51. end
  52.  
  53. local function log(message)
  54.   local file = io.open(config.log_file, "a")
  55.   file:write(os.date("[%Y-%m-%d %H:%M:%S] ") .. message .. "\n")
  56.   file:close()
  57. end
  58.  
  59. local function send_command(connection, cmd, option)
  60.   connection.write(IAC .. cmd .. option)
  61. end
  62.  
  63. local function handle_option(connection, cmd, option)
  64.   if cmd == DO then
  65.     if option == TERMINAL_TYPE then
  66.       send_command(connection, WILL, TERMINAL_TYPE)
  67.       connection.write(IAC .. SB .. TERMINAL_TYPE .. string.char(0) .. "ANSI" .. IAC .. SE)
  68.     elseif option == WINDOW_SIZE then
  69.       send_command(connection, WILL, WINDOW_SIZE)
  70.       local width, height = term.getViewport()
  71.       connection.write(IAC .. SB .. WINDOW_SIZE .. string.char(0) .. string.char(width) .. string.char(0) .. string.char(height) .. IAC .. SE)
  72.     else
  73.       send_command(connection, WONT, option)
  74.     end
  75.   elseif cmd == WILL then
  76.     if option == ECHO or option == SUPPRESS_GO_AHEAD then
  77.       send_command(connection, DO, option)
  78.     else
  79.       send_command(connection, DONT, option)
  80.     end
  81.   end
  82. end
  83.  
  84. local function handleANSI(str)
  85.     local i = 1
  86.     while i <= #str do
  87.         local c = str:sub(i, i)
  88.         if c == "\27" then
  89.             local seq, cmd = str:match("\27%[([%d;]*)([A-Za-z])", i)
  90.             if seq and cmd then
  91.                 local params = {}
  92.                 for param in seq:gmatch("%d+") do
  93.                     table.insert(params, tonumber(param))
  94.                 end
  95.  
  96.                 if #params == 0 then
  97.                     params = {1}
  98.                 end
  99.  
  100.                 if cmd == "H" or cmd == "f" then
  101.                     local x, y = params[2] or 1, params[1] or 1
  102.                     term.setCursor(x, y)
  103.                 elseif cmd == "J" then
  104.                     if params[1] == 2 then
  105.                         term.clear()
  106.                     elseif params[1] == 0 then
  107.                         term.clearLine()
  108.                     end
  109.                 elseif cmd == "K" then
  110.                     term.clearLine()
  111.                 elseif cmd == "A" then
  112.                     local x, y = term.getCursor()
  113.                     term.setCursor(x, y - (params[1] or 1))
  114.                 elseif cmd == "B" then
  115.                     local x, y = term.getCursor()
  116.                     term.setCursor(x, y + (params[1] or 1))
  117.                 elseif cmd == "C" then
  118.                     local x, y = term.getCursor()
  119.                     term.setCursor(x + (params[1] or 1), y)
  120.                 elseif cmd == "D" then
  121.                     local x, y = term.getCursor()
  122.                     term.setCursor(x - (params[1] or 1), y)
  123.                 elseif cmd == "m" then
  124.                     for _, param in ipairs(params) do
  125.                         if param == 0 then
  126.                             gpu.setForeground(0xFFFFFF)
  127.                             gpu.setBackground(0x000000)
  128.                         elseif param == 1 then
  129.                         elseif param >= 30 and param <= 37 then
  130.                             local colors = {
  131.                                 0x000000, 0xFF0000, 0x00FF00, 0xFFFF00,
  132.                                 0x0000FF, 0xFF00FF, 0x00FFFF, 0xFFFFFF
  133.                             }
  134.                             gpu.setForeground(colors[param - 29])
  135.                         elseif param >= 40 and param <= 47 then
  136.                             local colors = {
  137.                                 0x000000, 0xFF0000, 0x00FF00, 0xFFFF00,
  138.                                 0x0000FF, 0xFF00FF, 0x00FFFF, 0xFFFFFF
  139.                             }
  140.                             gpu.setBackground(colors[param - 39])
  141.                         end
  142.                     end
  143.                 end
  144.                 i = i + #seq + 3
  145.             else
  146.                 io.write(c)
  147.                 i = i + 1
  148.             end
  149.         else
  150.             io.write(c)
  151.             i = i + 1
  152.         end
  153.     end
  154. end
  155.  
  156. local function telnet(host, port)
  157.   local connection = inet.connect(host, port)
  158.  
  159.   if not connection then
  160.     error("Failed to connect to " .. host .. ":" .. port)
  161.   end
  162.  
  163.   print("Connected to " .. host .. ":" .. port)
  164.   log("Connected to " .. host .. ":" .. port)
  165.  
  166.   local buffer = ""
  167.   local in_iac = false
  168.   local cmd, option
  169.  
  170.   while true do
  171.     local data = connection.read(1024)
  172.     if data then
  173.       for i = 1, #data do
  174.         local char = data:sub(i, i)
  175.         if in_iac then
  176.           if not cmd then
  177.             cmd = char
  178.           elseif not option then
  179.             option = char
  180.             handle_option(connection, cmd, option)
  181.             in_iac, cmd, option = false, nil, nil
  182.           end
  183.         elseif char == IAC then
  184.           in_iac = true
  185.         else
  186.           buffer = buffer .. char
  187.         end
  188.       end
  189.      
  190.       if #buffer > 0 then
  191.         if config.color_enabled then
  192.           handleANSI(buffer)
  193.         else
  194.           io.write(buffer)
  195.         end
  196.         log(buffer)
  197.         buffer = ""
  198.       end
  199.     end
  200.    
  201.     local _, _, char, code = event.pull(0.05, "key_down")
  202.     if char then
  203.       local utf8char = unicode.char(char)
  204.       connection.write(utf8char)
  205.       if not connection.finishConnect() then
  206.         print("\nConnection closed")
  207.         log("Connection closed")
  208.         break
  209.       end
  210.     end
  211.   end
  212.  
  213.   connection.close()
  214. end
  215.  
  216. local function config_menu()
  217.   print("Configuration Menu")
  218.   io.write("Enter default host (current: " .. config.default_host .. "): ")
  219.   local new_host = io.read()
  220.   if new_host ~= "" then config.default_host = new_host end
  221.  
  222.   io.write("Enter default port (current: " .. config.default_port .. "): ")
  223.   local new_port = tonumber(io.read())
  224.   if new_port then config.default_port = new_port end
  225.  
  226.   io.write("Enable color? (y/n, current: " .. (config.color_enabled and "yes" or "no") .. "): ")
  227.   local color_choice = io.read():lower()
  228.   if color_choice == "y" or color_choice == "n" then
  229.     config.color_enabled = (color_choice == "y")
  230.   end
  231.  
  232.   save_config()
  233.   print("Configuration saved")
  234. end
  235.  
  236. local function connect_to_server()
  237.   io.write("Enter host (or press Enter for default): ")
  238.   local host = io.read()
  239.   host = host ~= "" and host or config.default_host
  240.  
  241.   io.write("Enter port (or press Enter for default): ")
  242.   local port_input = io.read()
  243.   local port = tonumber(port_input) or config.default_port
  244.  
  245.   telnet(host, port)
  246. end
  247.  
  248. local function display_logo()
  249.   print([[
  250.    U  ___ u   ____        _____  U _____ u  _      _   _   U _____ u  _____  
  251.     \/"_ \/U /"___|      |_ " _| \| ___"|/ |"|    | \ |"|  \| ___"|/ |_ " _|
  252.     | | | |\| | u  U  u    | |    |  _|" U | | u <|  \| |>  |  _|"     | |  
  253. .-,_| |_| | | |/__ /___\  /| |\   | |___  \| |/__U| |\  |u  | |___    /| |\  
  254.  \_)-\___/   \____|__"__|u |_|U   |_____|  |_____||_| \_|   |_____|  u |_|U  
  255.      \\    _// \\       _// \\_  <<   >>  //  \\ ||   \\,-.<<   >>  _// \\_
  256.     (__)  (__)(__)     (__) (__)(__) (__)(_")("_)(_")  (_/(__) (__)(__) (__)
  257.   ____                                                                      
  258.  |___"\                                                                      
  259. U __) |                                                                    
  260. \/ __/ \                                                                    
  261. |_____|u                                                                    
  262. <<  //                                                                      
  263. (__)(__)
  264. ]])
  265. end
  266.  
  267. local function main_menu()
  268.  while true do
  269.    print("\nOC-TELNET 2 Coded by nonogamer9!")
  270.    print("1. Connect to server")
  271.    print("2. Configure settings")
  272.    print("3. Exit")
  273.    io.write("Choose an option: ")
  274.    local choice = io.read()
  275.  
  276.    if choice == "1" then
  277.      connect_to_server()
  278.    elseif choice == "2" then
  279.      config_menu()
  280.    elseif choice == "3" then
  281.      break
  282.    else
  283.      print("Invalid option. Please try again.")
  284.    end
  285.  end
  286. end
  287.  
  288. display_logo()
  289. load_config()
  290. main_menu()
  291.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement