├── LICENSE
├── README.md
├── mmet.py
├── mmet.ui
└── ui_mmet.py
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2022 xxtg666
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # MinecraftModpackExportTool
2 | 将你的Minecraft游戏文件夹导出成CurseForge整合包格式,可发给好友,供PCL2等启动器一键安装
3 | ## 运行方法:
4 | 1.安装PySide2库
5 | 2.运行mmet.py
6 |
--------------------------------------------------------------------------------
/mmet.py:
--------------------------------------------------------------------------------
1 | import sys
2 | import os
3 | from tkinter import E
4 | from PySide2.QtWidgets import *
5 | from PySide2.QtCore import *
6 | from PySide2.QtGui import *
7 | from ui_mmet import Ui_MainWindow
8 | import json
9 | import shutil
10 | import getpass
11 | import zipfile
12 | import webbrowser as wb
13 | import traceback
14 | import pyperclip
15 | import platform
16 |
17 |
18 | def make_zip(dirpath, outFullName):
19 | zip = zipfile.ZipFile(outFullName, "w", zipfile.ZIP_DEFLATED)
20 | for path, dirnames, filenames in os.walk(dirpath):
21 | fpath = path.replace(dirpath, '')
22 | for filename in filenames:
23 | zip.write(os.path.join(path, filename),
24 | os.path.join(fpath, filename))
25 | zip.close()
26 |
27 |
28 | def iconFromBase64(base64):
29 | pixmap = QPixmap()
30 | pixmap.loadFromData(QByteArray.fromBase64(base64.encode()))
31 | icon = QIcon(pixmap)
32 | return icon
33 |
34 |
35 | class mmet(QMainWindow, Ui_MainWindow):
36 | def __init__(self):
37 | super().__init__()
38 | self.setupUi(self)
39 | self.on_setup()
40 | self.pb_s1.clicked.connect(self.on_pb_s1)
41 | self.pb_s2.clicked.connect(self.on_pb_s2)
42 | self.cb_s3_all.clicked.connect(self.on_cb_s3_all)
43 | self.pushButton.clicked.connect(self.on_export_clicked)
44 | self.action_MMET.triggered.connect(self.show_about)
45 | self.action_GitHub.triggered.connect(self.open_github)
46 | self.action_2.triggered.connect(self.bug_report)
47 | self.setWindowIcon(iconFromBase64("iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAgklEQVQ4y2NgGLTAxcXlPzomSTMI3Lhx4//BgwfBGMQGiXuaif7P8JP7T5QhEhIScAwzqDNd/b+GHPd/kr0EshnmIpCBJGsGORtkM8w7RBsC0ozsbJh3iDIA2WaYGNEGoNuMbABBL2CzGdkAEMBpAC6b0Q0h2WaSQ5tkANJItmZKAABzO4WhWjcV2gAAAABJRU5ErkJggg=="))
48 | self.show()
49 |
50 | def on_setup(self):
51 | self.groupBox_2.setEnabled(False)
52 | self.groupBox_3.setEnabled(False)
53 | self.groupBox_4.setEnabled(False)
54 |
55 | def on_pb_s1(self):
56 | self.versions_path = QFileDialog.getExistingDirectory(
57 | self, "选择 versions 文件夹")
58 | if self.versions_path[-8:-1]+self.versions_path[-1] == "versions":
59 | self.pb_s1.setText(self.versions_path)
60 | self.groupBox.setEnabled(False)
61 | self.groupBox_2.setEnabled(True)
62 | else:
63 | QMessageBox.warning(self, "错误", "选择的文件夹无效")
64 |
65 | def on_pb_s2(self):
66 | versions_list = os.listdir(self.versions_path)
67 | for i in versions_list:
68 | if not os.path.isdir(self.versions_path+os.sep+i):
69 | versions_list.remove(i)
70 | version = QInputDialog.getItem(
71 | self, "选择游戏版本", '请选择一个将要导出的游戏版本', versions_list, 0, False)
72 | self.game_version = version[0]
73 | if version[1]:
74 | self.pb_s2.setText(self.game_version)
75 | self.groupBox_2.setEnabled(False)
76 | self.groupBox_3.setEnabled(True)
77 | self.groupBox_4.setEnabled(True)
78 |
79 | def on_cb_s3_all(self):
80 | e_all = self.cb_s3_all.isChecked()
81 | if e_all:
82 | self.cb_s3_config.setEnabled(False)
83 | self.cb_s3_servers.setEnabled(False)
84 | self.cb_s3_options.setEnabled(False)
85 | self.cb_s3_resourcepacks.setEnabled(False)
86 | self.cb_s3_saves.setEnabled(False)
87 | self.cb_s3_shaderpacks.setEnabled(False)
88 | else:
89 | self.cb_s3_config.setEnabled(True)
90 | self.cb_s3_servers.setEnabled(True)
91 | self.cb_s3_options.setEnabled(True)
92 | self.cb_s3_resourcepacks.setEnabled(True)
93 | self.cb_s3_saves.setEnabled(True)
94 | self.cb_s3_shaderpacks.setEnabled(True)
95 |
96 | def on_export(self):
97 | QMessageBox.information(
98 | self, "准备导出", "点击 [OK] 以开始导出\n导出时可能会未响应,请耐心等待!")
99 | self.game_folder_path = self.versions_path+os.sep+self.game_version
100 | game_json_path = self.game_folder_path+os.sep+self.game_version+".json"
101 | PCL_ini_path = self.game_folder_path+os.sep+"PCL"+os.sep+"Setup.ini"
102 | if os.path.exists(PCL_ini_path):
103 | with open(PCL_ini_path, "r", encoding="utf-8") as f:
104 | ini = f.readlines()
105 | for i in range(len(ini)):
106 | if ini[i][:14] == "VersionFabric:":
107 | ini_fabric_line = i
108 | if ini[i][:13] == "VersionForge:":
109 | ini_forge_line = i
110 | VersionFabric = ini[ini_fabric_line].replace(
111 | "VersionFabric:", "").replace("\n", "")
112 | VersionForge = ini[ini_forge_line].replace(
113 | "VersionForge:", "").replace("\n", "")
114 | if VersionFabric != "":
115 | self.loader_version = "fabric-"+VersionFabric
116 | else:
117 | self.loader_version = "forge-"+VersionForge
118 | with open(game_json_path, "r", encoding="utf-8") as f:
119 | game_json = json.load(f)
120 | self.client_version = game_json["clientVersion"]
121 | else:
122 | try:
123 | with open(game_json_path, "r", encoding="utf-8") as f:
124 | game_json = json.load(f)
125 | self.loader_version = game_json["patches"][1]["id"] + \
126 | "-"+game_json["patches"][1]["version"]
127 | except:
128 | self.loader_version = QInputDialog.getText(
129 | self, '输入mod加载器信息', '无法自动读取mod加载器信息
请手动输入mod加载器名称及其版本
例如: fabric-0.14.6')
130 | try:
131 | self.client_version = game_json["patches"][0]["version"]
132 | except:
133 | self.client_version = QInputDialog.getText(
134 | self, '输入游戏版本信息', '无法自动读取游戏版本信息
请手动输入游戏版本
例如: 1.16.5')
135 | # QMessageBox.information(self,"debug",f"loader_version:{self.loader_version}\nclient_version:{self.client_version}\nVersionFabric:{VersionFabric}\nVersionForge:{VersionForge}")
136 | e_config = self.cb_s3_config.isChecked()
137 | e_servers = self.cb_s3_servers.isChecked()
138 | e_options = self.cb_s3_options.isChecked()
139 | e_resourcepacks = self.cb_s3_resourcepacks.isChecked()
140 | e_saves = self.cb_s3_saves.isChecked()
141 | e_shaderpacks = self.cb_s3_shaderpacks.isChecked()
142 | e_all = self.cb_s3_all.isChecked()
143 | manifest_json = {"minecraft": {"version": self.client_version, "modLoaders": [{"id": self.loader_version, "primary": True}]}, "manifestType": "minecraftModpack",
144 | "manifestVersion": 1, "name": self.game_version, "version": "1.0.0", "author": "MinecraftModpackExportTool "+getpass.getuser(), "files": [], "overrides": "overrides"}
145 | os.mkdir("mmet_temp")
146 | json.dump(manifest_json, open("mmet_temp"+os.sep +
147 | "manifest.json", "w", encoding="utf-8"))
148 | if not e_all:
149 | os.mkdir("mmet_temp"+os.sep+"overrides")
150 | shutil.copytree(self.game_folder_path+os.sep+"mods",
151 | "mmet_temp"+os.sep+"overrides"+os.sep+"mods")
152 | if e_config:
153 | shutil.copytree(self.game_folder_path+os.sep+"config",
154 | "mmet_temp"+os.sep+"overrides"+os.sep+"config")
155 | if e_servers:
156 | shutil.copy(self.game_folder_path+os.sep+"servers.dat",
157 | "mmet_temp"+os.sep+"overrides")
158 | if e_options:
159 | shutil.copy(self.game_folder_path+os.sep+"options.txt",
160 | "mmet_temp"+os.sep+"overrides")
161 | if e_resourcepacks:
162 | shutil.copytree(self.game_folder_path+os.sep +
163 | "resourcepacks", "mmet_temp"+os.sep+"overrides"+os.sep+"resourcepacks")
164 | if e_saves:
165 | shutil.copytree(self.game_folder_path+os.sep+"saves",
166 | "mmet_temp"+os.sep+"overrides"+os.sep+"saves")
167 | if e_shaderpacks:
168 | shutil.copytree(self.game_folder_path+os.sep+"shaderpacks",
169 | "mmet_temp"+os.sep+"overrides"+os.sep+"shaderpacks")
170 | else:
171 | shutil.copytree(self.game_folder_path, "mmet_temp"+os.sep+"overrides")
172 | try:
173 | shutil.rmtree("mmet_temp"+os.sep+"overrides" +os.sep+"PCL")
174 | except:
175 | pass
176 | os.remove("mmet_temp"+os.sep+"overrides" +os.sep+self.game_version+".jar")
177 | os.remove("mmet_temp"+os.sep+"overrides" +os.sep+self.game_version+".json")
178 | if os.path.exists("mmet_temp"+os.sep+"overrides"+os.sep+"config"+os.sep+"ias.json"):
179 | r = QMessageBox.warning(
180 | self, "盗号警告", "
作者: xxtg666
版本 1.0.6
") 204 | 205 | def open_github(self): 206 | wb.open("https://github.com/xxtg666/MinecraftModpackExportTool") 207 | 208 | def bug_report(self): 209 | wb.open("https://github.com/xxtg666/MinecraftModpackExportTool/issues") 210 | 211 | 212 | if __name__ == "__main__": 213 | app = QApplication(sys.argv) 214 | window = mmet() 215 | sys.exit(app.exec_()) 216 | -------------------------------------------------------------------------------- /mmet.ui: -------------------------------------------------------------------------------- 1 | 2 |