加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
文件
该仓库未声明开源许可证文件(LICENSE),使用请关注具体项目描述及其代码上游依赖。
克隆/下载
d2super_loader.cpp 22.36 KB
一键复制 编辑 原始数据 按行查看 历史
cc Yang 提交于 2021-01-23 16:38 . init
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689

#include <stdio.h>
#include <direct.h>
#include <io.h>
#include <atlconv.h>
#include "d2super_loader_common.h"
//如果需要隐藏DOS窗口的话,就放开下面这句
#pragma comment(linker, "/subsystem:\"windows\" /entry:\"mainCRTStartup\"")
enum VideoMode
{
gdi = 1,
software = 2,
ddraw = 3,
glide = 4,
opengl = 5, //UNUSED
d3d = 6,
rave = 7 //UNUSED
};
enum GameRes
{
res_640x480 = 0,
res_800x600 = 2
};
enum GameMode
{
none = 0x0,
client = 0x1,
server = 0x2,
multiplayer = 0x3,
launcher = 0x4,
expand = 0x5
};
typedef DWORD(__stdcall *type_pfnStormRegLoadString)(const char *keyname, const char *valuename, int a3, char *buffer, size_t buffersize);
typedef DWORD(__stdcall *type_pfnStormRegLoadValue)(const char *keyname, const char *valuename, int a3, int *value);
typedef DWORD(__stdcall *type_pfnStormOpenArchive)(LPCSTR lpFileName, DWORD dwPriority, DWORD dwFlags, HANDLE *hMPQ);
typedef DWORD(__stdcall *type_pfnStormCloseArchive)(HANDLE hMPQ);
typedef int(__fastcall *type_pfnStormSprintf)(void *, DWORD, const char *, ...);
typedef void(__fastcall *type_pfnFogSetLogPrefix)(const char *szPrefix);
typedef void(__fastcall *type_pfnFogSetErrorHandler)(const char *szApp, void *fnCallback, const char *szVersion, BOOL bAddInfo);
typedef void(__fastcall *type_pfnFogSetFileOptions)(BOOL bDirect, BOOL bQuickSeek);
typedef void(__fastcall *type_pfnFogSetAsyncData)(BOOL bState, DWORD dwUnknown);
typedef void(__fastcall *type_pfnFogFreeAsyncData)();
typedef BOOL(__fastcall *type_pfnIsErrorState)();
typedef void(__fastcall *type_pfnFogInit)();
typedef BOOL(__fastcall *type_pfnIsErrorState)();
typedef void(__fastcall *type_pfnErrorRescue)();
typedef void(__stdcall *type_pfnFreePools)(void *pParams);
typedef void(__stdcall *type_pfnSetServerParams)(void *pParams);
typedef BOOL(__fastcall *type_pfnFogIsExpansion)();
typedef BOOL(__stdcall *type_pfnD2WinLoadMPQs)();
typedef BOOL(__fastcall *type_pfnD2WinLoadExpansionMPQs)(int *, int *, BOOL, void *);
typedef void(__stdcall *type_pfnD2WinUnloadMPQs)();
typedef BOOL(__stdcall *type_pfnD2WinInitGfx)(HINSTANCE hInstance, int nDriver, BOOL bWindowed, BOOL bGFXCompress);
typedef BOOL(__stdcall *type_pfnD2WinDeinitGFX)();
typedef BOOL(__stdcall *type_pfnD2WinCreateWindow)(BOOL bWindowed, int ResoulutionMode);
typedef DWORD(__fastcall *type_pfnD2LaunchCall)(void *pvParam);
typedef void *(__stdcall *type_pfnD2GetHwnd)();
typedef void(__stdcall *type_pfnD2GfxRelease)();
typedef DWORD(__stdcall *type_pfnD2LangGetUsedLanguage)();
typedef void(__fastcall *type_pfnD2SoundInit)(BOOL bExpansion, BOOL bSoundBackground);
typedef DWORD(__fastcall *type_pfnD2Common10097)();
typedef void(__fastcall *type_pfnD2Fog10082)();
typedef void(__stdcall *type_pfnD2gfx10068)(DWORD);
typedef void(__stdcall *type_pfnD2gfx10071)(DWORD);
typedef int(__stdcall *type_pfnStorm426)(const char *, const char *, DWORD, DWORD);
static type_pfnStormRegLoadString m_pfnStormRegLoadString;
static type_pfnStormRegLoadValue m_pfnStormRegLoadValue;
static type_pfnStormOpenArchive m_pfnStormOpenArchive;
static type_pfnStormCloseArchive m_pfnStormCloseArchive;
static type_pfnStormSprintf m_pfnStormSprintf;
static type_pfnFogSetLogPrefix m_pfnFogSetLogPrefix;
static type_pfnFogSetErrorHandler m_pfnFogSetErrorHandler;
static type_pfnFogSetFileOptions m_pfnFogSetFileOptions;
static type_pfnFogSetAsyncData m_pfnFogSetAsyncData;
static type_pfnFogInit m_pfnFogInit;
static type_pfnFogIsExpansion m_pfnFogIsExpansion;
static type_pfnIsErrorState m_pfnIsErrorState;
static type_pfnErrorRescue m_pfnErrorRescue;
static type_pfnFogFreeAsyncData m_pfnFogFreeAsyncData;
static type_pfnFreePools m_pfnFreePools;
static type_pfnSetServerParams m_pfnSetServerParams;
static type_pfnD2WinLoadMPQs m_pfnD2WinLoadMPQs;
static type_pfnD2WinLoadExpansionMPQs m_pfnD2WinLoadExpansionMPQs;
static type_pfnD2WinUnloadMPQs m_pfnD2WinUnloadMPQs;
static type_pfnD2WinInitGfx m_pfnD2WinInitGfx;
static type_pfnD2WinDeinitGFX m_pfnD2WinDeinitGFX;
static type_pfnD2WinCreateWindow m_pfnD2WinCreateWindow;
static type_pfnD2GetHwnd m_pfnD2GetHwnd;
static type_pfnD2GfxRelease m_pfnD2GfxRelease;
static type_pfnD2GfxRelease m_pfnD2LangFree;
static type_pfnD2LangGetUsedLanguage m_pfnD2LangGetUsedLanguage;
static type_pfnD2SoundInit m_pfnD2SoundInit;
static type_pfnD2GfxRelease m_pfnD2SoundShutdown;
static type_pfnD2Common10097 m_pfnD2Common10097;
static type_pfnD2Fog10082 m_pfnD2Fog10082;
static type_pfnD2gfx10068 m_pfnD2GfxSetPerspective;
static type_pfnD2Fog10082 m_pfnD2GfxSetLowQuality;
static type_pfnD2Fog10082 m_pfnD2GfxSetGameName;
static type_pfnD2gfx10071 m_pfnD2GfxSetGamma;
static type_pfnD2Fog10082 m_pfnD2GfxFixAspectRatio;
static type_pfnStorm426 m_pfnStormSetResolution;
static type_pfnD2Fog10082 m_pfnD2WinUninit;
static type_pfnD2Fog10082 m_pfnD2MCPClientUninit;
static type_pfnD2Fog10082 m_pfnD2Common10925;
;
typedef struct
{
type_pfnD2LaunchCall pfnLaunch;
DWORD dwUnknown;
} ST_LAUNCH_CALLBACK;
typedef ST_LAUNCH_CALLBACK *(__fastcall *type_pfnD2LaunchGetCb)();
static type_pfnD2LaunchGetCb m_pfnD2LaunchGetCb;
static type_pfnD2LaunchGetCb m_pfnD2ClientGetCb;
static type_pfnD2LaunchGetCb m_pfnD2MultiGetCb;
static const char *m_pcBoxName = "D2Loader";
static int msgBox(LPCSTR boxName, UINT uType, LPCSTR pFormat, ...)
{
char buffer[300];
va_list lArgs;
va_start( lArgs, pFormat );
vsprintf_s( buffer, sizeof(buffer), pFormat, lArgs );
va_end(lArgs);
return MessageBox(NULL, buffer, boxName, uType);
}
static void D2Critical_Callback()
{
MessageBoxA(NULL, "An critical error occured!\nexit!", m_pcBoxName, MB_OK | MB_ICONASTERISK);
//exit(1);
}
static BOOL Proc_new()
{
return D2TRUE;
}
typedef void(__stdcall *type_pfnDllInit)();
static DWORD D2Loader_LoadLibrary(const char *dll)
{
type_pfnDllInit pfnDllInit = NULL;
char acDllName[MAX_PATH] = {0};
const char *pcTemp = strchr(dll, ':');
if (NULL != pcTemp)
{
memcpy(acDllName, dll, (DWORD)(pcTemp - dll));
pcTemp++;
}
else
{
strcpy_s(acDllName, sizeof(acDllName), dll);
}
DWORD module = (DWORD)GetModuleHandle(acDllName);
if (NULL != module)
{
return module;
}
module = (DWORD)LoadLibraryEx(acDllName, NULL, LOAD_LIBRARY_SEARCH_DEFAULT_DIRS);
if (NULL == module)
{
msgBox(m_pcBoxName, MB_OK | MB_ICONASTERISK, "Load %s failed!", acDllName);
exit(1);
}
if (NULL != pcTemp && NULL != (pfnDllInit = (type_pfnDllInit)GetProcAddress((HMODULE)module, pcTemp)))
{
pfnDllInit();
}
return module;
}
static DWORD GetDllOffset2(const char *dll, const char *pcName)
{
HMODULE module = (HMODULE)D2Loader_LoadLibrary(dll);
DWORD locatedAddress = (DWORD)GetProcAddress(module, (LPCSTR)pcName);
return locatedAddress;
}
static DWORD GetDllOffset(const char *dll, int offset)
{
return GetDllOffset2(dll, (LPCSTR)offset);
}
static void LoadAllLibraries()
{
const char *apcLibrary[] = {"Storm.dll","Fog.dll", "D2Sound.dll", "D2Lang.dll", "D2Gfx.dll", "D2Win.dll", "D2Launch.dll"};
for (int i = 0; i < sizeof(apcLibrary) / sizeof(apcLibrary[0]); i++)
{
D2Loader_LoadLibrary(apcLibrary[i]);
}
}
static BOOL D2Loader_InitFuncPtr()
{
m_pfnStormRegLoadString = (type_pfnStormRegLoadString)GetDllOffset("Storm.dll", 422);
m_pfnStormSprintf = (type_pfnStormSprintf)GetDllOffset("Storm.dll", 578);
m_pfnFogSetLogPrefix = (type_pfnFogSetLogPrefix)GetDllOffset("Fog.dll", 10021);
m_pfnFogSetErrorHandler = (type_pfnFogSetErrorHandler)GetDllOffset("Fog.dll", 10019);
m_pfnFogSetFileOptions = (type_pfnFogSetFileOptions)GetDllOffset("Fog.dll", 10101);
m_pfnFogSetAsyncData = (type_pfnFogSetAsyncData)GetDllOffset("Fog.dll", 10089);
m_pfnFogInit = (type_pfnFogInit)GetDllOffset("Fog.dll", 10218);
m_pfnD2WinLoadMPQs = (type_pfnD2WinLoadMPQs)GetDllOffset("D2Win.dll", 10174);
m_pfnD2WinLoadExpansionMPQs = (type_pfnD2WinLoadExpansionMPQs)GetDllOffset("D2Win.dll", 10072);
m_pfnFogIsExpansion = (type_pfnFogIsExpansion)GetDllOffset("Fog.dll", 10227);
m_pfnD2WinInitGfx = (type_pfnD2WinInitGfx)GetDllOffset("D2Win.dll", 10071);
m_pfnD2WinCreateWindow = (type_pfnD2WinCreateWindow)GetDllOffset("D2Win.dll", 10129);
m_pfnD2SoundInit = (type_pfnD2SoundInit)GetDllOffset("D2Sound.dll", 10023);
m_pfnD2SoundShutdown = (type_pfnD2GfxRelease)GetDllOffset("D2Sound.dll", 10024);
m_pfnD2WinDeinitGFX = (type_pfnD2WinDeinitGFX)GetDllOffset("D2Win.dll", 10132);
m_pfnD2GfxRelease = (type_pfnD2GfxRelease)GetDllOffset("D2Gfx.dll", 10050);
m_pfnD2WinUnloadMPQs = (type_pfnD2WinUnloadMPQs)GetDllOffset("D2Win.dll", 10079);
m_pfnD2GetHwnd = (type_pfnD2GetHwnd)GetDllOffset("D2Gfx.dll", 10007);
m_pfnD2LangFree = (type_pfnD2GfxRelease)GetDllOffset("D2Lang.dll", 10000);
m_pfnStormRegLoadValue = (type_pfnStormRegLoadValue)GetDllOffset("Storm.dll", 423);
m_pfnStormOpenArchive = (type_pfnStormOpenArchive)GetDllOffset("Storm.dll", 266);
m_pfnStormCloseArchive = (type_pfnStormCloseArchive)GetDllOffset("Storm.dll", 252);
m_pfnIsErrorState = (type_pfnIsErrorState)GetDllOffset("Fog.dll", 10039);
m_pfnErrorRescue = (type_pfnErrorRescue)GetDllOffset("Fog.dll", 10040);
m_pfnFogFreeAsyncData = (type_pfnFogFreeAsyncData)GetDllOffset("Fog.dll", 10090);
m_pfnFreePools = (type_pfnFreePools)GetDllOffset("Fog.dll", 10143);
m_pfnSetServerParams = (type_pfnSetServerParams)GetDllOffset("Fog.dll", 10185);
m_pfnD2Fog10082 = (type_pfnD2Fog10082)GetDllOffset("Fog.dll", 10082);
m_pfnD2Common10097 = (type_pfnD2Common10097)GetDllOffset("D2Common.dll", 10097);
m_pfnD2GfxSetPerspective = (type_pfnD2gfx10068)GetDllOffset("D2Gfx.dll", 10068);
m_pfnD2GfxSetLowQuality = (type_pfnD2Fog10082)GetDllOffset("D2Gfx.dll", 10008);
m_pfnD2GfxSetGameName = (type_pfnD2Fog10082)GetDllOffset("D2Gfx.dll", 10065);
m_pfnD2GfxSetGamma = (type_pfnD2gfx10071)GetDllOffset("D2Gfx.dll", 10071);
m_pfnD2GfxFixAspectRatio = (type_pfnD2Fog10082)GetDllOffset("D2Gfx.dll", 10049);
m_pfnStormSetResolution = (type_pfnStorm426)GetDllOffset("Storm.dll", 426);
m_pfnD2WinUninit = (type_pfnD2Fog10082)GetDllOffset("D2Win.dll", 10058);
m_pfnD2MCPClientUninit = (type_pfnD2Fog10082)GetDllOffset("D2MCPClient.dll", 10006);
m_pfnD2Common10925 = (type_pfnD2Fog10082)GetDllOffset("D2Common.dll", 10925);
return TRUE;
}
#define PATCH_FINISH 0xFFFFFFFF
#define PATCH_JMP 0x000000E9
#define PATCH_CALL 0x000000E8
#define PATCH_RETN 0x000000C3
#define PATCH_RETN4 0x000004C2
#define PATCH_RETN8 0x000008C2
#define PATCH_RETN0C 0x00000CC2
#define PATCH_RETN10 0x000010C2
#define PATCH_RETN14 0x000014C2
#define PATCH_RETN18 0x000018C2
#define PATCH_RETN1C 0x00001CC2
#define PATCH_NOPBLOCK 0x90909090
typedef struct
{
DWORD dwAddress;
DWORD dwData;
BOOL boolRelative;
size_t iPatchSize;
} DLLPatchStrc;
static BOOL D2SE_ApplyPatch(void *hGame, const DWORD dwBaseAddress, const DLLPatchStrc *pstPatch)
{
while (PATCH_FINISH != pstPatch->dwAddress)
{
int iReturn = 0;
DWORD dwAddress = pstPatch->dwAddress;
if (!dwAddress)
{
return FALSE;
}
dwAddress += dwBaseAddress;
DWORD dwData = pstPatch->dwData;
if (pstPatch->boolRelative)
{
dwData = dwData - (dwAddress + sizeof(dwData));
}
void *hAddress = (void *)dwAddress;
DWORD dwOldPage;
if (pstPatch->iPatchSize > 0)
{
BYTE abBuffer[1024];
for (size_t i = 0; i < pstPatch->iPatchSize; i++)
{
abBuffer[i] = (BYTE)dwData;
}
VirtualProtect(hAddress, pstPatch->iPatchSize, PAGE_EXECUTE_READWRITE, &dwOldPage);
iReturn = WriteProcessMemory(hGame, hAddress, &abBuffer, pstPatch->iPatchSize, 0);
VirtualProtect(hAddress, pstPatch->iPatchSize, dwOldPage, 0);
}
else
{
VirtualProtect(hAddress, sizeof(dwData), PAGE_EXECUTE_READWRITE, &dwOldPage);
iReturn = WriteProcessMemory(hGame, hAddress, &dwData, sizeof(dwData), 0);
VirtualProtect(hAddress, sizeof(dwData), dwOldPage, 0);
}
if (0 == iReturn)
{
return FALSE;
}
pstPatch++;
}
return TRUE;
}
static char m_acGlobalMpqPath[MAX_PATH]="";
static DWORD WINAPI D2Loader_GetMpqPath(HMODULE hModule, LPTSTR lpFilename, DWORD nSize)
{
char acTempPath[MAX_PATH] = {0};
char acTempPath2[MAX_PATH] = {0};
DWORD dwResult;
char *pcTemp;
dwResult = GetModuleFileName(hModule, acTempPath, sizeof(acTempPath));
if (0 == dwResult || 0 == acTempPath[0])
{
return 0;
}
pcTemp = strrchr(acTempPath, '\\');
if (!pcTemp)
{
strcpy_s(lpFilename, nSize, acTempPath);
return dwResult;
}
memcpy(acTempPath2, acTempPath, (DWORD)(pcTemp - acTempPath));
sprintf_s(&acTempPath2[strlen(acTempPath2)], sizeof(acTempPath2) - strlen(acTempPath2), "\\%s", lpFilename);
if (_access(acTempPath2, 0) == 0)
{
strcpy_s(lpFilename, nSize, acTempPath);
return dwResult;
}
memset(acTempPath2, 0, sizeof(acTempPath2));
strcpy_s(acTempPath2, sizeof(acTempPath2), m_acGlobalMpqPath);
while ('\\' == acTempPath2[strlen(acTempPath2) - 1])
{
acTempPath2[strlen(acTempPath2) - 1] = 0;
}
sprintf_s(&acTempPath2[strlen(acTempPath2)], sizeof(acTempPath2) - strlen(acTempPath2), "\\%s", lpFilename);
strcpy_s(lpFilename, nSize, acTempPath2);
return strlen(lpFilename);
}
static DWORD WINAPI D2Loader_GetMpqPathExp(LPCTSTR lpFileName)
{
char acTempPath[MAX_PATH] = {0};
if (!strstr(lpFileName, "d2exp.mpq"))
{
return GetFileAttributes(lpFileName);
}
strcpy_s(acTempPath, sizeof(acTempPath), m_acGlobalMpqPath);
while ('\\' == acTempPath[strlen(acTempPath) - 1])
{
acTempPath[strlen(acTempPath) - 1] = 0;
}
sprintf_s(&acTempPath[strlen(acTempPath)], sizeof(acTempPath) - strlen(acTempPath), "\\%s", "d2exp.mpq");
if (_access(acTempPath, 0) == 0)
{
return GetFileAttributes(acTempPath);
}
return GetFileAttributes(lpFileName);
}
static DWORD WINAPI D2Loader_GetMpqPathChar(LPCTSTR lpFileName)
{
char acTempPath[MAX_PATH] = {0};
if (!strstr(lpFileName, "d2char.mpq"))
{
return GetFileAttributes(lpFileName);
}
strcpy_s(acTempPath, sizeof(acTempPath), m_acGlobalMpqPath);
while ('\\' == acTempPath[strlen(acTempPath) - 1])
{
acTempPath[strlen(acTempPath) - 1] = 0;
}
sprintf_s(&acTempPath[strlen(acTempPath)], sizeof(acTempPath) - strlen(acTempPath), "\\%s", "d2exp.mpq");
if (_access(acTempPath, 0) == 0)
{
return GetFileAttributes(acTempPath);
}
return GetFileAttributes(lpFileName);
}
static void D2Loader_PatchMpqPath()
{
if (0 == m_acGlobalMpqPath[0])
{
return;
}
static const DLLPatchStrc astPatches[] =
{
//更新获取mpq的文件路径
{0x7DF6, PATCH_CALL, FALSE, 0x01}, //call
{0x7DF7, (DWORD)D2Loader_GetMpqPath, TRUE, 0x00},
{0x7DFB, PATCH_NOPBLOCK, FALSE, 0x01},
{PATCH_FINISH} // this must be the last entry in the array!
};
static const DLLPatchStrc astPatches2[] =
{
//判断是否资料片,d2exp.mpq,否则会判断为非资料片版本
{0x1FB20, (DWORD)0xBE, FALSE, 0x01},
{0x1FB21, (DWORD)D2Loader_GetMpqPathExp, FALSE, 0x00},
{0x1FB25, PATCH_NOPBLOCK, FALSE, 0x01},
{PATCH_FINISH} // this must be the last entry in the array!
};
static const DLLPatchStrc astPatches3[] =
{
//判断是否资料片,d2char.mpq,否则会无法开启TCP/IP多人游戏,只能单机
{0xCCB9, (DWORD)0xBE, FALSE, 0x01},
{0xCCBA, (DWORD)D2Loader_GetMpqPathChar, FALSE, 0x00},
{0xCCBE, PATCH_NOPBLOCK, FALSE, 0x01},
{PATCH_FINISH} // this must be the last entry in the array!
};
D2SE_ApplyPatch(GetCurrentProcess(), (DWORD)GetModuleHandle("D2Win.dll"), astPatches);
D2SE_ApplyPatch(GetCurrentProcess(), (DWORD)GetModuleHandle("Fog.dll"), astPatches2);
D2SE_ApplyPatch(GetCurrentProcess(), (DWORD)GetModuleHandle("D2Win.dll"), astPatches3);
}
int main(int argc, char **argv)
{
static ST_CLIENT_DATA stClientData;
static ST_CLIENT_DATA_EX stClientData_ex;
char acBuffer[MAX_PATH] = {0};
ST_LAUNCH_CALLBACK *pstCallBack = NULL;
DWORD dwGameMode = launcher;
DWORD dwVideoMode;
int iFixedAspectRatio;
BOOL boolInitGfx = FALSE, boolInitSound = FALSE, boolLoadMpqs = FALSE;
HANDLE hLanguageMPQ = NULL;
DWORD i;
HANDLE ahExtendMPQ[MAX_EXTEND_MPQ] = {NULL};
HANDLE event = OpenEventA(2, D2TRUE, "DIABLO_II_OK");
CoInitialize(0);
if (event)
{
SetEvent(event);
CloseHandle(event);
}
set_default_command(&stClientData, &stClientData_ex);
parse_command(argc, argv, &stClientData, &stClientData_ex,m_acGlobalMpqPath);
if(stClientData_ex.m_supermod_path[0])
{
_chdir(stClientData_ex.m_supermod_path);
}
//加载dll
LoadAllLibraries();
//relocate ptrs
if (TRUE != D2Loader_InitFuncPtr())
{
return 0;
}
D2Loader_PatchMpqPath();
stClientData.mpq_callback = Proc_new;
if (stClientData.glide_mode)
{
dwVideoMode = glide;
}
else if (stClientData.window_mode)
{
dwVideoMode = gdi;
}
else
{
dwVideoMode = (stClientData.d3d_mode ? d3d : ddraw);
}
memset(acBuffer, 0, sizeof(acBuffer));
if (0 >= m_pfnStormSprintf(acBuffer, sizeof(acBuffer) / sizeof(acBuffer[0]), "v%d.%02d", 1, 13))
{
msgBox(m_pcBoxName, MB_OK | MB_ICONEXCLAMATION, "Call Storm.Sprintf failed!");
goto out;
}
m_pfnFogSetLogPrefix("D2");
m_pfnFogSetErrorHandler(stClientData_ex.m_acGameTitle, D2Critical_Callback, acBuffer, D2TRUE);
if (NULL != m_pfnD2Common10097)
{
m_pfnD2Common10097();
}
m_pfnFogSetFileOptions(stClientData.direct, D2FALSE);
m_pfnFogSetAsyncData(D2TRUE, D2FALSE);
m_pfnD2Fog10082();
m_pfnFogInit();
boolInitGfx = TRUE;
printf("Loading MPQs...\r\n");
if (!m_pfnD2WinLoadMPQs())
{
msgBox(m_pcBoxName, MB_OK | MB_ICONEXCLAMATION, "Load MPQs failed!");
goto out;
}
boolLoadMpqs = TRUE;
if (!m_pfnD2WinLoadExpansionMPQs(NULL, NULL, 0, &stClientData))
{
msgBox(m_pcBoxName, MB_OK | MB_ICONEXCLAMATION, "Load Expansion MPQs failed!");
goto out;
}
stClientData.expansion = m_pfnFogIsExpansion();
if (0 != stClientData_ex.m_acLanguageMpq[0] && !m_pfnStormOpenArchive(stClientData_ex.m_acLanguageMpq, 0x1B58, 2, &hLanguageMPQ))
{
msgBox(m_pcBoxName, MB_OK | MB_ICONEXCLAMATION, "Load Language MPQ failed!");
goto out;
}
for (i = 0; i < stClientData_ex.m_dwExtendMpq; ++i)
{
if (!m_pfnStormOpenArchive(stClientData_ex.m_aacExtendMpq[i], 0x1B58, 2, &ahExtendMPQ[i]))
{
msgBox(m_pcBoxName, MB_OK | MB_ICONEXCLAMATION, "Load MPQ %s failed!", stClientData_ex.m_aacExtendMpq[i]);
goto out;
}
}
printf("Initing GFX...\r\n");
if (!m_pfnD2WinInitGfx(GetModuleHandle(NULL), dwVideoMode, stClientData.window_mode, !stClientData.no_gfx_compress))
{
msgBox(m_pcBoxName, MB_OK | MB_ICONEXCLAMATION, "Init GFX failed!");
goto out;
}
if (stClientData.perspective && dwVideoMode >= glide)
{
m_pfnD2GfxSetPerspective(D2TRUE);
}
printf("Creating a window...\r\n");
if (!m_pfnD2WinCreateWindow(stClientData.window_mode, res_800x600))
{
msgBox(m_pcBoxName, MB_OK | MB_ICONEXCLAMATION, "Create window failed!");
goto out;
}
if (stClientData.low_quality)
{
m_pfnD2GfxSetLowQuality();
}
if (stClientData.gamma)
{
m_pfnD2GfxSetGamma(stClientData.gamma);
}
if (0 != stClientData.game_name[0])
{
m_pfnD2GfxSetGameName();
}
iFixedAspectRatio = 1;
m_pfnStormRegLoadValue("Diablo II", "Fixed Aspect Ratio", 0, &iFixedAspectRatio);
if (stClientData.fix_aspect_ratio || iFixedAspectRatio != 1)
{
m_pfnD2GfxFixAspectRatio();
}
if (!stClientData.expansion)
{
m_pfnStormSetResolution("Diablo II", "Resolution", 0, 0);
}
if (!stClientData.no_sound)
{
printf("Initing sound system...\r\n");
m_pfnD2SoundInit(stClientData.expansion, D2FALSE);
boolInitSound = TRUE;
}
for (i = 0; i < stClientData_ex.m_dwExtendPlugin; ++i)
{
D2Loader_LoadLibrary(stClientData_ex.m_aacExtendPlugin[i]);
}
m_pfnD2LaunchGetCb = (type_pfnD2LaunchGetCb)GetDllOffset2("D2Launch.dll", "QueryInterface");
m_pfnD2ClientGetCb = (type_pfnD2LaunchGetCb)GetDllOffset2("D2Client.dll", "QueryInterface");
m_pfnD2MultiGetCb = (type_pfnD2LaunchGetCb)GetDllOffset2("D2Multi.dll", "QueryInterface");
while (TRUE)
{
printf("Entering the game mode: %d\r\n", dwGameMode);
switch (dwGameMode)
{
case launcher:
pstCallBack = m_pfnD2LaunchGetCb();
break;
case client:
pstCallBack = m_pfnD2ClientGetCb();
break;
case multiplayer:
pstCallBack = m_pfnD2MultiGetCb();
break;
default:
pstCallBack = NULL;
break;
}
if (NULL == pstCallBack)
{
break;
}
dwGameMode = pstCallBack->pfnLaunch(&stClientData);
}
out:
if (!stClientData.no_sound && boolInitSound)
{
printf("Shutting down the sound system...\r\n");
m_pfnD2SoundShutdown();
}
if (boolInitGfx)
{
printf("Shutting down the GFX...\r\n");
m_pfnD2WinDeinitGFX();
m_pfnD2GfxRelease();
}
m_pfnD2WinUninit();
m_pfnFogFreeAsyncData();
m_pfnD2MCPClientUninit();
if (NULL != m_pfnD2Common10925)
{
m_pfnD2Common10925();
}
m_pfnFreePools(NULL);
if (hLanguageMPQ)
{
m_pfnStormCloseArchive(hLanguageMPQ);
}
for (i = 0; i < stClientData_ex.m_dwExtendMpq; ++i)
{
if (ahExtendMPQ[i])
{
m_pfnStormCloseArchive(ahExtendMPQ[i]);
}
}
if (boolLoadMpqs)
{
printf("Unloading the MPQs...\r\n");
m_pfnD2WinUnloadMPQs();
}
printf("quit game!\r\n");
CoUninitialize();
return 0;
}
Loading...
马建仓 AI 助手
尝试更多
代码解读
代码找茬
代码优化