Beispiel #1
0
 def tournament_engine_real_time(self):
     while not self.shutdown:
         print("[WAIT - TOURNAMENT ENGINE REAL-TIME]")
         self.shutdown_event.wait(timeout=get_run_time() / 3)
         try:
             now_run_time = timezone.now()
             self.check_games(has_started=True,
                              multi_day=False,
                              all_games_completed=False)
             self.cache_games(has_started=True,
                              multi_day=False,
                              is_cache_dirty=True)
         except:
             log_exception()
         finally:
             finished_time = timezone.now()
             next_run = timezone.now() + datetime.timedelta(
                 seconds=get_run_time() / 3)
             total_run_time = (finished_time - now_run_time).total_seconds()
             log(
                 "RT Engine done running at {}, ran for a total of {} seconds. Next run at {}"
                 .format(finished_time, total_run_time,
                         next_run), LogLevel.engine)
             print(
                 "RT Engine done running at {}, ran for a total of {} seconds. Next run at {}"
                 .format(finished_time, total_run_time, next_run))
Beispiel #2
0
 async def game_logs(self, ctx, game_id=0, num_logs=-1, page=-1):
     try:
         if is_clotadmin(ctx.message.author.id):
             if game_id != 0 and num_logs != -1 and page != -1:
                 # good
                 print(
                     "Game Id: {}, num_logs per page: {}, page: {}".format(
                         game_id, num_logs, page))
                 game_logs = ProcessGameLog.objects.filter(
                     game__gameid=int(game_id)).order_by('id')
                 print("Number game logs: {}".format(game_logs.count()))
                 paginator = Paginator(game_logs, num_logs)
                 page = paginator.get_page(page)
                 for log in page:
                     await ctx.message.author.send(log.msg[0:1900])
                     if len(log.msg) > 1900:
                         await ctx.message.author.send(log.msg[1900:])
             else:
                 await ctx.send(
                     "You must pass in all parameters to the command.")
         else:
             await ctx.send("You must be an admin to use this command")
     except:
         log_exception()
         await ctx.send(
             "An error has occurred and was unable to process the command.")
Beispiel #3
0
 def is_multiday(self):
     try:
         settings_dict = json.loads('''{}'''.format(self.template_settings))
         if 'Pace' in self.template_settings:
             return settings_dict['Pace'] == "MultiDay"
     except:
         log_exception()
Beispiel #4
0
    async def bet(self, ctx, team="", wager=""):
        try:
            discord_user = await self.bot.bridge.getdiscordUsers(memberid=ctx.message.author.id)
            if not discord_user:
                discord_user = await self.bot.bridge.createDiscordUser(memberid=ctx.message.author.id)
            else:
                discord_user = discord_user[0]

            player = await self.bot.bridge.getPlayers(discord_member=discord_user)
            if not len(player):
                await ctx.send(self.bot.discord_link_text)
                return

            player = player[0]
            if not team.isnumeric():
                await ctx.send("{} is not a valid team id. Please enter a valid teamid. Betting via typing in a player's name isn't supported yet.".format(team))
                return

            team = int(team)
            team_odds = await self.bot.bridge.getBetTeamOdds(pk=team)
            if not len(team_odds):
                await ctx.send("{} is not a valid bet id.".format(team))
                return

            team_odds = team_odds[0]
            if not wager.isnumeric() or int(wager) < 1:
                await ctx.send("{} is not a valid wager. Please enter a valid wager amount.".format(wager))
                return

            # check to see if the player has enough coins to bet
            wager = int(wager)
            if player.bankroll < wager:
                await ctx.send("You only have {} coins to bet with. Please use a smaller wager.".format(player.bankroll))
                return

            if not team_odds.bet_game.game.betting_open:
                await ctx.send("Betting is no longer open for game {}.".format(team_odds.bet_game.gameid))
                return

            for players_team in team_odds.bet_game.players.split('-'):
                for token in players_team.split('.'):
                    if player.token == token:
                        await ctx.send("You cannot bet on a game you are playing in. Please choose a different bet.")
                        return

            # we have the game, tournament team and player with the wager...
            # go ahead and create the bet
            cb = await self.bot.bridge.getCLOTBook()
            if cb.calculate_decimal_odds_winnings(team_odds.decimal_odds, wager) < 1:
                await ctx.send("You must bet enough to win at least 1 coin. Please enter a different wager amount.")
                return

            bet = cb.create_new_bet(wager, player, team_odds)
            team_players = await self.bot.bridge.get_team_data_no_clan_player_list(team_odds.players.split('.'))
            await ctx.send("{} placed a bet on {} in game {} for {} coins to win {} coins.".format(
                    ctx.message.author.name, team_players, team_odds.bet_game.game.id, bet.wager, bet.winnings))
        except:
            log_exception()
