Esempio n. 1
0
    def test_game_info_data_hidding(self):
        '''
        player hero always must show actual data
        enemy hero always must show data on statrt of the turn
        '''
        self.pvp_create_battle(self.account_1, self.account_2, BATTLE_1X1_STATE.PROCESSING)
        self.pvp_create_battle(self.account_2, self.account_1, BATTLE_1X1_STATE.PROCESSING)

        hero_1 = heroes_logic.load_hero(account_id=self.account_1.id)
        hero_2 = heroes_logic.load_hero(account_id=self.account_2.id)

        hero_1.pvp.set_energy(1)
        heroes_logic.save_hero(hero_1)

        hero_2.pvp.set_energy(2)
        heroes_logic.save_hero(hero_2)

        data = form_game_info(self.account_1, is_own=True)

        self.assertEqual(data['account']['hero']['pvp']['energy'], 1)
        self.assertEqual(data['enemy']['hero']['pvp']['energy'], 0)

        hero_2.pvp.store_turn_data()
        heroes_logic.save_hero(hero_2)

        data = form_game_info(self.account_1, is_own=True)

        self.assertEqual(data['enemy']['hero']['pvp']['energy'], 2)
Esempio n. 2
0
    def test_is_old__not_own_hero(self):
        self.assertFalse(form_game_info(self.account_1, is_own=False)['account']['is_old'])

        TimePrototype(turn_number=666).save()
        self.assertTrue(form_game_info(self.account_1, is_own=False)['account']['is_old'])

        heroes_logic.save_hero(heroes_logic.load_hero(account_id=self.account_1.id))
        self.assertFalse(form_game_info(self.account_1, is_own=False)['account']['is_old'])
Esempio n. 3
0
    def test_is_old(self):
        self.assertFalse(form_game_info(self.account_1, is_own=True)['account']['is_old'])

        turn.set(666)
        self.assertTrue(form_game_info(self.account_1, is_own=True)['account']['is_old'])

        heroes_logic.save_hero(heroes_logic.load_hero(account_id=self.account_1.id))
        self.assertFalse(form_game_info(self.account_1, is_own=True)['account']['is_old'])
Esempio n. 4
0
    def test_is_old__not_own_hero(self):
        self.assertFalse(form_game_info(self.account_1, is_own=False)['account']['is_old'])

        TimePrototype(turn_number=666).save()
        self.assertTrue(form_game_info(self.account_1, is_own=False)['account']['is_old'])

        heroes_logic.save_hero(heroes_logic.load_hero(account_id=self.account_1.id))
        self.assertFalse(form_game_info(self.account_1, is_own=False)['account']['is_old'])
Esempio n. 5
0
    def test_is_old__not_own_hero(self):
        self.assertFalse(
            form_game_info(self.account_1, is_own=False)['account']['is_old'])

        TimePrototype(turn_number=666).save()
        self.assertTrue(
            form_game_info(self.account_1, is_own=False)['account']['is_old'])

        HeroPrototype.get_by_account_id(self.account_1.id).save()
        self.assertFalse(
            form_game_info(self.account_1, is_own=False)['account']['is_old'])
Esempio n. 6
0
    def test_not_own_hero_get_cached_data__not_cached(self):
        hero = heroes_logic.load_hero(account_id=self.account_1.id)

        with mock.patch('the_tale.game.heroes.objects.Hero.cached_ui_info_for_hero',
                        mock.Mock(return_value=self.create_not_own_ui_info(hero))) as cached_ui_info_for_hero:
            with mock.patch('the_tale.game.heroes.objects.Hero.ui_info',
                            mock.Mock(return_value=self.create_not_own_ui_info(hero))) as ui_info:
                form_game_info(self.account_1, is_own=False)

        self.assertEqual(cached_ui_info_for_hero.call_count, 1)
        self.assertEqual(cached_ui_info_for_hero.call_args, mock.call(account_id=self.account_1.id, recache_if_required=False, patch_turns=None, for_last_turn=True))
        self.assertEqual(ui_info.call_count, 0)
Esempio n. 7
0
    def test_not_own_hero_get_cached_data__not_cached(self):
        hero = heroes_logic.load_hero(account_id=self.account_1.id)

        with mock.patch('the_tale.game.heroes.objects.Hero.cached_ui_info_for_hero',
                        mock.Mock(return_value=self.create_not_own_ui_info(hero))) as cached_ui_info_for_hero:
            with mock.patch('the_tale.game.heroes.objects.Hero.ui_info',
                            mock.Mock(return_value=self.create_not_own_ui_info(hero))) as ui_info:
                form_game_info(self.account_1, is_own=False)

        self.assertEqual(cached_ui_info_for_hero.call_count, 1)
        self.assertEqual(cached_ui_info_for_hero.call_args, mock.call(account_id=self.account_1.id, recache_if_required=False, patch_turns=None, for_last_turn=True))
        self.assertEqual(ui_info.call_count, 0)
Esempio n. 8
0
    def test_game_info_data_hidding(self):
        '''
        player hero always must show actual data
        enemy hero always must show data on statrt of the turn
        '''
        self.pvp_create_battle(self.account_1, self.account_2,
                               BATTLE_1X1_STATE.PROCESSING)
        self.pvp_create_battle(self.account_2, self.account_1,
                               BATTLE_1X1_STATE.PROCESSING)

        self.storage = LogicStorage()
        self.storage.load_account_data(self.account_1)
        self.storage.load_account_data(self.account_2)

        hero_1 = self.storage.accounts_to_heroes[self.account_1.id]
        hero_2 = self.storage.accounts_to_heroes[self.account_2.id]

        meta_action_battle = meta_actions.ArenaPvP1x1.create(
            self.storage, hero_1, hero_2)
        meta_action_battle.set_storage(self.storage)

        action_prototypes.ActionMetaProxyPrototype.create(
            hero=hero_1,
            _bundle_id=hero_1.actions.current_action.bundle_id,
            meta_action=meta_action_battle)
        action_prototypes.ActionMetaProxyPrototype.create(
            hero=hero_2,
            _bundle_id=hero_1.actions.current_action.bundle_id,
            meta_action=meta_action_battle)

        meta_action_battle.hero_1_pvp.set_energy(1)
        meta_action_battle.hero_2_pvp.set_energy(2)

        heroes_logic.save_hero(hero_1)
        heroes_logic.save_hero(hero_2)

        data = form_game_info(self.account_1, is_own=True)

        self.assertEqual(
            data['account']['hero']['action']['data']['pvp']['energy'], 1)
        self.assertEqual(
            data['enemy']['hero']['action']['data']['pvp']['energy'], 0)

        meta_action_battle.hero_2_pvp.store_turn_data()
        heroes_logic.save_hero(hero_2)

        data = form_game_info(self.account_1, is_own=True)

        self.assertEqual(
            data['enemy']['hero']['action']['data']['pvp']['energy'], 2)
