218 lines
8.0 KiB
Python
218 lines
8.0 KiB
Python
import mmap
|
|
import struct
|
|
from pathlib import Path
|
|
import json
|
|
|
|
def read_until_null(indx: int, data: tuple) -> int:
|
|
end = indx
|
|
while end + 1 < len(data):
|
|
## Read 2 bytes at a time until null found
|
|
if data[end:end+2] == b"\x00\x00":
|
|
break
|
|
end += 2
|
|
return end
|
|
|
|
def read_until_space(indx: int, data: tuple) -> int:
|
|
end = indx
|
|
while end + 1 < len(data):
|
|
## Read 2 bytes at a time until null found
|
|
if data[end:end+2] == b"\x4F\x00":
|
|
break
|
|
end += 2
|
|
return end
|
|
|
|
|
|
# 8 bytes at a time
|
|
cd_db = {}
|
|
def get_props():
|
|
test = 0
|
|
for r in range(0,len(offsets_data),8):
|
|
test += 1
|
|
# offsets_data[4:8].hex()
|
|
card_index_name_data = int.from_bytes( offsets_data[r:r+4], byteorder='little', signed=False )
|
|
if card_index_name_data == 0:
|
|
continue
|
|
#card_index_desc_data = int.from_bytes( offsets_data[r+4:r+8], byteorder='little' )
|
|
#card_id = card_id[::-1]
|
|
#read until null found
|
|
# end = card_index_name_data
|
|
# while end + 1 < len(name_data):
|
|
# ## Read 2 bytes at a time until null found
|
|
# if name_data[end:end+2] == b"\x00\x00":
|
|
# break
|
|
# end += 2
|
|
# name = name_data[card_index_name_data:end].decode("utf-16le", errors="replace")
|
|
end_index = read_until_null(card_index_name_data, name_data)
|
|
name = name_data[card_index_name_data:end_index].decode("utf-16le", errors="replace")
|
|
print(name)
|
|
if name == '':
|
|
continue
|
|
#print(card_id.hex(' '))
|
|
# 2. Get last 14 bits using mask 0x3FFF (binary 11 1111 1111 1111)
|
|
#print([bin(x) for x in card_first])
|
|
# if test > 3:
|
|
# break;
|
|
#print(prop_data[r:r+8])
|
|
if cd_db.get(test) is None:
|
|
cd_db[test] = {}
|
|
# {
|
|
# f"name_{language_code}":name,
|
|
# f"desc_{language_code}": 'foo',
|
|
# f"name_addr_{language_code}": hex(card_index_name_data),
|
|
# f"desc_addr_{language_code}": hex(card_index_desc_data)
|
|
# }
|
|
cd_db[test][f"name_{language_code}"] = name
|
|
#cd_db[card_id][f"desc_{language_code}"] = desc
|
|
cd_db[test][f"name_addr_{language_code}"] = hex(card_index_name_data)
|
|
#cd_db[card_id][f"desc_addr_{language_code}"] = hex(card_index_desc_data)
|
|
|
|
language_code = 'E'
|
|
#offsets_data = Path(f"YGO_2020/bin/DLG_Indx_{language_code}.bin").read_bytes() # Get all the bytes
|
|
e_name_data = Path(f"YGO_2020/main/howto_db/howtoplay_{language_code}.bin").read_bytes() # Get all the bytes
|
|
#get_props()
|
|
language_code = 'J'
|
|
j_name_data = Path(f"YGO_2020/main/howto_db/howtoplay_{language_code}.bin").read_bytes() # Get all the bytes
|
|
|
|
print("now what?")
|
|
|
|
count_of_items = int.from_bytes(e_name_data[0:4], byteorder='big') # 202
|
|
## 202 * 8 = 1616 (Thats about where this started)
|
|
|
|
|
|
help_dump = {}
|
|
i_e = 1624
|
|
i_j = 1624
|
|
c = 1
|
|
while (i_e < len(e_name_data) and i_j < len(j_name_data)):
|
|
help_dump[c] = {}
|
|
e = read_until_null(i_e,e_name_data)
|
|
help_dump[c]['en'] = e_name_data[i_e:e].decode("utf-16be", errors="replace")
|
|
print(help_dump[c]['en'] )
|
|
i_e = e + 2
|
|
e = read_until_null(i_j,j_name_data)
|
|
help_dump[c]['ja'] = j_name_data[i_j:e].decode("utf-16be", errors="replace")
|
|
print(help_dump[c]['ja'])
|
|
i_j = e + 2
|
|
c+=1
|
|
print(c, " - strings extracted.")
|
|
# c = 333 not sure how to index these anymore
|
|
with open("helptext_dump.json", "w", encoding="utf-8") as outfile:
|
|
json.dump(help_dump, outfile, ensure_ascii=False, indent=2)
|
|
|
|
exit()
|
|
|
|
## Attempt to get ids or sense out of the beginning block, no luck so far
|
|
for r in range(0,len(name_data),8):
|
|
#id = int.from_bytes( name_data[r:r+4], byteorder='big', signed=False )
|
|
#id = int(name_data[r:r+4], 16) & 0xFFFFFFFF
|
|
id = struct.unpack('<I', name_data[r:r+4])[0] ## Only one that seemed to match the hex editor values for some reason.
|
|
print(r, ": ", (name_data[r:r+4]), " - " , id)
|
|
if (id == 4): ## Why four?
|
|
break
|
|
|
|
# What's 1616/4 == 404
|
|
read_until_null(1624,name_data)
|
|
name_data[1624:read_until_null(1624,name_data)].decode("utf-16be", errors="replace")
|
|
|
|
|
|
language_code = 'E'
|
|
script_data = Path(f"YGO_2020/main/scriptdata_{language_code}.bin").read_bytes() # Get all the bytes
|
|
|
|
|
|
offset = struct.unpack("<Q", script_data[0:8])[0] # 11914
|
|
titlecount = struct.unpack("<I", script_data[8:12])[0] # 307
|
|
scriptblockcount = struct.unpack("<I", script_data[12:16])[0] # 7340
|
|
|
|
titleStartPos = list()
|
|
titleEndPos = list()
|
|
titleOffset = list()
|
|
for p in range(titlecount):
|
|
i = p * 16
|
|
titleStartPos.append(struct.unpack("<I", script_data[i:i+4])[0])
|
|
titleEndPos.append(struct.unpack("<I", script_data[i+4:i+8])[0])
|
|
titleOffset.append(struct.unpack("<Q", script_data[i+8:i+16])[0])
|
|
## 307 items? Is that good
|
|
|
|
for o in range(len(titleOffset)):
|
|
start = titleOffset[o]
|
|
end = read_until_space(start,script_data)
|
|
print( script_data[start:end].decode("utf-8") )
|
|
|
|
## Old attempts at getting dlg file extracted, leaving block for reference
|
|
language_code = 'J'
|
|
offsets_data = Path(f"YGO_2020/bin/DLG_Indx_{language_code}.bin").read_bytes() # Get all the bytes
|
|
name_data = Path(f"YGO_2020/bin/DLG_Text_{language_code}.bin").read_bytes() # Get all the bytes
|
|
get_props()
|
|
|
|
# with open("dump2.json", "w", encoding="utf-16") as outfile:
|
|
# json.dump(cd_db, outfile, ensure_ascii=False, indent=2)
|
|
|
|
print()
|
|
|
|
### For dialog scripts eventually
|
|
# Int ReadInt(std::ifstream &file){
|
|
# Int value;
|
|
# std::array<Byte,4> bytes;
|
|
# file.read((char*)(bytes.data()),4);
|
|
# value = bytes[0] | (bytes[1]<<8) | (bytes[2]<<16) | (bytes[3]<<24);
|
|
# return value;
|
|
# }
|
|
# Long ReadLong(std::ifstream &file){
|
|
# Long value;
|
|
# std::array<Byte,8> bytes;
|
|
# file.read((char*)(bytes.data()),8);
|
|
# value = bytes[0] | (bytes[1]<<8) | (bytes[2]<<16) | (bytes[3]<<24) | (bytes[4]<<32) | (bytes[5]<<40) | (bytes[6]<<48) | (bytes[7]<<56);
|
|
# return value;
|
|
# }
|
|
|
|
# if (scriptFile.is_open()){
|
|
# Long pointerToPointers=ReadLong(scriptFile);
|
|
# Int titleCount=ReadInt(scriptFile);
|
|
# Int scriptBlockCount=ReadInt(scriptFile);
|
|
# std::vector<Int> titleStartPos;
|
|
# std::vector<Int> titleEndPos;
|
|
# std::vector<Long> titlePointer;
|
|
# for (Int i=0; i<titleCount;i++){
|
|
# titleStartPos.push_back(ReadInt(scriptFile)); # 1
|
|
# titleEndPos.push_back(ReadInt(scriptFile)); # 2
|
|
# titlePointer.push_back(ReadLong(scriptFile)); # 3
|
|
# }
|
|
# std::vector<std::string> titleNames;
|
|
# for (Int i=0; i<titleCount;i++){
|
|
# scriptFile.seekg(titlePointer[i],scriptFile.beg);
|
|
# titleNames.push_back(ReadByteString(scriptFile));
|
|
# }
|
|
|
|
# std::vector<std::vector<SCRIPT_BLOCK> > script;
|
|
# for (Int i=0; i< titleCount; i++){
|
|
# std::vector<SCRIPT_BLOCK> scriptBlocks;
|
|
# Int blockCount=titleEndPos[i]-titleStartPos[i]+1;
|
|
# int pointer;
|
|
# for (Int j=0; j<blockCount;j++){
|
|
# SCRIPT_BLOCK scriptBlock;
|
|
# scriptFile.seekg(pointerToPointers+titleStartPos[i]*32+j*32);
|
|
# pointer=ReadLong(scriptFile);
|
|
# scriptFile.seekg(pointer,scriptFile.beg);
|
|
# scriptBlock.chara=ReadByteString(scriptFile);
|
|
# scriptFile.seekg(pointerToPointers+titleStartPos[i]*32+j*32+8);
|
|
# pointer=ReadLong(scriptFile);
|
|
# scriptFile.seekg(pointer,scriptFile.beg);
|
|
# scriptBlock.arg1=ReadByteString(scriptFile);
|
|
# scriptFile.seekg(pointerToPointers+titleStartPos[i]*32+j*32+16);
|
|
# pointer=ReadLong(scriptFile);
|
|
# scriptFile.seekg(pointer,scriptFile.beg);
|
|
# scriptBlock.arg2=ReadByteString(scriptFile);
|
|
# scriptFile.seekg(pointerToPointers+titleStartPos[i]*32+j*32+24);
|
|
# pointer=ReadLong(scriptFile);
|
|
# scriptFile.seekg(pointer,scriptFile.beg);
|
|
# scriptBlock.text=ReadByteString(scriptFile);
|
|
# scriptBlocks.push_back(scriptBlock);
|
|
# }
|
|
# script.push_back(scriptBlocks);
|
|
# }
|
|
# scriptFile.close();
|
|
|
|
|
|
|
|
#>
|