def _check(self): now=time.time() if now-self.last_update_time < self.update_period: return True self.last_update_time=now if True: results = self.twitter.direct_messages(since_id=self.last_seen_dm_id) for result in results: self._parse_dm(result) if long(result.id) > self.last_seen_dm_id: self.last_seen_dm_id = long(result.id) redis_set('twitter:last_seen_dm_id',self.last_seen_dm_id) # doesn't seem to obey since_id #results = self.twitter.mentions_timeline(since_id=self.last_seen_tweet_id) results = [status for status in tweepy.Cursor(self.twitter.mentions_timeline,q=self.keyword,since_id=self.last_seen_tweet_id).items(100)] log_log('tweet list since %d: %s' % (long(self.last_seen_tweet_id),str(results))) for result in results: self._parse_tweet(result) if long(result.id) > self.last_seen_tweet_id: self.last_seen_tweet_id = long(result.id) redis_set('twitter:last_seen_tweet_id',self.last_seen_tweet_id) while self._post_next_reply(): pass log_log('TwitterNetwork: update done in %.1f seconds' % float(time.time()-self.last_update_time)) return True
def _check(self): now=time.time() if now-self.last_update_time < self.update_period: return True self.last_update_time=now if not self.last_seen_ids: self.last_seen_ids=redis_smembers('reddit:last_seen_ids') log_log('loaded last seen ids: %s ' % str(self.last_seen_ids)) if self.use_unread_api: for message in self.reddit.get_unread(): self._parse(message,not message.was_comment) else: messages=self.reddit.get_inbox() for message in messages: if not message.was_comment: self._parse(message,True) sr=self.reddit.get_subreddit("+".join(self.subreddits)) comments=sr.get_comments(limit=self.load_limit) for comment in comments: self._parse(comment,False) while self._post_next_reply(): pass log_log('RedditNetwork: update done in %.1f seconds' % float(time.time()-self.last_update_time)) return True
def _check_and_create(self, filename, contents): if len(filename) <= self.fs_prefix_tree: log_error('Filename %s too small for prefix tree %d' % (filename, self.fs_prefix_tree)) return None path = self.fs_location split_path = '' for p in range(self.fs_prefix_tree): path = os.path.join(path, filename[p]) split_path = '/'.join([split_path, filename[p]]) if os.path.exists(path): if not os.path.isdir(path): log_log('notadir') log_error('%s exists and is not a directory' % str(path)) return None else: os.mkdir(path) fpath = os.path.join(path, filename[self.fs_prefix_tree:]) split_path = '/'.join([split_path, filename[self.fs_prefix_tree:]]) if os.path.exists(fpath): log_error('%s exists' % str(fpath)) return None f = open(fpath, 'w') f.write(contents) f.close() return split_path
def RetrieveTipbotBalance(force_refresh=False): global cached_tipbot_balance, cached_tipbot_unlocked_balance, cached_tipbot_balance_timestamp if not force_refresh and cached_tipbot_balance_timestamp and time.time()-cached_tipbot_balance_timestamp < config.tipbot_balance_cache_time: return cached_tipbot_balance, cached_tipbot_unlocked_balance j = SendWalletJSONRPCCommand("getbalance",None) if not "result" in j: log_error('RetrieveTipbotBalance: result not found in reply') raise RuntimeError("") return result = j["result"] if not "balance" in result: log_error('RetrieveTipbotBalance: balance not found in result') raise RuntimeError("") return if not "unlocked_balance" in result: log_error('RetrieveTipbotBalance: unlocked_balance not found in result') raise RuntimeError("") return balance = result["balance"] unlocked_balance = result["unlocked_balance"] log_log('RetrieveTipbotBalance: balance: %s' % str(balance)) log_log('RetrieveTipbotBalance: unlocked_balance: %s' % str(unlocked_balance)) pending = long(balance)-long(unlocked_balance) if pending < 0: log_error('RetrieveTipbotBalance: Negative pending balance! balance %s, unlocked %s' % (str(balance),str(unlocked_balance))) raise RuntimeError("") return cached_tipbot_balance_timestamp=time.time() cached_tipbot_balance=balance cached_tipbot_unlocked_balance=unlocked_balance return balance, unlocked_balance
def _check_and_create(self,filename,contents): if len(filename)<=self.fs_prefix_tree: log_error('Filename %s too small for prefix tree %d' % (filename,self.fs_prefix_tree)) return None path=self.fs_location split_path='' for p in range(self.fs_prefix_tree): path=os.path.join(path,filename[p]) split_path='/'.join([split_path,filename[p]]) if os.path.exists(path): if not os.path.isdir(path): log_log('notadir') log_error('%s exists and is not a directory' % str(path)) return None else: os.mkdir(path) fpath=os.path.join(path,filename[self.fs_prefix_tree:]) split_path='/'.join([split_path,filename[self.fs_prefix_tree:]]) if os.path.exists(fpath): log_error('%s exists' % str(fpath)) return None f=open(fpath,'w') f.write(contents) f.close() return split_path
def _check(self): now = time.time() if now - self.last_update_time < self.update_period: return True self.last_update_time = now if not self.last_seen_ids: self.last_seen_ids = redis_smembers('reddit:last_seen_ids') log_log('loaded last seen ids: %s ' % str(self.last_seen_ids)) if self.use_unread_api: for message in self.reddit.get_unread(): self._parse(message, not message.was_comment) else: for message in self.reddit.inbox.unread(limit=self.load_limit): #if not message.was_comment: self._parse(message, True) #print "Submissions from %s" % ("+".join(self.subreddits)) #sr=self.reddit.subreddit("+".join(self.subreddits)) #for s in sr.new(limit=self.load_limit): # for comment in s.comments: # self._parse(comment,False) while self._post_next_reply(): pass log_log('RedditNetwork: update done in %.1f seconds' % float(time.time() - self.last_update_time)) return True
def is_acceptable_command_prefix(self,s): s=s.strip() log_log('checking whether %s is an acceptable command prefix' % s) if s=="": return True if re.match("%s[\t ]*[:,]?$"%config.tipbot_name, s): return True return False
def is_acceptable_command_prefix(self, s): s = s.strip() log_log('checking whether %s is an acceptable command prefix' % s) if s == "": return True if re.match("%s[\t ]*[:,]?$" % config.tipbot_name, s): return True return False
def SwitchToNextHand(link): identity=link.identity() log_log('switching to next hand, from current %d' % players[identity]['player_current_hand']) players[identity]['player_current_hand'] = players[identity]['player_current_hand'] + 1 if players[identity]['player_current_hand'] < len(players[identity]['player_hands']): if not players[identity]['finished']: dealer_hand = players[identity]['dealer_hand'] link.send("%s: Your hand is %s. Dealer's hand is %s" % (link.user.nick, PlayerHandsToString(link,True),HandToString(dealer_hand,identity in utf8users,True,False))) elif not players[identity]['finished']: DealerMove(link)
def GetIdentityFromPaymentID(p): if not redis_hexists("paymentid", p): log_log('PaymentID %s not found' % p) return None identity = redis_hget("paymentid", p) log_log('PaymentID %s => %s' % (p, str(identity))) # HACK - grandfathering pre-network payment IDs if identity.index(':') == -1: log_warn('Pre-network payment ID found, assuming freenode') identity = "freenode:" + identity return identity
def GetIdentityFromPaymentID(p): if not redis_hexists("paymentid",p): log_log('PaymentID %s not found' % p) return None identity = redis_hget("paymentid",p) log_log('PaymentID %s => %s' % (p, str(identity))) # HACK - grandfathering pre-network payment IDs if identity.index(':') == -1: log_warn('Pre-network payment ID found, assuming freenode') identity = "freenode:"+identity return identity
def PreparePinata(reset=False,units=None): p=redis_pipeline() if reset or not redis_hexists('pinata','target'): target=GetTarget((config.pinata_base_target+config.pinata_target_increment*random.randint(0,config.pinata_num_increments))*coinspecs.atomic_units) log_log('PreparePinata: target %s' % target) p.hset('pinata','target',target) if reset or not redis_hexists('pinata','units'): units=long(units or config.pinata_start_amount*coinspecs.atomic_units) if units < config.pinata_start_amount*coinspecs.atomic_units: units = long(config.pinata_start_amount*coinspecs.atomic_units) p.hset('pinata','units',units) p.hincrby('pinata','profit',-units) p.hincrby('earmarked','pinata',units) p.execute()
def Split(link,cmd): identity=link.identity() if not identity in players: link.send("%s: you are not in a game of blackjack - you can start one with !blackjack <amount>" % link.user.nick) return units = players[identity]['amount'] enough, reason = IsPlayerBalanceAtLeast(link,units) if not enough: link.send("%s: %s - please refund your account to continue playing" % (link.user.nick, reason)) return idx = players[identity]['player_current_hand'] hand = GetPlayerCurrentHand(link) if len(hand)!=2 or GetCardScore(hand[0])!=GetCardScore(hand[1]): link.send("%s: only pairs with the same value can be split" % (link.user.nick)) return if len(players[identity]['player_hands']) >= config.blackjack_split_to: link.send("%s: you can only split to %d" % (link.user.nick, config.blackjack_split_to)) return enough, reason = IsPlayerBalanceAtLeast(link,units+players[identity]['base_amount']) if not enough: link.send("%s: you do not have enough %s in your account to split hand %d" % (link.user.nick,coinspecs.name,idx+1)) return players[identity]['amount'] = players[identity]['amount'] + players[identity]['base_amount'] RecordMove(link,"split") log_log('splitting hand %d' % idx) split_card_0 = hand[0] split_card_1 = hand[1] players[identity]['player_hands'].insert(idx+1,players[identity]['player_hands'][idx].copy()) players[identity]['player_hands'][idx]['hand'] = [ split_card_0, DrawCard(players[identity]['deck']) ] players[identity]['player_hands'][idx+1]['hand'] = [ split_card_1, DrawCard(players[identity]['deck']) ] sidebets = players[identity]['sidebets'] if sidebets['splits']: bet_units = sidebets['splits'] nsplits = len(players[identity]['player_hands']) if nsplits == 2: win_units = bet_units * 5 elif nsplits == 3: win_units = bet_units * (11-5) elif nsplits == 4: win_units = bet_units * (21-11) if nsplits == 2: link.send('%s splits to %d - you win %s' % (link.user.nick, nsplits, AmountToString(win_units))) else: link.send('%s resplits to %d - you win another %s' % (link.user.nick, nsplits, AmountToString(win_units))) UpdateSidebetRecord(link,"splits",True,False,win_units) dealer_hand = players[identity]['dealer_hand'] link.send("%s: your hand is now %s. Dealer's hand is %s" % (link.user.nick,PlayerHandsToString(link),HandToString(dealer_hand,identity in utf8users,True,False)))
def _parse_dm(self,msg): if msg.sender.screen_name.lower() == self.login.lower() and not force_parse_self: log_log('Ignoring DM from self') return log_info('Twitter: parsing DM from %s: %s' % (msg.sender.screen_name,msg.text)) link=Link(self,User(self,msg.sender.screen_name),None,None) for line in msg.text.split('\n'): exidx=line.find('!') if exidx!=-1 and len(line)>exidx+1 and line[exidx+1] in string.ascii_letters and self.is_acceptable_command_prefix(line[:exidx]): cmd=line[exidx+1:].split(' ') cmd[0] = cmd[0].strip(' \t\n\r') log_info('Found command from %s: %s' % (link.identity(), str(cmd))) if self.on_command: self.on_command(link,cmd)
def _schedule_reply(self,item,recipient,text): log_log('scheduling reply to %s:%s: %s' % (item.id if item else '""',recipient or '""',text)) if item: ndata = redis_llen('reddit:replies') if ndata > 0: prev_item = redis_lindex('reddit:replies',ndata-1) if prev_item: prev_parts=prev_item.split(':',2) prev_fullname=prev_parts[0] prev_recipient=prev_parts[1] prev_text=prev_parts[2] if prev_fullname==item.fullname: log_log('Appending to previous item, also for the same fullname') new_text=prev_text+"\n\n"+text redis_lset('reddit:replies',ndata-1,(item.fullname if item else "")+":"+(recipient or "")+":"+new_text) return redis_rpush('reddit:replies',(item.fullname if item else "")+":"+(recipient or "")+":"+text)
def PreparePinata(reset=False, units=None): p = redis_pipeline() if reset or not redis_hexists('pinata', 'target'): target = GetTarget( (config.pinata_base_target + config.pinata_target_increment * random.randint(0, config.pinata_num_increments)) * coinspecs.atomic_units) log_log('PreparePinata: target %s' % target) p.hset('pinata', 'target', target) if reset or not redis_hexists('pinata', 'units'): units = long(units or config.pinata_start_amount * coinspecs.atomic_units) if units < config.pinata_start_amount * coinspecs.atomic_units: units = long(config.pinata_start_amount * coinspecs.atomic_units) p.hset('pinata', 'units', units) p.hincrby('pinata', 'profit', -units) p.hincrby('earmarked', 'pinata', units) p.execute()
def connect(self): if self.thread: return False try: cfg = config.network_config[self.name] self.login = cfg['login'] ckey = GetPassword(self.name + "/ckey") csecret = GetPassword(self.name + "/csecret") atoken = GetPassword(self.name + "/atoken") atsecret = GetPassword(self.name + "/atsecret") self.update_period = cfg['update_period'] self.keyword = cfg['keyword'].lower() self.fs_location = cfg['fs_location'] self.fs_prefix_tree = cfg['fs_prefix_tree'] self.uri_base = cfg['uri_base'] self.prefix_when_linked = cfg['prefix_when_linked'] self.fs_hash_length = cfg['fs_hash_length'] if self.fs_location and not self._is_valid_location( self.fs_location): log_error('Invalid location: %s' % self.fs_location) return False self.items_cache = dict() self.last_seen_tweet_id = long( redis_get('twitter:last_seen_tweet_id') or 0) self.last_seen_dm_id = long( redis_get('twitter:last_seen_dm_id') or 0) log_log('loaded last seen id: tweet %s, dm %s' % (str(self.last_seen_tweet_id), str(self.last_seen_dm_id))) auth = tweepy.OAuthHandler(ckey, csecret) auth.set_access_token(atoken, atsecret) self.twitter = tweepy.API(auth) self.stop = False self.thread = threading.Thread(target=self.run) self.thread.start() except Exception, e: log_error('Failed to login to twitter: %s' % str(e)) return False
def _parse_dm(self, msg): if msg.sender.screen_name.lower() == self.login.lower( ) and not force_parse_self: log_log('Ignoring DM from self') return log_info('Twitter: parsing DM from %s: %s' % (msg.sender.screen_name, msg.text)) link = Link(self, User(self, msg.sender.screen_name), None, None) for line in msg.text.split('\n'): exidx = line.find('!') if exidx != -1 and len(line) > exidx + 1 and line[ exidx + 1] in string.ascii_letters and self.is_acceptable_command_prefix( line[:exidx]): cmd = line[exidx + 1:].split(' ') cmd[0] = cmd[0].strip(' \t\n\r') log_info('Found command from %s: %s' % (link.identity(), str(cmd))) if self.on_command: self.on_command(link, cmd)
def _parse_tweet(self,msg): if msg.user.screen_name.lower() == self.login.lower() and not force_parse_self: log_log('Ignoring tweet from self') return log_info('Twitter: parsing tweet from %s: %s' % (msg.user.screen_name,msg.text)) # twitter special: +x means tip the user mentioned with a @ for line in msg.text.split('\n'): line=line.lower() line=line.replace(self.keyword,'',1).strip() log_log('After removal: %s' % line) if re.match(username_regexp+"[ \t]*"+amount_regexp,line) or re.match(amount_regexp+"[ \t]*"+username_regexp,line): link=Link(self,User(self,msg.user.screen_name),None,msg) match=re.search(username_regexp,line) if not match: continue target=match.group(0) match=re.search(amount_regexp,line.replace(target,'').strip()) if not match: continue amount=match.group(0) if self.on_command: try: synthetic_cmd=['tip',target.replace('@','').strip(),amount.replace('+','').strip()] log_log('Running synthetic command: %s' % (str(synthetic_cmd))) self.on_command(link,synthetic_cmd) except Exception,e: log_error('Failed to tip %s: %s' % (target,str(e)))
def _check(self): now = time.time() if now - self.last_update_time < self.update_period: return True self.last_update_time = now if True: results = self.twitter.direct_messages( since_id=self.last_seen_dm_id) for result in results: self._parse_dm(result) if long(result.id) > self.last_seen_dm_id: self.last_seen_dm_id = long(result.id) redis_set('twitter:last_seen_dm_id', self.last_seen_dm_id) # doesn't seem to obey since_id #results = self.twitter.mentions_timeline(since_id=self.last_seen_tweet_id) results = [ status for status in tweepy.Cursor( self.twitter.mentions_timeline, q=self.keyword, since_id=self.last_seen_tweet_id).items(100) ] log_log('tweet list since %d: %s' % (long(self.last_seen_tweet_id), str(results))) for result in results: self._parse_tweet(result) if long(result.id) > self.last_seen_tweet_id: self.last_seen_tweet_id = long(result.id) redis_set('twitter:last_seen_tweet_id', self.last_seen_tweet_id) while self._post_next_reply(): pass log_log('TwitterNetwork: update done in %.1f seconds' % float(time.time() - self.last_update_time)) return True
def connect(self): if self.thread: return False try: cfg=config.network_config[self.name] self.login=cfg['login'] ckey=GetPassword(self.name+"/ckey") csecret=GetPassword(self.name+"/csecret") atoken=GetPassword(self.name+"/atoken") atsecret=GetPassword(self.name+"/atsecret") self.update_period=cfg['update_period'] self.keyword=cfg['keyword'].lower() self.fs_location=cfg['fs_location'] self.fs_prefix_tree=cfg['fs_prefix_tree'] self.uri_base=cfg['uri_base'] self.prefix_when_linked=cfg['prefix_when_linked'] self.fs_hash_length=cfg['fs_hash_length'] if self.fs_location and not self._is_valid_location(self.fs_location): log_error('Invalid location: %s' % self.fs_location) return False self.items_cache=dict() self.last_seen_tweet_id=long(redis_get('twitter:last_seen_tweet_id') or 0) self.last_seen_dm_id=long(redis_get('twitter:last_seen_dm_id') or 0) log_log('loaded last seen id: tweet %s, dm %s' % (str(self.last_seen_tweet_id),str(self.last_seen_dm_id))) auth=tweepy.OAuthHandler(ckey,csecret) auth.set_access_token(atoken,atsecret) self.twitter=tweepy.API(auth) self.stop = False self.thread = threading.Thread(target=self.run) self.thread.start() except Exception,e: log_error('Failed to login to twitter: %s' % str(e)) return False
def RetrieveTipbotBalance(force_refresh=False): global cached_tipbot_balance, cached_tipbot_unlocked_balance, cached_tipbot_balance_timestamp if not force_refresh and cached_tipbot_balance_timestamp and time.time( ) - cached_tipbot_balance_timestamp < config.tipbot_balance_cache_time: return cached_tipbot_balance, cached_tipbot_unlocked_balance j = SendWalletJSONRPCCommand("getbalance", None) if not "result" in j: log_error('RetrieveTipbotBalance: result not found in reply') raise RuntimeError("") return result = j["result"] if not "balance" in result: log_error('RetrieveTipbotBalance: balance not found in result') raise RuntimeError("") return if not "unlocked_balance" in result: log_error( 'RetrieveTipbotBalance: unlocked_balance not found in result') raise RuntimeError("") return balance = result["balance"] unlocked_balance = result["unlocked_balance"] log_log('RetrieveTipbotBalance: balance: %s' % str(balance)) log_log('RetrieveTipbotBalance: unlocked_balance: %s' % str(unlocked_balance)) pending = long(balance) - long(unlocked_balance) if pending < 0: log_error( 'RetrieveTipbotBalance: Negative pending balance! balance %s, unlocked %s' % (str(balance), str(unlocked_balance))) raise RuntimeError("") return cached_tipbot_balance_timestamp = time.time() cached_tipbot_balance = balance cached_tipbot_unlocked_balance = unlocked_balance return balance, unlocked_balance
def _parse_tweet(self, msg): if msg.user.screen_name.lower() == self.login.lower( ) and not force_parse_self: log_log('Ignoring tweet from self') return log_info('Twitter: parsing tweet from %s: %s' % (msg.user.screen_name, msg.text)) # twitter special: +x means tip the user mentioned with a @ for line in msg.text.split('\n'): line = line.lower() line = line.replace(self.keyword, '', 1).strip() log_log('After removal: %s' % line) if re.match(username_regexp + "[ \t]*" + amount_regexp, line) or re.match( amount_regexp + "[ \t]*" + username_regexp, line): link = Link(self, User(self, msg.user.screen_name), None, msg) match = re.search(username_regexp, line) if not match: continue target = match.group(0) match = re.search(amount_regexp, line.replace(target, '').strip()) if not match: continue amount = match.group(0) if self.on_command: try: synthetic_cmd = [ 'tip', target.replace('@', '').strip(), amount.replace('+', '').strip() ] log_log('Running synthetic command: %s' % (str(synthetic_cmd))) self.on_command(link, synthetic_cmd) except Exception, e: log_error('Failed to tip %s: %s' % (target, str(e)))
log_warning('Failed to mark %s as read: %s' % (item.id,str(e))) return author=self.canonicalize(item.author.name) if author==self.canonicalize(self.login): return if item.id in self.last_seen_ids: #log_log('Already seen %s %.1f hours ago by %s: %s (%s), skipping' % (item.id,age/3600,str(author),repr(title),repr(item.body))) return age=time.time()-item.created_utc ts=long(float(item.created_utc)) title=item.link_title if hasattr(item,'link_title') else None log_log('Parsing new item %s from %.1f hours ago by %s: %s (%s)' % (item.id,age/3600,str(author),repr(title),repr(item.body))) self.last_seen_ids.add(item.id) redis_sadd('reddit:last_seen_ids',item.id) if is_pm or item.body.lower().find(self.keyword.lower()) >= 0: group=None #if not is_pm and hasattr(item,'subreddit'): # group=Group(self,item.subreddit.display_name) group = None self.items_cache[item.fullname]=item link=Link(self,User(self,author),group,item) for line in item.body.split('\n'): if is_pm: exidx=line.find('!') if exidx!=-1 and len(line)>exidx+1 and line[exidx+1] in string.ascii_letters and self.is_acceptable_command_prefix(line[:exidx]): cmd=line[exidx+1:].split(' ')
log_warn('author of %s has no name field, ignored' % str(item.id)) if True: try: item.mark_read() except Exception, e: log_warn('Failed to mark %s as read: %s' % (item.id, str(e))) return author = self.canonicalize(item.author.name) if author and author == self.canonicalize(self.login): return if item.id in self.last_seen_ids: log_log('Already seen %s %.1f hours ago by %s: %s (%s), skipping' % (item.id, age / 3600, str(author), repr(title), repr(item.body))) try: item.mark_read() except Exception, e: log_warn('Failed to mark %s as read: %s' % (item.id, str(e))) return age = time.time() - item.created_utc ts = long(float(item.created_utc)) title = item.link_title if hasattr(item, 'link_title') else None log_log( 'Parsing new item %s from %.1f hours ago by %s: %s (%s)' % (item.id, age / 3600, str(author), repr(title), repr(item.body))) self.last_seen_ids.add(item.id)
def DealerMove(link): identity=link.identity() log_log('dealer move - finished: %d' % players[identity]['finished']) if AreAllHandsFinished(link): log_log('all hands finished, marking game as finished') players[identity]['finished'] = True if not players[identity]['finished']: if not IsBlackjack(players[identity]['dealer_hand']): while ShouldDealerHit(link): card = DrawForDealer(link) dealer_hand = players[identity]['dealer_hand'] bustmsg = "" if GetHandScore(dealer_hand) > 21: bustmsg = " - Dealer busts!" link.send("%s: Dealer draws %s: %s%s" % (link.user.nick, GetCardName(card,identity in utf8users), HandToString(dealer_hand,identity in utf8users,False,True), bustmsg)) players[identity]['finished'] = True players[identity]['player_current_hand'] = 0 log_log('sweeping through open games') while players[identity]['player_current_hand'] < len(players[identity]['player_hands']): log_log('sweeping through hand %d' % players[identity]['player_current_hand']) if players[identity]['player_hands'][players[identity]['player_current_hand']]['finished']: log_log('%d is already finished, skipping' % players[identity]['player_current_hand']) players[identity]['player_current_hand'] = players[identity]['player_current_hand'] + 1 continue CheckEndGame(link,True) log_log('done sweeping through open games') sidebets = players[identity]['sidebets'] dealer_hand = players[identity]['dealer_hand'] if sidebets['splits']: bet_units = sidebets['splits'] nsplits = len(players[identity]['player_hands']) if nsplits == 1: link.send('%s did not split - you lose %s' % (link.user.nick, AmountToString(bet_units))) UpdateSidebetRecord(link,"splits",False,True,bet_units) if sidebets['buster']: bet_units = sidebets['buster'] if GetHandScore(dealer_hand) > 21: cards = len(dealer_hand) if cards == 3: win_units = bet_units * 3 / 2 elif cards == 4: win_units = bet_units * 3 elif cards == 5: win_units = bet_units * 5 elif cards == 6: win_units = bet_units * 11 elif cards >= 7: win_units = bet_units * 21 link.send('The dealer busted with %s cards - you win %s' % (cards, AmountToString(win_units))) UpdateSidebetRecord(link,"buster",True,False,win_units) else: link.send('The dealer did not bust - you lose %s' % (AmountToString(bet_units))) UpdateSidebetRecord(link,"buster",False,True,bet_units) del players[identity]
like.send_private(' !link_account reddit:myredditname') link.send_private('Linking accounts is irreversible, so make sure you only link to accounts') link.send_private('under your control') def ScanWho(link,cmd): link.network.update_users_list(link.group.name if link.group else None) def GetHeight(link,cmd): log_info('GetHeight: %s wants to know block height' % str(link)) try: j = SendDaemonHTMLCommand("getheight") except Exception,e: log_error('GetHeight: error: %s' % str(e)) link.send("An error has occured") return log_log('GetHeight: Got reply: %s' % str(j)) if not "height" in j: log_error('GetHeight: Cannot see height in here') link.send("Height not found") return height=j["height"] log_info('GetHeight: height is %s' % str(height)) link.send("Height: %s" % str(height)) def GetTipbotBalance(link,cmd): log_info('%s wants to know the tipbot balance' % str(link)) try: balance, unlocked_balance = RetrieveTipbotBalance() except Exception,e: link.send("An error has occured") return
link.send_private('under your control') def ScanWho(link, cmd): link.network.update_users_list(link.group.name if link.group else None) def GetHeight(link, cmd): log_info('GetHeight: %s wants to know block height' % str(link)) try: j = SendDaemonHTMLCommand("getheight") except Exception, e: log_error('GetHeight: error: %s' % str(e)) link.send("An error has occured") return log_log('GetHeight: Got reply: %s' % str(j)) if not "height" in j: log_error('GetHeight: Cannot see height in here') link.send("Height not found") return height = j["height"] log_info('GetHeight: height is %s' % str(height)) link.send("Height: %s" % str(height)) def GetTipbotBalance(link, cmd): log_info('%s wants to know the tipbot balance' % str(link)) try: balance, unlocked_balance = RetrieveTipbotBalance() except Exception, e: link.send("An error has occured")
cp = redis_pipeline() cp.delete('confirming_payments') if "payments" in result: payments = result["payments"] new_payments = [] n_confirming = 0 new_scan_block_height = scan_block_height for p in payments: payment_id = p["payment_id"] tx_hash = p["tx_hash"] bh = p["block_height"] ut = p["unlock_time"] amount = p["amount"] if redis_sismember("processed_txs", tx_hash): continue log_log('UpdateCoin: Looking at payment %s' % str(p)) confirmations = height - 1 - bh confirmations_needed = max(config.payment_confirmations, ut) if confirmations >= confirmations_needed: log_info('Payment %s is now confirmed' % str(p)) new_payments.append(p) if new_scan_block_height and bh > new_scan_block_height: new_scan_block_height = bh else: log_info('Payment %s has %d/%d confirmations' % (str(p), confirmations, confirmations_needed)) n_confirming += 1 new_scan_block_height = None try: recipient = GetIdentityFromPaymentID(payment_id)
raise def SendJSONRPCCommand(host,port,method,params): try: http = httplib.HTTPConnection(host,port,timeout=20) except Exception,e: log_error('SendJSONRPCCommand: Error connecting to %s:%u: %s' % (host, port, str(e))) raise d = dict(id="0",jsonrpc="2.0",method=method,params=params) try: j = json.dumps(d).encode() except Exception,e: log_error('SendJSONRPCCommand: Failed to encode JSON: %s' % str(e)) http.close() raise log_log('SendJSONRPCCommand: Sending json as body: %s' % j) headers = None try: http.request("POST","/json_rpc",body=j) except Exception,e: log_error('SendJSONRPCCommand: Failed to post request: %s' % str(e)) http.close() raise response = http.getresponse() if response.status != 200: log_error('SendJSONRPCCommand: Error, received reply status %s' % str(response.status)) http.close() raise RuntimeError("Error "+response.status) s = response.read() log_log('SendJSONRPCCommand: Received reply status %s: %s' % (response.status, str(s).replace('\r\n',' ').replace('\n',' '))) try:
if ret: return ret elif action == '903': log_info('SASL authentication success') self._irc_sendmsg('CAP END') elif action in ['902', '904', '905', '906']: log_error('SASL authentication failed (%s)' % action) elif action == '352': try: who_chan = parts[3] who_chan_user = parts[7].lower() if not who_chan_user in self.userstable[who_chan]: self.userstable[who_chan][who_chan_user] = None log_log("New list of users in %s: %s" % (who_chan, str(self.userstable[who_chan].keys()))) except Exception,e: log_error('Failed to parse "352" line: %s: %s' % (data, str(e))) elif action == '353': try: who_chan = parts[4] who_chan_users = cparts[1].split(" ") log_info('who_chan: %s' % str(who_chan)) log_info('who_chan_users: %s' % str(who_chan_users)) for who_chan_user in who_chan_users: who_chan_user=who_chan_user.lower() if not who_chan_user in self.userstable[who_chan]: if who_chan_user[0] in ["@","+"]: who_chan_user = who_chan_user[1:] self.userstable[who_chan][who_chan_user] = None
try: who=cmd[1] units=StringToUnits(cmd[2]) except Exception,e: link.send("Usage: tip nick amount") return if units <= 0: link.send("Invalid amount") return whoid = IdentityFromString(link,who) log_info("Tip: %s wants to tip %s %s" % (identity, whoid, AmountToString(units))) if link.group: userlist=[user.identity() for user in link.network.get_users(link.group.name)] log_log('users: %s' % str(userlist)) if not whoid in userlist: link.send("%s is not in %s: if you really intend to tip %s, type !confirmtip before tipping again" % (who, link.group.name, who)) pending_confirmations[identity]={'who': whoid, 'units': units} return pending_confirmations.pop(identity,None) PerformTip(link,whoid,units) def ConfirmTip(link,cmd): identity=link.identity() if not identity in pending_confirmations: link.send("%s has no tip waiting confirmation" % NickFromIdentity(identity)) return whoid=pending_confirmations[identity]['who'] units=pending_confirmations[identity]['units'] pending_confirmations.pop(identity,None)
def Roll(link): identity = link.identity() try: if redis_hexists('kitsune:rolls', identity): rolls = redis_hget('kitsune:rolls', identity) rolls = long(rolls) + 1 else: rolls = 1 except Exception, e: log_error('Failed to prepare roll for %s: %s' % (identity, str(e))) raise try: log_log('0') s = GetServerSeed(link, 'kitsune') + ":" + GetPlayerSeed( link, 'kitsune') + ":" + str(rolls) log_log('1') sh = hashlib.sha256(s).hexdigest() log_log('2') triplet = [ long(sh[0:3], base=16) % 6 + 1, long(sh[3:6], base=16) % 6 + 1, long(sh[6:9], base=16) % 6 + 1 ] log_log('3') return rolls, triplet except Exception, e: log_error('Failed to roll for %s: %s' % (identity, str(e))) raise
if target == aim: log_info("Pinata: %s hits the pinata containing %s" % (identity, AmountToString(pinata_units))) winner_ratio = config.pinata_winner_base_share * aim / min_target rain_ratio = (1 - winner_ratio) * config.pinata_rain_remainder_share carry_ratio = (1 - winner_ratio) * config.pinata_carry_remainder_share winner_units = long(pinata_units * winner_ratio) rain_units = long(pinata_units * rain_ratio) carry_units = long(pinata_units * carry_ratio) profit_units = pinata_units - winner_units - rain_units log_log("Pinata: %s to winner, %s to rain, %s carry" % (AmountToString(winner_units), AmountToString(rain_units), AmountToString(carry_units))) p = redis_pipeline() p.hincrby('earmarked', 'pinata', -pinata_units) p.hincrby('balances', account, winner_units) link.send('%s swings at the pinata with %s and hits!' % (link.user.nick, AmountToString(units))) link.send('%s gets splashed by %s' % (link.user.nick, AmountToString(winner_units))) userlist = link.network.get_users(group.name) log_log("users in %s: %s" % (group.name, str([user.identity() for user in userlist]))) userlist.remove(link) for n in config.no_rain_to_nicks:
if ret: return ret elif action == '903': log_info('SASL authentication success') self._irc_sendmsg('CAP END') elif action in ['902', '904', '905', '906']: log_error('SASL authentication failed (%s)' % action) elif action == '352': try: who_chan = parts[3] who_chan_user = parts[7].lower() if not who_chan_user in self.userstable[who_chan]: self.userstable[who_chan][who_chan_user] = None log_log("New list of users in %s: %s" % (who_chan, str(self.userstable[who_chan].keys()))) except Exception, e: log_error('Failed to parse "352" line: %s: %s' % (data, str(e))) elif action == '353': try: who_chan = parts[4] who_chan_users = cparts[1].split(" ") log_info('who_chan: %s' % str(who_chan)) log_info('who_chan_users: %s' % str(who_chan_users)) for who_chan_user in who_chan_users: who_chan_user = who_chan_user.lower() if not who_chan_user in self.userstable[who_chan]: if who_chan_user[0] in ["@", "+"]: who_chan_user = who_chan_user[1:]
return try: rolls, roll = Roll(link) except: link.send("An error occured") return target = (1 - config.dice_edge) / multiplier if not under: target = 1 - target log_info("Dice: %s's #%d roll: %.16g, target %s %.16g" % (identity, rolls, roll, "under" if under else "over", target)) lose_units = units win_units = long(units * multiplier) - lose_units log_log('units %s, multiplier %f, edge %f, lose_units %s, win_units %s' % (AmountToString(units), multiplier, config.dice_edge, AmountToString(lose_units), AmountToString(win_units))) if under: win = roll <= target else: win = roll >= target if win: msg = "%s bets %s and wins %s on roll #%d! %.16g %s %.16g" % (link.user.nick, AmountToString(lose_units), AmountToString(win_units+lose_units), rolls, roll, "<=" if under else ">=", target) else: msg = "%s bets %s and loses on roll #%d. %.16g %s %.16g" % (link.user.nick, AmountToString(lose_units), rolls, roll, ">" if under else "<", target) try: RecordGameResult(link,"dice",win,not win,win_units if win else lose_units) except: return redis_hset("dice:rolls",identity,rolls)
from tipbot.betutils import * def Roll(link): identity=link.identity() try: if redis_hexists('kitsune:rolls',identity): rolls = redis_hget('kitsune:rolls',identity) rolls = long(rolls) + 1 else: rolls = 1 except Exception,e: log_error('Failed to prepare roll for %s: %s' % (identity, str(e))) raise try: log_log('0') s = GetServerSeed(link,'kitsune') + ":" + GetPlayerSeed(link,'kitsune') + ":" + str(rolls) log_log('1') sh = hashlib.sha256(s).hexdigest() log_log('2') triplet = [ long(sh[0:3],base=16)%6+1, long(sh[3:6],base=16)%6+1, long(sh[6:9],base=16)%6+1 ] log_log('3') return rolls, triplet except Exception,e: log_error('Failed to roll for %s: %s' % (identity,str(e))) raise def Kitsune(link,cmd): identity=link.identity() try: amount=float(cmd[1])
link.send("%s: %s" % (link.user.nick, reason)) return try: if target==aim: log_info("Pinata: %s hits the pinata containing %s" % (identity, AmountToString(pinata_units))) winner_ratio = config.pinata_winner_base_share * aim / min_target rain_ratio = (1-winner_ratio) * config.pinata_rain_remainder_share carry_ratio = (1-winner_ratio) * config.pinata_carry_remainder_share winner_units = long(pinata_units * winner_ratio) rain_units = long(pinata_units * rain_ratio) carry_units = long(pinata_units * carry_ratio) profit_units = pinata_units - winner_units - rain_units log_log("Pinata: %s to winner, %s to rain, %s carry" % (AmountToString(winner_units),AmountToString(rain_units),AmountToString(carry_units))) p=redis_pipeline() p.hincrby('earmarked','pinata',-pinata_units) p.hincrby('balances',account,winner_units) link.send('%s swings at the pinata with %s and hits!' % (link.user.nick,AmountToString(units))) link.send('%s gets splashed by %s' % (link.user.nick,AmountToString(winner_units))) userlist=link.network.get_users(group.name) log_log("users in %s: %s" % (group.name,str([user.identity() for user in userlist]))) userlist.remove(link) for n in config.no_rain_to_nicks: i=IdentityFromString(link,n) l=Link(link.network,User(link.network,NickFromIdentity(i)),group) if l in userlist: userlist.remove(l)
def SendJSONRPCCommand(host, port, method, params): try: http = httplib.HTTPConnection(host, port, timeout=config.rpc_timeout) except Exception, e: log_error('SendJSONRPCCommand: Error connecting to %s:%u: %s' % (host, port, str(e))) raise d = dict(id="0", jsonrpc="2.0", method=method, params=params) try: j = json.dumps(d).encode() except Exception, e: log_error('SendJSONRPCCommand: Failed to encode JSON: %s' % str(e)) http.close() raise log_log('SendJSONRPCCommand: Sending json as body: %s' % j) headers = None try: http.request("POST", "/json_rpc", body=j) except Exception, e: log_error('SendJSONRPCCommand: Failed to post request: %s' % str(e)) http.close() raise response = http.getresponse() if response.status != 200: log_error('SendJSONRPCCommand: Error, received reply status %s' % str(response.status)) http.close() raise RuntimeError("Error " + response.status) s = response.read() log_log('SendJSONRPCCommand: Received reply status %s: %s' %
except Exception, e: link.send("Usage: tip nick amount") return if units <= 0: link.send("Invalid amount") return whoid = IdentityFromString(link, who) log_info("Tip: %s wants to tip %s %s" % (identity, whoid, AmountToString(units))) if link.group: userlist = [ user.identity() for user in link.network.get_users(link.group.name) ] log_log('users: %s' % str(userlist)) if not whoid in userlist: link.send( "%s is not in %s: if you really intend to tip %s, type !confirmtip before tipping again" % (who, link.group.name, who)) pending_confirmations[identity] = {'who': whoid, 'units': units} return pending_confirmations.pop(identity, None) PerformTip(link, whoid, units) def ConfirmTip(link, cmd): identity = link.identity() if not identity in pending_confirmations: link.send("%s has no tip waiting confirmation" % NickFromIdentity(identity))
cp = redis_pipeline() cp.delete('confirming_payments') if "payments" in result: payments = result["payments"] new_payments = [] n_confirming = 0 new_scan_block_height = scan_block_height for p in payments: payment_id=p["payment_id"] tx_hash = p["tx_hash"] bh = p["block_height"] ut = p["unlock_time"] amount=p["amount"] if redis_sismember("processed_txs",tx_hash): continue log_log('UpdateCoin: Looking at payment %s' % str(p)) confirmations = height-1-bh confirmations_needed = max(config.payment_confirmations,ut) if confirmations >= confirmations_needed: log_info('Payment %s is now confirmed' % str(p)) new_payments.append(p) if new_scan_block_height and bh > new_scan_block_height: new_scan_block_height = bh else: log_info('Payment %s has %d/%d confirmations' % (str(p),confirmations,confirmations_needed)) n_confirming += 1 new_scan_block_height = None try: recipient = GetIdentityFromPaymentID(payment_id) if not recipient: raise RuntimeError('Payment ID %s not found' % payment_id)