Added sortAlphabetically.py

Cleaned the other scripts a bit, added more details in readme.
This commit is contained in:
Farewell_ 2023-11-20 12:31:57 +01:00
parent a31e555ce7
commit c41c1e2ee5
4 changed files with 290 additions and 72 deletions

View File

@ -28,20 +28,38 @@ class Keys(Enum):
you also need to install the pip module `cryptography`:
> pip install cryptography
here's some examples :
here's some usage examples :
```py
# Display the help message
py .\encryption.py --help
py encryption.py --help
# Decrypting a datatable :
py .\encryption.py --input "data.bin" --output "data.json"
py encryption.py --input "data.bin" --output "data.json"
# Encrypting a datatable :
py .\encryption.py --enc --input "data.json" --output "data.bin"
py encryption.py --enc --input "data.json" --output "data.bin"
# Encrypting a fumen for use in CHN :
py .\encryption.py --enc --fumen --input "data_e.bin" --output "data_e.bin"
py encryption.py --enc --fumen --input "data_e.bin" --output "data_e.bin"
```
## sortAlphabetically.py
This script generates an alphabetically sorted music_order.bin file for a given language.
Possible languages are : japaneseText, englishUsText, chineseTText, chineseSText and koreanText
Here's some usage examples :
```py
# Display the help message
py sortAlphabetically.py --help
# Sort file by english name
py sortAlphabetically.py --language "englishUsText"
# Restore a backup of the original music_order file
py sortAlphabetically.py --restore
```
## checkDatatables.py
@ -58,6 +76,6 @@ This script generates a comprehensive list of various informations regarding you
To run this one you simply need to call it like so:
> py .\checkDatatables.py
> py checkDatatables.py
The output will be written in a file named `checks.json`

View File

@ -4,6 +4,15 @@ from encryption import decrypt_file
import json
import os
from helpers import (
doesPathExist,
findAllObjects,
findDoubloninList,
findKeyInList,
isChn,
loadFile,
)
# "japaneseText"
# "englishUsText"
# "chineseTText"
@ -11,73 +20,16 @@ import os
# "chineseSText"
language = "englishUsText"
isCHN = False
isChn = isChn()
# region Loading files
checkFile = {}
# Loading musicinfo.bin
try:
infos = json.load(gzip.open("./Data/x64/datatable/musicinfo.bin", "rb"))["items"]
except:
try:
infos = json.loads(
decrypt_file(input_file="./Data/x64/datatable/musicinfo.bin")
)["items"]
isCHN = True
except:
print("Couldn't load musicinfo.bin, exiting.")
exit(0)
# Loading music_usbsetting.bin
try:
usb = (
json.loads(
decrypt_file(input_file="./Data/x64/datatable/music_usbsetting.bin")
)["items"]
if isCHN
else None
)
except:
usb = None
# Loading music_order.bin
try:
order = (
json.loads(decrypt_file(input_file="./Data/x64/datatable/music_order.bin"))[
"items"
]
if isCHN
else json.load(gzip.open("./Data/x64/datatable/music_order.bin", "rb"))["items"]
)
except:
order = None
# Loading music_attribute.bin
try:
attributes = (
json.loads(decrypt_file(input_file="./Data/x64/datatable/music_attribute.bin"))[
"items"
]
if isCHN
else json.load(gzip.open("./Data/x64/datatable/music_attribute.bin", "rb"))[
"items"
]
)
except:
attributes = None
# Loading wordlist.bin
try:
words = (
json.loads(decrypt_file(input_file="./Data/x64/datatable/wordlist.bin"))[
"items"
]
if isCHN
else json.load(gzip.open("./Data/x64/datatable/wordlist.bin", "rb"))["items"]
)
except:
words = None
infos = loadFile(path="./Data/x64/datatable/musicinfo.bin")
usb = loadFile(path="./Data/x64/datatable/music_usbsetting.bin")
order = loadFile(path="./Data/x64/datatable/music_order.bin")
attributes = loadFile(path="./Data/x64/datatable/music_attribute.bin")
words = loadFile(path="./Data/x64/datatable/wordlist.bin")
# endregion
# Forcing japanese language on 08.18 as this is what is usually used for omnimix.
@ -94,9 +46,9 @@ class Genres(Enum):
Vocaloid = 3
GameMusic = 4
NamcoOriginal = 5
Variety = 6 if not isCHN else 7
Classical = 7 if not isCHN else 8
if not isCHN:
Variety = 6 if not isChn else 7
Classical = 7 if not isChn else 8
if not isChn:
Custom = 9
@classmethod

74
helpers.py Normal file
View File

