some refactoring, botan tracking, join command

This commit is contained in:
Jannes Höke 2016-03-09 11:31:38 +01:00
parent cebffecc35
commit 13946e63bc
2 changed files with 98 additions and 39 deletions

118
bot.py
View file

@ -1,24 +1,32 @@
import logging import logging
from datetime import datetime
from random import randint
from telegram import Updater, InlineQueryResultArticle, ParseMode from telegram import Updater, InlineQueryResultArticle, ParseMode, Message, Chat
from telegram.utils.botan import Botan
from game_manager import GameManager from game_manager import GameManager
import card as c import card as c
from credentials import TOKEN from credentials import TOKEN, BOTAN_TOKEN
from start_bot import start_bot from start_bot import start_bot
logging.basicConfig( logging.basicConfig(
format='%(asctime)s - %(name)s - %(levelname)s - %(message)s', format='%(asctime)s - %(name)s - %(levelname)s - %(message)s',
level=logging.INFO) level=logging.DEBUG)
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
gm = GameManager() gm = GameManager()
u = Updater(TOKEN) u = Updater(TOKEN)
dp = u.dispatcher dp = u.dispatcher
botan = False
if BOTAN_TOKEN:
botan = Botan(BOTAN_TOKEN)
help_text = "Follow these steps:\n\n" \ help_text = "Follow these steps:\n\n" \
"1. Add this bot to a group\n" \ "1. Add this bot to a group\n" \
"2. In the group, start a new game with /new\n" \ "2. In the group, start a new game with /new or join an already" \
" running game with /join\n" \
"3. The bot will send a link into the group. " \ "3. The bot will send a link into the group. " \
"Click the link and then on the <b>Start</b> " \ "Click the link and then on the <b>Start</b> " \
"button to join the game.\n" \ "button to join the game.\n" \
@ -31,7 +39,12 @@ help_text = "Follow these steps:\n\n" \
"at the moment) and an option to see the current game state.\n\n" \ "at the moment) and an option to see the current game state.\n\n" \
"Players can join the game at any time, though you currently " \ "Players can join the game at any time, though you currently " \
"can not play more than one game at a time. To leave a game, " \ "can not play more than one game at a time. To leave a game, " \
"send /leave into the group." "send /leave into the group.\n" \
"If you enjoy this bot, " \
"<a href=\"https://telegram.me/storebot?start=mau_mau_bot\">" \
"rate me</a>, join the " \
"<a href=\"https://telegram.me/unobotupdates\">update channel</a>" \
" and buy an UNO card game.\n"
def list_subtract(list1, list2): def list_subtract(list1, list2):
@ -73,10 +86,30 @@ def error(bot, update, error):
def new_game(bot, update): def new_game(bot, update):
""" Handler for the /new command """ """ Handler for the /new command """
chat_id = update.message.chat_id chat_id = update.message.chat_id
link = gm.generate_invite_link(u.bot.getMe().username, chat_id) if update.message.chat.type == 'private':
bot.sendMessage(chat_id, help(bot, update)
text="Click this link to join the game: %s" % link, else:
disable_web_page_preview=True) link = gm.generate_invite_link(u.bot.getMe().username, chat_id)
bot.sendMessage(chat_id,
text="Click this link and press the Start button to"
" join the game: %s" % link,
disable_web_page_preview=True)
if botan:
botan.track(update.message, 'New games')
def join_game(bot, update):
""" Handler for the /join command """
chat_id = update.message.chat_id
if update.message.chat.type == 'private':
help(bot, update)
else:
link = gm.generate_invite_link(u.bot.getMe().username, chat_id,
join=True)
bot.sendMessage(chat_id,
text="Click this link and press the Start button to"
" join the game: %s" % link,
disable_web_page_preview=True)
def leave_game(bot, update): def leave_game(bot, update):
@ -132,38 +165,44 @@ def help(bot, update):
""" Handler for the /help command """ """ Handler for the /help command """
bot.sendMessage(update.message.chat_id, bot.sendMessage(update.message.chat_id,
text=help_text, text=help_text,
parse_mode=ParseMode.HTML) parse_mode=ParseMode.HTML,
disable_web_page_preview=True)
def reply_to_query(bot, update): def reply_to_query(bot, update):
""" Builds the result list for inline queries and answers to the client """ """ Builds the result list for inline queries and answers to the client """
user_id = update.inline_query.from_user.id
player = gm.userid_player[user_id]
game = gm.userid_game[user_id]
results = list() results = list()
playable = list() playable = list()
if user_id == game.current_player.user.id: try:
if game.choosing_color: user_id = update.inline_query.from_user.id
add_choose_color(results) player = gm.userid_player[user_id]
else: game = gm.userid_game[user_id]
playable = list(sorted(player.playable_cards())) except KeyError:
add_no_game(results)
for card in playable: else:
add_play_card(card, results) if user_id == game.current_player.user.id:
if game.choosing_color:
if not player.drew: add_choose_color(results)
add_draw(player, results, could_play_card=bool(len(playable)))
else: else:
add_pass(results) playable = list(sorted(player.playable_cards()))
if game.last_card.special == c.DRAW_FOUR and game.draw_counter: for card in playable:
add_call_bluff(results) add_play_card(card, results)
add_other_cards(playable, player, results) if not player.drew:
add_draw(player, results,
could_play_card=bool(len(playable)))
add_gameinfo(game, results) else:
add_pass(results)
if game.last_card.special == c.DRAW_FOUR and game.draw_counter:
add_call_bluff(results)
add_other_cards(playable, player, results)
add_gameinfo(game, results)
bot.answerInlineQuery(update.inline_query.id, results, cache_time=0) bot.answerInlineQuery(update.inline_query.id, results, cache_time=0)
@ -195,6 +234,17 @@ def add_other_cards(playable, player, results):
) )
def add_no_game(results):
results.append(
InlineQueryResultArticle(
"nogame",
title="You are not playing",
message_text='Not playing right now. Use /new to start a game or '
'/join to join the current game in this group'
)
)
def add_draw(player, results, could_play_card): def add_draw(player, results, could_play_card):
results.append( results.append(
InlineQueryResultArticle( InlineQueryResultArticle(
@ -281,7 +331,7 @@ def process_result(bot, update):
chat_id = gm.chatid_gameid[game] chat_id = gm.chatid_gameid[game]
logger.debug("Selected result: " + result_id) logger.debug("Selected result: " + result_id)
if result_id in ('hand', 'gameinfo'): if result_id in ('hand', 'gameinfo', 'nogame'):
return return
elif result_id == 'call_bluff': elif result_id == 'call_bluff':
do_call_bluff(bot, chat_id, game, player) do_call_bluff(bot, chat_id, game, player)
@ -309,6 +359,11 @@ def do_play_card(bot, chat_id, game, player, result_id, user):
gm.leave_game(user) gm.leave_game(user)
bot.sendMessage(chat_id, text="Player won!") bot.sendMessage(chat_id, text="Player won!")
if botan:
botan.track(Message(randint(1, 1000000000), user, datetime.now(),
Chat(chat_id, 'group')),
'Played cards')
def do_draw(game, player): def do_draw(game, player):
draw_counter_before = game.draw_counter draw_counter_before = game.draw_counter
@ -345,6 +400,7 @@ def do_call_bluff(bot, chat_id, game, player):
dp.addTelegramInlineHandler(inline) dp.addTelegramInlineHandler(inline)
dp.addTelegramCommandHandler('start', start) dp.addTelegramCommandHandler('start', start)
dp.addTelegramCommandHandler('new', new_game) dp.addTelegramCommandHandler('new', new_game)
dp.addTelegramCommandHandler('join', join_game)
dp.addTelegramCommandHandler('leave', leave_game) dp.addTelegramCommandHandler('leave', leave_game)
dp.addTelegramCommandHandler('help', help) dp.addTelegramCommandHandler('help', help)
dp.addErrorHandler(error) dp.addErrorHandler(error)

View file

@ -17,19 +17,22 @@ class GameManager(object):
self.userid_player = dict() self.userid_player = dict()
self.logger = logging.getLogger(__name__) self.logger = logging.getLogger(__name__)
def generate_invite_link(self, bot_name, chat_id): def generate_invite_link(self, bot_name, chat_id, join=False):
""" """
Generate a game join link with a unique ID and connect the game to the Generate a game join link with a unique ID and connect the game to the
group chat group chat
""" """
game_id = str(uuid4()) if join and chat_id in self.chatid_gameid:
game = Game() game_id = self.chatid_gameid[chat_id]
else:
game_id = str(uuid4())
game = Game()
self.logger.info("Creating new game with id " + game_id) self.logger.info("Creating new game with id " + game_id)
self.gameid_game[game_id] = game self.gameid_game[game_id] = game
self.chatid_gameid[chat_id] = game_id self.chatid_gameid[chat_id] = game_id
self.chatid_gameid[game_id] = chat_id self.chatid_gameid[game_id] = chat_id
self.chatid_gameid[game] = chat_id self.chatid_gameid[game] = chat_id
return LINK_PATTERN % (bot_name, game_id) return LINK_PATTERN % (bot_name, game_id)