Skip to content

Instantly share code, notes, and snippets.

@snowyegret23
Last active September 4, 2024 23:30
Show Gist options
  • Save snowyegret23/93409e56f0d486df69f80590cd39c648 to your computer and use it in GitHub Desktop.
Save snowyegret23/93409e56f0d486df69f80590cd39c648 to your computer and use it in GitHub Desktop.
gedonia export
import json
import UnityPy
import os
import csv
from concurrent.futures import ThreadPoolExecutor, as_completed
from natsort import natsorted
import sys
import shutil
import queue
import threading
def copy_library_folder(fp: str):
src_folder = f"{fp}/Resources"
dst_folder = f"{fp}/library"
if os.path.exists(dst_folder):
print("[copy_library_folder][Info] library folder already exists.")
return
if os.path.exists(src_folder):
shutil.copytree(src_folder, dst_folder)
print("[copy_library_folder][Info] Copying library folder completed.\n")
return
else:
print("[copy_library_folder][Warn] Resources folder not found")
print("[copy_library_folder][Warn] Please check unity3d file")
input("Press Enter to exit...")
sys.exit()
def load_typetree(fp: str):
with open(f"{fp}/typetree.json", "r", encoding="utf-8") as f:
tree = json.load(f)
return tree
def export(fn, trees, result_queue):
env = UnityPy.load(fn)
print(f"[dump_mb][Info] current working file: {env.file.name}")
for obj in env.objects:
if obj.type.name == "MonoBehaviour":
monobehaviour = obj.read()
try:
script = monobehaviour.m_Script.read()
except:
continue
if monobehaviour.m_Script == None or monobehaviour.m_Script == "":
continue
if obj.serialized_type.nodes:
tree = obj.read_typetree()
else:
try:
typetree = trees[script.m_ClassName]
except:
continue
tree = obj.read_typetree(typetree)
if tree.get("name") is not None and tree.get("russianName") is not None:
tmp_lst = [
fn,
obj.path_id,
script.name,
tree.get("name", ""),
tree.get("russianName", ""),
tree.get("basicDescription", ""),
tree.get("bascDescriptionRus", ""),
tree.get("text", ""),
tree.get("russianText", ""),
]
result_queue.put(tmp_lst)
def csv_writer(result_queue, csv_file):
with open(csv_file, "w", encoding="utf-8", newline="") as f:
writer = csv.writer(f)
writer.writerow(
[
"file_name",
"path_id",
"script_name",
"name",
"russianName",
"basicDescription",
"bascDescriptionRus",
"text",
"russianText",
]
)
f.flush()
while True:
row = result_queue.get()
if row is None:
break
writer.writerow(row)
f.flush()
def main():
data_folder = os.path.dirname(os.path.abspath(__file__))
print(f"[dump_mb][Info] current working directory: {data_folder}")
copy_library_folder(data_folder)
trees = load_typetree(f"{data_folder}\\TypeTree")
all_files = os.listdir(data_folder)
ban_files = ["globalgamemanagers.assets"]
filtered_files = [
i
for i in all_files
if (
i.endswith(".assets") or (i.startswith("level") and not i.endswith(".resS"))
)
and i not in ban_files
]
asset_list = natsorted(
[i for i in filtered_files if i.endswith(".assets")]
) + natsorted([i for i in filtered_files if i.startswith("level")])
result_queue = queue.Queue()
csv_thread = threading.Thread(
target=csv_writer, args=(result_queue, "export_test.csv")
)
csv_thread.start()
max_workers = os.cpu_count()
with ThreadPoolExecutor(max_workers=max_workers) as executor:
futures = {
executor.submit(export, asset, trees, result_queue): asset
for asset in asset_list
}
for future in as_completed(futures):
future.result()
result_queue.put(None)
csv_thread.join()
if __name__ == "__main__":
main()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment