Skip to content

Commit f8f987a

Browse files
committed
fix python time.sleep not working
1 parent f1f7c96 commit f8f987a

File tree

7 files changed

+207
-124
lines changed

7 files changed

+207
-124
lines changed

OpenSpeedy_en_US.ts

Lines changed: 39 additions & 35 deletions
Large diffs are not rendered by default.

OpenSpeedy_zh_CN.ts

Lines changed: 39 additions & 35 deletions
Large diffs are not rendered by default.

OpenSpeedy_zh_TW.ts

Lines changed: 39 additions & 35 deletions
Large diffs are not rendered by default.

mainwindow.ui

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -632,7 +632,7 @@ QSlider::handle:horizontal:pressed {
632632
<string notr="true"/>
633633
</property>
634634
<property name="title">
635-
<string>💻系统进程</string>
635+
<string>💻进程</string>
636636
</property>
637637
<layout class="QVBoxLayout" name="verticalLayout_4">
638638
<item>

speedpatch/speedpatch.cpp

Lines changed: 89 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
/*
1+
/*
22
* OpenSpeedy - Open Source Game Speed Controller
33
* Copyright (C) 2025 Game1024
44
*
@@ -19,6 +19,7 @@
1919
* <https://www.gnu.org/licenses/>.
2020
*/
2121
#include <windows.h>
22+
#include <winternl.h>
2223
#include "Minhook.h"
2324
#include "speedpatch.h"
2425
#include <atomic>
@@ -37,18 +38,22 @@ static HANDLE hShare;
3738
static bool* pEnable;
3839

3940
typedef VOID (WINAPI* SLEEP) (DWORD);
40-
typedef UINT_PTR (WINAPI* SETTIMER) (HWND,
41-
UINT_PTR,
42-
UINT,
43-
TIMERPROC
44-
);
41+
typedef DWORD (WINAPI* SLEEPEX) (DWORD, BOOL);
42+
43+
typedef UINT_PTR (WINAPI* SETTIMER) (
44+
HWND,
45+
UINT_PTR,
46+
UINT,
47+
TIMERPROC
48+
);
4549
typedef DWORD (WINAPI* TIMEGETTIME) (VOID);
46-
typedef MMRESULT (WINAPI* TIMESETEVENT) (UINT,
47-
UINT,
48-
LPTIMECALLBACK,
49-
DWORD_PTR,
50-
UINT
51-
);
50+
typedef MMRESULT (WINAPI* TIMESETEVENT) (
51+
UINT,
52+
UINT,
53+
LPTIMECALLBACK,
54+
DWORD_PTR,
55+
UINT
56+
);
5257

5358
typedef LONG (WINAPI* GETMESSAGETIME) (VOID);
5459
typedef DWORD (WINAPI* GETTICKCOUNT) (VOID);
@@ -60,11 +65,23 @@ typedef BOOL (WINAPI* QUERYPERFORMANCEFREQUENCY) (LARGE_INTEGER*);
6065
typedef VOID (WINAPI* GETSYSTEMTIMEASFILETIME) (LPFILETIME);
6166
typedef VOID (WINAPI* GETSYSTEMTIMEPRECISEASFILETIME) (LPFILETIME);
6267

68+
typedef BOOL (WINAPI* SETWAITABLETIMEREX) (
69+
HANDLE,
70+
const LARGE_INTEGER*,
71+
LONG,
72+
PTIMERAPCROUTINE,
73+
LPVOID,
74+
PREASON_CONTEXT,
75+
ULONG);
76+
6377
inline VOID shouldUpdateAll();
6478

6579
static SLEEP pfnKernelSleep = NULL;
6680
static SLEEP pfnDetourSleep = NULL;
6781

82+
static SLEEPEX pfnKernelSleepEx = NULL;
83+
static SLEEPEX pfnDetourSleepEx = NULL;
84+
6885
static SETTIMER pfnKernelSetTimer = NULL;
6986
static SETTIMER pfnDetourSetTimer = NULL;
7087

@@ -95,6 +112,9 @@ static GETSYSTEMTIMEASFILETIME pfnDetourGetSystemTimeAsFileTime = NULL;
95112
static GETSYSTEMTIMEPRECISEASFILETIME pfnKernelGetSystemTimePreciseAsFileTime = NULL;
96113
static GETSYSTEMTIMEPRECISEASFILETIME pfnDetourGetSystemTimePreciseAsFileTime = NULL;
97114

115+
static SETWAITABLETIMEREX pfnKernelSetWaitableTimerEx = NULL;
116+
static SETWAITABLETIMEREX pfnDetourSetWaitableTimerEx = NULL;
117+
98118
SPEEDPATCH_API void ChangeSpeed(double factor_)
99119
{
100120
factor.store(factor_);
@@ -199,6 +219,12 @@ VOID WINAPI DetourSleep(DWORD dwMilliseconds)
199219
pfnKernelSleep(dwMilliseconds / SpeedFactor());
200220
}
201221

222+
DWORD WINAPI DetourSleepEx(DWORD dwMilliseconds, BOOL bAlertable)
223+
{
224+
std::shared_lock<std::shared_mutex> lock(mutex);
225+
return pfnKernelSleepEx(dwMilliseconds / SpeedFactor(), bAlertable);
226+
}
227+
202228
UINT_PTR WINAPI DetourSetTimer(HWND hWnd,
203229
UINT_PTR nIDEvent,
204230
UINT uElapse,
@@ -484,6 +510,27 @@ DetourGetSystemTimePreciseAsFileTime(LPFILETIME lpSystemTimeAsFileTime)
484510
(*lpSystemTimeAsFileTime) = { ulRtn.LowPart, ulRtn.HighPart };
485511
}
486512

513+
BOOL WINAPI DetourSetWaitableTimerEx(
514+
HANDLE hTimer,
515+
const LARGE_INTEGER* lpDueTime,
516+
LONG lPeriod,
517+
PTIMERAPCROUTINE pfnCompletionRoutine,
518+
LPVOID lpArgToCompletionRoutine,
519+
PREASON_CONTEXT WakeContext,
520+
ULONG TolerableDelay
521+
)
522+
{
523+
LARGE_INTEGER dueTime = {0};
524+
dueTime.QuadPart = lpDueTime->QuadPart / SpeedFactor();
525+
return pfnKernelSetWaitableTimerEx(hTimer,
526+
&dueTime,
527+
lPeriod,
528+
pfnCompletionRoutine,
529+
lpArgToCompletionRoutine,
530+
WakeContext,
531+
TolerableDelay);
532+
}
533+
487534
inline VOID shouldUpdateAll()
488535
{
489536
shouldUpdateTimeGetTime = true;
@@ -498,10 +545,18 @@ inline VOID shouldUpdateAll()
498545
template <typename S, typename T>
499546
inline VOID MH_HOOK(S* pTarget, S* pDetour, T** ppOriginal)
500547
{
501-
MH_CreateHook(reinterpret_cast<LPVOID> (pTarget),
502-
reinterpret_cast<LPVOID> (pDetour),
503-
reinterpret_cast<LPVOID*> (ppOriginal));
504-
MH_EnableHook(reinterpret_cast<LPVOID> (pTarget));
548+
549+
if (MH_CreateHook(reinterpret_cast<LPVOID> (pTarget),
550+
reinterpret_cast<LPVOID> (pDetour),
551+
reinterpret_cast<LPVOID*> (ppOriginal)) != MH_OK)
552+
{
553+
MessageBoxW(NULL, L"MH装载失败", L"DLL", MB_OK);
554+
}
555+
556+
if (MH_EnableHook(reinterpret_cast<LPVOID> (pTarget)) != MH_OK)
557+
{
558+
MessageBoxW(NULL, L"MH装载失败", L"DLL", MB_OK);
559+
}
505560
}
506561

507562
template <typename T>
@@ -533,9 +588,13 @@ BOOL APIENTRY DllMain(HMODULE hModule,
533588
LPVOID lpReserved)
534589
{
535590
FILETIME now = { 0 };
591+
HMODULE hKernel32;
592+
SETWAITABLETIMEREX pSetWaitableTimerEx;
536593
switch (ul_reason_for_call)
537594
{
538595
case DLL_PROCESS_ATTACH:
596+
hKernel32 = GetModuleHandleW(L"kernel32.dll");
597+
539598
if (MH_Initialize() != MH_OK)
540599
{
541600
MessageBoxW(NULL, L"MH装载失败", L"DLL", MB_OK);
@@ -587,8 +646,17 @@ BOOL APIENTRY DllMain(HMODULE hModule,
587646
baselineDetourGetSystemTimePreciseAsFileTime.store(now);
588647
prevcallDetourGetSystemTimePreciseAsFileTime.store(now);
589648

590-
MH_HOOK(
591-
&Sleep, &DetourSleep, reinterpret_cast<LPVOID*> (&pfnKernelSleep));
649+
MH_HOOK(&Sleep,
650+
&DetourSleep,
651+
reinterpret_cast<LPVOID*> (&pfnKernelSleep));
652+
MH_HOOK(&SleepEx,
653+
&DetourSleepEx,
654+
reinterpret_cast<LPVOID*>(&pfnKernelSleepEx));
655+
656+
pSetWaitableTimerEx = (SETWAITABLETIMEREX)GetProcAddress(hKernel32, "SetWaitableTimerEx");
657+
MH_HOOK(pSetWaitableTimerEx,
658+
&DetourSetWaitableTimerEx,
659+
reinterpret_cast<LPVOID*>(&pfnKernelSetWaitableTimerEx));
592660
MH_HOOK(&SetTimer,
593661
&DetourSetTimer,
594662
reinterpret_cast<LPVOID*> (&pfnKernelSetTimer));
@@ -617,6 +685,8 @@ BOOL APIENTRY DllMain(HMODULE hModule,
617685
&DetourGetSystemTimePreciseAsFileTime,
618686
reinterpret_cast<LPVOID*> (
619687
&pfnKernelGetSystemTimePreciseAsFileTime));
688+
689+
620690
break;
621691
case DLL_THREAD_ATTACH:
622692
break;
@@ -633,6 +703,7 @@ BOOL APIENTRY DllMain(HMODULE hModule,
633703
MH_UNHOOK(pfnKernelSleep);
634704
MH_UNHOOK(pfnKernelSetTimer);
635705
MH_UNHOOK(pfnKernelTimeGetTime);
706+
MH_UNHOOK(pfnKernelTimeSetEvent);
636707
MH_UNHOOK(pfnKernelGetTickCount);
637708
MH_UNHOOK(pfnKernelGetTickCount64);
638709
MH_UNHOOK(pfnKernelQueryPerformanceCounter);

translations/OpenSpeedy_en_US.qm

71 Bytes
Binary file not shown.

translations/OpenSpeedy_zh_TW.qm

57 Bytes
Binary file not shown.

0 commit comments

Comments
 (0)