Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- local programName = "cldvChat"
- local args = {...}
- local dtype = args[1]
- local modemPosition
- if pocket then
- modemPosition = "back"
- else
- modemPosition = "right"
- end
- ---
- -- Helper Functions
- function findDeviceIndex (t, target)
- for i = 1, #t, 1 do
- if t[i].id == target then
- return i
- end
- end
- return 0
- end
- function prettyPrint (prefix, text, prefixColor, textColor, bgColor)
- local colors = {
- ["white"] = "0",
- ["0"] = "0",
- ["orange"] = "1",
- ["1"] = "1",
- ["magenta"] = "2",
- ["2"] = "2",
- ["lightblue"] = "3",
- ["3"] = "3",
- ["yellow"] = "4",
- ["4"] = "4",
- ["lime"] = "5",
- ["5"] = "5",
- ["pink"] = "6",
- ["6"] = "6",
- ["gray"] = "7",
- ["7"] = "7",
- ["lightgray"] = "8",
- ["8"] = "8",
- ["cyan"] = "9",
- ["9"] = "9",
- ["purple"] = "a",
- ["a"] = "a",
- ["blue"] = "b",
- ["b"] = "b",
- ["brown"] = "c",
- ["c"] = "c",
- ["green"] = "d",
- ["d"] = "d",
- ["red"] = "e",
- ["e"] = "e",
- ["black"] = "f",
- ["f"] = "f"
- }
- prefixColor = colors[prefixColor] or "b"
- textColor = colors[textColor] or "0"
- bgColor = colors[bgColor] or "f"
- local deviceWidth, _ = term.current().getSize()
- local texts = {}
- texts[1] = text
- local idx = 1
- local maxLength = deviceWidth - #prefix
- -- Split text after last space or after maxLength if the string is too long
- -- Note: The prefix has to be smaller than the maxLength.
- while (#texts[idx] > maxLength) do
- local lastSpace = nil
- local offset = 0
- lastSpace = string.sub(texts[idx], 1, maxLength):match'^.*() '
- if string.find(texts[idx], "\n") then
- local start, _ = string.find(texts[idx], "\n")
- offset = 1
- lastSpace = math.min(lastSpace, start - 1)
- end
- if lastSpace == nil then lastSpace = maxLength end
- if idx == 1 then maxLength = deviceWidth end
- texts[idx + 1] = string.sub(texts[idx], lastSpace + 1 + offset)
- texts[idx] = string.sub(texts[idx], 1, lastSpace)
- idx = idx + 1
- end
- -- Setup color strings
- local tColorS = ""
- local bgColorS = ""
- for i = 1, #prefix, 1 do
- tColorS = tColorS .. prefixColor
- bgColorS = bgColorS .. bgColor
- end
- -- Print prefix
- term.blit(prefix, tColorS, bgColorS)
- -- Print texts
- for i = 1, #texts, 1 do
- tColorS = ""
- bgColorS = ""
- for j = 1, #texts[i], 1 do
- tColorS = tColorS .. textColor
- bgColorS = bgColorS .. bgColor
- end
- term.blit(texts[i], tColorS, bgColorS)
- print("")
- end
- return #texts
- end
- function printMessage (name, message, sender)
- sender = sender or false
- local nameColor = "b"
- if sender then
- nameColor = "5"
- end
- name = name .. ": "
- return prettyPrint(name, message, nameColor)
- end
- ---
- function client ()
- local protocol = args[2] or "cldvChat"
- local hostname = args[3] or "cldvChatServer"
- local clientName = args[4] or nil
- if not clientName then
- prettyPrint ("", "Please enter your name: ", nil, "8")
- clientName = read()
- end
- while #clientName > 20 do
- prettyPrint ("", "Your name is too long! Enter a smaller name: ", nil, "8")
- clientName = read()
- end
- local hosts = rednet.lookup(protocol, hostname)
- if tonumber(hosts) then
- local tmpHosts = hosts
- hosts = {}
- hosts[1] = tmpHosts
- end
- for i = 1, #hosts, 1 do
- if not rednet.send(hosts[i], "/" .. clientName, protocol) then
- error("Could not send message.")
- else
- prettyPrint ("", "Connected! Type /quit to disconnect", nil, "8")
- end
- end
- parallel.waitForAny(
- -- Receive messages
- function ()
- local message
- while true do
- _, message, _ = rednet.receive(protocol)
- local separator, _ = string.find(message, ":")
- local isCommand, _ = string.find(message, "/")
- if separator and not isCommand then
- local name = string.sub(message, 1, separator - 1)
- message = string.sub(message, separator + 2)
- term.clearLine()
- local x, y = term.getCursorPos()
- term.setCursorPos(1, y)
- printMessage(name, message, false)
- end
- --print (message)
- end
- end,
- -- Send messages
- function ()
- local message
- while true do
- message = read()
- if message == "/quit" then
- prettyPrint ("", "Disconnected!", nil, "8")
- return
- end
- -- Clear read output and write it prettier
- local x, y = term.getCursorPos()
- term.setCursorPos(x, y - 1)
- term.clearLine()
- local _, maxHeight = term.current().getSize()
- local offset = printMessage(clientName, message, true) - 1
- y = math.min(y + offset, maxHeight)
- term.setCursorPos(x, y)
- for i = 1, #hosts, 1 do
- if not rednet.send(hosts[i], message, protocol) then
- error("Could not send message.")
- end
- end
- end
- end
- )
- for i = 1, #hosts, 1 do
- if not rednet.send(hosts[i], "/quit", protocol) then
- error("Could not send message.")
- end
- end
- end
- function server ()
- local protocol = args[2] or "cldvChat"
- local name = args[3] or "cldvChatServer"
- local devices = {}
- rednet.host(protocol, name)
- prettyPrint ("", "Server running!", nil, "8")
- while true do
- local deviceID
- local message
- deviceID, message, _ = rednet.receive(protocol)
- local index = findDeviceIndex(devices, deviceID)
- local isCommand, _ = string.find(message, "/")
- -- Add device
- if index == 0 then
- local device = {
- name = string.sub(message, 2),
- id = deviceID
- }
- table.insert(devices, device)
- prettyPrint ("", "Add client " .. device.name .. " with ID " .. tostring(deviceID), nil, "8")
- -- Remove device
- elseif message == "/quit" then
- if index == 0 then
- error("Could not remove device, index not found.")
- else
- local device = devices[index]
- table.remove(devices, index)
- prettyPrint ("", device.name .. " with ID " .. tostring(deviceID) .. " disconnected.", nil, "8")
- device = nil
- end
- elseif isCommand then
- prettyPrint ("", devices[index].name .. " tried to connect but is already connected.", nil, "8")
- -- Send message to all connected devices
- else
- -- Print to server log
- printMessage(devices[index].name, message, false)
- message = devices[index].name .. ": " .. message
- -- Send message to all clients
- for i = 1, #devices, 1 do
- if deviceID ~= devices[i].id then
- if not rednet.send(devices[i].id, message, protocol) then
- error("Could not send message.")
- end
- end
- end
- end
- end
- rednet.unhost(protocol)
- end
- function main ()
- if not rednet.isOpen(modemPosition) then
- error("Could not open modem '".. modemPosition .. "'")
- return
- end
- if dtype == "client" then
- client()
- elseif dtype == "server" then
- server()
- elseif dtype == "update" then
- shell.run("pastebin", "run", "FuQ3WvPs 4izkdH5g " .. programName)
- elseif dtype == "help" then
- prettyPrint ("", "Arguments:\n - " .. programName .. " server <protocol> <hostname>\n - " .. programName .. " client <protocol> <hostname> <username>\n - " .. programName .. " update\n - " .. programName .. " help\n", nil, "8")
- else
- error("Please specify the device type as 'server' or 'client' by passing it as the first argument.")
- end
- end
- rednet.open(modemPosition)
- main()
- rednet.close(modemPosition)
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement