/* In the spirit of Call of Duty preservation, this source is being provided to help others in cracking Call of Duty builds. Only about a week was spent figuring this out with the initial focus being for Campaign and Zombies builds as they're both enjoyable without LAN, but seeing the community's broader ambitions, this code is being released rather than gatekept, and hope others will follow suit to hopefully help create an open-source, drama-free community for all recent IW-based CODs. This is a very basic demonstration, but shows how easy offline is to achieve in these Call of Duty titles. The provided offsets are for the latest battle net build of Call of Duty Vanguard, but the same functions and concepts apply across other recent IW-based COD titles, with only minor differences. Everything provided is tailored for battle net authentication; authentication methods for other platforms may vary. For builds with arxan integrity checks, recommend referring to this github repo: https://github.com/mallgrab/CWHook Hooking utils were taken from this github repo: https://github.com/auroramod/h1-mod/tree/develop/src/common/utils It was also very saddening to learn some ego-driven narcissists were lashing out over our previous releases, praying they can get the help they require. Enjoy! */ struct lua_State { }; enum StatsSource : __int8 { STATS_ONLINE = 0x0, STATS_OFFLINE = 0x1, STATS_COUNT = 0x2, }; struct CoDUserData { int signinState; char gamertag[36]; int gamertagSuffix; int hashOfGamertag; char platformGamertag[64]; char fullGamertag[36]; uint64_t xuid; char xuidString[21]; uint64_t platformId; char platformIdString[21]; }; CoDUserData* GetUserData(int controllerIndex) { return reinterpret_cast(0x277B8D0_b)(controllerIndex); } void GamerProfile_LogInProfile(int controller) { reinterpret_cast(0x3DA1780_b)(controller); } void LoadSavedAchievements() { reinterpret_cast(0x2133940_b)(); } void lua_pushboolean(lua_State* luaVM, int b) { reinterpret_cast(0x7473710_b)(luaVM, b); } void LiveStorage_StatsInit(const int controllerIndex, bool clear, bool freshStart, StatsSource statsSource) { reinterpret_cast(0x2A0D0D0_b)(controllerIndex, clear, freshStart, statsSource); } int Lua_ReturnTrue(lua_State* luaVM) { lua_pushboolean(luaVM, 1); return 1; } bool AlwaysTrue() { return true; } void PlatformPatches() { uintptr_t platformData = 0x9AD1DD8_b; utils::hook::set(platformData, 2); utils::hook::set(platformData + 0x2D0, true); /* these two patches are optional, but prevent battle net connectivity issues if previous account info is stored, alternatively, clearing the registry keys on game startup using winreg functions is also an option Computer\HKEY_CURRENT_USER\SOFTWARE\Blizzard Entertainment\Battle.net\Launch Options\FORE */ utils::hook::nop(0x4129A7E_b, 5); utils::hook::nop(0x41298D5_b, 5); // allow playing without internet connected utils::hook::jump(0x412B400_b, AlwaysTrue); } void ProfilePatches() { /* XUID and XUID string must be set to enter matches, otherwise you'll be kicked when entering a match for providing a bad userinfo string */ uint64_t xuidValue = 0x12345678; const char* xuid_string = va("%Iu", xuidValue); CoDUserData* profile = GetUserData(0); profile->signinState = 2; const char* username = "Player"; strncpy_s(profile->gamertag, sizeof(profile->gamertag), username, _TRUNCATE); strncpy_s(profile->platformGamertag, sizeof(profile->platformGamertag), username, _TRUNCATE); strncpy_s(profile->fullGamertag, sizeof(profile->fullGamertag), username, _TRUNCATE); // since this is local only, theres no need for this to be unique profile->xuid = xuidValue; strncpy_s(profile->xuidString, xuid_string, sizeof(profile->xuidString)); // should always be the same as this is used for loading settings in 'Documents/GAME/players' profile->platformId = xuidValue; strncpy_s(profile->platformIdString, xuid_string, sizeof(profile->platformIdString)); // initializes gamerprofile settings and SP DDL GamerProfile_LogInProfile(0); LoadSavedAchievements(); } // apply near game start void LaunchPatches() { // IsPremiumPlayer utils::hook::jump(0x6795230_b, Lua_ReturnTrue); // OfflineDataFetched utils::hook::jump(0x72FDE00_b, Lua_ReturnTrue); // 2C8B174B6BF663C4 utils::hook::jump(0x6795FE0_b, Lua_ReturnTrue); /* force the force_offline_menus dvar to register as true, alternatively can either patch "ui/utils/bootutils.lua" to enable the "Go Offline" button, or use LUI_OpenMenu function to open "MainMenuOffline" */ memcpy((void*)0x2A7C246_b, "\xB2\x01", 2); // patch Live_IsInSystemlinkLobby (needed for maps to load/start) memcpy((void*)0x38BC6A0_b, "\xB0\x01", 2); } // best to call after platform initialization void GeneralPatches() { PlatformPatches(); ProfilePatches(); // online stats utils::hook::set(0x107693D8_b, 1); // offline stats utils::hook::set(0x107693D8_b + 0x2585C, 1); // init stats LiveStorage_StatsInit(0, 1, 0, STATS_ONLINE); // fix sp launch utils::hook::set(0x11BA1894_b, 0); }