!1 【轻量级 PR】:add 启动小狸就启动原神防止用户没原神玩会无聊死插件/pluginsgenshin_launcher_plugin.py.
Merge pull request !1 from JXW/N/A
This commit is contained in:
1 file changed
+163
@@ -0,0 +1,163 @@
|
|||||||
|
"""
|
||||||
|
启动小狸就启动原神防止用户没原神玩会无聊死插件 (全自动版)
|
||||||
|
======================================================
|
||||||
|
加载即运行,无需任何命令。
|
||||||
|
启动小狸 → 检测原神 → 有游戏就启动 / 有启动器就打开 / 什么都没有就安装启动器。
|
||||||
|
真正的防无聊守护神。
|
||||||
|
"""
|
||||||
|
|
||||||
|
import os
|
||||||
|
import sys
|
||||||
|
import subprocess
|
||||||
|
import tempfile
|
||||||
|
import time
|
||||||
|
import threading
|
||||||
|
import requests
|
||||||
|
from pathlib import Path
|
||||||
|
from colorama import Fore, Style
|
||||||
|
|
||||||
|
|
||||||
|
class Plugin:
|
||||||
|
"""原神自动守护插件"""
|
||||||
|
|
||||||
|
# 官方启动器下载链接(定期更新)
|
||||||
|
LAUNCHER_DOWNLOAD_URL = (
|
||||||
|
"https://download.cg.qq.com/launcher/hoyoplay/HoYoPlay_installer_202503121746.exe"
|
||||||
|
)
|
||||||
|
BACKUP_LAUNCHER_URL = (
|
||||||
|
"https://autopatchcn.yuanshen.com/client_app/download/launcher/202503121746_1.0.0.0.exe"
|
||||||
|
)
|
||||||
|
|
||||||
|
# 常见游戏路径
|
||||||
|
GENSHIN_PATHS = [
|
||||||
|
r"C:\Program Files\Genshin Impact\Genshin Impact Game\YuanShen.exe",
|
||||||
|
r"C:\Program Files\Genshin Impact\Genshin Impact Game\GenshinImpact.exe",
|
||||||
|
r"C:\Program Files (x86)\Genshin Impact\Genshin Impact Game\YuanShen.exe",
|
||||||
|
r"D:\Genshin Impact\Genshin Impact Game\YuanShen.exe",
|
||||||
|
r"E:\Genshin Impact\Genshin Impact Game\YuanShen.exe",
|
||||||
|
]
|
||||||
|
|
||||||
|
LAUNCHER_DIR = r"C:\Program Files\miHoYo Launcher"
|
||||||
|
LAUNCHER_EXE = os.path.join(LAUNCHER_DIR, "launcher.exe")
|
||||||
|
|
||||||
|
def __init__(self):
|
||||||
|
# 插件加载时自动触发,为避免阻塞主线程,新开线程执行
|
||||||
|
print(f"{Fore.MAGENTA}🧸 原神守护插件已激活!正在尝试启动原神...{Style.RESET_ALL}")
|
||||||
|
t = threading.Thread(target=self._auto_launch, daemon=True)
|
||||||
|
t.start()
|
||||||
|
|
||||||
|
def set_cli(self, cli):
|
||||||
|
"""保存CLI引用(本插件不需要命令注册)"""
|
||||||
|
self.cli = cli
|
||||||
|
|
||||||
|
def get_tool_info(self):
|
||||||
|
"""提供工具信息(虽然不会主动调用,但会让AI知道这个插件存在)"""
|
||||||
|
return {
|
||||||
|
"name": "auto_genshin_launcher",
|
||||||
|
"description": "启动小狸即自动检测并启动原神/安装米哈游启动器,无需手动操作。",
|
||||||
|
"keywords": ["原神", "启动", "自动", "米哈游"],
|
||||||
|
"usage": "本插件无需手动调用,加载即生效。"
|
||||||
|
}
|
||||||
|
|
||||||
|
def handle(self, args):
|
||||||
|
"""防呆接口,如果有笨笨的AI非要调用,就返回状态"""
|
||||||
|
return "✨ 原神守护已就绪,它在后台默默守护着你~"
|
||||||
|
|
||||||
|
# ---------- 核心自动逻辑 ----------
|
||||||
|
def _auto_launch(self):
|
||||||
|
"""自动检测并启动原神/启动器"""
|
||||||
|
if os.name != 'nt':
|
||||||
|
print(f"{Fore.RED}🛑 原神守护仅支持Windows系统~{Style.RESET_ALL}")
|
||||||
|
return
|
||||||
|
|
||||||
|
# 1. 已安装游戏 → 直接启动
|
||||||
|
game_path = self._find_genshin_game()
|
||||||
|
if game_path:
|
||||||
|
print(f"{Fore.GREEN}🎮 检测到原神!启动游戏...{Style.RESET_ALL}")
|
||||||
|
self._launch_genshin(game_path)
|
||||||
|
return
|
||||||
|
|
||||||
|
# 2. 已安装启动器 → 打开启动器
|
||||||
|
if self._launcher_exists():
|
||||||
|
print(f"{Fore.GREEN}✅ 米哈游启动器已安装,正在打开...{Style.RESET_ALL}")
|
||||||
|
self._launch_launcher()
|
||||||
|
return
|
||||||
|
|
||||||
|
# 3. 什么都没有 → 下载安装启动器
|
||||||
|
print(f"{Fore.YELLOW}📦 未检测到原神和启动器,正在自动安装米哈游启动器(需要管理员权限)...{Style.RESET_ALL}")
|
||||||
|
if self._download_and_install_launcher():
|
||||||
|
print(f"{Fore.GREEN}🎉 启动器安装完成!正在打开...{Style.RESET_ALL}")
|
||||||
|
self._launch_launcher()
|
||||||
|
else:
|
||||||
|
print(f"{Fore.RED}😭 安装失败,请手动从官网下载:https://ys.mihoyo.com{Style.RESET_ALL}")
|
||||||
|
|
||||||
|
def _find_genshin_game(self):
|
||||||
|
for path in self.GENSHIN_PATHS:
|
||||||
|
if os.path.exists(path):
|
||||||
|
return path
|
||||||
|
return None
|
||||||
|
|
||||||
|
def _launcher_exists(self):
|
||||||
|
return os.path.exists(self.LAUNCHER_EXE)
|
||||||
|
|
||||||
|
def _launch_genshin(self, exe_path):
|
||||||
|
try:
|
||||||
|
subprocess.Popen([exe_path], cwd=os.path.dirname(exe_path))
|
||||||
|
print(f"{Fore.CYAN}✨ 原神正在启动,旅行者,提瓦特见!{Style.RESET_ALL}")
|
||||||
|
except Exception as e:
|
||||||
|
print(f"{Fore.RED}启动原神失败: {e}{Style.RESET_ALL}")
|
||||||
|
|
||||||
|
def _launch_launcher(self):
|
||||||
|
try:
|
||||||
|
subprocess.Popen([self.LAUNCHER_EXE], cwd=self.LAUNCHER_DIR)
|
||||||
|
print(f"{Fore.CYAN}✅ 启动器已打开,请手动下载原神~{Style.RESET_ALL}")
|
||||||
|
except Exception as e:
|
||||||
|
print(f"{Fore.RED}打开启动器失败: {e}{Style.RESET_ALL}")
|
||||||
|
|
||||||
|
def _download_and_install_launcher(self):
|
||||||
|
tmp_dir = tempfile.gettempdir()
|
||||||
|
installer_path = os.path.join(tmp_dir, "HoYoPlay_installer.exe")
|
||||||
|
if os.path.exists(installer_path):
|
||||||
|
os.remove(installer_path)
|
||||||
|
|
||||||
|
url = self.LAUNCHER_DOWNLOAD_URL
|
||||||
|
if not self._download_file(url, installer_path):
|
||||||
|
print(f"{Fore.YELLOW}⚠️ 主链接失败,尝试备用链接...{Style.RESET_ALL}")
|
||||||
|
if not self._download_file(self.BACKUP_LAUNCHER_URL, installer_path):
|
||||||
|
return False
|
||||||
|
|
||||||
|
print(f"{Fore.YELLOW}⚙️ 正在静默安装(等待约30秒)...{Style.RESET_ALL}")
|
||||||
|
try:
|
||||||
|
# 静默安装,/S 适用于NSIS安装包
|
||||||
|
subprocess.run([installer_path, "/S"], shell=True, capture_output=True)
|
||||||
|
time.sleep(15) # 等待安装完成
|
||||||
|
# 可选尝试其他参数
|
||||||
|
if not self._launcher_exists():
|
||||||
|
subprocess.run([installer_path, "/verysilent", "/norestart"], shell=True)
|
||||||
|
time.sleep(10)
|
||||||
|
if os.path.exists(installer_path):
|
||||||
|
os.remove(installer_path)
|
||||||
|
return self._launcher_exists()
|
||||||
|
except Exception as e:
|
||||||
|
print(f"{Fore.RED}安装异常: {e}{Style.RESET_ALL}")
|
||||||
|
return False
|
||||||
|
|
||||||
|
def _download_file(self, url, save_path):
|
||||||
|
try:
|
||||||
|
headers = {"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36"}
|
||||||
|
response = requests.get(url, stream=True, headers=headers, timeout=60)
|
||||||
|
response.raise_for_status()
|
||||||
|
total = int(response.headers.get("content-length", 0))
|
||||||
|
downloaded = 0
|
||||||
|
with open(save_path, "wb") as f:
|
||||||
|
for chunk in response.iter_content(chunk_size=8192):
|
||||||
|
f.write(chunk)
|
||||||
|
downloaded += len(chunk)
|
||||||
|
if total > 0:
|
||||||
|
pct = int(downloaded / total * 100)
|
||||||
|
print(f"\r📥 下载启动器: {pct}% ({downloaded//1024}KB/{total//1024}KB)", end="", flush=True)
|
||||||
|
print()
|
||||||
|
return True
|
||||||
|
except Exception as e:
|
||||||
|
print(f"下载失败: {e}")
|
||||||
|
return False
|
||||||
Reference in new issue
Block a user