@ -0,0 +1,74 @@
import gzip
import json
import os
from encryption import decrypt_file
def isChn():
return os.path.exists("./Data/x64/datatable/music_usbsetting.bin")
def loadFile(path: str):
if doesPathExist(path):
try:
if not isChn():
# Loading files for 08.18
return json.load(gzip.open(path, "rb"))["items"]
else:
# Loading files for 32.09 CHN
return json.loads(decrypt_file(input_file=path))["items"]
except Exception as error:
print(error)
print("Couldn't load", path)
return None
else:
print(path, "doesn't exist")
def findKeyInList(list: list, key: str, keyValue, value=None):
for object in list:
try:
if object[key] == keyValue:
if value is not None:
return object[value]
else:
return object
except:
if value is not None:
print(
value
+ " doesn't exist in "
+ str(object)
+ ", are you using the right language ?"
)
exit(0)
if value is not None:
return ""
else:
return None
def findAllObjects(list: list, key: str, keyValue):
templist = []
templist.append(list)
objects = []
for element in templist[0]:
if element[key] == keyValue:
objects.append(element)
return objects
def findDoubloninList(list: list, key: str, keyValue):
if len(findAllObjects(list=list, key=key, keyValue=keyValue)) > 1:
return True
return False
def doesPathExist(path: str):
if os.path.exists(path):
return True
return False

174
sortAlphabetically.py Normal file
View File

@ -0,0 +1,174 @@
from argparse import ArgumentParser
import gzip
from io import StringIO
import json
import os
import shutil
from helpers import doesPathExist, isChn, findKeyInList, loadFile
from encryption import encrypt_file
language = ""
order = None
words = None
def loadFiles():
global order, words
# Loading music_order.bin and wordlist.bin
order = loadFile(path="./Data/x64/datatable/music_order.bin")
words = loadFile(path="./Data/x64/datatable/wordlist.bin")
if any([order == None, words == None]):
print(
"Couldn't load files. Consider restoring your music_order file using the --restore flag."
)
exit(0)
class Entry:
name = ""
genreNo = -1
id = ""
uniqueId = -1
closeDispType = -1
def __init__(self, name, genreNo, id, uniqueId, closeDispType):
self.name = name
self.genreNo = genreNo
self.id = id
self.uniqueId = uniqueId
self.closeDispType = closeDispType
def toJson(self):
return {
# "name": self.name,
"genreNo": self.genreNo,
"id": self.id,
"uniqueId": self.uniqueId,
"closeDispType": self.closeDispType,
}
def sort(reverse: bool):
# Adding all the existing songs in song_order in an array
entries = []
for entry in order:
name = findKeyInList(
list=words,
key="key",
keyValue="song_" + entry["id"],
value=language,
)
if name == "":
print(entry["id"] + " is missing a name")
entries.append(
Entry(
name=name,
genreNo=entry["genreNo"],
id=entry["id"],
uniqueId=entry["uniqueId"],
closeDispType=entry["closeDispType"],
)
)
print("Sorting", str(len(entries)), "entries")
# Sorting names alphabetically.
if reverse:
print("Reversed sorting order!")
entries.sort(key=lambda x: x.name, reverse=reverse)
# Backing up the original order file
if not doesPathExist(path="./Data/x64/datatable/music_order.bin.bak"):
print("Backed up music_order")
shutil.move(
"./Data/x64/datatable/music_order.bin",
"./Data/x64/datatable/music_order.bin.bak",
)
file = {"items": []}
for entry in entries:
file["items"].append(entry.toJson())
# Writing song_order.bin
json_object = json.dumps(file, ensure_ascii=False, indent="\t")
if not isChn():
# Saving compressed bin file for 08.18
with open("./Data/x64/datatable/music_order.bin", "wb") as outfile:
outfile.write(gzip.compress(bytes(json_object, encoding="utf-8")))
else:
# Saving encrypted compressed bin file for 32.09 CHN
# This is terrible but it works fine :))
with open(
"./Data/x64/datatable/music_order.json", "w", encoding="utf-8"
) as outfile:
outfile.write(json_object)
encrypted_object = encrypt_file(
input_file="./Data/x64/datatable/music_order.json"
)
os.remove("./Data/x64/datatable/music_order.json")
with open("./Data/x64/datatable/music_order.bin", "wb") as outfile:
outfile.write(encrypted_object)
def restore():
# Checking if we have a backup
if doesPathExist(path="./Data/x64/datatable/music_order.bin.bak"):
print("Restoring music_order")
# Removing current music_order file
if os.path.isfile("./Data/x64/datatable/music_order.bin"):
os.remove("./Data/x64/datatable/music_order.bin")
# Restoring backup
shutil.move(
"./Data/x64/datatable/music_order.bin.bak",
"./Data/x64/datatable/music_order.bin",
)
else:
print("There is no backup to restore.")
if __name__ == "__main__":
parser = ArgumentParser()
parser.add_argument(
"--restore",
action="store_true",
default=False,
help="Use this flag to restore a backup of the original file",
)
parser.add_argument(
"--reverse",
action="store_true",
default=False,
help="Revert sorting order",
)
parser.add_argument(
"-l",
"--language",
default="englishUsText",
help="This sets the language used for sorting the files. Possible values are : japaneseText, englishUsText, chineseTText, chineseSText and koreanText",
)
args = parser.parse_args()
language = args.language
if language not in [
"japaneseText",
"englishUsText",
"chineseTText",
"chineseSText",
"koreanText",
]:
print(
"Invalid language, Possible values are : japaneseText, englishUsText, chineseTText, chineseSText and koreanText"
)
exit(1)
if not args.restore:
loadFiles()
sort(args.reverse)
else:
restore()