Beispiel #1
0
    def handle(self, *args, **options):
        try:
            games = Game.objects.filter(status__in=(Game.STATUS_PUBLISHED,
                                                    Game.STATUS_FINISHING),
                                        ending_at__lte=timezone.now()).all()

            for game in games:
                if game.smart_contract_id in (None, '', '0'):
                    continue

                if game.status is Game.STATUS_PUBLISHED:
                    try:
                        tx = game.finish()
                    except Exception as e:
                        message = 'Game %d: %s' % (game.id, e)

                        logger.error(message)
                        print(message)

                        continue

                    logger.info('Finish transaction submitted: %s' % (tx))
                    print('For progress see tx: %s' % (tx))
                elif game.get_state() == Game.STATUS_FINISHED:
                    game.status = Game.STATUS_FINISHED
                    game.save()

                    push_message = push.GameFinishedPushMessage(payload=game)

                    PushHelper.inform_all_devices(push_message)

        except Game.DoesNotExist:
            print('No games to proceed')
Beispiel #2
0
    def finish(self):
        if self.smart_contract_id in (None, '0'):
            raise AttributeError('Invalid smart contract address')

        if self.status != Game.STATUS_PUBLISHED:
            raise RuntimeError('Invalid status')

        num_players = self.get_stat().get('numPlayers', 0)

        if num_players < 5:
            self.ending_at += timezone.timedelta(hours=24)
            self.save()

            push_message = push.GameUpdatedPushMessage(payload=self)

            PushHelper.inform_all_devices(push_message)

            return None

        self.status = Game.STATUS_FINISHING
        self.ending_at += timezone.timedelta(hours=1)

        keep_trying = True

        while keep_trying:
            try:
                AccountHelper.unlock_base_account()
                keep_trying = False
            except socket.timeout:
                keep_trying = True

        keep_trying = True

        while keep_trying:
            try:
                contract = self.get_smart_contract()
                tx = contract.transact(
                    transaction={
                        'from': AccountHelper.get_base_account(),
                        'gasPrice': ContractHelper.getGasPrice()
                    }).finish()
                keep_trying = False
            except socket.timeout:
                keep_trying = True

        self.save()

        push_message = push.GameUnpublishedPushMessage(payload=self)

        PushHelper.inform_all_devices(push_message)

        return tx
Beispiel #3
0
    def handle(self, *args, **options):
        try:
            games = Game.objects.filter(
                status=Game.STATUS_PUBLISHED,
                type=Game.TYPE_1_DAY,
                ending_at__gte=timezone.now()).all()

            for game in games:
                push_message = push.GameStartedPushMessage(payload=game)

                PushHelper.inform_all_devices(push_message)

        except Game.DoesNotExist:
            print('No games to proceed')
Beispiel #4
0
        def update_game_stats(event_log):
            web3 = self.get_web3()

            args = event_log.get('args', {})

            num_players = args.get('numPlayers', 0)

            if num_players > self.num_players:
                self.num_players = num_players
                self.prize_amount = web3.fromWei(args.get('prizeAmount', 0),
                                                 'ether')

                self.save()

                push_message = push.GameUpdatedPushMessage(payload=self)

                PushHelper.inform_all_devices(push_message)
Beispiel #5
0
    def create(self, request, *args, **kwargs):
        serializer = self.get_serializer(data=request.data)
        serializer.is_valid(raise_exception=True)
        instance = self.get_object()

        valid_data = serializer.validated_data
        action = valid_data.get('action')
        os = valid_data.get('os')
        token = valid_data.get('token')

        push_message = serializer.get_push_message(action, instance)

        if not push_message.is_valid():
            raise HttpResponseBadRequest(push_message.errors)

        if os is not None:
            if os == DeviceOS.IOS:
                PushHelper.inform_apns_devices(push_message, token)
            elif os == DeviceOS.ANDROID:
                PushHelper.inform_gcm_devices(push_message, token)
        else:
            PushHelper.inform_all_devices(push_message)

        headers = self.get_success_headers(serializer.data)

        return Response(serializer.data,
                        status=status.HTTP_200_OK,
                        headers=headers)
