Skip to content

Commit ad893b6

Browse files
committed
Bot and conn now have a memory DefaultDict, where command can stick data they want to keep in memory
1 parent d3d6b5e commit ad893b6

3 files changed

Lines changed: 103 additions & 0 deletions

File tree

cloudbot/bot.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import asyncio
22
import time
33
import logging
4+
import collections
45
import re
56
import os
67
import gc
@@ -61,6 +62,9 @@ def __init__(self, loop=asyncio.get_event_loop()):
6162
# for plugins
6263
self.logger = logger
6364

65+
# for plugins to abuse
66+
self.memory = collections.defaultdict()
67+
6468
# declare and create data folder
6569
self.data_dir = os.path.abspath('data')
6670
if not os.path.exists(self.data_dir):

cloudbot/client.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import asyncio
22
import logging
3+
import collections
34

45
from cloudbot.permissions import PermissionManager
56

@@ -48,6 +49,9 @@ def __init__(self, bot, name, nick, *, channels=None, config=None):
4849
# create permissions manager
4950
self.permissions = PermissionManager(self)
5051

52+
# for plugins to abuse
53+
self.memory = collections.defaultdict()
54+
5155
def describe_server(self):
5256
raise NotImplementedError
5357

plugins/randoms.py

Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,104 @@
1+
"""
2+
randoms.py
3+
Dice, coins, and other randomized things!
4+
"""
5+
16
import asyncio
27
import random
38
import re
49

510
from cloudbot import hook
611

12+
whitespace_re = re.compile(r'\s+')
13+
valid_diceroll = re.compile(r'^([+-]?(?:\d+|\d*d(?:\d+|F))(?:[+-](?:\d+|\d*d(?:\d+|F)))*)( .+)?$', re.I)
14+
sign_re = re.compile(r'[+-]?(?:\d*d)?(?:\d+|F)', re.I)
15+
split_re = re.compile(r'([\d+-]*)d?(F|\d*)', re.I)
16+
17+
18+
def n_rolls(count, n):
19+
"""roll an n-sided die count times
20+
:type count: int
21+
:type n: int | str
22+
"""
23+
if n == "F":
24+
return [random.randint(-1, 1) for x in range(min(count, 100))]
25+
if n < 2: # it's a coin
26+
if count < 100:
27+
return [random.randint(0, 1) for x in range(count)]
28+
else: # fake it
29+
return [int(random.normalvariate(.5 * count, (.75 * count) ** .5))]
30+
else:
31+
if count < 100:
32+
return [random.randint(1, n) for x in range(count)]
33+
else: # fake it
34+
return [int(random.normalvariate(.5 * (1 + n) * count,
35+
(((n + 1) * (2 * n + 1) / 6. -
36+
(.5 * (1 + n)) ** 2) * count) ** .5))]
37+
38+
39+
@asyncio.coroutine
40+
@hook.command("roll", "dice")
41+
def dice(text, notice):
42+
"""<dice roll> - simulates dice rolls. Example: 'dice 2d20-d5+4 roll 2': D20s, subtract 1D5, add 4
43+
:type text: str
44+
"""
45+
46+
if hasattr(text, "groups"):
47+
text, desc = text.groups()
48+
else: # type(text) == str
49+
match = valid_diceroll.match(whitespace_re.sub("", text))
50+
if match:
51+
text, desc = match.groups()
52+
else:
53+
notice("Invalid dice roll '{}'".format(text))
54+
return
55+
56+
if "d" not in text:
57+
return
58+
59+
spec = whitespace_re.sub('', text)
60+
if not valid_diceroll.match(spec):
61+
notice("Invalid dice roll '{}'".format(text))
62+
return
63+
groups = sign_re.findall(spec)
64+
65+
total = 0
66+
rolls = []
67+
68+
for roll in groups:
69+
count, side = split_re.match(roll).groups()
70+
count = int(count) if count not in " +-" else 1
71+
if side.upper() == "F": # fudge dice are basically 1d3-2
72+
for fudge in n_rolls(count, "F"):
73+
if fudge == 1:
74+
rolls.append("\x033+\x0F")
75+
elif fudge == -1:
76+
rolls.append("\x034-\x0F")
77+
else:
78+
rolls.append("0")
79+
total += fudge
80+
elif side == "":
81+
total += count
82+
else:
83+
side = int(side)
84+
try:
85+
if count > 0:
86+
d = n_rolls(count, side)
87+
rolls += list(map(str, d))
88+
total += sum(d)
89+
else:
90+
d = n_rolls(-count, side)
91+
rolls += [str(-x) for x in d]
92+
total -= sum(d)
93+
except OverflowError:
94+
# I have never seen this happen. If you make this happen, you win a cookie
95+
return "Thanks for overflowing a float, jerk >:["
96+
97+
if desc:
98+
return "{}: {} ({})".format(desc.strip(), total, ", ".join(rolls))
99+
else:
100+
return "{} ({})".format(total, ", ".join(rolls))
101+
7102

8103
@asyncio.coroutine
9104
@hook.command

0 commit comments

Comments
 (0)