def filter_messages(bot: DeltaBot, message: Message, replies: Replies) -> None: """Detect messages like +1 or -1 to increase/decrease score. """ if not message.quote: return score = _parse(message.text) if not score: return sender = message.get_sender_contact().addr is_admin = bot.is_admin(sender) if score < 0 and not is_admin: return if not is_admin and db.get_score(sender) - score < 0: replies.add(text="❌ You can't give what you don't have...", quote=message) return receiver = message.quote.get_sender_contact().addr if sender == receiver: return sender_score = _add_score(sender, -score) receiver_score = _add_score(receiver, score) if is_admin: text = '{0}: {1}{4}' else: text = '{0}: {1}{4}\n{2}: {3}{4}' text = text.format( bot.get_contact(receiver).name, receiver_score, bot.get_contact(sender).name, sender_score, _getdefault(bot, 'score_badge')) replies.add(text=text, quote=message)
def _run_turn(gid: int, db: DBManager, bot: DeltaBot) -> str: game = db.get_game_by_gid(gid) if not game: return 'This is not your game group' if not game['board']: return 'There is no game running' board = Board(game['board']) b_orb = board.get_orb(Atom.BLACK) w_orb = board.get_orb(Atom.WHITE) result = board.result() pboard = '{}\n\n{} {} – {} {}'.format(board, b_orb, result[Atom.BLACK], result[Atom.WHITE], w_orb) if 0 in result.values() and not board.fist_round: db.set_board(game['p1'], game['p2'], None) if result[Atom.WHITE] == 0: winner = '{} {}'.format(board.get_orb(Atom.BLACK), bot.get_contact(game['black']).name) else: player2 = game['p2'] if game['black'] == game['p1'] else game['p1'] winner = '{} {}'.format(board.get_orb(Atom.WHITE), bot.get_contact(player2).name) text = '🏆 Game over.\n{} Wins!!!\n\n{}'.format(winner, pboard) text += '\n\n▶️ Play again? /chr_new' else: if board.turn == Atom.BLACK: turn = bot.get_contact(game['black']).name else: turn = bot.get_contact(game['p2'] if game['black'] == game['p1'] else game['p1']).name text = "{} {} it's your turn...\n\n{}".format( board.get_orb(board.turn), turn, pboard) return text
def filter_messages(bot: DeltaBot, message: Message, replies: Replies) -> None: """Detect messages like +1 or -1 to increase/decrease score.""" if message.quote: receiver_addr = message.quote.get_sender_contact().addr score = _parse(message.text) else: args = message.text.split(maxsplit=2) if len(args) == 2 and "@" in args[0]: receiver_addr = args[0] score = _parse(args[1]) else: score = 0 if not score: return sender_addr = message.get_sender_contact().addr is_admin = bot.is_admin(sender_addr) if (score < 0 and not is_admin) or sender_addr == receiver_addr: return with session_scope() as session: sender = session.query(User).filter_by(addr=sender_addr).first() if not sender: sender = User(addr=sender_addr) session.add(sender) if not is_admin and sender.score - score < 0: replies.add(text="❌ You can't give what you don't have...", quote=message) return if not is_admin: sender.score -= score sender_score = sender.score receiver = session.query(User).filter_by(addr=receiver_addr).first() if not receiver: receiver = User(addr=receiver_addr) session.add(receiver) receiver.score += score receiver_score = receiver.score if is_admin: text = "{0}: {1}{4}" else: text = "{0}: {1}{4}\n{2}: {3}{4}" text = text.format( bot.get_contact(receiver_addr).name, receiver_score, bot.get_contact(sender_addr).name, sender_score, _getdefault(bot, "score_badge"), ) replies.add(text=text, quote=message)
def friends_profile(bot: DeltaBot, payload: str, message: Message, replies: Replies) -> None: """See the biography of the given address or your own in no address provided. """ if payload.isnumeric(): contact = bot.get_contact(int(payload)) elif '@' not in payload: contact = message.get_sender_contact() else: contact = bot.get_contact(payload) bio = db.get_bio(contact.addr) if bio is None: replies.add(text='No biography found for {}'.format(contact.addr)) else: replies.add(filename=contact.get_profile_image(), text='{}:\n{}'.format(contact.addr, bio))
def poll_end(bot: DeltaBot, args: str, message: Message, replies: Replies) -> None: """Close the poll with the given id.""" if args: addr = message.get_sender_contact().addr try: with session_scope() as session: poll = session.query(Poll).filter_by(id=int(args[0]), addr=addr).one() text, html = _format_poll(bot, poll, closed=True) addresses = set(vote.addr for vote in poll.votes) session.delete(poll) addresses.add(addr) for addr in addresses: contact = bot.get_contact(addr) if not contact.is_blocked(): replies.add(text=text, html=html, chat=bot.get_chat(contact)) except NoResultFound: replies.add(text="❌ Invalid poll", quote=message, chat=message.get_sender_chat()) else: replies.add(text="❌ Invalid poll", quote=message, chat=message.get_sender_chat())
def _show_status(bot: DeltaBot, gid: int, turn: str = None) -> str: contacts = db.get_players(gid) text = ec + '👤 Players({}):\n'.format(len(contacts)) if turn: fstr = '• {} ({})\n' else: fstr = '• {0}\n' for c in contacts: text += fstr.format(bot.get_contact(c['addr']).name, c['round']) text += '\n' if turn: text += "Turn: {}".format(bot.get_contact(turn).name) else: text += 'Waiting for players...\n\n/corpse_join /corpse_start' return text
def reversi_new(bot: DeltaBot, message: Message, replies: Replies) -> None: """Start a new Reversi game in the current game group. """ sender = message.get_sender_contact().addr game = db.get_game_by_gid(message.chat.id) # this is not your game group if game is None or sender not in (game['p1'], game['p2']): replies.add(text='This is not your game group') elif game['board'] is None: b = Board() db.set_game(game['p1'], game['p2'], b.export(), sender) p2 = game['p2'] if sender == game['p1'] else game['p1'] text = 'Game started!\n{}: {}\n{}: {}\n\n'.format( b.get_disk(BLACK), bot.get_contact(sender).name, b.get_disk(WHITE), bot.get_contact(p2).name) replies.add(text=text + _run_turn(bot, message.chat.id)) else: replies.add(text='There is a game running already')
def _run_turn(bot: DeltaBot, gid: int) -> str: g = db.get_game_by_gid(gid) if not g: return 'This is not your game group' if not g['board']: return 'There is no game running' b = Board(g['board']) result = b.result() if result['status'] in (0, 1): if result['status'] == 1: b.turn = BLACK if b.turn == WHITE else WHITE db.set_board(g['p1'], g['p2'], b.export()) if b.turn == BLACK: disk = b.get_disk(BLACK) turn = '{} {}'.format(disk, g['black']) else: disk = b.get_disk(WHITE) p2 = g['p2'] if g['black'] == g['p1'] else g['p1'] turn = '{} {}'.format(disk, p2) text = "{} it's your turn...\n\n{}\n\n{}".format( bot.get_contact(turn).name, b, b.get_score()) else: db.set_board(g['p1'], g['p2'], None) black, white = result[BLACK], result[WHITE] if black == white: text = '🤝 Game over.\nIt is a draw!\n\n' else: if black > white: disk = b.get_disk(BLACK) winner = '{} {}'.format(disk, g['black']) else: disk = b.get_disk(WHITE) p2 = g['p2'] if g['black'] == g['p1'] else g['p1'] winner = '{} {}'.format(disk, p2) text = '🏆 Game over.\n{} Wins!\n\n'.format( bot.get_contact(winner).name) text += '\n\n'.join(( str(b), b.get_score(), '▶️ Play again? /reversi_new')) return text
def scoreSet(bot: DeltaBot, args: list, message: Message, replies: Replies) -> None: """Set score for given address. Example: `/score [email protected] +100` """ score = _parse(args[1]) if not score: replies.add(text='❌ Invalid number, use + or -', quote=message) else: score = _add_score(args[0], score) name = bot.get_contact(args[0]).name text = '{}: {}{}'.format(name, score, _getdefault(bot, 'score_badge')) replies.add(text=text, quote=message)
def friends_list(bot: DeltaBot, replies: Replies) -> None: """Get the list of users and their biography. """ users = [] for row in db.get_users(): contact = bot.get_contact(row['addr']) users.append('{}:\n{}... /friends_profile_{}'.format( row['addr'], row['bio'][:100], contact.id)) if users: while users: replies.add(text='\n\n―――――――――――――――\n\n'.join(users[:50])) users = users[50:] else: replies.add(text='Empty List')
def score(bot: DeltaBot, payload: str, message: Message, replies: Replies) -> None: """Get score from given address or your current score if no address is given. Example: `/score` """ if payload: addr = payload else: addr = message.get_sender_contact().addr name = bot.get_contact(addr).name badge = _getdefault(bot, 'score_badge') replies.add(text='{0}: {1}/{2}{3}'.format(name, db.get_score(addr), db.get_score(), badge))
def _run_turn(bot: DeltaBot, player: sqlite3.Row, group: Chat, paragraph: str) -> None: contact = bot.get_contact(player['addr']) text = ec + "⏳ Round {}/3\n\n{}, it's your turn...".format( player['round'], contact.name) group.send_text(text) if paragraph: text = ec + '📝 Complete the phrase:\n...{}\n\n'.format(' '.join( paragraph.rsplit(maxsplit=5)[-5:])) else: text = '📝 You are the first!\nSend a message with at least 10 words.' text = ec + text bot.get_chat(contact).send_text(text)
def score(bot: DeltaBot, payload: str, message: Message, replies: Replies) -> None: """Get score of given address or your current score if no address is given. Example: `/score` """ if payload: addr = payload else: addr = message.get_sender_contact().addr with session_scope() as session: user = session.query(User).filter_by(addr=addr).first() score = user.score if user else 0 total_score = session.query(func.sum(User.score)).scalar() name = bot.get_contact(addr).name badge = _getdefault(bot, "score_badge") replies.add(text="{0}: {1}/{2}{3}".format(name, score, total_score, badge))
def chr_new(message: Message, bot: DeltaBot, replies: Replies) -> None: """Start a new Chain Reaction game in the current game group.""" sender = message.get_sender_contact() game = DBASE.get_game_by_gid(message.chat.id) if game is None or sender.addr not in (game['p1'], game['p2']): replies.add(text='This is not your game group') elif game['board'] is None: board = Board() DBASE.set_game(game['p1'], game['p2'], sender.addr, board.export()) player2 = bot.get_contact(game['p2'] if sender.addr == game['p1'] else game['p1']) text = '▶️ Game started!\n{}: {}\n{}: {}\n\n'.format( board.get_orb(Atom.BLACK), sender.name, board.get_orb(Atom.WHITE), player2.name) replies.add(text=text + _run_turn(message.chat.id, DBASE, bot)) else: replies.add(text='There is a game running already')
def group_remove(bot: DeltaBot, args: list, message: Message, replies: Replies) -> None: """Remove the member with the given address from the group with the given id. If no address is provided, removes yourself from group/channel. """ sender = message.get_sender_contact() if not args: replies.add(text='❌ Invalid ID') return type_, gid = args[0][0], int(args[0][1:]) if type_ == 'c': ch = db.get_channel_by_id(gid) if not ch: replies.add(text='❌ Invalid ID') return for g in _get_cchats(bot, ch['id'], include_admin=True): if sender in g.get_contacts(): g.remove_contact(sender) return replies.add(text='❌ You are not a member of that channel') elif type_ == 'g': gr = db.get_group(gid) if not gr: replies.add(text='❌ Invalid ID') return g = bot.get_chat(gr['id']) if sender not in g.get_contacts(): replies.add(text='❌ You are not a member of that group') return addr = args[-1] if '@' in args[-1] else '' if addr: if addr == bot.self_contact.addr: replies.add(text='❌ You can not remove me from the group') return contact = bot.get_contact(addr) g.remove_contact(contact) if not contact.is_blocked(): chat = bot.get_chat(contact) replies.add(text='❌ Removed from {} by {}'.format( g.get_name(), sender.addr), chat=chat) replies.add(text='✔️{} removed'.format(addr)) else: g.remove_contact(sender)
def scoreSet(bot: DeltaBot, args: list, message: Message, replies: Replies) -> None: """Set score for given address. Example: `/scoreSet [email protected] 100` """ score = _parse(args[1] if args[1].startswith(("+", "-")) else "+" + args[1]) if not score: replies.add(text="❌ Invalid number", quote=message) else: with session_scope() as session: user = session.query(User).filter_by(addr=args[0]).first() if not user: user = User(addr=args[0]) session.add(user) user.score += score score = user.score name = bot.get_contact(args[0]).name text = "{}: {}{}".format(name, score, _getdefault(bot, "score_badge")) replies.add(text=text, quote=message)
def poll_end(bot: DeltaBot, payload: str, message: Message, replies: Replies) -> None: """Close the poll with the given id. """ args = payload.split() if len(args) not in (1, 2): replies.add(text='Invalid syntax') return if len(args) == 2: chat = bot.get_chat(int(args[0])) payload = args[1] if message.get_sender_contact() not in chat.get_contacts(): replies.add(text='You are not a member of that group') return else: chat = message.chat pid = int(payload) poll = db.get_gpoll_by_id(pid) addr = message.get_sender_contact().addr if poll and chat.id == poll['gid']: db.end_gpoll(poll['id']) text = format_gpoll(poll, closed=True) text += '\n\n(Poll closed by {})'.format(addr) replies.add(text=text, chat=chat) db.remove_gpoll_by_id(pid) elif len(args) == 1: poll = db.get_poll_by_id(pid) if poll and addr == poll['addr']: db.end_poll(poll['id']) text = _format_poll(bot, poll, closed=True) for addr in db.get_poll_participants(poll['id']): contact = bot.get_contact(addr) if not contact.is_blocked(): replies.add(text=text, chat=bot.get_chat(contact)) db.remove_poll_by_id(poll['id']) else: replies.add(text='Invalid poll id') else: replies.add(text='Invalid poll id')
def chr_play(payload: str, message: Message, bot: DeltaBot, replies: Replies) -> None: """Invite a friend to play Chain Reaction. Example: `/chr_play [email protected]` """ if not payload: replies.add(text="Missing address") return if payload == bot.self_contact.addr: replies.add(text="Sorry, I don't want to play") return player1 = message.get_sender_contact() player2 = bot.get_contact(payload) if player1 == player2: replies.add(text="You can't play with yourself") return game = DBASE.get_game_by_players(player1.addr, player2.addr) if game is None: # first time playing with player2 board = Board() chat = bot.create_group( '🧬 {} 🆚 {} [ChainReaction]'.format(player1.addr, player2.addr), [player1, player2]) DBASE.add_game(player1.addr, player2.addr, chat.id, Board().export(), player1.addr) text = 'Hello {1},' \ 'You have been invited by {0} to play Chain Reaction' text += '\n\n{2}: {0}\n{3}: {1}\n\n' text = text.format(player1.name, player2.name, board.get_orb(Atom.BLACK), board.get_orb(Atom.WHITE)) replies.add(text=text + _run_turn(chat.id, DBASE, bot), chat=chat) else: text = 'You already have a game group with {}'.format(player2.name) replies.add(text=text, chat=bot.get_chat(game['gid']))