]> git.lizzy.rs Git - furrybot.git/blob - bot.lua
Refactoring, added 8ball command
[furrybot.git] / bot.lua
1 furrybot.commands = {}
2 furrybot.requests = {}
3
4 local C = minetest.get_color_escape_sequence
5
6 furrybot.colors = {
7         ping = C("#00DCFF"),
8         system = C("#FFFA00"),
9         error = C("#D70029"),
10         detail = C("#FF6683"),
11         rpg = C("#FFD94E"),
12         braces = C("#FFFAC0"),
13         info = C("#00FFC3"),
14         fun = C("#A0FF24"),
15         random = C("#A300BE"),
16 }
17
18 -- helper functions
19
20 function furrybot.send(msg, color)
21         minetest.send_chat_message("/me " .. furrybot.colors.braces .. "[" .. color .. msg .. furrybot.colors.braces .. "]")
22 end
23
24 function furrybot.ping(player, color)
25         return furrybot.colors.ping .. "@" .. player .. color
26 end
27
28 function furrybot.ping_message(player, message, color)
29         furrybot.send(furrybot.ping(player, color) .. ": " .. message, "")
30 end
31
32 function furrybot.error_message(player, error, detail)
33         furrybot.ping_message(player, error .. (detail and furrybot.colors.detail .. " '" .. detail .. "'" .. furrybot.colors.error or "") .. ".", furrybot.colors.error)
34 end
35
36 function furrybot.recieve(msg)
37         msg = minetest.strip_colors(msg)
38         if msg:find("<") == 1 then
39                 local idx = msg:find(">")
40                 local player = msg:sub(2, idx - 1)
41                 local message = msg:sub(idx + 3, #msg)
42                 if message:find("!") == 1 then
43                         local args = message:sub(2, #message):split(" ")
44                         local cmd = table.remove(args, 1)
45                         local func = furrybot.commands[cmd]
46                         if func then
47                                 func(player, unpack(args))
48                         else
49                                 furrybot.error_message(player, "Invalid command", cmd)
50                         end
51                 end
52         end
53 end
54
55 function furrybot.player_online(name)
56         for _, n in ipairs(minetest.get_player_names()) do
57                 if name == n then
58                         return true
59                 end
60         end
61 end
62
63 function furrybot.online_or_error(name, other, allow_self)
64         if not other then
65                 furrybot.error_message(name, "You need to specify a player")
66         elseif name == other and not allow_self then
67                 furrybot.error_message(name, "You need to specify a different player than yourself")
68         elseif furrybot.player_online(other) then
69                 return true
70         else
71                 furrybot.error_message(name, "Player not online", other)
72         end
73 end
74
75 function furrybot.choose(list, color)
76         return furrybot.colors.random .. list[math.random(#list)] .. color
77 end
78
79 function furrybot.random(min, max, color)
80         return furrybot.colors.random .. math.random(#list) .. color
81 end
82
83 function furrybot.http_request(url, name, callback)
84         furrybot.http.fetch({url = url}, function(res)
85                 if res.succeeded then
86                         callback(res.data)
87                 else
88                         furrybot.ping_player_error(name, "Request failed with code", res.code)
89                 end
90         end)
91 end
92
93 function furrybot.json_http_request(url, name, callback)
94         furrybot.http_request(url, name, function(raw)
95                 local data = minetest.parse_json(raw)
96                 callback(data[1] or data)
97         end)
98 end
99
100 function furrybot.strrandom(str, seed, ...)
101         local v = 0
102         local pr = PseudoRandom(seed)
103         for i = 1, #str do
104                 v = v + str:byte(i) * pr:next()
105         end
106         return PseudoRandom(v):next(...)
107 end
108
109 function furrybot.repeat_string(str, times)
110         local msg = ""
111         for i = 1, times do
112                 msg = msg .. str
113         end
114         return msg
115 end
116
117 function furrybot.simple_rpg_command(action)
118         return function(name, target)
119                 if furrybot.online_or_error(name, target) then
120                         furrybot.send(name .. " " .. action .. " " .. target .. ".", furrybot.colors.rpg)
121                 end
122         end
123 end
124
125 function furrybot.request_command(on_request, on_accept)
126         return function(name, target)
127                 if furrybot.online_or_error(name, target) then
128                         furrybot.requests[target] = {
129                                 origin = name,
130                                 func = on_accept,
131                         }
132                         on_request(name, target)
133                 end
134         end
135 end
136
137 -- Commands
138
139 -- system
140 function furrybot.commands.help()
141         local keys = {}
142         for k in pairs(furrybot.commands) do
143                 table.insert(keys, k)
144         end
145         furrybot.send("Available commands: " .. table.concat(keys, ", "), furrybot.colors.system)
146 end
147
148 function furrybot.commands.accept(name)
149         local tbl = furrybot.requests[name]
150         if tbl then
151                 furrybot.requests[name] = nil
152                 tbl.func(tbl.origin, name)
153         else
154                 furrybot.error_message(name, "Nothing to accept")
155         end
156 end
157
158 function furrybot.commands.deny(name)
159         local tbl = furrybot.requests[name]
160         if tbl then
161                 furrybot.requests[name] = nil
162                 furrybot.ping_message(name, "Denied request")
163         else
164                 furrybot.error_message(name, "Nothing to deny")
165         end
166 end
167
168 -- don't bug players that are running ClamityBot commands from discord
169 function furrybot.commands.status()
170 end
171
172 function furrybot.commands.cmd()
173 end
174
175 -- rpg
176 furrybot.commands.hug = furrybot.simple_rpg_command("hugs")
177 furrybot.commands.cuddle = furrybot.simple_rpg_command("cuddles")
178 furrybot.commands.kiss = furrybot.simple_rpg_command("kisses")
179 furrybot.commands.hit = furrybot.simple_rpg_command("hits")
180 furrybot.commands.slap = furrybot.simple_rpg_command("slap")
181 furrybot.commands.beat = furrybot.simple_rpg_command("beat")
182
183 furrybot.commands.sex = furrybot.request_command(function(name, target)
184         furrybot.ping_message(target, name .. " wants to have sex with you. Type !accept to accept or !deny to deny.", furrybot.colors.system)
185 end, function(name, target)
186         furrybot.send(name .. " and " .. target .. " are having sex! OwO", furrybot.colors.rpg)
187 end)
188 furrybot.commands.bang = furrybot.commands.sex
189 furrybot.commands.fuck = furrybot.commands.sex
190
191 -- misc
192 function furrybot.commands.rolldice(name)
193         furrybot.ping_message(name, "rolled a dice and got a " .. furrybot.random(1, 6, furrybot.colors.system) .. ".", furrybot.colors.system)
194 end
195
196 function furrybot.commands.coinflip(name)
197         furrybot.ping_message(name, "flipped a coin and got " .. furrybot.choose({"Heads", "Tails"}, furrybot.colors.system) .. ".", furrybot.colors.system)
198 end
199
200 function furrybot.commands.choose(name, ...)
201         local options = {...}
202         if #options > 1 then
203                 furrybot.ping_message(name, "I choose " .. furrybot.choose(options, "", furrybot.colors.system) .. ".", furrybot.colors.system)
204         else
205                 furrybot.error_message(name, "Not enough options")
206         end
207 end
208 furrybot.commands["8ball"] = furrybot.commands.choose
209
210 function furrybot.commands.dicksize(name, target)
211         target = target or name
212         local size = furrybot.strrandom(target, 31242, 2, 10)
213         local dick = furrybot.repeat_string("=", size) .. "D"
214         furrybot.send(dick .. furrybot.colors.system .. "   <= " .. furrybot.ping(target, furrybot.colors.system) .. "'s Dick", C("#FF4DE1"))
215 end
216 furrybot.commands.cocksize = furrybot.commands.dicksize
217
218 -- fun
219 function furrybot.commands.verse(name)
220         furrybot.json_http_request("https://labs.bible.org/api/?type=json&passage=random", name, function(data)
221                 furrybot.send(data.text .. furrybot.colors.info .. "[" .. data.bookname .. " " .. data.chapter .. "," .. data.verse .. "]", furrybot.colors.fun)
222         end)
223 end
224
225 function furrybot.commands.define(name, word)
226         if word then
227                 furrybot.json_http_request("https://api.dictionaryapi.dev/api/v1/entries/en_US/" .. word, name, function(data)
228                         local meaning = data.meaning
229                         local selected = meaning.exclamation or meaning.noun or meaning.verb or meaning.adjective or meaning["transitive verb"] or meaning.adverb or meaning["relative adverb"]
230                         if not selected then
231                                 print(dump(meaning))
232                                 furrybot.error_message(name, "Error in parsing response")
233                         else
234                                 furrybot.send(word:sub(1, 1):upper() .. word:sub(2, #word):lower() .. ": " .. furrybot.colors.fun .. selected[1].definition, furrybot.colors.info)
235                         end
236                 end)
237         else
238                 furrybot.error_message(name, "You need to specify a word")
239         end
240 end
241
242 function furrybot.commands.insult(name, target)
243         if furrybot.online_or_error(name, target, true) then
244                 furrybot.http_request("https://insult.mattbas.org/api/insult", name, function(data)
245                         furrybot.ping_message(target, data, furrybot.colors.fun)
246                 end)
247         end
248 end
249
250 function furrybot.commands.joke(name, first, last)
251         if not first then
252                 first = "Chuck"
253                 last = "Norris"
254         elseif not last then
255                 last = ""
256         end
257         furrybot.json_http_request("http://api.icndb.com/jokes/random?firstName=" .. first .. "&lastName=" .. last, name, function(data)
258                 local joke = data.value.joke:gsub("&quot;", "\""):gsub("  ", " ")
259                 furrybot.send(joke, furrybot.colors.fun)
260         end)
261 end
262
263 -- send reload message
264 if furrybot.loaded then
265         furrybot.send("Reloaded", furrybot.colors.system)
266 else
267         furrybot.loaded = true
268 end