Fix a crash with arena reloading on custom maps
This commit is contained in:
parent
21d5b05554
commit
835f74065c
@ -315,7 +315,10 @@ namespace Components
|
|||||||
Friends::LoggedOn = (Steam::Proxy::SteamUser_ && Steam::Proxy::SteamUser_->LoggedOn());
|
Friends::LoggedOn = (Steam::Proxy::SteamUser_ && Steam::Proxy::SteamUser_->LoggedOn());
|
||||||
if (!Steam::Proxy::SteamFriends) return;
|
if (!Steam::Proxy::SteamFriends) return;
|
||||||
|
|
||||||
|
if (Game::Sys_IsMainThread())
|
||||||
|
{
|
||||||
Game::UI_UpdateArenas();
|
Game::UI_UpdateArenas();
|
||||||
|
}
|
||||||
|
|
||||||
int count = Steam::Proxy::SteamFriends->GetFriendCount(4);
|
int count = Steam::Proxy::SteamFriends->GetFriendCount(4);
|
||||||
|
|
||||||
|
@ -227,18 +227,18 @@ namespace Components
|
|||||||
|
|
||||||
pushad
|
pushad
|
||||||
|
|
||||||
push [esp + 28h]
|
push[esp + 28h]
|
||||||
call PrintMessagePipe
|
call PrintMessagePipe
|
||||||
add esp, 4h
|
add esp, 4h
|
||||||
|
|
||||||
popad
|
popad
|
||||||
ret
|
ret
|
||||||
|
|
||||||
returnPrint:
|
returnPrint :
|
||||||
pushad
|
pushad
|
||||||
|
|
||||||
push 0 // gLog
|
push 0 // gLog
|
||||||
push [esp + 2Ch] // data
|
push[esp + 2Ch] // data
|
||||||
call NetworkLog
|
call NetworkLog
|
||||||
add esp, 8h
|
add esp, 8h
|
||||||
|
|
||||||
@ -262,6 +262,8 @@ namespace Components
|
|||||||
{
|
{
|
||||||
const auto* g_log = (*Game::g_log) ? (*Game::g_log)->current.string : "";
|
const auto* g_log = (*Game::g_log) ? (*Game::g_log)->current.string : "";
|
||||||
|
|
||||||
|
if (g_log) // This can be null - has happened before
|
||||||
|
{
|
||||||
if (std::strcmp(g_log, file) == 0)
|
if (std::strcmp(g_log, file) == 0)
|
||||||
{
|
{
|
||||||
if (std::strcmp(folder, "userraw") != 0)
|
if (std::strcmp(folder, "userraw") != 0)
|
||||||
@ -273,6 +275,7 @@ namespace Components
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
__declspec(naked) void Logger::BuildOSPath_Stub()
|
__declspec(naked) void Logger::BuildOSPath_Stub()
|
||||||
{
|
{
|
||||||
@ -280,8 +283,8 @@ namespace Components
|
|||||||
{
|
{
|
||||||
pushad
|
pushad
|
||||||
|
|
||||||
push [esp + 20h + 8h]
|
push[esp + 20h + 8h]
|
||||||
push [esp + 20h + 10h]
|
push[esp + 20h + 10h]
|
||||||
call RedirectOSPath
|
call RedirectOSPath
|
||||||
add esp, 8h
|
add esp, 8h
|
||||||
|
|
||||||
@ -419,7 +422,7 @@ namespace Components
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
void PrintAliasError(Game::conChannel_t channel, const char * originalMsg, const char* soundName, const char* lastErrorStr)
|
void PrintAliasError(Game::conChannel_t channel, const char* originalMsg, const char* soundName, const char* lastErrorStr)
|
||||||
{
|
{
|
||||||
// We add a bit more info and we clear the sound stream when it happens
|
// We add a bit more info and we clear the sound stream when it happens
|
||||||
// to avoid spamming the error
|
// to avoid spamming the error
|
||||||
|
@ -103,7 +103,7 @@ namespace Components
|
|||||||
|
|
||||||
const char* Maps::LoadArenaFileStub(const char* name, char* buffer, int size)
|
const char* Maps::LoadArenaFileStub(const char* name, char* buffer, int size)
|
||||||
{
|
{
|
||||||
std::string data = RawFiles::ReadRawFile(name, buffer, size);
|
std::string data;
|
||||||
|
|
||||||
if (Maps::UserMap.isValid())
|
if (Maps::UserMap.isValid())
|
||||||
{
|
{
|
||||||
@ -116,6 +116,10 @@ namespace Components
|
|||||||
data = Utils::IO::ReadFile(arena);
|
data = Utils::IO::ReadFile(arena);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
data = RawFiles::ReadRawFile(name, buffer, size);
|
||||||
|
}
|
||||||
|
|
||||||
strncpy_s(buffer, size, data.data(), _TRUNCATE);
|
strncpy_s(buffer, size, data.data(), _TRUNCATE);
|
||||||
return buffer;
|
return buffer;
|
||||||
@ -177,7 +181,7 @@ namespace Components
|
|||||||
auto patchZone = std::format("patch_{}", zoneInfo->name);
|
auto patchZone = std::format("patch_{}", zoneInfo->name);
|
||||||
if (FastFiles::Exists(patchZone))
|
if (FastFiles::Exists(patchZone))
|
||||||
{
|
{
|
||||||
data.push_back({patchZone.data(), zoneInfo->allocFlags, zoneInfo->freeFlags});
|
data.push_back({ patchZone.data(), zoneInfo->allocFlags, zoneInfo->freeFlags });
|
||||||
}
|
}
|
||||||
|
|
||||||
return FastFiles::LoadLocalizeZones(data.data(), data.size(), sync);
|
return FastFiles::LoadLocalizeZones(data.data(), data.size(), sync);
|
||||||
@ -185,7 +189,7 @@ namespace Components
|
|||||||
|
|
||||||
void Maps::OverrideMapEnts(Game::MapEnts* ents)
|
void Maps::OverrideMapEnts(Game::MapEnts* ents)
|
||||||
{
|
{
|
||||||
auto callback = [] (Game::XAssetHeader header, void* ents)
|
auto callback = [](Game::XAssetHeader header, void* ents)
|
||||||
{
|
{
|
||||||
Game::MapEnts* mapEnts = reinterpret_cast<Game::MapEnts*>(ents);
|
Game::MapEnts* mapEnts = reinterpret_cast<Game::MapEnts*>(ents);
|
||||||
Game::clipMap_t* clipMap = header.clipMap;
|
Game::clipMap_t* clipMap = header.clipMap;
|
||||||
@ -294,7 +298,7 @@ namespace Components
|
|||||||
|
|
||||||
call Maps::GetWorldData
|
call Maps::GetWorldData
|
||||||
|
|
||||||
mov [esp + 20h], eax
|
mov[esp + 20h], eax
|
||||||
popad
|
popad
|
||||||
pop eax
|
pop eax
|
||||||
|
|
||||||
@ -314,6 +318,22 @@ namespace Components
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Maps::ForceRefreshArenas()
|
||||||
|
{
|
||||||
|
if (Game::Sys_IsMainThread())
|
||||||
|
{
|
||||||
|
Game::sharedUiInfo_t* uiInfo = reinterpret_cast<Game::sharedUiInfo_t*>(0x62E4B78);
|
||||||
|
uiInfo->updateArenas = 1;
|
||||||
|
Game::UI_UpdateArenas();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Dangerous!!
|
||||||
|
assert(false, "Arenas refreshed from wrong thread??");
|
||||||
|
Logger::Print("Tried to refresh arenas from a thread that is NOT the main thread!! This could have lead to a crash. Please report this bug and how you got it!");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// TODO : Remove hook entirely?
|
// TODO : Remove hook entirely?
|
||||||
void Maps::GetBSPName(char* buffer, size_t size, const char* format, const char* mapname)
|
void Maps::GetBSPName(char* buffer, size_t size, const char* format, const char* mapname)
|
||||||
{
|
{
|
||||||
@ -459,7 +479,7 @@ namespace Components
|
|||||||
char hashBuf[100] = { 0 };
|
char hashBuf[100] = { 0 };
|
||||||
unsigned int hash = atoi(Game::MSG_ReadStringLine(msg, hashBuf, sizeof hashBuf));
|
unsigned int hash = atoi(Game::MSG_ReadStringLine(msg, hashBuf, sizeof hashBuf));
|
||||||
|
|
||||||
if(!Maps::CheckMapInstalled(mapname, false, true) || hash && hash != Maps::GetUsermapHash(mapname))
|
if (!Maps::CheckMapInstalled(mapname, false, true) || hash && hash != Maps::GetUsermapHash(mapname))
|
||||||
{
|
{
|
||||||
// Reconnecting forces the client to download the new map
|
// Reconnecting forces the client to download the new map
|
||||||
Command::Execute("disconnect", false);
|
Command::Execute("disconnect", false);
|
||||||
@ -480,12 +500,12 @@ namespace Components
|
|||||||
push eax
|
push eax
|
||||||
pushad
|
pushad
|
||||||
|
|
||||||
push [esp + 28h]
|
push[esp + 28h]
|
||||||
push ebp
|
push ebp
|
||||||
call Maps::TriggerReconnectForMap
|
call Maps::TriggerReconnectForMap
|
||||||
add esp, 8h
|
add esp, 8h
|
||||||
|
|
||||||
mov [esp + 20h], eax
|
mov[esp + 20h], eax
|
||||||
|
|
||||||
popad
|
popad
|
||||||
pop eax
|
pop eax
|
||||||
@ -495,7 +515,7 @@ namespace Components
|
|||||||
|
|
||||||
push 487C50h // Rotate map
|
push 487C50h // Rotate map
|
||||||
|
|
||||||
skipRotation:
|
skipRotation :
|
||||||
retn
|
retn
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -506,7 +526,7 @@ namespace Components
|
|||||||
{
|
{
|
||||||
pushad
|
pushad
|
||||||
|
|
||||||
push [esp + 24h]
|
push[esp + 24h]
|
||||||
call Maps::PrepareUsermap
|
call Maps::PrepareUsermap
|
||||||
pop eax
|
pop eax
|
||||||
|
|
||||||
@ -523,7 +543,7 @@ namespace Components
|
|||||||
{
|
{
|
||||||
pushad
|
pushad
|
||||||
|
|
||||||
push [esp + 24h]
|
push[esp + 24h]
|
||||||
call Maps::PrepareUsermap
|
call Maps::PrepareUsermap
|
||||||
pop eax
|
pop eax
|
||||||
|
|
||||||
@ -756,7 +776,7 @@ namespace Components
|
|||||||
Maps::AddDlc({ 2, "Resurgence Pack", {"mp_abandon", "mp_vacant", "mp_trailerpark", "mp_strike", "mp_fuel2"} });
|
Maps::AddDlc({ 2, "Resurgence Pack", {"mp_abandon", "mp_vacant", "mp_trailerpark", "mp_strike", "mp_fuel2"} });
|
||||||
Maps::AddDlc({ 3, "IW4x Classics", {"mp_nuked", "mp_cross_fire", "mp_cargoship", "mp_bloc", "mp_killhouse", "mp_bog_sh", "mp_cargoship_sh", "mp_shipment", "mp_shipment_long", "mp_rust_long", "mp_firingrange", "mp_bloc_sh", "mp_crash_tropical", "mp_estate_tropical", "mp_fav_tropical", "mp_storm_spring"} });
|
Maps::AddDlc({ 3, "IW4x Classics", {"mp_nuked", "mp_cross_fire", "mp_cargoship", "mp_bloc", "mp_killhouse", "mp_bog_sh", "mp_cargoship_sh", "mp_shipment", "mp_shipment_long", "mp_rust_long", "mp_firingrange", "mp_bloc_sh", "mp_crash_tropical", "mp_estate_tropical", "mp_fav_tropical", "mp_storm_spring"} });
|
||||||
Maps::AddDlc({ 4, "Call Of Duty 4 Pack", {"mp_farm", "mp_backlot", "mp_pipeline", "mp_countdown", "mp_crash_snow", "mp_carentan", "mp_broadcast", "mp_showdown", "mp_convoy", "mp_citystreets"} });
|
Maps::AddDlc({ 4, "Call Of Duty 4 Pack", {"mp_farm", "mp_backlot", "mp_pipeline", "mp_countdown", "mp_crash_snow", "mp_carentan", "mp_broadcast", "mp_showdown", "mp_convoy", "mp_citystreets"} });
|
||||||
Maps::AddDlc({ 5, "Modern Warfare 3 Pack", {"mp_dome", "mp_hardhat", "mp_paris", "mp_seatown", "mp_bravo", "mp_underground", "mp_plaza2", "mp_village", "mp_alpha"}});
|
Maps::AddDlc({ 5, "Modern Warfare 3 Pack", {"mp_dome", "mp_hardhat", "mp_paris", "mp_seatown", "mp_bravo", "mp_underground", "mp_plaza2", "mp_village", "mp_alpha"} });
|
||||||
|
|
||||||
Maps::UpdateDlcStatus();
|
Maps::UpdateDlcStatus();
|
||||||
|
|
||||||
@ -845,12 +865,6 @@ namespace Components
|
|||||||
// Load usermap arena file
|
// Load usermap arena file
|
||||||
Utils::Hook(0x630A88, Maps::LoadArenaFileStub, HOOK_CALL).install()->quick();
|
Utils::Hook(0x630A88, Maps::LoadArenaFileStub, HOOK_CALL).install()->quick();
|
||||||
|
|
||||||
// Always refresh arena when loading or unloading a zone
|
|
||||||
Utils::Hook::Nop(0x485017, 2);
|
|
||||||
Utils::Hook::Nop(0x4BDFB7, 2); // Unknown
|
|
||||||
Utils::Hook::Nop(0x45ED6F, 2); // loadGameInfo
|
|
||||||
Utils::Hook::Nop(0x4A5888, 2); // UI_InitOnceForAllClients
|
|
||||||
|
|
||||||
// Allow hiding specific smodels
|
// Allow hiding specific smodels
|
||||||
Utils::Hook(0x50E67C, Maps::HideModelStub, HOOK_CALL).install()->quick();
|
Utils::Hook(0x50E67C, Maps::HideModelStub, HOOK_CALL).install()->quick();
|
||||||
|
|
||||||
@ -880,7 +894,7 @@ namespace Components
|
|||||||
Game::Font_s* font = Game::R_RegisterFont("fonts/smallFont", 0);
|
Game::Font_s* font = Game::R_RegisterFont("fonts/smallFont", 0);
|
||||||
auto height = Game::R_TextHeight(font);
|
auto height = Game::R_TextHeight(font);
|
||||||
auto scale = 0.75f;
|
auto scale = 0.75f;
|
||||||
float color[4] = {0.0f, 1.0f, 0.0f, 1.0f};
|
float color[4] = { 0.0f, 1.0f, 0.0f, 1.0f };
|
||||||
|
|
||||||
unsigned int i = 0;
|
unsigned int i = 0;
|
||||||
for (auto& model : models)
|
for (auto& model : models)
|
||||||
|
@ -13,7 +13,7 @@ namespace Components
|
|||||||
{
|
{
|
||||||
ZeroMemory(&this->searchPath, sizeof this->searchPath);
|
ZeroMemory(&this->searchPath, sizeof this->searchPath);
|
||||||
this->hash = Maps::GetUsermapHash(this->mapname);
|
this->hash = Maps::GetUsermapHash(this->mapname);
|
||||||
Game::UI_UpdateArenas();
|
Maps::ForceRefreshArenas();
|
||||||
}
|
}
|
||||||
|
|
||||||
~UserMapContainer()
|
~UserMapContainer()
|
||||||
@ -29,7 +29,10 @@ namespace Components
|
|||||||
{
|
{
|
||||||
bool wasValid = this->isValid();
|
bool wasValid = this->isValid();
|
||||||
this->mapname.clear();
|
this->mapname.clear();
|
||||||
if (wasValid) Game::UI_UpdateArenas();
|
if (wasValid)
|
||||||
|
{
|
||||||
|
Maps::ForceRefreshArenas();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void loadIwd();
|
void loadIwd();
|
||||||
@ -95,6 +98,8 @@ namespace Components
|
|||||||
|
|
||||||
static Dvar::Var RListSModels;
|
static Dvar::Var RListSModels;
|
||||||
|
|
||||||
|
static void ForceRefreshArenas();
|
||||||
|
|
||||||
static void GetBSPName(char* buffer, size_t size, const char* format, const char* mapname);
|
static void GetBSPName(char* buffer, size_t size, const char* format, const char* mapname);
|
||||||
static void LoadAssetRestrict(Game::XAssetType type, Game::XAssetHeader asset, const std::string& name, bool* restrict);
|
static void LoadAssetRestrict(Game::XAssetType type, Game::XAssetHeader asset, const std::string& name, bool* restrict);
|
||||||
static void LoadMapZones(Game::XZoneInfo *zoneInfo, unsigned int zoneCount, int sync);
|
static void LoadMapZones(Game::XZoneInfo *zoneInfo, unsigned int zoneCount, int sync);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user