Last active
November 10, 2022 16:56
-
-
Save zach2good/9d0656f9e90156980c7d98ac42053519 to your computer and use it in GitHub Desktop.
NPC DAT Renamer script for FFXI
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env python | |
# npc_renamer by zach2good, use as you please! | |
# | |
# For use on the NPC DATs listed here: | |
# https://www.reddit.com/r/ffximodding/comments/9ndg2d/complete_list_of_zone_dats_by_zone_id/ | |
# | |
# Usage: npc_renamer.py <input file to read> | |
# : If the input file is .DAT, a corresponding .json file will be made. | |
# : If the input file is .json, a corresponding .new.DAT file will be made. | |
# | |
# Alternate usage: npc_renamer.py <filename1> <filename2> | |
# : You can use the script this way to binary compare two files. | |
# | |
# Examples: | |
# | |
# Prints the help message: | |
# .\npc_renamer.py | |
# | |
# Will generate 114.json, which you can edit the strings inside: | |
# .\npc_renamer.py 114.DAT | |
# | |
# Will generate 114.new.DAT, which you can rename and use with XIPivot or whatever: | |
# .\npc_renamer.py 114.json | |
# | |
# Will binary compare two files (useful to make sure the script is working as expected | |
# with no edits): | |
# .\npc_renamer.py 114.DAT 114.new.DAT | |
import sys | |
import json | |
import filecmp | |
def to_json_file(dat_filename, json_filename): | |
out_dict = {} | |
with open(dat_filename, mode="rb") as file: | |
index = 0 | |
while data := file.read(32): | |
last_four_bytes = list(data[0x1C:]) | |
data = data.split(b"\x00")[0] | |
data = data.decode(encoding="ascii", errors="ignore") | |
out_dict[index] = (data, last_four_bytes) | |
index = index + 1 | |
json_data = json.dumps(out_dict, indent=4) | |
with open(json_filename, "w") as out_file: | |
out_file.write(json_data) | |
def to_dat_file(json_filename, dat_filename): | |
data = {} | |
with open(json_filename) as json_file: | |
data = json.load(json_file) | |
with open(dat_filename, "wb") as out_file: | |
for value in data.values(): | |
name = value[0] | |
if len(name) > 27: | |
print(f"Name is too long!: {name}") | |
print(f"Maximum length is 27, got {len(name)}.") | |
sys.exit(-1) | |
last_four_bytes = value[1] | |
data = bytearray(32) | |
data[0 : len(name)] = bytearray(name, encoding="ascii") | |
data[0x1C] = last_four_bytes[0] | |
data[0x1D] = last_four_bytes[1] | |
data[0x1E] = last_four_bytes[2] | |
data[0x1F] = last_four_bytes[3] | |
out_file.write(data) | |
def compare(file1, file2): | |
print(file1) | |
print(file2) | |
if filecmp.cmp(file1, file2): | |
print("Files are binary twins!") | |
else: | |
print("Files are different!") | |
def print_help(): | |
print("Usage: npc_renamer.py <input file to read>") | |
print(" : If the input file is .DAT, a corresponding .json file will be made.") | |
print(" : If the input file is .json, a corresponding .new.DAT file will be made.") | |
print("") | |
print("Alternate usage: npc_renamer.py <filename1> <filename2>") | |
print(" : You can use the script this way to binary compare two files.") | |
def main() -> int: | |
if len(sys.argv) == 1: | |
print_help() | |
return -1 | |
if len(sys.argv) == 2: | |
input_filename = sys.argv[1] | |
if input_filename.endswith(".DAT"): | |
output_filename = input_filename.replace(".DAT", ".json") | |
to_json_file(input_filename, output_filename) | |
elif input_filename.endswith(".json"): | |
output_filename = input_filename.replace(".json", ".new.DAT") | |
to_dat_file(input_filename, output_filename) | |
elif len(sys.argv) == 3: | |
filename1 = sys.argv[1] | |
filename2 = sys.argv[2] | |
compare(filename1, filename2) | |
return 0 | |
if __name__ == "__main__": | |
sys.exit(main()) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment