void ExtractGameobjectModels()
{
    printf("Extracting GameObject models...\n");

    DB2CascFileSource source(CascStorage, "DBFilesClient\\GameObjectDisplayInfo.db2");
    DB2FileLoader db2;
    if (!db2.Load(&source, GameobjectDisplayInfoLoadInfo::Instance()))
    {
        printf("Fatal error: Invalid GameObjectDisplayInfo.db2 file format!\n");
        exit(1);
    }

    std::string basepath = szWorkDirWmo;
    basepath += "/";

    std::string modelListPath = basepath + "temp_gameobject_models";
    FILE* model_list = fopen(modelListPath.c_str(), "wb");
    if (!model_list)
    {
        printf("Fatal error: Could not open file %s\n", modelListPath.c_str());
        return;
    }

    for (uint32 rec = 0; rec < db2.GetRecordCount(); ++rec)
    {
        DB2Record record = db2.GetRecord(rec);
        uint32 fileId = record.GetUInt32(0, 0);
        if (!fileId)
            continue;

        std::string fileName = Trinity::StringFormat("FILE%08X.xxx", fileId);
        bool result = false;
        uint32 header;
        if (!GetHeaderMagic(fileName, &header))
            continue;

        if (header == MODEL_WMO)
            result = ExtractSingleWmo(fileName);
        else if (header == MODEL_MD20 || header == MODEL_MD21)
            result = ExtractSingleModel(fileName);
        else
            ASSERT(false, "%s header: %d - %c%c%c%c", fileName.c_str(), header, (header >> 24) & 0xFF, (header >> 16) & 0xFF, (header >> 8) & 0xFF, header & 0xFF);

        if (result)
        {
            uint32 displayId = record.GetId();
            uint32 path_length = fileName.length();
            fwrite(&displayId, sizeof(uint32), 1, model_list);
            fwrite(&path_length, sizeof(uint32), 1, model_list);
            fwrite(fileName.c_str(), sizeof(char), path_length, model_list);
        }
    }

    fclose(model_list);

    printf("Done!\n");
}
Exemple #2
0
int main(int argc, char ** argv)
{
    Trinity::Banner::Show("VMAP data extractor", [](char const* text) { printf("%s\n", text); }, nullptr);

    bool success = true;
    const char *versionString = "V4.06 2018_02";

    // Use command line arguments, when some
    if (!processArgv(argc, argv, versionString))
        return 1;

    if (!RetardCheck())
        return 1;

    // some simple check if working dir is dirty
    else
    {
        std::string sdir = std::string(szWorkDirWmo) + "/dir";
        std::string sdir_bin = std::string(szWorkDirWmo) + "/dir_bin";
        struct stat status;
        if (!stat(sdir.c_str(), &status) || !stat(sdir_bin.c_str(), &status))
        {
            printf("Your output directory seems to be polluted, please use an empty directory!\n");
            printf("<press return to exit>");
            char garbage[2];
            return scanf("%c", garbage);
        }
    }

    printf("Extract %s. Beginning work ....\n\n", versionString);
    //xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
    // Create the working directory
    if (mkdir(szWorkDirWmo
#if defined(__linux__) || defined(__APPLE__)
                    , 0711
#endif
                    ))
            success = (errno == EEXIST);

    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;

        FirstLocale = i;
        uint32 build = CASC::GetBuildNumber(CascStorage);
        if (!build)
        {
            CascStorage.reset();
            continue;
        }

        printf("Detected client build: %u\n\n", build);
        break;
    }

    if (FirstLocale == -1)
    {
        printf("FATAL ERROR: No locales defined, unable to continue.\n");
        return 1;
    }

    // Extract models, listed in GameObjectDisplayInfo.dbc
    ExtractGameobjectModels();

    //xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
    //map.dbc
    if (success)
    {
        printf("Read Map.dbc file... ");

        DB2CascFileSource source(CascStorage, "DBFilesClient\\Map.db2");
        DB2FileLoader db2;
        if (!db2.Load(&source, MapLoadInfo::Instance()))
        {
            printf("Fatal error: Invalid Map.db2 file format! %s\n", CASC::HumanReadableCASCError(GetLastError()));
            exit(1);
        }

        for (uint32 x = 0; x < db2.GetRecordCount(); ++x)
        {
            DB2Record record = db2.GetRecord(x);
            map_info& m = map_ids[record.GetId()];

            const char* map_name = record.GetString("Directory");
            size_t max_map_name_length = sizeof(m.name);
            if (strlen(map_name) >= max_map_name_length)
            {
                printf("Fatal error: Map name too long!\n");
                exit(1);
            }

            strncpy(m.name, map_name, max_map_name_length);
            m.name[max_map_name_length - 1] = '\0';
            m.parent_id = int16(record.GetUInt16("ParentMapID"));
            if (m.parent_id >= 0)
                maps_that_are_parents.insert(m.parent_id);
        }

        for (uint32 x = 0; x < db2.GetRecordCopyCount(); ++x)
        {
            DB2RecordCopy copy = db2.GetRecordCopy(x);
            auto itr = map_ids.find(copy.SourceRowId);
            if (itr != map_ids.end())
            {
                map_info& id = map_ids[copy.NewRowId];
                strcpy(id.name, itr->second.name);
                id.parent_id = itr->second.parent_id;
            }
        }

        printf("Done! (" SZFMTD " maps loaded)\n", map_ids.size());
        ParsMapFiles();
    }

    CascStorage.reset();

    printf("\n");
    if (!success)
    {
        printf("ERROR: Extract %s. Work NOT complete.\n   Precise vector data=%d.\nPress any key.\n", versionString, preciseVectorData);
        getchar();
    }

    printf("Extract %s. Work complete. No errors.\n", versionString);
    return 0;
}