フォルダー抽出

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
import os
import xml.etree.ElementTree as ET

RBX_NS = "http://www.roblox.com/roblox"

# Studio 互換サービスマップ
EXPORT_MAP = {
    "ServerScriptService": "ServerScriptService",
    "StarterGui": "StarterGui",
    "ReplicatedStorage": "ReplicatedStorage",
    "StarterPlayerScripts": "StarterPlayerScripts",
}

def ensure_dir(path):
    if not os.path.exists(path):
        os.makedirs(path)

def export_script(item, out_dir):
    name = item.find("./Properties/string[@name='Name']").text
    source = item.find("./Properties/ProtectedString[@name='Source']").text or ""

    class_name = item.attrib["class"]

    if class_name == "Script":
        filename = f"{name}_server.lua"
    elif class_name == "LocalScript":
        filename = f"{name}_client.lua"
    else:
        filename = f"{name}.lua"

    with open(os.path.join(out_dir, filename), "w", encoding="utf-8") as f:
        f.write(source)

def export_folder(item, out_dir):
    name = item.find("./Properties/string[@name='Name']").text
    new_dir = os.path.join(out_dir, name)
    ensure_dir(new_dir)
    return new_dir

def export_rbxmx(item, out_dir):
    name = item.find("./Properties/string[@name='Name']").text
    filename = os.path.join(out_dir, f"{name}.rbxmx")
    ET.ElementTree(item).write(filename, encoding="utf-8", xml_declaration=True)

def export_item(item, out_dir):
    class_name = item.attrib["class"]

    if class_name in ["Script", "LocalScript", "ModuleScript"]:
        export_script(item, out_dir)

    elif class_name == "Folder":
        new_dir = export_folder(item, out_dir)
        for child in item.findall("Item"):
            export_item(child, new_dir)

    elif class_name in ["ScreenGui", "Frame", "Model"]:
        export_rbxmx(item, out_dir)

    else:
        # その他の Item は無視(Studio 互換)
        pass

def export_rbxlx_to_os(rbxlx_path, out_root):
    tree = ET.parse(rbxlx_path)
    root = tree.getroot()

    for item in root.findall("Item"):
        class_name = item.attrib["class"]

        # StarterPlayerScripts は StarterPlayer の子
        if class_name == "StarterPlayer":
            sps = item.find("Item[@class='StarterPlayerScripts']")
            if sps is not None:
                out_dir = os.path.join(out_root, "StarterPlayerScripts")
                ensure_dir(out_dir)
                for child in sps.findall("Item"):
                    export_item(child, out_dir)

        # その他のサービス
        if class_name in EXPORT_MAP:
            out_dir = os.path.join(out_root, EXPORT_MAP[class_name])
            ensure_dir(out_dir)
            for child in item.findall("Item"):
                export_item(child, out_dir)

    print("[EXPORT] Completed.")

if __name__ == "__main__":
    export_rbxlx_to_os(
        r"C:\Users\User\Documents\自分のプログラム.rbxlx",
        "out2",
    )

フォルダー一覧

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
import os

def print_tree(root_dir, prefix=""):
    # フォルダ内のファイル・ディレクトリを取得
    entries = sorted(os.listdir(root_dir))
    for i, entry in enumerate(entries):
        path = os.path.join(root_dir, entry)
        connector = "└── " if i == len(entries) - 1 else "├── "
        print(prefix + connector + entry)
        if os.path.isdir(path):
            # 下層フォルダを再帰的に処理
            new_prefix = prefix + ("    " if i == len(entries) - 1 else "│   ")
            print_tree(path, new_prefix)

def export_markdown_tree(root_dir):
    print("```")
    print(os.path.basename(root_dir) + "/")
    print_tree(root_dir)
    print("```")

# 使用例
if __name__ == "__main__":
    folder = r"C:\Users\User\eclipse-workspace\roblox\src\out2"  # ←ここに対象フォルダを指定
    export_markdown_tree(folder)