Skip to content

Commit c68d84b

Browse files
committed
Merge pull request #109 from d-Rickyy-b/dev
Fix game being stuck and add reset stat feature
2 parents b5d7ece + 2c534fe commit c68d84b

File tree

9 files changed

+103
-13
lines changed

9 files changed

+103
-13
lines changed

blackjack/game/blackjackgame.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
# -*- coding: utf-8 -*-
22
import logging
3-
3+
from datetime import datetime
44
from enum import Enum
5+
56
import blackjack.errors as errors
67
from blackjack.game import Player, Dealer, Deck
78

@@ -17,6 +18,7 @@ def __init__(self, gametype=None, game_id=None, lang_id="en"):
1718
self.list_won = []
1819
self.list_tie = []
1920
self.list_lost = []
21+
self.datetime_started = datetime.now()
2022
self.bets_active = True
2123
self._current_player = 0
2224
self.players = []

blackjackbot/__init__.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
stop_command_handler = CommandHandler("stop", game.stop_cmd)
1515
language_command_handler = CommandHandler("language", settings.language_cmd)
1616
stats_command_handler = CommandHandler("stats", util.stats_cmd)
17+
resetstats_command_handler = CommandHandler("resetstats", util.reset_stats_cmd)
1718
comment_command_handler = CommandHandler("comment", util.comment_cmd)
1819
comment_text_command_handler = MessageHandler(Filters.text & ~(Filters.forwarded | Filters.command), util.comment_text)
1920

@@ -33,12 +34,13 @@
3334
start_callback_handler = CallbackQueryHandler(game.start_callback, pattern=r"^start_[0-9]{7}$")
3435
newgame_callback_handler = CallbackQueryHandler(game.newgame_callback, pattern=r"^newgame$")
3536
language_callback_handler = CallbackQueryHandler(settings.language_callback, pattern=r"^lang_([a-z]{2}(?:-[a-z]{2})?)$")
37+
reset_stats_callback_handler = CallbackQueryHandler(util.reset_stats_callback, pattern=r"^reset_stats_(confirm|cancel)$")
3638

3739
handlers = [banned_user_handler,
3840
start_command_handler, stop_command_handler, join_callback_handler, hit_callback_handler,
3941
stand_callback_handler, start_callback_handler, language_command_handler, stats_command_handler,
4042
newgame_callback_handler, reload_lang_command_handler, language_callback_handler, users_command_handler,
4143
comment_command_handler, comment_text_command_handler, answer_command_handler, ban_command_handler,
42-
unban_command_handler, bans_command_handler]
44+
unban_command_handler, bans_command_handler, resetstats_command_handler, reset_stats_callback_handler]
4345

4446
__all__ = ['handlers', 'error_handler']

blackjackbot/commands/game/commands.py

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -168,12 +168,11 @@ def hit_callback(update, context):
168168
player_cards = get_cards_string(player, lang_id)
169169
if player.has_blackjack():
170170
text = (translator("your_cards_are") + "\n\n" + translator("got_blackjack")).format(user_mention, player.cardvalue, player_cards)
171-
update.effective_message.edit_text(text=text, parse_mode=ParseMode.HTML, reply_markup=None)
172-
next_player(update, context)
173-
elif player.cardvalue == 21:
171+
else:
174172
text = (translator("your_cards_are") + "\n\n" + translator("got_21")).format(user_mention, player.cardvalue, player_cards)
175-
update.effective_message.edit_text(text=text, parse_mode=ParseMode.HTML, reply_markup=None)
176-
next_player(update, context)
173+
174+
update.effective_message.edit_text(text=text, parse_mode=ParseMode.HTML, reply_markup=None)
175+
next_player(update, context)
177176

178177

179178
@needs_active_game
Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
# -*- coding: utf-8 -*-
22
from .functions import remove_inline_keyboard, get_start_keyboard, generate_evaluation_string, html_mention, get_game_keyboard, get_join_keyboard
33
from .decorators import admin_method, needs_active_game
4-
from .commands import stats_cmd, comment_cmd, comment_text
4+
from .commands import stats_cmd, comment_cmd, comment_text, reset_stats_cmd, reset_stats_callback
55

66
__all__ = ['remove_inline_keyboard', 'get_start_keyboard', 'generate_evaluation_string', 'html_mention', 'get_game_keyboard', 'get_join_keyboard',
7-
'stats_cmd', 'comment_cmd', 'comment_text', 'admin_method', 'needs_active_game']
7+
'stats_cmd', 'comment_cmd', 'comment_text', 'admin_method', 'needs_active_game', 'reset_stats_cmd', 'reset_stats_callback']

blackjackbot/commands/util/commands.py

Lines changed: 53 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# -*- coding: utf-8 -*-
22

3-
from telegram import ForceReply, ParseMode
3+
from telegram import ForceReply, ParseMode, InlineKeyboardButton, InlineKeyboardMarkup
44

55
from blackjackbot.commands.admin.functions import notify_admins
66
from blackjackbot.lang import translate
@@ -13,6 +13,58 @@ def stats_cmd(update, context):
1313
update.message.reply_text(get_user_stats(update.effective_user.id), parse_mode=ParseMode.HTML)
1414

1515