Beispiel #5
0
 def update_player_profiles_routine(self):
     while not self.shutdown:
         try:
             # Updates every player's name and clan
             self.update_all_player_clans()
         except:
             log_exception()
         print("[WAIT - PLAYER PROFILE UPDATE]")
         # Run once a day
         self.shutdown_event.wait(timeout=get_run_time() * 480)
Beispiel #6
0
    def worker_routine(self):
        while not self.shutdown:
            try:
                self.process_mdl_games()
                self.parse_and_update_clan_logo()
                #self.process_team_vacations() # for now do not process any team vacations...that takes too long
            except Exception:
                log_exception()

            print("[WAIT - WORKER]")
            self.shutdown_event.wait(timeout=get_run_time() * 20)
Beispiel #7
0
 def handle(self, *args, **options):
     try:
         if settings.DEBUG:
             bot = WZBot()
             bot.run(os.environ['WZ_TEST_BOT_TOKEN'])
         else:
             bot = WZBot()
             bot.run(os.environ['WZ_BOT_TOKEN'])
     except SystemExit:
         pass
     except Exception:
         log_exception()
Beispiel #8
0
    def is_correct_player(self, player_token, player_team):
        try:
            player = Player.objects.filter(token=player_token)[0]
            tt = TournamentTeam.objects.filter(pk=player_team)[0]
            if player.clan and player.clan.name == tt.clan_league_clan.clan.name:
                return True

            tplayers = TournamentPlayer.objects.filter(team=tt)
            for tplayer in tplayers:
                if tplayer.player.token == player_token:
                    return True
            return False
        except:
            log_exception()
            return False
Beispiel #9
0
    def check_games(self, **kwargs):
        log("Running check_games on thread {}".format(threading.get_ident()),
            LogLevel.engine)
        tournaments = Tournament.objects.filter(**kwargs)
        for tournament in tournaments:
            games_in_progress = 0
            if self.shutdown:
                return

            # if we get this far, we actually need to check the tournament
            child_tournament = find_tournament_by_id(tournament.id, True)
            if child_tournament and child_tournament.should_process_in_engine(
            ):
                try:
                    games = TournamentGame.objects.filter(
                        is_finished=False, tournament=tournament)
                    games_in_progress = games.count()
                    log(
                        "[PROCESS GAMES]: Processing {} games for tournament {}"
                        .format(games.count(),
                                tournament.name), LogLevel.engine)
                    for game in games.iterator():
                        # process the game
                        # query the game status
                        child_tournament.process_game(game)
                    # in case tournaments get stalled for some reason
                    # for it to process new games based on current tournament data
                    child_tournament.process_new_games()

                    if hasattr(child_tournament, 'clan_league_template'
                               ) and not child_tournament.multi_day:
                        child_tournament.multi_day = True
                        child_tournament.save()
                except Exception as e:
                    log_exception()
                finally:
                    child_tournament.update_in_progress = False
                    child_tournament.save()

                # if we are finished, and there are no outstanding games in progress...we are deemed "all_games_completed"
                if child_tournament.is_finished and games_in_progress == 0:
                    log(
                        "[PROCESS GAMES]: Child tournament {} has all games completed."
                        .format(tournament.name), LogLevel.engine)
                    child_tournament.all_games_completed = True
                    child_tournament.save()

            gc.collect()
Beispiel #10
0
    def tournament_engine(self):
        while not self.shutdown:
            print("[WAIT - TOURNAMENT ENGINE]")
            self.shutdown_event.wait(timeout=get_run_time() * 10)
            try:
                engine = Engine.objects.all()
                if not engine or engine.count() == 0:
                    # create the engine object!
                    engine = Engine()
                    engine.save()
                else:
                    engine = engine[0]
                    engine.last_run_time = timezone.now()
                    engine.next_run_time = timezone.now() + datetime.timedelta(
                        seconds=get_run_time())
                    engine.save()

                print("Process Games Starting...")

                # bulk of the logic, we handle all types of tournaments separately here
                # there must be logic for each tournament type, as the child class contains
                # the logic
                self.check_games(has_started=True,
                                 multi_day=True,
                                 all_games_completed=False)
                self.cache_games(has_started=True,
                                 multi_day=True,
                                 is_cache_dirty=True)
                self.cleanup_logs()
            except Exception as e:
                log_exception()
            finally:
                finished_time = timezone.now()
                next_run = timezone.now() + datetime.timedelta(
                    seconds=get_run_time())
                total_run_time = (finished_time -
                                  engine.last_run_time).total_seconds()
                log(
                    "Engine done running at {}, ran for a total of {} seconds. Next run at {}"
                    .format(finished_time, total_run_time,
                            next_run), LogLevel.engine)
                print(
                    "Engine done running at {}, ran for a total of {} seconds. Next run at {}"
                    .format(finished_time, total_run_time, next_run))
                engine.last_run_time = finished_time
                engine.next_run_time = next_run
                engine.save()
Beispiel #11
0
    def cache_games(self, **kwargs):
        tournaments = Tournament.objects.filter(**kwargs)
        for tournament in tournaments:
            games_in_progress = 0
            if self.shutdown:
                return
            child_tournament = find_tournament_by_id(tournament.id, True)
            if child_tournament:
                log(
                    "[CACHE]: Checking games for tournament: {}, shutdown: {}".
                    format(tournament.name, self.shutdown), LogLevel.engine)
                try:
                    # we only need to cache if there are unfinished games
                    games = TournamentGame.objects.filter(
                        tournament=child_tournament, is_finished=False)
                    games_in_progress = games.count()
                    child_tournament.cache_data()
                except Exception as e:
                    log_exception()
                finally:
                    log(
                        "[CACHE]: Child tournament {} update done.".format(
                            tournament.name), LogLevel.engine)

                # if the tournament is finished and there are no more outstanding games that are in progress
                # the cache is no longer dirty and we should stop looking at it
                log(
                    "[CACHE]: {} has {} games in progress, is_finished: {}".
                    format(child_tournament.name, games_in_progress,
                           child_tournament.is_finished), LogLevel.engine)
                if child_tournament.is_finished and games_in_progress == 0:
                    log(
                        "[CACHE]: Child tournament {} cache is no longer dirty."
                        .format(tournament.name), LogLevel.engine)
                    child_tournament.is_cache_dirty = False
                    child_tournament.save()
                elif games_in_progress > 0:
                    child_tournament.is_cache_dirty = True
                    child_tournament.save()
                    # cache is not dirty...let's get this on the next time around

            gc.collect()
Beispiel #12
0
    async def status(self, ctx, server):
        try:
            url = ""
            if server == "clot" or server == "CLOT":
                url = 'http://wzclot.eastus.cloudapp.azure.com'
                r = requests.get(url)
            elif server == "wz" or server == "WZ":
                url = 'https://www.warzone.com/MultiPlayer/'
                r = requests.get(url)
            r.status_code
            if str(r.status_code) == "200":
                status = "{} - ONLINE".format(url)
            else:
                status = "{} - OFFLINE".format(url)

            await ctx.send("Server Status: {}".format(status))
        except:
            log_exception()
            await ctx.send(
                "An error has occurred and was unable to process the command.")
