Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- -- Chat Assistant Admin Edition
- local version = "v0.1.8 Admin Edition"
- print("1lann's Chat Assistant Central Server")
- print(version)
- print("Please don't touch me :(")
- local chat = peripheral.wrap("right")
- --local modem = peripheral.wrap("top")
- local drive = peripheral.wrap("left")
- local operatingChannel = 27158
- local successChannel = 27159
- local wrapLength = 36
- local pmOnly = true
- if not chat then
- error("Could not find chatbox!")
- end
- chat.setLabel("CA")
- if modem then
- modem.closeAll()
- modem.open(successChannel)
- print("Modem ready")
- else
- print("Warning: No modem found")
- end
- if drive then
- print("Disk drive detected")
- if drive.getAudioTitle() then
- print("Loaded with disk: "..drive.getAudioTitle())
- drive.stopAudio()
- else
- print("No music disk found!")
- end
- else
- print("No disk drive detected")
- end
- local database = {}
- local localDatabase = {}
- local messageQueue = {}
- local receiveQueue = {}
- local pendingReminders = {}
- local musicLength = 190
- local musicClock = musicLength * -1
- local successCalls = {}
- local orderedKeys = {}
- local searchAndTrim = function(message, searches, limit)
- if not limit then
- limit = #message + 1
- end
- for k, v in pairs(searches) do
- local startPos, endPos = message:lower():find(v)
- local match = nil
- local err, msg = pcall(function() match = message:lower():match(v) end)
- if endPos and startPos <= limit then
- if err then
- return true, message:sub(endPos, -1), {match}, startPos
- else
- return true, message:sub(endPos, -1), {}, startPos
- end
- end
- end
- return false, message
- end
- local saveDatabase = function()
- local f = io.open("/chat-config", "w")
- f:write(textutils.serialize(database))
- f:close()
- end
- local textWrap = function(message)
- local messages = {}
- local currentMessage = ""
- for word in message:gmatch("%S+") do
- if #(currentMessage .. word) > wrapLength then
- table.insert(messages, currentMessage)
- if word ~= "`" then
- currentMessage = word .. " "
- end
- elseif word == "`" then
- table.insert(messages, currentMessage)
- currentMessage = ""
- else
- currentMessage = currentMessage .. word .. " "
- end
- end
- if #currentMessage > 0 then
- table.insert(messages, currentMessage)
- end
- return messages
- end
- local randomLoadingMessage = function()
- local messages = {
- "Alright, let me just look that up...",
- "I'll look that up for you...",
- "One moment...",
- "Sure, I'll find that for you..."
- }
- return messages[math.random(1, #messages)]
- end
- local tell = function(player, messages, successCallback, localAction, shouldSay)
- for k,v in pairs(messages) do
- if k == 1 then
- table.insert(messageQueue, {player, v, successCallback, localAction, shouldSay})
- else
- table.insert(messageQueue, {player, v, nil, localAction, shouldSay})
- end
- end
- os.queueEvent("ca_send_message")
- end
- local function trim(s)
- return s:match("^%s*(.-)%s*$")
- end
- local commands = {}
- commands["remind"] = function(time, units, player, message)
- if time ~= nil and time > 0 then
- if not database[player] then
- database[player] = {}
- end
- if not database[player].reminders then
- database[player].reminders = {}
- end
- if #database[player].reminders >= 3 then
- return true, {"Sorry, I can only store 3 reminders at once.", "To cancel a reminder, you can \"cancel reminder\" it"}
- end
- if units == "sec" then
- table.insert(database[player].reminders, {message, os.clock() + time})
- saveDatabase()
- return true, {"Okay, I will remind you in " .. time .. " seconds.", "Use \"cancel reminder\" to cancel your reminder"}
- else
- table.insert(database[player].reminders, {message, os.clock() + time*60})
- saveDatabase()
- return true, {"Okay, I will remind you in " .. time .. " minutes.", "Use \"cancel reminder\" to cancel your reminder"}
- end
- else
- return true, {"Sorry, I couldn't understand", "when you wanted to be reminded :("}
- end
- end
- commands["remote-services"] = function(player, post, shouldSay)
- print(player .. " requested remote services.")
- tell(player, {randomLoadingMessage()}, nil, nil, shouldSay)
- local resp = http.post("http://chatbox.chuie.io/query", post)
- if not resp then
- return true, {"Sorry, I could not connect to the", "remote services to fulfill your query!"}
- end
- local response = textutils.unserialize(resp.readAll())
- resp.close()
- if response.error then
- local serverError = textWrap(response.error)
- table.insert(serverError, 1, "The server responded with an error:")
- return true, serverError
- else
- return true, textWrap(response.success)
- end
- end
- commands["irl-time"] = function(player, location, shouldSay)
- location = location:gsub(" now%?", "")
- location = location:gsub("%?", "")
- location = location:gsub(" right ", "")
- if #trim(location) == 0 then
- return false
- end
- local post = "query_type=time&location=" .. textutils.urlEncode(trim(location))
- return commands["remote-services"](player, post, shouldSay)
- end
- commands["weather"] = function(player, location, time, shouldSay)
- location = location:gsub(" today", "")
- location = location:gsub(" now%?", "")
- location = location:gsub("%?", "")
- location = location:gsub(" right ", "")
- location = location:gsub(" tomorrow", "")
- if #trim(location) == 0 then
- return false
- end
- local post = "query_type=weather&location=" ..
- textutils.urlEncode(trim(location)) .. "&time=" .. time
- return commands["remote-services"](player, post, shouldSay)
- end
- commands["define"] = function(player, word, shouldSay)
- if #word == 0 then
- return false
- end
- local post = "query_type=definition&word=" .. textutils.urlEncode(word)
- return commands["remote-services"](player, post, shouldSay)
- end
- commands["convert"] = function(player, conversion, shouldSay)
- if conversion:find("%d") > 10 then
- return false
- end
- if #conversion == 0 then
- return false
- end
- local post = "query_type=conversion&conversion=" .. textutils.urlEncode(conversion)
- return commands["remote-services"](player, post, shouldSay)
- end
- local matches = {}
- matches["1remind"] = function(player, message)
- if searchAndTrim(message, {" in %d+"}, 6) then
- local _, search = searchAndTrim(message, {" in %d"}, 6)
- local secSuccess, secSearch, secMatch = searchAndTrim(search, {"(%d+) secs,? ", "(%d+) sec,? ", "(%d+) seconds,? ", "(%d+) second,? "}, 3)
- local minSuccess, minSearch, minMatch = searchAndTrim(search, {"(%d+) min,? ", "(%d+) minute,? ", "(%d+) minutes,? ", "(%d+)mins,? "}, 3)
- if secSuccess then
- local remindSuccess, search = searchAndTrim(secSearch, {" remind me ", " reminder "}, 8)
- if remindSuccess then
- _, search = searchAndTrim(search, {" to "}, 12)
- return commands.remind(tonumber(secMatch[1]), "sec", player, search:sub(2, -1))
- end
- elseif minSuccess then
- local remindSuccess, search = searchAndTrim(minSearch, {" remind me ", " reminder "}, 8)
- if remindSuccess then
- _, search = searchAndTrim(search, {" to "}, 12)
- return commands.remind(tonumber(minMatch[1]), "min", player, search:sub(2, -1))
- end
- end
- elseif searchAndTrim(message, {" remind me ", " reminder "}, 6) then
- if searchAndTrim(message, {" cancel "}, 10) then
- return
- end
- local _, search = searchAndTrim(message, {" remind me ", " reminder "}, 6)
- local secSuccess, secSearch, secMatch = searchAndTrim(search, {" in (%d+) secs,? ", " in (%d+) sec,? ", " in (%d+) seconds,? ", " in (%d+) second,? "}, 3)
- local minSuccess, minSearch, minMatch = searchAndTrim(search, {" in (%d+) min,? ", " in (%d+) minute,? ", " in (%d+) minutes,? ", " in (%d+)mins,? "}, 3)
- if secSuccess then
- _, search = searchAndTrim(secSearch, {" to "}, 12)
- return commands.remind(tonumber(secMatch[1]), "sec", player, search:sub(2, -1))
- elseif minSuccess then
- _, search = searchAndTrim(minSearch, {" to "}, 12)
- return commands.remind(tonumber(minMatch[1]), "min", player, search:sub(2, -1))
- else
- local searchSuccess, search = searchAndTrim(search, {" to "}, 12)
- if searchSuccess then
- local secSuccess, _, secMatch, secStart = searchAndTrim(search, {" in (%d+) secs", " in (%d+) sec", " in (%d+) seconds", " in (%d+) second"})
- local minSuccess, _, minMatch, minStart = searchAndTrim(search, {" in (%d+) min", " in (%d+) minute", " in (%d+) minutes", " in (%d+)mins"})
- if secSuccess then
- return commands.remind(tonumber(secMatch[1]), "sec", player, search:sub(2, secStart - 1))
- elseif minSuccess then
- return commands.remind(tonumber(minMatch[1]), "min", player, search:sub(2, minStart - 1))
- else
- return true, {"Sorry, I couldn't understand", "when you wanted to be reminded :("}
- end
- else
- return true, {"Sorry, I couldn't understand", "when you wanted to be reminded :("}
- end
- end
- end
- end
- matches["cancel-reminder"] = function(player, message)
- if searchAndTrim(message, {" cancel reminder", " dismiss reminder", " delete reminder"}, 6) then
- if database[player] and database[player].reminders then
- if #database[player].reminders < 1 then
- return true, {"You don't have any reminders set!"}
- elseif #database[player].reminders == 1 then
- local reminderText = database[player].reminders[1][1]
- table.remove(database[player].reminders, 1)
- saveDatabase()
- return true, {"Alright, your reminder:", reminderText, "has been cancelled."}
- else
- local _, search = searchAndTrim(message, {" cancel reminder", " dismiss reminder"})
- if searchAndTrim(search, {"%d+"}) then
- local _, _, match = searchAndTrim(search, {"(%d+)"})
- if tonumber(match[1]) <= #database[player].reminders then
- local reminderText = database[player].reminders[tonumber(match[1])][1]
- table.remove(database[player].reminders, tonumber(match[1]))
- saveDatabase()
- return true, {"Alright, your reminder:", reminderText, "has been cancelled."}
- else
- return true, {"Sorry, I could not find that reminder index!"}
- end
- end
- local returnTable = {}
- table.insert(returnTable, "Here are your active reminders: ")
- for k,v in pairs(database[player].reminders) do
- table.insert(returnTable, "#"..tostring(k)..": "..v[1])
- end
- table.insert(returnTable, "What reminder number would you like to cancel?")
- table.insert(returnTable, "You can append \"#\" or \"number\" as a prefix")
- return true, returnTable
- end
- end
- elseif #localDatabase[player] > 0 and localDatabase[player][#localDatabase[player]][1] == "cancel-reminder" then
- if searchAndTrim(message, {"^%d+", "^# ?%d+", "^number ?%d+"}) then
- local _, _, match = searchAndTrim(message, {"(%d+)"})
- if tonumber(match[1]) <= #database[player].reminders then
- local reminderText = database[player].reminders[tonumber(match[1])][1]
- table.remove(database[player].reminders, tonumber(match[1]))
- saveDatabase()
- return true, {"Alright, your reminder:", reminderText, "has been cancelled."}, true
- else
- return true, {"Sorry, I could not find that reminder index!"}
- end
- end
- end
- end
- matches["list-reminders"] = function(player, message)
- if searchAndTrim(message, {" what reminders? ", " what are my %S* ?reminder", " list reminder"}, 6) then
- if database[player] and database[player].reminders then
- if #database[player].reminders < 1 then
- return true, {"You currently have no set reminders!"}
- elseif #database[player].reminders == 1 then
- return true, {"You have 1 active reminder:", database[player].reminders[1][1], "Use \"cancel reminder\" to cancel a reminder"}
- else
- local returnTable = {}
- table.insert(returnTable, "Your active reminders: ")
- for k,v in pairs(database[player].reminders) do
- table.insert(returnTable, "#"..k..": "..v[1])
- end
- table.insert(returnTable, "Use \"cancel reminder\" to cancel a reminder")
- return true, returnTable
- end
- end
- end
- end
- matches["compliment"] = function(player, message)
- if #localDatabase[player] > 0 and (os.clock() - localDatabase[player][#localDatabase[player]][2]) < 30 then
- if searchAndTrim(message, {"thank", "kudo", "cool", "nice", "wow", "awesome"}) then
- return true, {"If that was a compliment directed", "towards me, Thank you! :D"}
- end
- end
- end
- matches["time"] = function(player, message, shouldSay)
- if searchAndTrim(message, {" what ", " whats ", " what's ", " what is "}, 6) then
- local _, search = searchAndTrim(message, {" what ", " whats ", " what's ", " what is "}, 6)
- if searchAndTrim(search, {" time", " date", " day"}, 15) then
- _, search = searchAndTrim(search, {" time", " date", " day"}, 15)
- if searchAndTrim(search, {" for ", " in ", " is it in ", " is it for "}, 8) then
- _, location = searchAndTrim(search, {" for ", " in ", " is it in ", " is it for "}, 8)
- return commands["irl-time"](player, location, shouldSay)
- else
- return true, {"The current in-game time is " .. textutils.formatTime(os.time())}
- end
- end
- -- elseif searchAndTrim(message, {" time ", " date ", " day "}, 5) then
- -- _, search = searchAndTrim(message, {" time ", " date ", " day "}, 5)
- -- if searchAndTrim(search, {" for ", " in ", " is it in ", " is it for "}, 8) then
- -- _, location = searchAndTrim(search, {" for ", " in ", " is it in ", " is it for "}, 8)
- -- return commands["irl-time"](player, location, shouldSay)
- -- else
- -- return true, {"The current in-game time is " .. textutils.formatTime(os.time())}
- -- end
- end
- end
- matches["help"] = function(player, message)
- if #localDatabase[player] > 0 and (os.clock() - localDatabase[player][#localDatabase[player]][2]) < 100 then
- if searchAndTrim(message, {" what is this", " whats that", " what's that", " what is chat", " what's chat", " what are you", " what is that", " what is ca"}) then
- return true, {
- "Hello there, I'm CA, short for Chat Assistant.",
- "My creator is 1lann. If you would like a list",
- "of what I can do, ask \"what can ca do?\".",
- "Thanks for trying me out!",
- "Running " .. version}
- end
- end
- end
- matches["help-cando"] = function(player, message)
- if searchAndTrim(message, {" what can ca do"}) then
- return true, {
- "Here are some examples of what you can ask:",
- "What is the time?",
- "What is the time in New York?",
- "How's the weather in London?",
- "What's tomorrow's forecast for Beijing?",
- "Lookup how old is Obama?",
- "What does assistant mean?",
- "Define astute",
- "What is 24 C to F?",
- "What is 300 g in lb?",
- "What is 200 USD in GBP?",
- "",
- "You can also ask questions without everyone",
- "seeing by prefixing ##.",
- }
- end
- end
- matches["1stopwatch"] = function(player, message)
- if searchAndTrim(message, {" start stopwatch", " start counting", " stopwatch start", " start the stopwatch"}, 6) then
- localDatabase[player].stopwatch = {}
- localDatabase[player].stopwatch.running = true
- localDatabase[player].stopwatch.start = os.clock()
- return true, {"Alright, I have started the stopwatch."}
- elseif searchAndTrim(message, {" stop stopwatch", " quit stopwatch", " stop counting", " quit counting",
- " stop the stopwatch", " quit the stopwatch", " stopwatch stop", " stopwatch end", " stopwatch quit",
- " end counting", " end stopwatch"}, 10) then
- if localDatabase[player].stopwatch then
- if localDatabase[player].stopwatch.running then
- localDatabase[player].stopwatch.running = false
- localDatabase[player].stopwatch.start = os.clock() - localDatabase[player].stopwatch.start
- local reading = math.ceil(localDatabase[player].stopwatch.start*100 - 0.5)/100
- return true, {"Okay, I stopped the stopwatch", "The stopwatch reads: "..reading.." seconds"}
- else
- local reading = math.ceil(localDatabase[player].stopwatch.start*100 - 0.5)/100
- return true, {"The stopwatch has already been stopped", "The stopwatch reads: "..reading.." seconds"}
- end
- else
- end
- elseif searchAndTrim(message, {" how much time", " stopwatch", " time passed"}) then
- if localDatabase[player].stopwatch then
- if localDatabase[player].stopwatch.running then
- local rawReading = os.clock() - localDatabase[player].stopwatch.start
- local reading = math.ceil(rawReading*100 - 0.5)/100
- return true, {"The running stopwatch reads: "..reading.." seconds"}
- else
- local reading = math.ceil(localDatabase[player].stopwatch.start*100 - 0.5)/100
- return true, {"The stopped stopwatch reads: "..reading.." seconds"}
- end
- else
- return true, {"You have never started the stopwatch!"}
- end
- end
- end
- local alphabet = "abcdefghijklmnopqrstuvwxyz"
- matches["math"] = function(player, message)
- local matchSuccess, _, search = searchAndTrim(message, {" what's (%(*%d.+)$", " what is (%(*%d.+)$", " whats (%(*%d.+)$", "^%S+ (%(*%d.+)$", "^(%(*%d.+)$", " what does (%(*%d.+)$", " what is (%(*%d.+)$"})
- if matchSuccess then
- search = search[1]
- end
- if matchSuccess and (search:find("%+") or search:find("%*") or search:find("%^") or search:find("%/") or search:find("%-")) then
- search = search:gsub("%?", "")
- search = search:gsub("=", "")
- for i = 1, #alphabet do
- search = search:gsub(alphabet:sub(i, i), "")
- end
- local func = loadstring("return "..search)
- local result = nil
- if func then
- if pcall(function() result = func() end) then
- return true, {"The answer is: "..tostring(result)}
- else
- return true, {"Sorry, I couldn't calculate that!", "Make sure you don't use any", "alphabetical letters in it"}
- end
- else
- return true, {"Sorry, I couldn't process that calculation!", "Make sure you don't use any", "alphabetical letters in it"}
- end
- end
- end
- matches["weather"] = function(player, message, shouldSay)
- if searchAndTrim(message, {" what ", " whats ", " what's ", " what is ", " how ", " how's ", " how is "}, 6) then
- local _, search = searchAndTrim(message, {" what ", " whats ", " what's ", " what is ", " how ", " how's ", " how is "}, 6)
- if searchAndTrim(search, {" weather ", " forecast ", " temperature ", " hot ", " cold "}, 8) then
- _, search = searchAndTrim(search, {" weather ", " forecast ", " temperature ", " hot ", " cold "}, 8)
- if searchAndTrim(search, {" for ", " in ", " at "}, 10) then
- _, location = searchAndTrim(search, {" for ", " in ", " at "}, 10)
- if searchAndTrim(search, {" tomorrow"}, 40) then
- return commands["weather"](player, location, "tomorrow", shouldSay)
- else
- return commands["weather"](player, location, "today", shouldSay)
- end
- end
- elseif searchAndTrim(search, {" now ", " today", " tomorrow"}, 8) then
- _, search = searchAndTrim(search, {" now ", " today", " tomorrow"}, 8)
- if searchAndTrim(search, {" weather ", " forecast ", " temperature ", " hot ", " cold "}, 8) then
- _, search = searchAndTrim(search, {" weather ", " forecast ", " temperature ", " hot ", " cold "}, 8)
- if searchAndTrim(search, {" for ", " in ", " at "}, 10) then
- _, location = searchAndTrim(search, {" for ", " in ", " at "}, 10)
- if searchAndTrim(message, {" tomorrow"}) then
- return commands["weather"](player, location, "tomorrow", shouldSay)
- else
- return commands["weather"](player, location, "today", shouldSay)
- end
- end
- end
- end
- elseif searchAndTrim(message, {" weather ", " forecast ", " temperature "}, 6) then
- local _, search = searchAndTrim(message, {" weather ", " forecast ", " temperature "}, 6)
- if searchAndTrim(search, {" for ", " in ", " at "}, 10) then
- _, location = searchAndTrim(search, {" for ", " in ", " at "}, 10)
- if searchAndTrim(search, {" tomorrow"}, 40) then
- return commands["weather"](player, location, "tomorrow", shouldSay)
- else
- return commands["weather"](player, location, "today", shouldSay)
- end
- end
- elseif searchAndTrim(message, {" will ", " is "}, 10) then
- if searchAndTrim(message, {" rain", " sun", " snow", " clear", " hot ", " cold "}, 30) then
- _, search = searchAndTrim(message, {" rain", " sun", " snow", " clear", " hot ", " cold "}, 30)
- if searchAndTrim(search, {" for ", " in ", " at "}, 20) then
- _, location = searchAndTrim(search, {" for ", " in ", " at "}, 20)
- if searchAndTrim(search, {" tomorrow"}, 40) then
- return commands["weather"](player, location, "tomorrow", shouldSay)
- else
- return commands["weather"](player, location, "today", shouldSay)
- end
- end
- end
- end
- end
- matches["define"] = function(player, message, shouldSay)
- if searchAndTrim(message, {" define ", " definition ", " meaning "}, 20) then
- local _, search = searchAndTrim(message, {" define ", " definition ", " meaning "}, 20)
- local word = search:gsub(" of ", "")
- word = word:gsub(" the ", "")
- word = word:gsub("%?", "")
- word = word:gsub("%.", "")
- return commands["define"](player, trim(word), shouldSay)
- elseif searchAndTrim(message, {" what does "}, 20) then
- local _, search = searchAndTrim(message, {" what does "}, 20)
- if searchAndTrim(search, {" mean"}) then
- local word = message:match("does (.+) mean")
- if not word then
- return false
- end
- if trim(word) == "that" then
- return false
- end
- return commands["define"](player, trim(word), shouldSay)
- end
- end
- end
- matches["convert"] = function(player, message, shouldSay)
- if message:match("%d+%.%d+.+ to .+") then
- return commands["convert"](player, message, shouldSay)
- elseif message:match("%d+%.%d+.+ in .+") then
- return commands["convert"](player, message, shouldSay)
- elseif message:match("%d+.+ to .+") then
- return commands["convert"](player, message, shouldSay)
- elseif message:match("%d+.+ in .+") then
- return commands["convert"](player, message, shouldSay)
- end
- end
- matches["1music"] = function(player, message)
- if searchAndTrim(message, {" play ", " listen to "}, 6) then
- local _, search = searchAndTrim(message, {" play ", " listen to ", " start "})
- if drive then
- if searchAndTrim(search, {" music", " some music", " song", " some song", " the music", " the song", tostring(drive.hasAudio())}, 3) then
- if drive.getAudioTitle() and (os.clock() - musicClock) < musicLength then
- return true, {"Music is already playing!"}, false, true
- elseif drive.getAudioTitle() then
- return true, {"Now playing: "..drive.getAudioTitle()}, false, true, function()
- musicClock = os.clock()
- drive.playAudio()
- end
- else
- return true, {"I don't have any music in", "my disk drive to play :("}, false, true
- end
- else
- return true, {"Sorry, I currently can only play", "the disk in my disk drive :("}
- end
- else
- return true, {"Sorry, I don't have a disk drive", "to play music with :("}, false, true
- end
- elseif searchAndTrim(message, {" what ", " whats ", " what's ", " what is "}, 6) then
- local _, search = searchAndTrim(message, {" what ", " whats ", " what's ", " what is "})
- if searchAndTrim(search, {" song", " this song", " the song", " music", " this music", " playing", " the music", " the current song", " this current song", " currently play"}, 3) then
- if drive and drive.getAudioTitle() and (os.clock() - musicClock) < musicLength then
- return true, {"The currently playing song is", drive.getAudioTitle()}
- else
- return true, {"There currently is no music playing!"}, false, true
- end
- end
- elseif searchAndTrim(message, {" stop ", " pause "}) then
- local _, search = searchAndTrim(message, {" stop ", " pause "})
- if searchAndTrim(search, {" play", " music", " the music", " the song", " this music", " this song"}, 3) then
- if drive and drive.getAudioTitle() and (os.clock() - musicClock) < musicLength then
- return true, {"Ok, music stopped"}, false, true, function()
- drive.stopAudio()
- musicClock = musicLength * -1
- end
- else
- return true, {"There currently is no music playing!"}, false, true
- end
- end
- end
- end
- matches["joke"] = function(player, message)
- if searchAndTrim(message, {" tell me a joke", " tell a joke", " give me a joke", " give a joke"}, 4) then
- local jokes = {'Did you hear about the guy whose whole left side was cut off? He\'s all right now.',
- "I'm reading a book about anti-gravity. It's impossible to put down.",
- "I wondered why the baseball was getting bigger. Then it hit me.",
- "It's not that the man did not know how to juggle, he just didn't have the balls to do it.",
- "I'm glad I know sign language, it's pretty handy.",
- "My friend's bakery burned down last night. Now his business is toast.",
- "Why did the cookie cry? It was feeling crumby.",
- "I used to be a banker, but I lost interest.",
- "A drum and a symbol fall off a cliff",
- "Why do seagulls fly over the sea? Because they aren't bay-gulls!",
- "Why did the fireman wear red, white, and blue suspenders? To hold his pants up.",
- "Why didn't the crab share his food? Because crabs are territorial animals, that don't share anything.",
- "Why was the javascript developer sad? Because he didn't Node how to Express himself.",
- "What do I look like? A JOKE MACHINE!?",
- "How did the hipster burn the roof of his mouth? He ate the pizza before it was cool.",
- "Why is it hard to make puns for kleptomaniacs? They are always taking things literally.",
- "Why do mermaid wear sea-shells? Because b-shells are too small.",
- "I'm a humorless, cold hearted, machine.",
- "Two fish in a tank. One looks to the other and says 'Can you even drive this thing???'",
- "Two fish swim down a river, and hit a wall. One says: 'Dam!'",
- "What's funnier than a monkey dancing with an elephant? Two monkeys dancing with an elephant.",
- "How did Darth Vader know what Luke was getting for Christmas? He felt his presents.",
- "What's red and bad for your teeth? A Brick.",
- "What's orange and sounds like a parrot? A Carrot.",
- "What do you call a cow with no legs? Ground beef",
- "Two guys walk into a bar. You'd think the second one would have noticed.",
- "What is a centipedes's favorite Beatle song? I want to hold your hand, hand, hand, hand...",
- "What do you call a chicken crossing the road? Poultry in moton. ",
- "Did you hear about the Mexican train killer? He had locomotives",
- "What do you call a fake noodle? An impasta",
- "How many tickles does it take to tickle an octupus? Ten-tickles!",
- "At the rate law schools are turning them out, by 2050 there will be more lawyers than humans."
- }
- return true, textWrap(jokes[math.random(1, #jokes)])
- end
- end
- matches["zlookup"] = function(player, message, shouldSay)
- if searchAndTrim(message, {" wolfram ", " wolframalpha ", " wa ", " wa, ", " lookup ",
- " wa: ", " lookup: ", " search for ", " search "}, 4) then
- local _, query = searchAndTrim(message, {" wolfram ", " wolframalpha ", " wa ", " wa, ", " lookup ",
- " wa: ", " lookup: ", " search for ", " search "}, 4)
- if #trim(query) == 0 then
- return false
- end
- local post = "query_type=wolframalpha&query=" .. textutils.urlEncode(trim(query))
- return commands["remote-services"](player, post, shouldSay)
- end
- end
- if fs.exists("/chat-config") then
- local f = io.open("/chat-config")
- database = textutils.unserialize(f:read("*a"))
- f:close()
- end
- if database then
- print("Database loaded!")
- else
- database = {}
- print("Database failed to be loaded!")
- end
- print("Running chat assistant")
- for k,v in pairs(database) do
- if v.reminders and #v.reminders > 0 then
- for i = 1, #v.reminders do
- database[k].reminders[i][2] = 0
- end
- end
- end
- local checkTimer = os.startTimer(1)
- local success, messages, clear, localAction, callbackFunc = nil, nil, nil, nil, nil
- local function mainLoop()
- while true do
- local e, side, player, message = os.pullEvent()
- if e == "chat_message" or e == "chatbox_command" then
- if message:sub(1, 2) == "$$" then
- message = message:sub(3, -1)
- end
- message = " " .. message .. " "
- if not localDatabase[player] then
- localDatabase[player] = {}
- end
- if message == "cancel" then
- table.insert(localDatabase[player], {"clear", os.clock()})
- end
- local shouldSay = e == "chat_message"
- if player == "Ale32bit" then
- shouldSay = false
- end
- table.insert(receiveQueue, {player, message, shouldSay})
- os.queueEvent("ca_receive_message")
- elseif e == "timer" and side == checkTimer then
- checkTimer = os.startTimer(1)
- for k,v in pairs(database) do
- if v.reminders and #v.reminders > 0 then
- for i = 1, #v.reminders do
- if v.reminders[#v.reminders - i + 1] and os.clock() >= v.reminders[#v.reminders - i + 1][2] then
- if (not pendingReminders[tostring(#v.reminders - i + 1)]) or pendingReminders[tostring(#v.reminders - i + 1)] < os.clock() then
- pendingReminders[tostring(#v.reminders - i + 1)] = os.clock() + 5
- tell(k, {"Reminder: " .. v.reminders[#v.reminders - i + 1][1]},
- function()
- pendingReminders[tostring(#v.reminders - i + 1)] = nil
- table.remove(database[k].reminders, #v.reminders - i + 1)
- saveDatabase()
- end)
- end
- end
- end
- end
- end
- end
- end
- end
- local function messageReceiveLoop()
- while true do
- os.pullEvent("ca_receive_message")
- while #receiveQueue > 0 do
- player, message, shouldSay = unpack(receiveQueue[1])
- for _, key in pairs(orderedKeys) do
- local err, msg = pcall(function() success, messages, clear, localAction, callbackFunc = matches[key](player, message, shouldSay) end)
- if not err then
- print("An error has occured while running: "..key)
- print(msg)
- tell(player, {"Sorry! An error occured while executing", "your request."}, nil, nil, shouldSay)
- else
- if success then
- if key == "1remind" then
- shouldSay = false
- end
- tell(player, messages, callbackFunc, localAction, shouldSay)
- if clear then
- table.insert(localDatabase[player], {"clear", os.clock()})
- else
- table.insert(localDatabase[player], {key, os.clock()})
- end
- break
- end
- end
- success, messages, clear, localAction, callbackFunc = nil, nil, nil, nil
- end
- table.remove(receiveQueue, 1)
- end
- end
- end
- local function sendLoop()
- while true do
- os.pullEvent("ca_send_message")
- while #messageQueue > 0 do
- local result = nil
- sleep(0.1)
- if messageQueue[1][5] and not pmOnly then
- pcall(function() result = chat.say(messageQueue[1][2]) end)
- else
- pcall(function() result = chat.tell(messageQueue[1][1], messageQueue[1][2]) end)
- end
- if result then
- if messageQueue[1][3] then
- local err, msg = pcall(messageQueue[1][3])
- if not err then
- print("Error while running callback")
- print(msg)
- end
- end
- elseif modem and not messageQueue[1][4] then
- local newID = tostring({}):sub(8, -1)
- if messageQueue[1][3] then
- successCalls[newID] = messageQueue[1][3]
- end
- modem.transmit(operatingChannel, operatingChannel, {
- "chat-assistant-network", newID, messageQueue[1][1], messageQueue[1][2]
- })
- end
- table.remove(messageQueue, 1)
- end
- end
- end
- local function receiveLoop()
- while true do
- local event, side, channel, reply, message = os.pullEvent()
- if event == "modem_message" and channel == successChannel and type(message) == "string" then
- if successCalls[message] then
- local err, msg = pcall(successCalls[message])
- if not err then
- print("Error while running remote callback")
- print(msg)
- end
- successCalls[message] = nil
- end
- end
- end
- end
- for k in pairs(matches) do
- table.insert(orderedKeys, k)
- end
- table.sort(orderedKeys)
- parallel.waitForAny(mainLoop, sendLoop, receiveLoop, messageReceiveLoop)
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement