From 63b3cc8c02f24e307cf4df44b65db19226397d76 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=89=8B=E7=93=9C=E4=B8=80=E5=8D=81=E9=9B=AA?= Date: Sun, 11 Aug 2024 15:45:49 +0800 Subject: [PATCH] =?UTF-8?q?chore:=20=E5=8E=9F=E5=A7=8B=E8=84=9A=E6=9C=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- script/BootWay.03.ps1 | 45 ++++++++++++++ script/BootWay05.bat | 90 ++++++++++++++++++++++++++++ script/BootWay05.ps1 | 123 ++++++++++++++++++++++++++++++++++++++ script/BootWay05.utf8.bat | 93 ++++++++++++++++++++++++++++ script/checkVersion.cjs | 42 +++++++++++++ script/dbghelp.dll | Bin 0 -> 13824 bytes 6 files changed, 393 insertions(+) create mode 100644 script/BootWay.03.ps1 create mode 100644 script/BootWay05.bat create mode 100644 script/BootWay05.ps1 create mode 100644 script/BootWay05.utf8.bat create mode 100644 script/checkVersion.cjs create mode 100644 script/dbghelp.dll diff --git a/script/BootWay.03.ps1 b/script/BootWay.03.ps1 new file mode 100644 index 00000000..d4fb6707 --- /dev/null +++ b/script/BootWay.03.ps1 @@ -0,0 +1,45 @@ +# Dont Use This Script +# 2024.7.3 +function Get-QQpath { + try { + $key = Get-ItemProperty -Path "HKLM:\SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\Uninstall\QQ" + $uninstallString = $key.UninstallString + return [System.IO.Path]::GetDirectoryName($uninstallString) + "\QQ.exe" + } + catch { + throw "get QQ path error: $_" + } +} +function Select-QQPath { + Add-Type -AssemblyName System.Windows.Forms + [System.Windows.Forms.Application]::EnableVisualStyles() + + $dialogTitle = "Select QQ.exe" + + $filePicker = New-Object System.Windows.Forms.OpenFileDialog + $filePicker.Title = $dialogTitle + $filePicker.Filter = "Executable Files (*.exe)|*.exe|All Files (*.*)|*.*" + $filePicker.FilterIndex = 1 + $null = $filePicker.ShowDialog() + if (-not ($filePicker.FileName)) { + throw "User did not select an .exe file." + } + return $filePicker.FileName +} + +$params = $args -join " " +Try { + $QQpath = Get-QQpath +} +Catch { + $QQpath = Select-QQPath +} + +if (!(Test-Path $QQpath)) { + throw "provided QQ path is invalid: $QQpath" +} + +$Bootfile = Join-Path $PSScriptRoot "napcat.mjs" +$env:ELECTRON_RUN_AS_NODE = 1 +$commandInfo = Get-Command $QQpath -ErrorAction Stop +Start-Process powershell -ArgumentList "-noexit", "-noprofile", "-command &{& chcp 65001;& '$($commandInfo.Path)' --enable-logging }" \ No newline at end of file diff --git a/script/BootWay05.bat b/script/BootWay05.bat new file mode 100644 index 00000000..06d2ee3b --- /dev/null +++ b/script/BootWay05.bat @@ -0,0 +1,90 @@ +@echo off +REM 检查当前会话是否具有管理员权限 +openfiles >nul 2>&1 +if %errorlevel% neq 0 ( + REM 如果不是管理员,则重新启动脚本以管理员模式运行 + echo 请求管理员权限... + powershell -Command "Start-Process cmd -ArgumentList '/c %~f0 %*' -Verb RunAs" + exit /b +) + +REM 设置当前工作目录 +cd /d %~dp0 + +REM 获取当前目录路径 +set currentPath=%cd% +set currentPath=%currentPath:\=/% + +REM 生成JavaScript代码 +set "jsCode=(async () =^>await import('file:///%currentPath%/napcat.mjs'))();" + +REM 将JavaScript代码保存到文件中 +echo %jsCode% > loadScript.js +echo JavaScript code has been generated and saved to loadScript.js + +REM 设置NAPCAT_PATH环境变量为 当前目录的loadScript.js地址 +set NAPCAT_PATH=%cd%\loadScript.js + +REM 获取QQ路径 + + +:loop_read +for /f "tokens=2*" %%a in ('reg query "HKEY_LOCAL_MACHINE\SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\Uninstall\QQ" /v "UninstallString"') do ( + set RetString=%%b + goto :napcat_boot +) + +:napcat_boot +for %%a in (%RetString%) do ( + set "pathWithoutUninstall=%%~dpa" +) + +SET QQPath=%pathWithoutUninstall%QQ.exe + +REM 拿不到QQ路径则退出 +if not exist "%QQpath%" ( + echo provided QQ path is invalid: %QQpath% + pause + exit /b +) + +REM 收集dbghelp.dll路径和HASH信息 +set QQdir=%~dp0 +set oldDllPath=%QQdir%dbghelp.dll +set newDllPath=%currentPath%\dbghelp.dll + +for /f "tokens=*" %%A in ('certutil -hashfile "%oldDllPath%" MD5') do ( + if not defined oldDllHash set oldDllHash=%%A +) +for /f "tokens=*" %%A in ('certutil -hashfile "%newDllPath%" MD5') do ( + if not defined newDllHash set newDllHash=%%A +) + +REM 如果文件一致则跳过 +if "%oldDllHash%" neq "%newDllHash%" ( + tasklist /fi "imagename eq QQ.exe" 2>nul | find /i "QQ.exe" >nul + if %errorlevel% equ 0 ( + REM 文件占用则退出 + echo dbghelp.dll is in use, cannot continue. + ) else ( + REM 文件未占用则尝试覆盖 + copy /y "%newDllPath%" "%oldDllPath%" + if %errorlevel% neq 0 ( + echo Failed to copy dbghelp.dll + pause + exit /b + ) else ( + echo dbghelp.dll has been copied to %QQdir% + ) + ) +) + +REM 带参数启动QQ +REM 判断wt是否存在,存在则通过wt启动,不存在则通过cmd启动 +REM %QQPath% --enable-logging %* +where wt >nul 2>nul +if %errorlevel% equ 0 ( + wt "cmd" /c "%QQPath%" --enable-logging %* +) else ( + "%QQPath%" --enable-logging %* +) diff --git a/script/BootWay05.ps1 b/script/BootWay05.ps1 new file mode 100644 index 00000000..862281ef --- /dev/null +++ b/script/BootWay05.ps1 @@ -0,0 +1,123 @@ +# 检查当前会话是否具有管理员权限 +function Test-Administrator { + $user = [Security.Principal.WindowsIdentity]::GetCurrent() + (New-Object Security.Principal.WindowsPrincipal $user).IsInRole([Security.Principal.WindowsBuiltinRole]::Administrator) +} + +if (-not (Test-Administrator)) { + # 如果不是管理员,则重新启动脚本以管理员模式运行 + $scriptPath = $myInvocation.MyCommand.Path + if (-not $scriptPath) { + $scriptPath = $PSCommandPath + } + $newProcess = New-Object System.Diagnostics.ProcessStartInfo "powershell"; + $newProcess.Arguments = "-File `"$scriptPath`" $args" + $newProcess.Verb = "runas"; + [System.Diagnostics.Process]::Start($newProcess); + exit +} + +function Get-QQpath { + try { + $key = Get-ItemProperty -Path "HKLM:\SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\Uninstall\QQ" + $uninstallString = $key.UninstallString + return [System.IO.Path]::GetDirectoryName($uninstallString) + "\QQ.exe" + } + catch { + throw "get QQ path error: $_" + } +} +function Select-QQPath { + Add-Type -AssemblyName System.Windows.Forms + [System.Windows.Forms.Application]::EnableVisualStyles() + + $dialogTitle = "Select QQ.exe" + + $filePicker = New-Object System.Windows.Forms.OpenFileDialog + $filePicker.Title = $dialogTitle + $filePicker.Filter = "Executable Files (*.exe)|*.exe|All Files (*.*)|*.*" + $filePicker.FilterIndex = 1 + $null = $filePicker.ShowDialog() + if (-not ($filePicker.FileName)) { + throw "User did not select an .exe file." + } + return $filePicker.FileName +} + +# 设置当前工作目录 +$scriptDirectory = Split-Path -Path $MyInvocation.MyCommand.Definition -Parent +Set-Location $scriptDirectory + +# 获取当前目录路径 +$currentPath = Get-Location + +# 替换\为/ +$currentPath = $currentPath -replace '\\', '/' + +# 生成JavaScript代码 +$jsCode = @" +(async () => { + await import('file:///$currentPath/napcat.mjs'); +})(); +"@ + +# 将JavaScript代码保存到文件中 +$jsFilePath = Join-Path $currentPath "loadScript.js" +$jsCode | Out-File -FilePath $jsFilePath -Encoding UTF8 + +Write-Output "JavaScript code has been generated and saved to $jsFilePath" +# 设置NAPCAT_PATH环境变量为 当前目录的loadScript.js地址 +$env:NAPCAT_PATH = $jsFilePath + +$params = $args -join " " +Try { + $QQpath = Get-QQpath +} +Catch { + $QQpath = Select-QQPath +} +# 拿不到QQ路径则退出 +if (!(Test-Path $QQpath)) { + Write-Output "provided QQ path is invalid: $QQpath" + Read-Host "Press any key to continue..." + exit +} + +$commandInfo = Get-Command $QQpath -ErrorAction Stop + +# 收集dbghelp.dll路径和HASH信息 +$QQpath = Split-Path $QQpath +$oldDllPath = Join-Path $QQpath "dbghelp.dll" +$oldDllHash = Get-FileHash $oldDllPath -Algorithm MD5 +$newDllPath = Join-Path $currentPath "dbghelp.dll" +$newDllHash = Get-FileHash $newDllPath -Algorithm MD5 +# 如果文件一致则跳过 +if ($oldDllHash.Hash -ne $newDllHash.Hash) { + $processes = Get-Process -Name QQ -ErrorAction SilentlyContinue + if ($processes) { + # 文件占用则退出 + Write-Output "dbghelp.dll is in use by the following processes:" + $processes | ForEach-Object { Write-Output "$($_.Id) $($_.Name) $($_.Path)" } + Write-Output "dbghelp.dll is in use, cannot continue." + Read-Host "Press any key to continue..." + exit + } else { + # 文件未占用则尝试覆盖 + try { + Copy-Item -Path "$newDllPath" -Destination "$oldDllPath" -Force + Write-Output "dbghelp.dll has been copied to $QQpath" + } catch { + Write-Output "Failed to copy dbghelp.dll: $_" + Read-Host "Press any key to continue..." + exit + } + } +} + +# 带参数启动QQ +try { + Start-Process powershell -ArgumentList '-noexit', '-noprofile', "-command &{& chcp 65001;& '$($commandInfo.Path)' --enable-logging $params}" -NoNewWindow -ErrorAction Stop +} catch { + Write-Output "Failed to start process as administrator: $_" + Read-Host "Press any key to continue..." +} \ No newline at end of file diff --git a/script/BootWay05.utf8.bat b/script/BootWay05.utf8.bat new file mode 100644 index 00000000..2836a38a --- /dev/null +++ b/script/BootWay05.utf8.bat @@ -0,0 +1,93 @@ +@echo off +REM 检查当前会话是否具有管理员权限 +openfiles >nul 2>&1 +if %errorlevel% neq 0 ( + REM 如果不是管理员,则重新启动脚本以管理员模式运行 + echo 请求管理员权限... + where wt >nul 2>nul + if %errorlevel% equ 0 ( + powershell -Command "Start-Process cmd -ArgumentList ' /c %~f0 %*' -Verb RunAs" + ) else ( + powershell -Command "Start-Process wt -ArgumentList 'cmd /c %~f0 %*' -Verb RunAs" + ) + + REM wt "cmd" /c "%~f0 %*" + exit /b +) + +REM 设置当前工作目录 +cd /d %~dp0 + +REM 获取当前目录路径 +set currentPath=%cd% +set currentPath=%currentPath:\=/% + +REM 生成JavaScript代码 +set "jsCode=(async () =^>await import('file:///%currentPath%/napcat.mjs'))();" + +REM 将JavaScript代码保存到文件中 +echo %jsCode% > loadScript.js +echo JavaScript code has been generated and saved to loadScript.js + +REM 设置NAPCAT_PATH环境变量为 当前目录的loadScript.js地址 +set NAPCAT_PATH=%cd%\loadScript.js + +REM 获取QQ路径 + + +:loop_read +for /f "tokens=2*" %%a in ('reg query "HKEY_LOCAL_MACHINE\SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\Uninstall\QQ" /v "UninstallString"') do ( + set RetString=%%b + goto :napcat_boot +) + +:napcat_boot +for %%a in (%RetString%) do ( + set "pathWithoutUninstall=%%~dpa" +) + +SET QQPath=%pathWithoutUninstall%QQ.exe + +REM 拿不到QQ路径则退出 +if not exist "%QQpath%" ( + echo provided QQ path is invalid: %QQpath% + pause + exit /b +) + +REM 收集dbghelp.dll路径和HASH信息 +set QQdir=%~dp0 +set oldDllPath=%QQdir%dbghelp.dll +set newDllPath=%currentPath%\dbghelp.dll + +for /f "tokens=*" %%A in ('certutil -hashfile "%oldDllPath%" MD5') do ( + if not defined oldDllHash set oldDllHash=%%A +) +for /f "tokens=*" %%A in ('certutil -hashfile "%newDllPath%" MD5') do ( + if not defined newDllHash set newDllHash=%%A +) + +REM 如果文件一致则跳过 +if "%oldDllHash%" neq "%newDllHash%" ( + tasklist /fi "imagename eq QQ.exe" 2>nul | find /i "QQ.exe" >nul + if %errorlevel% equ 0 ( + REM 文件占用则退出 + echo dbghelp.dll is in use, cannot continue. + ) else ( + REM 文件未占用则尝试覆盖 + copy /y "%newDllPath%" "%oldDllPath%" + if %errorlevel% neq 0 ( + echo Failed to copy dbghelp.dll + pause + exit /b + ) else ( + echo dbghelp.dll has been copied to %QQdir% + ) + ) +) + +REM 带参数启动QQ +REM 判断wt是否存在,存在则通过wt启动,不存在则通过cmd启动 +REM %QQPath% --enable-logging %* +chcp 65001 +"%QQPath%" --enable-logging %* diff --git a/script/checkVersion.cjs b/script/checkVersion.cjs new file mode 100644 index 00000000..6863b9c9 --- /dev/null +++ b/script/checkVersion.cjs @@ -0,0 +1,42 @@ +const fs = require("fs"); +const process = require("process"); + +console.log("[NapCat] [CheckVersion] 开始检测当前仓库版本..."); +try { + const packageJson = require("../package.json"); + const currentVersion = packageJson.version; + const targetVersion = process.env.VERSION; + + console.log("[NapCat] [CheckVersion] currentVersion:", currentVersion, "targetVersion:", targetVersion); + + // 验证 targetVersion 格式 + if (!targetVersion || typeof targetVersion !== 'string') { + console.error("[NapCat] [CheckVersion] 目标版本格式不正确或未设置!"); + return; + } + + // 写入脚本文件的统一函数 + const writeScriptToFile = (content) => { + fs.writeFileSync("./checkVersion.sh", content, { flag: 'w' }); + console.log("[NapCat] [CheckVersion] checkVersion.sh 文件已更新。"); + }; + + if (currentVersion === targetVersion) { + // 不需要更新版本,写入一个简单的脚本 + const simpleScript = "#!/bin/bash\necho \"CheckVersion Is Done\""; + writeScriptToFile(simpleScript); + } else { + // 更新版本,构建安全的sed命令 + const safeScriptContent = ` + #!/bin/bash + git config --global user.email "bot@test.wumiao.wang" + git config --global user.name "Version" + sed -i "s/\\\"version\\\": \\\"${currentVersion}\\\"/\\\"version\\\": \\\"${targetVersion}\\\"/g" package.json + git add . + git commit -m "chore:version change" + git push -u origin main`; + writeScriptToFile(safeScriptContent); + } +} catch (error) { + console.error("[NapCat] [CheckVersion] 检测过程中发生错误:", error); +} \ No newline at end of file diff --git a/script/dbghelp.dll b/script/dbghelp.dll new file mode 100644 index 0000000000000000000000000000000000000000..f1fbedf59d1769f3462306ecb2dc13f8132bd3ec GIT binary patch literal 13824 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 R)xEF#v+AF7{%=R%e*lZ`CGr3O literal 0 HcmV?d00001