Esempio n. 9
0
    def test_game_info_caching(self):
        self.pvp_create_battle(self.account_1, self.account_2, BATTLE_1X1_STATE.PROCESSING)
        self.pvp_create_battle(self.account_2, self.account_1, BATTLE_1X1_STATE.PROCESSING)

        hero_1 = heroes_logic.load_hero(account_id=self.account_1.id)
        hero_2 = heroes_logic.load_hero(account_id=self.account_2.id)

        def get_ui_info(hero, **kwargs):
            if hero.id == hero_1.id:
                return {'actual_on_turn': hero_1.saved_at_turn,
                        'action': {'data': {'pvp__actual':'actual',
                                            'pvp__last_turn':'last_turn'}},
                        'changed_fields': [],
                        'ui_caching_started_at': 0}
            else:
                return self.create_not_own_ui_info(hero_2)

        with mock.patch('the_tale.game.heroes.objects.Hero.ui_info', get_ui_info):
            data = form_game_info(self.account_1, is_own=True)

        self.assertEqual(data['account']['hero']['action']['data']['pvp'], 'actual')
        self.assertEqual(data['enemy']['hero']['action']['data']['pvp'], 'last_turn')

        self.assertFalse('pvp__actual' in data['account']['hero']['action']['data']['pvp'])
        self.assertFalse('pvp__last_turn' in data['account']['hero']['action']['data']['pvp'])
        self.assertFalse('pvp__actual' in data['enemy']['hero']['action']['data']['pvp'])
        self.assertFalse('pvp__last_turn' in data['enemy']['hero']['action']['data']['pvp'])

        self.assertNotEqual(data['enemy']['hero']['cards'], 'fake')
        self.assertEqual(data['enemy']['hero']['energy']['max'], 0)
        self.assertEqual(data['enemy']['hero']['energy']['value'], 0)
        self.assertEqual(data['enemy']['hero']['energy']['bonus'], 0)
        self.assertEqual(data['enemy']['hero']['energy']['discount'], 0)
Esempio n. 10
0
    def test_not_own_hero_get_cached_data(self):
        hero = heroes_logic.load_hero(account_id=self.account_1.id)

        with mock.patch(
                'the_tale.game.heroes.objects.Hero.ui_info',
                mock.Mock(return_value=self.create_not_own_ui_info(
                    hero))) as ui_info:
            data = form_game_info(self.account_1, is_own=False)

        self.assertEqual(data['account']['hero']['action']['data']['pvp'],
                         'last_turn')
        self.assertEqual(data['enemy'], None)

        self.assertFalse(
            'pvp__actual' in data['account']['hero']['action']['data']['pvp'])
        self.assertFalse('pvp__last_turn' in data['account']['hero']['action']
                         ['data']['pvp'])

        self.assertNotEqual(data['account']['hero']['cards'], 'fake')
        self.assertEqual(data['account']['hero']['energy']['max'], 0)
        self.assertEqual(data['account']['hero']['energy']['value'], 0)
        self.assertEqual(data['account']['hero']['energy']['bonus'], 0)
        self.assertEqual(data['account']['hero']['energy']['discount'], 0)

        self.assertEqual(ui_info.call_count, 1)
        self.assertEqual(ui_info.call_args, mock.call(actual_guaranteed=False))
Esempio n. 11
0
    def test_own_hero_get_cached_data(self):
        hero = heroes_logic.load_hero(account_id=self.account_1.id)

        with mock.patch(
                'the_tale.game.heroes.objects.Hero.cached_ui_info_for_hero',
                mock.Mock(
                    return_value={
                        'actual_on_turn': hero.saved_at_turn,
                        'pvp': 'actual',
                        'ui_caching_started_at': 0
                    })) as cached_ui_info_for_hero:
            with mock.patch(
                    'the_tale.game.heroes.objects.Hero.ui_info') as ui_info:
                data = form_game_info(self.account_1, is_own=True)

        self.assertEqual(data['account']['hero']['pvp'], 'actual')
        self.assertEqual(data['enemy'], None)

        self.assertEqual(cached_ui_info_for_hero.call_count, 1)
        self.assertEqual(
            cached_ui_info_for_hero.call_args,
            mock.call(account_id=self.account_1.id,
                      recache_if_required=True,
                      patch_turns=None,
                      for_last_turn=False))
        self.assertEqual(ui_info.call_count, 0)
Esempio n. 12
0
    def test_game_info_caching(self):
        self.pvp_create_battle(self.account_1, self.account_2, BATTLE_1X1_STATE.PROCESSING)
        self.pvp_create_battle(self.account_2, self.account_1, BATTLE_1X1_STATE.PROCESSING)

        hero_1 = heroes_logic.load_hero(account_id=self.account_1.id)
        hero_2 = heroes_logic.load_hero(account_id=self.account_2.id)

        def get_ui_info(hero, **kwargs):
            if hero.id == hero_1.id:
                return {'actual_on_turn': hero_1.saved_at_turn,
                        'pvp__actual':'actual',
                        'pvp__last_turn':'last_turn',
                        'changed_fields': [],
                        'ui_caching_started_at': 0}
            else:
                return self.create_not_own_ui_info(hero_2)

        with mock.patch('the_tale.game.heroes.objects.Hero.ui_info', get_ui_info):
            data = form_game_info(self.account_1, is_own=True)

        self.assertEqual(data['account']['hero']['pvp'], 'actual')
        self.assertEqual(data['enemy']['hero']['pvp'], 'last_turn')

        self.assertFalse('pvp__actual' in data['account']['hero']['pvp'])
        self.assertFalse('pvp__last_turn' in data['account']['hero']['pvp'])
        self.assertFalse('pvp__actual' in data['enemy']['hero']['pvp'])
        self.assertFalse('pvp__last_turn' in data['enemy']['hero']['pvp'])

        self.assertNotEqual(data['enemy']['hero']['cards'], 'fake')
        self.assertEqual(data['enemy']['hero']['energy']['max'], 0)
        self.assertEqual(data['enemy']['hero']['energy']['value'], 0)
        self.assertEqual(data['enemy']['hero']['energy']['bonus'], 0)
        self.assertEqual(data['enemy']['hero']['energy']['discount'], 0)
