Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- -- [ --------------------------------------------------------------------- ] --
- -- [ RedNetChat ] --
- -- [ A public chat client for ComputerCraft ] --
- -- [ Created by GPG Incorporated. ] --
- -- [ --------------------------------------------------------------------- ] --
- -- Indicates if the application is running
- local RUNNING = false
- -- Url of the api
- local API_URL = "http://rednetchat.gpgautier.nl/api.php"
- -- Queue with all the messages
- local MESSAGE_QUEUE = {}
- -- Indicates if there is a message loading
- local MESSAGE_LOADING = false
- -- Protocol to use for sending and recieving messages
- local PROTOCOL = "rednet"
- -- ID of this client
- local ID = os.computerID()
- -- Nickname for the user in chat
- local NICKNAME = ""
- -- ID for the chat session
- local SESSION = nil
- -- Indicates if requests and responses should be logged
- local LOGGING = true
- -- Display buffer
- local DISPLAY_BUFFER = {}
- -- Pointer for the display buffer
- local DISPLAY_BUFFER_POINTER = 0
- -- Indicates if the client is joined
- local JOINED = false
- -- The last nicknamed that you messaged with
- local LAST_MSG = nil
- -- Target for private messaging
- local TARGET = nil
- -- Channel for group messaging
- local CHANNEL = 1
- -- Process the message queue and send a message when queued
- function processQueue()
- -- only process when there is no message loading
- if not MESSAGE_LOADING then
- if MESSAGE_QUEUE[1] ~= nil then
- MESSAGE_LOADING = true
- http.request(API_URL, MESSAGE_QUEUE[1])
- table.remove(MESSAGE_QUEUE, 1)
- end
- end
- end
- -- Add a message to the queue
- function addMessage(header, body)
- local key, value, message, session
- if SESSION ~= nil then
- session = SESSION
- else
- session = ""
- end
- -- assemble the post data
- message = "?protocol=" .. PROTOCOL
- message = message .. "&session=" .. session
- message = message .. "&channel=" .. CHANNEL
- message = message .. "&origin=" .. ID
- message = message .. "&nickname=" .. NICKNAME
- message = message .. "&header=" .. header
- message = message .. "&body="
- if body ~= nil then
- message = message .. body
- end
- if LOGGING then log(message) end
- -- add the message to the queue
- table.insert(MESSAGE_QUEUE, message)
- -- start processing the message queue
- processQueue()
- end
- -- Handles all OS events
- function handleEvents()
- local type, param1, param2, param3, param4
- while JOINED == false or RUNNING do
- type, param1, param2, param3, param4 = os.pullEvent()
- -- Handles incoming http events
- if type == "http_failure" or type == "http_success" then
- if param2 ~= nil then
- param2 = param2.readAll()
- end
- if LOGGING then log(param2) end
- if type == "http_success" then
- handleResponse(textutils.unserialize(param2))
- end
- -- indicate that the message is finished loading and start sending the next message
- MESSAGE_LOADING = false
- processQueue()
- end
- end
- end
- -- Handles http responses
- function handleResponse(response)
- -- check if the protocol matches
- if response.protocol ~= PROTOCOL then
- return
- end
- -- check for correct origin
- if tonumber(response.origin) ~= ID then
- return
- end
- if response.header == "join" then
- if response.status == "ok" then
- SESSION = response.session
- JOINED = true
- CHANNEL = response.channel
- else
- writeHeader()
- term.setCursorPos(2, 9)
- term.clearLine()
- term.write("Error: " .. response.body)
- NICKNAME = ""
- inputNickname()
- end
- elseif response.header == "leave" then
- addMessage("update")
- SESSION = nil
- elseif response.header == "msg" then
- if response.status == "error" then
- appendDisplayBuffer(response.body)
- else
- LAST_MSG = response.body
- end
- elseif response.header == "update" then
- local messages = response.body
- showOnlineUsers(response.online)
- if messages ~= nil and messages ~= "" then
- local i, message
- for i, message in pairs(messages) do
- message = messages[i]
- if message.sender ~= nil and message.header == "msg" then
- LAST_MSG = message.sender
- end
- appendDisplayBuffer(message.body)
- end
- end
- end
- end
- -- General logging function
- function log(message)
- local file = io.open(ID .. "_rednetchat.log", "a")
- file:write("\n" .. message)
- file:close()
- end
- -- Receive buffer updates for the service
- function updateBuffer()
- while RUNNING do
- if SESSION ~= nil then
- addMessage("update")
- end
- sleep(1)
- end
- end
- -- Enable and process the input buffer
- function inputBuffer()
- local buffer
- term.setCursorPos(1, 4)
- term.write("--------------------------------------------------")
- while RUNNING do
- buffer = ""
- while buffer == nil or buffer == "" do
- term.setCursorPos(1, 3)
- term.clearLine()
- term.write("Send > ")
- buffer = read()
- end
- if buffer:sub(1, 5) == "/join" then
- join(buffer:sub(7))
- elseif buffer == "/leave" then
- leave()
- elseif buffer:sub(1, 4) == "/msg" then
- msg(buffer:sub(6))
- elseif buffer:sub(1, 7) == "/public" then
- if TARGET ~= nil then
- TARGET = nil
- appendDisplayBuffer("Public messaging")
- end
- elseif buffer:sub(1, 8) == "/private" then
- local target = buffer:sub(10)
- if target ~= "" and target ~= nil then
- TARGET = target
- appendDisplayBuffer("Private messaging to " .. TARGET)
- else
- TARGET = nil
- appendDisplayBuffer("Public messaging")
- end
- elseif buffer:sub(1, 2) == "/r" then
- r(buffer:sub(4))
- else
- if TARGET ~= nil then
- msg(TARGET .. " " .. buffer)
- else
- say(buffer)
- end
- end
- end
- end
- -- Writes the application header
- function writeHeader()
- term.clear()
- term.setCursorPos(1, 1)
- term.write("RedNet Chat 0.5 beta by GPG Incorporated")
- term.setCursorPos(1, 2)
- term.write("--------------------------------------------------")
- end
- -- COMMAND - /join
- function join(channel)
- channel = tonumber(channel)
- if channel == nil then
- channel = 1
- end
- addMessage("join", channel)
- end
- -- COMMAND - /leave
- function leave()
- addMessage("leave")
- end
- -- COMMAND - /say
- function say(message)
- addMessage("say", message)
- end
- --
- function msg(message)
- addMessage("msg", message)
- end
- --
- function r(message)
- addMessage("msg", LAST_MSG .. " " .. message)
- end
- --
- function appendDisplayBuffer(message)
- local length
- length = message:len()
- if length > 50 then
- table.insert(DISPLAY_BUFFER, message:sub(1, 50))
- DISPLAY_BUFFER_POINTER = DISPLAY_BUFFER_POINTER + 1
- appendDisplayBuffer(message:sub(51))
- else
- table.insert(DISPLAY_BUFFER, message)
- DISPLAY_BUFFER_POINTER = DISPLAY_BUFFER_POINTER + 1
- end
- showDisplayBuffer()
- end
- --
- function showDisplayBuffer()
- local i, line, pointer, x, y
- if DISPLAY_BUFFER_POINTER == 0 then
- return
- end
- x, y = term.getCursorPos()
- line = 5
- pointer = -(11 - DISPLAY_BUFFER_POINTER)
- for i = pointer, pointer + 11 do
- term.setCursorPos(1, line)
- term.clearLine()
- if DISPLAY_BUFFER[i] ~= nil then
- term.write(tostring(DISPLAY_BUFFER[i]))
- end
- line = line + 1
- end
- term.setCursorPos(x, y)
- end
- --
- function showOnlineUsers(online)
- local x, y = term.getCursorPos()
- if online == nil then
- online = "-"
- end
- term.setCursorPos(1, 17)
- term.write("--------------------------------------------------")
- term.setCursorPos(1, 18)
- term.clearLine()
- term.write("Online: " .. online)
- term.setCursorPos(x, y)
- end
- --
- function inputNickname()
- term.setCursorPos(1, 4)
- term.write(" Enter a username and press enter.")
- while NICKNAME == "" do
- term.setCursorPos(2, 6)
- term.clearLine()
- term.write("Username: ")
- NICKNAME = read()
- end
- join()
- end
- -- Application entry
- function main()
- local file = io.open(ID .. "_rednetchat.log", "w")
- file:write("RedNet Log")
- file:close()
- writeHeader()
- parallel.waitForAll(handleEvents, inputNickname)
- RUNNING = true
- writeHeader()
- showDisplayBuffer()
- parallel.waitForAll(handleEvents, updateBuffer, inputBuffer)
- end
- main()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement