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 )