Пример #1
0
    FAFile* FAfopen(const std::string& filename)
    {
        bfs::path path(filename);
        path.make_preferred();

        if(!bfs::exists(filename))
        {
            int nError = ERROR_SUCCESS;
            
            if(diabdat == NULL && !SFileOpenArchive(getMPQFileName().c_str(), 0, STREAM_FLAG_READ_ONLY, &diabdat))
                nError = GetLastError();

            if(nError != ERROR_SUCCESS)
            {
                std::cerr << "Failed to open " << DIABDAT_MPQ << std::endl;
                return NULL;
            }
            
            std::string stormPath = getStormLibPath(path);

            if(!SFileHasFile(diabdat, stormPath.c_str()))
            {
                std::cerr << "File " << path << " not found" << std::endl;
                return NULL;
            }
            
            FAFile* file = new FAFile();
            file->data.mpqFile = malloc(sizeof(HANDLE));

            if(!SFileOpenFileEx(diabdat, stormPath.c_str(), 0, (HANDLE*)file->data.mpqFile))
            {
                std::cerr << "Failed to open " << filename << " in " << DIABDAT_MPQ;
                delete file;
                return NULL;
            }

            file->mode = FAFile::MPQFile;

            return file;
        }
        else
        {
            FILE* plainFile = fopen(filename.c_str(), "rb");
            if(plainFile == NULL)
                return NULL;

            FAFile* file = new FAFile();
            file->mode = FAFile::PlainFile; 
            file->data.plainFile.file = plainFile;
            file->data.plainFile.filename = new std::string(filename);

            return file;
        }
    }
Пример #2
0
    bool exists(const std::string& filename)
    {
        bfs::path path(filename);
        path.make_preferred();

        if(bfs::exists(filename))
            return true;

        std::lock_guard<std::mutex> lock(m);
        std::string stormPath = getStormLibPath(path);

        return SFileHasFile(diabdat, stormPath.c_str());
    }
Пример #3
0
    FAFile* FAfopen(const std::string& filename)
    {
        bfs::path path(filename);
        path.make_preferred();

        if(!bfs::exists(filename))
        {
            std::lock_guard<std::mutex> lock(m);
            std::string stormPath = getStormLibPath(path);

            if(!SFileHasFile(diabdat, stormPath.c_str()))
            {
                std::cerr << "File " << path << " not found" << std::endl;
                return NULL;
            }

            FAFile* file = new FAFile();
            file->data.mpqFile = malloc(sizeof(HANDLE));

            if(!SFileOpenFileEx(diabdat, stormPath.c_str(), 0, (HANDLE*)file->data.mpqFile))
            {
                std::cerr << "Failed to open " << filename << " in " << DIABDAT_MPQ;
                delete file;
                return NULL;
            }

            file->mode = FAFile::MPQFile;

            return file;
        }
        else
        {
            FILE* plainFile = fopen(filename.c_str(), "rb");
            if(plainFile == NULL)
                return NULL;

            FAFile* file = new FAFile();
            file->mode = FAFile::PlainFile;
            file->data.plainFile.file = plainFile;
            file->data.plainFile.filename = new std::string(filename);

            return file;
        }
    }
Пример #4
0
	bool MpkManip::hasFile(const char* filename)
	{
		return SFileHasFile(m_hMpk,(char*)filename) != FALSE;
	}
