-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathmain.py
261 lines (237 loc) · 11.9 KB
/
main.py
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
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
import os
import winreg
import shutil
import vdf
import requests
import re
import subprocess
import sys
import time
import zipfile
import io
__version__ = "1.0.0" # 脚本当前版本
MOD_UPDATE_URL = "https://pastebin.com/raw/*****" # 替换为你的模组更新信息 Raw URL
LOCAL_MOD_VERSION_FILE = ".mod_version" # 本地存储模组版本号的文件名
def get_local_mod_version():
if os.path.exists(LOCAL_MOD_VERSION_FILE):
try:
with open(LOCAL_MOD_VERSION_FILE, "r") as f:
return f.read().strip()
except Exception as e:
print(f"[!] 警告:读取本地模组版本文件时发生错误:{e}")
return None
return None
def save_local_mod_version(version):
try:
with open(LOCAL_MOD_VERSION_FILE, "w") as f:
f.write(version)
except Exception as e:
print(f"[!] 警告:保存本地模组版本文件时发生错误:{e}")
def find_steam_path():
try:
key = winreg.OpenKey(winreg.HKEY_CURRENT_USER, r"Software\Valve\Steam")
steam_path, _ = winreg.QueryValueEx(key, "SteamPath")
winreg.CloseKey(key)
return steam_path
except FileNotFoundError:
return None
def find_7dtd_path(steam_path):
libraryfolders_path = os.path.join(steam_path, "steamapps", "libraryfolders.vdf")
if not os.path.exists(libraryfolders_path):
print("[!] 错误:未找到libraryfolders.vdf文件。")
return None
print(f"[+] Libraryfolders.vdf路径:{libraryfolders_path}")
try:
with open(libraryfolders_path, 'r', encoding='utf-8') as f:
data = vdf.load(f)
for key, value in data.get('libraryfolders', {}).items():
if isinstance(value, dict) and 'apps' in value and '251570' in value['apps']:
return value['path']
print("[!] 错误:在libraryfolders.vdf中未找到七日杀(AppID 251570)的安装路径。")
return None
except Exception as e:
print(f"[!] 错误:解析libraryfolders.vdf文件时发生错误:{e}")
return None
def copy_mods(source_mods_path, dest_mods_path):
if not os.path.exists(source_mods_path):
print("[!] 警告:当前目录中未找到“Mods”文件夹。跳过复制操作。")
return
print(f"[+] 在当前目录中找到“Mods”文件夹。")
if os.path.exists(dest_mods_path):
try:
shutil.copytree(source_mods_path, dest_mods_path, dirs_exist_ok=True)
print(f"[+] 模组已成功复制到:{dest_mods_path}")
except Exception as e:
print(f"[!] 错误:复制模组时发生错误:{e}")
else:
print(f"[!] 错误:目标模组目录不存在:{dest_mods_path}")
def download_and_install_mod(download_url, game_mods_path):
print("[+] 开始下载模组更新...")
try:
response = requests.get(download_url, stream=True)
response.raise_for_status()
total_size_in_bytes = int(response.headers.get('content-length', 0))
block_size = 1024
downloaded_size = 0
filename = download_url.split('/')[-1]
filepath = os.path.join(os.getcwd(), filename)
with open(filepath, 'wb') as file:
for data in response.iter_content(block_size):
downloaded_size += len(data)
file.write(data)
done = int(50 * downloaded_size / total_size_in_bytes)
sys.stdout.write(f"\r[{'█' * done}{'.' * (50 - done)}] {downloaded_size // 1024} KB / {total_size_in_bytes // 1024} KB")
sys.stdout.flush()
print(f"\n[+] 下载完成:{filepath}")
print("[+] 开始安装模组...")
try:
with zipfile.ZipFile(filepath, 'r') as zf:
for member in zf.namelist():
source = zf.open(member)
target_path = os.path.join(game_mods_path, member)
if member.endswith('/'):
os.makedirs(target_path, exist_ok=True)
else:
with open(target_path, "wb") as target:
shutil.copyfileobj(source, target)
print(f"[+] 模组已成功安装到:{game_mods_path}")
return True # 返回 True 表示安装成功
except zipfile.BadZipFile:
print("[!] 错误:下载的更新文件不是有效的 ZIP 文件。")
return False
except Exception as e:
print(f"[!] 错误:解压和安装模组时发生错误:{e}")
return False
os.remove(filepath)
except requests.exceptions.RequestException as e:
print(f"[!] 错误:下载模组更新失败:{e}")
return False
except Exception as e:
print(f"[!] 错误:下载和安装模组时发生未知错误:{e}")
return False
def check_for_mod_update(current_version, update_url):
print("[+] 检查模组更新...")
try:
response = requests.get(update_url)
response.raise_for_status()
remote_content = response.text
version_match = re.search(r"latest_mod_version = \"(.*?)\"", remote_content)
download_url_match = re.search(r"download_url = \"(.*?)\"", remote_content)
if version_match and download_url_match:
latest_mod_version = version_match.group(1)
download_url = download_url_match.group(1)
if latest_mod_version > current_version:
print(f"[+] 发现模组新版本: {latest_mod_version}, 当前版本: {current_version}")
print(f"[+] 下载链接: {download_url}")
return latest_mod_version, download_url
else:
print("[+] 当前模组已是最新版本。")
return None, None
else:
print("[!] 警告:无法在远程更新信息中找到模组版本信息或下载链接。")
return None, None
except requests.exceptions.RequestException as e:
print(f"[!] 错误:检查模组更新失败,无法连接到 {update_url}。错误信息:{e}")
return None, None
except Exception as e:
print(f"[!] 错误:检查模组更新时发生未知错误:{e}")
return None, None
if __name__ == "__main__":
print("[+] -----------------------------------------------------")
print("[+] 七日杀模组复制工具")
print(f"[+] 版本: {__version__}")
print("[+] -----------------------------------------------------")
# 获取本地模组版本,如果不存在则创建
local_mod_version = get_local_mod_version()
if not local_mod_version:
local_mod_version = "0.0.0" # 初始版本号
save_local_mod_version(local_mod_version)
print(f"[+] 本地没有检测到模组版本信息,已创建并设置为:{local_mod_version}")
else:
print(f"[+] 本地模组版本:{local_mod_version}")
# 检查模组更新
if MOD_UPDATE_URL != "YOUR_MOD_UPDATE_RAW_URL_HERE":
latest_mod_version, mod_download_url = check_for_mod_update(local_mod_version, MOD_UPDATE_URL)
if latest_mod_version and mod_download_url:
# 获取游戏模组路径
steam_path = find_steam_path()
if steam_path:
game_library_path = find_7dtd_path(steam_path)
if game_library_path:
game_mods_path = os.path.join(game_library_path, "steamapps", "common", "7 Days To Die", "Mods")
if download_and_install_mod(mod_download_url, game_mods_path):
# 只有在模组下载安装成功后才更新本地版本号
save_local_mod_version(latest_mod_version)
else:
print("[!] 错误:无法找到七日杀游戏路径,无法安装模组更新。")
else:
print("[!] 错误:无法找到 Steam 路径,无法安装模组更新。")
else:
print("[!] 警告:请先配置 MOD_UPDATE_URL 以启用自动模组更新。")
# 步骤 1: 查找Steam安装路径
print("[+] 步骤1:查找Steam安装路径...")
steam_path = find_steam_path()
if not steam_path:
print("[!] 错误:注册表中未找到SteamPath键值对应的Steam安装路径。")
manual_input = True
else:
print(f"[+] 已找到Steam路径:{steam_path}")
steamapps_path = os.path.join(steam_path, "steamapps")
if not os.path.exists(steamapps_path):
print("[!] 错误:未找到SteamApps目录。")
manual_input = True
else:
print(f"[+] SteamApps路径:{steamapps_path}")
manual_input = False
if not manual_input:
# 步骤 2: 读取libraryfolders.vdf文件查找七日杀路径
print("[+] 步骤2:读取libraryfolders.vdf文件以查找七日杀路径...")
game_library_path = find_7dtd_path(steam_path)
if game_library_path:
print(f"[+] 找到七日杀库路径(来自libraryfolders.vdf):{game_library_path}")
game_mods_path = os.path.join(game_library_path, "steamapps", "common", "7 Days To Die", "Mods")
if not os.path.exists(game_mods_path):
print(f"[!] 错误:未找到七日杀模组目录:{game_mods_path}")
manual_input = True
else:
print(f"[+] 七日杀模组路径:{game_mods_path}")
# 步骤 3: 检查七日杀模组目录中已有的模组
print("[+] 步骤3:检查七日杀模组目录中已有的模组...")
if os.listdir(game_mods_path):
print(f"[+] 在以下路径中找到已有的模组:{game_mods_path}")
for item in os.listdir(game_mods_path):
print(f" {item}")
else:
print(f"[+] 在以下路径中未找到已有的模组:{game_mods_path}")
# 步骤 4: 将当前目录下的Mods复制到七日杀的mod当中
print("[+] 步骤4:将当前目录下“Mods”文件夹中的模组复制到七日杀的模组目录中...")
current_mods_path = os.path.join(os.getcwd(), "Mods")
copy_mods(current_mods_path, game_mods_path)
else:
manual_input = True
if manual_input:
# 步骤 5: 手动输入
print("[+] 步骤5:需要手动输入。")
drive_letter = input("请输入您的Steam库所在的盘符(例如:D):").strip().upper()
if not drive_letter:
print("[!] 错误:未输入盘符。")
else:
manual_game_mods_path = os.path.join(f"{drive_letter}:\\", "SteamLibrary", "steamapps", "common", "7 Days To Die", "Mods")
print(f"[+] 使用手动输入路径:{manual_game_mods_path}")
if not os.path.exists(manual_game_mods_path):
print(f"[!] 错误:指定的路径不存在:{manual_game_mods_path}")
else:
print("[+] 检查手动输入路径中已有的模组...")
if os.listdir(manual_game_mods_path):
print(f"[+] 在以下路径中找到已有的模组:{manual_game_mods_path}")
for item in os.listdir(manual_game_mods_path):
print(f" {item}")
else:
print(f"[+] 在以下路径中未找到已有的模组:{manual_game_mods_path}")
print("[+] 将当前目录下“Mods”文件夹中的模组复制到手动输入的路径中...")
current_mods_path = os.path.join(os.getcwd(), "Mods")
copy_mods(current_mods_path, manual_game_mods_path)
print("[+] -----------------------------------------------------")
print("[+] 操作已完成。")
print("[+] -----------------------------------------------------")
input("按任意键退出...")