Beispiel #1
0
 def get_queryset(self):
     try:
         if Round.objects.filter(season=Season.get_current_season()).count() > 0:
             return Ladders.get_season_ranked_participants(
                 Season.get_current_season(), amount=10).prefetch_related(
                 Prefetch('bot', queryset=Bot.objects.all().only('user_id', 'name')),
                 Prefetch('bot__user', queryset=User.objects.all().only('patreon_level')))  # top 10 bots
         else:
             return SeasonParticipation.objects.none()
     except NoCurrentSeason:
         return SeasonParticipation.objects.none()
Beispiel #2
0
    def __init__(self, *args, **kwargs, ):
        super().__init__(*args, **kwargs)

        # change the available fields based upon whether the bot_data is available for editing or not
        # and whether there's a current season
        if self.instance.bot_data_is_currently_frozen():
            self.fields['bot_data'].disabled = True

        try:
            Season.get_current_season()
            # in season
        except NoCurrentSeason:
            # outside season - don't allow activation
            self.fields['active'].disabled = True
            self.fields['active'].required = False
Beispiel #3
0
    def handle(self, *args, **options):
        bot_id = options['botid']
        seasons = [
            options['seasonid'] if options['seasonid'] is not None else
            Season.get_current_season().id
        ]
        if options['allseasons']:
            seasons = Season.objects.all()

        self.stdout.write(f'looping   {len(seasons)} Seasons')
        for s in seasons:
            if isinstance(s, Season):
                season_id = s.id
            else:
                season_id = s
            if bot_id is not None:
                sp = SeasonParticipation.objects.get(season_id=season_id,
                                                     bot_id=bot_id)
                with transaction.atomic():
                    sp.lock_me()
                    self.stdout.write(
                        f'Generating current season stats for bot {bot_id}...')
                    StatsGenerator.update_stats(sp)
            else:
                for sp in SeasonParticipation.objects.filter(
                        season_id=season_id):
                    with transaction.atomic():
                        sp.lock_me()
                        self.stdout.write(
                            f'Generating current season stats for bot {sp.bot_id}...'
                        )
                        StatsGenerator.update_stats(sp)

        self.stdout.write('Done')
Beispiel #4
0
 def CheckEloSum(self):
     sumElo = SeasonParticipation.objects.filter(
         season=Season.get_current_season()).aggregate(Sum('elo'))
     self.assertEqual(
         sumElo['elo__sum'],
         ELO_START_VALUE *
         Bot.objects.all().count())  # starting ELO times number of bots
def stats(request):
    return {
        'match_count_1h': Result.objects.only('id').filter(created__gte=timezone.now() - timedelta(hours=1)).count(),
        'match_count_24h': Result.objects.only('id').filter(created__gte=timezone.now() - timedelta(hours=24)).count(),
        'active_bots': Bot.objects.only('id').filter(active=True).count(),
        'arenaclients': User.objects.only('id').filter(type='ARENA_CLIENT', is_active=True).count(),
        'aiarena_settings': settings,
        'random_donator': User.random_donator(),
        'config': config,
        'current_season': Season.get_current_season_or_none(),
    }
Beispiel #6
0
    def start_next_match(requesting_user):
        with transaction.atomic():
            # REQUESTED MATCHES
            match = Matches._attempt_to_start_a_requested_match(
                requesting_user)
            if match is not None:
                return match  # a match was found - we're done

            # LADDER MATCHES
            current_season = Season.get_current_season()
            # Get rounds with un-started matches
            rounds = Round.objects.raw(
                """
                SELECT distinct cr.id from core_round cr 
                inner join core_match cm on cr.id = cm.round_id
                where season_id=%s
                and finished is null
                and cm.started is null
                order by number
                for update""", (current_season.id, ))

            for round in rounds:
                match = Matches._attempt_to_start_a_ladder_match(
                    requesting_user, round)
                if match is not None:
                    return match  # a match was found - we're done

            # If none of the previous matches were able to start, and we don't have 2 active bots available,
            # then we give up.
            active_bots = Bot.objects.only("id").filter(
                active=True).select_for_update()
            if not Bots.available_is_more_than(active_bots, 2):
                raise NotEnoughAvailableBots()

            # If we get to here, then we have
            # - no matches from any existing round we can start
            # - at least 2 active bots available for play

            if Round.max_active_rounds_reached():
                raise MaxActiveRounds()
            else:  # generate new round
                round = Matches._attempt_to_generate_new_round(current_season)
                match = Matches._attempt_to_start_a_ladder_match(
                    requesting_user, round)
                if match is None:
                    raise APIException(
                        "Failed to start match. There might not be any available participants."
                    )
                else:
                    return match
Beispiel #7
0
    def start_match(match, assign_to) -> bool:
        match.lock_me()  # lock self to avoid race conditions
        if match.started is None:
            # Avoid starting a match when a participant is not available
            participations = MatchParticipation.objects.raw(
                """
                SELECT cm.id FROM core_matchparticipation cm
                where ((cm.use_bot_data =0 or cm.update_bot_data =0) or cm.bot_id not in (
                        select bot_id
                        from core_matchparticipation
                        inner join core_match m on core_matchparticipation.match_id = m.id
                        left join core_result cr on m.id = cr.match_id
                        where m.started is not null
                        and cr.type is null
                        and (core_matchparticipation.use_bot_data = 1 or core_matchparticipation.update_bot_data =1)       
                        and m.id != %s 
                    )) and match_id = %s

            """, (match.id, match.id))

            if len(participations) < 2:
                # Todo: Commented out to avoid log spam. This used to be a last second sanity check.
                # Todo: Investigate whether it is still the case or whether this is no longer considered a system fault
                # Todo: worthy of a warning message being logged.
                # logger.warning(f"Match {match.id} failed to start unexpectedly"
                #                f" because one of the participants was not available.")
                return False

            if match.round:  # if this is a ladder match, record the starting elo
                for p in participations:
                    p.starting_elo = p.bot.seasonparticipation_set.only('elo', 'bot_id') \
                        .get(season=Season.get_current_season()).elo
                    p.save()

            match.started = timezone.now()
            match.assigned_to = assign_to
            match.save()
            return True
        else:
            logger.warning(
                f"Match {match.id} failed to start unexpectedly as it was already started."
            )
            return False
Beispiel #8
0
 def get(self, request, *args, **kwargs):
     season = Season.get_current_season_or_none()
     if season is None:
         return render(request, 'ranking_no_season.html')
     else:
         return redirect('season', pk=season.pk)