Esempio n. 13
0
    def test_pvp_prepairing(self):
        self.pvp_create_battle(self.account_1, self.account_2, state=BATTLE_1X1_STATE.PREPAIRING)
        self.pvp_create_battle(self.account_2, self.account_1, state=BATTLE_1X1_STATE.PREPAIRING)

        data = form_game_info(self.account_1)
        self.assertEqual(data['mode'], 'pve')
        self.assertFalse(data['account']['in_pvp_queue'])
        self.assertEqual(data['enemy'], None)
Esempio n. 14
0
    def test_pvp_in_queue(self):
        self.pvp_create_battle(self.account_1, None)
        self.pvp_create_battle(self.account_2, None)

        data = form_game_info(self.account_1)
        self.assertEqual(data['mode'], 'pve')
        self.assertTrue(data['account']['in_pvp_queue'])
        self.assertEqual(data['enemy'], None)
Esempio n. 15
0
    def test_pvp_in_queue(self):
        self.pvp_create_battle(self.account_1, None)
        self.pvp_create_battle(self.account_2, None)

        data = form_game_info(self.account_1)
        self.assertEqual(data['mode'], 'pve')
        self.assertTrue(data['account']['in_pvp_queue'])
        self.assertEqual(data['enemy'], None)
Esempio n. 16
0
    def test_pvp_prepairing(self):
        self.pvp_create_battle(self.account_1, self.account_2, state=BATTLE_1X1_STATE.PREPAIRING)
        self.pvp_create_battle(self.account_2, self.account_1, state=BATTLE_1X1_STATE.PREPAIRING)

        data = form_game_info(self.account_1)
        self.assertEqual(data['mode'], 'pve')
        self.assertFalse(data['account']['in_pvp_queue'])
        self.assertEqual(data['enemy'], None)
Esempio n. 17
0
    def test_pvp_processing(self):
        self.pvp_create_battle(self.account_1, self.account_2, state=BATTLE_1X1_STATE.PROCESSING)
        self.pvp_create_battle(self.account_2, self.account_1, state=BATTLE_1X1_STATE.PROCESSING)

        data = form_game_info(self.account_1)
        self.assertEqual(data['mode'], 'pvp')
        self.assertFalse(data['account']['in_pvp_queue'])
        self.assertFalse(data['enemy']['in_pvp_queue'])

        self.assertEqual(data['account']['id'], self.account_1.id)
        self.assertEqual(data['enemy']['id'], self.account_2.id)
Esempio n. 18
0
    def test_pvp_processing(self):
        self.pvp_create_battle(self.account_1, self.account_2, state=BATTLE_1X1_STATE.PROCESSING)
        self.pvp_create_battle(self.account_2, self.account_1, state=BATTLE_1X1_STATE.PROCESSING)

        data = form_game_info(self.account_1)
        self.assertEqual(data['mode'], 'pvp')
        self.assertFalse(data['account']['in_pvp_queue'])
        self.assertFalse(data['enemy']['in_pvp_queue'])

        self.assertEqual(data['account']['id'], self.account_1.id)
        self.assertEqual(data['enemy']['id'], self.account_2.id)
Esempio n. 19
0
    def test_game_info_data_hidding(self):
        '''
        player hero always must show actual data
        enemy hero always must show data on statrt of the turn
        '''
        self.pvp_create_battle(self.account_1, self.account_2, BATTLE_1X1_STATE.PROCESSING)
        self.pvp_create_battle(self.account_2, self.account_1, BATTLE_1X1_STATE.PROCESSING)

        self.storage = LogicStorage()
        self.storage.load_account_data(self.account_1)
        self.storage.load_account_data(self.account_2)

        hero_1 = self.storage.accounts_to_heroes[self.account_1.id]
        hero_2 = self.storage.accounts_to_heroes[self.account_2.id]

        meta_action_battle = meta_actions.ArenaPvP1x1.create(self.storage, hero_1, hero_2)
        meta_action_battle.set_storage(self.storage)

        action_prototypes.ActionMetaProxyPrototype.create(hero=hero_1, _bundle_id=hero_1.actions.current_action.bundle_id, meta_action=meta_action_battle)
        action_prototypes.ActionMetaProxyPrototype.create(hero=hero_2, _bundle_id=hero_1.actions.current_action.bundle_id, meta_action=meta_action_battle)

        meta_action_battle.hero_1_pvp.set_energy(1)
        meta_action_battle.hero_2_pvp.set_energy(2)

        heroes_logic.save_hero(hero_1)
        heroes_logic.save_hero(hero_2)

        data = form_game_info(self.account_1, is_own=True)

        self.assertEqual(data['account']['hero']['action']['data']['pvp']['energy'], 1)
        self.assertEqual(data['enemy']['hero']['action']['data']['pvp']['energy'], 0)

        meta_action_battle.hero_2_pvp.store_turn_data()
        heroes_logic.save_hero(hero_2)

        data = form_game_info(self.account_1, is_own=True)

        self.assertEqual(data['enemy']['hero']['action']['data']['pvp']['energy'], 2)
Esempio n. 20
0
    def test_own_hero_get_cached_data(self):
        hero = heroes_logic.load_hero(account_id=self.account_1.id)

        with mock.patch('the_tale.game.heroes.objects.Hero.cached_ui_info_for_hero',
                        mock.Mock(return_value={'actual_on_turn': hero.saved_at_turn,
                                                'pvp':'actual',
                                                'ui_caching_started_at': 0})) as cached_ui_info_for_hero:
            with mock.patch('the_tale.game.heroes.objects.Hero.ui_info') as ui_info:
                data = form_game_info(self.account_1, is_own=True)

        self.assertEqual(data['account']['hero']['pvp'], 'actual')
        self.assertEqual(data['enemy'], None)

        self.assertEqual(cached_ui_info_for_hero.call_count, 1)
        self.assertEqual(cached_ui_info_for_hero.call_args, mock.call(account_id=self.account_1.id, recache_if_required=True, patch_turns=None, for_last_turn=False))
        self.assertEqual(ui_info.call_count, 0)
