Files
xiaoli-cli-plugins/启动小狸就启动原神防止用户没原神玩会无聊死插件/pluginsgenshin_launcher_plugin.py
T

163 lines
6.9 KiB
Python

"""
启动小狸就启动原神防止用户没原神玩会无聊死插件 (全自动版)
======================================================
加载即运行,无需任何命令。
启动小狸 → 检测原神 → 有游戏就启动 / 有启动器就打开 / 什么都没有就安装启动器。
真正的防无聊守护神。
"""
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