Tools/Extractors: Implement proper installed locale detection

This commit is contained in:
Shauren
2017-08-18 16:45:36 +02:00
parent 3f39913628
commit 7eab6dbb95
4 changed files with 84 additions and 23 deletions

View File

@@ -70,21 +70,34 @@ CASC::StorageHandle CASC::OpenStorage(boost::filesystem::path const& path, DWORD
return StorageHandle(handle);
}
namespace CASC
{
static DWORD GetStorageInfo(StorageHandle const& storage, CASC_STORAGE_INFO_CLASS storageInfoClass)
{
DWORD value = 0;
size_t infoDataSizeNeeded = 0;
if (!::CascGetStorageInfo(storage.get(), storageInfoClass, &value, sizeof(value), &infoDataSizeNeeded))
{
if (GetLastError() == ERROR_INSUFFICIENT_BUFFER)
{
std::unique_ptr<char> buf(new char[infoDataSizeNeeded]);
::CascGetStorageInfo(storage.get(), storageInfoClass, buf.get(), infoDataSizeNeeded, &infoDataSizeNeeded);
return *reinterpret_cast<DWORD*>(buf.get());
}
}
return value;
}
}
DWORD CASC::GetBuildNumber(StorageHandle const& storage)
{
DWORD buildNumber = 0;
size_t infoDataSizeNeeded = 0;
if (!::CascGetStorageInfo(storage.get(), CascStorageGameBuild, &buildNumber, sizeof(buildNumber), &infoDataSizeNeeded))
{
if (GetLastError() == ERROR_INSUFFICIENT_BUFFER)
{
std::unique_ptr<char> buf(new char[infoDataSizeNeeded]);
::CascGetStorageInfo(storage.get(), CascStorageGameBuild, buf.get(), infoDataSizeNeeded, &infoDataSizeNeeded);
return *reinterpret_cast<DWORD*>(buf.get());
}
}
return GetStorageInfo(storage, CascStorageGameBuild);
}
return buildNumber;
DWORD CASC::GetInstalledLocalesMask(StorageHandle const& storage)
{
return GetStorageInfo(storage, CascStorageInstalledLocales);
}
CASC::FileHandle CASC::OpenFile(StorageHandle const& storage, char const* fileName, DWORD localeMask, bool printErrors /*= false*/)

View File

@@ -50,6 +50,7 @@ namespace CASC
StorageHandle OpenStorage(boost::filesystem::path const& path, DWORD localeMask);
DWORD GetBuildNumber(StorageHandle const& storage);
DWORD GetInstalledLocalesMask(StorageHandle const& storage);
FileHandle OpenFile(StorageHandle const& storage, char const* fileName, DWORD localeMask, bool printErrors = false);
DWORD GetFileSize(FileHandle const& file, PDWORD fileSizeHigh);

View File

@@ -1337,6 +1337,25 @@ bool OpenCascStorage(int locale)
}
}
uint32 GetInstalledLocalesMask()
{
try
{
boost::filesystem::path const storage_dir(boost::filesystem::canonical(input_path) / "Data");
CASC::StorageHandle storage = CASC::OpenStorage(storage_dir, 0);
if (!storage)
return false;
return CASC::GetInstalledLocalesMask(storage);
}
catch (boost::filesystem::filesystem_error const& error)
{
printf("Unable to determine installed locales mask: %s\n", error.what());
}
return 0;
}
static bool RetardCheck()
{
try
@@ -1375,12 +1394,14 @@ int main(int argc, char * arg[])
HandleArgs(argc, arg);
int FirstLocale = -1;
uint32 build = 0;
if (!RetardCheck())
return 1;
uint32 installedLocalesMask = GetInstalledLocalesMask();
int32 firstInstalledLocale = -1;
uint32 build = 0;
for (int i = 0; i < TOTAL_LOCALES; ++i)
{
if (CONF_Locale && !(CONF_Locale & (1 << i)))
@@ -1389,12 +1410,15 @@ int main(int argc, char * arg[])
if (i == LOCALE_none)
continue;
if (!(installedLocalesMask & WowLocaleToCascLocaleFlags[i]))
continue;
if (!OpenCascStorage(i))
continue;
if ((CONF_extract & EXTRACT_DBC) == 0)
{
FirstLocale = i;
firstInstalledLocale = i;
build = CASC::GetBuildNumber(CascStorage);
if (!build)
{
@@ -1418,14 +1442,14 @@ int main(int argc, char * arg[])
ExtractDBFilesClient(i);
CascStorage.reset();
if (FirstLocale < 0)
if (firstInstalledLocale < 0)
{
FirstLocale = i;
firstInstalledLocale = i;
build = tempBuild;
}
}
if (FirstLocale < 0)
if (firstInstalledLocale < 0)
{
printf("No locales detected\n");
return 0;
@@ -1433,21 +1457,21 @@ int main(int argc, char * arg[])
if (CONF_extract & EXTRACT_CAMERA)
{
OpenCascStorage(FirstLocale);
OpenCascStorage(firstInstalledLocale);
ExtractCameraFiles();
CascStorage.reset();
}
if (CONF_extract & EXTRACT_GT)
{
OpenCascStorage(FirstLocale);
OpenCascStorage(firstInstalledLocale);
ExtractGameTables();
CascStorage.reset();
}
if (CONF_extract & EXTRACT_MAP)
{
OpenCascStorage(FirstLocale);
OpenCascStorage(firstInstalledLocale);
ExtractMaps(build);
CascStorage.reset();
}

View File

@@ -162,6 +162,25 @@ bool OpenCascStorage(int locale)
}
}
uint32 GetInstalledLocalesMask()
{
try
{
boost::filesystem::path const storage_dir(boost::filesystem::canonical(input_path) / "Data");
CASC::StorageHandle storage = CASC::OpenStorage(storage_dir, 0);
if (!storage)
return false;
return CASC::GetInstalledLocalesMask(storage);
}
catch (boost::filesystem::filesystem_error const& error)
{
printf("Unable to determine installed locales mask: %s\n", error.what());
}
return 0;
}
// Local testing functions
bool FileExists(const char* file)
{
@@ -414,12 +433,16 @@ int main(int argc, char ** argv)
))
success = (errno == EEXIST);
int FirstLocale = -1;
uint32 installedLocalesMask = GetInstalledLocalesMask();
int32 FirstLocale = -1;
for (int i = 0; i < TOTAL_LOCALES; ++i)
{
if (i == LOCALE_none)
continue;
if (!(installedLocalesMask & WowLocaleToCascLocaleFlags[i]))
continue;
if (!OpenCascStorage(i))
continue;