Esempio n. 21
0
def api_info(context):
    account = context.requested_account

    if account is None and context.account.is_authenticated:
        account = context.account

    data = game_logic.form_game_info(account=account,
                                     is_own=False if account is None else
                                     (context.account.id == account.id),
                                     client_turns=context.client_turns)

    if context.api_version in ('1.8', '1.7', '1.6', '1.5', '1.4', '1.3', '1.2',
                               '1.1', '1.0'):
        data = game_logic.game_info_from_1_9_to_1_8(data)

    if context.api_version in ('1.7', '1.6', '1.5', '1.4', '1.3', '1.2', '1.1',
                               '1.0'):
        data = game_logic.game_info_from_1_8_to_1_7(data)

    if context.api_version in ('1.6', '1.5', '1.4', '1.3', '1.2', '1.1',
                               '1.0'):
        data = game_logic.game_info_from_1_7_to_1_6(data)

    if context.api_version in ('1.5', '1.4', '1.3', '1.2', '1.1', '1.0'):
        data = game_logic.game_info_from_1_6_to_1_5(data)

    if context.api_version in ('1.4', '1.3', '1.2', '1.1', '1.0'):
        data = game_logic.game_info_from_1_5_to_1_4(data)

    if context.api_version in ('1.3', '1.2', '1.1', '1.0'):
        data = game_logic.game_info_from_1_4_to_1_3(data)

    if context.api_version in ('1.2', '1.1', '1.0'):
        data = game_logic.game_info_from_1_3_to_1_2(data)

    if context.api_version in ('1.1', '1.0'):
        data = game_logic.game_info_from_1_2_to_1_1(data)

    if context.api_version == '1.0':
        data = game_logic.game_info_from_1_1_to_1_0(data)

    return dext_views.AjaxOk(content=data)
Esempio n. 22
0
    def test_not_own_hero_get_cached_data(self):
        hero = heroes_logic.load_hero(account_id=self.account_1.id)

        with mock.patch('the_tale.game.heroes.objects.Hero.ui_info',
                        mock.Mock(return_value=self.create_not_own_ui_info(hero))) as ui_info:
            data = form_game_info(self.account_1, is_own=False)

        self.assertEqual(data['account']['hero']['action']['data']['pvp'], 'last_turn')
        self.assertEqual(data['enemy'], None)

        self.assertFalse('pvp__actual' in data['account']['hero']['action']['data']['pvp'])
        self.assertFalse('pvp__last_turn' in data['account']['hero']['action']['data']['pvp'])

        self.assertNotEqual(data['account']['hero']['cards'], 'fake')
        self.assertEqual(data['account']['hero']['energy']['max'], 0)
        self.assertEqual(data['account']['hero']['energy']['value'], 0)
        self.assertEqual(data['account']['hero']['energy']['bonus'], 0)
        self.assertEqual(data['account']['hero']['energy']['discount'], 0)

        self.assertEqual(ui_info.call_count, 1)
        self.assertEqual(ui_info.call_args, mock.call(actual_guaranteed=False))
Esempio n. 23
0
    def test_is_old__pvp(self):
        self.pvp_create_battle(self.account_1, self.account_2, BATTLE_1X1_STATE.PROCESSING)
        self.pvp_create_battle(self.account_2, self.account_1, BATTLE_1X1_STATE.PROCESSING)

        hero_1 = heroes_logic.load_hero(account_id=self.account_1.id)
        hero_2 = heroes_logic.load_hero(account_id=self.account_2.id)

        self.assertFalse(form_game_info(self.account_1)['account']['is_old'])
        self.assertFalse(form_game_info(self.account_1)['enemy']['is_old'])

        TimePrototype(turn_number=666).save()
        self.assertTrue(form_game_info(self.account_1)['account']['is_old'])
        self.assertTrue(form_game_info(self.account_1)['enemy']['is_old'])

        heroes_logic.save_hero(hero_1)
        heroes_logic.save_hero(hero_2)

        self.assertFalse(form_game_info(self.account_1)['account']['is_old'])
        self.assertFalse(form_game_info(self.account_1)['enemy']['is_old'])
Esempio n. 24
0
    def test_is_old__pvp(self):
        self.pvp_create_battle(self.account_1, self.account_2, BATTLE_1X1_STATE.PROCESSING)
        self.pvp_create_battle(self.account_2, self.account_1, BATTLE_1X1_STATE.PROCESSING)

        hero_1 = heroes_logic.load_hero(account_id=self.account_1.id)
        hero_2 = heroes_logic.load_hero(account_id=self.account_2.id)

        self.assertFalse(form_game_info(self.account_1)['account']['is_old'])
        self.assertFalse(form_game_info(self.account_1)['enemy']['is_old'])

        TimePrototype(turn_number=666).save()
        self.assertTrue(form_game_info(self.account_1)['account']['is_old'])
        self.assertTrue(form_game_info(self.account_1)['enemy']['is_old'])

        heroes_logic.save_hero(hero_1)
        heroes_logic.save_hero(hero_2)

        self.assertFalse(form_game_info(self.account_1)['account']['is_old'])
        self.assertFalse(form_game_info(self.account_1)['enemy']['is_old'])
Esempio n. 25
0
    def test_is_old__pvp(self):
        self.pvp_create_battle(self.account_1, self.account_2,
                               BATTLE_1X1_STATE.PROCESSING)
        self.pvp_create_battle(self.account_2, self.account_1,
                               BATTLE_1X1_STATE.PROCESSING)

        hero_1 = HeroPrototype.get_by_account_id(self.account_1.id)
        hero_2 = HeroPrototype.get_by_account_id(self.account_2.id)

        self.assertFalse(form_game_info(self.account_1)['account']['is_old'])
        self.assertFalse(form_game_info(self.account_1)['enemy']['is_old'])

        TimePrototype(turn_number=666).save()
        self.assertTrue(form_game_info(self.account_1)['account']['is_old'])
        self.assertTrue(form_game_info(self.account_1)['enemy']['is_old'])

        hero_1.save()
        hero_2.save()

        self.assertFalse(form_game_info(self.account_1)['account']['is_old'])
        self.assertFalse(form_game_info(self.account_1)['enemy']['is_old'])
