3 local C = minetest.get_color_escape_sequence
5 function furrybot.send(msg, color)
6 minetest.send_chat_message("/me " .. C("#00FF3C") .. "[" .. C(color or "#FFFA00") .. msg .. C("#00FF3C") .. "]")
9 function furrybot.ping(player)
10 return C("#00DCFF") .. "@" .. player .. C("#FFFA00")
13 function furrybot.ping_player(player, message)
14 furrybot.send(furrybot.ping(player) .. ": " .. message)
17 function furrybot.ping_player_error(player, err, detail)
18 furrybot.ping_player(player, C("#D70029") .. " " .. err .. (detail and C("#FF6683") .. " '" .. detail .. "'" .. C("#D70029") or "") .. ".")
21 function furrybot.recieve(msg)
22 msg = minetest.strip_colors(msg)
23 if msg:find("<") == 1 then
24 local idx = msg:find(">")
25 local player = msg:sub(2, idx - 1)
26 local message = msg:sub(idx + 3, #msg)
27 if message:find("!") == 1 then
28 local args = message:sub(2, #message):split(" ")
29 local cmd = table.remove(args, 1)
30 local func = furrybot.commands[cmd]
32 func(player, unpack(args))
34 furrybot.ping_player_error(player, "Invalid command", cmd)
40 function furrybot.player_online(name)
41 for _, n in ipairs(minetest.get_player_names()) do
48 function furrybot.check_online(name, target)
50 furrybot.ping_player_error(name, "You need to specify a player")
51 elseif name == target then
52 furrybot.ping_player_error(name, "You need to specify a different player than yourself")
53 elseif furrybot.player_online(target) then
56 furrybot.ping_player_error(name, "Player not online", target)
60 function furrybot.choose(list)
61 return list[math.random(#list)]
64 function furrybot.http_request(url, name, callback)
65 furrybot.http.fetch({url = url}, function(res)
69 furrybot.ping_player_error(name, "Request failed with code", res.code)
74 function furrybot.json_http_request(url, name, callback)
75 furrybot.http_request(url, name, function(data)
76 callback(minetest.parse_json(data)[1])
80 function furrybot.rand(str, seed, ...)
82 local pr = PseudoRandom(seed)
84 v = v + str:byte(i) * pr:next()
86 return PseudoRandom(v):next(...)
91 function furrybot.commands.hug(name, target)
92 if furrybot.check_online(name, target) then
93 furrybot.send(name .. " hugs " .. target .. ".")
97 furrybot.commands.cuddle = furrybot.commands.hug
99 function furrybot.commands.kiss(name, target)
100 if furrybot.check_online(name, target) then
101 furrybot.send(name .. " kisses " .. target .. ".")
105 furrybot.target_list = {}
107 function furrybot.commands.bang(name, target)
108 if furrybot.check_online(name, target) then
109 furrybot.target_list[target] = function()
110 furrybot.send(ping(name) .. " and " .. ping(target) .. " are having sex! OwO")
112 furrybot.ping_player(target, name .. " wants to have sex with you. Type !accept to accept or !deny to deny.")
116 furrybot.commands.sex = furrybot.commands.bang
117 furrybot.commands.fuck = furrybot.commands.bang
119 function furrybot.commands.accept(name)
120 local func = furrybot.target_list[name]
124 furrybot.ping_player_error(name, "Nothing to accept")
128 function furrybot.commands.deny(name)
129 if furrybot.target_list[name] then
130 furrybot.target_list[name] = nil
131 furrybot.ping_player(name, "Denied request")
133 furrybot.ping_player_error(name, "Nothing to deny")
137 function furrybot.commands.hit(name, target)
138 if furrybot.check_online(name, target) then
139 furrybot.send(name .. " hits " .. target)
143 furrybot.commands.slap = furrybot.commands.hit
144 furrybot.commands.beat = furrybot.commands.hit
146 function furrybot.commands.help()
148 for k in pairs(furrybot.commands) do
149 table.insert(keys, k)
151 furrybot.send("Available commands: " .. table.concat(keys, ", "))
154 function furrybot.commands.verse(name)
155 furrybot.json_http_request("https://labs.bible.org/api/?type=json&passage=random", name, function(data)
156 furrybot.send(data.text .. C("#00FFC3") .. "[" .. data.bookname .. " " .. data.chapter .. "," .. data.verse .. "]")
160 function furrybot.commands.define(name, word)
162 furrybot.json_http_request("https://api.dictionaryapi.dev/api/v1/entries/en_US/" .. word, name, function(data)
163 local meaning = data.meaning
164 local selected = meaning.exclamation or meaning.noun or meaning.verb or meaning.adjective or meaning["transitive verb"] or meaning.adverb or meaning["relative adverb"]
167 furrybot.ping_player_error(name, "Error in parsing response")
169 furrybot.send(C("#00FFC3") .. word:sub(1, 1):upper() .. word:sub(2, #word):lower() .. ": " .. C("#FFFA00") .. selected[1].definition)
173 furrybot.ping_player_error(name, "You need to specify a word")
177 function furrybot.commands.insult(name, target)
178 if furrybot.check_online(name, target) then
179 furrybot.http_request("https://insult.mattbas.org/api/insult", name, function(data)
180 furrybot.ping_player(target, data)
185 function furrybot.commands.rolldice(name)
186 furrybot.ping_player(name, "rolled a dice and got a " .. C("#AAFF43") .. math.random(6))
189 function furrybot.commands.coinflip(name)
190 furrybot.ping_player(name, "flipped a coin and got " .. C("#AAFF43") .. furrybot.choose({"Heads", "Tails"}))
193 function furrybot.commands.status()
196 function furrybot.commands.cmd()
199 function furrybot.commands.cocksize(name, target)
200 target = target or name
201 local msg = C("#FF4DE1")
202 local size = furrybot.rand(target, 31242, 2, 10)
207 furrybot.send(msg .. C("#FFFA00") .. " <= " .. furrybot.ping(target) .. "'s Cock")
210 furrybot.commands.dicksize = furrybot.commands.cocksize
212 if furrybot.loaded then
213 furrybot.send("Reloaded")
215 furrybot.loaded = true