Beispiel #13
0
    async def on_ready(self):
        try:
            await self.bridge.log_bot_msg(
                f'[CONNECT] Logged in as:\n{self.user} (ID: {self.user.id})\n')

            # cache all the guilds we're in when we login and the real-time-ladder channels
            for guild in self.guilds:
                if guild.name == "-B's CLOT":
                    print("Found -B's CLOT, caching...id: {}".format(guild.id))
                    self.clot_server = guild
                for channel in guild.channels:
                    if channel.name == "real-time-ladder" or channel.name == "real_time_ladder":
                        print("Found RTL Channel in guild: {}".format(
                            guild.name))
                    elif channel.name == "monthly-template-circuit" or channel.name == "monthly_template_circuit":
                        print("Caching MTC channel in guild: {}".format(
                            guild.name))
                        self.mtc_channels.append(channel)
                    elif channel.name == "clan-league-bot-chat" or channel.name == "clan_league_bot_chat":
                        print("Caching CL channel in guild: {}".format(
                            guild.name))
                        self.clan_league_channels.append(channel)
                    elif channel.name == "critical-errors":
                        print("Caching Critical Error Channel in guild: {}".
                              format(guild.name))
                        self.critical_error_channels.append(channel)
            if not hasattr(self, 'uptime'):
                self.uptime = timezone.now()

            print("Creating communication thread...")
            self.shutdown_thread = threading.Thread(
                target=self.handle_shutdown)
            self.shutdown_thread.start()

            print("Creating flushing thread")
            self.flush_thread = threading.Thread(target=self.flush)
            self.flush_thread.start()

        except Exception as e:
            log_exception()
Beispiel #14
0
 def process_team_vacations(self):
     try:
         start_time = datetime.datetime.utcnow()
         log("Starting process team vacation: {}".format(start_time),
             LogLevel.engine)
         tournaments = Tournament.objects.filter(is_finished=False,
                                                 has_started=True)
         for t in tournaments:
             if self.shutdown:
                 return
             gc.collect()
             t = find_tournament_by_id(t.id, True)
             teams = TournamentTeam.objects.filter(tournament=t)
             for team in teams:
                 if self.shutdown:
                     return
                 team.on_vacation = t.is_team_on_vacation(team)
                 team.save()
         end_time = datetime.datetime.utcnow()
         log(
             "End process team vacations. Total Time: {}".format(
                 (end_time - start_time).total_seconds()), LogLevel.engine)
     except Exception:
         log_exception()
Beispiel #15
0
    def api_create_fake_game_and_get_settings(self, templateid):
        # first, create the game
        ret = {}
        data = {}
        data['hostEmail'] = self.client_email
        data['hostAPIToken'] = self.client_token
        data['templateID'] = templateid
        data['gameName'] = "get template settings"
        data['players'] = [{
            "token": "OpenSeat",
            "team": "None"
        }, {
            "token": "OpenSeat",
            "team": "None"
        }]

        gameID = 0
        try:
            gameInfo = self.api_create_game(data)
            gameInfo = gameInfo.json()

            # the game has been posted, make sure we have a game id and then query the settings
            if 'gameID' in gameInfo:
                # great, query the settings
                gameID = gameInfo['gameID']
                data = {}
                data['gameID'] = gameID
                data['GetSettings'] = 'true'
                gameSettings = self.api_query_game_settings(gameID)

                # if 'error' in gameSettings.json():
                # return an error, and just delete the game
                # got the settings, now send this back as we want to display in the form
                # for the creator
                # delete the game first
                deleteGame = self.api_delete_game(int(gameID))
                deleteGame = deleteGame.json()

                if 'success' in deleteGame:
                    # game deleted successfully
                    ret['success'] = 'true'

                    # convert the gameSettings we need from here into readable text so that the client doesn't have to do
                    # any conversion
                    gameSettings = gameSettings.json()
                    log(
                        "Getting settings for template: {}".format(
                            gameSettings), LogLevel.informational)
                    if 'settings' in gameSettings:
                        settings = gameSettings['settings']
                        # this is so we can cache the entire template settings if the tournament actually gets created
                        ret['settings'] = settings
                        if 'Pace' in settings:
                            # convert into days
                            directbootTimeMinutes = gameSettings['settings'][
                                'DirectBoot']
                            autobootTimeMinutes = gameSettings['settings'][
                                'AutoBoot']
                            ret['Pace'] = gameSettings['settings']['Pace']

                            fmt = ""
                            if ret['Pace'] == 'RealTime':
                                fmt = '{0.minutes} minutes {0.seconds} seconds'
                            else:
                                fmt = '{0.days} days {0.hours} hours'

                            if directbootTimeMinutes is not 'none':
                                ret['directBoot'] = fmt.format(
                                    rd(minutes=directbootTimeMinutes))
                            if autobootTimeMinutes is not 'none':
                                ret['autoBoot'] = fmt.format(
                                    rd(minutes=autobootTimeMinutes))
            else:
                # not good, error, TODO: Log???
                if 'error' in gameInfo:
                    ret['error'] = gameInfo['error']
        except:
            # catch the error, if we have created the game delete it here
            log_exception()
            if gameID is not 0 and 'success' not in ret:
                data = {}
                data['gameID'] = gameID
                deleteGame = self.api_delete_game(int(gameID))

        if 'error' in gameInfo and gameInfo[
                'error'] == 'GameTemplateKeyNotFound':
            ret['error'] = "The template id is invalid. Please enter a valid template id!"
        elif 'success' not in ret:
            ret['error'] = "There was a problem with getting the template settings. Please try again later."

        return ret
