Skip to content

Commit

Permalink
Merge pull request #109 from d-Rickyy-b/dev
Browse files Browse the repository at this point in the history
Fix game being stuck and add reset stat feature
  • Loading branch information
d-Rickyy-b committed Jul 30, 2022
2 parents cf0d910 + 1e449a7 commit 2b5b847
Show file tree
Hide file tree
Showing 9 changed files with 103 additions and 13 deletions.
4 changes: 3 additions & 1 deletion blackjack/game/blackjackgame.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
# -*- coding: utf-8 -*-
import logging

from datetime import datetime
from enum import Enum

import blackjack.errors as errors
from blackjack.game import Player, Dealer, Deck

Expand All @@ -17,6 +18,7 @@ def __init__(self, gametype=None, game_id=None, lang_id="en"):
self.list_won = []
self.list_tie = []
self.list_lost = []
self.datetime_started = datetime.now()
self.bets_active = True
self._current_player = 0
self.players = []
Expand Down
4 changes: 3 additions & 1 deletion blackjackbot/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
stop_command_handler = CommandHandler("stop", game.stop_cmd)
language_command_handler = CommandHandler("language", settings.language_cmd)
stats_command_handler = CommandHandler("stats", util.stats_cmd)
resetstats_command_handler = CommandHandler("resetstats", util.reset_stats_cmd)
comment_command_handler = CommandHandler("comment", util.comment_cmd)
comment_text_command_handler = MessageHandler(Filters.text & ~(Filters.forwarded | Filters.command), util.comment_text)

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

handlers = [banned_user_handler,
start_command_handler, stop_command_handler, join_callback_handler, hit_callback_handler,
stand_callback_handler, start_callback_handler, language_command_handler, stats_command_handler,
newgame_callback_handler, reload_lang_command_handler, language_callback_handler, users_command_handler,
comment_command_handler, comment_text_command_handler, answer_command_handler, ban_command_handler,
unban_command_handler, bans_command_handler]
unban_command_handler, bans_command_handler, resetstats_command_handler, reset_stats_callback_handler]

__all__ = ['handlers', 'error_handler']
9 changes: 4 additions & 5 deletions blackjackbot/commands/game/commands.py
Original file line number Diff line number Diff line change
Expand Up @@ -168,12 +168,11 @@ def hit_callback(update, context):
player_cards = get_cards_string(player, lang_id)
if player.has_blackjack():
text = (translator("your_cards_are") + "\n\n" + translator("got_blackjack")).format(user_mention, player.cardvalue, player_cards)
update.effective_message.edit_text(text=text, parse_mode=ParseMode.HTML, reply_markup=None)
next_player(update, context)
elif player.cardvalue == 21:
else:
text = (translator("your_cards_are") + "\n\n" + translator("got_21")).format(user_mention, player.cardvalue, player_cards)
update.effective_message.edit_text(text=text, parse_mode=ParseMode.HTML, reply_markup=None)
next_player(update, context)

update.effective_message.edit_text(text=text, parse_mode=ParseMode.HTML, reply_markup=None)
next_player(update, context)


@needs_active_game
Expand Down
4 changes: 2 additions & 2 deletions blackjackbot/commands/util/__init__.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# -*- coding: utf-8 -*-
from .functions import remove_inline_keyboard, get_start_keyboard, generate_evaluation_string, html_mention, get_game_keyboard, get_join_keyboard
from .decorators import admin_method, needs_active_game
from .commands import stats_cmd, comment_cmd, comment_text
from .commands import stats_cmd, comment_cmd, comment_text, reset_stats_cmd, reset_stats_callback

__all__ = ['remove_inline_keyboard', 'get_start_keyboard', 'generate_evaluation_string', 'html_mention', 'get_game_keyboard', 'get_join_keyboard',
'stats_cmd', 'comment_cmd', 'comment_text', 'admin_method', 'needs_active_game']
'stats_cmd', 'comment_cmd', 'comment_text', 'admin_method', 'needs_active_game', 'reset_stats_cmd', 'reset_stats_callback']
54 changes: 53 additions & 1 deletion blackjackbot/commands/util/commands.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# -*- coding: utf-8 -*-

from telegram import ForceReply, ParseMode
from telegram import ForceReply, ParseMode, InlineKeyboardButton, InlineKeyboardMarkup

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


def reset_stats_cmd(update, context):
"""Asks the user if they want to reset their statistics"""
user_id = update.effective_user.id
chat_id = update.effective_chat.id

