Syfax 2 Report post Posted June 18, 2016 title explain Quote Share this post Link to post Share on other sites
Eviles 179 Report post Posted June 18, 2016 Open user.lua and find it: decompile_folder_bin('C:/Users/Synyster/Documents/Tales of Pirates/scripts/table',2) change to your folder, the number after mean the version of your client. After it open decompile. Quote Share this post Link to post Share on other sites
MonkeyCode 453 Report post Posted June 18, 2016 I thought his decompiler was coded in python. Also, syfax if you continue to post threads "title explain" without giving your errors, providing codes, explaining your problem, you will not like it. Last warning to you. 2 Quote Share this post Link to post Share on other sites
Wrexor 61 Report post Posted June 18, 2016 17 minutes ago, KONG said: I thought his decompiler was coded in python. Also, syfax if you continue to post threads "title explain" without giving your errors, providing codes, explaining your problem, you will not like it. Last warning to you. There is a version using lua Quote Share this post Link to post Share on other sites
Sultan 68 Report post Posted June 19, 2016 8 hours ago, KONG said: I thought his decompiler was coded in python. Also, syfax if you continue to post threads "title explain" without giving your errors, providing codes, explaining your problem, you will not like it. Last warning to you. I'm glad that I'm not only one here who get pissed about it. You made my day @KONG Quote Share this post Link to post Share on other sites
Wrexor 61 Report post Posted June 20, 2016 3 hours ago, Syfax said: I ask in the time needed so ,i asked this question because when i decompile TOP II Binnaries and open .txt files i see them weirdly written , (choosed it's version) Thanks for the help What Kong meant is that you should say that when creating the thread. How can one help you if he doesn't know what problem you have? 2 Quote Share this post Link to post Share on other sites
V3ct0r 2,117 Report post Posted June 21, 2016 @Syfax do you can share it? We will see how to use it and write a guide. @KONG, @Sultan Why not if title explains the question? There is expression 'Subject' Quote Some useful links / Полезные ссылки Tips for making a topic in 'Questions & Help' / Рекомендации по созданию тем в разделе "Помощь" Server Advertising Section Rules / Правила раздела "Реклама серверов" Available e-mail domains for registration / Допустимые e-mail домены для регистрации User groups / Группы пользователей User ranks / Звания пользователей "Broken" pictures on the forum / "Битые" изображения на форуме Beware of scammers! / Осторожно, мошенники! My developments / Мои разработки Mods for client and server / Моды для клиента и сервера PKOdev.NET website for Tales of Pirates Server / PKOdev.NET веб-обвязка для сервера Пиратии I do not provide any help in private messages and outside the forum. Use 'Questions & Help' section please. Thank you for understanding! Я не оказываю какую-либо помощь в личных сообщениях и вне форума. Пожалуйста, используйте раздел "Пиратия: Помощь". Благодарю за понимание! Share this post Link to post Share on other sites
Lucky 65 Report post Posted June 21, 2016 (edited) 1 hour ago, V3ct0r said: @Syfax do you can share it? We will see how to use it and write a guide. @KONG, @Sultan Why not if title explains the question? There is expression 'Subject' its on my Archive called Deguix Decompiler (lua-jit) https://mega.nz/#!WEIBTS5J!zBj0tvzfVUvuItzJn_YH38wx3mG0vHKR0owfZFzp2dU Edit: i still prefer the pyton decompiler Put this in txt and save it as .py (u must have python installed ) #o-----------------------------------------------------------------------------o #| Bin decompiler v.1.6.2 | #(-----------------------------------------------------------------------------) #| By deguix / An Utility for TOP/PKO/KOP | Compatible w/ Python 3.3 | #| ---------------------------------------------------------| #| | #| This script decompiles the .bin files for most game versions. If any | #| game version isn't supported, please let me know. Configuration section is | #| found at the bottom of the file. | #o-----------------------------------------------------------------------------o import struct from types import * import subprocess #--------------------------------------------- class top_tsv: name = '' file_name = '' list = [] version = '' frombin_map = [('',{'v':0})] def __init__(self, file_name=0, version=0, encoding=0): if (file_name == 0): self.file_name = toptablefolder+self.__class__.__name__ else: self.file_name = file_name if (version == 0): self.version = toptableversion else: self.version = version if (encoding == 0): self.encoding = 'gbk' else: self.encoding = encoding self.list = [] self.frombin_map = [('',{'v':0})] def unencrypt(self): item = [] #Load data file = open(self.file_name+'.bin', 'rb') data = bytearray(file.read()) file.close() i = 0 array_size = int(list(struct.unpack_from('<i',data[i:i+4]))[0]) rdata = data[i:i+4] data = data[i+4:len(data)] m = 0 k = 0 l = len(data)//array_size #2.2 encryption if ((((((self.version >= 4) and (self.version <= 5)) or (self.version == 8)) and ((self.__class__.__name__ != 'magicsingleinfo') and (self.__class__.__name__ != 'magicgroupinfo') and (self.__class__.__name__ != 'resourceinfo') and (self.__class__.__name__ != 'terraininfo')))) or ((self.version >= 6) and (self.version <= 7))): newbytes = bytes.fromhex('98 9D 9F 68 E0 66 AB 70 E9 D1 E0 E0 CB DD D1 CB D5 CF') while(k<l): item = data[i:i+array_size] i = i+array_size if ((((((self.version >= 4) and (self.version <= 5)) or (self.version == 8)) and ((self.__class__.__name__ != 'magicsingleinfo') and (self.__class__.__name__ != 'magicgroupinfo') and (self.__class__.__name__ != 'resourceinfo') and (self.__class__.__name__ != 'terraininfo')))) or ((self.version >= 6) and (self.version <= 7))): for m,c in enumerate(item): j = m % len(newbytes) item[m] = ((item[m] - newbytes[j]) + 256) % 256 rdata = rdata + item k = k + 1 m = 0 file = open(self.file_name+'-un.bin', 'wb') file.write(rdata) file.close() def load_bin_data(self): array = [] item = [] addresses = [] #Load structure (calculate size) struct_type_map={ "char":"c", "byte":"b", "ubyte":"B", "_bool":"?", "short":"h", "ushort":"H", "int":"i", "uint":"I", "long":"l", "ulong":"L", "quad":"q", "uquad":"Q", "float":"f", "double":"d", "str":"s", "color":"B", "rcolor":"B", } struct_vars = {'t':'','s':1,'l':1,'stp':1,'f':-1,'v':-1,'lpad':0,'rpad':0,'sa':-1,'sap':-1,'ea':-1,'eap':-1,'st':'','lm':0,'sm':0,'smb':0,'smea':0,'sv':0,'func':0} #initialize addresses struct_init_address = 0 struct_limit_address = 0 struct_marked_addresses = [0,0,0,0,0,0] struct_func_indexes = [] for i, v in enumerate(list(zip(*self.frombin_map))[1]): struct_item = struct_vars.copy() struct_item.update(v) if struct_item['smb']>=1: struct_marked_addresses[struct_item['smb']] = struct_init_address if struct_item['lm']>=1: struct_init_address = struct_marked_addresses[struct_item['lm']] if struct_item['sm']>=1: struct_marked_addresses[struct_item['sm']] = struct_init_address if (type(struct_item['func']) == FunctionType): struct_func_indexes.append(i) elif (struct_item['v'] == -1): if type(struct_item['t']) == tuple: struct_item['s'] = len(struct_item['t']) struct_item['st'] = [] for j,t in enumerate(struct_item['t']): struct_item['st'].append(struct_type_map[struct_item['t'][j]]) struct_item['st'] = tuple(struct_item['st']) struct_item['s'] = len(struct_item['st']) else: struct_item['st'] = struct_type_map[struct_item['t']] if ((struct_item['t'] == 'color') or (struct_item['t'] == 'rcolor')): struct_item['s'] = 3 struct_item['sa'] = struct_init_address struct_item['sap'] = struct_item['sa'] + struct_item['lpad'] struct_item['ea'] = struct_item['sap'] if type(struct_item['t']) == tuple: for j,t in enumerate(struct_item['t']): struct_item['ea'] = struct_item['ea'] + struct.calcsize(struct_item['st'][j]) * ((struct_item['stp'] * struct_item['l'])-(struct_item['stp']-1)) else: struct_item['ea'] = struct_item['ea'] + struct.calcsize(struct_item['st']) * ((struct_item['s'] * struct_item['stp'] * struct_item['l'])-(struct_item['stp']-1)) if struct_item['smea']>=1: struct_marked_addresses[struct_item['smea']] = struct_item['ea'] struct_item['eap'] = struct_item['ea'] + struct_item['rpad'] struct_init_address = struct_item['eap'] if (struct_init_address > struct_limit_address): struct_limit_address = struct_init_address #print(struct_item) self.frombin_map[i] = (self.frombin_map[i][0],struct_item) struct_size = struct_limit_address #Load data file = open(self.file_name+'.bin', 'rb') data = bytearray(file.read()) file.close() i = 0 k = 0 array_size = int(list(struct.unpack_from('<i',data[i:i+4]))[0]) if array_size != struct_size: print(self.file_name+'.bin: Actual array size ('+str(array_size)+') doesn''t match structure size ('+str(struct_size)+')') raise 'Size error.' data = data[i+4:len(data)] m = 0 k = 0 l = len(data)//struct_size #2.2 encryption if ((((((self.version >= 4) and (self.version <= 5)) or (self.version == 8)) and ((self.__class__.__name__ != 'magicsingleinfo') and (self.__class__.__name__ != 'magicgroupinfo') and (self.__class__.__name__ != 'resourceinfo') and (self.__class__.__name__ != 'terraininfo')))) or ((self.version >= 6) and (self.version <= 7))): newbytes = bytes.fromhex('98 9D 9F 68 E0 66 AB 70 E9 D1 E0 E0 CB DD D1 CB D5 CF') while(k<l): item = data[i:i+struct_size] i = i+struct_size if ((((((self.version >= 4) and (self.version <= 5)) or (self.version == 8)) and ((self.__class__.__name__ != 'magicsingleinfo') and (self.__class__.__name__ != 'magicgroupinfo') and (self.__class__.__name__ != 'resourceinfo') and (self.__class__.__name__ != 'terraininfo')))) or ((self.version >= 6) and (self.version <= 7))): for m,c in enumerate(item): j = m % len(newbytes) item[m] = ((item[m] - newbytes[j]) + 256) % 256 array.append(item) k = k + 1 m = 0 #Associate the data with the structure self.list = [] self.list.append(list(zip(*self.frombin_map))[0]) for y,rawrow in enumerate(array): row = [] for x,cell_struct in enumerate(list(zip(*self.frombin_map))[1]): if type(cell_struct['func']) == FunctionType: cell = [] cell.append('0') row.append(self.transformtostr(cell,**cell_struct)) else: cell = [] if (cell_struct['v'] == -1): i = cell_struct['sap'] for j in range(cell_struct['l']): processed_data=list(struct.unpack_from('<'+str((cell_struct['s']//len(cell_struct['st']))*cell_struct['stp'])+"".join(cell_struct['st']),rawrow,i))[::cell_struct['stp']] #if (x == 4) and (y == 70): # #print(cell_struct['s']) cell.append(processed_data) i=i+cell_struct['s']*struct.calcsize("".join(cell_struct['st']))*cell_struct['stp'] #sizeof here if (cell_struct['t'] == 'rcolor'): cell[0].reverse() else: cell.append(cell_struct['v']) #if y == 70: # print(cell) #'s':0x02,'l':0x08 row.append(self.transformtostr(cell,**cell_struct)) self.list.append(row) for x,row in enumerate(self.list): if x>0: for func_index in struct_func_indexes: self.list[x][func_index] = list(zip(*self.frombin_map))[1][func_index]['func'](func_index, row) deletions = 0 for z,struct_item_name in enumerate(list(zip(*self.frombin_map))[0]): if (struct_item_name == ''): del self.list[x][z-deletions] deletions = deletions + 1 return def i(self,x): for i,v in enumerate(self.list): if(x==v): return i break return -1 def j(self,x): for i,v in enumerate(list(zip(*self.frombin_map))[0]): if(x==v): return i break return -1 def remap(self,v): for i,n in enumerate(list(zip(*v))[0]): if self.j(n) == -1: self.frombin_map.append((list(zip(*v))[0][i],list(zip(*v))[1][i])) else: if (list(zip(*v))[1][i] == {}): del self.frombin_map[self.j(n)] else: self.frombin_map[self.j(n)] = (list(zip(*v))[0][i],list(zip(*v))[1][i]) def bintotsv(self): file = open(self.file_name+'.txt', 'wt', encoding=self.encoding) for i,a in enumerate(self.list): a=list(a) if (i==0): deletions = 0 for z,item in enumerate(a[:]): if (item == ''): del a[z-deletions] deletions = deletions + 1 file.write('//'+'\t'.join(a)) else: #print(a) file.write('\n'+'\t'.join(a)) file.close() return self def trim_nullbytestr(string, flag=0): #flag=1, return "0" when string is empty result = string for i,byte in enumerate(string[:]): if byte == '\00': result = string[:i] break if (flag & 1) and ((string == '\00') or (string == '')): result = '0' return result def transformtostr(self,result,t,s,l,stp,f,v,ea,eap,lpad,rpad,sa,sap,st,sm,lm,smb,smea,sv,func): if v != -1: return str(v) _type = t j = 0 for n,v in enumerate(result[:]): m = 0 if type(t) == tuple: _type = t[j] is_integer = not((_type=="float") or (_type=="double") or (_type=="str") or (_type=="char") or (_type=="_bool")) if is_integer: if f==-1: f=0 for k,w in enumerate(v[:]): if is_integer: #Result: flag=0x0001 = remove FF's, #flag=0x0002 = cut file defect bytes, #flag=0x0004 = remove 0's, #flag=0x0008 = return space instead of nil, #flag=0x0010 = multiply number by 100, #flag=0x0020 = return -1 if empty if ((((f & 0x4) and (w == 0))) or ((f & 0x1) and ((w == (2**8)-1) or (w == (2**16)-1) or (w == (2**32)-1) or (w == (2**64)-1) or (w == -1))) or ((f & 0x2) and ((((_type=="byte") or (_type=="ubyte")) and (w == (2**8)-51)) or (((_type=="short") or (_type=="ushort")) and (w == (2**16)-12851)) or (((_type=="long") or (_type=="ulong")) and (w == (2**32)-842150451)) or (((_type=="quad") or (_type=="uquad")) and (w == (2**64)-3617008641903833651))))): del result[j][m] m=m-1 else: if (f & 0x2 and w == 0): result[j] = result[j][:m] break if (f & 0x10): result[j][m]=result[j][m]*100 result[j][m]=str(result[j][m]) m=m+1 if (_type=="float"): if f==-1: f=3 result[j][k]=str(round(float(w),f)) if (_type=="str"): #flag=0x1 = return "0" when string is empty, #flag=0x2 = strip space characters around string, #flag=0x8 = if first char = null, then make it space if f==-1: f=0 if ((w[0] == 205) and (w[1] == 205)): result[j][m] = '' else: result[j][m] = w.decode(self.encoding,'ignore') if ((f & 0x8) and (w[0] == 0)): result[j][m] = ' ' for o,x in enumerate(result[j][m]): if (x == '\00' or x == '\n'): result[j][m] = result[j][m][:o] break if (f & 0x2): result[j][m] = result[j][m].strip() if ((f & 0x1) and (result[j][m] == '')): result = '0' if (result[j] != '0'): result[j] = ','.join(result[j]) if is_integer: if ((f & 0x20) and (result == '')): result = '-1' elif (result[j] == ''): result[j] = '0' j=j+1 if (_type=="str"): result = ','.join(result) if ((f & 1) and (result == '')): result = '0' else: result = ';'.join(result) if is_integer: if ((f & 0x20) and (result == '')): result = '-1' elif (result == ''): result = '0' return result #--------------------------------------------- #map(None,*list) = zip(*list) class areaset(top_tsv): def __init__(self, file_name=0, version=0, encoding=0): top_tsv.__init__(self, file_name, version, encoding) self.frombin_map = [ ('ID' ,{'t':'ulong','lpad':0x04}), ('Name' ,{'t':'str','s':0x48,'rpad':0x1C,'f':0x08}), ('RGB color' ,{'t':'color','rpad':0x01}), ('Sound effect ID' ,{'t':'long'}), ('Color RGB' ,{'t':'rcolor','rpad':0x01}), ('Lighting RGB value' ,{'t':'rcolor','rpad':0x01}), ('Lighting angle' ,{'t':'float','s':0x03,'f':0x01}), ('Is it city?' ,{'t':'ubyte','rpad':0x03}) ] class characterinfo(top_tsv): def __init__(self, file_name=0, version=0, encoding=0): top_tsv.__init__(self, file_name, version, encoding) self.frombin_map = [ ('ID' ,{'t':'long','lpad':0x04}), ('Name' ,{'t':'str','s':0x48,'rpad':0x40}), ('Short Name' ,{'t':'str','s':0x10,'rpad':0x01}), ('Model Type' ,{'t':'ubyte'}), ('Logic Type' ,{'t':'ubyte','rpad':0x01}), ('Framework Number' ,{'t':'ushort'}), ('Suite Serial' ,{'t':'ushort'}), ('Suite Quantity' ,{'t':'ushort'}), ('Part 00' ,{'t':'ushort'}), ('Part 01' ,{'t':'ushort'}), ('Part 02' ,{'t':'ushort'}), ('Part 03' ,{'t':'ushort'}), ('Part 04' ,{'t':'ushort'}), ('Part 05' ,{'t':'ushort'}), ('Part 06' ,{'t':'ushort'}), ('Part 07' ,{'t':'ushort'}), ('FeffID' ,{'t':'ushort','s':0x02}), ('EeffID' ,{'t':'ushort','rpad':0x04}), ('Special Effect Action Serial' ,{'t':'ushort','s':0x03}), ('Shadow' ,{'t':'ushort'}), ('Action ID' ,{'t':'ushort'}), ('Transparency' ,{'t':'ubyte','rpad':0x01}), ('Moving Sound Effect' ,{'t':'short'}), ('Breathing Sound Effect' ,{'t':'short'}), ('Death Sound Effect' ,{'t':'short'}), ('Can it be controlled?' ,{'t':'ubyte'}), ('Area Limited?' ,{'t':'ubyte'}), ('Altitude Excursion' ,{'t':'short'}), ('Item types that can equip' ,{'t':'short','s':0x06,'rpad':0x1E}), ('Length' ,{'t':'float'}), ('Width' ,{'t':'float'}), ('Height' ,{'t':'float'}), ('Collision Range' ,{'t':'ushort'}), ('Birth' ,{'t':'ubyte','s':0x02,'rpad':0x01}), ('Death' ,{'t':'ubyte','s':0x02,'rpad':0x01}), ('Birth Effect' ,{'t':'ushort'}), ('Death Effect' ,{'t':'ushort'}), ('Hibernate Action' ,{'t':'ubyte','rpad':0x01}), ('Death Instant Action' ,{'t':'ubyte','rpad':0x01}), ('Remaining HP Effect Display' ,{'t':'ulong','s':0x03}), ('Attack can swerve' ,{'t':'ubyte'}), ('Confirm to blow away' ,{'t':'ubyte','rpad':0x02}), ('Script' ,{'t':'ulong'}), ('Weapon Used' ,{'t':'ulong'}), ('Skill ID' ,{'t':'long','s':0x0B,'stp':0x2,'sm':1}), ('Skill Rate' ,{'t':'long','s':0x0B,'stp':0x2,'lm':1,'lpad':0x4}), ('Drop ID' ,{'t':'long','s':0x0A,'stp':0x2,'sm':1}), ('Drop Rate' ,{'t':'long','s':0x0A,'stp':0x2,'lm':1,'lpad':0x4}), ('Quantity Limit' ,{'t':'ulong','sm':1,'lpad':0x50}), ('Fatality Rate' ,{'t':'ulong'}), ('Prefix Lvl' ,{'t':'ulong'}), ('Quest Drop ID' ,{'t':'long','s':0x0A,'stp':0x2,'lm':1,'smb':2}), ('Quest Drop Rate' ,{'t':'long','s':0x0A,'stp':0x2,'lm':1,'lpad':0x4}), ('AI' ,{'t':'ulong','lm':2}), ('Turn?' ,{'t':'ubyte','rpad':0x03}), ('Vision' ,{'t':'ulong'}), ('Noise' ,{'t':'ulong'}), ('GetExp' ,{'t':'ulong'}), ('Light' ,{'t':'ubyte','rpad':0x03}), ('MobExp' ,{'t':'ulong'}), ('Level' ,{'t':'ulong'}), ('Max HP' ,{'t':'long'}), ('Current HP' ,{'t':'long'}), ('Max SP' ,{'t':'long'}), ('Current SP' ,{'t':'long'}), ('Minimum Attack' ,{'t':'long'}), ('Maximum Attack' ,{'t':'long'}), ('Physical Resistance' ,{'t':'long'}), ('Defense' ,{'t':'long'}), ('Hit rate' ,{'t':'long'}), ('Dodge rate' ,{'t':'long'}), ('Critical Chance' ,{'t':'long'}), ('Drop Rate Chance' ,{'t':'long'}), ('HP Recovery Per Cycle' ,{'t':'long'}), ('SP Recovery Per Cycle' ,{'t':'long'}), ('Attack Speed' ,{'t':'long'}), ('Attack Distance' ,{'t':'long'}), ('Chase Distance' ,{'t':'long'}), ('Movement Speed' ,{'t':'long'}), ('Col' ,{'t':'long'}), ('Strength' ,{'t':'long'}), ('Agility' ,{'t':'long'}), ('Accuracy' ,{'t':'long'}), ('Constitution' ,{'t':'long'}), ('Spirit' ,{'t':'long'}), ('Luck' ,{'t':'long'}), ('Left_Rad' ,{'t':'ulong'}), ('Guild ID' ,{'t':'str','s':0x20,'rpad':0x01}), ('Title' ,{'t':'str','s':0x20,'rpad':0x01}), ('Class' ,{'t':'str','s':0x10,'rpad':0x02}), ('Experience' ,{'t':'ulong'}), ('Next Level Experience' ,{'t':'ulong','lpad':0x04}), ('Reputation' ,{'t':'ulong'}), ('AP' ,{'t':'ushort'}), #dunno rly ('TP' ,{'t':'ushort'}), #dunno rly ('GD' ,{'t':'ulong'}), ('SPRI' ,{'t':'ulong'}), ('Story' ,{'t':'ulong'}), ('Max Sail' ,{'t':'ulong'}), ('Sail' ,{'t':'ulong'}), ('StaSA' ,{'t':'ulong'}), ('SCSM' ,{'t':'ulong'}), ('TStrength' ,{'t':'long'}), ('TAgility' ,{'t':'long'}), ('TAccuracy' ,{'t':'long'}), ('TConstitution' ,{'t':'long'}), ('TSpirit' ,{'t':'long'}), ('TLuck' ,{'t':'long'}), ('TMax HP' ,{'t':'long'}), ('TMax SP' ,{'t':'long'}), ('TAttack' ,{'t':'long'}), ('TDefense' ,{'t':'long'}), ('THit Rate' ,{'t':'long'}), ('TDodge Rate' ,{'t':'long'}), ('TDrop Rate Chance' ,{'t':'long'}), ('TCritical Rate Chance' ,{'t':'long'}), ('THP Recovery' ,{'t':'long'}), ('TSP Recovery' ,{'t':'long'}), ('TAttack Speed' ,{'t':'long'}), ('TAttack Distance' ,{'t':'long'}), ('TMovement Speed' ,{'t':'long'}), ('TSPRI' ,{'t':'ulong'}), ('TSCSM' ,{'t':'ulong'}), ('chasf' ,{'t':'float','s':0x03,'rpad':0x4}) ] if self.version == 1: self.remap([ ('Name' ,{'t':'str','s':0x48,'rpad':0x31}), ('Logic Type' ,{'t':'ubyte'}), ('TSCSM' ,{'t':'ulong','rpad':0x4}), ('chasf' ,{}) ]) if self.version >= 3: self.remap([ ('Name' ,{'t':'str','s':0x48,'rpad':0x48}), ('Short Name' ,{'t':'str','s':0x20,'rpad':0x08}), ('Logic Type' ,{'t':'ubyte'}), ('Item types that can equip' ,{'t':'short','s':0x06,'rpad':0x1C}), ('TSCSM' ,{'t':'ulong','rpad':0x08}), ('chasf' ,{'t':'float','s':0x03,'rpad':0xC}) ]) if self.version == 5: self.remap([ ('Name' ,{'t':'str','s':0x48,'rpad':0x48}), ('Short Name' ,{'t':'str','s':0x20,'rpad':0x08}), ('Logic Type' ,{'t':'ubyte'}), ('Item types that can equip' ,{'t':'short','s':0x06,'rpad':0x1C}), ('TSCSM' ,{'t':'ulong','rpad':0x08}), ('chasf' ,{'t':'float','s':0x03,'rpad':0x4}) ]) class characterposeinfo(top_tsv): def __init__(self, file_name=0, version=0, encoding=0): top_tsv.__init__(self, file_name, version, encoding) self.frombin_map = [ ('ID' ,{'t':'ulong','lpad':0x04}), ('Pose' ,{'t':'str','s':0x48,'rpad':0x1C}), ('Fists' ,{'t':'ushort'}), ('Sword' ,{'t':'ushort'}), ('2H Sword' ,{'t':'ushort'}), ('Dual Swords' ,{'t':'ushort'}), ('Firegun' ,{'t':'ushort'}), ('Bow' ,{'t':'ushort'}), ('Dagger' ,{'t':'ushort','rpad':0x02}) ] class chaticons(top_tsv): def __init__(self, file_name=0, version=0, encoding=0): top_tsv.__init__(self, file_name, version, encoding) self.frombin_map = [ ('ID' ,{'t':'ulong','lpad':0x04}), ('File' ,{'t':'str','s':0x48,'rpad':0x2C}), ('?' ,{'t':'ulong'}), ('?' ,{'t':'ulong'}), ('File2' ,{'t':'str','s':0x10}), ('?' ,{'t':'ulong'}), ('?' ,{'t':'ulong'}), ('File3' ,{'t':'str','s':0x10}), ('?' ,{'t':'ulong'}), ('?' ,{'t':'ulong','rpad':0x1C}), ('?' ,{'t':'ulong'}) ] class elfskillinfo(top_tsv): def __init__(self, file_name=0, version=0, encoding=0): top_tsv.__init__(self, file_name, version, encoding) self.frombin_map = [ ('ID' ,{'t':'ulong','lpad':0x04}), ('Name' ,{'t':'str','s':0x48,'rpad':0x1C}), ('Kind ID' ,{'t':'ulong','sm':1,'lpad':0x04}), ('Level' ,{'t':'ulong','lm':1}) ] class eventsound(top_tsv): def __init__(self, file_name=0, version=0, encoding=0): top_tsv.__init__(self, file_name, version, encoding) self.frombin_map = [ ('ID' ,{'t':'ulong','lpad':0x04}), ('Name' ,{'t':'str','s':0x48,'rpad':0x1C}), ('Sound ID' ,{'t':'ulong'}) ] class forgeitem(top_tsv): def __init__(self, file_name=0, version=0, encoding=0): top_tsv.__init__(self, file_name, version, encoding) self.frombin_map = [ ('Level' ,{'t':'ubyte','sm':1,'lpad':0x6C}), ('Failed Level' ,{'t':'str','s':0x48,'lm':1,'smb':2,'lpad':0x08}), ('Success Rate' ,{'t':'ubyte','lm':2,'lpad':0x01,'rpad':0x05}), ('Requirement 1' ,{'t':('ushort','ubyte'),'rpad':0x01}), ('Requirement 2' ,{'t':('ushort','ubyte'),'rpad':0x01}), ('Requirement 3' ,{'t':('ushort','ubyte'),'rpad':0x01}), ('Requirement 4' ,{'t':('ushort','ubyte'),'rpad':0x01}), ('Requirement 5' ,{'t':('ushort','ubyte'),'rpad':0x01}), ('Requirement 6' ,{'t':('ushort','ubyte'),'rpad':0x01}), ('Required Gold' ,{'t':'ulong','lm':2,'lpad':0x03}) ] class hairs(top_tsv): def __init__(self, file_name=0, version=0, encoding=0): top_tsv.__init__(self, file_name, version, encoding) self.frombin_map = [ ('ID' ,{'t':'ulong','lpad':0x04}), ('Name' ,{'t':'str','s':0x48,'rpad':0x1C}), ('Color' ,{'t':'str','s':0x08,'rpad':0x04}), ('Required Item 0' ,{'t':'ulong','s':0x02}), ('Required Item 1' ,{'t':'ulong','s':0x02}), ('Required Item 2' ,{'t':'ulong','s':0x02}), ('Required Item 3' ,{'t':'ulong','s':0x02}), ('Required Gold' ,{'t':'ulong'}), ('Model' ,{'t':'ulong'}), ('Failed Model' ,{'t':'ulong','rpad':0x08}), ('For Lance?' ,{'t':'ubyte'}), ('For Carsise?' ,{'t':'ubyte'}), ('For Phyllis?' ,{'t':'ubyte'}), ('For Ami?' ,{'t':'ubyte','rpad':0x04}) ] if self.version >= 3: self.remap([ ('Color' ,{'t':'str','s':0x20,'rpad':0x08}) ]) class iteminfo(top_tsv): def __init__(self, file_name=0, version=0, encoding=0): top_tsv.__init__(self, file_name, version, encoding) self.frombin_map = [ ('ID' ,{'t':'ulong','lpad':0x04}), ('Name' ,{'t':'str','s':0x4C,'rpad':0x6C}), ('Icon Name' ,{'t':'str','s':0x10,'rpad':0x01}), ('Model (Ground)' ,{'t':'str','s':0x10,'rpad':0x03}), ('Model (Lance)' ,{'t':'str','s':0x10,'rpad':0x03}), ('Model (Carsise)' ,{'t':'str','s':0x10,'rpad':0x03}), ('Model (Phyllis)' ,{'t':'str','s':0x10,'rpad':0x03}), ('Model (Ami)' ,{'t':'str','s':0x10,'rpad':0x03}), ('Ship Symbol' ,{'t':'ushort'}), ('Ship Size' ,{'t':'ushort'}), ('Item Type' ,{'t':'ushort'}), ('Obtain Prefix Rate' ,{'v':0}), ('Set ID' ,{'v':0}), ('Forging Level' ,{'t':'ubyte'}), ('Stable Level' ,{'t':'ubyte'}), ('Repairable' ,{'t':'ubyte'}), ('Tradable' ,{'t':'ubyte'}), ('Pick-upable' ,{'t':'ubyte'}), ('Droppable' ,{'t':'ubyte'}), ('Deletable' ,{'t':'ubyte','smea':1,'rpad':0x23}), ('Max Stack Size' ,{'t':'ulong'}), ('Instance' ,{'t':'ubyte'}), ('Price' ,{'t':'ulong','lm':1,'smb':2,'lpad':0x03}), ('Character Types' ,{'t':'byte','s':4}), ('Character Level' ,{'t':'ushort'}), ('Character Classes' ,{'t':'byte','s':0x13,'rpad':0x03}), ('Character Nick' ,{'v':0}), ('Character Reputation' ,{'v':0}), ('Equipable Slots' ,{'t':'byte','s':0x0A,'lm':2}), ('Item Switch Locations' ,{'t':'byte','s':0x0A}), ('Item Obtain Into Location Determine' ,{'t':'ubyte'}), ('+STR %' ,{'t':'short'}), ('+AGI %' ,{'t':'short'}), ('+ACC %' ,{'t':'short'}), ('+CON %' ,{'t':'short'}), ('+SPR %' ,{'t':'short'}), ('+LUK %' ,{'t':'short'}), ('+Attack Speed %' ,{'t':'short'}), ('+Attack Range %' ,{'t':'short'}), ('+Min Attack %' ,{'t':'short'}), ('+Max Attack %' ,{'t':'short'}), ('+Defense %' ,{'t':'short'}), ('+Max HP %' ,{'t':'short'}), ('+Max SP %' ,{'t':'short'}), ('+Dodge Rate %' ,{'t':'short'}), ('+Hit Rate %' ,{'t':'short'}), ('+Critical Rate %' ,{'t':'short'}), ('+Treasure Drop Rate %' ,{'t':'short'}), ('+HP Recovery %' ,{'t':'short'}), ('+SP Recovery %' ,{'t':'short'}), ('+Movement Speed %' ,{'t':'short'}), ('+Resource Gathering Rate %' ,{'t':'short'}), ('+STR (Min,Max)' ,{'t':'short','s':0x02}), ('+AGI' ,{'t':'short','s':0x02}), ('+ACC' ,{'t':'short','s':0x02}), ('+CON' ,{'t':'short','s':0x02}), ('+SPR' ,{'t':'short','s':0x02}), ('+LUK' ,{'t':'short','s':0x02}), ('+Attack Speed' ,{'t':'short','s':0x02}), ('+Attack Range' ,{'t':'short','s':0x02}), ('+Min Attack' ,{'t':'short','s':0x02}), ('+Max Attack' ,{'t':'short','s':0x02}), ('+Defense' ,{'t':'short','s':0x02}), ('+Max HP' ,{'t':'short','s':0x02}), ('+Max SP' ,{'t':'short','s':0x02}), ('+Dodge' ,{'t':'short','s':0x02}), ('+Hit Rate' ,{'t':'short','s':0x02}), ('+Critical Rate' ,{'t':'short','s':0x02}), ('+Treasure Drop Rate' ,{'t':'short','s':0x02}), ('+HP Recovery' ,{'t':'short','s':0x02}), ('+SP Recovery' ,{'t':'short','s':0x02}), ('+Movement Speed' ,{'t':'short','s':0x02}), ('+Resource Gathering Rate' ,{'t':'short','s':0x02}), ('+Physical Resist' ,{'t':'short','s':0x02}), ('Aftected By Left Hand Efs' ,{'t':'short'}), ('+Energy' ,{'t':'ushort','s':0x02,'sm':1,'lpad':0x04,'smea':2}), ('+Durability' ,{'t':'ushort','s':0x02,'lm':1}), ('Gem Sockets' ,{'t':'ushort','lm':2}), ('Ship Durability Recovery' ,{'v':0}), ('Ship Cannon Amount' ,{'v':0}), ('Ship Member Count' ,{'v':0}), ('Ship Label' ,{'v':0}), ('Ship Cargo Capacity' ,{'v':0}), ('Ship Fuel Consumption' ,{'v':0}), ('Ship Attack Speed' ,{'v':0}), ('Ship Movement Speed' ,{'v':0}), ('Usage Script' ,{'t':'str','s':0x20,'rpad':0x02}), ('Display Effect' ,{'t':'ushort'}), ('Bind Effect' ,{'t':'ushort','s':0x08,'stp':0x2,'sm':1}), ('Bind Effect 2' ,{'t':'ushort','s':0x08,'stp':0x2,'lm':1,'lpad':0x2}), ('1st Inv Slot Effect' ,{'t':'ushort','s':0x02}), ('Drop Model Effect' ,{'t':'ushort','s':0x02}), ('Item Usage Effect' ,{'t':'ushort','s':0x02}), ('Description' ,{'t':'str','s':0x100,'rpad':0x0C,'f':0x01}) ] if self.version == 1: self.remap([ ('Description' ,{'t':'str','s':0x80,'rpad':0x0C,'f':0x01}) ]) if self.version >= 4: self.remap([ ('Equipable Slots' ,{'t':'byte','s':0x0E,'lm':2}), ('Item Switch Locations' ,{'t':'byte','s':0x0E}), ]) if self.version == 7: self.remap([ ('Item Type' ,{'t':'ushort', 'rpad':0x02}), ('Deletable' ,{'t':'ubyte','smea':1,'rpad':0x21}), ('Price' ,{'t':'ulong','lm':1,'smb':2,'lpad':0x01}), ]) class itempre(top_tsv): def __init__(self, file_name=0, version=0, encoding=0): top_tsv.__init__(self, file_name, version, encoding) self.frombin_map = [ ('ID' ,{'t':'ulong','lpad':0x04}), ('Name' ,{'t':'str','s':0x48,'rpad':0x1C}) ] class itemrefineeffectinfo(top_tsv): def __init__(self, file_name=0, version=0, encoding=0): top_tsv.__init__(self, file_name, version, encoding) self.frombin_map = [ ('ID' ,{'t':'ulong','lpad':0x04}), ('Name' ,{'t':'str','s':0x48,'rpad':0x1C}), ('?' ,{'t':'ulong'}), ('ID 1 (Lance)' ,{'t':'ushort','smea':1,'rpad':0x06}), ('ID 1 (Carsise)' ,{'t':'ushort','smea':2,'rpad':0x06}), ('ID 1 (Phyllis)' ,{'t':'ushort','smea':3,'rpad':0x06}), ('ID 1 (Ami)' ,{'t':'ushort','smea':4,'rpad':0x06}), ('? 1' ,{'t':'ubyte','smea':5}), ('ID 2 (Lance)' ,{'t':'ushort','lm':1,'smea':1}), ('ID 2 (Carsise)' ,{'t':'ushort','lm':2,'smea':2}), ('ID 2 (Phyllis)' ,{'t':'ushort','lm':3,'smea':3}), ('ID 2 (Ami)' ,{'t':'ushort','lm':4,'smea':4}), ('? 2' ,{'t':'ubyte','lm':5,'smea':5}), ('ID 3 (Lance)' ,{'t':'ushort','lm':1,'smea':1}), ('ID 3 (Carsise)' ,{'t':'ushort','lm':2,'smea':2}), ('ID 3 (Phyllis)' ,{'t':'ushort','lm':3,'smea':3}), ('ID 3 (Ami)' ,{'t':'ushort','lm':4,'smea':4}), ('? 3' ,{'t':'ubyte','lm':5,'smea':5}), ('ID 4 (Lance)' ,{'t':'ushort','lm':1}), ('ID 4 (Carsise)' ,{'t':'ushort','lm':2}), ('ID 4 (Phyllis)' ,{'t':'ushort','lm':3}), ('ID 4 (Ami)' ,{'t':'ushort','lm':4}), ('? 4' ,{'t':'ubyte','lm':5,'rpad':0x10}) ] class itemrefineinfo(top_tsv): def __init__(self, file_name=0, version=0, encoding=0): top_tsv.__init__(self, file_name, version, encoding) self.frombin_map = [ ('ID' ,{'t':'ulong','lpad':0x04}), ('Name' ,{'t':'str','s':0x48,'rpad':0x1C}), ('?' ,{'t':'ushort'}), ('?' ,{'t':'ushort'}), ('?' ,{'t':'ushort'}), ('?' ,{'t':'ushort'}), ('?' ,{'t':'ushort'}), ('?' ,{'t':'ushort'}), ('?' ,{'t':'ushort'}), ('?' ,{'t':'ushort'}), ('?' ,{'t':'ushort'}), ('?' ,{'t':'ushort'}), ('?' ,{'t':'ushort'}), ('?' ,{'t':'ushort'}), ('?' ,{'t':'ushort'}), ('?' ,{'t':'ushort'}), ('?' ,{'t':'float'}), ('?' ,{'t':'float'}), ('?' ,{'t':'float'}), ('?' ,{'t':'float'}) ] class itemtype(top_tsv): def __init__(self, file_name=0, version=0, encoding=0): top_tsv.__init__(self, file_name, version, encoding) self.frombin_map = [ ('ID' ,{'t':'ulong','lpad':0x04}), ('Name' ,{'t':'str','s':0x48,'rpad':0x1C}) ] class magicgroupinfo(top_tsv): def __init__(self, file_name=0, version=0, encoding=0): top_tsv.__init__(self, file_name, version, encoding) self.frombin_map = [ ('ID' ,{'t':'ulong','lpad':0x04,'rpad':0x64}), ('Name' ,{'t':'str','s':0x20}), ('Number of Types' ,{'t':'ulong'}), ('Types' ,{'t':'long','s':0x08,'f':0x01}), ('Quantities' ,{'t':'long','s':0x08,'rpad':0x04}), ('?' ,{'t':'ulong'}) ] class magicsingleinfo(top_tsv): def __init__(self, file_name=0, version=0, encoding=0): top_tsv.__init__(self, file_name, version, encoding) self.frombin_map = [ ('ID' ,{'t':'ulong','lpad':0x04}), ('Name' ,{'t':'str','s':0x48,'rpad':0x3C}), ('?' ,{'t':'ulong'}), ('?' ,{'t':'str','s':0x18,'l':0x08}), ('?' ,{'t':'ulong'}), ('?' ,{'t':'ulong'}), ('?' ,{'t':'str','s':0x18,'l':0x08}), ('?' ,{'t':'long','s':0x08}), ('?' ,{'t':'ulong'}), ('?' ,{'t':'ulong'}), ('?' ,{'t':'str','s':0x18}) ] class mapinfo(top_tsv): def __init__(self, file_name=0, version=0, encoding=0): top_tsv.__init__(self, file_name, version, encoding) self.frombin_map = [ ('ID' ,{'t':'ulong','lpad':0x04}), ('File' ,{'t':'str','s':0x48,'rpad':0x1C}), ('Name' ,{'t':'str','s':0x10,'smea':1,'rpad':0x17}), ('?' ,{'t':'ubyte'}), ('Coords' ,{'t':'ulong','s':0x02,'lm':1,'rpad':0x0C}), ('?' ,{'v':''}), ('Color' ,{'t':'color'}) ] if self.version == 6: self.remap([ ('Name' ,{'t':'str','s':0x20,'smea':1,'rpad':0x17}) ]) class musicinfo(top_tsv): def __init__(self, file_name=0, version=0, encoding=0): top_tsv.__init__(self, file_name, version, encoding) self.frombin_map = [ ('ID' ,{'t':'ulong','lpad':0x04}), ('File' ,{'t':'str','s':0x48,'rpad':0x1C}), ('?' ,{'t':'ulong'}) ] class notifyset(top_tsv): def __init__(self, file_name=0, version=0, encoding=0): top_tsv.__init__(self, file_name, version, encoding) self.frombin_map = [ ('ID' ,{'t':'ulong','lpad':0x04}), ('?' ,{'t':'str','s':0x48,'rpad':0x1C}), ('Hint Mode' ,{'t':'ubyte'}), ('Message' ,{'t':'str','s':0x40,'rpad':0x03}) ] class objevent(top_tsv): def __init__(self, file_name=0, version=0, encoding=0): top_tsv.__init__(self, file_name, version, encoding) self.frombin_map = [ ('ID' ,{'t':'ulong','lpad':0x04}), ('?' ,{'t':'str','s':0x48,'rpad':0x32}), ('?' ,{'t':'ushort'}), ('?' ,{'t':'ushort'}), ('?' ,{'t':'ushort'}), ('?' ,{'t':'ushort'}), ('?' ,{'t':'ushort'}), ('?' ,{'t':'ushort'}), ('?' ,{'t':'ushort'}), ('?' ,{'t':'ubyte','rpad':0x03}) ] class resourceinfo(top_tsv): def __init__(self, file_name=0, version=0, encoding=0): top_tsv.__init__(self, file_name, version, encoding) self.frombin_map = [ ('ID' ,{'t':'ulong','lpad':0x04}), ('File' ,{'t':'str','s':0x48,'rpad':0x1C}), ('?' ,{'t':'ulong'}) ] class sceneffectinfo(top_tsv): def __init__(self, file_name=0, version=0, encoding=0): top_tsv.__init__(self, file_name, version, encoding) self.frombin_map = [ ('ID' ,{'t':'ulong','lpad':0x04}), ('File' ,{'t':'str','s':0x48,'rpad':0x1C}), ('Name' ,{'t':'str','s':0x10}), ('Image Name' ,{'t':'str','s':0x10,'rpad':0x04}), ('Flag' ,{'t':'ulong'}), ('ObjTypeID' ,{'t':'ulong','rpad':0x04}), ('Dummy' ,{'t':'long','s':0x08,'f':0x21}), ('Dummy 2' ,{'t':'long'}), ('?' ,{'t':'ulong'}), ('?' ,{'t':'float'}), ('?' ,{'t':'float'}), ('?' ,{'t':'float'}) ] def specialdata(cindex,array): if (array[3] == '0'): return array[17] if (array[3] == '3'): return array[6] if (array[3] == '6'): return array[14] return '0' def specialdata2(cindex,array): if (array[3] == '3'): return array[7] if (array[3] == '6'): return array[15] return '0' class sceneobjinfo(top_tsv): def __init__(self, file_name=0, version=0, encoding=0): top_tsv.__init__(self, file_name, version, encoding) self.frombin_map = [ ('ID' ,{'t':'ulong','lpad':0x04}), ('File' ,{'t':'str','s':0x48,'rpad':0x1C}), ('Name' ,{'t':'str','s':0x10}), ('?' ,{'t':'ulong'}), ('?' ,{'v':0,'func':specialdata}), ('?' ,{'v':0,'func':specialdata2}), ('' ,{'t':'ubyte','s':0x03,'rpad':0x09}), ('' ,{'t':('ulong','float','ulong')}), ('?' ,{'t':'ulong','sm':1,'lpad':0x04}), ('?' ,{'t':'ulong','smea':2,'lpad':0x04}), ('?' ,{'t':'ulong','sm':3,'lm':2}), ('?' ,{'t':'ulong','lm':1}), ('?' ,{'t':'ulong','lm':3}), ('?' ,{'t':'ulong'}), ('' ,{'t':'str','s':0x0C}), ('' ,{'t':'ulong','rpad':0x04}), ('?' ,{'t':'ulong','rpad':0x04}), ('' ,{'t':'ulong','s':0x0C,'rpad':0x18,'f':0x02}), #some defect with files makes this flag necessary ] class selectcha(top_tsv): def __init__(self, file_name=0, version=0, encoding=0): top_tsv.__init__(self, file_name, version, encoding) self.frombin_map = [ ('ID' ,{'t':'ulong','lpad':0x04}), ('Name' ,{'t':'str','s':0x48,'rpad':0x20}), ('?' ,{'t':'ulong','smea':1,'rpad':0x100}), ('?' ,{'t':'ulong','s':0x1,'smea':2}), ('?' ,{'t':'ulong','s':0x38,'lm':1}), ('?' ,{'t':'ulong','s':0x1,'lpad':0xFC,'lm':2,'rpad':0xFC}), ('?' ,{'t':'ulong','s':0x1,'rpad':0xFC}), ('?' ,{'t':'ulong','s':0x1,'rpad':0x0514}) ] class serverset(top_tsv): def __init__(self, file_name=0, version=0, encoding=0): top_tsv.__init__(self, file_name, version, encoding) self.frombin_map = [ ('ID' ,{'t':'ulong','lpad':0x04}), ('Name' ,{'t':'str','s':0x48,'rpad':0x1C}), ('Region' ,{'t':'str','s':0x10,'sm':1,'lpad':0x50,'rpad':0x04,'f':0x01}), ('IP #1' ,{'t':'str','s':0x10,'lm':1,'f':0x01}), ('IP #2' ,{'t':'str','s':0x10,'f':0x01}), ('IP #3' ,{'t':'str','s':0x10,'f':0x01}), ('IP #4' ,{'t':'str','s':0x10,'f':0x01}), ('IP #5' ,{'t':'str','s':0x10,'f':0x01}) ] if self.version >= 3: self.remap([ ('Region' ,{'t':'str','s':0x10,'sm':1,'lpad':0x50,'smea':2,'f':0x01}), ('Description' ,{'t':'str','s':0x0100,'lm':2,'lpad':0x01,'rpad':0x04}), ('?' ,{'t':'str','s':0x10,'rpad':0x03}) ]) class shadeinfo(top_tsv): def __init__(self, file_name=0, version=0, encoding=0): top_tsv.__init__(self, file_name, version, encoding) self.frombin_map = [ ('ID' ,{'t':'ulong','lpad':0x04}), ('?' ,{'t':'str','s':0x48,'rpad':0x1C}), ('?' ,{'t':'str','s':0x10,'rpad':0x04}), ('?' ,{'t':'float'}), ('?' ,{'t':'ulong'}), ('?' ,{'t':'ulong'}), ('?' ,{'t':'ulong'}), ('?' ,{'t':'ulong'}), ('?' ,{'t':'ulong'}), ('?' ,{'t':'ulong'}), ('?' ,{'t':'ulong'}), ('?' ,{'t':'ulong'}), ('?' ,{'t':'ulong'}), ('?' ,{'t':'ulong'}) ] def ship15id(cindex,array): return str(int(array[0])+1) class shipinfo(top_tsv): def __init__(self, file_name=0, version=0, encoding=0): top_tsv.__init__(self, file_name, version, encoding) self.frombin_map = [ ('ID' ,{'t':'ulong','lpad':0x04}), ('Name' ,{'t':'str','s':0x48,'rpad':0x5C}), ('Item ID' ,{'t':'ushort','sm':1,'lpad':0x80}), ('Char ID' ,{'t':'ushort'}), ('Action ID' ,{'t':'ushort','rpad':0x0A}), ('Hull' ,{'t':'ushort','sm':2,'lpad':0x80,'smea':3}), ('Engine' ,{'t':'short','s':0x10,'lm':2,'lpad':0x20,'f':0x04}), ('Mobility' ,{'t':'short','s':0x10,'lm':2,'f':0x04}), ('Cannon' ,{'t':'short','s':0x10,'lpad':0x20,'f':0x04}), ('Component' ,{'t':'short','s':0x0C,'f':0x04}), ('Level Restriction' ,{'t':'ushort','lm':3,'rpad':0x02}), ('Class Restriction' ,{'t':'short','rpad':0x1E}), ('Durability' ,{'t':'ushort'}), ('Durability Recovery' ,{'t':'ushort'}), ('Defense' ,{'t':'ushort'}), ('Physical Resist' ,{'t':'ushort'}), ('Min Attack' ,{'t':'ushort'}), ('Max Attack' ,{'t':'ushort'}), ('Attack Range' ,{'t':'ushort'}), ('Reloading Time' ,{'t':'ushort'}), ('Cannon Area of Effect' ,{'t':'ushort'}), ('Cargo Capacity' ,{'t':'ushort'}), ('Fuel' ,{'t':'ushort'}), ('Fuel Consumption' ,{'t':'ushort'}), ('Attack Speed' ,{'t':'ushort'}), ('Movement Speed' ,{'t':'ushort','smea':2}), ('Description' ,{'t':'str','s':0x80,'lm':1}), ('Remark' ,{'t':'ushort','lm':2}) ] if self.version == 1: self.frombin_map[0:0] = [ ('' ,{'t':'ulong','lpad':0x04}) ] self.remap([ ('ID' ,{'v':0,'func':ship15id}) ]) if self.version >= 3: self.remap([ ('Hull' ,{'t':'ushort','sm':2,'lpad':0x98,'smea':3}), ('Engine' ,{'t':'short','s':0x13,'lm':2,'lpad':0x26,'f':0x04}), ('Mobility' ,{'t':'short','s':0x13,'lm':2,'smea':4,'f':0x04}), ('Cannon' ,{'t':'short','s':0x13,'lpad':0x26,'f':0x04}), ('Component' ,{'t':'short','s':0x0F,'f':0x04}), ('Class Restriction' ,{'t':'short','rpad':0x24}), ('Remark' ,{'t':'ushort','lm':2,'rpad':0x02}) ]) class shipiteminfo(top_tsv): def __init__(self, file_name=0, version=0, encoding=0): top_tsv.__init__(self, file_name, version, encoding) self.frombin_map = [ ('ID' ,{'t':'ulong','lpad':0x04}), ('Name' ,{'t':'str','s':0x48,'rpad':0x5C}), ('Model' ,{'t':'ulong','sm':1,'lpad':0x80}), ('Propeller 1' ,{'t':'ushort'}), ('Propeller 2' ,{'t':'ushort'}), ('Propeller 3' ,{'t':'ushort'}), ('Propeller 4' ,{'t':'ushort'}), ('Price' ,{'t':'ulong'}), ('Durability' ,{'t':'ushort'}), ('Durability Recovery' ,{'t':'ushort'}), ('Defense' ,{'t':'ushort'}), ('Physical Resist' ,{'t':'ushort'}), ('Min Attack' ,{'t':'ushort'}), ('Max Attack' ,{'t':'ushort'}), ('Attack Range' ,{'t':'ushort'}), ('Reloading Time' ,{'t':'ushort'}), ('Cannon Area of Effect' ,{'t':'ushort'}), ('Cargo Capacity' ,{'t':'ushort'}), ('Fuel' ,{'t':'ushort'}), ('Fuel Consumption' ,{'t':'ushort'}), ('Attack Speed' ,{'t':'ushort'}), ('Movement Speed' ,{'t':'ushort','smea':2}), ('Description' ,{'t':'str','s':0x80,'lm':1}), ('Remark' ,{'t':'ushort','lm':2,'rpad':0x02}) ] if self.version == 1: self.frombin_map[0:0] = [ ('' ,{'t':'ulong','lpad':0x04}) ] self.remap([ ('ID' ,{'v':0,'func':ship15id}) ]) class skilleff(top_tsv): def __init__(self, file_name=0, version=0, encoding=0): top_tsv.__init__(self, file_name, version, encoding) self.frombin_map = [ ('ID' ,{'t':'ulong','lpad':0x04}), ('Name' ,{'t':'str','s':0x48,'rpad':0x2E}), #to 0x30 ('Activation Interval' ,{'t':'short'}), ('Transfer Persists Duration' ,{'t':'str','s':0x20,'f':0x01}), ('Use Effect Script' ,{'t':'str','s':0x20,'f':0x01}), ('Remove Effect Script' ,{'t':'str','s':0x20,'f':0x01}), ('Can it be Manually Cancelled?' ,{'t':'ubyte'}), ('Can Move?' ,{'t':'ubyte'}), ('Can use Skill?' ,{'t':'ubyte'}), ('Can use Normal Attack?' ,{'t':'ubyte'}), ('Can Trade?' ,{'t':'ubyte'}), ('Can use Items?' ,{'t':'ubyte'}), ('Can Attack?' ,{'t':'ubyte'}), ('Can be Attacked?' ,{'t':'ubyte'}), ('Can be Item Target?' ,{'t':'ubyte'}), ('Can be Skill Target?' ,{'t':'ubyte'}), ('Can be Invisible?' ,{'t':'ubyte'}), ('Can be Seen as Yourself?' ,{'t':'ubyte'}), ('Can use Inventory?' ,{'t':'ubyte'}), ('Can Talk to NPC?' ,{'t':'ubyte'}), ('Remove Effect ID' ,{'t':'ubyte'}), ('Screen Effect' ,{'t':'ubyte'}), ('Client Performance' ,{'t':'ubyte','rpad':0x03}), ('Client Display ID' ,{'t':'short'}), ('Ground Status Effect' ,{'t':'short'}), ('Center Display' ,{'t':'ubyte'}), ('Knock out Display' ,{'t':'ubyte'}), ('Special Effect of Recipe' ,{'t':'ushort'}), ('Dummy 1' ,{'t':'short'}), ('Display Effect When Attacked With?' ,{'t':'ubyte'}), ('Dummy 2' ,{'t':'ubyte','rpad':0x08}) #changed to 0x10 ] if ((self.version == 6) or (self.version == 7)): self.remap([ ('Name' ,{'t':'str','s':0x48,'rpad':0x30,'f':0x01}), ('Dummy 2' ,{'t':'ubyte','rpad':0x0A}) ]) if (self.version >= 8): self.remap([ ('Name' ,{'t':'str','s':0x48,'rpad':0x2E,'f':0x01}), ('Dummy 2' ,{'t':'ubyte','rpad':0x0C}) ]) class skillinfo(top_tsv): def __init__(self, file_name=0, version=0, encoding=0): top_tsv.__init__(self, file_name, version, encoding) self.frombin_map = [ ('ID' ,{'t':'ulong','lpad':0x04}), ('Name' ,{'t':'str','s':0x48,'rpad':0x2F}), ('Not Life Skill?' ,{'t':'byte'}), ('Class Requirement' ,{'t':'byte','s':0x02,'l':0x04,'rpad':0x0A}), ('Left Hand Requirement' ,{'t':'short','s':0x02,'l':0x08}), ('Right Hand Requirement' ,{'t':'short','s':0x02,'l':0x08}), ('Armor Requirement' ,{'t':'short','s':0x02,'l':0x08}), ('Conch Usage' ,{'t':'short','s':0x03,'rpad':0x2A}), ('Skill Phase' ,{'t':'byte'}), ('Skill Type' ,{'t':'byte','smea':1,'rpad':0x16}), ('Useful/Harmful' ,{'t':'byte','smea':2}), ('Learning Level' ,{'t':'short','lm':1}), ('Prerequisite' ,{'t':'short','s':0x02,'l':0x03}), ('Skill Points Consumption' ,{'t':'byte'}), ('Discharged Status' ,{'t':'byte'}), ('Apply Point' ,{'t':'byte','rpad':0x01}), ('Cast Range' ,{'t':'ushort'}), ('Process Target' ,{'t':'byte'}), ('Attack Mode' ,{'t':'byte'}), ('Angle' ,{'t':'short','lm':2,'lpad':0x01}), ('Radius' ,{'t':'short'}), ('Region Shape' ,{'t':'byte'}), ('Prophase Management Formula' ,{'t':'str','s':0x20,'rpad':0x85,'smea':1}), #prev: 0x01 ('Add Surface Formula' ,{'t':'str','s':0x20,'rpad':0x01,'smea':2}), ('SP Formula' ,{'t':'str','s':0x20,'lpad':0x01,'rpad':0x01,'lm':1}), #5 ('Durability Consumption Formula' ,{'t':'str','s':0x20,'rpad':0x01}), ('Top-up Consumption Formula' ,{'t':'str','s':0x20,'rpad':0x01}), #appears as #2 ('Region Formula' ,{'t':'str','s':0x20,'rpad':0x01}), ('Discharge Phase Formula' ,{'t':'str','s':0x20,'lpad':0x01,'rpad':0x01,'lm':2}), ('Effect Phase Formula' ,{'t':'str','s':0x20,'rpad':0x01}), ('Positive Effect Formula' ,{'t':'str','s':0x20,'rpad':0x01}), ('Opposing Effect Formula' ,{'t':'str','s':0x20,'rpad':0x02}), ('Bind Status ID Can Removed Manually' ,{'t':'ulong','rpad':0x16}), ('Self Parameter' ,{'v':0}), ('Self Effect' ,{'v':0}), ('Consumable' ,{'v':0}), ('Duration' ,{'v':0}), ('Target Parameter' ,{'v':0}), ('Splash Parameter' ,{'t':'short'}), ('Duration on Target' ,{'t':'short'}), ('Splash Persists Effect' ,{'t':'short'}), ('Morph ID' ,{'t':'short'}), ('Summon ID' ,{'t':'short','rpad':0x02}), ('Discharge Duration' ,{'v':0}), ('Repeated Discharge Duration' ,{'t':'str','s':0x20,'rpad':0x01}), ('Damage Effect' ,{'t':'short','sm':3,'lpad':0x03}), ('Play Effect' ,{'t':'byte','rpad':0x01}), ('Action' ,{'t':'short','s':0x0A}), ('Keyframe' ,{'t':'short'}), ('Attack Sound Effect' ,{'t':'short'}), ('Character Dummy' ,{'t':'short','s':0x02,'rpad':0x02}), ('Character Effect' ,{'t':'ushort','s':0x02,'rpad':0x02}), ('Base Standard Value' ,{'t':'ushort','s':0x02,'rpad':0x02}), ('Item Dummy' ,{'t':'short'}), ('Item Effect' ,{'t':'short','s':0x02}), ('Item Effect 2' ,{'t':'short','s':0x02}), ('Path of Flight Keyframe' ,{'t':'short'}), ('Character Dummy' ,{'t':'short'}), ('Item Dummy 2' ,{'t':'short'}), ('Path of Flight Effect' ,{'t':'short'}), ('Path of Flight Speed' ,{'t':'short'}), ('Attacked Sound Effect' ,{'t':'short'}), ('Dummy' ,{'t':'short'}), ('Character Attacked Effect' ,{'t':'short'}), ('Effect Duration Point' ,{'t':'byte','rpad':0x01}), ('Surface Attacked Effect' ,{'t':'short'}), ('Water Surface Effect' ,{'t':'short'}), ('Icon' ,{'t':'str','s':0x10,'rpad':0x01}), ('Play Count' ,{'t':'byte','smea':4}), ('Command' ,{'t':'byte','s':0x02,'lm':3}), ('Description' ,{'t':'str','s':0x80,'lm':4}), ('Effect' ,{'t':'str','s':0x80}), ('Consumption' ,{'t':'str','s':0x80,'rpad':0x2E}) ] if self.version == 6: self.remap([ ('Consumption' ,{'t':'str','s':0x80,'rpad':0x32}) ]) class stoneinfo(top_tsv): def __init__(self, file_name=0, version=0, encoding=0): top_tsv.__init__(self, file_name, version, encoding) self.frombin_map = [ ('ID' ,{'t':'ulong','lpad':0x04}), ('File' ,{'t':'str','s':0x48,'rpad':0x1C}), ('Item ID' ,{'t':'ulong'}), ('?' ,{'t':'ulong','s':0x03}), ('?' ,{'t':'ulong'}), ('Script' ,{'t':'str','s':0x40}) ] class terraininfo(top_tsv): def __init__(self, file_name=0, version=0, encoding=0): top_tsv.__init__(self, file_name, version, encoding) self.frombin_map = [ ('ID' ,{'t':'ulong','lpad':0x04}), ('File' ,{'t':'str','s':0x48,'rpad':0x1C}), ('?' ,{'t':'ulong','rpad':0x04}), ('?' ,{'t':'ulong'}) ] class helpinfoset(top_tsv): def __init__(self, file_name=0, version=0, encoding=0): top_tsv.__init__(self, file_name, version, encoding) if self.version >= 3: self.frombin_map = [ ('ID' ,{'t':'ulong','lpad':0x04}), ('Name' ,{'t':'str','s':0x48,'rpad':0x1C}), ('Description' ,{'t':'str','s':0x800}) ] class monsterlist(top_tsv): def __init__(self, file_name=0, version=0, encoding=0): top_tsv.__init__(self, file_name, version, encoding) if self.version >= 3: self.frombin_map = [ ('ID' ,{'t':'ulong','lpad':0x04,'rpad':0x64}), ('Name' ,{'t':'str','s':0x80}), ('Level' ,{'t':'str','s':0x80}), ('Coordinates' ,{'t':'ulong','s':0x02}), ('Map' ,{'t':'str','s':0x80}) ] class npclist(top_tsv): def __init__(self, file_name=0, version=0, encoding=0): monsterlist.__init__(self, file_name, version, encoding) class monsterinfo(top_tsv): def __init__(self, file_name=0, version=0, encoding=0): top_tsv.__init__(self, file_name, version, encoding) if self.version >= 4: self.frombin_map = [ ('ID' ,{'t':'ulong','lpad':0x04}), ('Name' ,{'t':'str','s':0x48,'rpad':0x3C}), ('Start Coordinates' ,{'t':'ulong','s':0x02,'f':0x10}), ('End Coordinates' ,{'t':'ulong','s':0x02,'f':0x10}), ('Char IDs' ,{'t':'ulong','s':0x02,'rpad':0x18}), ('Map' ,{'t':'str','s':0x10,'rpad':0x10}) ] toptablebins = [ areaset, characterinfo, characterposeinfo, chaticons, elfskillinfo, eventsound, forgeitem, hairs, iteminfo, itempre, itemrefineeffectinfo, itemrefineinfo, itemtype, magicgroupinfo, magicsingleinfo, mapinfo, monsterinfo, musicinfo, notifyset, objevent, resourceinfo, sceneffectinfo, sceneobjinfo, serverset, selectcha, shadeinfo, shipinfo, shipiteminfo, skilleff, skillinfo, stoneinfo, terraininfo, helpinfoset, monsterlist, npclist ] def decompile_bin_folder(folder, version, encoding='gbk'): print('Folder to decompile: '+folder) for c in toptablebins: myc = c(folder+c.__name__, version, encoding) try: myc.load_bin_data() except IOError: print('File doesn''t exist: "'+myc.file_name+'.bin') myc.bintotsv() print('Decompiled to file: '+myc.file_name+'.txt') print('Folder decompiled successfully: '+folder) def decompile_bin(file_name, binary, version, encoding='gbk'): print('File to decompile: '+file_name+'.bin. Binary structure to be used: '+binary.__name__) myc = binary(file_name, version, encoding) try: myc.load_bin_data() except IOError: print('File doesn''t exist: "'+myc.file_name+'.bin') myc.bintotsv() print('Decompiled to file: '+file_name+'.txt') def decrypt_bin_folder(folder, version, encoding='gbk'): print('Folder to decrypt: '+folder) for c in toptablebins: myc = c(folder+c.__name__, version, encoding) try: myc.load_bin_data() except IOError: print('File doesn''t exist: "'+myc.file_name+'.bin') myc.unencrypt() print('Decrypted file: '+myc.file_name+'.bin') print('Folder decrypted successfully: '+folder) def compile_bin_gamefolder(folder): print('Folder to compile: '+folder+'scripts/table/') cur_folder = os.getcwd() os.chdir(folder) subprocess.call(['system/game.exe','startgame','table_bin']) os.chdir(cur_folder) print('Folder compiled successfully: '+folder) def translate_bin_folder(folder, version, folder2, version2, encoding='gbk', encoding2='gbk'): #grab data from 1, and translated names from 2. print('Folder to decompile: '+folder) for c in toptablebins: myc = c(folder+c.__name__, version, encoding) try: myc.load_bin_data() except IOError: print('File doesn''t exist: "'+myc.file_name+'.bin') myc2 = c(folder2+c.__name__, version2, encoding2) try: myc2.load_bin_data() except IOError: print('File doesn''t exist: "'+myc2.file_name+'.bin') #translation process: #if 2 ids same, copy name from second to first. #if second id is higher, keep the item in first. #if first id is higher, add the second. i=1 j=1 if ((myc.__class__.__name__ != 'chaticons') and (myc.__class__.__name__ != 'forgeitem') and (myc.__class__.__name__ != 'monsterinfo') and (myc.__class__.__name__ != 'serverset')): while (j<len(myc2.list)): b = myc2.list[j] if (i>=len(myc.list)): myc.list.append(b) i=i+1 j=j+1 else: a = myc.list[i] if a[0] == b[0]: if ((myc.__class__.__name__ != 'helpinfoset') and (myc.__class__.__name__ != 'musicinfo') and (myc.__class__.__name__ != 'resourceinfo') and (myc.__class__.__name__ != 'sceneffectinfo') and (myc.__class__.__name__ != 'shadeinfo') and (myc.__class__.__name__ != 'terraininfo')): a[1] = b[1] if ((myc.__class__.__name__ == 'characterinfo') or (myc.__class__.__name__ == 'hairs') or (myc.__class__.__name__ == 'helpinfoset') or (myc.__class__.__name__ == 'mapinfo') or (myc.__class__.__name__ == 'monsterlist') or (myc.__class__.__name__ == 'npclist') or (myc.__class__.__name__ == 'sceneffectinfo') or (myc.__class__.__name__ == 'sceneobjinfo') or (myc.__class__.__name__ == 'shadeinfo')): a[2] = b[2] if ((myc.__class__.__name__ == 'notifyset') or (myc.__class__.__name__ == 'sceneffectinfo')): a[3] = b[3] if ((myc.__class__.__name__ == 'monsterlist') or (myc.__class__.__name__ == 'npclist')): a[4] = b[4] if ((myc.__class__.__name__ == 'iteminfo')): a[93] = b[93] if ((myc.__class__.__name__ == 'skillinfo')): a[70] = b[70] a[71] = b[71] a[72] = b[72] i=i+1 j=j+1 elif a[0] > b[0]: myc.list.insert(i, myc2.list[j]) j=j+1 elif a[0] < b[0]: i=i+1 i=0 j=0 myc.bintotsv() print('Translated to file: '+myc.file_name+'.txt') print('Folder translated successfully: '+folder) def make_droplist(outfile): char_info = characterinfo() try: char_info.load_bin_data() except IOError: print('"'+char_info.file_name+'.bin'+'" doesn''t exist, skipping...') char_info.bintotsv() item_info = iteminfo() try: item_info.load_bin_data() except IOError: print('"'+item_info.file_name+'.bin'+'" doesn''t exist, skipping...') item_info.bintotsv() file = open(outfile, 'w', encoding=toptableencoding, errors='ignore') all_itemdroprates = [] for i,v in enumerate(item_info.list): if i != 0: item_id = int(v[0]) item_name = str(v[1]) item_droprates = [] for j,w in enumerate(char_info.list): if j != 0: char_name = str(w[1]) print(j) char_dropitems = unjop(w[46]) char_dropitemrates = unjop(w[47]) for k,x in enumerate(char_dropitems[0]): if item_id == int(x): t_droprate = 0 try: t_droprate = round(10000/int(char_dropitemrates[0][k]),6) except ZeroDivisionError: t_droprate = 10000 except IndexError: t_droprate = 10000/4294967295 item_droprates.append((char_name,t_droprate)) break item_droprates.sort(key=lambda a: a[1], reverse=True) all_itemdroprates.append((item_name, item_droprates)) all_itemdroprates.sort(key=lambda a: str.lower(a[0])) i = 0 for item_name, item_droprates in all_itemdroprates: if item_droprates != []: if i != 0: file.write('\n') file.write(item_name + ": ") for j,w in enumerate(item_droprates): if j == 0: file.write(w[0] + "(" + str(w[1]) + "%)") else: file.write(", " + w[0] + "(" + str(w[1]) + "%)") i = i + 1 file.close() def make_cha_droplist(outfile): char_info = characterinfo() try: char_info.load_bin_data() except IOError: print('"'+char_info.file_name+'.bin'+'" doesn''t exist, skipping...') char_info.bintotsv() item_info = iteminfo() try: item_info.load_bin_data() except IOError: print('"'+item_info.file_name+'.bin'+'" doesn''t exist, skipping...') item_info.bintotsv() file = open(outfile, 'w', encoding=toptableencoding, errors='ignore') all_chardroprates = [] for i,v in enumerate(char_info.list): if i != 0: char_name = str(v[1]) char_dropitems = unjop(v[46]) char_dropitemrates = unjop(v[47]) char_droprates = [] for j,w in enumerate(char_dropitems[0]): item_name = "" item_id = int(w) for k,x in enumerate(item_info.list): if item_id == 0: break if k != 0: if item_id == int(x[0]): item_name = str(x[1]) break if item_name == "": break t_droprate = 0 try: t_droprate = round(10000/int(char_dropitemrates[0][j]),6) except ZeroDivisionError: t_droprate = 10000 except IndexError: t_droprate = 10000/4294967295 char_droprates.append((item_name,t_droprate)) char_droprates.sort(key=lambda a: a[1], reverse=True) all_chardroprates.append((char_name, char_droprates)) all_chardroprates.sort(key=lambda a: str.lower(a[0])) i = 0 for char_name, char_droprates in all_chardroprates: if char_droprates != []: if i != 0: file.write('\n') file.write(char_name + ": ") for j,w in enumerate(char_droprates): if j == 0: file.write(w[0] + "(" + str(w[1]) + "%)") else: file.write(", " + w[0] + "(" + str(w[1]) + "%)") i = i + 1 file.close() def fixskillscripts(): for c in toptablebins: myc = c() try: myc.load_bin_data() except IOError: print('"'+myc.file_name+'.bin'+'" doesn''t exist, skipping...') if ((myc.__class__.__name__ == 'skillinfo')): file = open(toptablefolder + 'skillinfo.funcs.txt', 'wt', encoding=toptableencoding) for line_number, data in enumerate(myc.list): if line_number != 0: mydata = list(data) mylist = list(range(22,32)) mylist[len(mylist):len(mylist)] = [44] for function_effect_id in mylist: if (mydata[function_effect_id] != '0'): params1 = 'l' params2 = 'l' event_number = function_effect_id-22 if (event_number == 22): #44-22 event_number = 10 if (event_number == 7): params1 = 'a,d,l' params2 = 'l,a,d' if ((event_number == 6) or (event_number == 8) or (event_number == 9)): params1 = 'a,l' params2 = 'l,a' file.write('function '+'Skill_'+str(mydata[0])+'_'+str(event_number)+'('+params1+')\treturn skill(0,'+str(mydata[0])+','+str(event_number)+','+params2+') end --'+mydata[function_effect_id]+'\n') mydata[function_effect_id] = 'Skill_'+str(mydata[0])+'_'+str(event_number) mydata = tuple(mydata) myc.list[line_number] = mydata file.close() if ((myc.__class__.__name__ == 'skilleff')): file = open(toptablefolder + 'skilleff.funcs.txt', 'wt', encoding=toptableencoding) for line_number, data in enumerate(myc.list): if line_number != 0: mydata = list(data) for function_effect_id in list(range(3,6)): if (mydata[function_effect_id] != '0'): params1 = 'l' params2 = 'l' event_number = function_effect_id-3 if ((event_number == 1) or (event_number == 2)): params1 = 'a,l' params2 = 'l,a' file.write('function '+'Skill_Effect_'+str(mydata[0])+'_'+str(event_number)+'('+params1+')\treturn skill(1,'+str(mydata[0])+','+str(event_number)+','+params2+') end --'+mydata[function_effect_id]+'\n') mydata[function_effect_id] = 'Skill_Effect_'+str(mydata[0])+'_'+str(event_number) mydata = tuple(mydata) myc.list[line_number] = mydata file.close() if ((myc.__class__.__name__ == 'iteminfo')): file = open(toptablefolder + 'iteminfo.funcs.txt', 'wt', encoding=toptableencoding) for line_number, data in enumerate(myc.list): if line_number != 0: mydata = list(data) function_effect_id = 86 if (mydata[function_effect_id] != '0'): params1 = 'p,i' params2 = 'p,i' file.write('function '+'Item_Skill_'+str(mydata[0])+'('+params1+')\treturn skill(2,'+str(mydata[0])+',0,0,'+params2+') end --'+mydata[function_effect_id]+'\n') mydata[function_effect_id] = 'Item_Skill_'+str(mydata[0]) mydata = tuple(mydata) myc.list[line_number] = mydata file.close() myc.bintotsv() print('Finished successfully.') ''' for c in toptablebins: myc = c() try: myc.load_bin_data() except IOError: print('"'+myc.file_name+'.bin'+'" doesn''t exist, skipping...') if ((myc.__class__.__name__ == 'iteminfo')): file = open(toptablefolder + 'iteminfo.books.txt', 'wt', encoding=toptableencoding) for line_number, data in enumerate(myc.list): if line_number != 0: mydata = list(data) id_id = 0 name_id = 1 item_type_id = 10 if (mydata[item_type_id] == '34'): file.write('skills[ITEM_SKILL]['+mydata[id_id]+'][0] = function(s) itemskill_learnplayerskillbook(s, SK_'+mydata[name_id]+') end\n') mydata = tuple(mydata) myc.list[line_number] = mydata file.close() myc.bintotsv() print('Finished successfully.') ''' ''' for c in toptablebins: myc = c() try: myc.load_bin_data() except IOError: print('"'+myc.file_name+'.bin'+'" doesn''t exist, skipping...') myc.bintotsv() if (myc.file_name == 'iteminfo'): equip_list = [] #print(myc.list[1]) for i, a in enumerate(myc.list): if (i!=0): if (a[28].split(',')[0] != '-1'): myitem = [] myitem.append(a[1]) myitem.append(a[0]) myitem.append(a[10]) for x in a[28].split(',')[0:2]: if (x=='-2'): x='' myitem.append(x) myitem.append(a[24]) for x in a[23].split(',')[0:4]: if ((x=='-1') or (x=='-2')): x='' myitem.append(x) for x in a[25].split(',')[0:19]: if ((x=='-1') or (x=='-2')): x='' myitem.append(x) myitem.append(a[31]) myitem.append(a[32]) myitem.append(a[33]) myitem.append(a[34]) myitem.append(a[35]) myitem.append(a[36]) myitem.append(a[42]) myitem.append(a[43]) myitem.append(a[39]) myitem.append(a[40]) myitem.append(a[41]) myitem.append(a[45]) myitem.append(a[44]) myitem.append(a[47]) myitem.append(a[46]) myitem.append(a[48]) myitem.append(a[49]) myitem.append(a[37]) myitem.append(a[50]) myitem.append(a[52].split(',')[0]) myitem.append(a[52].split(',')[1]) myitem.append(a[53].split(',')[0]) myitem.append(a[53].split(',')[1]) myitem.append(a[54].split(',')[0]) myitem.append(a[54].split(',')[1]) myitem.append(a[55].split(',')[0]) myitem.append(a[55].split(',')[1]) myitem.append(a[56].split(',')[0]) myitem.append(a[56].split(',')[1]) myitem.append(a[57].split(',')[0]) myitem.append(a[57].split(',')[1]) myitem.append(a[63].split(',')[0]) myitem.append(a[63].split(',')[1]) myitem.append(a[64].split(',')[0]) myitem.append(a[64].split(',')[1]) myitem.append(a[60].split(',')[0]) myitem.append(a[60].split(',')[1]) myitem.append(a[61].split(',')[0]) myitem.append(a[61].split(',')[1]) myitem.append(a[62].split(',')[0]) myitem.append(a[62].split(',')[1]) myitem.append(a[72].split(',')[0]) myitem.append(a[72].split(',')[1]) myitem.append(a[66].split(',')[0]) myitem.append(a[66].split(',')[1]) myitem.append(a[65].split(',')[0]) myitem.append(a[65].split(',')[1]) myitem.append(a[68].split(',')[0]) myitem.append(a[68].split(',')[1]) myitem.append(a[67].split(',')[0]) myitem.append(a[67].split(',')[1]) myitem.append(a[69].split(',')[0]) myitem.append(a[69].split(',')[1]) myitem.append(a[70].split(',')[0]) myitem.append(a[70].split(',')[1]) myitem.append(a[58].split(',')[0]) myitem.append(a[58].split(',')[1]) myitem.append(a[71].split(',')[0]) myitem.append(a[71].split(',')[1]) equip_list.append(myitem) file = open(toptablefolder + 'iteminfo.equip.txt', 'wt', encoding=toptableencoding) for i,a in enumerate(equip_list): a=list(a) if (i==0): file.write('\t'.join(a)) else: file.write('\n'+'\t'.join(a)) file.close() if (myc.file_name == 'iteminfo'): equip_list = [] #for i, a in myc.list: # if (item[24] != '0'): # equip_list.append([a[1],]) file = open(toptablefolder + 'iteminfo.equip.txt', 'wt', encoding=toptableencoding) for i,a in enumerate(equip_list): a=list(a) if (i==0): file.write('//'+'\t'.join(a)) else: file.write('\n'+'\t'.join(a)) file.close() ''' ''' def unjop(s): result = s.split(";") for i,v in enumerate(result): result[i] = s.split(",") return result #TODO: improve drasticly these algorithms from collections import OrderedDict def make_itemmodellist(outfile): item_info = iteminfo() try: item_info.load_bin_data() except IOError: print('"'+item_info.file_name+'.bin'+'" doesn''t exist, skipping...') item_info.bintotsv() file = open(outfile, 'w', encoding=toptableencoding, errors='ignore') all_modelitems = OrderedDict() for i,v in enumerate(item_info.list): if i != 0: item_id = int(v[0]) item_name = str(v[1]) item_modellance = str(v[4]) item_modelcarsise = str(v[5]) item_modelphyllis = str(v[6]) item_modelami = str(v[7]) try: all_modelitems[item_modellance].append(item_name + ' (Lance)') except KeyError: all_modelitems[item_modellance] = [] all_modelitems[item_modellance].append(item_name + ' (Lance)') try: all_modelitems[item_modelcarsise].append(item_name + ' (Carsise)') except KeyError: all_modelitems[item_modelcarsise] = [] all_modelitems[item_modelcarsise].append(item_name + ' (Carsise)') try: all_modelitems[item_modelphyllis].append(item_name + ' (Phyllis)') except KeyError: all_modelitems[item_modelphyllis] = [] all_modelitems[item_modelphyllis].append(item_name + ' (Phyllis)') try: all_modelitems[item_modelami].append(item_name + ' (Ami)') except KeyError: all_modelitems[item_modelami] = [] all_modelitems[item_modelami].append(item_name + ' (Ami)') all_modelitems = sorted(all_modelitems.items(), key=lambda t: t[0]) i = 0 for model, item_names in all_modelitems: if model != '0': if i != 0: file.write('\n') file.write(model + ": ") for j,w in enumerate(item_names): if j == 0: file.write(w) else: file.write(", " + w) i = i + 1 file.close() ''' def unjop(s): result = s.split(";") for i,v in enumerate(result): result[i] = s.split(",") return result def make_droplist(outfile): char_info = characterinfo() try: char_info.load_bin_data() except IOError: print('"'+char_info.file_name+'.bin'+'" doesn''t exist, skipping...') char_info.bintotsv() item_info = iteminfo() try: item_info.load_bin_data() except IOError: print('"'+item_info.file_name+'.bin'+'" doesn''t exist, skipping...') item_info.bintotsv() file = open(outfile, 'w', encoding=toptableencoding, errors='ignore') all_itemdroprates = [] for i,v in enumerate(item_info.list): if i != 0: item_id = int(v[0]) item_name = str(v[1]) item_droprates = [] for j,w in enumerate(char_info.list): if j != 0: char_name = str(w[1]) print(j) char_dropitems = unjop(w[46]) char_dropitemrates = unjop(w[47]) for k,x in enumerate(char_dropitems[0]): if item_id == int(x): t_droprate = 0 try: t_droprate = round(10000/int(char_dropitemrates[0][k]),6) except ZeroDivisionError: t_droprate = 10000 except IndexError: t_droprate = 10000/4294967295 item_droprates.append((char_name,t_droprate)) break item_droprates.sort(key=lambda a: a[1], reverse=True) all_itemdroprates.append((item_name, item_droprates)) all_itemdroprates.sort(key=lambda a: str.lower(a[0])) i = 0 for item_name, item_droprates in all_itemdroprates: if item_droprates != []: if i != 0: file.write('\n') file.write(item_name + ": ") for j,w in enumerate(item_droprates): if j == 0: file.write(w[0] + "(" + str(w[1]) + "%)") else: file.write(", " + w[0] + "(" + str(w[1]) + "%)") i = i + 1 file.close() def make_cha_droplist(outfile): char_info = characterinfo() try: char_info.load_bin_data() except IOError: print('"'+char_info.file_name+'.bin'+'" doesn''t exist, skipping...') char_info.bintotsv() item_info = iteminfo() try: item_info.load_bin_data() except IOError: print('"'+item_info.file_name+'.bin'+'" doesn''t exist, skipping...') item_info.bintotsv() file = open(outfile, 'w', encoding=toptableencoding, errors='ignore') all_chardroprates = [] for i,v in enumerate(char_info.list): if i != 0: char_name = str(v[1]) char_dropitems = unjop(v[46]) char_dropitemrates = unjop(v[47]) char_droprates = [] for j,w in enumerate(char_dropitems[0]): item_name = "" item_id = int(w) for k,x in enumerate(item_info.list): if item_id == 0: break if k != 0: if item_id == int(x[0]): item_name = str(x[1]) break if item_name == "": break t_droprate = 0 try: t_droprate = round(10000/int(char_dropitemrates[0][j]),6) except ZeroDivisionError: t_droprate = 10000 except IndexError: t_droprate = 10000/4294967295 char_droprates.append((item_name,t_droprate)) char_droprates.sort(key=lambda a: a[1], reverse=True) all_chardroprates.append((char_name, char_droprates)) all_chardroprates.sort(key=lambda a: str.lower(a[0])) i = 0 for char_name, char_droprates in all_chardroprates: if char_droprates != []: if i != 0: file.write('\n') file.write(char_name + ": ") for j,w in enumerate(char_droprates): if j == 0: file.write(w[0] + "(" + str(w[1]) + "%)") else: file.write(", " + w[0] + "(" + str(w[1]) + "%)") i = i + 1 file.close() #from os.path import join, getsize #for root, dirs, files in os.walk('.'): # if(root == '.'): # for filename in files: # if (filename[-4:] == ".bin"): # print(filename) #key for sql inventory/bank/tempinv: 31 39 38 30 30 32 31 36 31, same decryption method. import re def make_res(): res = [] areaset_list = [] mapinfo_list = [] color_list = [] for c in toptablebins: myc = c() try: myc.load_bin_data() except IOError: print('"'+myc.file_name+'.bin'+'" doesn''t exist, skipping...') #translation process: #if 2 ids same, copy name from second to first. #if second id is higher, keep the item in first. #if first id is higher, add the second. i=1 j=1 print(myc.file_name) #TABLE_characterinfo_TXT_N_1356# if ((myc.__class__.__name__ != 'chaticons') and (myc.__class__.__name__ != 'forgeitem') and (myc.__class__.__name__ != 'monsterinfo')): while (i<len(myc.list)): if (myc.__class__.__name__ == 'areaset'): areaset_list.append(myc.list[i][:]) if (myc.__class__.__name__ == 'mapinfo'): mapinfo_list.append(myc.list[i][:]) a = myc.list[i] if ((myc.__class__.__name__ != 'helpinfoset') and (myc.__class__.__name__ != 'mapinfo') and (myc.__class__.__name__ != 'musicinfo') and (myc.__class__.__name__ != 'resourceinfo') and (myc.__class__.__name__ != 'sceneffectinfo') and (myc.__class__.__name__ != 'sceneobjinfo') and (myc.__class__.__name__ != 'shadeinfo') and (myc.__class__.__name__ != 'terraininfo')): res.append(('T_'+myc.__class__.__name__+'_TXT_'+str(a[0]),a[1])) a[1] = ('#T_'+myc.__class__.__name__+'_TXT_'+str(a[0])+'#').upper() if (myc.__class__.__name__ == 'characterinfo'): a[2] = ('#T_'+myc.__class__.__name__+'_TXT_'+str(a[0])+'#').upper() if ((myc.__class__.__name__ == 'hairs')): temp = 1 for j,v in enumerate(color_list): if (v[1] == a[2]): temp = 0 a[2] = '#T_COLOR_'+str(j)+'#' if temp == 1: color_list.append(('T_COLOR_'+str(len(color_list)),a[2])) res.append(('T_COLOR_'+str(len(color_list)-1),a[2])) a[2] = '#T_COLOR_'+str(len(color_list)-1)+'#' if (myc.__class__.__name__ == 'sceneffectinfo'): res.append(('T_sei_'+str(a[0]),a[2])) a[2] = ('#T_sei_'+str(a[0])+'#').upper() res.append(('T_seiD_'+str(a[0]),a[3])) a[3] = ('#T_seiD_'+str(a[0])+'#').upper() if (myc.__class__.__name__ == 'shadeinfo'): res.append(('T_si_'+str(a[0]),a[2])) a[2] = ('#T_si_'+str(a[0])+'#').upper() if (myc.__class__.__name__ == 'mapinfo'): res.append(('T_mi_'+str(a[0]),a[2])) a[2] = ('#T_mi_'+str(a[0])+'#').upper() if (myc.__class__.__name__ == 'sceneobjinfo'): res.append(('T_soi_'+str(a[0]),a[2])) a[2] = ('#T_soi_'+str(a[0])+'#').upper() if ((myc.__class__.__name__ == 'monsterlist') or (myc.__class__.__name__ == 'npclist')): for j,v in enumerate(mapinfo_list): if (a[4][:15] == v[2]): a[4] = ('#T_mi_'+str(v[0])+'#').upper() break if (myc.__class__.__name__ == 'npclist'): temp = 1 for j,v in enumerate(areaset_list): if (a[2] == v[1]): temp = 0 a[2] = ('#T_AREASET_TXT_'+str(v[0])+'#').upper() break if temp == 1: for j,v in enumerate(mapinfo_list): if (a[2][:15] == v[2]): temp = 0 a[2] = ('#T_mi_'+str(v[0])+'#').upper() break if ((myc.__class__.__name__ == 'iteminfo')): res.append(('T_'+myc.__class__.__name__+'_TXT_D_'+str(a[0]),a[93])) a[93] = ('#T_'+myc.__class__.__name__+'_TXT_D_'+str(a[0])+'#').upper() if ((myc.__class__.__name__ == 'skillinfo')): res.append(('T_'+myc.__class__.__name__+'_TXT_D_'+str(a[0]),a[70])) a[70] = ('#T_'+myc.__class__.__name__+'_TXT_D_'+str(a[0])+'#').upper() res.append(('T_'+myc.__class__.__name__+'_TXT_F_'+str(a[0]),a[71])) a[71] = ('#T_'+myc.__class__.__name__+'_TXT_F_'+str(a[0])+'#').upper() res.append(('T_'+myc.__class__.__name__+'_TXT_U_'+str(a[0]),a[72])) a[72] = ('#T_'+myc.__class__.__name__+'_TXT_U_'+str(a[0])+'#').upper() i=i+1 i=0 myc.bintotsv() file = open('C:/Utenti/Alen/Desktop/res.txt', 'w', encoding=toptableencoding, errors='ignore') while (i<len(res)): file.write(res[i][0].upper()+' { "'+re.sub(r'([\"])', r'\\\1', re.sub(r'\\\"', r'"', res[i][1]))+'" }\n') i=i+1 file.close() print('Finished successfully.') ######################### # Configuration section # ######################### #Version history: #2.5 PKO: +4 bytes to skilleff.bin (2 of those added to the end instead of next to the name, like the other 2 versions). #2.5 KOP: +4 bytes to skilleff.bin, all files encrypted, can compile ResourceInfo. #2.5 TOP: +4 bytes to skilleff.bin and skillinfo.bin, all files encrypted, can compile ResourceInfo. #2.4 server: 2.4 with -8 bytes on characterinfo. #2.4: +4 equipment slots, +4 item switch locations (8 bytes), +monsterinfo added, +encryption of magicsingleinfo, magicgroupinfo, resourceinfo, terraininfo. #2.0: all: Too many changes to list, but most important is helpinfoset, monsterlist, and npclist added, stringset replaced with the .res file in the system folder. #1.38: all: added chasf to characterinfo (and many extra bytes), and fix shipinfo/shipiteminfo id being +1 than should be. Base version. #1.35: all: Earliest version supported. #Version numbers: #8 for PKO v2.5 (latest). #7 for KOP v2.5 (latest). #6 for TOP v2.5 (latest). #5 for PKO v2.4 server only (decompiling server bins will result in resolved resource strings, which can then be used on other versions). #4 for PKO v2.4 (used by the newer v2 servers). #3 for TOP v2.0 (used by all older v2 servers). #2 for TOP v1.38 (latest). #1 for TOP v1.35 (used by a couple of servers). #decompile_bin_folder('C:/Decompiler/PKO1.38/table/', 2, encoding='gbk') #decompile_bin_folder('C:/Games/TOP2.5/scripts/table/', 6, encoding='gbk') #decompile_bin_folder('C:/Games/PKO2.5/scripts/table/', 8) #decompile_bin_folder('C:/Games/KOP2.5/scripts/table/', 7) decompile_bin_folder('C:/Decompiler/PKO2.4/table/', 4) #compile_bin_gamefolder('C:/Games/TOP/') #decrypt_bin_folder('C:/Games/TOP2.5/scripts/table/', 6, encoding='gbk') #decrypt_bin_folder('C:/Games/PKO2.5/scripts/table/', 8, encoding='gbk') #decompile_bin('C:/Games/TOP2.5/scripts/table/sceneffectinfo', sceneffectinfo, 6, encoding='gbk') #without ".bin" #decompile_bin('C:/Games/TOP2.5/scripts/table/characterinfo', characterinfo, 6, encoding='gbk') #without ".bin" #decompile_bin('C:/Games/TOP2.5/scripts/table/serverset', serverset, 6, encoding='gbk') #without ".bin" #translate_bin_folder('C:/Games/PKO2.5/scripts/table/', 8, 'C:/Games/TOP2.5/scripts/table/', 6) #make_res() #remember, need to compile before doing the next translation #compile_bin_gamefolder('C:/Games/PKO2.5/') #translate_bin_folder('C:/Games/KOP2.5/scripts/table/', 7, 'C:/Games/PKO2.5/scripts/table/', 8) #make_res() #translate_bin_folder('C:/Games/KOP2.5/scripts/table/', 7, 'C:/Games/TOP2.5/scripts/table/', 6) #make_res() #toptablefolder = 'C:/Games/PKO2.4/scripts/table/' #toptableversion = 4 #make_itemmodelsunique(1) #automatically fix skill scripts (needed because of adjustments in skillinfo - compile before doing this) #fixskillscripts() #make_cha_droplist("C:/Games (x86)/TOP/rzo2/scripts/table/chardroplist.txt") #make_droplist("C:/Games (x86)/TOP/rzo2/scripts/table/itemdroplist.txt") #make_res() ################################ # End of configuration section # ################################ Edited June 21, 2016 by Lucky Quote Share this post Link to post Share on other sites