mirror of
https://github.com/spiffcode/hostile-takeover.git
synced 2025-12-16 12:08:36 +00:00
132 lines
3.5 KiB
C++
132 lines
3.5 KiB
C++
#include "server/levelinfocache.h"
|
|
#include "server/ncpackfile.h"
|
|
#include "mpshared/indexloader.h"
|
|
#include "base/log.h"
|
|
|
|
namespace wi {
|
|
|
|
void LevelInfoCache::SubmitIndex(const std::string& indexfile) {
|
|
int cLoaded = 0;
|
|
IndexLoader index;
|
|
if (index.InitFromFile(indexfile.c_str())) {
|
|
int c = index.GetCount();
|
|
for (int i = 0; i < c; i++) {
|
|
const IndexEntry *entry = index.GetEntry(i);
|
|
if (SubmitHelper(entry->packid)) {
|
|
cLoaded++;
|
|
}
|
|
}
|
|
}
|
|
RLOG() << cLoaded << " mission packs successfully submitted.";
|
|
}
|
|
|
|
bool LevelInfoCache::SubmitHelper(const PackId& packid) {
|
|
bool success = false;
|
|
NoCachePackFileReader pakr;
|
|
if (packm_.Mount(pakr, &packid)) {
|
|
success = Submit(pakr, packid);
|
|
packm_.Unmount(pakr, &packid);
|
|
}
|
|
return success;
|
|
}
|
|
|
|
bool LevelInfoCache::Submit(PackFileReader& pakr, const PackId& packid) {
|
|
// Create new infomap before removing old (if it exists), in case invalid
|
|
LevelInfoMap infomap;
|
|
CreateLevelInfoMap(pakr, packid, &infomap);
|
|
if (infomap.size() == 0) {
|
|
return false;
|
|
}
|
|
// Remove the old pack, if present, then add this pack
|
|
PackMap::iterator it = map_.find(packid.id);
|
|
if (it != map_.end()) {
|
|
map_.erase(it);
|
|
}
|
|
map_.insert(PackMap::value_type(packid.id,
|
|
std::make_pair(packid, infomap)));
|
|
|
|
return true;
|
|
}
|
|
|
|
void LevelInfoCache::CreateLevelInfoMap(PackFileReader& pakr,
|
|
const PackId& packid, LevelInfoMap *infomap) {
|
|
Enum enm;
|
|
char szFile[256];
|
|
while (pakr.EnumFiles(&enm, PACKENUM_LAST, szFile, sizeof(szFile))) {
|
|
if (strlen(szFile) <= 4) {
|
|
continue;
|
|
}
|
|
if (strcmp(&szFile[strlen(szFile) - 4], ".lvl") != 0) {
|
|
continue;
|
|
}
|
|
LevelInfo info;
|
|
if (!info.Load(pakr, szFile)) {
|
|
continue;
|
|
}
|
|
infomap->insert(LevelInfoMap::value_type(std::string(szFile), info));
|
|
}
|
|
}
|
|
|
|
int LevelInfoCache::FindInfo(const PackId& packid, const std::string& level,
|
|
LevelInfo *pinfo, PackId *ppackidUpgrade) {
|
|
if (packid.id != PACKID_MAIN) {
|
|
switch (packm_.IsInstalled(&packid, ppackidUpgrade)) {
|
|
case 0:
|
|
// Don't know about this pack at all
|
|
return 0;
|
|
|
|
case 1:
|
|
// Know about this pack, and have this version
|
|
break;
|
|
|
|
case 2:
|
|
// Know about this pack, but client has wrong version
|
|
return 2;
|
|
}
|
|
}
|
|
|
|
// Lazy load the LevelInfo if necessary
|
|
PackMap::iterator it0 = map_.find(packid.id);
|
|
if (it0 == map_.end()) {
|
|
if (!SubmitHelper(packid)) {
|
|
return 0;
|
|
}
|
|
it0 = map_.find(packid.id);
|
|
if (it0 == map_.end()) {
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
// Same packid? If not, re-submit
|
|
if (memcmp(&it0->second.first, &packid, sizeof(packid)) != 0) {
|
|
if (!SubmitHelper(packid)) {
|
|
return 0;
|
|
}
|
|
it0 = map_.find(packid.id);
|
|
if (it0 == map_.end()) {
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
LevelInfoMap::iterator it1 = it0->second.second.find(level);
|
|
if (it1 == it0->second.second.end()) {
|
|
return 0;
|
|
}
|
|
|
|
if (pinfo != NULL) {
|
|
*pinfo = it1->second;
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
void LevelInfoCache::RemoveInfo(const PackId& packid) {
|
|
PackMap::iterator it = map_.find(packid.id);
|
|
if (it != map_.end()) {
|
|
if (memcmp(&it->second.first, &packid, sizeof(packid)) == 0) {
|
|
map_.erase(it);
|
|
}
|
|
}
|
|
}
|
|
|
|
} // namespace wi
|