Mercurial > prosody-modules
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); |