16+
def reset_stats_cmd(update, context):
17+
"""Asks the user if they want to reset their statistics"""
18+
user_id = update.effective_user.id
19+
chat_id = update.effective_chat.id
20+
21+
_modify_old_reset_message(context)
22+
23+
db = Database()
24+
lang_id = db.get_lang_id(user_id)
25+
26+
keyboard = [[
27+
InlineKeyboardButton(translate("reset_stats_confirm_button"), callback_data='reset_stats_confirm'),
28+
InlineKeyboardButton(translate("reset_stats_cancel_button"), callback_data='reset_stats_cancel'),
29+
]]
30+
reply_markup = InlineKeyboardMarkup(keyboard)
31+
32+
sent_message = update.message.reply_text(translate("reset_stats_confirm", lang_id), reply_markup=reply_markup)
33+
reset_message = {"message_id": sent_message.message_id, "chat_id": chat_id}
34+
context.user_data["reset_messages"] = reset_message
35+
36+
37+
def _modify_old_reset_message(context):
38+
"""Removes the last saved reset confirmation messages from the chat history"""
39+
reset_message = context.user_data.get("reset_message", None)
40+
if reset_message is None:
41+
return
42+
43+
try:
44+
context.bot.edit_message_reply_markup(chat_id=reset_message.get("chat_id"), message_id=reset_message.get("message_id"))
45+
except:
46+
pass
47+
48+
context.user_data["reset_messages"] = None
49+
50+
51+
def reset_stats_callback(update, context):
52+
"""Handler for confirmation of statistics reset"""
53+
query = update.callback_query
54+
query.answer()
55+
56+
user_id = update.effective_user.id
57+
db = Database()
58+
lang_id = db.get_lang_id(user_id)
59+
60+
if query.data == "reset_stats_confirm":
61+
db.reset_stats(user_id=user_id)
62+
query.edit_message_text(translate("reset_stats_executed", lang_id))
63+
64+
elif query.data == "reset_stats_cancel":
65+
query.edit_message_text(translate("reset_stats_cancelled", lang_id))
66+
67+
1668
def comment_cmd(update, context):
1769
"""MessageHandler callback for the /comment command"""
1870
if context.user_data.get("state", UserState.IDLE) != UserState.IDLE:

blackjackbot/gamestore.py

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
# -*- coding: utf-8 -*-
22
import logging
3+
from datetime import datetime, timedelta
34
from random import randint
45

56
from .errors.noactivegameexception import NoActiveGameException
@@ -82,3 +83,20 @@ def _game_stopped_callback(self, game):
8283
self.remove_game(self._game_dict[game.id])
8384

8485
self.logger.debug("Current games: {}".format(len(self._chat_dict)))
86+
87+
def cleanup_stale_games(self):
88+
stale_timeout_min = 10
89+
now = datetime.now()
90+
remove_chat_ids = []
91+
92+
for game_id, chat_id in self._game_dict.items():
93+
game = self.get_game(chat_id)
94+
95+
game_older_than_10_mins = game.datetime_started < (now - timedelta(minutes=stale_timeout_min))
96+
if game_older_than_10_mins:
97+
logging.info("Killing game with id {} because it's stale for > {} mins".format(game.id, stale_timeout_min))
98+
# TODO notify chat
99+
remove_chat_ids.append(chat_id)
100+
101+
for chat_id in remove_chat_ids:
102+
self.remove_game(chat_id)

blackjackbot/lang/strings/translations_en.json

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,5 +47,11 @@
4747
"admin_reply": "⚠ You need to reply to the user's comment!",
4848
"reply_from_maintainer": "The maintainer of this bot sent you a reply:\n\n{}",
4949
"statistic_template": "Here are your statistics 📊:\n\n<b>Played Games:</b> {}\n<b>Won Games:</b> {}\n<b>Last Played:</b> {} UTC\n\n{}\n\n<b>Winning rate:</b> {:.2%}",
50-
"dealer_name": "Dealer"
50+
"dealer_name": "Dealer",
51+
"reset_stats_confirm": "Do you really want to reset your statistics?",
52+
"reset_stats_confirm_button": "Reset",
53+
"reset_stats_cancel_button": "Cancel",
54+
"reset_stats_executed": "Alright, I reset your statistics!",
55+
"reset_stats_cancelled": "Okay, I did not reset your statistics!",
56+
"no_stats": "You haven't played yet, there are no statistics for you."
5157
}

bot.py

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,11 @@
44
import logging.handlers
55
import pathlib
66

7-
from telegram.ext import Updater
7+
from telegram.ext import Updater, JobQueue
88

99
import config
1010
from blackjackbot import handlers, error_handler
11+
from blackjackbot.gamestore import GameStore
1112

1213
logdir_path = pathlib.Path(__file__).parent.joinpath("logs").absolute()
1314
logfile_path = logdir_path.joinpath("bot.log")
@@ -32,6 +33,16 @@
3233

3334
updater.dispatcher.add_error_handler(error_handler)
3435

36+
37+
# Set up jobs
38+
def stale_game_cleaner(context):
39+
gs = GameStore()
40+
gs.cleanup_stale_games()
41+
42+
43+
updater.job_queue.run_repeating(callback=stale_game_cleaner, interval=300, first=300)
44+
45+
3546
if config.USE_WEBHOOK:
3647
updater.start_webhook(listen=config.WEBHOOK_IP, port=config.WEBHOOK_PORT, url_path=config.BOT_TOKEN, cert=config.CERTPATH, webhook_url=config.WEBHOOK_URL)
3748
updater.bot.set_webhook(config.WEBHOOK_URL)

database/statistics.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@ def get_user_stats(user_id):
6363

6464
if played_games == 0:
6565
# prevent division by zero errors
66-
played_games = 1
66+
return translate("no_stats")
6767

6868
last_played_formatted = datetime.utcfromtimestamp(last_played).strftime('%d.%m.%y %H:%M')
6969
win_percentage = round(float(won_games) / float(played_games), 4)

0 commit comments

Comments
 (0)