forked from metin2/client
Improved pack initialization algorithm, archive types are now configurable in the Index file.
This commit is contained in:
@ -183,10 +183,22 @@ bool CEterPackManager::isExist(const char * c_szFileName)
|
||||
return isExistInPack(c_szFileName);
|
||||
}
|
||||
|
||||
|
||||
bool CEterPackManager::RegisterPack(const char * c_szName, const char * c_szDirectory, const BYTE* c_pbIV)
|
||||
bool CEterPackManager::PackExists(const std::string& name, const std::string& container)
|
||||
{
|
||||
auto it = m_PackMap.find(c_szName);
|
||||
if (container == "FOLDER") {
|
||||
return _access(name.c_str(), 0) == 0;
|
||||
}
|
||||
else if (container == "ZIP") {
|
||||
std::string zipName = name + ".zip";
|
||||
return _access(zipName.c_str(), 0) == 0;
|
||||
}
|
||||
|
||||
throw std::runtime_error("Unexpected container type: " + container + "!");
|
||||
}
|
||||
|
||||
bool CEterPackManager::RegisterPack(const std::string& name, const std::string& container)
|
||||
{
|
||||
auto it = m_PackMap.find(name);
|
||||
|
||||
if (it != m_PackMap.end())
|
||||
return true;
|
||||
@ -196,24 +208,28 @@ bool CEterPackManager::RegisterPack(const char * c_szName, const char * c_szDire
|
||||
|
||||
std::shared_ptr<FileProvider> pack;
|
||||
|
||||
// TODO: allow configurable containers
|
||||
|
||||
//pack = std::make_shared<Folder>(c_szName);
|
||||
pack = std::make_shared<ZIP>(std::string(c_szName) + ".zip");
|
||||
// Determine requested container type
|
||||
if (container == "FOLDER")
|
||||
pack = std::make_shared<Folder>(name);
|
||||
else if (container == "ZIP")
|
||||
pack = std::make_shared<ZIP>(name + ".zip");
|
||||
else
|
||||
throw std::runtime_error("Unexpected container type: " + container + "!");
|
||||
|
||||
// Load container data
|
||||
auto packFiles = pack->listFiles();
|
||||
|
||||
for (auto const& fileName : packFiles)
|
||||
m_FileMap.insert({ fileName, pack });
|
||||
|
||||
m_PackMap.insert({ c_szName, pack });
|
||||
m_PackMap.insert({ name, pack });
|
||||
|
||||
return true;
|
||||
}
|
||||
catch (std::exception& e)
|
||||
{
|
||||
#ifdef _DEBUG
|
||||
Tracef("Unable to load file provider '%s': %s\n", c_szName, e.what());
|
||||
Tracef("Unable to load file provider '%s': %s\n", name.c_str(), e.what());
|
||||
#endif
|
||||
|
||||
return false;
|
||||
|
@ -17,8 +17,8 @@ class CEterPackManager : public CSingleton<CEterPackManager>
|
||||
};
|
||||
|
||||
typedef std::list<std::shared_ptr<FileProvider>> TEterPackList;
|
||||
typedef std::unordered_map<std::string, std::shared_ptr<FileProvider>, stringhash> TEterPackMap;
|
||||
typedef std::unordered_map<std::string, std::shared_ptr<FileProvider>, stringhash> TFileMap;
|
||||
typedef std::unordered_map<std::string, std::shared_ptr<FileProvider>> TEterPackMap;
|
||||
typedef std::unordered_map<std::string, std::shared_ptr<FileProvider>> TFileMap;
|
||||
typedef std::shared_ptr<std::vector<char>> TPackDataPtr;
|
||||
|
||||
public:
|
||||
@ -34,7 +34,8 @@ class CEterPackManager : public CSingleton<CEterPackManager>
|
||||
bool isExist(const char * c_szFileName);
|
||||
bool isExistInPack(const char * c_szFileName);
|
||||
|
||||
bool RegisterPack(const char * c_szName, const char * c_szDirectory, const BYTE* c_pbIV = NULL);
|
||||
bool PackExists(const std::string& name, const std::string& container);
|
||||
bool RegisterPack(const std::string& name, const std::string& container);
|
||||
std::string ConvertFileName(std::string fileName);
|
||||
|
||||
const TFileMap& GetFileMap();
|
||||
|
@ -203,18 +203,31 @@ const char* ApplicationStringTable_GetStringz(DWORD dwID)
|
||||
|
||||
int Setup(LPSTR lpCmdLine); // Internal function forward
|
||||
|
||||
bool PackInitialize(const char * c_pszFolder)
|
||||
bool PackInitialize(const std::string& packFolder)
|
||||
{
|
||||
NANOBEGIN
|
||||
if (_access(c_pszFolder, 0) != 0)
|
||||
if (_access(packFolder.c_str(), 0) != 0)
|
||||
return true;
|
||||
|
||||
std::string stFolder(c_pszFolder);
|
||||
stFolder += "/";
|
||||
// Initialize variables
|
||||
bool bPackFirst = true;
|
||||
std::string stFolder = packFolder + "/";
|
||||
std::string stFileName;
|
||||
|
||||
std::string stFileName(stFolder);
|
||||
stFileName += "Index";
|
||||
#ifdef _DISTRIBUTE
|
||||
Tracef("Info: Pack search mode set to archive-first.\n");
|
||||
|
||||
// Set Index file name to production value
|
||||
stFileName = stFolder + "Index";
|
||||
#else
|
||||
bPackFirst = false;
|
||||
Tracef("Info: Pack search mode set to file-first.\n");
|
||||
|
||||
// Set Index file name to development value
|
||||
stFileName = stFolder + "Index.dev";
|
||||
#endif
|
||||
|
||||
// Set up file reader
|
||||
CMappedFile file;
|
||||
LPCVOID pvData;
|
||||
|
||||
@ -228,52 +241,43 @@ bool PackInitialize(const char * c_pszFolder)
|
||||
CMemoryTextFileLoader TextLoader;
|
||||
TextLoader.Bind(file.Size(), pvData);
|
||||
|
||||
bool bPackFirst = TRUE;
|
||||
|
||||
const std::string& strPackType = TextLoader.GetLineString(0);
|
||||
|
||||
if (strPackType.compare("FILE") && strPackType.compare("PACK"))
|
||||
{
|
||||
TraceError("Pack/Index has invalid syntax. First line must be 'PACK' or 'FILE'");
|
||||
return false;
|
||||
}
|
||||
|
||||
#ifdef _DISTRIBUTE
|
||||
Tracef("<EFBFBD>˸<EFBFBD>: <20><> <20><><EFBFBD><EFBFBD><EFBFBD>Դϴ<D4B4>.\n");
|
||||
|
||||
//if (0 == strPackType.compare("FILE"))
|
||||
//{
|
||||
// bPackFirst = FALSE;
|
||||
// Tracef("<22>˸<EFBFBD>: <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>Դϴ<D4B4>.\n");
|
||||
//}
|
||||
//else
|
||||
//{
|
||||
// Tracef("<22>˸<EFBFBD>: <20><> <20><><EFBFBD><EFBFBD><EFBFBD>Դϴ<D4B4>.\n");
|
||||
//}
|
||||
#else
|
||||
bPackFirst = FALSE;
|
||||
Tracef("<EFBFBD>˸<EFBFBD>: <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>Դϴ<D4B4>.\n");
|
||||
#endif
|
||||
|
||||
// Set up archive manager
|
||||
CTextFileLoader::SetCacheMode();
|
||||
CEterPackManager::Instance().SetSearchMode(bPackFirst);
|
||||
|
||||
CSoundData::SetPackMode(); // Miles <20><><EFBFBD><EFBFBD> <20>ݹ<EFBFBD><DDB9><EFBFBD> <20><><EFBFBD><EFBFBD>
|
||||
|
||||
// Read lines and parse tokens
|
||||
std::string strPackName, strTexCachePackName;
|
||||
for (DWORD i = 1; i < TextLoader.GetLineCount() - 1; i += 2)
|
||||
CTokenVector tokens = CTokenVector();
|
||||
|
||||
for (DWORD i = 0; i < TextLoader.GetLineCount() - 1; i++)
|
||||
{
|
||||
const std::string & c_rstFolder = TextLoader.GetLineString(i);
|
||||
const std::string & c_rstName = TextLoader.GetLineString(i + 1);
|
||||
// Split line into tokens
|
||||
TextLoader.SplitLineByTab(i, &tokens);
|
||||
|
||||
// Check if the read number of tokens is valid
|
||||
if (tokens.size() != 2)
|
||||
{
|
||||
TraceError("Invalid number of tokens on line %d: expected %d, got %d!", i, 2, tokens.size());
|
||||
return false;
|
||||
}
|
||||
|
||||
// Assign tokens into variables
|
||||
const std::string& c_rstName = tokens[0];
|
||||
const std::string& c_rstContainer = tokens[1];
|
||||
|
||||
// Load pack
|
||||
strPackName = stFolder + c_rstName;
|
||||
strTexCachePackName = strPackName + "_texcache";
|
||||
CEterPackManager::Instance().RegisterPack(strPackName, c_rstContainer);
|
||||
|
||||
CEterPackManager::Instance().RegisterPack(strPackName.c_str(), c_rstFolder.c_str());
|
||||
CEterPackManager::Instance().RegisterPack(strTexCachePackName.c_str(), c_rstFolder.c_str());
|
||||
// Try to load texture cache pack if it exists
|
||||
strTexCachePackName = strPackName + "_texcache";
|
||||
if (CEterPackManager::Instance().PackExists(strTexCachePackName, c_rstContainer)) {
|
||||
CEterPackManager::Instance().RegisterPack(strTexCachePackName, c_rstContainer);
|
||||
}
|
||||
}
|
||||
|
||||
CEterPackManager::Instance().RegisterPack((stFolder + "root").c_str(), (stFolder + "root").c_str());
|
||||
NANOEND
|
||||
return true;
|
||||
}
|
||||
|
Reference in New Issue
Block a user