Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- -- ============================================================
- -- BONZIWORLD <-> OPENCOMPUTERS BRIDGE (FIXED)
- -- ============================================================
- local internet = require("internet")
- local serialization = require("serialization")
- local component = require("component")
- local computer = require("computer")
- print("========================================")
- print(" BonziWORLD OpenComputers Bridge")
- print("========================================")
- print("")
- if not component.isAvailable("internet") then
- print("[-] Internet card is missing or disabled.")
- return
- end
- io.write("Server URL: ")
- local serverUrl = io.read()
- io.write("Room ID: ")
- local roomInput = io.read()
- io.write("Bot Name: ")
- local botName = io.read()
- if not botName or botName == "" then
- botName = "OC_Bot"
- end
- serverUrl = serverUrl:gsub("^https?://", ""):gsub("/+$", "")
- local room = tonumber(roomInput) or roomInput
- local host = serverUrl
- local path = "/socket.io/?EIO=4&transport=websocket"
- local ws = nil
- local socketConnected = false
- local loggedIn = false
- local shuttingDown = false
- local messageQueue = {}
- local pingInterval = 25000
- local pingTimeout = 20000
- local APP_HEARTBEAT = 10
- local SEND_DELAY = 0.20
- local LOGIN_DELAY = 1.5
- local reconnectDelay = 2
- local lastPacketTime = 0
- local function now()
- return math.floor(computer.uptime() * 1000)
- end
- local function socketEvent(eventName, data)
- return "42" .. serialization.serialize({ eventName, data })
- end
- local function rawSend(packet)
- if not ws or not socketConnected then return false end
- local ok, err = pcall(function()
- -- Frame basic text payload for WebSocket transmission over TCP
- local length = #packet
- local frame = string.char(0x81)
- if length <= 125 then
- frame = frame .. string.char(length)
- elseif length <= 65535 then
- frame = frame .. string.char(126, math.floor(length / 256), length % 256)
- else
- return error("Payload too large")
- end
- ws:write(frame .. packet)
- end)
- if not ok then
- print("\n[-] WebSocket send failed:\n " .. tostring(err))
- return false
- end
- return true
- end
- local function sendChat(message)
- if not message or message == "" then return false end
- return rawSend(socketEvent("talk", { text = message, say = message }))
- end
- local function sendApplicationHeartbeat()
- return rawSend(socketEvent("talk", { text = "", say = "" }))
- end
- local function sendLogin()
- print("[>] Login: " .. botName)
- print("[>] Room: " .. tostring(room))
- return rawSend(socketEvent("login", { name = botName, room = room }))
- end
- local function processPacket(packet)
- if not packet then return end
- lastPacketTime = now()
- if packet:sub(1, 1) == "0" then
- local ok, data = pcall(serialization.unserialize, packet:sub(2))
- if ok and type(data) == "table" then
- pingInterval = tonumber(data.pingInterval) or pingInterval
- pingTimeout = tonumber(data.pingTimeout) or pingTimeout
- end
- rawSend("40")
- return
- end
- if packet == "2" then
- rawSend("3")
- return
- end
- if packet == "3" then return end
- if packet:sub(1, 1) == "1" then
- socketConnected, loggedIn = false, false
- return
- end
- if packet == "40" then
- if not socketConnected then
- socketConnected = true
- print("[+] Socket.IO connected.")
- end
- return
- end
- if packet:sub(1, 2) == "42" then
- local ok, decoded = pcall(serialization.unserialize, packet:sub(3))
- if ok and type(decoded) == "table" then
- local eventName, payload = decoded[1], decoded[2]
- if eventName == "talk" and type(payload) == "table" then
- local sender = payload.name or "User"
- local text = payload.text or payload.say or ""
- if text ~= "" and sender ~= botName then
- print("\n[" .. sender .. "]: " .. text)
- io.write("> ")
- end
- end
- end
- return
- end
- end
- local function closeSocket()
- socketConnected, loggedIn = false, false
- if ws then
- pcall(function() ws:close() end)
- end
- ws = nil
- end
- local function connect()
- print("\n----------------------------------------")
- print("[*] Connecting...\n[*] " .. serverUrl)
- print("----------------------------------------")
- -- Open raw TCP connection over port 443 (or standard HTTP/WS ports)
- local stream, err = internet.open(host, 443)
- if not stream then
- print("[-] TCP connection failed: " .. tostring(err))
- return false
- end
- ws = stream
- -- Perform basic WebSocket HTTP upgrade handshake
- local wsKey = "dGhlIHNhbXBsZSBub25jZQ=="
- ws:write("GET " .. path .. " HTTP/1.1\r\n" ..
- "Host: " .. host .. "\r\n" ..
- "Upgrade: websocket\r\n" ..
- "Connection: Upgrade\r\n" ..
- "Sec-WebSocket-Key: " .. wsKey .. "\r\n" ..
- "Sec-WebSocket-Version: 13\r\n\r\n")
- socketConnected = true
- loggedIn = true
- print("[+] Connected to BonziWORLD successfully!")
- return true
- end
- print("[*] Starting bridge...")
- while not shuttingDown do
- if not ws or not socketConnected then
- if not connect() then
- os.sleep(reconnectDelay)
- reconnectDelay = math.min(reconnectDelay * 2, 30)
- end
- else
- os.sleep(0.1)
- end
- end
Advertisement
Add Comment
Please, Sign In to add comment