Ejemplo n.º 1
0
    def _maybe_insert_encounters(self, db: DbWrapper,
                                 dungeon: CrossServerDungeon,
                                 sub_dungeon: CrossServerSubDungeon,
                                 result_floor: ResultFloor):
        sql = 'SELECT count(*) FROM encounters WHERE dungeon_id={} and sub_dungeon_id={}'.format(
            dungeon.dungeon_id, sub_dungeon.sub_dungeon_id)
        encounter_count = db.get_single_value(sql, int)
        if encounter_count:
            logger.debug('Skipping encounter insert for {}-{}'.format(
                dungeon.dungeon_id, sub_dungeon.sub_dungeon_id))
            return

        logger.warning('Executing encounter insert for {}-{}'.format(
            dungeon.dungeon_id, sub_dungeon.sub_dungeon_id))
        for stage in result_floor.stages:
            for slot in stage.slots:
                csc = self.data.card_by_monster_id(slot.monster_id)
                card = csc.jp_card.card
                enemy = card.enemy()

                turns = card.enemy_turns
                if dungeon.jp_dungeon.full_dungeon_type == RawDungeonType.TECHNICAL and card.enemy_turns_alt:
                    turns = card.enemy_turns_alt

                sd = sub_dungeon.jp_sub_dungeon
                hp = int(
                    round(sd.hp_mult * enemy.hp.value_at(slot.monster_level)))
                atk = int(
                    round(sd.atk_mult *
                          enemy.atk.value_at(slot.monster_level)))
                defence = int(
                    round(sd.def_mult *
                          enemy.defense.value_at(slot.monster_level)))

                # TODO: add comments based on slot data
                encounter = Encounter(
                    dungeon_id=dungeon.dungeon_id,
                    sub_dungeon_id=sub_dungeon.sub_dungeon_id,
                    enemy_id=slot.monster_id,
                    monster_id=slot.visible_monster_id(),
                    stage=stage.stage_idx,
                    comment_jp=None,
                    comment_na=None,
                    comment_kr=None,
                    amount=slot.min_spawn
                    if slot.min_spawn == slot.max_spawn else None,
                    order_idx=slot.order,
                    turns=turns,
                    level=slot.monster_level,
                    hp=hp,
                    atk=atk,
                    defence=defence)

                db.insert_or_update(encounter, force_insert=True)

                drops = Drop.from_slot(slot, encounter)
                for drop in drops:
                    db.insert_or_update(drop)
    def process(self, db: DbWrapper):
        print('Starting deletion of old records')
        print('schedule size:',
              db.get_single_value('select count(*) from schedule'))
        print('deleted_rows size',
              db.get_single_value('select count(*) from deleted_rows'))

        # This is a hint to mysql that we shouldn't insert into deleted_rows
        # while purging. The client should handle deleting old events in bulk.
        db.fetch_data('set @TRIGGER_DISABLED=true')

        delete_timestamp = date2tstamp(datetime.now() - timedelta(weeks=4))
        print('deleting before', delete_timestamp)
        schedule_deletes = db.update_item(
            "DELETE FROM `schedule` WHERE end_timestamp < {}".format(
                delete_timestamp))
        deleted_row_deletes = db.update_item(
            "DELETE FROM `deleted_rows` WHERE tstamp < {}".format(
                delete_timestamp))

        logger.info("purged {} old schedules and {} old deleted_rows".format(
            schedule_deletes, deleted_row_deletes))
Ejemplo n.º 3
0
 def process(self, db: DbWrapper):
     logger.warning('timestamp update of %s tables', len(_UPDATE_TABLES))
     for table in _UPDATE_TABLES:
         max_tstamp_sql = 'SELECT MAX(tstamp) AS tstamp FROM `{}`'.format(
             table)
         tstamp = db.get_single_value(max_tstamp_sql, op=int)
         update_sql = "INSERT INTO timestamps (name, tstamp) values ('{}', {}) ON DUPLICATE KEY UPDATE tstamp = {}".format(
             table, tstamp, tstamp)
         rows_updated = db.update_item(update_sql)
         if rows_updated:
             logger.info('Updated tstamp for {} to {}'.format(
                 table, tstamp))
     logger.warning('done updating timestamps')
 def _process_auto_override(self, db: DbWrapper):
     logger.info('checking for auto name overrides')
     for m in self.data.ownable_cards:
         name = m.na_card.card.name
         name_clean = remove_diacritics(name)
         if name != name_clean:
             existing_name = db.get_single_value(
                 'select name_en_override from monsters where monster_id = {}'.format(m.monster_id),
                 fail_on_empty=False)
             if not existing_name:
                 logger.info('applying name override (%s): %s -> %s', m.monster_id, name, name_clean)
                 db.update_item('update monsters set name_en_override = "{}" where monster_id = {}'.format(
                     name_clean, m.monster_id))