Esempio n. 26
0
 def test_account__other(self):
     data = form_game_info(self.account_2, is_own=True)
     self.assertEqual(data['mode'], 'pve')
     self.assertFalse(data['account']['in_pvp_queue'])
     self.assertEqual(data['account']['id'], self.account_2.id)
     self.assertEqual(data['enemy'], None)
Esempio n. 27
0
def api_info(context):
    '''
Информация о текущем ходе и герое

- **адрес:** /game/api/info
- **http-метод:** GET
- **версии:** 1.5
- **параметры:**
    * GET: account — идентификатор аккаунта
    * GET: client_turns — номера ходов, по отношению к которым можно вернуть сокращённую информацию о герое (только изменённые с этого времени поля).
- **возможные ошибки**: нет

Если параметр account не будет указан, то вернётся информация об игре текущего пользователя, а на запрос от неавторизованного пользователя — общая информация об игре (без информации об аккаунте и герое).

Часть информации в ответе является личной и доступна только залогиненному игроку, для остальных на её месте будет валидная с точки зрения формата заглушка. Такая информация обозначена следующим образом: **[личная информация]**.

Полный ответ имеет большой размер, поэтому реализован следующий механизм его сжатия:

- в параметре client_turns можно передать список номеров ходов (через запятую), для которых на клиенте есть полная информация;
- если сервер сможет, в ответе он вернёт только изменившуюся информацию о герое;
- сокращению подвергается только информация в <hero_info>;
- сокращение происходит удалением неизменившихся полей <hero_info> (только на верхнем уровне, без рекурсии);
- чтобы получить полную информацию, скопируйте недостаующие поля из закэшированной на стороне клиента информации для хода, указанного в .account.hero.patch_turn;
- сервер не гарантирует, что вернёт сокращённую информацию;
- сервер может вернуть патч для любого из переданных в client_turns ходов;
- имеет смысл в параметре client_turns передавать последние 2-3 хода;
- обратите внимание, сжатие ответа применяется и к информации о противнике в PvP! Поэтому первый запрос при PvP всегда должен требовать полную информацию.

Формат данных в ответе:

    {
      "mode": "pve"|"pvp",             // режим героя
      "turn": {                        // информация о номере хода
        "number": <целое число>,       // номер хода
        "verbose_date": "строка",      // дата для игроков (в мире Сказки)
        "verbose_time": "строка"       // время для игроков (в мире Сказки)
      },
      "game_state": <целое число>,     // состояние игры (остановлена/запущена, см. в описании API)
      "map_version": "строка",         // версия актуальной карты игры
      "account": <account_info>|null,  // информация о запрашиваемом аккаунте и герое
      "enemy": <account_info>|null     // информация о противнике, если идёт pvp сражение
    }

    <account_info> = {
      "new_messages": <целое число>, // количество личных сообщений
      "id": <целое число>,           // идентификатор аккаунта
      "last_visit": <timestamp>,     // примерное время последнего посещения игры
      "is_own": true|false,          // информация о собственном герое или о чужом
      "is_old": true|false,          // информация устаревшая или нет
      "hero": <hero_info>,           // информация о герое
      "in_pvp_queue": true|false     // находится ли герой в очереди на арену
    }

    <hero_info> = {
      "patch_turn": null|<целое число>,  // номер хода, для которого возвращается патч или null, если информация полная

      "energy":{                      // энергия игрока [личная информация]
            "bonus": <целое число>,   // дополнительная энергия
            "max": <целое число>,     // максимальное количество
            "value": <целое число>,   // текущее количество
            "discount": <целое число> // скидка энергии при её трате (например, от использования артефактов)
      },

      "equipment":{                      // экипировка героя, словарь <идентификатор типа экипировки, информация об артефакте>
        "<целое число>": <artifact_info> // идентификатор типа экипировки: информация об артефакте
      },

      "cards":{                          // карты судьбы [личная информация]
        "cards": [                       // список карт
          <card_info>                    // информация о карте
        ],
        "help_count": <целое число>,     // сколько помощи накоплено для получения новой карты
        "help_barrier": <целое число>    // сколько всего помощи надо накопить для новой карты
      },

      "companion": <companion_info>|null,// информация о спутнике

      "bag":{                            // содержимое рюкзака, словарь <внутренний идентификатор предмета, описание> ()
        "<целое число>": <artifact_info> // идентификатор слота: информация об артефакте
      },

      "base":{                                // базовые параметры героя
        "experience": <целое число>,          // текущий опыт
        "race": <целое число>,                // раса
        "health": <целое число>,              // здоровье
        "name": "строка",                     // имя героя
        "level": <целое число>,               // уровень героя
        "gender": <целое число>,              // пол
        "experience_to_level": <целое число>, // абсолютное количество опыта до следующего уровня
        "max_health": <целое число>,          // максимальное количество здоровья
        "destiny_points": <целое число>       // сколько способностей сейчас может выбрать
        "money": <целое число>,               // количество денег у героя
        "alive": true|false,                  // жив герой или мёртв
      },

      "secondary":{                              // второстепенные параметры
        "max_bag_size": <целое число>,           // максимальный размер рюкзака
        "power": [<целое число>, <целое число>], // физическая сила, магическая сила
        "move_speed": <дробное число>,           // скорость движения
        "loot_items_count": <целое число>,       // количество лута в рюкзаке
        "initiative": <дробное число>            // инициатива героя
      },

      "diary": "строка",       // версия дневника героя, если она изменилась, необходимо перезапросить дневни

      "messages":[             // сообщения из журнала
        [                      // запись в задании
          <timestamp>,         // timestamp создания сообщения
          "строка",            // текстовое описание времени в игре
          "строка",            // текст
          <целое число>|null,  // идентификатор типа фразы, найти идентификатор типа фразы можно в адресе страницы лингвистики с фразами этого типа
          {"строка": "строка"} // словарь соотношения переменных и их значений (ВНИМАНИЕ! перечень переменных может изменяться без изменения версии этого метода)
        ]
      ],

      "habits": { // черты
        "строка": {              // идентификатор черты
          "verbose": "строка",   // текущее текстовое значение черты для игрока (название характера)
          "raw": <дробное число> // текущее числовое значение черты
        }
      },

      "quests": {     // информация о заданиях
        "quests": [   // список глобальных заданий
          {
            "line": [ // список «базовых» заданий (цепочка последовательных заданий)
               {
                 "type": "строка",            // тип задания
                 "uid":  "строка",            // уникальный идентификатор задания
                 "name": "строка",            // название задания
                 "action": "строка",          // описание текущего действия героя в задании
                 "choice": "строка"|null,     // текущий выбор героя в задании
                 "choice_alternatives": [     // альтернативные выборы
                   [
                     "строка",                // уникальный идентификатор выбора
                     "строка"                 // текстовое описание выбора
                   ]
                 ],
                 "experience": <целое число>, // количество опыта за задание
                 "power": <целое число>,      // количество влияния за задание
                 "actors": [                  // список «актёров», участвующих в задании
                   [
                     "строка",                // название актёра
                     <целое число>",                // тип актёра (список типов приведён в описании API)
                     <quest_actor_info>       // данные, специфичные для конкретного типа актёра
                   ]
                 ]
               }
            ]
          }
        ]
      },

      "action":{                     // текущее действие
        "percents": <дробное число>, // процент выполнения
        "description": "строка",     // описание
        "info_link": "url"|null      // ссылка на доп. информацию
        "type": <целое число>        // идентификатор типа действия
        "data": null|<словарь>       // дополнительная информация о действиии или null, если такой нет
      },

      "position":{                      // позиция героя на клеточной карте
        "x": <дробное число>,           // координата x
        "y": <дробное число>,           // координата y
        "dx": <дробное число>,          // направление взгляда по x
        "dy": <дробное число>,          // направленеи взгляда по y
      },

      "permissions": {                        // права на выполнение различных операций
        "can_participate_in_pvp": true|false, // может ли участвовать в pvp
        "can_repair_building": true|false,    // может ли чинить здания
      },

      "might": {                                    // могущество игрока
        "value": <дробное число>,                   // величина
        "crit_chance": <дробное число>,             // вероятность критического срабатывания помощи
        "pvp_effectiveness_bonus": <дробное число>, // бонус к эффективности в pvp от могущества
        "politics_power": <дробное число>            // бонус к политическому влиянию героя
      },

      "id": <целое число>,                             // идентификатор
      "actual_on_turn": <целое число>,                 // данные на какой ход предоставлены

      "sprite": <целое число>  // идентификатор спрайта, которым отображается герой
      }

    <quest_actor_info> = <quest_actor_place_info>|<quest_actor_person_info>|<quest_actor_spending_info>

    <quest_actor_place_info> = { // информация о городе
      "id": <целое числое>,      // идентификатор
      "name": "строка"           // название города
    }

    <quest_actor_person_info> = {     // информация о жителе города
        "id": <целое числое>          // идентификатор
        "name": "строка",             // имя
        "race": <целое числое>,       // раса
        "gender": <целое числое>,     // пол
        "profession": <целое числое>, // профессия
        "mastery_verbose": "строка",  // профессия
        "place": <целое числое>       // идентификатор города
    }

    <quest_actor_spending_info> = { // информация о целях накопления
      "goal": "строка"              // описание цели накопления
    }

    <artifact_info> = {                              // информация об артефакте
        "name": "строка",                            // название
        "power": [<целое число>, <целое число>],     // сила [физическая, магическая]
        "type": <целое число>,                       // тип
        "integrity": [<целое число>, <целое число>], // целостность [текущая, максимальная]
        "rarity": <целое число>,                     // редкость
        "effect": <целое число>,                     // тип эффекта на артефакте
        "special_effect": <целое число>,             // тип особого свойства артефакта (эффекта, который действует независимо от редкости)
        "preference_rating": <дробное число>,        // «полезность» артефакта с точки зрения героя
        "equipped": true|false,                      // может ли быть экипирован
        "id": <целое число>                          // уникальный идентификатор рода артефакта
    }

    <card_info> = {                              // информация о карте в колоде игрока
        "name": "строка",                        // название
        "type": <целое число>,                   // тип
        "rarity": <целое число>,                 // редкость карты
        "uid": <целое число>,                    // уникальный идентификатор в колоде игрока
        "auction": true|false                    // может быть продана на рынке
    }

    <companion_info> = {                         // информация о спутнике героя
        "type": <целое число>,                   // тип спутника
        "name": "строка",                        // название/имя спутника
        "health": <целое число>,                 // текущее здоровье
        "max_health": <целое число>,             // максимальное здоровье
        "experience": <целое число>,             // текущий опыт слаженности
        "experience_to_level": <целое число>,    // опыта до следующего уровня слаженности
        "coherence": <целое число>,              // текущая слаженность
        "real_coherence": <целое число>          // полная слаженность (без учёта ограничений на максимум слаженности)
    }

примечания:

- если информация о герое устаревшая (is_old == true), то следует повторить запрос через несколько секунд (но лучше не злоупотреблять)

    '''
    account = context.requested_account

    if account is None and context.account.is_authenticated:
        account = context.account

    data = game_logic.form_game_info(account=account,
                                     is_own=False if account is None else
                                     (context.account.id == account.id),
                                     client_turns=context.client_turns)

    if context.api_version in ('1.5', '1.4', '1.3', '1.2', '1.1', '1.0'):
        data = game_logic.game_info_from_1_6_to_1_5(data)

    if context.api_version in ('1.4', '1.3', '1.2', '1.1', '1.0'):
        data = game_logic.game_info_from_1_5_to_1_4(data)

    if context.api_version in ('1.3', '1.2', '1.1', '1.0'):
        data = game_logic.game_info_from_1_4_to_1_3(data)

    if context.api_version in ('1.2', '1.1', '1.0'):
        data = game_logic.game_info_from_1_3_to_1_2(data)

    if context.api_version in ('1.1', '1.0'):
        data = game_logic.game_info_from_1_2_to_1_1(data)

    if context.api_version == '1.0':
        data = game_logic.game_info_from_1_1_to_1_0(data)

    return dext_views.AjaxOk(content=data)
