From 0d33fe8fe435d6947e987a5aea05d01776797531 Mon Sep 17 00:00:00 2001 From: H3CoF6 <1707889225@qq.com> Date: Sat, 28 Feb 2026 05:37:19 +0800 Subject: [PATCH] feat: update welcome page and fix handle error --- electron/services/keyService.ts | 9 ++-- src/pages/WelcomePage.scss | 76 ++++++++++++++++++++++++++ src/pages/WelcomePage.tsx | 96 ++++++++++++++++++++++----------- 3 files changed, 146 insertions(+), 35 deletions(-) diff --git a/electron/services/keyService.ts b/electron/services/keyService.ts index 2da4539..538e8cc 100644 --- a/electron/services/keyService.ts +++ b/electron/services/keyService.ts @@ -146,10 +146,11 @@ export class KeyService { this.koffi = require('koffi') this.kernel32 = this.koffi.load('kernel32.dll') - this.OpenProcess = this.kernel32.func('OpenProcess', 'HANDLE', ['uint32', 'bool', 'uint32']) - this.CloseHandle = this.kernel32.func('CloseHandle', 'bool', ['HANDLE']) - this.TerminateProcess = this.kernel32.func('TerminateProcess', 'bool', ['HANDLE', 'uint32']) - this.QueryFullProcessImageNameW = this.kernel32.func('QueryFullProcessImageNameW', 'bool', ['HANDLE', 'uint32', this.koffi.out('uint16*'), this.koffi.out('uint32*')]) + // 直接使用原生支持的 'void*' 替换 'HANDLE',绝对不会再报类型错误 + this.OpenProcess = this.kernel32.func('OpenProcess', 'void*', ['uint32', 'bool', 'uint32']) + this.CloseHandle = this.kernel32.func('CloseHandle', 'bool', ['void*']) + this.TerminateProcess = this.kernel32.func('TerminateProcess', 'bool', ['void*', 'uint32']) + this.QueryFullProcessImageNameW = this.kernel32.func('QueryFullProcessImageNameW', 'bool', ['void*', 'uint32', this.koffi.out('uint16*'), this.koffi.out('uint32*')]) return true } catch (e) { diff --git a/src/pages/WelcomePage.scss b/src/pages/WelcomePage.scss index 395b24e..3890db4 100644 --- a/src/pages/WelcomePage.scss +++ b/src/pages/WelcomePage.scss @@ -803,3 +803,79 @@ opacity: 1; } } + + +.brute-force-progress { + margin-top: 16px; + padding: 14px 16px; + background: var(--bg-tertiary); + border: 1px solid var(--border-color); + border-radius: 12px; + animation: slideUp 0.3s ease; + + .status-header { + display: flex; + justify-content: space-between; + align-items: center; + margin-bottom: 10px; + + .status-text { + font-size: 13px; + color: var(--text-primary); + font-weight: 500; + margin: 0; + animation: pulse 2s ease-in-out infinite; + } + + .percent { + font-size: 14px; + color: var(--primary); + font-weight: 700; + font-family: var(--font-mono); + } + } + + .progress-bar-container { + width: 100%; + height: 8px; + background: var(--bg-primary); + border-radius: 4px; + overflow: hidden; + border: 1px solid var(--border-color); + box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.05); + + .fill { + height: 100%; + background: linear-gradient(90deg, var(--primary) 0%, color-mix(in srgb, var(--primary) 60%, white) 100%); + border-radius: 4px; + transition: width 0.3s cubic-bezier(0.4, 0, 0.2, 1); + position: relative; + + &::after { + content: ''; + position: absolute; + top: 0; + left: 0; + right: 0; + bottom: 0; + background: linear-gradient( + 90deg, + transparent, + rgba(255, 255, 255, 0.3), + transparent + ); + animation: progress-shimmer 1.5s infinite linear; + } + } + } +} + +@keyframes pulse { + 0%, 100% { opacity: 1; } + 50% { opacity: 0.7; } +} + +@keyframes progress-shimmer { + 0% { transform: translateX(-100%); } + 100% { transform: translateX(100%); } +} \ No newline at end of file diff --git a/src/pages/WelcomePage.tsx b/src/pages/WelcomePage.tsx index a1e556b..4623d2f 100644 --- a/src/pages/WelcomePage.tsx +++ b/src/pages/WelcomePage.tsx @@ -48,6 +48,7 @@ function WelcomePage({ standalone = false }: WelcomePageProps) { const [dbKeyStatus, setDbKeyStatus] = useState('') const [imageKeyStatus, setImageKeyStatus] = useState('') const [isManualStartPrompt, setIsManualStartPrompt] = useState(false) + const [imageKeyPercent, setImageKeyPercent] = useState(null) // 安全相关 state const [enableAuth, setEnableAuth] = useState(false) @@ -111,8 +112,25 @@ function WelcomePage({ standalone = false }: WelcomePageProps) { const removeDb = window.electronAPI.key.onDbKeyStatus((payload: { message: string; level: number }) => { setDbKeyStatus(payload.message) }) - const removeImage = window.electronAPI.key.onImageKeyStatus((payload: { message: string }) => { - setImageKeyStatus(payload.message) + const removeImage = window.electronAPI.key.onImageKeyStatus((payload: { message: string, percent?: number }) => { + let msg = payload.message; + let pct = payload.percent; + + // 解析文本中的百分比 + if (pct === undefined) { + const match = msg.match(/\(([\d.]+)%\)/); + if (match) { + pct = parseFloat(match[1]); + msg = msg.replace(/\s*\([\d.]+%\)/, ''); + } + } + + setImageKeyStatus(msg); + if (pct !== undefined) { + setImageKeyPercent(pct); + } else if (msg.includes('启动多核') || msg.includes('定位') || msg.includes('准备')) { + setImageKeyPercent(0); + } }) return () => { removeDb?.() @@ -297,6 +315,7 @@ function WelcomePage({ standalone = false }: WelcomePageProps) { } setIsFetchingImageKey(true) setError('') + setImageKeyPercent(0) setImageKeyStatus('正在准备获取图片密钥...') try { // 拼接完整的账号目录,确保 KeyService 能准确找到模板文件 @@ -727,37 +746,52 @@ function WelcomePage({ standalone = false }: WelcomePageProps) { )} {currentStep.id === 'image' && ( -
-
-
- - setImageXorKey(e.target.value)} - /> -
-
- - setImageAesKey(e.target.value)} - /> +
+
+
+ + setImageXorKey(e.target.value)} + /> +
+
+ + setImageAesKey(e.target.value)} + /> +
+ + + + {isFetchingImageKey ? ( +
+
+ {imageKeyStatus || '正在启动多核爆破引擎...'} + {imageKeyPercent !== null && {imageKeyPercent.toFixed(1)}%} +
+ {imageKeyPercent !== null && ( +
+
+
+ )} +
+ ) : ( + imageKeyStatus &&
{imageKeyStatus}
+ )} + +
请在微信中打开几张图片后再点击获取
- - - - {imageKeyStatus &&
{imageKeyStatus}
} -
请在微信中打开几张图片后再点击获取
-
)}