[Maps] Load map specific arena files

This commit is contained in:
momo5502 2017-04-08 15:32:51 +02:00
parent 0e56b345d8
commit 8b22a1ff70
4 changed files with 68 additions and 22 deletions

View File

@ -389,16 +389,15 @@ namespace Components
std::string path = Dvar::Var("fs_basepath").get<std::string>() + "\\usermaps\\" + mapname;
std::vector<std::string> list = { mapname + ".ff", mapname + "_load.ff", mapname + ".iwd" };
for (auto i = list.begin(); i != list.end(); ++i)
for (int i = 0; i < ARRAYSIZE(Maps::UserMapFiles); ++i)
{
std::string filename = path + "\\" + *i;
if (strstr(i->data(), "_svr_") == nullptr && Utils::IO::FileExists(filename))
std::string filename = path + "\\" + mapname + Maps::UserMapFiles[i];
if (Utils::IO::FileExists(filename))
{
std::map<std::string, json11::Json> file;
std::string fileBuffer = Utils::IO::ReadFile(filename);
file["name"] = *i;
file["name"] = mapname + Maps::UserMapFiles[i];
file["size"] = static_cast<int>(fileBuffer.size());
file["hash"] = Utils::Cryptography::SHA256::Compute(fileBuffer, true);
@ -506,7 +505,18 @@ namespace Components
url = url.substr(4);
std::string mapname = Maps::GetUserMap()->getName();
if(!Maps::GetUserMap()->isValid() || (url != (mapname + ".ff") && url != (mapname + ".iwd") && url != (mapname + "_load.ff")))
bool isValidFile = false;
for (int i = 0; i < ARRAYSIZE(Maps::UserMapFiles); ++i)
{
if(url == (mapname + Maps::UserMapFiles[i]))
{
isValidFile = true;
break;
}
}
if(!Maps::GetUserMap()->isValid() || !isValidFile)
{
Download::Forbid(nc);
return;

View File

@ -12,6 +12,14 @@ namespace Components
std::vector<Maps::DLC> Maps::DlcPacks;
std::vector<Game::XAssetEntry> Maps::EntryPool;
const char* Maps::UserMapFiles[4] =
{
".ff",
"_load.ff",
".iwd",
".arena",
};
Maps::UserMapContainer* Maps::GetUserMap()
{
return &Maps::UserMap;
@ -83,6 +91,25 @@ namespace Components
}
}
const char* Maps::LoadArenaFileStub(const char* name, char* buffer, int size)
{
std::string data = Game::LoadModdableRawfile(0, name);
if(Maps::UserMap.isValid())
{
std::string mapname = Maps::UserMap.getName();
std::string arena = Utils::String::VA("usermaps/%s/%s.arena", mapname.data(), mapname.data());
if (Utils::IO::FileExists(arena))
{
data.append(Utils::IO::ReadFile(arena));
}
}
strncpy_s(buffer, size, data.data(), data.size());
return buffer;
}
void Maps::UnloadMapZones(Game::XZoneInfo* zoneInfo, unsigned int zoneCount, int sync)
{
Game::DB_LoadXAssets(zoneInfo, zoneCount, sync);
@ -396,21 +423,18 @@ namespace Components
{
if (Utils::IO::DirectoryExists(Utils::String::VA("usermaps/%s", map.data())))
{
std::string zoneHash;
std::string zonePath = Utils::String::VA("usermaps/%s/%s.ff", map.data(), map.data());
if (Utils::IO::FileExists(zonePath))
std::string hash;
for(int i = 0; i < ARRAYSIZE(Maps::UserMapFiles); ++i)
{
zoneHash = Utils::Cryptography::SHA256::Compute(Utils::IO::ReadFile(zonePath));
std::string filePath = Utils::String::VA("usermaps/%s/%s%s", map.data(), map.data(), Maps::UserMapFiles[i]);
if (Utils::IO::FileExists(filePath))
{
hash.append(Utils::Cryptography::SHA256::Compute(Utils::IO::ReadFile(filePath)));
}
}
std::string iwdHash;
std::string iwdPath = Utils::String::VA("usermaps/%s/%s.iwd", map.data(), map.data());
if (Utils::IO::FileExists(iwdPath))
{
iwdHash = Utils::Cryptography::SHA256::Compute(Utils::IO::ReadFile(iwdPath));
}
return Utils::Cryptography::JenkinsOneAtATime::Compute(zoneHash + iwdHash);
return Utils::Cryptography::JenkinsOneAtATime::Compute(hash);
}
return 0;
@ -871,6 +895,9 @@ namespace Components
// Conflicts with Theater's SV map rotation check, but this one is safer!
Utils::Hook(0x5AA91C, Maps::RotateCheckStub, HOOK_CALL).install()->quick();
// Load usermap arena file
Utils::Hook(0x630A88, Maps::LoadArenaFileStub, HOOK_CALL).install()->quick();
Game::ReallocateAssetPool(Game::XAssetType::ASSET_TYPE_GAMEWORLD_SP, 1);
Game::ReallocateAssetPool(Game::XAssetType::ASSET_TYPE_IMAGE, 7168);
Game::ReallocateAssetPool(Game::XAssetType::ASSET_TYPE_LOADED_SOUND, 2700);

View File

@ -8,11 +8,12 @@ namespace Components
class UserMapContainer
{
public:
UserMapContainer() : wasFreed(false) { }
UserMapContainer() : wasFreed(false), hash(0) {}
UserMapContainer(std::string _mapname) : wasFreed(false), mapname(_mapname)
{
ZeroMemory(&this->searchPath, sizeof this->searchPath);
this->hash = Maps::GetUsermapHash(this->mapname);
Game::UI_UpdateArenas();
}
~UserMapContainer()
@ -24,7 +25,12 @@ namespace Components
unsigned int getHash() { return this->hash; }
std::string getName() { return this->mapname; }
bool isValid() { return !this->mapname.empty(); }
void clear() { this->mapname.clear(); }
void clear()
{
bool wasValid = this->isValid();
this->mapname.clear();
if(wasValid) Game::UI_UpdateArenas();
}
void loadIwd();
void freeIwd();
@ -54,6 +60,7 @@ namespace Components
static std::vector<std::string> GetDependenciesForMap(std::string map);
static std::string CurrentMainZone;
static const char* UserMapFiles[4];
static bool CheckMapInstalled(const char* mapname, bool error = false, bool dlcIsTrue = false);
@ -105,6 +112,8 @@ namespace Components
static int TriggerReconnectForMap(const char* mapname);
static void RotateCheckStub();
static const char* LoadArenaFileStub(const char* name, char* buffer, int size);
void reallocateEntryPool();
};
}

View File

@ -13,7 +13,7 @@ namespace Components
Utils::Hook(0x5FA46C, RawFiles::LoadModdableRawfileFunc, HOOK_CALL).install()->quick();
Utils::Hook(0x5FA4D6, RawFiles::LoadModdableRawfileFunc, HOOK_CALL).install()->quick();
Utils::Hook(0x6321EF, RawFiles::LoadModdableRawfileFunc, HOOK_CALL).install()->quick();
Utils::Hook(0x630A88, RawFiles::LoadModdableRawfileFunc, HOOK_CALL).install()->quick();
//Utils::Hook(0x630A88, RawFiles::LoadModdableRawfileFunc, HOOK_CALL).install()->quick(); // Arena parsing, handled by usermap hook
Utils::Hook(0x59A6F8, RawFiles::LoadModdableRawfileFunc, HOOK_CALL).install()->quick();
Utils::Hook(0x57F1E6, RawFiles::LoadModdableRawfileFunc, HOOK_CALL).install()->quick();
Utils::Hook(0x57ED36, RawFiles::LoadModdableRawfileFunc, HOOK_CALL).install()->quick();