]> git.lizzy.rs Git - furrybot.git/blob - bot.lua
Japanese waifu names
[furrybot.git] / bot.lua
1 furrybot.commands = {}
2 furrybot.requests = {}
3
4 local http, env, storage
5 local C = minetest.get_color_escape_sequence
6
7 furrybot.colors = {
8         ping = C("#00DCFF"),
9         system = C("#FFFA00"),
10         error = C("#D70029"),
11         detail = C("#FF6683"),
12         roleplay = C("#FFD94E"),
13         braces = C("#FFFAC0"),
14         info = C("#00FFC3"),
15         fun = C("#A0FF24"),
16         random = C("#A300BE"),
17         money = C("#A11600"),
18 }
19
20 -- helper functions
21 function furrybot.send(msg, color)
22         minetest.send_chat_message("/me " .. furrybot.colors.braces .. "[" .. color .. msg .. furrybot.colors.braces .. "]")
23 end
24
25 function furrybot.ping(player, color)
26         return furrybot.colors.ping .. "@" .. player .. color
27 end
28
29 function furrybot.ping_message(player, message, color)
30         furrybot.send(furrybot.ping(player, color) .. ": " .. message, "")
31 end
32
33 function furrybot.error_message(player, error, detail)
34         furrybot.ping_message(player, error .. (detail and furrybot.colors.detail .. " '" .. detail .. "'" .. furrybot.colors.error or "") .. ".", furrybot.colors.error)
35 end
36
37 function furrybot.parse_message(player, message, discord)
38         if message:find("!") == 1 and not furrybot.ignored[player] then
39                 local args = message:sub(2, #message):split(" ")
40                 local cmd = table.remove(args, 1)
41                 local def = furrybot.commands[cmd]
42
43                 if def then
44                         if (def.unsafe or def.operator) and discord then
45                                 furrybot.error_message(player, "Sorry, you cannot run this command from discord: ", cmd)
46                         elseif def.operator and not furrybot.is_operator(player) then
47                                 furrybot.error_message(player, "Sorry, you need to be an operator run this command: ", cmd)
48                         elseif not def.ignore then
49                                 def.func(player, unpack(args))
50                         end
51                 else
52                         furrybot.error_message(player, "Invalid command", cmd)
53                 end
54         end
55 end
56
57 function furrybot.reload()
58         local func, err = env.loadfile("clientmods/furrybot/bot.lua")
59         if func then
60                 local old_fb = table.copy(furrybot)
61                 local status, init = pcall(func)
62
63                 if status then
64                         status, init = init(http, env, storage)
65                 end
66
67                 if not status then
68                         furrybot = old_fb
69                         furrybot.send("Error: " .. furrybot.colors.detail .. init, furrybot.colors.error)
70                 end
71         else
72                 furrybot.send("Syntax error: " .. furrybot.colors.detail .. err, furrybot.colors.error)
73         end
74 end
75
76 function furrybot.player_online(name)
77         for _, n in ipairs(minetest.get_player_names()) do
78                 if name == n then
79                         return true
80                 end
81         end
82 end
83
84 function furrybot.online_or_error(name, other, allow_self)
85         if not other then
86                 furrybot.error_message(name, "You need to specify a player")
87         elseif name == other and not allow_self then
88                 furrybot.error_message(name, "You need to specify a different player than yourself")
89         elseif furrybot.player_online(other) then
90                 return true
91         else
92                 furrybot.error_message(name, "Player not online", other)
93         end
94 end
95
96 function furrybot.choose(list, color)
97         return furrybot.colors.random .. list[math.random(#list)] .. color
98 end
99
100 function furrybot.random(min, max, color)
101         return furrybot.colors.random .. math.random(min, max) .. color
102 end
103
104 function furrybot.http_request(url, name, callback)
105         http.fetch({url = url}, function(res)
106                 if res.succeeded then
107                         callback(res.data)
108                 else
109                         furrybot.error_message(name, "Request failed with code", res.code)
110                 end
111         end)
112 end
113
114 function furrybot.json_http_request(url, name, callback)
115         furrybot.http_request(url, name, function(raw)
116                 local data = minetest.parse_json(raw)
117                 callback(data[1] or data)
118         end)
119 end
120
121 function furrybot.strrandom(str, seed, ...)
122         local v = 0
123         local pr = PseudoRandom(seed)
124         for i = 1, #str do
125                 v = v + str:byte(i) * pr:next()
126         end
127         return PseudoRandom(v):next(...)
128 end
129
130 function furrybot.repeat_string(str, times)
131         local msg = ""
132         for i = 1, times do
133                 msg = msg .. str
134         end
135         return msg
136 end
137
138 function furrybot.uppercase(str)
139         return str:sub(1, 1):upper() .. str:sub(2, #str)
140 end
141
142 function furrybot.interactive_roleplay_command(cmd, action)
143         furrybot.commands[cmd] = {
144                 params = "<player>",
145                 help = furrybot.uppercase(cmd) .. " another player",
146                 func = function(name, target)
147                         if furrybot.online_or_error(name, target) then
148                                 furrybot.send(name .. " " .. action .. " " .. target .. ".", furrybot.colors.roleplay)
149                         end
150                 end,
151         }
152 end
153
154 function furrybot.solo_roleplay_command(cmd, action, help)
155         furrybot.commands[cmd] = {
156                 help = furrybot.uppercase(cmd),
157                 func = function(name)
158                         furrybot.send(name .. " " .. action .. ".", furrybot.colors.roleplay)
159                 end,
160         }
161 end
162
163 function furrybot.request_command(cmd, help, on_request, on_accept, unsafe)
164         furrybot.commands[cmd] = {
165                 unsafe = true,
166                 params = "<player>",
167                 help = "Request to " .. help,
168                 func = function(name, target)
169                         if furrybot.online_or_error(name, target) and on_request(name, target) ~= false then
170                                 furrybot.requests[target] = {
171                                         origin = name,
172                                         func = on_accept,
173                                 }
174                         end
175                 end,
176         }
177 end
178
179 function furrybot.is_operator(name)
180         return name == minetest.localplayer:get_name() or furrybot.operators[name]
181 end
182
183 function furrybot.list_change_command(cmd, list_name, title, status)
184         furrybot.commands[cmd] = {
185                 operator = true,
186                 func = function(name, target)
187                         if target then
188                                 if furrybot[list_name][target] == status then
189                                         furrybot.error_message(name, "Player " .. (status and "already" or "not") .. " " .. title .. ": ", target)
190                                 else
191                                         furrybot[list_name][target] = status
192                                         storage:set_string(list_name, minetest.serialize(furrybot[list_name]))
193                                         furrybot.ping_message(name, "Successfully " .. cmd .. (cmd:sub(#cmd, #cmd) == "e" and "" or "e") .. "d " .. target, furrybot.colors.system)
194                                 end
195                         else
196                                 furrybot.error_message(name, "You need to specify a player")
197                         end
198                 end,
199         }
200 end
201
202 function furrybot.list_command(cmd, list_name, title)
203         furrybot.commands[cmd] = {
204                 func = function()
205                         local names = {}
206
207                         for name in pairs(furrybot[list_name]) do
208                                 table.insert(names, name)
209                         end
210
211                         furrybot.send("List of " .. title .. ": " .. table.concat(names, ", "), furrybot.colors.system)
212                 end,
213         }
214 end
215
216 furrybot.commands.cmd = {
217         ignore = true,
218 }
219
220 furrybot.commands.status = {
221         ignore = true,
222 }
223
224 furrybot.commands.help = {
225         params = "[<command>]",
226         help = "Display help for a commands or show list of available commands",
227         func = function(name, command)
228                 if command then
229                         local def = furrybot.commands[command]
230
231                         if def then
232                                 furrybot.send("!" .. command .. (def.params and " " .. def.params or "") .. ": " .. (def.help or "No description given"), furrybot.colors.system)
233                         else
234                                 furrybot.error_message(name, "Invalid command", command)
235                         end
236                 else
237                         local commands = {}
238
239                         for cmd in pairs(furrybot.commands) do
240                                 table.insert(commands, cmd)
241                         end
242
243                         table.sort(commands)
244
245                         furrybot.send("Available commands: " .. table.concat(commands, ", "), furrybot.colors.system)
246                 end
247         end,
248 }
249
250 furrybot.commands.accept = {
251         unsafe = true,
252         help = "Accept a request",
253         func = function(name)
254                 local tbl = furrybot.requests[name]
255                 if tbl then
256                         furrybot.requests[name] = nil
257                         tbl.func(tbl.origin, name)
258                 else
259                         furrybot.error_message(name, "Nothing to accept")
260                 end
261         end,
262 }
263
264 furrybot.commands.deny = {
265         unsafe = true,
266         help = "Deny a request",
267         func = function(name)
268                 local tbl = furrybot.requests[name]
269                 if tbl then
270                         furrybot.requests[name] = nil
271                         furrybot.ping_message(name, "Denied request", furrybot.colors.system)
272                 else
273                         furrybot.error_message(name, "Nothing to deny")
274                 end
275         end,
276 }
277
278 return function(_http, _env, _storage)
279         http, env, storage = _http, _env, _storage
280
281         furrybot.operators = minetest.deserialize(storage:get_string("operators")) or {}
282         furrybot.ignored = minetest.deserialize(storage:get_string("ignored")) or {}
283
284         for _, f in ipairs {"nsfw", "roleplay", "death", "economy", "random", "http", "operator", "bullshit", "marriage", "waifu"} do
285                 local func, err = env.loadfile("clientmods/furrybot/" .. f .. ".lua")
286
287                 if not func then
288                         return false, err
289                 end
290
291                 func()(http, env, storage)
292         end
293
294         furrybot.send("FurryBot - " .. C("#170089") .. "https://github.com/EliasFleckenstein03/furrybot", furrybot.colors.system)
295
296         if furrybot.loaded then
297                 furrybot.send("Reloaded", furrybot.colors.system)
298         else
299                 furrybot.loaded = true
300         end
301
302         return true
303 end