Beispiel #16
0
    def create_initial_odds_for_game(self, game, ratings1, ratings2):
        try:
            # get the ratings from the players in the game
            probs = self.probability_to_win(ratings1, ratings2)
            probs1 = probs[0]
            probs2 = probs[1]

            log_cb_msg(
                "Initial probabilities for gameid {}: {}% to {}%".format(
                    game.gameid, probs1, probs2))
            probability = "{}!{}".format(probs1, probs2)

            decimal1 = self.prob_to_decimal_odds(probs1)
            decimal2 = self.prob_to_decimal_odds(probs2)

            log_cb_msg("Decimal odds for gameid {}: {} {}".format(
                game.gameid, decimal1, decimal2))

            american1 = self.decimal_odds_to_american(decimal1)
            american2 = self.decimal_odds_to_american(decimal2)

            # round the american to the nearest 5 or 0, and change that back into decimal
            log_cb_msg(
                "American odds for gameid {} before rounding: {} {}".format(
                    game.gameid, american1, american2))
            american1 = self.round_to_nearest_multiple(american1)
            american2 = self.round_to_nearest_multiple(american2)
            american_odds = "{}!{}".format(american1, american2)

            log_cb_msg("American odds for gameid {}: {}".format(
                game.gameid, american_odds))

            decimal1 = self.american_odds_to_decimal(american1)
            decimal2 = self.american_odds_to_decimal(american2)
            decimal_odds = "{}!{}".format(decimal1, decimal2)
            log_cb_msg("Decimal odds for gameid {}: {}".format(
                game.gameid, decimal_odds))

            bet_game = BetGameOdds(gameid=game.id,
                                   game=game,
                                   players=game.players,
                                   initial=True,
                                   decimal_odds=decimal_odds,
                                   probability=probability,
                                   american_odds=american_odds)
            bet_game.save()

            players1 = game.players.split('-')[0]
            players2 = game.players.split('-')[1]
            team_odds1 = BetTeamOdds(bet_game=bet_game,
                                     players_index=0,
                                     decimal_odds=decimal1,
                                     american_odds=american1,
                                     players=players1)
            team_odds1.save()

            team_odds2 = BetTeamOdds(bet_game=bet_game,
                                     players_index=1,
                                     decimal_odds=decimal2,
                                     american_odds=american2,
                                     players=players2)
            team_odds2.save()

            log_cb_msg("Created initial odds for gameid {}".format(
                game.gameid))
        except:
            log_exception()
