minerbot-phoenix/plugins/minercoin.py

130 lines
4.7 KiB
Python
Raw Permalink Normal View History

2019-01-31 03:25:04 +00:00
"""MinerCoin.
How it works:
- On !minercoin, generate a mathematical challenge and present it in a non-bot-parseable way. Store the answer for later.
- On the next message in the channel the challenges are presented and issued from by said user, check and see if the answer is correct.
- If the answer is correct, reward the user with MinerCoins.
- If not, no reward is issued.
- Only let the user try a challenge every hour."""
2019-01-31 05:03:37 +00:00
import plugin, time, random, traceback, datetime
2019-01-31 03:25:04 +00:00
from pluralslib import plural
from dictdata import DictData
challenges = DictData("challenges.json")
last_used = DictData("times.json")
count = DictData("minercoin.json")
2019-01-31 05:03:37 +00:00
def username(f):
def __username(bot,channel,nick,*args):
return f(bot,channel,nick,bot.event.source.user.strip(),*args)
return __username
def get(username):
2019-01-31 03:25:04 +00:00
return count.get(username,0), last_used.get(username,0), challenges.get(username)
def set(source,ncount,nlast_used,nchallenge=None):
username = source.user
count[username]=ncount
last_used[username]=nlast_used
challenges[username]=nchallenge
2019-01-31 05:03:37 +00:00
names = "Alice Bob Carol Danvers Eve Frank Gerald Hope Indiana Jared Kate Larry Monica Nathan Orion Peter Quibley Ryan Stewart Tobias Uriah Violet Warren Xylia Yvonne Zelda".split()
2019-01-31 03:25:04 +00:00
# OK, this needs explaining.
# [int count, lambda verify, lambda answer, string question]
# count = how many numbers to generate
questions = [
2019-01-31 05:03:37 +00:00
# [2,lambda x,y: (x>=0 and x<=100),lambda x,y: int(round((x/100.)*y)),"Calculate {}% of {}. (round to the nearest whole number)"],
[1,lambda x: (x<182),lambda x: names[x%26],"If I introduce you to {}, what is their name?",lambda x: [names[x%26]]],
[2,lambda x,y: (x<195 and y<195),lambda x,y: (x%13)*(y%13),"Calculate {} times {}.",lambda x,y: [(i%13) for i in (x,y)]]
2019-01-31 03:25:04 +00:00
]
2019-01-31 05:03:37 +00:00
def safelist(n):
try:
return list(n)
except TypeError:
return [n]
2019-01-31 03:25:04 +00:00
def get_question():
q = random.choice(questions)
nums = [random.randint(0,200) for x in range(q[0])]
while not q[1](*nums):
nums = [random.randint(0,200) for x in range(q[0])]
cha = str(q[2](*nums))
2019-01-31 05:03:37 +00:00
if len(q)==5:
nums = safelist(q[4](*nums))
chq = q[3].format(*nums)
2019-01-31 03:25:04 +00:00
return chq, cha
2019-02-04 20:19:41 +00:00
@plugin.group("minercoin","<ask/count/score/cooldown/wait>")
2019-01-31 03:25:04 +00:00
def minercoin(bot,channel,nick,*args):
2019-02-04 20:19:41 +00:00
if args[0] not in "ask count cooldown score wait".split():
bot.say(channel,"{}: Usage: !minercoin <ask/count/score/cooldown/wait>".format(nick))
2019-01-31 03:25:04 +00:00
return True # only allow selected subcommands
elif channel!="#bots":
bot.say(channel,"{}: MinerCoin is only awarded in #bots, same as tildes!".format(nick))
return True
return False
leadins = ["pro-minercoin question","anti-autoasker question","pro-login question","pro-minerobber challenge"]
@minercoin.command("ask")
2019-01-31 05:03:37 +00:00
@username
def minercoin_ask(bot,channel,nick,username,*args):
cnt, last, challenge = get(username)
if (int(time.time())-last)<(60*60): # if it hasn't been an hour since the last one...
2019-01-31 03:25:04 +00:00
bot.say(channel,"{} is a doodoo head and needs to wait longer between attempts! (1 hour between attempts)".format(nick))
return
2019-01-31 05:03:37 +00:00
try:
question, challenge = get_question()
bot.say(channel,"{}: {}: {}".format(nick,random.choice(leadins),question))
set(bot.event.source,cnt,int(time.time()),challenge)
except:
traceback.print_exc()
2019-01-31 03:25:04 +00:00
@plugin.listener("minercoin_answer")
2019-01-31 05:03:37 +00:00
@username
def minercoin_listen(bot,channel,nick,username,message):
cnt, last, challenge = get(username)
2019-01-31 03:25:04 +00:00
if challenge is None: return
elif message==challenge:
2019-01-31 05:03:37 +00:00
payout = random.randint(1,5)
bot.say(channel,"{}: You are a winner and get {}!".format(nick,plural(payout,"MinerCoin")))
cnt+=payout
2019-01-31 03:25:04 +00:00
else:
bot.say(channel,"{} is a quitter and gets no MinerCoin!".format(nick))
set(bot.event.source,cnt,last,None)
@minercoin.command("count")
2019-01-31 05:03:37 +00:00
@username
def minercoin_count(bot,channel,nick,username,*args):
if username in count:
cnt = get(username)[0]
bot.say(channel,"{}: You have {}!".format(nick,plural(cnt,"MinerCoin")))
2019-01-31 03:25:04 +00:00
else:
bot.say(channel,"{}: You don't have any MinerCoin! Get some by asking! (!minercoin ask)".format(nick))
2019-02-04 20:10:51 +00:00
minercoin.command("score")(username(minercoin_count))
2019-01-31 03:25:04 +00:00
@minercoin.command("cooldown")
2019-01-31 05:03:37 +00:00
@username
def minercoin_cooldown(bot,channel,nick,username,*args):
last = get(username)[1]
if last==0: # special case: never used before
bot.say(channel,"{}: You can ask for more MinerCoin right away!".format(nick))
else:
delta = 3600-(int(time.time())-last)
delta = int(round(delta))
2019-02-04 20:24:33 +00:00
if delta<0:
bot.say(channel,"{}: You can ask for more MinerCoin right away!".format(nick))
2019-02-04 20:25:35 +00:00
return
2019-01-31 05:03:37 +00:00
minutes,seconds = divmod(delta,60)
timedesc = ""
if minutes:
timedesc += plural(minutes,"minute")+" and "
timedesc += plural(seconds,"second")
bot.say(channel,"{}: Please wait {} before asking for more MinerCoin.".format(nick,timedesc))
2019-02-04 20:12:07 +00:00
minercoin.command("wait")(minercoin_cooldown)