def __init__(self, filename=None, file_type='packet', string_input=False): def gen_card(c, equip=True): card = raw_card_dict[c['card_id']].copy() card.idolize(c['idolized']) card.level_up(*[ c[attr] for attr in ['skill_level', 'slot_num', 'level', 'bond'] ]) if equip: card.equip_gem(c['equipped_gems']) return card if filename is None: self.raw_card = raw_card_dict self.owned_card = card_dataframe(raw_card_dict) self.owned_gem = {k: 0 for k in list(gem_skill_id_dict.values())} self.team_list = [] else: try: if file_type == 'packet': card_info, gem_owning_info, deck_info = self.get_user_packet_info( filename) elif file_type == 'ieb': card_info, gem_owning_info, deck_info = self.get_ieb_info( filename, string_input) elif file_type == 'pll': card_info, gem_owning_info, deck_info = self.get_pll_info( filename, string_input) elif file_type == 'minaraishi': card_info, gem_owning_info, deck_info = self.get_minaraishi_info( filename, string_input) elif file_type == 'SIT': card_info, gem_owning_info, deck_info = self.get_SIT_info( filename, string_input) else: print( 'Incorrect file type {0}. Please choose packet or ieb'. format(file_type)) raise # Owned skill gems of user self.owned_gem = { k: 0 for k in list(gem_skill_id_dict.values()) } self.owned_gem.update(gem_owning_info) # Owned cards of user: dict of gem-unequipped cards self.raw_card = { k: gen_card(c, equip=False) for k, c in card_info.items() if c['card_id'] != '0' } self.owned_card = card_dataframe(self.raw_card) # Teams of user: list of gem-equipped cards self.team_list = [ None if deck is None else Team( [gen_card(c, equip=True) for c in deck]) for deck in deck_info ] except: print( 'Failed to generate user information from profile file{0}!' .format(' ' + filename if not string_input else ''))
def get_SIT_info(self, SIT_file, string_input=False): def get_card_levelup_info(card_info): card_id = str(card_info['card']['id']) card = raw_card_dict[card_id].copy() card.idolize(card_info['idolized']) res = { 'unit_id': card_info['card']['game_id'], 'card_id': card_id, 'idolized': card.idolized, 'level': card.level, 'bond': card.bond, 'skill_level': card_info['skill'], 'slot_num': card_info['skill_slots'], 'equipped_gems': [] } return res SIT_info = json.loads( SIT_file if string_input else open(SIT_file).read()) # Generate user card information card_info, index = dict(), 1 for item in SIT_info: card_id = item['card']['id'] try: card_info[str(index)] = get_card_levelup_info(item) index += 1 except: print( 'Cannot generate card level-up info from card id, maybe it is a promo card', card_id) gem_owning_info, deck_info = { gem: 9 for gem in list(gem_skill_id_dict.values()) }, [] return card_info, gem_owning_info, deck_info
def get_pll_info(self, pll_file, string_input=False): def get_card_levelup_info(card_info): res = { 'unit_id': str(card_info['unit_id']), 'card_id': uid_cid_dict[str(card_info['unit_id'])], 'idolized': card_info['rank'] == 2, 'level': card_info['level'], 'bond': card_info['love'], 'skill_level': card_info['unit_skill_level'], 'slot_num': card_info['unit_removable_skill_capacity'], 'equipped_gems': [] } return res pll_info = json.loads( pll_file if string_input else open(pll_file).read()) # Generate user card information card_info, owning_id_dict = dict(), dict() error_capture = '' for i, card in enumerate(pll_info['unit_info'], 1): try: card_info[str(i)] = get_card_levelup_info(card) owning_id_dict[str(card['unit_owning_user_id'])] = str(i) except: if error_capture == '': error_capture += pll_file print('{0} is not in uid_cid_dict, please update {1}'.format( card['unit_id'], unit_db_dir)) # if error_capture != '': print(error_capture) for key, equip_info in pll_info['removable_info'][ 'equipment_info'].items(): value = [ x['unit_removable_skill_id'] for x in equip_info['detail'] ] card_info[owning_id_dict[key]]['equipped_gems'] = [ gem_skill_id_dict[x] for x in value ] # Generate user gem information gem_owning_info = { skill_name: 0 for skill_name in list(gem_skill_id_dict.values()) } for x in pll_info['removable_info']['owning_info']: skill_name = gem_skill_id_dict[x['unit_removable_skill_id']] gem_owning_info[skill_name] = x['total_amount'] # Generate user team information deck_info = [] for i, deck in enumerate(pll_info['deck_info'], 1): ids = [ card_info[owning_id_dict[str(x['unit_owning_user_id'])]] for x in deck['unit_owning_user_ids'] ] if len(ids) == 9: deck_info.append(ids) else: print('Invalid team: {0}-th team only has {1} members placed'. format(i, len(ids))) deck_info.append(None) return card_info, gem_owning_info, deck_info
def get_user_packet_info(self, packet_file): def load_packets(packet_file): def fix_file(file_name): text = open(file_name).read() lines, last = text.split('\n'), None if lines[-1] != ']': # When the packet file is broken, drop the last incomplete packet for i, line in enumerate(reversed(lines)): if '},' == line.strip(): indent, last = len(line) - len( line.lstrip()) - 2, len(lines) - i - 1 lines[last] = line.replace(',', '') break if last is not None: lines = lines[:last + 1] + [ ' ' * i + '}' for i in range(indent, 0, -2) ] + ['', ']'] text = '\n'.join(lines) return text def extract_json(packet): if packet['_source']['layers'].get('http') is None or packet[ '_source']['layers']['http'].get( "http.file_data") is None: return None text = packet['_source']['layers']['http']['http.file_data'] text = text[text.find('{'):text.rfind('}') + 1] try: return eval( text.replace('true', 'True').replace('false', 'False').replace( 'null', 'None')) except: return None packets = json.loads(fix_file(packet_file)) is_response_data = lambda item: False if item is None else (type( item) == dict and item.get('response_data') is not None) responses = [ x for x in [extract_json(packet) for packet in packets] if is_response_data(x) ] for resp in responses: resp_data = resp['response_data'] if type(resp_data) == list and len( resp_data) > 0 and resp_data[0]['result'].get( 'present_cnt') is not None: useful_info = resp_data result, profile = dict(), dict() for item in useful_info: temp = item['result'] if temp == []: continue elif type(temp) == dict and temp.get( 'equipment_info') is not None: result['gem_equip_info'] = temp['equipment_info'] result['gem_owning_info'] = temp['owning_info'] profile['removable_info'] = temp elif type(temp) == list: if temp[0].get('display_rank') is not None: result['card_owning_info'] = temp profile['unit_info'] = temp elif temp[0].get('deck_name') is not None: result['deck_info'] = temp profile['deck_info'] = temp with open('packet_to_json.json', 'w') as fp: fp.write(json.dumps(profile)) return result def get_card_levelup_info(card_info): res = { 'unit_id': str(card_info['unit_id']), 'card_id': uid_cid_dict[str(card_info['unit_id'])], 'idolized': card_info['rank'] == 2, 'level': card_info['level'], 'bond': card_info['love'], 'skill_level': card_info['unit_skill_level'], 'slot_num': card_info['unit_removable_skill_capacity'], 'equipped_gems': [] } return res # Load packet file temp = load_packets(packet_file) # Generate user card information card_info, owning_id_dict = dict(), dict() for i, card in enumerate(temp['card_owning_info'], 1): try: card_info[str(i)] = get_card_levelup_info(card) owning_id_dict[str(card['unit_owning_user_id'])] = str(i) except: print('{0} is not in uid_cid_dict, please update {1}'.format( card['unit_id'], self.unit_db_file)) for key, value in temp['gem_equip_info'].items(): card_info[owning_id_dict[key]]['equipped_gems'] = [ gem_skill_id_dict[x['unit_removable_skill_id']] for x in value['detail'] ] # Generate user gem information gem_owning_info = { skill_name: 0 for skill_name in list(gem_skill_id_dict.values()) } for x in temp['gem_owning_info']: skill_name = gem_skill_id_dict[x['unit_removable_skill_id']] gem_owning_info[skill_name] = x['total_amount'] # Generate user team information deck_info = [] for deck in temp['deck_info']: ids = [ card_info[owning_id_dict[str(x['unit_owning_user_id'])]] for x in deck['unit_owning_user_ids'] ] deck_info.append(ids) return card_info, gem_owning_info, deck_info