Пример #5
0
bool WINAPI SFileOpenPatchArchive(
    HANDLE hMpq,
    const TCHAR * szPatchMpqName,
    const char * szPatchPathPrefix,
    DWORD dwFlags)
{
    TMPQArchive * haPatch;
    TMPQArchive * ha = (TMPQArchive *)hMpq;
    HANDLE hPatchMpq = NULL;
    char szPatchPrefixBuff[MPQ_PATCH_PREFIX_LEN];
    int nError = ERROR_SUCCESS;

    // Keep compiler happy
    dwFlags = dwFlags;

    // Verify input parameters
    if(!IsValidMpqHandle(ha))
        nError = ERROR_INVALID_HANDLE;
    if(szPatchMpqName == NULL || *szPatchMpqName == 0)
        nError = ERROR_INVALID_PARAMETER;

    // If the user didn't give the patch prefix, get default one
    if(szPatchPathPrefix != NULL)
    {
        // Save length of the patch prefix
        if(strlen(szPatchPathPrefix) > MPQ_PATCH_PREFIX_LEN - 2)
            nError = ERROR_INVALID_PARAMETER;
    }

    //
    // We don't allow adding patches to archives that have been open for write
    //
    // Error scenario:
    //
    // 1) Open archive for writing
    // 2) Modify or replace a file
    // 3) Add patch archive to the opened MPQ
    // 4) Read patched file
    // 5) Now what ?
    //

    if(nError == ERROR_SUCCESS)
    {
        if((ha->pStream->StreamFlags & STREAM_FLAG_READ_ONLY) == 0)
            nError = ERROR_ACCESS_DENIED;
    }

    // Open the archive like it is normal archive
    if(nError == ERROR_SUCCESS)
    {
        if(!SFileOpenArchive(szPatchMpqName, 0, MPQ_OPEN_READ_ONLY, &hPatchMpq))
            return false;
        haPatch = (TMPQArchive *)hPatchMpq;

        // Older WoW patches (build 13914) used to have
        // several language versions in one patch file
        // Those patches needed to have a path prefix
        // We can distinguish such patches by not having the (patch_metadata) file
        if(szPatchPathPrefix == NULL)
        {
            if(!SFileHasFile(hPatchMpq, PATCH_METADATA_NAME))
            {
                GetDefaultPatchPrefix(ha->pStream->szFileName, szPatchPrefixBuff);
                szPatchPathPrefix = szPatchPrefixBuff;
            }
        }

        // Save the prefix for patch file names.
        // Make sure that there is backslash after it
        if(szPatchPathPrefix != NULL && *szPatchPathPrefix != 0)
        {
            strcpy(haPatch->szPatchPrefix, szPatchPathPrefix);
            strcat(haPatch->szPatchPrefix, "\\");
            haPatch->cchPatchPrefix = strlen(haPatch->szPatchPrefix);
        }

        // Now add the patch archive to the list of patches to the original MPQ
        while(ha != NULL)
        {
            if(ha->haPatch == NULL)
            {
                haPatch->haBase = ha;
                ha->haPatch = haPatch;
                return true;
            }

            // Move to the next archive
            ha = ha->haPatch;
        }

        // Should never happen
        nError = ERROR_CAN_NOT_COMPLETE;
    }

    SetLastError(nError);
    return false;
}
Пример #6
0
int SC2Map::readGameStrings_txt( const HANDLE archive )
{
  string gameStrings;
  string suffix( ".SC2Data\\LocalizedData\\GameStrings.txt" );

  list<string>::iterator itr;

  bool localeFound = false;

  // first check local user config
  itr = configUserLocal.localePreferences.begin();
  while( itr != configUserLocal.localePreferences.end() && !localeFound )
  {
    gameStrings.assign( *itr );
    gameStrings.append( suffix );

    if( SFileHasFile( archive, gameStrings.data() ) )
    {
      // gameStrings now holds name of valid file in archive
      localeFound = true;
    }

    ++itr;
  }

  // then global user config
  itr = configUserGlobal.localePreferences.begin();
  while( itr != configUserGlobal.localePreferences.end() && !localeFound )
  {
    gameStrings.assign( *itr );
    gameStrings.append( suffix );

    if( SFileHasFile( archive, gameStrings.data() ) )
    {
      // gameStrings now holds name of valid file in archive
      localeFound = true;
    }

    ++itr;
  }

  // last resort is global internal config
  itr = configInternal.localePreferences.begin();
  while( itr != configInternal.localePreferences.end() && !localeFound )
  {
    gameStrings.assign( *itr );
    gameStrings.append( suffix );

    if( SFileHasFile( archive, gameStrings.data() ) )
    {
      // gameStrings now holds name of valid file in archive
      localeFound = true;
    }

    ++itr;
  }

  int bufferSize;
  u8* bufferFreeAfterUse;

  if( readArchiveFile( archive, gameStrings.data(), &bufferSize, &bufferFreeAfterUse ) < 0 )
  {
    return -1;
  }

  // this is a plain text file, so copy the data into a null-terminated character
  // buffer so we can use string searching on it
  char bufferString[bufferSize + 1];
  memcpy( bufferString, bufferFreeAfterUse, bufferSize );
  bufferString[sizeof( bufferString ) - 1] = '\0';

  // release the buffer with the file's data
  delete bufferFreeAfterUse;

  // try to find the map's name here, otherwise use the
  // filename--the goal is to name the output files
  char strMapName[FILENAME_LENGTH];

  char attributeName[] = "DocInfo/Name=";

  char* findAttribute = strstr( bufferString, attributeName );

  if( findAttribute == NULL )
  {
    // return -1 because we should choose another name
    return -1;
  }

  // we did find a name
  int nameStartIndex = (int)findAttribute -
                       (int)bufferString  +
                       strlen( attributeName );
  int i = 0;
  while( nameStartIndex + i < bufferSize &&
         bufferString[nameStartIndex + i] != '\r' )
  {
    strMapName[i] = bufferString[nameStartIndex + i];
    ++i;
  }
  strMapName[i] = '\0';

  // put it in a nice string and done!
  mapName.assign( strMapName );

  return 0;
}
Пример #7
0
QByteArray MPQ::readFile(const QString &fileName)
{
    static QHash<QString, QByteArray> files;

    static const QString mpqs[] = {
        "patch-2.MPQ",
        "patch.MPQ",
        "dbc.MPQ",
        "model.MPQ",
        "interface.MPQ",
        "texture.MPQ",
        ""
    };

    if (files.contains(fileName))
        return files[fileName];

    const QString *mpq = mpqs;

    HANDLE hMPQ = 0;

    while (!mpq->isEmpty()) {
        QString path = MPQ::gameDir() + "Data/" + *mpq;

        hMPQ = getHandle(path);

        if (hMPQ && SFileHasFile(hMPQ, fileName.toUtf8().constData()))
            break;
        else
            hMPQ = 0;

        mpq++;
    }

    if (!hMPQ) {
        qCritical("File '%s' not found", qPrintable(fileName));
        return files[fileName];
    }

    HANDLE hFile;

    if (!SFileOpenFileEx(hMPQ, fileName.toUtf8().constData(), SFILE_OPEN_FROM_MPQ, &hFile)) {
        qCritical("Cannot open file '%s' from archive", qPrintable(fileName));
        return files[fileName];
    }

    DWORD size = SFileGetFileSize(hFile, NULL);

    if (size == SFILE_INVALID_SIZE) {
        qCritical("Cannot read file '%s' from archive", qPrintable(fileName));
        return files[fileName];
    }

    char *data = new char[size];

    if (!SFileReadFile(hFile, data, size, NULL, NULL)) {
        qCritical("Cannot read file '%s' from archive", qPrintable(fileName));
        SFileCloseFile(hFile);
        delete[] data;
        return files[fileName];
    }

    SFileCloseFile(hFile);

    files[fileName] = QByteArray(data, size);

    delete[] data;

    return files[fileName];
}