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
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
|
import pathlib
import zipfile
import tomllib
class Mod:
def __init__(self, file_name, name, mod_id) -> None:
self.file_name = file_name
self.name = name
self.mod_id = mod_id
self.前置 = {}
self.可选前置 = {}
self.被需要 = {}
self.被可选需要 = {}
def add_dependency(self, mod_id, side):
self.前置[mod_id] = side
def add_optional_dependency(self, mod_id, side):
self.可选前置[mod_id] = side
def add_required_by(self, mod_id, side):
self.被需要[mod_id] = side
def add_optional_required_by(self, mod_id, side):
self.被可选需要[mod_id] = side
OUTPUT_LINES: list[str] = []
MODS: dict[str, Mod] = {}
def add_line(line: str):
OUTPUT_LINES.append(line + "\n")
def output(path="./mods.txt"):
file = pathlib.Path(path)
if file.suffix == ".txt":
with file.open("w") as f:
f.writelines(OUTPUT_LINES)
else:
print("文件路径不正确")
def scan_mods_dir(dir: pathlib.Path):
for jar in dir.iterdir():
if jar.suffix == ".jar":
scan_jar(jar)
def scan_jar(jar: pathlib.Path):
dir = zipfile.Path(jar, "META-INF/")
results = [f for f in dir.glob("*mods.toml")]
if len(results) < 1:
add_line(f"{jar.name} 中未找到 mods.toml 文件")
else:
mod_file = results[0]
with mod_file.open("rb") as f:
content = tomllib.load(f)
mod_id = content["mods"][0]["modId"]
display_name = content["mods"][0]["displayName"]
mod = Mod(jar.name, display_name, mod_id)
if "dependencies" in content:
pick_dependencies(mod, content)
if mod.mod_id in MODS:
add_line(f"模组 ID 重合:{MODS[mod.mod_id]} 和 {mod.file_name}")
else:
MODS[mod.mod_id] = mod
def pick_dependencies(mod: Mod, content):
for each_mod_id, each_mod in content["dependencies"].items():
if each_mod_id != mod.mod_id:
add_line(f"{mod.file_name} 添加了 {each_mod_id} 的依赖关系")
for each_item in each_mod:
if "type" in each_item:
need_type = each_item["type"]
else:
mandatory = each_item["mandatory"]
if mandatory is True:
need_type = "required"
else:
need_type = "optional"
if each_item["modId"] not in ["minecraft", "forge", "neoforge"]:
if "side" in each_item:
if each_item["side"] == "BOTH":
side = "双端"
elif each_item["side"] == "SERVER":
side = "服务端"
else: # "CLIENT"
side = "客户端"
else:
side = "没说放哪"
if need_type == "required":
mod.add_dependency(each_item["modId"], side)
elif need_type == "optional":
mod.add_optional_dependency(each_item["modId"], side)
def seek_required():
for mod_id, mod in MODS.items():
for tmp_mod_id, side in mod.前置.items():
if tmp_mod_id in MODS:
MODS[tmp_mod_id].add_required_by(mod_id, side)
else:
add_line(f"* 没找到 {mod.file_name} 需要的 {tmp_mod_id},或许已内置")
for tmp_mod_id, side in mod.可选前置.items():
if tmp_mod_id in MODS:
MODS[tmp_mod_id].add_optional_required_by(mod_id, side)
def analysis_relations():
for mod in MODS.values():
add_line(f"{mod.name}")
add_line(f"\t{mod.file_name}")
if len(mod.前置) > 0:
add_line("前置:")
for tmp_mod_id, side in mod.前置.items():
if tmp_mod_id not in MODS:
add_line(f"\t* 需要 {tmp_mod_id},但没有文件")
else:
add_line(f"\t{side}:{MODS[tmp_mod_id].name}")
add_line(f"\t\t{MODS[tmp_mod_id].file_name}")
elif len(mod.可选前置) > 0:
add_line("可选前置:")
for tmp_mod_id, side in mod.可选前置.items():
if tmp_mod_id in MODS:
add_line(f"\t{side}:{MODS[tmp_mod_id].name}")
add_line(f"\t\t{MODS[tmp_mod_id].file_name}")
else:
add_line(f"\t{side}(未添加):{tmp_mod_id}")
elif len(mod.被需要) > 0:
add_line("需要本模组:")
for tmp_mod_id, side in mod.被需要.items():
add_line(f"\t{side}:{MODS[tmp_mod_id].name}")
add_line(f"\t\t{MODS[tmp_mod_id].file_name}")
elif len(mod.被可选需要) > 0:
add_line("可选需要本模组:")
for tmp_mod_id, side in mod.被可选需要.items():
add_line(f"\t{side}:{MODS[tmp_mod_id].name}")
add_line(f"\t\t{MODS[tmp_mod_id].file_name}")
else:
add_line("独立模组")
add_line("\n")
mods_dir = input()
mods_dir = pathlib.Path(mods_dir)
scan_mods_dir(mods_dir)
seek_required()
add_line("<---------------->\n")
analysis_relations()
output()
|