Ejemplo n.º 5
0
def pull_data(args):
    if args.logsql:
        logging.getLogger('database').setLevel(logging.DEBUG)

    server = args.server.upper()
    endpoint = None
    if server == 'NA':
        endpoint = pad_api.ServerEndpoint.NA
    elif server == 'JP':
        endpoint = pad_api.ServerEndpoint.JA
    else:
        raise Exception('unexpected server:' + args.server)

    api_client = pad_api.PadApiClient(endpoint, args.user_uuid,
                                      args.user_intid)

    print('login')
    api_client.login()

    print('load_player_data')
    api_client.load_player_data()

    friend_card = api_client.get_any_card_except_in_cur_deck()
    dungeon_id = args.dungeon_id
    floor_id = args.floor_id
    loop_count = args.loop_count
    pull_id = int(time.time())

    print('Connecting to database')
    with open(args.db_config) as f:
        db_config = json.load(f)

    dry_run = False
    db_wrapper = DbWrapper(dry_run)
    db_wrapper.connect(db_config)
    entry_id = int(
        db_wrapper.get_single_value("SELECT MAX(entry_id) FROM wave_data;"))

    print('entering dungeon', dungeon_id, 'floor', floor_id, loop_count,
          'times')
    for e_idx in range(loop_count):
        print('entering', e_idx)
        entry_id += 1
        entry_json = api_client.enter_dungeon(dungeon_id,
                                              floor_id,
                                              self_card=friend_card)
        wave_response = pad_api.extract_wave_response_from_entry(entry_json)
        leaders = entry_json['entry_leads']

        for stage_idx, floor in enumerate(wave_response.floors):
            for monster_idx, monster in enumerate(floor.monsters):
                wave_item = WaveItem(pull_id=pull_id,
                                     entry_id=entry_id,
                                     server=server,
                                     dungeon_id=dungeon_id,
                                     floor_id=floor_id,
                                     stage=stage_idx,
                                     slot=monster_idx,
                                     monster=monster,
                                     leader_id=leaders[0],
                                     friend_id=leaders[1])
                db_wrapper.insert_item(wave_item.insert_sql())

        if server != 'NA':
            time.sleep(.5)
Ejemplo n.º 6
0
    def _maybe_insert_encounters(self,
                                 db: DbWrapper,
                                 dungeon: CrossServerDungeon,
                                 sub_dungeon: CrossServerSubDungeon,
                                 result_floor: ResultFloor):
        for stage in result_floor.stages:
            seen_enemies = set()
            for slot in stage.slots:
                csc = self.data.card_by_monster_id(slot.monster_id)
                card = csc.cur_card.card
                enemy = card.enemy()
                seen_enemies.add(slot.monster_id)

                turns = card.enemy_turns
                if dungeon.cur_dungeon.full_dungeon_type == RawDungeonType.TECHNICAL and card.enemy_turns_alt:
                    turns = card.enemy_turns_alt

                sd = sub_dungeon.cur_sub_dungeon
                hp = int(round(sd.hp_mult * enemy.hp.value_at(slot.monster_level)))
                atk = int(round(sd.atk_mult * enemy.atk.value_at(slot.monster_level)))
                defence = int(round(sd.def_mult * enemy.defense.value_at(slot.monster_level)))
                exp = int(round(enemy.xp.value_at(slot.monster_level)))

                # TODO: add comments based on slot data
                encounter = Encounter(
                    dungeon_id=dungeon.dungeon_id,
                    sub_dungeon_id=sub_dungeon.sub_dungeon_id,
                    enemy_id=slot.monster_id,
                    monster_id=slot.visible_monster_id(),
                    stage=stage.stage_idx,
                    comment_jp=None,
                    comment_na=None,
                    comment_kr=None,
                    amount=slot.min_spawn if slot.min_spawn == slot.max_spawn else None,
                    order_idx=slot.order,
                    turns=turns,
                    level=slot.monster_level,
                    hp=hp,
                    atk=atk,
                    defence=defence,
                    exp=exp)

                sql = '''
                    SELECT encounter_id 
                    FROM encounters 
                    WHERE dungeon_id={} 
                    AND sub_dungeon_id={}
                    AND stage={}
                    AND enemy_id={}
                    AND level={}
                '''.format(dungeon.dungeon_id, sub_dungeon.sub_dungeon_id, stage.stage_idx,
                           slot.monster_id, slot.monster_level)
                stored_encounter_id = db.get_single_value(sql, int, fail_on_empty=False)

                if stored_encounter_id:
                    encounter.encounter_id = stored_encounter_id

                db.insert_or_update(encounter)

                drops = Drop.from_slot(slot, encounter)
                for drop in drops:
                    db.insert_or_update(drop)

            if seen_enemies:
                sql = '''
                    SELECT encounter_id, enemy_id
                    FROM encounters
                    WHERE dungeon_id={}
                    AND sub_dungeon_id={}
                    AND stage={}
                    AND enemy_id not in ({})
                    '''.format(dungeon.dungeon_id, sub_dungeon.sub_dungeon_id, stage.stage_idx,
                               ','.join(map(str, seen_enemies)))
                self._print_bad_enemies('in-stage', dungeon, sub_dungeon, db, sql)

        # In case there are missing stages (e.g. no more invades/commons)
        seen_stage_indexes = [stage.stage_idx for stage in result_floor.stages]
        sql = '''
            SELECT encounter_id, enemy_id
            FROM encounters
            WHERE dungeon_id={}
            AND sub_dungeon_id={}
            AND stage not in ({})
            '''.format(dungeon.dungeon_id, sub_dungeon.sub_dungeon_id, ','.join(map(str, seen_stage_indexes)))
        self._print_bad_enemies('out-stage', dungeon, sub_dungeon, db, sql)
