comparison mod_muc_dicebot/mod_muc_dicebot.lua @ 4579:b305814bd930

mod_muc_dicebot: A thing to roll dice Do you see what happens, Jitsi? Do you see what happens when you make it hard for me to use a proper bot? This is what happens, Jitsi. This is what happens when you meet a stranger in the alps! Ahem. In all seriousness, this is more of a quick hack than anything else. It will look for `.r` in MUC messages and if it finds it, it'll interpret it as an instruction to roll a few dice. Injects the results in the body of the message. Eats the message alive if it is malformed.
author Jonas Schäfer <jonas@wielicki.name>
date Sat, 29 May 2021 15:17:05 +0200
parents
children 785389a2d2b3
comparison
equal deleted inserted replaced
4578:d95fcde6e39d 4579:b305814bd930
1 local muc = module:depends("muc");
2 local rand = require"util.random";
3
4 local s_match = string.match;
5 local s_gmatch = string.gmatch;
6 local t_insert = table.insert;
7 local t_concat = table.concat;
8
9 local rooms = module:get_option_set("muc_dicebot_rooms", nil);
10 local xmlns_nick = "http://jabber.org/protocol/nick";
11
12 local function is_room_affected(roomjid)
13 return not rooms or rooms:contains(roomjid)
14 end
15
16 local function roll(sides)
17 if sides > 256 then
18 return nil, "too many sides"
19 end
20 local factor = math.floor(256 / sides);
21 local cutoff = sides * factor;
22 module:log("error", "%d -> %d %d %d", sides, max, factor, cutoff);
23 for i=1,10 do
24 local randomness = string.byte(rand.bytes(1), 1);
25 module:log("error", "%d", randomness);
26 if randomness < cutoff then
27 return (randomness % sides) + 1
28 end
29 end
30 return nil, "failed to find valid number"
31 end
32
33 local function muc_broadcast_message(event)
34 if not is_room_affected(event.room.jid) then
35 return
36 end
37
38 local stanza = event.stanza;
39 local body = stanza:get_child("body");
40 local text = body:get_text();
41 module:log("error", "%q %q %q", stanza, body, text);
42 local dice = s_match(text, "^[%.!]r%s(.+)$");
43 if not dice or dice == "" then
44 return
45 end
46
47 local results = {};
48 local count = 0;
49 local sum = 0;
50 for ndice, sep, sides in s_gmatch(dice, "(%d*)([wd]?)(%d+)") do
51 if not sep or sep == "" then
52 sides = ndice .. sides
53 ndice = "1"
54 end
55 local ndice = tonumber(ndice);
56 count = count + ndice;
57 if count > 100 then
58 return true
59 end
60 local sides = tonumber(sides);
61 for i=1,ndice do
62 local value = roll(sides);
63 t_insert(results, tostring(value));
64 sum = sum + value;
65 end
66 end
67 body:text("\n⇒ "..t_concat(results, " ").." (sum: "..sum..")");
68 end
69
70 module:hook("muc-broadcast-message", muc_broadcast_message);