#!/usr/bin/env python import csv import json import cStringIO import sys import struct import numbers import os import codecs from SWPlugin import SWPlugin from collections import OrderedDict from smon_decryptor import decrypt_request, decrypt_response from monsters import monsters_name_map # ref: http://stackoverflow.com/a/5838817/1020222 class DictUnicodeWriter(object): def __init__(self, f, fieldnames, dialect=csv.excel, encoding="utf-8", newfile=True, **kwds): # Redirect output to a queue self.queue = cStringIO.StringIO() self.writer = csv.DictWriter(self.queue, fieldnames, dialect=dialect, **kwds) self.stream = f self.encoder = codecs.getincrementalencoder(encoding)() if newfile: self.writebom() def writerow(self, D): self.writer.writerow({k:unicode(v).encode("utf-8") for k, v in D.items()}) # Fetch UTF-8 output from the queue ... data = self.queue.getvalue() data = data.decode("utf-8") # ... and reencode it into the target encoding data = self.encoder.encode(data) # write to the target stream self.stream.write(data) # empty queue self.queue.truncate(0) def writerows(self, rows): for D in rows: self.writerow(D) def writeheader(self): self.writer.writeheader() def writebom(self): """Write BOM, so excel can identify this as UTF8""" self.stream.write(u'\ufeff'.encode('utf8')) def monster_name(uid, default_unknown="???", full=True): uid = str(uid) name_map = monsters_name_map if uid in name_map and len(name_map[uid]) > 0: return name_map[uid] else: if uid[0:3] in name_map and len(name_map[uid[0:3]]) > 0: attribute = int(uid[-1]) awakened = int(uid[-2]) if full: return "%s%s (%s)" % ("AWAKENED " if awakened else "", name_map[uid[0:3]], monster_attribute(attribute)) elif not awakened: return name_map[uid[0:3]] return default_unknown def monster_attribute(attribute): name_map = { 1: "물", 2: "불", 3: "풍", 4: "빛", 5: "암" } if attribute in name_map: return name_map[attribute] else: return attribute def rune_effect_type(id, mode=0): """mode 0 = rune optimizer, mode 1 = csv export""" if mode != 0 and mode != 1: raise ValueError('Should be 0 (optimizer) or 1 (csv)') effect_type_map = { 0: ("",""), 1: ("체력", "HP +%s"), 2: ("체력%", "HP %s%%"), 3: ("공격", "ATK +%s"), 4: ("공격%", "ATK %s%%"), 5: ("방어", "DEF +%s"), 6: ("방어%", "DEF %s%%"), # 7: "UNKNOWN", # ? 8: ("공속", "SPD +%s"), 9: ("치확", "CRI Rate %s%%"), 10: ("치피", "CRI Dmg %s%%"), 11: ("효저", "Resistance %s%%"), 12: ("효적", "Accuracy %s%%") } return effect_type_map[id][mode] if id in effect_type_map else "UNKNOWN" def rune_effect(eff): typ = eff[0] value = eff[1] flats = [1,3,5,8] if len(eff) > 3: if eff[3] != 0: if typ in flats: value = "%s -> +%s" % (value, str(int(value) + int(eff[3]))) else: value = "%s%% -> %s" % (value, str(int(value) + int(eff[3]))) if typ == 0: ret = "" elif typ == 7 or typ > 12: ret = "UNK %s %s" % (typ, value) else: ret = rune_effect_type(typ,1) % value if len(eff) > 2: if eff[2] != 0: ret = "%s (Converted)" % ret return ret def rune_set_id(id): name_map = { 1: "활력", 2: "수호", 3: "신속", 4: "칼날", 5: "격노", 6: "집중", 7: "인내", 8: "맹공", 10: "절망", 11: "흡혈", 13: "폭주", 14: "응보", 15: "의지", 16: "보호", 17: "반격", 18: "파괴", } if id in name_map: return name_map[id] else: return "???" def map_craft(craft, craft_id): type_str = str(craft['craft_type_id']) return { 'id': craft_id, 'item_id': craft['craft_item_id'], 'type': 'E' if craft['craft_type'] == 1 else 'G', 'set': rune_set_id(int(type_str[:-4])), 'stat': rune_effect_type(int(type_str[-4:-2])), 'grade': int(type_str[-1:]) } def map_rune(rune, rune_id, monster_id=0, monster_uid=0): cvs_map ={ 'slot': rune['slot_no'], 'rune_set': rune_set_id(rune['set_id']), 'rune_grade': rune['class'], 'rune_level': rune['upgrade_curr'], 'pri_eff': rune_effect(rune['pri_eff']), 'pre_eff': rune_effect(rune['prefix_eff']) } if rune_id != None: cvs_map.update({ 'sell_price': rune['sell_value'], 'rune_id': rune_id, 'monster_id': '%s (%s)' % (monster_id, monster_name(monster_uid)) if monster_id != 0 else '0', }) for i in range(0, len(rune['sec_eff'])): cvs_map['sub' + str(i + 1)] = rune_effect(rune['sec_eff'][i]) subs = { 'ATK flat': '-', 'ATK%': '-', 'HP flat': '-', 'HP%': '-', 'DEF flat': '-', 'DEF%': '-', 'RES': '-', 'ACC': '-', 'SPD': '-', 'CDmg': '-', 'CRate': '-', } for sec_eff in rune['sec_eff']: subs[rune_effect_type(sec_eff[0])] = sec_eff[1] + (sec_eff[3] if len(sec_eff) > 2 else 0) optimizer_map = {"id": rune_id, "unique_id": rune['rune_id'], "monster": monster_id, "monster_n":monster_name(monster_uid, "Unknown name"), "set": rune_set_id(rune['set_id']), "slot": rune['slot_no'], "grade": rune['class'], "level": rune['upgrade_curr'], "m_t": rune_effect_type(rune['pri_eff'][0]), "m_v": rune['pri_eff'][1], "i_t": rune_effect_type(rune['prefix_eff'][0]), "i_v": rune['prefix_eff'][1], "locked":0, "sub_res": subs['RES'], "sub_cdmg": subs['CDmg'], "sub_atkf": subs['ATK flat'], "sub_acc": subs['ACC'], "sub_atkp": subs['ATK%'], "sub_defp": subs['DEF%'], "sub_deff": subs['DEF flat'], "sub_hpp": subs['HP%'], "sub_hpf": subs['HP flat'], "sub_spd": subs['SPD'], "sub_crate": subs['CRate']} for sub in range(0,4): optimizer_map['s%s_t' % (sub + 1)] = rune_effect_type(rune['sec_eff'][sub][0]) if len(rune['sec_eff']) >= sub + 1 else "" optimizer_map['s%s_v' % (sub + 1)] = rune['sec_eff'][sub][1] +\ (rune['sec_eff'][sub][3] if len(rune['sec_eff'][sub]) > 2 else 0) \ if len(rune['sec_eff']) >= sub + 1 else 0 optimizer_map['s%s_data' % (sub + 1)] = {"enchanted": rune['sec_eff'][sub][2] == 1, "gvalue": rune['sec_eff'][sub][3]} \ if len(rune['sec_eff']) >= sub + 1 and len(rune['sec_eff'][sub]) > 2 else {} return optimizer_map, cvs_map def map_monster(monster, monster_id_mapping, storage_id, wizard_name=None): csv_map = { 'name': monster_name(monster['unit_master_id']), 'level': monster['unit_level'], 'grade': monster['class'], 'attribute': monster_attribute(monster['attribute']), 'in_storage': "Yes" if monster['building_id'] == storage_id else "No", 'hp': int(monster['con']) * 15, 'atk': monster['atk'], 'def': monster['def'], 'spd': monster['spd'], 'crate': monster['critical_rate'], 'cdmg': monster['critical_damage'], 'res': monster['resist'], 'acc': monster['accuracy'] } if wizard_name is None: csv_map['id'] = monster_id_mapping[monster['unit_id']] else: csv_map.update({'wizard_name' : wizard_name}), if monster_id_mapping: optimizer_monster = {"id": monster_id_mapping[monster['unit_id']], "name":"%s%s" % (monster_name(monster['unit_master_id'], "Unknown name"), " (In Storage)" if monster['building_id'] == storage_id else ""), "level": monster['unit_level'], "unit_id": monster['unit_id'], "master_id": monster['unit_master_id'], "stars": monster['class'], "attribute": monster_attribute(monster['attribute']), "b_hp": int(monster['con']) * 15, "b_atk": monster['atk'], "b_def": monster['def'], "b_spd": monster['spd'], "b_crate": monster['critical_rate'], "b_cdmg": monster['critical_damage'], "b_res": monster['resist'], "b_acc": monster['accuracy']} else: optimizer_monster = None return optimizer_monster, csv_map
Run
Reset
Share
Import
Link
Embed
Language▼
English
中文
Python Fiddle
Python Cloud IDE
Follow @python_fiddle
Browser Version Not Supported
Due to Python Fiddle's reliance on advanced JavaScript techniques, older browsers might have problems running it correctly. Please download the latest version of your favourite browser.
Chrome 10+
Firefox 4+
Safari 5+
IE 10+
Let me try anyway!
url:
Go
Python Snippet
Stackoverflow Question