Ejemplo n.º 7
0
    def _maybe_insert_encounters(self, db: DbWrapper,
                                 dungeon: CrossServerDungeon,
                                 sub_dungeon: CrossServerSubDungeon,
                                 result_floor: ResultFloor):
        for stage in result_floor.stages:
            seen_enemies = set()
            for slot in stage.slots:
                csc = self.data.card_by_monster_id(slot.monster_id)
                card = csc.jp_card.card
                enemy = card.enemy()
                seen_enemies.add(slot.monster_id)

                turns = card.enemy_turns
                if dungeon.jp_dungeon.full_dungeon_type == RawDungeonType.TECHNICAL and card.enemy_turns_alt:
                    turns = card.enemy_turns_alt

                sd = sub_dungeon.jp_sub_dungeon
                hp = int(
                    round(sd.hp_mult * enemy.hp.value_at(slot.monster_level)))
                atk = int(
                    round(sd.atk_mult *
                          enemy.atk.value_at(slot.monster_level)))
                defence = int(
                    round(sd.def_mult *
                          enemy.defense.value_at(slot.monster_level)))

                # TODO: add comments based on slot data
                encounter = Encounter(
                    dungeon_id=dungeon.dungeon_id,
                    sub_dungeon_id=sub_dungeon.sub_dungeon_id,
                    enemy_id=slot.monster_id,
                    monster_id=slot.visible_monster_id(),
                    stage=stage.stage_idx,
                    comment_jp=None,
                    comment_na=None,
                    comment_kr=None,
                    amount=slot.min_spawn
                    if slot.min_spawn == slot.max_spawn else None,
                    order_idx=slot.order,
                    turns=turns,
                    level=slot.monster_level,
                    hp=hp,
                    atk=atk,
                    defence=defence)

                sql = '''
                    SELECT encounter_id 
                    FROM encounters 
                    WHERE dungeon_id={} 
                    AND sub_dungeon_id={}
                    AND stage={}
                    AND enemy_id={}
                '''.format(dungeon.dungeon_id, sub_dungeon.sub_dungeon_id,
                           stage.stage_idx, slot.monster_id)
                stored_encounter_id = db.get_single_value(sql,
                                                          int,
                                                          fail_on_empty=False)

                if stored_encounter_id:
                    encounter.encounter_id = stored_encounter_id

                db.insert_or_update(encounter)

                drops = Drop.from_slot(slot, encounter)
                for drop in drops:
                    db.insert_or_update(drop)

            if seen_enemies:
                sql = '''
                    SELECT encounter_id, enemy_id
                    FROM encounters
                    WHERE dungeon_id={}
                    AND sub_dungeon_id={}
                    AND stage={}
                    AND enemy_id not in ({})
                    '''.format(dungeon.dungeon_id, sub_dungeon.sub_dungeon_id,
                               stage.stage_idx,
                               ','.join(map(str, seen_enemies)))
                bad_stored_encounters = db.fetch_data(sql)
                if bad_stored_encounters:
                    encounter_list_str = ','.join([
                        str(x['encounter_id']) for x in bad_stored_encounters
                    ])
                    delete_drops_sql = 'DELETE FROM drops WHERE encounter_id IN ({});'.format(
                        encounter_list_str)
                    delete_encounters_sql = 'DELETE FROM encounters WHERE encounter_id IN ({});'.format(
                        encounter_list_str)
                    human_fix_logger.warning(
                        'Found bad stored encounters for %s: [%s] - %s\n%s\n%s',
                        dungeon.na_dungeon.clean_name,
                        sub_dungeon.na_sub_dungeon.clean_name,
                        encounter_list_str, delete_drops_sql,
                        delete_encounters_sql)