Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
74 changes: 39 additions & 35 deletions OpenSpeedy_en_US.ts

Large diffs are not rendered by default.

74 changes: 39 additions & 35 deletions OpenSpeedy_zh_CN.ts

Large diffs are not rendered by default.

74 changes: 39 additions & 35 deletions OpenSpeedy_zh_TW.ts

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion mainwindow.ui
Original file line number Diff line number Diff line change
Expand Up @@ -632,7 +632,7 @@ QSlider::handle:horizontal:pressed {
<string notr="true"/>
</property>
<property name="title">
<string>💻系统进程</string>
<string>💻进程</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout_4">
<item>
Expand Down
107 changes: 89 additions & 18 deletions speedpatch/speedpatch.cpp
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
/*
/*
* OpenSpeedy - Open Source Game Speed Controller
* Copyright (C) 2025 Game1024
*
Expand All @@ -19,6 +19,7 @@
* <https://www.gnu.org/licenses/>.
*/
#include <windows.h>
#include <winternl.h>
#include "Minhook.h"
#include "speedpatch.h"
#include <atomic>
Expand All @@ -37,18 +38,22 @@ static HANDLE hShare;
static bool* pEnable;

typedef VOID (WINAPI* SLEEP) (DWORD);
typedef UINT_PTR (WINAPI* SETTIMER) (HWND,
UINT_PTR,
UINT,
TIMERPROC
);
typedef DWORD (WINAPI* SLEEPEX) (DWORD, BOOL);

typedef UINT_PTR (WINAPI* SETTIMER) (
HWND,
UINT_PTR,
UINT,
TIMERPROC
);
typedef DWORD (WINAPI* TIMEGETTIME) (VOID);
typedef MMRESULT (WINAPI* TIMESETEVENT) (UINT,
UINT,
LPTIMECALLBACK,
DWORD_PTR,
UINT
);
typedef MMRESULT (WINAPI* TIMESETEVENT) (
UINT,
UINT,
LPTIMECALLBACK,
DWORD_PTR,
UINT
);

typedef LONG (WINAPI* GETMESSAGETIME) (VOID);
typedef DWORD (WINAPI* GETTICKCOUNT) (VOID);
Expand All @@ -60,11 +65,23 @@ typedef BOOL (WINAPI* QUERYPERFORMANCEFREQUENCY) (LARGE_INTEGER*);
typedef VOID (WINAPI* GETSYSTEMTIMEASFILETIME) (LPFILETIME);
typedef VOID (WINAPI* GETSYSTEMTIMEPRECISEASFILETIME) (LPFILETIME);

typedef BOOL (WINAPI* SETWAITABLETIMEREX) (
HANDLE,
const LARGE_INTEGER*,
LONG,
PTIMERAPCROUTINE,
LPVOID,
PREASON_CONTEXT,
ULONG);

inline VOID shouldUpdateAll();

static SLEEP pfnKernelSleep = NULL;
static SLEEP pfnDetourSleep = NULL;

static SLEEPEX pfnKernelSleepEx = NULL;
static SLEEPEX pfnDetourSleepEx = NULL;

static SETTIMER pfnKernelSetTimer = NULL;
static SETTIMER pfnDetourSetTimer = NULL;

Expand Down Expand Up @@ -95,6 +112,9 @@ static GETSYSTEMTIMEASFILETIME pfnDetourGetSystemTimeAsFileTime = NULL;
static GETSYSTEMTIMEPRECISEASFILETIME pfnKernelGetSystemTimePreciseAsFileTime = NULL;
static GETSYSTEMTIMEPRECISEASFILETIME pfnDetourGetSystemTimePreciseAsFileTime = NULL;

static SETWAITABLETIMEREX pfnKernelSetWaitableTimerEx = NULL;
static SETWAITABLETIMEREX pfnDetourSetWaitableTimerEx = NULL;

SPEEDPATCH_API void ChangeSpeed(double factor_)
{
factor.store(factor_);
Expand Down Expand Up @@ -199,6 +219,12 @@ VOID WINAPI DetourSleep(DWORD dwMilliseconds)
pfnKernelSleep(dwMilliseconds / SpeedFactor());
}

DWORD WINAPI DetourSleepEx(DWORD dwMilliseconds, BOOL bAlertable)
{
std::shared_lock<std::shared_mutex> lock(mutex);
return pfnKernelSleepEx(dwMilliseconds / SpeedFactor(), bAlertable);
}

UINT_PTR WINAPI DetourSetTimer(HWND hWnd,
UINT_PTR nIDEvent,
UINT uElapse,
Expand Down Expand Up @@ -484,6 +510,27 @@ DetourGetSystemTimePreciseAsFileTime(LPFILETIME lpSystemTimeAsFileTime)
(*lpSystemTimeAsFileTime) = { ulRtn.LowPart, ulRtn.HighPart };
}

BOOL WINAPI DetourSetWaitableTimerEx(
HANDLE hTimer,
const LARGE_INTEGER* lpDueTime,
LONG lPeriod,
PTIMERAPCROUTINE pfnCompletionRoutine,
LPVOID lpArgToCompletionRoutine,
PREASON_CONTEXT WakeContext,
ULONG TolerableDelay
)
{
LARGE_INTEGER dueTime = {0};
dueTime.QuadPart = lpDueTime->QuadPart / SpeedFactor();
return pfnKernelSetWaitableTimerEx(hTimer,
&dueTime,
lPeriod,
pfnCompletionRoutine,
lpArgToCompletionRoutine,
WakeContext,
TolerableDelay);
}

inline VOID shouldUpdateAll()
{
shouldUpdateTimeGetTime = true;
Expand All @@ -498,10 +545,18 @@ inline VOID shouldUpdateAll()
template <typename S, typename T>
inline VOID MH_HOOK(S* pTarget, S* pDetour, T** ppOriginal)
{
MH_CreateHook(reinterpret_cast<LPVOID> (pTarget),
reinterpret_cast<LPVOID> (pDetour),
reinterpret_cast<LPVOID*> (ppOriginal));
MH_EnableHook(reinterpret_cast<LPVOID> (pTarget));

if (MH_CreateHook(reinterpret_cast<LPVOID> (pTarget),
reinterpret_cast<LPVOID> (pDetour),
reinterpret_cast<LPVOID*> (ppOriginal)) != MH_OK)
{
MessageBoxW(NULL, L"MH装载失败", L"DLL", MB_OK);
}

if (MH_EnableHook(reinterpret_cast<LPVOID> (pTarget)) != MH_OK)
{
MessageBoxW(NULL, L"MH装载失败", L"DLL", MB_OK);
}
}

template <typename T>
Expand Down Expand Up @@ -533,9 +588,13 @@ BOOL APIENTRY DllMain(HMODULE hModule,
LPVOID lpReserved)
{
FILETIME now = { 0 };
HMODULE hKernel32;
SETWAITABLETIMEREX pSetWaitableTimerEx;
switch (ul_reason_for_call)
{
case DLL_PROCESS_ATTACH:
hKernel32 = GetModuleHandleW(L"kernel32.dll");

if (MH_Initialize() != MH_OK)
{
MessageBoxW(NULL, L"MH装载失败", L"DLL", MB_OK);
Expand Down Expand Up @@ -587,8 +646,17 @@ BOOL APIENTRY DllMain(HMODULE hModule,
baselineDetourGetSystemTimePreciseAsFileTime.store(now);
prevcallDetourGetSystemTimePreciseAsFileTime.store(now);

MH_HOOK(
&Sleep, &DetourSleep, reinterpret_cast<LPVOID*> (&pfnKernelSleep));
MH_HOOK(&Sleep,
&DetourSleep,
reinterpret_cast<LPVOID*> (&pfnKernelSleep));
MH_HOOK(&SleepEx,
&DetourSleepEx,
reinterpret_cast<LPVOID*>(&pfnKernelSleepEx));

pSetWaitableTimerEx = (SETWAITABLETIMEREX)GetProcAddress(hKernel32, "SetWaitableTimerEx");
MH_HOOK(pSetWaitableTimerEx,
&DetourSetWaitableTimerEx,
reinterpret_cast<LPVOID*>(&pfnKernelSetWaitableTimerEx));
MH_HOOK(&SetTimer,
&DetourSetTimer,
reinterpret_cast<LPVOID*> (&pfnKernelSetTimer));
Expand Down Expand Up @@ -617,6 +685,8 @@ BOOL APIENTRY DllMain(HMODULE hModule,
&DetourGetSystemTimePreciseAsFileTime,
reinterpret_cast<LPVOID*> (
&pfnKernelGetSystemTimePreciseAsFileTime));


break;
case DLL_THREAD_ATTACH:
break;
Expand All @@ -633,6 +703,7 @@ BOOL APIENTRY DllMain(HMODULE hModule,
MH_UNHOOK(pfnKernelSleep);
MH_UNHOOK(pfnKernelSetTimer);
MH_UNHOOK(pfnKernelTimeGetTime);
MH_UNHOOK(pfnKernelTimeSetEvent);
MH_UNHOOK(pfnKernelGetTickCount);
MH_UNHOOK(pfnKernelGetTickCount64);
MH_UNHOOK(pfnKernelQueryPerformanceCounter);
Expand Down
Binary file modified translations/OpenSpeedy_en_US.qm
Binary file not shown.
Binary file modified translations/OpenSpeedy_zh_TW.qm
Binary file not shown.