_modify_old_reset_message(context)

db = Database()
lang_id = db.get_lang_id(user_id)

keyboard = [[
InlineKeyboardButton(translate("reset_stats_confirm_button"), callback_data='reset_stats_confirm'),
InlineKeyboardButton(translate("reset_stats_cancel_button"), callback_data='reset_stats_cancel'),
]]
reply_markup = InlineKeyboardMarkup(keyboard)

sent_message = update.message.reply_text(translate("reset_stats_confirm", lang_id), reply_markup=reply_markup)
reset_message = {"message_id": sent_message.message_id, "chat_id": chat_id}
context.user_data["reset_messages"] = reset_message


def _modify_old_reset_message(context):
"""Removes the last saved reset confirmation messages from the chat history"""
reset_message = context.user_data.get("reset_message", None)
if reset_message is None:
return

try:
context.bot.edit_message_reply_markup(chat_id=reset_message.get("chat_id"), message_id=reset_message.get("message_id"))
except:
pass

context.user_data["reset_messages"] = None


def reset_stats_callback(update, context):
"""Handler for confirmation of statistics reset"""
query = update.callback_query
query.answer()

user_id = update.effective_user.id
db = Database()
lang_id = db.get_lang_id(user_id)

if query.data == "reset_stats_confirm":
db.reset_stats(user_id=user_id)
query.edit_message_text(translate("reset_stats_executed", lang_id))

elif query.data == "reset_stats_cancel":
query.edit_message_text(translate("reset_stats_cancelled", lang_id))


def comment_cmd(update, context):
"""MessageHandler callback for the /comment command"""
if context.user_data.get("state", UserState.IDLE) != UserState.IDLE:
Expand Down
18 changes: 18 additions & 0 deletions blackjackbot/gamestore.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
# -*- coding: utf-8 -*-
import logging
from datetime import datetime, timedelta
from random import randint

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

self.logger.debug("Current games: {}".format(len(self._chat_dict)))

def cleanup_stale_games(self):
stale_timeout_min = 10
now = datetime.now()
remove_chat_ids = []

for game_id, chat_id in self._game_dict.items():
game = self.get_game(chat_id)

game_older_than_10_mins = game.datetime_started < (now - timedelta(minutes=stale_timeout_min))
if game_older_than_10_mins:
logging.info("Killing game with id {} because it's stale for > {} mins".format(game.id, stale_timeout_min))
# TODO notify chat
remove_chat_ids.append(chat_id)

for chat_id in remove_chat_ids:
self.remove_game(chat_id)
8 changes: 7 additions & 1 deletion blackjackbot/lang/strings/translations_en.json
Original file line number Diff line number Diff line change
Expand Up @@ -47,5 +47,11 @@
"admin_reply": "⚠ You need to reply to the user's comment!",
"reply_from_maintainer": "The maintainer of this bot sent you a reply:\n\n{}",
"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%}",
"dealer_name": "Dealer"
"dealer_name": "Dealer",
"reset_stats_confirm": "Do you really want to reset your statistics?",
"reset_stats_confirm_button": "Reset",
"reset_stats_cancel_button": "Cancel",
"reset_stats_executed": "Alright, I reset your statistics!",
"reset_stats_cancelled": "Okay, I did not reset your statistics!",
"no_stats": "You haven't played yet, there are no statistics for you."
}
13 changes: 12 additions & 1 deletion bot.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,11 @@
import logging.handlers
import pathlib

from telegram.ext import Updater
from telegram.ext import Updater, JobQueue

import config
from blackjackbot import handlers, error_handler
from blackjackbot.gamestore import GameStore

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

updater.dispatcher.add_error_handler(error_handler)


# Set up jobs
def stale_game_cleaner(context):
gs = GameStore()
gs.cleanup_stale_games()


updater.job_queue.run_repeating(callback=stale_game_cleaner, interval=300, first=300)


if config.USE_WEBHOOK:
updater.start_webhook(listen=config.WEBHOOK_IP, port=config.WEBHOOK_PORT, url_path=config.BOT_TOKEN, cert=config.CERTPATH, webhook_url=config.WEBHOOK_URL)
updater.bot.set_webhook(config.WEBHOOK_URL)
Expand Down
2 changes: 1 addition & 1 deletion database/statistics.py
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ def get_user_stats(user_id):

if played_games == 0:
# prevent division by zero errors
played_games = 1
return translate("no_stats")

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

0 comments on commit 2b5b847

Please sign in to comment.