mirror of
https://github.com/mod-playerbots/azerothcore-wotlk.git
synced 2026-02-15 16:26:08 +00:00
133 lines
3.9 KiB
C++
133 lines
3.9 KiB
C++
/*
|
|
* This file is part of the AzerothCore Project. See AUTHORS file for Copyright information
|
|
*
|
|
* This program is free software; you can redistribute it and/or modify it
|
|
* under the terms of the GNU Affero General Public License as published by the
|
|
* Free Software Foundation; either version 3 of the License, or (at your
|
|
* option) any later version.
|
|
*
|
|
* This program is distributed in the hope that it will be useful, but WITHOUT
|
|
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
|
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for
|
|
* more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License along
|
|
* with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
*/
|
|
|
|
#include "MPQMgr.h"
|
|
#include "DBC.h"
|
|
#include "MPQ.h"
|
|
#include "Utils.h"
|
|
|
|
char const* MPQMgr::Files[] =
|
|
{
|
|
"common.MPQ",
|
|
"common-2.MPQ",
|
|
"expansion.MPQ",
|
|
"lichking.MPQ",
|
|
"patch.MPQ",
|
|
"patch-2.MPQ",
|
|
"patch-3.MPQ"
|
|
};
|
|
|
|
char const* MPQMgr::Languages[] = { "enGB", "enUS", "deDE", "esES", "frFR", "koKR", "zhCN", "zhTW", "enCN", "enTW", "esMX", "ruRU" };
|
|
|
|
void MPQMgr::Initialize()
|
|
{
|
|
InitializeDBC();
|
|
uint32 size = sizeof(Files) / sizeof(char*);
|
|
for (uint32 i = 0; i < size; ++i)
|
|
{
|
|
MPQArchive* arc = new MPQArchive(std::string("Data/" + std::string(Files[i])).c_str());
|
|
Archives.push_front(arc); // MPQ files have to be transversed in reverse order to properly account for patched files
|
|
printf("Opened %s\n", Files[i]);
|
|
}
|
|
}
|
|
|
|
void MPQMgr::InitializeDBC()
|
|
{
|
|
BaseLocale = -1;
|
|
std::string fileName;
|
|
uint32 size = sizeof(Languages) / sizeof(char*);
|
|
MPQArchive* _baseLocale = nullptr;
|
|
for (uint32 i = 0; i < size; ++i)
|
|
{
|
|
std::string _fileName = "Data/" + std::string(Languages[i]) + "/locale-" + std::string(Languages[i]) + ".MPQ";
|
|
FILE* file = fopen(_fileName.c_str(), "rb");
|
|
if (file)
|
|
{
|
|
if (BaseLocale == -1)
|
|
{
|
|
BaseLocale = i;
|
|
_baseLocale = new MPQArchive(_fileName.c_str());
|
|
fileName = _fileName;
|
|
LocaleFiles[i] = _baseLocale;
|
|
}
|
|
else
|
|
LocaleFiles[i] = new MPQArchive(_fileName.c_str());
|
|
|
|
AvailableLocales.insert(i);
|
|
printf("Detected locale: %s\n", Languages[i]);
|
|
}
|
|
}
|
|
Archives.push_front(_baseLocale);
|
|
if (BaseLocale == -1)
|
|
{
|
|
printf("No locale data detected. Please make sure that the executable is in the same folder as your WoW installation.\n");
|
|
ABORT();
|
|
}
|
|
else
|
|
printf("Using default locale: %s\n", Languages[BaseLocale]);
|
|
}
|
|
|
|
FILE* MPQMgr::GetFile(const std::string& path )
|
|
{
|
|
GUARD_RETURN(mutex, nullptr);
|
|
MPQFile file(path.c_str());
|
|
if (file.isEof())
|
|
return nullptr;
|
|
return file.GetFileStream();
|
|
}
|
|
|
|
DBC* MPQMgr::GetDBC(const std::string& name )
|
|
{
|
|
std::string path = "DBFilesClient\\" + name + ".dbc";
|
|
return new DBC(GetFile(path));
|
|
}
|
|
|
|
FILE* MPQMgr::GetFileFrom(const std::string& path, MPQArchive* file )
|
|
{
|
|
GUARD_RETURN(mutex, nullptr);
|
|
mpq_archive* mpq_a = file->mpq_a;
|
|
|
|
uint32_t filenum;
|
|
if (libmpq__file_number(mpq_a, path.c_str(), &filenum))
|
|
return nullptr;
|
|
|
|
libmpq__off_t transferred;
|
|
libmpq__off_t size = 0;
|
|
libmpq__file_unpacked_size(mpq_a, filenum, &size);
|
|
|
|
// HACK: in patch.mpq some files don't want to open and give 1 for filesize
|
|
if (size <= 1)
|
|
return nullptr;
|
|
|
|
uint8* buffer = new uint8[size];
|
|
|
|
//libmpq_file_getdata
|
|
libmpq__file_read(mpq_a, filenum, (unsigned char*)buffer, size, &transferred);
|
|
|
|
// Pack the return into a FILE stream
|
|
FILE* ret = tmpfile();
|
|
if (!ret)
|
|
{
|
|
printf("Could not create temporary file. Please run as Administrator or root\n");
|
|
exit(1);
|
|
}
|
|
fwrite(buffer, sizeof(uint8), size, ret);
|
|
fseek(ret, 0, SEEK_SET);
|
|
delete[] buffer;
|
|
return ret;
|
|
}
|