mirror of
https://gitlab.com/Syroot/Worms.git
synced 2025-05-05 11:19:29 +03:00
Use original logic if there's no fallback and / or webservice failed.
This commit is contained in:
parent
f242a6b745
commit
48e6988083
@ -65,7 +65,7 @@
|
|||||||
<SubSystem>Windows</SubSystem>
|
<SubSystem>Windows</SubSystem>
|
||||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||||
<EnableUAC>false</EnableUAC>
|
<EnableUAC>false</EnableUAC>
|
||||||
<AdditionalDependencies>wininet.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
<AdditionalDependencies>wininet.lib;ws2_32.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||||
</Link>
|
</Link>
|
||||||
</ItemDefinitionGroup>
|
</ItemDefinitionGroup>
|
||||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||||
@ -83,20 +83,18 @@
|
|||||||
<OptimizeReferences>true</OptimizeReferences>
|
<OptimizeReferences>true</OptimizeReferences>
|
||||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||||
<EnableUAC>false</EnableUAC>
|
<EnableUAC>false</EnableUAC>
|
||||||
<AdditionalDependencies>wininet.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
<AdditionalDependencies>wininet.lib;ws2_32.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||||
</Link>
|
</Link>
|
||||||
</ItemDefinitionGroup>
|
</ItemDefinitionGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ClCompile Include="fkConfig.cpp" />
|
<ClCompile Include="fkConfig.cpp" />
|
||||||
<ClCompile Include="fkPatch.cpp" />
|
<ClCompile Include="fkPatch.cpp" />
|
||||||
<ClCompile Include="fkUtils.cpp" />
|
<ClCompile Include="fkUtils.cpp" />
|
||||||
<ClCompile Include="fkWinHandle.cpp" />
|
|
||||||
<ClCompile Include="main.cpp" />
|
<ClCompile Include="main.cpp" />
|
||||||
<ClCompile Include="PEInfo.cpp" />
|
<ClCompile Include="PEInfo.cpp" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ClInclude Include="fkConfig.h" />
|
<ClInclude Include="fkConfig.h" />
|
||||||
<ClInclude Include="fkWinHandle.h" />
|
|
||||||
<ClInclude Include="fkPatch.h" />
|
<ClInclude Include="fkPatch.h" />
|
||||||
<ClInclude Include="fkUtils.h" />
|
<ClInclude Include="fkUtils.h" />
|
||||||
<ClInclude Include="PEInfo.h" />
|
<ClInclude Include="PEInfo.h" />
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
#include "fkUtils.h"
|
#include "fkUtils.h"
|
||||||
|
#include <string>
|
||||||
#include "fkPatch.h"
|
#include "fkPatch.h"
|
||||||
|
|
||||||
namespace fk
|
namespace fk
|
||||||
@ -17,11 +18,10 @@ namespace fk
|
|||||||
return GAME_VERSION_NONE;
|
return GAME_VERSION_NONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
void throwLastError()
|
std::string getErrorMessage(int error)
|
||||||
{
|
{
|
||||||
DWORD error = GetLastError();
|
|
||||||
if (error == ERROR_SUCCESS)
|
if (error == ERROR_SUCCESS)
|
||||||
return;
|
return std::string();
|
||||||
|
|
||||||
LPTSTR buffer = NULL;
|
LPTSTR buffer = NULL;
|
||||||
const DWORD cchMsg = FormatMessageA(
|
const DWORD cchMsg = FormatMessageA(
|
||||||
@ -31,13 +31,13 @@ namespace fk
|
|||||||
{
|
{
|
||||||
std::string message(buffer);
|
std::string message(buffer);
|
||||||
LocalFree(buffer);
|
LocalFree(buffer);
|
||||||
throw std::exception(message.c_str());
|
return message;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
CHAR buffer[32];
|
CHAR buffer[32];
|
||||||
sprintf_s(buffer, "Error code 0x%08X.", error);
|
sprintf_s(buffer, "Error code 0x%08X.", error);
|
||||||
throw std::exception(buffer);
|
return buffer;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -25,7 +25,7 @@ namespace fk
|
|||||||
};
|
};
|
||||||
|
|
||||||
int getGameVersion(DWORD timeDateStamp);
|
int getGameVersion(DWORD timeDateStamp);
|
||||||
void throwLastError();
|
std::string getErrorMessage(int error);
|
||||||
|
|
||||||
void patchNops(ULONG dwAddr, SIZE_T dwPatchSize);
|
void patchNops(ULONG dwAddr, SIZE_T dwPatchSize);
|
||||||
void patchJump(PVOID pDest, SIZE_T dwPatchSize, PVOID pCallee, DWORD dwJumpType = IJ_JUMP);
|
void patchJump(PVOID pDest, SIZE_T dwPatchSize, PVOID pCallee, DWORD dwJumpType = IJ_JUMP);
|
||||||
|
@ -1,20 +0,0 @@
|
|||||||
#include "fkWinHandle.h"
|
|
||||||
#include "fkUtils.h"
|
|
||||||
#include <stdexcept>
|
|
||||||
|
|
||||||
namespace fk
|
|
||||||
{
|
|
||||||
WinHandle::WinHandle(HANDLE handle, BOOL(__stdcall* closeProc)(HANDLE))
|
|
||||||
: _handle(handle)
|
|
||||||
, _closeProc(closeProc)
|
|
||||||
{
|
|
||||||
if (!_handle || _handle == INVALID_HANDLE_VALUE)
|
|
||||||
fk::throwLastError();
|
|
||||||
}
|
|
||||||
|
|
||||||
WinHandle::~WinHandle()
|
|
||||||
{
|
|
||||||
if (_handle)
|
|
||||||
_closeProc(_handle);
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,19 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
#include <Windows.h>
|
|
||||||
|
|
||||||
namespace fk
|
|
||||||
{
|
|
||||||
struct WinHandle
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
WinHandle(HANDLE handle, BOOL(__stdcall* closeProc)(HANDLE));
|
|
||||||
~WinHandle();
|
|
||||||
|
|
||||||
operator bool() { return _handle; }
|
|
||||||
operator HANDLE() { return _handle; }
|
|
||||||
|
|
||||||
private:
|
|
||||||
HANDLE _handle;
|
|
||||||
BOOL(__stdcall* _closeProc)(HANDLE);
|
|
||||||
};
|
|
||||||
}
|
|
@ -1,16 +1,16 @@
|
|||||||
#define WIN32_LEAN_AND_MEAN
|
#define WIN32_LEAN_AND_MEAN
|
||||||
#include <Windows.h>
|
#include <Windows.h>
|
||||||
#include <WinInet.h>
|
#include <WinInet.h>
|
||||||
|
#include <winsock.h>
|
||||||
#include "fkConfig.h"
|
#include "fkConfig.h"
|
||||||
#include "fkUtils.h"
|
#include "fkUtils.h"
|
||||||
#include "fkWinHandle.h"
|
|
||||||
#include "PEInfo.h"
|
#include "PEInfo.h"
|
||||||
|
|
||||||
|
// ---- Configuration ----
|
||||||
|
|
||||||
CHAR cfgFallbackIP[16];
|
CHAR cfgFallbackIP[16];
|
||||||
CHAR cfgServiceUrl[MAX_PATH];
|
CHAR cfgServiceUrl[MAX_PATH];
|
||||||
BOOL cfgShowErrors;
|
BOOL cfgShowErrors;
|
||||||
PEInfo pe;
|
|
||||||
CHAR resolvedIP[16] = {};
|
|
||||||
|
|
||||||
void configure()
|
void configure()
|
||||||
{
|
{
|
||||||
@ -35,52 +35,105 @@ void configure()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void resolveIP(LPTSTR buffer)
|
// ---- Patch: IP Resolval ----
|
||||||
|
|
||||||
|
CHAR cachedIP[16] = {};
|
||||||
|
|
||||||
|
bool resolveIPCached(LPSTR buffer)
|
||||||
{
|
{
|
||||||
if (!*resolvedIP)
|
if (!*cachedIP)
|
||||||
|
return false;
|
||||||
|
lstrcpy(buffer, cachedIP);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool resolveIPExternal(LPSTR buffer)
|
||||||
|
{
|
||||||
|
if (!*cfgServiceUrl)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
// Query a web service which replies with the IP in plain text.
|
||||||
|
HINTERNET hInternet = 0, hFile = 0;
|
||||||
|
if (hInternet = InternetOpen(NULL, INTERNET_OPEN_TYPE_DIRECT, NULL, NULL, 0))
|
||||||
{
|
{
|
||||||
// Initially resolve the external IP through a web service.
|
if (hFile = InternetOpenUrl(hInternet, cfgServiceUrl, NULL, 0,
|
||||||
fk::WinHandle hInternet(InternetOpen(NULL, INTERNET_OPEN_TYPE_DIRECT, NULL, NULL, 0), InternetCloseHandle);
|
INTERNET_FLAG_NO_COOKIES | INTERNET_FLAG_NO_CACHE_WRITE | INTERNET_FLAG_RELOAD, NULL))
|
||||||
fk::WinHandle hFile(InternetOpenUrl(hInternet, cfgServiceUrl, NULL, 0,
|
{
|
||||||
INTERNET_FLAG_NO_COOKIES | INTERNET_FLAG_NO_CACHE_WRITE | INTERNET_FLAG_RELOAD, NULL), InternetCloseHandle);
|
DWORD responseLength = 0;
|
||||||
|
CHAR response[16];
|
||||||
DWORD responseLength = 0;
|
if (InternetReadFile(hFile, response, 16, &responseLength))
|
||||||
CHAR response[16];
|
{
|
||||||
if (!InternetReadFile(hFile, response, 16, &responseLength))
|
if (responseLength >= 8)
|
||||||
fk::throwLastError();
|
{
|
||||||
if (responseLength < 8)
|
response[responseLength] = '\0';
|
||||||
throw std::exception("Response was too short.");
|
BYTE temp;
|
||||||
|
if (sscanf_s(response, "%hhu.%hhu.%hhu.%hhu", &temp, &temp, &temp, &temp) == 4)
|
||||||
response[responseLength] = '\0';
|
lstrcpy(buffer, response);
|
||||||
BYTE temp;
|
else
|
||||||
if (sscanf_s(response, "%hhu.%hhu.%hhu.%hhu", &temp, &temp, &temp, &temp) != 4)
|
SetLastError(0x20000002);
|
||||||
throw std::exception("Response could not be parsed.");
|
}
|
||||||
|
else
|
||||||
lstrcpy(resolvedIP, response);
|
{
|
||||||
|
SetLastError(0x20000001);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
lstrcpy(buffer, resolvedIP);
|
|
||||||
|
DWORD error = GetLastError();
|
||||||
|
if (hFile) InternetCloseHandle(hFile);
|
||||||
|
if (hInternet) InternetCloseHandle(hInternet);
|
||||||
|
if (error && cfgShowErrors)
|
||||||
|
{
|
||||||
|
CHAR msg[512];
|
||||||
|
sprintf_s(msg, "Could not resolve your IP through the web service. %s", fk::getErrorMessage(error).c_str());
|
||||||
|
MessageBox(NULL, msg, "fkNetcode", MB_ICONWARNING);
|
||||||
|
}
|
||||||
|
return !error;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool resolveIPFallback(LPSTR buffer)
|
||||||
|
{
|
||||||
|
if (!*cfgFallbackIP)
|
||||||
|
return false;
|
||||||
|
lstrcpy(buffer, cfgFallbackIP);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool resolveIPOriginal(LPSTR buffer)
|
||||||
|
{
|
||||||
|
// Use the original logic to "resolve" the (NAT) IP.
|
||||||
|
CHAR hostName[200];
|
||||||
|
hostent* host;
|
||||||
|
if (gethostname(hostName, 200) || !(host = gethostbyname(hostName)))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
sprintf_s(hostName, "%hhu.%hhu.%hhu.%hhu",
|
||||||
|
host->h_addr_list[0][0],
|
||||||
|
host->h_addr_list[0][1],
|
||||||
|
host->h_addr_list[0][2],
|
||||||
|
host->h_addr_list[0][3]);
|
||||||
|
lstrcpy(buffer, hostName);
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool __stdcall patchResolveIP(LPSTR buffer, int bufferLength)
|
bool __stdcall patchResolveIP(LPSTR buffer, int bufferLength)
|
||||||
{
|
{
|
||||||
try
|
// Return value not used by W2, but meant to be 0 if no error.
|
||||||
|
if (resolveIPCached(buffer) || resolveIPExternal(buffer) || resolveIPFallback(buffer) || resolveIPOriginal(buffer))
|
||||||
{
|
{
|
||||||
resolveIP(buffer);
|
lstrcpy(cachedIP, buffer);
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
catch (std::exception& ex)
|
else
|
||||||
{
|
{
|
||||||
lstrcpy(buffer, *cfgFallbackIP ? cfgFallbackIP : "0.0.0.0");
|
return true;
|
||||||
if (cfgShowErrors)
|
|
||||||
{
|
|
||||||
CHAR message[512];
|
|
||||||
sprintf_s(message, "Could not resolve your IP address. %s", ex.what());
|
|
||||||
MessageBox(NULL, message, "fkNetcode", MB_ICONWARNING);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return true; // not used
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void patch(int gameVersion)
|
// ---- Patch ----
|
||||||
|
|
||||||
|
void patch(PEInfo& pe, int gameVersion)
|
||||||
{
|
{
|
||||||
fk::patchJump((PVOID)pe.Offset(0x00001799), 5, &patchResolveIP, fk::IJ_JUMP); // replace IP resolve with web service
|
fk::patchJump((PVOID)pe.Offset(0x00001799), 5, &patchResolveIP, fk::IJ_JUMP); // replace IP resolve with web service
|
||||||
|
|
||||||
@ -98,12 +151,15 @@ void patch(int gameVersion)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ---- Main ----
|
||||||
|
|
||||||
BOOL WINAPI DllMain(HMODULE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
|
BOOL WINAPI DllMain(HMODULE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
|
||||||
{
|
{
|
||||||
switch (fdwReason)
|
switch (fdwReason)
|
||||||
{
|
{
|
||||||
case DLL_PROCESS_ATTACH:
|
case DLL_PROCESS_ATTACH:
|
||||||
{
|
{
|
||||||
|
PEInfo pe;
|
||||||
int version = fk::getGameVersion(pe.FH->TimeDateStamp);
|
int version = fk::getGameVersion(pe.FH->TimeDateStamp);
|
||||||
if (version == fk::GAME_VERSION_NONE)
|
if (version == fk::GAME_VERSION_NONE)
|
||||||
{
|
{
|
||||||
@ -114,7 +170,7 @@ BOOL WINAPI DllMain(HMODULE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
configure();
|
configure();
|
||||||
patch(version);
|
patch(pe, version);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user