Esempio n. 28
0
 def test_no_account(self):
     data = form_game_info()
     self.assertEqual(data['mode'], 'pve')
     self.assertEqual(data['account'], None)
     self.assertEqual(data['enemy'], None)
Esempio n. 29
0
 def test_account__other(self):
     data = form_game_info(self.account_2, is_own=True)
     self.assertEqual(data['mode'], 'pve')
     self.assertFalse(data['account']['in_pvp_queue'])
     self.assertEqual(data['account']['id'], self.account_2.id)
     self.assertEqual(data['enemy'], None)
Esempio n. 30
0
 def test_no_account(self):
     data = form_game_info()
     self.assertEqual(data['mode'], 'pve')
     self.assertEqual(data['account'], None)
     self.assertEqual(data['enemy'], None)
Esempio n. 31
0
def api_info(context):
    '''
Информация о текущем ходе и герое

- **адрес:** /game/api/info
- **http-метод:** GET
- **версии:** 1.5
- **параметры:**
    * GET: account — идентификатор аккаунта
    * GET: client_turns — номера ходов, по отношению к которым можно вернуть сокращённую информацию о герое (только изменённые с этого времени поля).
- **возможные ошибки**: нет

Если параметр account не будет указан, то вернётся информация об игре текущего пользователя, а на запрос от неавторизованного пользователя — общая информация об игре (без информации об аккаунте и герое).

Часть информации в ответе является личной и доступна только залогиненному игроку, для остальных на её месте будет валидная с точки зрения формата заглушка. Такая информация обозначена следующим образом: **[личная информация]**.

Полный ответ имеет большой размер, поэтому реализован следующий механизм его сжатия:

- в параметре client_turns можно передать список номеров ходов (через запятую), для которых на клиенте есть полная информация;
- если сервер сможет, в ответе он вернёт только изменившуюся информацию о герое;
- сокращению подвергается только информация в &lt;hero_info&gt;;
- сокращение происходит удалением неизменившихся полей <hero_info> (только на верхнем уровне, без рекурсии);
- чтобы получить полную информацию, скопируйте недостаующие поля из закэшированной на стороне клиента информации для хода, указанного в .account.hero.patch_turn;
- сервер не гарантирует, что вернёт сокращённую информацию;
- сервер может вернуть патч для любого из переданных в client_turns ходов;
- имеет смысл в параметре client_turns передавать последние 2-3 хода;
- обратите внимание, сжатие ответа применяется и к информации о противнике в PvP! Поэтому первый запрос при PvP всегда должен требовать полную информацию.

Формат данных в ответе:

    {
      "mode": "pve"|"pvp",             // режим героя
      "turn": {                        // информация о номере хода
        "number": <целое число>,       // номер хода
        "verbose_date": "строка",      // дата для игроков (в мире Сказки)
        "verbose_time": "строка"       // время для игроков (в мире Сказки)
      },
      "game_state": <целое число>,     // состояние игры (остановлена/запущена, см. в описании API)
      "map_version": "строка",         // версия актуальной карты игры
      "account": <account_info>|null,  // информация о запрашиваемом аккаунте и герое
      "enemy": <account_info>|null     // информация о противнике, если идёт pvp сражение
    }

    <account_info> = {
      "new_messages": <целое число>, // количество личных сообщений
      "id": <целое число>,           // идентификатор аккаунта
      "last_visit": <timestamp>,     // примерное время последнего посещения игры
      "is_own": true|false,          // информация о собственном герое или о чужом
      "is_old": true|false,          // информация устаревшая или нет
      "hero": <hero_info>,           // информация о герое
      "in_pvp_queue": true|false     // находится ли герой в очереди на арену
    }

    <hero_info> = {
      "patch_turn": null|<целое число>,  // номер хода, для которого возвращается патч или null, если информация полная

      "energy":{                      // энергия игрока [личная информация]
            "bonus": <целое число>,   // дополнительная энергия
            "max": <целое число>,     // максимальное количество
            "value": <целое число>,   // текущее количество
            "discount": <целое число> // скидка энергии при её трате (например, от использования артефактов)
      },

      "equipment":{                      // экипировка героя, словарь <идентификатор типа экипировки, информация об артефакте>
        "<целое число>": <artifact_info> // идентификатор типа экипировки: информация об артефакте
      },

      "cards":{                          // карты судьбы [личная информация]
        "cards": [                       // список карт
          <card_info>                    // информация о карте
        ],
        "help_count": <целое число>,     // сколько помощи накоплено для получения новой карты
        "help_barrier": <целое число>    // сколько всего помощи надо накопить для новой карты
      },

      "companion": <companion_info>|null,// информация о спутнике

      "bag":{                            // содержимое рюкзака, словарь <внутренний идентификатор предмета, описание> ()
        "<целое число>": <artifact_info> // идентификатор слота: информация об артефакте
      },

      "base":{                                // базовые параметры героя
        "experience": <целое число>,          // текущий опыт
        "race": <целое число>,                // раса
        "health": <целое число>,              // здоровье
        "name": "строка",                     // имя героя
        "level": <целое число>,               // уровень героя
        "gender": <целое число>,              // пол
        "experience_to_level": <целое число>, // абсолютное количество опыта до следующего уровня
        "max_health": <целое число>,          // максимальное количество здоровья
        "destiny_points": <целое число>       // сколько способностей сейчас может выбрать
        "money": <целое число>,               // количество денег у героя
        "alive": true|false,                  // жив герой или мёртв
      },

      "secondary":{                              // второстепенные параметры
        "max_bag_size": <целое число>,           // максимальный размер рюкзака
        "power": [<целое число>, <целое число>], // физическая сила, магическая сила
        "move_speed": <дробное число>,           // скорость движения
        "loot_items_count": <целое число>,       // количество лута в рюкзаке
        "initiative": <дробное число>            // инициатива героя
      },

      "diary": "строка",       // версия дневника героя, если она изменилась, необходимо перезапросить дневни

      "messages":[             // сообщения из журнала
        [                      // запись в задании
          <timestamp>,         // timestamp создания сообщения
          "строка",            // текстовое описание времени в игре
          "строка",            // текст
          <целое число>|null,  // идентификатор типа фразы, найти идентификатор типа фразы можно в адресе страницы лингвистики с фразами этого типа
          {"строка": "строка"} // словарь соотношения переменных и их значений (ВНИМАНИЕ! перечень переменных может изменяться без изменения версии этого метода)
        ]
      ],

      "habits": { // черты
        "строка": {              // идентификатор черты
          "verbose": "строка",   // текущее текстовое значение черты для игрока (название характера)
          "raw": <дробное число> // текущее числовое значение черты
        }
      },

      "quests": {     // информация о заданиях
        "quests": [   // список глобальных заданий
          {
            "line": [ // список «базовых» заданий (цепочка последовательных заданий)
               {
                 "type": "строка",            // тип задания
                 "uid":  "строка",            // уникальный идентификатор задания
                 "name": "строка",            // название задания
                 "action": "строка",          // описание текущего действия героя в задании
                 "choice": "строка"|null,     // текущий выбор героя в задании
                 "choice_alternatives": [     // альтернативные выборы
                   [
                     "строка",                // уникальный идентификатор выбора
                     "строка"                 // текстовое описание выбора
                   ]
                 ],
                 "experience": <целое число>, // количество опыта за задание
                 "power": <целое число>,      // количество влияния за задание
                 "actors": [                  // список «актёров», участвующих в задании
                   [
                     "строка",                // название актёра
                     <целое число>",                // тип актёра (список типов приведён в описании API)
                     <quest_actor_info>       // данные, специфичные для конкретного типа актёра
                   ]
                 ]
               }
            ]
          }
        ]
      },

      "action":{                     // текущее действие
        "percents": <дробное число>, // процент выполнения
        "description": "строка",     // описание
        "info_link": "url"|null      // ссылка на доп. информацию
        "type": <целое число>        // идентификатор типа действия
        "data": null|<словарь>       // дополнительная информация о действиии или null, если такой нет
      },

      "position":{                      // позиция героя на клеточной карте
        "x": <дробное число>,           // координата x
        "y": <дробное число>,           // координата y
        "dx": <дробное число>,          // направление взгляда по x
        "dy": <дробное число>,          // направленеи взгляда по y
      },

      "permissions": {                        // права на выполнение различных операций
        "can_participate_in_pvp": true|false, // может ли участвовать в pvp
        "can_repair_building": true|false,    // может ли чинить здания
      },

      "might": {                                    // могущество игрока
        "value": <дробное число>,                   // величина
        "crit_chance": <дробное число>,             // вероятность критического срабатывания помощи
        "pvp_effectiveness_bonus": <дробное число>, // бонус к эффективности в pvp от могущества
        "politics_power": <дробное число>            // бонус к политическому влиянию героя
      },

      "id": <целое число>,                             // идентификатор
      "actual_on_turn": <целое число>,                 // данные на какой ход предоставлены

      "sprite": <целое число>  // идентификатор спрайта, которым отображается герой
      }

    <quest_actor_info> = <quest_actor_place_info>|<quest_actor_person_info>|<quest_actor_spending_info>

    <quest_actor_place_info> = { // информация о городе
      "id": <целое числое>,      // идентификатор
      "name": "строка"           // название города
    }

    <quest_actor_person_info> = {     // информация о жителе города
        "id": <целое числое>          // идентификатор
        "name": "строка",             // имя
        "race": <целое числое>,       // раса
        "gender": <целое числое>,     // пол
        "profession": <целое числое>, // профессия
        "mastery_verbose": "строка",  // профессия
        "place": <целое числое>       // идентификатор города
    }

    <quest_actor_spending_info> = { // информация о целях накопления
      "goal": "строка"              // описание цели накопления
    }

    <artifact_info> = {                              // информация об артефакте
        "name": "строка",                            // название
        "power": [<целое число>, <целое число>],     // сила [физическая, магическая]
        "type": <целое число>,                       // тип
        "integrity": [<целое число>, <целое число>], // целостность [текущая, максимальная]
        "rarity": <целое число>,                     // редкость
        "effect": <целое число>,                     // тип эффекта на артефакте
        "special_effect": <целое число>,             // тип особого свойства артефакта (эффекта, который действует независимо от редкости)
        "preference_rating": <дробное число>,        // «полезность» артефакта с точки зрения героя
        "equipped": true|false,                      // может ли быть экипирован
        "id": <целое число>                          // уникальный идентификатор рода артефакта
    }

    <card_info> = {                              // информация о карте в колоде игрока
        "name": "строка",                        // название
        "type": <целое число>,                   // тип
        "rarity": <целое число>,                 // редкость карты
        "uid": <целое число>,                    // уникальный идентификатор в колоде игрока
        "auction": true|false                    // может быть продана на рынке
    }

    <companion_info> = {                         // информация о спутнике героя
        "type": <целое число>,                   // тип спутника
        "name": "строка",                        // название/имя спутника
        "health": <целое число>,                 // текущее здоровье
        "max_health": <целое число>,             // максимальное здоровье
        "experience": <целое число>,             // текущий опыт слаженности
        "experience_to_level": <целое число>,    // опыта до следующего уровня слаженности
        "coherence": <целое число>,              // текущая слаженность
        "real_coherence": <целое число>          // полная слаженность (без учёта ограничений на максимум слаженности)
    }

примечания:

- если информация о герое устаревшая (is_old == true), то следует повторить запрос через несколько секунд (но лучше не злоупотреблять)

    '''
    account = context.requested_account

    if account is None and context.account.is_authenticated:
        account = context.account

    data = game_logic.form_game_info(account=account,
                                     is_own=False if account is None else (context.account.id == account.id),
                                     client_turns=context.client_turns)

    if context.api_version in ('1.5', '1.4', '1.3', '1.2', '1.1', '1.0'):
        data = game_logic.game_info_from_1_6_to_1_5(data)

    if context.api_version in ('1.4', '1.3', '1.2', '1.1', '1.0'):
        data = game_logic.game_info_from_1_5_to_1_4(data)

    if context.api_version in ('1.3', '1.2', '1.1', '1.0'):
        data = game_logic.game_info_from_1_4_to_1_3(data)

    if context.api_version in ('1.2', '1.1', '1.0'):
        data = game_logic.game_info_from_1_3_to_1_2(data)

    if context.api_version in ('1.1', '1.0'):
        data = game_logic.game_info_from_1_2_to_1_1(data)

    if context.api_version == '1.0':
        data = game_logic.game_info_from_1_1_to_1_0(data)

    return dext_views.AjaxOk(content=data)