[Maps] Download missing map on map rotation
This commit is contained in:
parent
9cc8da0786
commit
0a00ceef9e
@ -549,6 +549,12 @@ namespace Components
|
|||||||
Game::DB_LoadXAssets(&info, 1, true);
|
Game::DB_LoadXAssets(&info, 1, true);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
Command::Add("awaitDatabase", [](Command::Params*)
|
||||||
|
{
|
||||||
|
Logger::Print("Waiting for database...\n");
|
||||||
|
while (!Game::Sys_IsDatabaseReady()) std::this_thread::sleep_for(100ms);
|
||||||
|
});
|
||||||
|
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
// ZoneBuilder debugging
|
// ZoneBuilder debugging
|
||||||
Utils::IO::WriteFile("userraw/logs/iw4_reads.log", "", false);
|
Utils::IO::WriteFile("userraw/logs/iw4_reads.log", "", false);
|
||||||
@ -558,7 +564,7 @@ namespace Components
|
|||||||
FastFiles::StreamRead = true;
|
FastFiles::StreamRead = true;
|
||||||
Utils::Hook::Call<void(bool)>(0x4B8DB0)(true); // currently set to Load_GfxWorld
|
Utils::Hook::Call<void(bool)>(0x4B8DB0)(true); // currently set to Load_GfxWorld
|
||||||
FastFiles::StreamRead = false;
|
FastFiles::StreamRead = false;
|
||||||
}, HOOK_CALL).install()->quick();
|
}, HOOK_CALL).install()/*->quick()*/;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -416,6 +416,52 @@ namespace Components
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int Maps::TriggerReconnectForMap(const char* mapname)
|
||||||
|
{
|
||||||
|
Theatre::StopRecording();
|
||||||
|
|
||||||
|
if(!Maps::CheckMapInstalled(mapname, false, true))
|
||||||
|
{
|
||||||
|
// Reconnecting forces the client to download the new map
|
||||||
|
Command::Execute("disconnect", false);
|
||||||
|
Command::Execute("awaitDatabase", false); // Wait for the database to load
|
||||||
|
Command::Execute("wait 100", false);
|
||||||
|
Command::Execute("openmenu popup_reconnectingtoparty", false);
|
||||||
|
Command::Execute("wait 8000", false); // Seems like 8000ms?
|
||||||
|
Command::Execute("closemenu popup_reconnectingtoparty", false);
|
||||||
|
Command::Execute("reconnect", false);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
__declspec(naked) void Maps::RotateCheckStub()
|
||||||
|
{
|
||||||
|
__asm
|
||||||
|
{
|
||||||
|
push eax
|
||||||
|
pushad
|
||||||
|
|
||||||
|
push [esp + 28h]
|
||||||
|
call Maps::TriggerReconnectForMap
|
||||||
|
add esp, 4h
|
||||||
|
|
||||||
|
mov[esp + 20h], eax
|
||||||
|
|
||||||
|
popad
|
||||||
|
pop eax
|
||||||
|
|
||||||
|
test eax, eax
|
||||||
|
jnz skipRotation
|
||||||
|
|
||||||
|
push 487C50h // Rotate map
|
||||||
|
|
||||||
|
skipRotation:
|
||||||
|
retn
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
__declspec(naked) void Maps::SpawnServerStub()
|
__declspec(naked) void Maps::SpawnServerStub()
|
||||||
{
|
{
|
||||||
__asm
|
__asm
|
||||||
@ -622,7 +668,6 @@ namespace Components
|
|||||||
}
|
}
|
||||||
|
|
||||||
Dvar::Var("isDlcInstalled_All").setRaw(hasAllDlcs ? 1 : 0);
|
Dvar::Var("isDlcInstalled_All").setRaw(hasAllDlcs ? 1 : 0);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Maps::reallocateEntryPool()
|
void Maps::reallocateEntryPool()
|
||||||
@ -672,24 +717,29 @@ namespace Components
|
|||||||
Utils::Hook::Set<Game::XAssetEntry*>(0x5BAEA2, Maps::EntryPool.data() + 1);
|
Utils::Hook::Set<Game::XAssetEntry*>(0x5BAEA2, Maps::EntryPool.data() + 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Maps::CheckMapInstalled(const char* mapname, bool error)
|
// dlcIsTrue serves as a check if the map is a custom map and if it's missing
|
||||||
|
bool Maps::CheckMapInstalled(const char* mapname, bool error, bool dlcIsTrue)
|
||||||
{
|
{
|
||||||
if (FastFiles::Exists(mapname)) return true;
|
if (FastFiles::Exists(mapname)) return true;
|
||||||
if (!error) return false;
|
|
||||||
|
|
||||||
for (auto& pack : Maps::DlcPacks)
|
for (auto& pack : Maps::DlcPacks)
|
||||||
{
|
{
|
||||||
for (auto map : pack.maps)
|
for (auto map : pack.maps)
|
||||||
{
|
{
|
||||||
if (map == std::string(mapname))
|
if (map == std::string(mapname))
|
||||||
|
{
|
||||||
|
if (error)
|
||||||
{
|
{
|
||||||
Components::Logger::SoftError("Missing DLC pack %s (%d) containing map %s (%s).\nPlease download it to play this map.",
|
Components::Logger::SoftError("Missing DLC pack %s (%d) containing map %s (%s).\nPlease download it to play this map.",
|
||||||
pack.name.data(), pack.index, Game::UI_LocalizeMapName(mapname), mapname);
|
pack.name.data(), pack.index, Game::UI_LocalizeMapName(mapname), mapname);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return dlcIsTrue;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Components::Logger::SoftError("Missing map file %s.\nYou may have a damaged installation or are attempting to load a non-existant map.", mapname);
|
if (error) Components::Logger::SoftError("Missing map file %s.\nYou may have a damaged installation or are attempting to load a non-existant map.", mapname);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -820,6 +870,10 @@ namespace Components
|
|||||||
Utils::Hook(0x5A9D51, Maps::LoadMapLoadscreenStub, HOOK_CALL).install()->quick();
|
Utils::Hook(0x5A9D51, Maps::LoadMapLoadscreenStub, HOOK_CALL).install()->quick();
|
||||||
Utils::Hook(0x5B34DD, Maps::LoadMapLoadscreenStub, HOOK_CALL).install()->quick();
|
Utils::Hook(0x5B34DD, Maps::LoadMapLoadscreenStub, HOOK_CALL).install()->quick();
|
||||||
|
|
||||||
|
// Download the map before a maprotation if necessary
|
||||||
|
// Conflicts with Theater's SV map rotation check, but this one is safer!
|
||||||
|
Utils::Hook(0x5AA91C, Maps::RotateCheckStub, HOOK_CALL).install()->quick();
|
||||||
|
|
||||||
Game::ReallocateAssetPool(Game::XAssetType::ASSET_TYPE_GAMEWORLD_SP, 1);
|
Game::ReallocateAssetPool(Game::XAssetType::ASSET_TYPE_GAMEWORLD_SP, 1);
|
||||||
Game::ReallocateAssetPool(Game::XAssetType::ASSET_TYPE_IMAGE, 7168);
|
Game::ReallocateAssetPool(Game::XAssetType::ASSET_TYPE_IMAGE, 7168);
|
||||||
Game::ReallocateAssetPool(Game::XAssetType::ASSET_TYPE_LOADED_SOUND, 2700);
|
Game::ReallocateAssetPool(Game::XAssetType::ASSET_TYPE_LOADED_SOUND, 2700);
|
||||||
|
@ -55,7 +55,7 @@ namespace Components
|
|||||||
|
|
||||||
static std::string CurrentMainZone;
|
static std::string CurrentMainZone;
|
||||||
|
|
||||||
static bool CheckMapInstalled(const char* mapname, bool error = false);
|
static bool CheckMapInstalled(const char* mapname, bool error = false, bool dlcIsTrue = false);
|
||||||
|
|
||||||
static UserMapContainer* GetUserMap();
|
static UserMapContainer* GetUserMap();
|
||||||
static unsigned int GetUsermapHash(std::string map);
|
static unsigned int GetUsermapHash(std::string map);
|
||||||
@ -102,7 +102,8 @@ namespace Components
|
|||||||
static void SpawnServerStub();
|
static void SpawnServerStub();
|
||||||
static void LoadMapLoadscreenStub();
|
static void LoadMapLoadscreenStub();
|
||||||
|
|
||||||
static void IwdFreeStub(Game::iwd_t* iwd);
|
static int TriggerReconnectForMap(const char* mapname);
|
||||||
|
static void RotateCheckStub();
|
||||||
|
|
||||||
void reallocateEntryPool();
|
void reallocateEntryPool();
|
||||||
};
|
};
|
||||||
|
@ -267,7 +267,7 @@ namespace Components
|
|||||||
{
|
{
|
||||||
if (Party::Container.valid)
|
if (Party::Container.valid)
|
||||||
{
|
{
|
||||||
if ((Game::Sys_Milliseconds() - Party::Container.joinTime) > 5000)
|
if ((Game::Sys_Milliseconds() - Party::Container.joinTime) > 10'000)
|
||||||
{
|
{
|
||||||
Party::Container.valid = false;
|
Party::Container.valid = false;
|
||||||
Party::ConnectError("Server connection timed out.");
|
Party::ConnectError("Server connection timed out.");
|
||||||
@ -276,7 +276,7 @@ namespace Components
|
|||||||
|
|
||||||
if (Party::Container.awaitingPlaylist)
|
if (Party::Container.awaitingPlaylist)
|
||||||
{
|
{
|
||||||
if ((Game::Sys_Milliseconds() - Party::Container.requestTime) > 5000)
|
if ((Game::Sys_Milliseconds() - Party::Container.requestTime) > 5'000)
|
||||||
{
|
{
|
||||||
Party::Container.awaitingPlaylist = false;
|
Party::Container.awaitingPlaylist = false;
|
||||||
Party::ConnectError("Playlist request timed out.");
|
Party::ConnectError("Playlist request timed out.");
|
||||||
|
@ -321,22 +321,23 @@ namespace Components
|
|||||||
|
|
||||||
void Theatre::MapChangeStub()
|
void Theatre::MapChangeStub()
|
||||||
{
|
{
|
||||||
if (*Game::demoRecording)
|
Theatre::StopRecording();
|
||||||
{
|
|
||||||
Command::Execute("stoprecord", true);
|
|
||||||
}
|
|
||||||
|
|
||||||
Utils::Hook::Call<void()>(0x464A60)();
|
Utils::Hook::Call<void()>(0x464A60)();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// DANGEROUS, DON'T USE THIS ONE!
|
||||||
void Theatre::MapChangeSVStub(char* a1, char* a2)
|
void Theatre::MapChangeSVStub(char* a1, char* a2)
|
||||||
|
{
|
||||||
|
Theatre::StopRecording();
|
||||||
|
Utils::Hook::Call<void(char*, char*)>(0x487C50)(a1, a2);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Theatre::StopRecording()
|
||||||
{
|
{
|
||||||
if (*Game::demoRecording)
|
if (*Game::demoRecording)
|
||||||
{
|
{
|
||||||
Command::Execute("stoprecord", true);
|
Command::Execute("stoprecord", true);
|
||||||
}
|
}
|
||||||
|
|
||||||
Utils::Hook::Call<void(char*, char*)>(0x487C50)(a1, a2);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Theatre::Theatre()
|
Theatre::Theatre()
|
||||||
@ -359,7 +360,7 @@ namespace Components
|
|||||||
// Autorecording
|
// Autorecording
|
||||||
Utils::Hook(0x5A1D6A, Theatre::InitCGameStub, HOOK_CALL).install()->quick();
|
Utils::Hook(0x5A1D6A, Theatre::InitCGameStub, HOOK_CALL).install()->quick();
|
||||||
Utils::Hook(0x4A712A, Theatre::MapChangeStub, HOOK_CALL).install()->quick();
|
Utils::Hook(0x4A712A, Theatre::MapChangeStub, HOOK_CALL).install()->quick();
|
||||||
Utils::Hook(0x5AA91C, Theatre::MapChangeSVStub, HOOK_CALL).install()->quick();
|
//Utils::Hook(0x5AA91C, Theatre::MapChangeSVStub, HOOK_CALL).install()->quick();
|
||||||
|
|
||||||
// UIScripts
|
// UIScripts
|
||||||
UIScript::Add("loadDemos", Theatre::LoadDemos);
|
UIScript::Add("loadDemos", Theatre::LoadDemos);
|
||||||
|
@ -11,6 +11,8 @@ namespace Components
|
|||||||
const char* getName() override { return "Theatre"; };
|
const char* getName() override { return "Theatre"; };
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
static void StopRecording();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
class DemoInfo
|
class DemoInfo
|
||||||
{
|
{
|
||||||
|
Loading…
Reference in New Issue
Block a user