Beispiel #6
0
    def handle(self, *args, **options):
        game_id = options.get('game_id')
        push_type = options.get('game_type')
        device_token = options.get('device_token')

        try:
            game = Game.objects.get(id=game_id)
            push_message = None

            if push_type == 'game_started':
                push_message = push.GameStartedPushMessage(payload=game)
            elif push_type == 'game_updated':
                push_message = push.GameNewPlayerPushMessage(payload=game)
            elif push_type == 'game_finishing':
                push_message = push.GameUnpublishedPushMessage(payload=game)
            elif push_type == 'game_finished':
                push_message = push.GameFinishedPushMessage(payload=game)

            if push_message:
                if device_token and GCMDevice.objects.filter(
                        registration_id=device_token).exists():
                    PushHelper.inform_gcm_devices(push_message, device_token)
                elif device_token and APNSDevice.objects.filter(
                        registration_id=device_token).exists():
                    PushHelper.inform_apns_devices(push_message, device_token)
                else:
                    PushHelper.inform_all_devices(push_message)

        except Game.DoesNotExist:
            print('No games to proceed')
Beispiel #7
0
    def handle(self, *args, **options):
        try:
            games = Game.objects.filter(status=Game.STATUS_PUBLISHED,
                                        type__in=(
                                            Game.TYPE_1_DAY,
                                            Game.TYPE_7_DAYS,
                                        ),
                                        started_at__lte=timezone.now(),
                                        ending_at__gt=timezone.now()).all()

            for game in games:

                if not Web3.isAddress(game.smart_contract_id):
                    continue

                logger.info('Processing game %d' % (game.id))

                keep_trying = True

                stat = {}
                players = []

                while keep_trying:
                    try:
                        stat = game.get_stat()
                        players = game.get_players()

                        keep_trying = False

                        logger.info('Game %d: Pulling game stats.' % (game.id))
                        logger.debug('Game %d: Stat: %s' %
                                     (game.id, str(stat)))
                    except socket.timeout:
                        logger.error(
                            'Game %d: Handled timeout error. Trying again.')
                        keep_trying = True

                stat_num_players = stat.get('numPlayers', 0)

                GamePlayer.objects.filter(game_id=game.id).delete()

                for player in players:
                    GamePlayer.objects.create(game_id=game.id, wallet=player)

                logger.info('Game %d: Checking num players')
                logger.debug(
                    'Game %d: Game num players: %d Stat num players: %d' %
                    (game.id, game.num_players, stat_num_players))

                if game.num_players < stat_num_players:
                    logger.info('Game %d: Updating game' % (game.id))
                    game.num_players = stat_num_players
                    game.prize_amount = Web3.fromWei(
                        stat.get('prizeAmount', 0), 'ether')
                    game.save()

                    logger.info('Game %d: Sending notification to debices' %
                                (game.id))
                    push_message = push.GameNewPlayerPushMessage(payload=game)
                    PushHelper.inform_all_devices(push_message)

        except Game.DoesNotExist:
            message = 'No games to proceed'
            logger.error(message)
            print(message)

        try:
            games = Game.objects.filter(status=Game.STATUS_PUBLISHED,
                                        type__in=(
                                            Game.TYPE_30_DAYS,
                                            Game.TOKEN_GAME,
                                        ),
                                        started_at__lte=timezone.now(),
                                        ending_at__gt=timezone.now()).all()

            for game in games:
                child_games = Game.objects\
                    .exclude(type__in=(Game.TYPE_30_DAYS, Game.TOKEN_GAME,))\
                    .exclude(status__in=(Game.STATUS_CANCELED,))\
                    .filter(started_at__gte=game.started_at, ending_at__lte=game.ending_at)

                if game.type != Game.TOKEN_GAME:
                    game.prize_amount = 0

                num_players_qs = GamePlayer.objects \
                    .distinct('wallet') \
                    .exclude(game__type__in=(Game.TYPE_30_DAYS, Game.TOKEN_GAME,)) \
                    .exclude(game__status=Game.STATUS_CANCELED) \
                    .filter(game__started_at__gte=game.started_at, game__ending_at__lte=game.ending_at)

                if game.type == Game.TYPE_30_DAYS:
                    num_players_qs = num_players_qs.filter(is_winner=False)\
                                                .filter(game__status=Game.STATUS_FINISHED)

                game.num_players = num_players_qs.count()

                GamePlayer.objects.filter(game_id=game.id).delete()

                for player in num_players_qs:
                    GamePlayer.objects.create(game_id=game.id,
                                              wallet=player.wallet,
                                              is_winner=False,
                                              prize_amount=0)

                for child_game in child_games:
                    if game.type != Game.TOKEN_GAME:
                        game.prize_amount += ((child_game.prize_amount / 0.8) *
                                              0.1)

                game.save()

        except Game.DoesNotExist:
            pass