def parse_visit_data(data): friend = data['friend'] monsters = friend['unit_list'] storage_id = None wizard_id = 'unknown' for building in friend['building_list']: wizard_id = building['wizard_id'] if building['building_master_id'] == 25: storage_id = building['building_id'] break monsters.sort(key = lambda mon: (1 if mon['building_id'] == storage_id else 0, 6 - mon['class'], 40 - mon['unit_level'], mon['attribute'], mon['unit_id'])) with open("visit-" + str(wizard_id) + ".json", "w") as f: f.write(json.dumps(data, indent=4)) with open("visit-" + str(wizard_id) + "-monsters.csv", "wb") as visit_file: visit_fieldnames = ['wizard_name', 'name', 'grade', 'level', 'attribute', 'in_storage', 'hp', 'atk', 'hp', 'def', 'spd', 'crate', 'cdmg', 'res', 'acc', 'slot', 'rune_set','rune_grade','rune_level', 'pri_eff','pre_eff','sub1','sub2','sub3','sub4'] visit_header = {'wizard_name': 'Wizard Name','name': 'Name','level': 'Level','grade': 'Stars', 'attribute': 'Attribute','in_storage': 'In Storage','hp' : 'hp', 'atk': 'atk', 'def': 'def', 'spd': 'spd', 'crate':'cri rate', 'cdmg': 'cri dmg', 'res': 'resistance', 'acc': 'accuracy', 'rune_set': 'Rune set', 'slot': 'Slot No', 'rune_grade': 'Stars', 'rune_level': 'level', 'pri_eff': 'Primary effect', 'pre_eff': 'Prefix effect', 'sub1': 'First Substat', 'sub2': 'Second Substat', 'sub3': 'Third Substat', 'sub4': 'Fourth Substat', } SWPlugin.call_plugins('process_csv_row', ('visit', 'header', (visit_fieldnames, visit_header))) visit_writer = DictUnicodeWriter(visit_file, fieldnames=visit_fieldnames) visit_writer.writerow(visit_header) for monster in monsters: _, monster_csv = map_monster(monster, None, storage_id, friend['wizard_name']) SWPlugin.call_plugins('process_csv_row', ('visit', 'monster', (monster, monster_csv))) visit_writer.writerow(monster_csv) monster_runes = monster['runes'] if isinstance(monster_runes, dict): monster_runes = monster_runes.values() monster_runes.sort(key = lambda r: r['slot_no']) for rune in monster_runes: _, rune_map = map_rune(rune, None) SWPlugin.call_plugins('process_csv_row', ('visit', 'rune', (rune, rune_map))) visit_writer.writerow(rune_map) visit_footer = [] SWPlugin.call_plugins('process_csv_row', ('visit', 'footer', visit_footer)) if len(visit_footer) > 0: visit_writer.writerows(visit_footer)
def log_summon(self, req_json, resp_json, config): if not config["log_summon"]: return wizard_id = str(resp_json['wizard_info']['wizard_id']) if 'unit_list' in resp_json: if 'item_info' in resp_json: scroll = identify_scroll(resp_json['item_info']['item_master_id']) else: mode = req_json['mode'] if mode == 3: scroll = 'Crystal' elif mode == 5: scroll = 'Social' else: scroll = 'Unidentified' filename = "%s-summons.csv" % wizard_id is_new_file = not os.path.exists(filename) with open(filename, "ab") as log_file: field_names = ['date', 'scroll', 'unit_name', 'attribute', 'grade', 'awake'] header = {'date': 'Date', 'scroll': 'Scroll', 'unit_name': 'Unit', 'attribute': 'Attribute', 'grade': 'Grade', 'awake': 'Awakened'} SWPlugin.call_plugins('process_csv_row', ('summon_logger', 'header', (field_names, header))) log_writer = DictUnicodeWriter(log_file, fieldnames=field_names) if is_new_file: log_writer.writerow(header) if 'unit_list' in resp_json and len(resp_json['unit_list']) > 0: for i in range(0, len(resp_json['unit_list'])): unit_name = monster_name(resp_json['unit_list'][i]['unit_master_id'],'',False) attribute = monster_attribute(resp_json['unit_list'][i]['attribute']) grade = resp_json['unit_list'][i]['class'] awakened = str(resp_json['unit_list'][i]['unit_master_id']) if int(awakened[-2]) == 0: awake = 'No' else: awake = 'Yes' log_entry = {'date': time.strftime("%Y-%m-%d %H:%M"), 'scroll': scroll, 'unit_name': unit_name, 'attribute': attribute, 'grade': grade, 'awake': awake} SWPlugin.call_plugins('process_csv_row', ('summon_logger', 'entry', (field_names, log_entry))) log_writer.writerow(log_entry) return
def response(self, flow: http.HTTPFlow) -> None: if self.sw_request is None: return try: req_plain, req_json = self._parse_request(flow) resp_plain, resp_json = self._parse_response(flow) if 'command' not in resp_json: self.sw_request = None return try: SWPlugin.call_plugins('process_request', (req_json, resp_json)) except Exception as e: ctx.log.error(f"Exception while executing plugin : {e}") except Exception as e: ctx.log.error(f"Unknown exception {e}")
def onResponse(self, proxy, response): if self.request is None: # we have not obtained a valid request yet return try: req_plain, req_json = self._parse_request(self.request) resp_plain, resp_json = self._parse_response(response) if 'command' not in resp_json: # we only want apis that are commands self.request = None return try: SWPlugin.call_plugins('process_request', (req_json, resp_json)) except Exception as e: logger.exception('Exception while executing plugin : {}'.format(e)) except Exception as e: logger.debug('unknown exception: {}'.format(e))
def onResponse(self, proxy, response): if self.request is None: # we have not obtained a valid request yet return try: req_plain, req_json = self._parse_request(self.request) resp_plain, resp_json = self._parse_response(response) if "command" not in resp_json: # we only want apis that are commands self.request = None return try: SWPlugin.call_plugins("process_request", (req_json, resp_json)) except Exception as e: logger.exception("Exception while executing plugin : {}".format(e)) except Exception as e: logger.debug("unknown exception: {}".format(e))
def log_end_battle(self, req_json, resp_json, config): if not config["log_runs"]: return command = req_json['command'] if command == 'BattleDungeonResult': stage = '%s B%s' % (get_map_value(req_json['dungeon_id'], dungeon_map, req_json['dungeon_id']), req_json['stage_id']) if command == 'BattleScenarioResult': wizard_id = str(resp_json['wizard_info']['wizard_id']) if 'run-logger-data' in config and wizard_id in config['run-logger-data'] \ and 'stage' in config['run-logger-data'][wizard_id]: stage = config['run-logger-data'][wizard_id]['stage'] else: stage = 'unknown' wizard_id = str(resp_json['wizard_info']['wizard_id']) win_lost = 'Win' if resp_json["win_lose"] == 1 else 'Lost' # Are we recording losses? if not config["log_wipes"] and win_lost == 'Lost': return reward = resp_json['reward'] if 'reward' in resp_json else {} crystal = reward['crystal'] if 'crystal' in reward else 0 energy = reward['energy'] if 'energy' in reward else 0 timer = req_json['clear_time'] m = divmod(timer / 1000, 60) elapsed_time = '%s:%02d' % (m[0], m[1]) filename = "%s-runs.csv" % wizard_id is_new_file = not os.path.exists(filename) with open(filename, "ab") as log_file: field_names = ['date', 'dungeon', 'result', 'time', 'mana', 'crystal', 'energy', 'drop', 'grade', 'value', 'set', 'eff', 'slot', 'rarity', 'main_stat', 'prefix_stat','sub1','sub2','sub3','sub4'] header = {'date': 'Date','dungeon': 'Dungeon', 'result': 'Result', 'time':'Clear time', 'mana':'Mana', 'crystal': 'Crystal', 'energy': 'Energy', 'drop': 'Drop', 'grade': 'Rune Grade','value': 'Sell value', 'set': 'Rune Set', 'eff': 'Max Efficiency', 'slot': 'Slot', 'rarity': 'Rune Rarity', 'main_stat': 'Main stat', 'prefix_stat': 'Prefix stat', 'sub1': 'Secondary stat 1', 'sub2': 'Secondary stat 2,', 'sub3': 'Secondary stat 3', 'sub4': 'Secondary stat 4'} SWPlugin.call_plugins('process_csv_row', ('run_logger', 'header', (field_names, header))) log_writer = DictUnicodeWriter(log_file, fieldnames=field_names) if is_new_file: log_writer.writerow(header) log_entry = {'date': time.strftime("%Y-%m-%d %H:%M"), 'dungeon': stage, 'result': win_lost, 'time': elapsed_time, 'mana': reward['mana'], 'crystal': crystal, 'energy': energy} if 'crate' in reward: if 'rune' in reward['crate']: rune = reward['crate']['rune'] eff = rune_efficiency(rune) * 100 rune_set = rune_set_id(rune['set_id']) slot = rune['slot_no'] grade = rune['class'] rank = get_map_value(len(rune['sec_eff']), rune_class_map) log_entry['drop'] = 'Rune' log_entry['grade'] = '%s*' % grade log_entry['value'] = rune['sell_value'] log_entry['set'] = rune_set log_entry['eff'] = '%0.2f%%' % eff log_entry['slot'] = slot log_entry['rarity'] = rank log_entry['main_stat'] = rune_effect(rune['pri_eff']) log_entry['prefix_stat'] = rune_effect(rune['prefix_eff']) i = 1 for se in rune['sec_eff']: log_entry['sub%s' %i] = rune_effect(se) i += 1 else: other_item = self.get_item_name(reward['crate']) log_entry['drop'] = other_item if 'instance_info' in resp_json: log_entry['drop'] = 'Secret Dungeon' SWPlugin.call_plugins('process_csv_row', ('run_logger', 'entry', (field_names, log_entry))) log_writer.writerow(log_entry) return
def parse_login_data(data): try: wizard = data['wizard_info'] except: wizard = {'wizard_id': 0} try: inventory = data['inventory_info'] except: inventory = [] try: monsters = data['unit_list'] except: monsters = [] try: runes = data['runes'] except: runes = [] if isinstance(runes, dict): runes = runes.values() inventory_map = { "Unknown Scrolls": (9, 1), "Mystical Scrolls": (9, 2), "Light & Darkness Scrolls": (9, 3), "Water Scrolls": (9, 4), "Fire Scrolls": (9, 5), "Wind Scrolls": (9, 6), "? Scrolls(maybe Legendary?)": (9, 7), "Exclusive Summons": (9, 8), "Legendary Summoning Pieces": (9, 9), "Light & Dark Summoning Pieces": (9, 10), "Low Magic Essence": (11, 11006), "Mid Magic Essence": (11, 12006), "High Magic Essence": (11, 13006), "Low Water Essence": (11, 11001), "Mid Water Essence": (11, 12001), "High Water Essence": (11, 13001), "Low Fire Essence": (11, 11002), "Mid Fire Essence": (11, 12002), "High Fire Essence": (11, 13002), "Low Wind Essence": (11, 11003), "Mid Wind Essence": (11, 12003), "High Wind Essence": (11, 13003), "Low Light Essence": (11, 11004), "Mid Light Essence": (11, 12004), "High Light Essence": (11, 13004), "Low Dark Essence": (11, 11005), "Mid Dark Essence": (11, 12005), "High Dark Essence": (11, 13005), } inventory_map = OrderedDict(sorted(inventory_map.items(), key=lambda t: t[1][0] * t[1][1])) storage_id = None for building in data['building_list']: if building['building_master_id'] == 25: storage_id = building['building_id'] break monsters.sort(key = lambda mon: (1 if mon['building_id'] == storage_id else 0, 6 - mon['class'], 40 - mon['unit_level'], mon['attribute'], 1 - ((mon['unit_master_id'] / 10) % 10), mon['unit_id'])) runes.sort(key = lambda r: (r['set_id'], r['slot_no'])) with open(str(wizard['wizard_id']) + ".json", "w") as f: f.write(json.dumps(data, indent=4)) with open(str(wizard['wizard_id']) + "-swarfarm.json", "w") as f: f.write(json.dumps({ 'inventory_info': inventory, 'unit_list': monsters, 'runes': runes, 'building_list': data['building_list'], 'deco_list': data['deco_list'], 'wizard': wizard, 'unit_lock_list': data['unit_lock_list'], 'helper_list': data['helper_list'], })) with open(str(wizard['wizard_id']) + "-info.csv", "wb") as wizard_file: wizard_fields = ['id','name','crystal','mana','arena'] wizard_headers = {'id': 'Wizard id', 'name': 'Wizard Name', 'crystal': 'Crystals', 'mana': 'Mana', 'arena': 'Arena score'} for name in inventory_map.keys(): wizard_fields.append(name) wizard_headers[name] = name SWPlugin.call_plugins('process_csv_row', ('wizard', 'header', (wizard_fields, wizard_headers))) wizard_writter = DictUnicodeWriter(wizard_file, fieldnames=wizard_fields) wizard_writter.writerow(wizard_headers) wizard_data = {'id': wizard['wizard_id'], 'name': wizard['wizard_name'], 'crystal': wizard['wizard_crystal'], 'mana': wizard['wizard_mana'], 'arena': data['pvp_info']['arena_score'] } for i in inventory_map.keys(): t = inventory_map[i] for item in inventory: if item['item_master_type'] == t[0] and item['item_master_id'] == t[1]: wizard_data[i] = item['item_quantity'] wizard_footer = [] SWPlugin.call_plugins('process_csv_row', ('wizard', 'wizard', (wizard, wizard_data))) SWPlugin.call_plugins('process_csv_row', ('wizard', 'footer', wizard_footer)) wizard_writter.writerow(wizard_data) if len(wizard_footer) > 0: wizard_writter.writerows(wizard_footer) optimizer = { "runes": [], "mons": [], "savedBuilds": [], } rune_id_mapping = {} monster_id_mapping = {} rune_id = 1 for rune in runes: rune_id_mapping[rune['rune_id']] = rune_id rune_id += 1 monster_id = 1 for monster in monsters: monster_id_mapping[monster['unit_id']] = monster_id monster_id += 1 monster_runes = monster['runes'] if isinstance(monster_runes, dict): monster_runes = monster_runes.values() monster_runes.sort(key = lambda r: r['slot_no']) for rune in monster_runes: rune_id_mapping[rune['rune_id']] = rune_id rune_id += 1 with open(str(wizard['wizard_id']) + "-runes.csv", "wb") as rune_file: rune_fieldnames = ['rune_id','monster_id','rune_set','slot','rune_grade','rune_level','sell_price','pri_eff' ,'pre_eff','sub1','sub2','sub3','sub4'] runes_header = {'rune_id': 'Rune id','monster_id': 'Equipped to monster', 'rune_set': 'Rune set', 'slot': 'Slot No', 'rune_grade': 'Stars', 'rune_level': 'level', 'sell_price': 'Sell Price', 'pri_eff': 'Primary effect', 'pre_eff': 'Prefix effect', 'sub1': 'First Substat', 'sub2': 'Second Substat', 'sub3': 'Third Substat', 'sub4': 'Fourth Substat' } SWPlugin.call_plugins('process_csv_row', ('runes', 'header', (rune_fieldnames, runes_header))) rune_writer = DictUnicodeWriter(rune_file, fieldnames=rune_fieldnames) rune_writer.writerow(runes_header) for rune in runes: optimizer_rune, csv_rune = map_rune(rune, rune_id_mapping[rune['rune_id']]) SWPlugin.call_plugins('process_csv_row', ('runes', 'rune', (rune, csv_rune))) optimizer['runes'].append(optimizer_rune) rune_writer.writerow(csv_rune) with open(str(wizard['wizard_id']) +"-monsters.csv", "wb") as monster_file: monster_fieldnames = ['id','name','level','grade','attribute','in_storage','hp', 'atk', 'hp', 'def', 'spd', 'crate', 'cdmg', 'res', 'acc'] monster_header = {'id': 'Monster Id','name': 'Name','level': 'Level','grade': 'Stars', 'attribute': 'Attribute','in_storage': 'In Storage','hp' : 'hp', 'atk': 'atk', 'def': 'def', 'spd': 'spd', 'crate':'cri rate', 'cdmg': 'cri dmg', 'res': 'resistance', 'acc': 'accuracy'} SWPlugin.call_plugins('process_csv_row', ('monster', 'header', (monster_fieldnames, monster_header))) monster_writer = DictUnicodeWriter(monster_file, fieldnames=monster_fieldnames) monster_writer.writerow(monster_header) for monster in monsters: optimizer_monster, csv_monster = map_monster(monster, monster_id_mapping, storage_id) SWPlugin.call_plugins('process_csv_row', ('monster', 'monster', (monster, csv_monster))) monster_writer.writerow(csv_monster) optimizer['mons'].append(optimizer_monster) monster_runes = monster['runes'] if isinstance(monster_runes, dict): monster_runes = monster_runes.values() monster_runes.sort(key = lambda r: r['slot_no']) for rune in monster_runes: optimizer_rune, csv_rune = map_rune(rune, rune_id_mapping[rune['rune_id']], monster_id_mapping[monster['unit_id']], monster['unit_master_id']) optimizer_rune["monster_n"] = "%s%s" % (monster_name(monster['unit_master_id'], "Unknown name"), " (In Storage)" if monster['building_id'] == storage_id else "") optimizer['runes'].append(optimizer_rune) SWPlugin.call_plugins('process_csv_row', ('runes', 'rune', (rune, csv_rune))) rune_writer.writerow(csv_rune) rune_footer = [] monster_footer = [] SWPlugin.call_plugins('process_csv_row', ('runes', 'footer', rune_footer)) SWPlugin.call_plugins('process_csv_row', ('monster', 'footer', monster_footer)) if len(rune_footer) > 0: rune_writer.writerows(rune_footer) if len(monster_footer) > 0: monster_writer.writerows(monster_footer) with open(str(wizard['wizard_id']) +"-optimizer.json", "w") as f: f.write(json.dumps(optimizer))
def parse_login_data(data): try: wizard = data['wizard_info'] except: wizard = {'wizard_id': 0} try: inventory = data['inventory_info'] except: inventory = [] try: monsters = data['unit_list'] except: monsters = [] try: runes = data['runes'] except: runes = [] if isinstance(runes, dict): runes = runes.values() inventory_map = { "Unknown Scrolls": (9, 1), "Mystical Scrolls": (9, 2), "Light & Darkness Scrolls": (9, 3), "? Scrolls(maybe Legendary?)": (9, 7), "Exclusive Summons": (9, 8), "Legendary Summoning Pieces": (9, 9), "Light & Dark Summoning Pieces": (9, 10), "Low Magic Essence": (11, 11006), "Mid Magic Essence": (11, 12006), "High Magic Essence": (11, 13006), "Low Water Essence": (11, 11001), "Mid Water Essence": (11, 12001), "High Water Essence": (11, 13001), "Low Fire Essence": (11, 11002), "Mid Fire Essence": (11, 12002), "High Fire Essence": (11, 13002), "Low Wind Essence": (11, 11003), "Mid Wind Essence": (11, 12003), "High Wind Essence": (11, 13003), "Low Light Essence": (11, 11004), "Mid Light Essence": (11, 12004), "High Light Essence": (11, 13004), "Low Dark Essence": (11, 11005), "Mid Dark Essence": (11, 12005), "High Dark Essence": (11, 13005), } inventory_map = OrderedDict(sorted(inventory_map.items(), key=lambda t: t[1][0] * t[1][1])) storage_id = None for building in data['building_list']: if building['building_master_id'] == 25: storage_id = building['building_id'] break monsters.sort(key = lambda mon: (1 if mon['building_id'] == storage_id else 0, 6 - mon['class'], 40 - mon['unit_level'], mon['attribute'], 1 - ((mon['unit_master_id'] / 10) % 10), mon['unit_id'])) runes.sort(key = lambda r: (r['set_id'], r['slot_no'])) with open(str(wizard['wizard_id']) + ".json", "w") as f: f.write(json.dumps(data, indent=4)) with open(str(wizard['wizard_id']) + "-swarfarm.json", "w") as f: f.write(json.dumps({ 'inventory_info': inventory, 'unit_list': monsters, 'runes': runes, 'building_list': data['building_list'], 'deco_list': data['deco_list'], 'wizard': wizard, 'unit_lock_list': data['unit_lock_list'], 'helper_list': data['helper_list'], })) with open(str(wizard['wizard_id']) + "-info.csv", "wb") as wizard_file: wizard_fields = ['id','name','crystal','mana','arena'] wizard_headers = {'id': 'Wizard id', 'name': 'Wizard Name', 'crystal': 'Crystals', 'mana': 'Mana', 'arena': 'Arena score'} for name in inventory_map.keys(): wizard_fields.append(name) wizard_headers[name] = name SWPlugin.call_plugins('process_csv_row', ('wizard', 'header', (wizard_fields, wizard_headers))) wizard_writter = DictUnicodeWriter(wizard_file, fieldnames=wizard_fields) wizard_writter.writerow(wizard_headers) wizard_data = {'id': wizard['wizard_id'], 'name': wizard['wizard_name'], 'crystal': wizard['wizard_crystal'], 'mana': wizard['wizard_mana'], 'arena': data['pvp_info']['arena_score'] } for i in inventory_map.keys(): t = inventory_map[i] for item in inventory: if item['item_master_type'] == t[0] and item['item_master_id'] == t[1]: wizard_data[i] = item['item_quantity'] wizard_footer = [] SWPlugin.call_plugins('process_csv_row', ('wizard', 'wizard', (wizard, wizard_data))) SWPlugin.call_plugins('process_csv_row', ('wizard', 'footer', wizard_footer)) wizard_writter.writerow(wizard_data) if len(wizard_footer) > 0: wizard_writter.writerows(wizard_footer) optimizer = { "runes": [], "mons": [], "savedBuilds": [], } rune_id_mapping = {} monster_id_mapping = {} rune_id = 1 for rune in runes: rune_id_mapping[rune['rune_id']] = rune_id rune_id += 1 monster_id = 1 for monster in monsters: monster_id_mapping[monster['unit_id']] = monster_id monster_id += 1 monster_runes = monster['runes'] if isinstance(monster_runes, dict): monster_runes = monster_runes.values() monster_runes.sort(key = lambda r: r['slot_no']) for rune in monster_runes: rune_id_mapping[rune['rune_id']] = rune_id rune_id += 1 with open(str(wizard['wizard_id']) + "-runes.csv", "wb") as rune_file: rune_fieldnames = ['rune_id','monster_id','rune_set','slot','rune_grade','rune_level','sell_price','pri_eff' ,'pre_eff','sub1','sub2','sub3','sub4'] runes_header = {'rune_id': 'Rune id','monster_id': 'Equipped to monster', 'rune_set': 'Rune set', 'slot': 'Slot No', 'rune_grade': 'Stars', 'rune_level': 'level', 'sell_price': 'Sell Price', 'pri_eff': 'Primary effect', 'pre_eff': 'Prefix effect', 'sub1': 'First Substat', 'sub2': 'Second Substat', 'sub3': 'Third Substat', 'sub4': 'Fourth Substat' } SWPlugin.call_plugins('process_csv_row', ('runes', 'header', (rune_fieldnames, runes_header))) rune_writer = DictUnicodeWriter(rune_file, fieldnames=rune_fieldnames) rune_writer.writerow(runes_header) for rune in runes: optimizer_rune, csv_rune = map_rune(rune, rune_id_mapping[rune['rune_id']]) SWPlugin.call_plugins('process_csv_row', ('runes', 'rune', (rune, csv_rune))) optimizer['runes'].append(optimizer_rune) rune_writer.writerow(csv_rune) with open(str(wizard['wizard_id']) +"-monsters.csv", "wb") as monster_file: monster_fieldnames = ['id','name','level','grade','attribute','in_storage','hp', 'atk', 'hp', 'def', 'spd', 'crate', 'cdmg', 'res', 'acc'] monster_header = {'id': 'Monster Id','name': 'Name','level': 'Level','grade': 'Stars', 'attribute': 'Attribute','in_storage': 'In Storage','hp' : 'hp', 'atk': 'atk', 'def': 'def', 'spd': 'spd', 'crate':'cri rate', 'cdmg': 'cri dmg', 'res': 'resistance', 'acc': 'accuracy'} SWPlugin.call_plugins('process_csv_row', ('monster', 'header', (monster_fieldnames, monster_header))) monster_writer = DictUnicodeWriter(monster_file, fieldnames=monster_fieldnames) monster_writer.writerow(monster_header) for monster in monsters: optimizer_monster, csv_monster = map_monster(monster, monster_id_mapping, storage_id) SWPlugin.call_plugins('process_csv_row', ('monster', 'monster', (monster, csv_monster))) monster_writer.writerow(csv_monster) optimizer['mons'].append(optimizer_monster) monster_runes = monster['runes'] if isinstance(monster_runes, dict): monster_runes = monster_runes.values() monster_runes.sort(key = lambda r: r['slot_no']) for rune in monster_runes: optimizer_rune, csv_rune = map_rune(rune, rune_id_mapping[rune['rune_id']], monster_id_mapping[monster['unit_id']], monster['unit_master_id']) optimizer_rune["monster_n"] = "%s%s" % (monster_name(monster['unit_master_id'], "Unknown name"), " (In Storage)" if monster['building_id'] == storage_id else "") optimizer['runes'].append(optimizer_rune) SWPlugin.call_plugins('process_csv_row', ('runes', 'rune', (rune, csv_rune))) rune_writer.writerow(csv_rune) rune_footer = [] monster_footer = [] SWPlugin.call_plugins('process_csv_row', ('runes', 'footer', rune_footer)) SWPlugin.call_plugins('process_csv_row', ('monster', 'footer', monster_footer)) if len(rune_footer) > 0: rune_writer.writerows(rune_footer) if len(monster_footer) > 0: monster_writer.writerows(monster_footer) with open(str(wizard['wizard_id']) +"-optimizer.json", "w") as f: f.write(json.dumps(optimizer))
def parse_visit_data(data): friend = data['friend'] monsters = friend['unit_list'] storage_id = None wizard_id = 'unknown' for building in friend['building_list']: wizard_id = building['wizard_id'] if building['building_master_id'] == 25: storage_id = building['building_id'] break monsters.sort(key=lambda mon: (1 if mon[ 'building_id'] == storage_id else 0, 6 - mon['class'], 40 - mon[ 'unit_level'], mon['attribute'], mon['unit_id'])) with open("visit-" + str(wizard_id) + ".json", "w") as f: f.write(json.dumps(data, indent=4)) with open("visit-" + str(wizard_id) + "-monsters.csv", "wb") as visit_file: visit_fieldnames = [ 'wizard_name', 'name', 'grade', 'level', 'attribute', 'in_storage', 'hp', 'atk', 'hp', 'def', 'spd', 'crate', 'cdmg', 'res', 'acc', 'slot', 'rune_set', 'rune_grade', 'rune_level', 'pri_eff', 'pre_eff', 'sub1', 'sub2', 'sub3', 'sub4' ] visit_header = { 'wizard_name': 'Wizard Name', 'name': 'Name', 'level': 'Level', 'grade': 'Stars', 'attribute': 'Attribute', 'in_storage': 'In Storage', 'hp': 'hp', 'atk': 'atk', 'def': 'def', 'spd': 'spd', 'crate': 'cri rate', 'cdmg': 'cri dmg', 'res': 'resistance', 'acc': 'accuracy', 'rune_set': 'Rune set', 'slot': 'Slot No', 'rune_grade': 'Stars', 'rune_level': 'level', 'pri_eff': 'Primary effect', 'pre_eff': 'Prefix effect', 'sub1': 'First Substat', 'sub2': 'Second Substat', 'sub3': 'Third Substat', 'sub4': 'Fourth Substat', } SWPlugin.call_plugins('process_csv_row', ('visit', 'header', (visit_fieldnames, visit_header))) visit_writer = DictUnicodeWriter(visit_file, fieldnames=visit_fieldnames) visit_writer.writerow(visit_header) for monster in monsters: _, monster_csv = map_monster(monster, None, storage_id, friend['wizard_name']) SWPlugin.call_plugins('process_csv_row', ('visit', 'monster', (monster, monster_csv))) visit_writer.writerow(monster_csv) monster_runes = monster['runes'] if isinstance(monster_runes, dict): monster_runes = monster_runes.values() monster_runes.sort(key=lambda r: r['slot_no']) for rune in monster_runes: _, rune_map = map_rune(rune, None) SWPlugin.call_plugins('process_csv_row', ('visit', 'rune', (rune, rune_map))) visit_writer.writerow(rune_map) visit_footer = [] SWPlugin.call_plugins('process_csv_row', ('visit', 'footer', visit_footer)) if len(visit_footer) > 0: visit_writer.writerows(visit_footer)
def log_summon(self, req_json, resp_json, config): if not config["log_summon"]: return wizard_id = str(resp_json['wizard_info']['wizard_id']) if 'unit_list' in resp_json: if 'item_info' in resp_json: scroll = identify_scroll( resp_json['item_info']['item_master_id']) else: mode = req_json['mode'] if mode == 3: scroll = 'Crystal' elif mode == 5: scroll = 'Social' else: scroll = 'Unidentified' filename = "%s-summons.csv" % wizard_id is_new_file = not os.path.exists(filename) with open(filename, "ab") as log_file: field_names = [ 'date', 'scroll', 'unit_name', 'attribute', 'grade', 'awake' ] header = { 'date': 'Date', 'scroll': 'Scroll', 'unit_name': 'Unit', 'attribute': 'Attribute', 'grade': 'Grade', 'awake': 'Awakened' } SWPlugin.call_plugins('process_csv_row', ('summon_logger', 'header', (field_names, header))) log_writer = DictUnicodeWriter(log_file, fieldnames=field_names) if is_new_file: log_writer.writerow(header) if 'unit_list' in resp_json and len(resp_json['unit_list']) > 0: for i in range(0, len(resp_json['unit_list'])): unit_name = monster_name( resp_json['unit_list'][i]['unit_master_id'], '', False) attribute = monster_attribute( resp_json['unit_list'][i]['attribute']) grade = resp_json['unit_list'][i]['class'] awakened = str(resp_json['unit_list'][i]['unit_master_id']) if int(awakened[-2]) == 0: awake = 'No' else: awake = 'Yes' log_entry = { 'date': time.strftime("%Y-%m-%d %H:%M"), 'scroll': scroll, 'unit_name': unit_name, 'attribute': attribute, 'grade': grade, 'awake': awake } SWPlugin.call_plugins('process_csv_row', ('summon_logger', 'entry', (field_names, log_entry))) log_writer.writerow(log_entry) return
def log_end_battle(self, req_json, resp_json, config): if not config["log_arena"]: return command = req_json['command'] if command == 'BattleArenaResult': wizard_id = str(resp_json['wizard_info']['wizard_id']) if 'arena-logger-data' in config and wizard_id in config['arena-logger-data'] \ and 'start' in config['arena-logger-data'][wizard_id]: start = config['arena-logger-data'][wizard_id]['start'] delta = int(time.time()) - start m = divmod(delta, 60) s = m[1] # seconds elapsed_time = '%s:%02d' % (m[0], s) opp_monster_list = config['arena-logger-data'][wizard_id]['opp_monster_list'] else: elapsed_time = 'N/A' wizard_id = str(resp_json['wizard_info']['wizard_id']) if not os.path.exists('%s-optimizer.json' % wizard_id): logger.warn("optimizer file is needed for arena plugin") return user_mons = self.build_unit_dictionary(wizard_id) win_lost = 'Win' if resp_json["win_lose"] == 1 else 'Lost' reward = resp_json['reward'] if 'reward' in resp_json else {} mana = reward['mana'] if 'mana' in reward else 0 crystal = reward['crystal'] if 'crystal' in reward else 0 energy = reward['energy'] if 'energy' in reward else 0 honor = reward['honor_point'] if 'honor_point' in reward else 0 opponent_list = {} if 'arena-logger-data' in config and wizard_id in config['arena-logger-data'] \ and 'arena_list' in config['arena-logger-data'][wizard_id]: opponent_list.update(config['arena-logger-data'][wizard_id]['arena_list']) if 'arena-logger-data' in config and wizard_id in config['arena-logger-data'] \ and 'revenge_list' in config['arena-logger-data'][wizard_id]: opponent_list.update(config['arena-logger-data'][wizard_id]['revenge_list']) opponent_list.update(rival_name) opponent_id = str(config['arena-logger-data'][wizard_id]['opponent_id']) if opponent_list.has_key(opponent_id): opponent = opponent_list[opponent_id] else: opponent = opponent_id del config['arena-logger-data'][wizard_id]['start'] # make sure start time doesn't persist del config['arena-logger-data'][wizard_id]['opp_monster_list'] # make sure opp_mons doen't persist del config['arena-logger-data'][wizard_id]['opponent_id'] # make sure opponent_id doesn't persist # don't delete arena_list or revenge_list as they are needed for future battles filename = "%s-arena.csv" % wizard_id is_new_file = not os.path.exists(filename) with open(filename, "ab") as log_file: field_names = ['date', 'result', 'time', 'mana', 'crystal', 'energy', 'honor', 'opponent', 'team1', 'team2', 'team3', 'team4', 'opteam1', 'opteam2', 'opteam3', 'opteam4'] header = {'date': 'Date', 'result': 'Result', 'time':'Clear time', 'mana':'Mana', 'crystal': 'Crystal', 'energy': 'Energy', 'honor': 'Honor', 'opponent': 'Opponent', 'team1': 'Team1', 'team2': 'Team2', 'team3': 'Team3', 'team4': 'Team4', 'opteam1': 'OpTeam1', 'opteam2': 'OpTeam2', 'opteam3': 'OpTeam3', 'opteam4': 'OpTeam4'} SWPlugin.call_plugins('process_csv_row', ('arena_logger', 'header', (field_names, header))) log_writer = DictUnicodeWriter(log_file, fieldnames=field_names) if is_new_file: log_writer.writerow(header) log_entry = {'date': time.strftime("%Y-%m-%d %H:%M"), 'result': win_lost, 'time': elapsed_time, 'mana': mana, 'crystal': crystal, 'energy': energy, 'honor' : honor} log_entry['opponent'] = opponent if 'unit_list' in resp_json and len(resp_json['unit_list']) > 0: for i in range(1, len(resp_json['unit_list']) + 1): log_entry['team%s' % i] = monster_name(resp_json['unit_list'][i-1]['unit_master_id']) else: for i in range(1, len(req_json['unit_id_list']) + 1): id = req_json['unit_id_list'][i-1]['unit_id'] log_entry['team%s' % i] = user_mons[id] for i in range(1, len(opp_monster_list) + 1): log_entry['opteam%s' % i] = monster_name(opp_monster_list[i]) SWPlugin.call_plugins('process_csv_row', ('arena_logger', 'entry', (field_names, log_entry))) log_writer.writerow(log_entry) return
def log_end_battle(self, req_json, resp_json, config): if not config["log_guild_battle"]: return command = req_json['command'] if command == 'BattleGuildWarResult': wizard_id = str(resp_json['wizard_info']['wizard_id']) if 'guild-battle-logger-data' in config and wizard_id in config['guild-battle-logger-data'] \ and 'start' in config['guild-battle-logger-data'][wizard_id]: start = config['guild-battle-logger-data'][wizard_id]['start'] delta = int(time.time()) - start m = divmod(delta, 60) s = m[1] # seconds elapsed_time = '%s:%02d' % (m[0], s) opp_monster_list = config['guild-battle-logger-data'][wizard_id]['opp_monster_list'] monster_list = config['guild-battle-logger-data'][wizard_id]['monster_list'] else: elapsed_time = 'N/A' wizard_id = str(resp_json['wizard_info']['wizard_id']) user_mons = self.build_unit_dictionary(wizard_id) guildpoints = 0 for reward in resp_json['reward_list']: guildpoints += reward['guild_point_var'] guildpoints += reward['guild_point_bonus'] round1 = win_lose_round[resp_json['win_lose_list'][0]] round2 = win_lose_round[resp_json['win_lose_list'][1]] result = win_lose_battle[resp_json['win_lose_list'][0]*resp_json['win_lose_list'][1]] oppguild = config['guild-battle-logger-data'][wizard_id]['guildname'] opponent_list = {} if 'guild-battle-logger-data' in config and wizard_id in config['guild-battle-logger-data'] \ and 'guild_opponent_list' in config['guild-battle-logger-data'][wizard_id]: opponent_list.update(config['guild-battle-logger-data'][wizard_id]['guild_opponent_list']) opponent_id = str(config['guild-battle-logger-data'][wizard_id]['opponent_id']) if opponent_list.has_key(opponent_id): opponent = opponent_list[opponent_id] else: opponent = opponent_id del config['guild-battle-logger-data'][wizard_id]['start'] # make sure start time doesn't persist del config['guild-battle-logger-data'][wizard_id]['opp_monster_list'] # make sure opp_mons doen't persist del config['guild-battle-logger-data'][wizard_id]['opponent_id'] # make sure opponent_id doesn't persist filename = "%s-guildbattle.csv" % wizard_id is_new_file = not os.path.exists(filename) with open(filename, "ab") as log_file: field_names = ['date', 'oppguild', 'opponent', 'round1', 'team1', 'team2', 'team3', 'opteam1', 'opteam2', 'opteam3', 'round2', 'team4', 'team5', 'team6', 'opteam4', 'opteam5', 'opteam6', 'result', 'guildpoints'] header = {'date': 'Date', 'oppguild': 'Enemy Guild', 'opponent': 'Opponent', 'round1': 'Round 1', 'team1': 'Team1', 'team2': 'Team2', 'team3': 'Team3', 'opteam1': 'OpTeam1', 'opteam2': 'OpTeam2', 'opteam3': 'OpTeam3', 'round2': 'Round 2', 'team4': 'Team4', 'team5': 'Team5', 'team6': 'Team6', 'opteam4': 'OpTeam4', 'opteam5': 'OpTeam5', 'opteam6': 'OpTeam6', 'result': 'Result', 'guildpoints': 'Guild Points'} SWPlugin.call_plugins('process_csv_row', ('guild_battle_logger', 'header', (field_names, header))) log_writer = DictUnicodeWriter(log_file, fieldnames=field_names) if is_new_file: log_writer.writerow(header) log_entry = {'date': time.strftime("%Y-%m-%d %H:%M"), 'oppguild': oppguild, 'opponent': opponent, 'round1': round1, 'round2': round2, 'result': result, 'guildpoints' : guildpoints} for i in range(1, len(monster_list) + 1): log_entry['team%s' % i] = monster_name(monster_list[i]) for i in range(1, len(opp_monster_list) + 1): log_entry['opteam%s' % i] = monster_name(opp_monster_list[i]) SWPlugin.call_plugins('process_csv_row', ('guild_battle_logger', 'entry', (field_names, log_entry))) log_writer.writerow(log_entry) return
def log_end_battle(self, req_json, resp_json, config): if not config["log_runs"]: return command = req_json['command'] if command == 'BattleDungeonResult': stage = '%s B%s' % (get_map_value(req_json['dungeon_id'], dungeon_map, req_json['dungeon_id']), req_json['stage_id']) if command == 'BattleScenarioResult': wizard_id = str(resp_json['wizard_info']['wizard_id']) if 'run-logger-data' in config and wizard_id in config['run-logger-data'] \ and 'stage' in config['run-logger-data'][wizard_id]: stage = config['run-logger-data'][wizard_id]['stage'] else: stage = 'unknown' wizard_id = str(resp_json['wizard_info']['wizard_id']) if not os.path.exists('%s-optimizer.json' % wizard_id): logger.warn("Optimizer file is needed for RunLogger plugin") return user_mons = self.build_unit_dictionary(wizard_id) win_lost = 'Win' if resp_json["win_lose"] == 1 else 'Lost' # Are we recording losses? if 'log_wipes' in config and not config["log_wipes"] and win_lost == 'Lost': return reward = resp_json['reward'] if 'reward' in resp_json else {} mana = reward['mana'] if 'mana' in reward else 0 crystal = reward['crystal'] if 'crystal' in reward else 0 energy = reward['energy'] if 'energy' in reward else 0 timer = req_json['clear_time'] m = divmod(timer / 1000, 60) elapsed_time = '%s:%02d' % (m[0], m[1]) filename = "%s-runs.csv" % wizard_id is_new_file = not os.path.exists(filename) with open(filename, "ab") as log_file: field_names = ['date', 'dungeon', 'result', 'time', 'mana', 'crystal', 'energy', 'drop', 'grade', 'value', 'set', 'eff', 'slot', 'rarity', 'main_stat', 'prefix_stat','sub1','sub2','sub3','sub4','team1','team2','team3','team4','team5'] header = {'date': 'Date','dungeon': 'Dungeon', 'result': 'Result', 'time':'Clear time', 'mana':'Mana', 'crystal': 'Crystal', 'energy': 'Energy', 'drop': 'Drop', 'grade': 'Rune Grade','value': 'Sell value', 'set': 'Rune Set', 'eff': 'Max Efficiency', 'slot': 'Slot', 'rarity': 'Rune Rarity', 'main_stat': 'Main stat', 'prefix_stat': 'Prefix stat', 'sub1': 'Secondary stat 1', 'sub2': 'Secondary stat 2,', 'sub3': 'Secondary stat 3', 'sub4': 'Secondary stat 4', 'team1': 'Team1', 'team2': 'Team2', 'team3': 'Team3', 'team4': 'Team4', 'team5': 'Team5'} SWPlugin.call_plugins('process_csv_row', ('run_logger', 'header', (field_names, header))) log_writer = DictUnicodeWriter(log_file, fieldnames=field_names) if is_new_file: log_writer.writerow(header) if 'crate' in reward: if 'mana' in reward['crate']: reward['mana'] += reward['crate']['mana'] if 'energy' in reward['crate']: reward['energy'] += reward['crate']['energy'] if 'crystal' in reward['crate']: reward['crystal'] += reward['crate']['crystal'] log_entry = {'date': time.strftime("%Y-%m-%d %H:%M"), 'dungeon': stage, 'result': win_lost, 'time': elapsed_time, 'mana': mana, 'crystal': crystal, 'energy': energy} if 'crate' in reward: if 'rune' in reward['crate']: rune = reward['crate']['rune'] eff = rune_efficiency(rune) * 100 rune_set = rune_set_id(rune['set_id']) slot = rune['slot_no'] grade = rune['class'] rank = get_map_value(len(rune['sec_eff']), rune_class_map) log_entry['drop'] = 'Rune' log_entry['grade'] = '%s*' % grade log_entry['value'] = rune['sell_value'] log_entry['set'] = rune_set log_entry['eff'] = '%0.2f%%' % eff log_entry['slot'] = slot log_entry['rarity'] = rank log_entry['main_stat'] = rune_effect(rune['pri_eff']) log_entry['prefix_stat'] = rune_effect(rune['prefix_eff']) i = 1 for se in rune['sec_eff']: log_entry['sub%s' %i] = rune_effect(se) i += 1 else: other_item = self.get_item_name(reward['crate']) log_entry['drop'] = other_item if 'unit_list' in resp_json and len(resp_json['unit_list']) > 0: for i in range(1, len(resp_json['unit_list']) + 1): log_entry['team%s' % i] = monster_name(resp_json['unit_list'][i-1]['unit_master_id']) else: for i in range(1, len(req_json['unit_id_list']) + 1): id = req_json['unit_id_list'][i-1]['unit_id'] log_entry['team%s' % i] = user_mons[id] if 'instance_info' in resp_json: log_entry['drop'] = 'Secret Dungeon' SWPlugin.call_plugins('process_csv_row', ('run_logger', 'entry', (field_names, log_entry))) log_writer.writerow(log_entry) return
def log_end_battle(self, req_json, resp_json, config): if not config["log_arena"]: return command = req_json['command'] if command == 'BattleArenaResult': wizard_id = str(resp_json['wizard_info']['wizard_id']) if 'arena-logger-data' in config and wizard_id in config['arena-logger-data'] \ and 'start' in config['arena-logger-data'][wizard_id]: start = config['arena-logger-data'][wizard_id]['start'] delta = int(time.time()) - start m = divmod(delta, 60) s = m[1] # seconds elapsed_time = '%s:%02d' % (m[0], s) opp_monster_list = config['arena-logger-data'][wizard_id][ 'opp_monster_list'] else: elapsed_time = 'N/A' wizard_id = str(resp_json['wizard_info']['wizard_id']) if not os.path.exists('%s-optimizer.json' % wizard_id): logger.warn("optimizer file is needed for arena plugin") return user_mons = self.build_unit_dictionary(wizard_id) win_lost = 'Win' if resp_json["win_lose"] == 1 else 'Lost' reward = resp_json['reward'] if 'reward' in resp_json else {} mana = reward['mana'] if 'mana' in reward else 0 crystal = reward['crystal'] if 'crystal' in reward else 0 energy = reward['energy'] if 'energy' in reward else 0 honor = reward['honor_point'] if 'honor_point' in reward else 0 opponent_list = {} if 'arena-logger-data' in config and wizard_id in config['arena-logger-data'] \ and 'arena_list' in config['arena-logger-data'][wizard_id]: opponent_list.update( config['arena-logger-data'][wizard_id]['arena_list']) if 'arena-logger-data' in config and wizard_id in config['arena-logger-data'] \ and 'revenge_list' in config['arena-logger-data'][wizard_id]: opponent_list.update( config['arena-logger-data'][wizard_id]['revenge_list']) opponent_list.update(rival_name) opponent_id = str( config['arena-logger-data'][wizard_id]['opponent_id']) if opponent_list.has_key(opponent_id): opponent = opponent_list[opponent_id] else: opponent = opponent_id del config['arena-logger-data'][wizard_id][ 'start'] # make sure start time doesn't persist del config['arena-logger-data'][wizard_id][ 'opp_monster_list'] # make sure opp_mons doen't persist del config['arena-logger-data'][wizard_id][ 'opponent_id'] # make sure opponent_id doesn't persist # don't delete arena_list or revenge_list as they are needed for future battles filename = "%s-arena.csv" % wizard_id is_new_file = not os.path.exists(filename) with open(filename, "ab") as log_file: field_names = [ 'date', 'result', 'time', 'mana', 'crystal', 'energy', 'honor', 'opponent', 'team1', 'team2', 'team3', 'team4', 'opteam1', 'opteam2', 'opteam3', 'opteam4' ] header = { 'date': 'Date', 'result': 'Result', 'time': 'Clear time', 'mana': 'Mana', 'crystal': 'Crystal', 'energy': 'Energy', 'honor': 'Honor', 'opponent': 'Opponent', 'team1': 'Team1', 'team2': 'Team2', 'team3': 'Team3', 'team4': 'Team4', 'opteam1': 'OpTeam1', 'opteam2': 'OpTeam2', 'opteam3': 'OpTeam3', 'opteam4': 'OpTeam4' } SWPlugin.call_plugins('process_csv_row', ('arena_logger', 'header', (field_names, header))) log_writer = DictUnicodeWriter(log_file, fieldnames=field_names) if is_new_file: log_writer.writerow(header) log_entry = { 'date': time.strftime("%Y-%m-%d %H:%M"), 'result': win_lost, 'time': elapsed_time, 'mana': mana, 'crystal': crystal, 'energy': energy, 'honor': honor } log_entry['opponent'] = opponent if 'unit_list' in resp_json and len(resp_json['unit_list']) > 0: for i in range(1, len(resp_json['unit_list']) + 1): log_entry['team%s' % i] = monster_name( resp_json['unit_list'][i - 1]['unit_master_id']) else: for i in range(1, len(req_json['unit_id_list']) + 1): id = req_json['unit_id_list'][i - 1]['unit_id'] log_entry['team%s' % i] = user_mons[id] for i in range(1, len(opp_monster_list) + 1): log_entry['opteam%s' % i] = monster_name(opp_monster_list[i]) SWPlugin.call_plugins('process_csv_row', ('arena_logger', 'entry', (field_names, log_entry))) log_writer.writerow(log_entry) return
def __init__(self, config: str = "swproxy.config"): self.config = config self.sw_request = None SWPlugin.set_config_name(config=config)
def log_end_battle(self, req_json, resp_json, config): if not config["log_raids"]: return wizard_id = str(resp_json['wizard_info']['wizard_id']) if 'raid-logger-data' in config and wizard_id in config['raid-logger-data'] \ and 'start' in config['raid-logger-data'][wizard_id]: start_data = config['raid-logger-data'][wizard_id] delta = int(time.time()) - start_data['start'] m = divmod(delta, 60) s = m[1] # seconds elapsed_time = '%s:%02d' % (m[0], s) else: elapsed_time = 'N/A' win_lost = 'Win' if resp_json["win_lose"] == 1 else 'Lost' if win_lost == 'Win': order = 0 for i in resp_json['battle_reward_list']: if wizard_id != str(i['wizard_id']): order += 1 else: break reward = resp_json['battle_reward_list'][order]['reward_list'][0] if reward['item_master_type'] == 1: log_reward = {'drop': 'Rainbowmon 3*'} elif reward['item_master_type'] == 6: log_reward = {'drop': 'Mana Stones', 'value': reward['item_quantity']} elif reward['item_master_type'] == 27: if reward['runecraft_type'] == 2: item = 'Grindstone' elif reward['runecraft_type'] == 1: item = 'Enchanted Gem' value = resp_json['reward']['crate']['runecraft_info']['sell_value'] rune_set = rune_set_id(reward['runecraft_set_id']) rarity = identify_rune_grade(reward['runecraft_rank']) stat = rune_effect_type(reward['runecraft_effect_id']) log_reward = {'drop': item, 'value': value, 'set': rune_set, 'rarity': rarity, 'stat': stat} elif reward['item_master_type'] == 9: if reward['item_master_id'] == 2: log_reward = {'drop': "Mystical Scroll"} elif reward['item_master_id'] == 8: log_reward = {'drop': "Summoning Stones x%s" % reward['item_quantity']} elif reward['item_master_type'] == 10: #placeholder waiting for info log_reward = {'drop': "Shapeshifting Stone x%s" % reward['item_quantity']} else: log_reward = {'drop': "Unknown drop %s" % json.dumps(reward)} filename = "%s-raids.csv" % wizard_id is_new_file = not os.path.exists(filename) with open(filename, "ab") as log_file: field_names = ['date', 'raid', 'result', 'time', 'team1', 'team2', 'drop', 'value', 'set', 'rarity', 'stat'] header = {'date': 'Date', 'raid': 'Raid', 'result': 'Result', 'time': 'Clear time', 'team1': 'Teammate #1', 'team2': 'Teammate #2', 'drop': 'Drop', 'value': 'Sell value', 'set': 'Rune Set', 'rarity': 'Rarity', 'stat': 'Stat'} SWPlugin.call_plugins('process_csv_row', ('raid_logger', 'header', (field_names, header))) log_writer = DictUnicodeWriter(log_file, fieldnames=field_names) if is_new_file: log_writer.writerow(header) log_entry = {'date': time.strftime("%Y-%m-%d %H:%M"), 'raid': start_data['stage'] if 'stage' in start_data else 'unknown', 'result': win_lost, 'time': elapsed_time, 'team1': start_data['team'][0], 'team2': start_data['team'][1]} log_entry.update(log_reward) SWPlugin.call_plugins('process_csv_row', ('raid_logger', 'entry', (field_names, log_entry))) log_writer.writerow(log_entry) return