Beispiel #17
0
    async def cb(self, ctx, option="", arg="", coins=""):
        try:
            discord_user = await self.bot.bridge.getDiscordUsers(memberid=ctx.message.author.id)
            if not discord_user:
                await self.bot.bridge.createDiscordUser(memberid=ctx.message.author.id)
            else:
                discord_user = discord_user[0]

            if option == "":
                await ctx.send("You must specify an option with this command.")
                return

            if option == "stats":
                await ctx.send("This command is currently under construction.")
            elif option == "on":
                if ctx.message.author.guild_permissions.administrator or is_clotadmin(ctx.message.author.id):
                    if arg == "results":
                        # create a link for results only
                        discord_channel_link = await self.bot.bridge.getDiscordChannelClotBookLinks(
                            channelid=ctx.message.channel.id, results_only=True)
                        if len(discord_channel_link.count) > 0:
                            await ctx.send("There is already a CLOTBook results link to this channel.")
                            return
                        await self.bot.bridge.createChannelClotbookLink(channelid=ctx.message.channel.id,
                                                                          discord_user=discord_user,
                                                                          results_only=True)
                        await ctx.send("The CLOTBook will start using this channel to send live betting results.")
                    else:
                        discord_channel_link = await self.bot.bridge.getDiscordChannelClotBookLinks(channelid=ctx.message.channel.id, results_only=True)
                        if len(discord_channel_link.count) == 0:
                            await self.bot.bridge.createChannelClotbookLink(channelid=ctx.message.channel.id, discord_user=discord_user)
                            await ctx.send("The CLOTBook will start using this channel to send live betting updates.")
                        else:
                            await ctx.send("This channel is already registered to receive CLOTBook Updates")
                else:
                    await ctx.send("You must be a server administrator to use this command.")
            elif option == "off":
                if ctx.message.author.guild_permissions.administrator or is_clotadmin(ctx.message.author.id):
                    if arg == "results":
                        discord_channel_link = await self.bot.bridge.getDiscordChannelClotBookLinks(channelid=ctx.message.channel.id, results_only=True)
                        if discord_channel_link:
                            await self.bot.bridge.deleteObject(discord_channel_link[0])
                            await ctx.send("The CLOTBook will no longer use this channel for sending results.")
                        else:
                            await ctx.send("This channel is not hooked up to receive CLOTBook updates.")
                    else:
                        discord_channel_link = await self.bot.bridge.getDiscordChannelClotBookLinks(channelid=ctx.message.channel.id, results_only=False)
                        if discord_channel_link:
                            await self.bot.bridge.deleteObject(discord_channel_link[0])
                            await ctx.send("The CLOTBook will no longer use this channel for updates.")
                        else:
                            await ctx.send("This channel is not hooked up to receive CLOTBook updates.")
                else:
                    await ctx.send("You must be a server administrator to use this command.")
            elif option == "me":
                player = await self.bot.bridge.getPlayers(discord_member=discord_user)
                if not player:
                    await ctx.send(self.bot.discord_link_text)
                    return
                player = player[0]
                user = self.bot.get_user(discord_user.memberid)
                emb = self.bot.get_embed(user)
                emb.title = "{}'s last 10 bets".format(user.name)
                bets = await self.bot.bridge.getBetsOrderByCreatedTime(player=player)
                total_bets = len(bets)
                bets = bets[:10]
                bet_text = ""
                for bet in bets:
                    if bet.game.is_finished:
                        bet_text += "[Game Link]({}) - Bet {} coins, ".format(bet.game.game_link, bet.wager)
                        if bet.winnings == 0:
                            bet_text += "and lost bet\n"
                        else:
                            bet_text += "and won {} coins\n".format(bet.winnings)
                    else:
                        bet_text += "Bet {} coins on [Game]({}) to win {}\n".format(bet.wager, bet.game.game_link, bet.winnings)

                if len(bet_text) > 0:
                    emb.add_field(name="Bets", value=bet_text)

                info_text = "Total Bets: {}\nBankroll: {} coins".format(total_bets, player.bankroll)
                emb.add_field(name="Info", value=info_text)
                await ctx.send(embed=emb)

            elif option == "initial":
                if not is_clotadmin(ctx.message.author.id):
                    await ctx.send("Only CLOT admins can use this command.")
                    return
                if arg.isnumeric():
                    game = await self.bot.bridge.getGames(gameid=arg)
                    if not len(game):
                        game = await self.bot.bridge.getGames(pk=int(arg))
                        if not len(game):
                            await ctx.send("You must specify a valid game id to use with this command.")
                            return
                    game = game[0]

                    odds = await self.bot.bridge.getBetGameOdds(game=game)
                    for odd in odds:
                        odd.delete()
                    game.create_initial_lines()
                    await ctx.send("Updated initial lines for game {}".format(game.gameid))
                    return
            elif option == "br":
                if not is_clotadmin(ctx.message.author.id):
                    await ctx.send("Only CLOT admins can use this command.")
                    return
                player = await self.bot.bridge.getPlayers(token=arg)
                if not len(player):
                    await ctx.send("Player with token {} cannot be found in the CLOT database.")
                    return
                if coins.isnumeric():
                    player[0].bankroll += float(coins)
                    player[0].save()

            elif option.isnumeric():
                # try to look up the game id
                game = int(option)
            else:
                await ctx.send("You must specify an option with this command.")
        except:
            log_exception()