Beispiel #1
0
void ae3d::FileSystem::LoadPakFile( const char* path )
{
    if (path == nullptr)
    {
        System::Print( "LoadPakFile: path is null\n" );
    }

    Global::pakFiles.emplace_back( PakFile() );
    unsigned entryCount = 0;
    std::ifstream ifs( path );
    if (!ifs.is_open())
    {
        System::Print( "LoadPakFile: Could not open %s\n", path );
    }

    ifs.read( (char*)&entryCount, 4 );
    auto& pakFile = Global::pakFiles.back();
    pakFile.entries.resize( entryCount );
    pakFile.path = path;

    for (unsigned i = 0; i < entryCount; ++i)
    {
        auto& entry = pakFile.entries[i];
        char entryPath[ 128 ];
        ifs.read( entryPath, 128 );
        entry.path = entryPath;
        unsigned entrySize = 0;
        ifs.read( (char*)&entrySize, 4 );
        entry.contents.resize( entrySize );
        ifs.read( (char*)entry.contents.data(), entrySize );
    }
}
Beispiel #2
0
bool TestPakFile(const TCHAR* Filename)
{	
	FPakFile PakFile(Filename, FParse::Param(FCommandLine::Get(), TEXT("signed")));
	if (PakFile.IsValid())
	{
		UE_LOG(LogPakFile, Display, TEXT("Checking pak file \"%s\". This may take a while..."), Filename);
		FArchive& PakReader = *PakFile.GetSharedReader(NULL);
		int32 ErrorCount = 0;
		int32 FileCount = 0;

		for (FPakFile::FFileIterator It(PakFile); It; ++It, ++FileCount)
		{
			const FPakEntry& Entry = It.Info();
			void* FileContents = FMemory::Malloc(Entry.Size);
			PakReader.Seek(Entry.Offset);
			uint32 SerializedCrcTest = 0;
			FPakEntry EntryInfo;
			EntryInfo.Serialize(PakReader, PakFile.GetInfo().Version);
			if (EntryInfo != Entry)
			{
				UE_LOG(LogPakFile, Error, TEXT("Serialized hash mismatch for \"%s\"."), *It.Filename());
				ErrorCount++;
			}
			PakReader.Serialize(FileContents, Entry.Size);
		
			uint8 TestHash[20];
			FSHA1::HashBuffer(FileContents, Entry.Size, TestHash);
			if (FMemory::Memcmp(TestHash, Entry.Hash, sizeof(TestHash)) != 0)
			{
				UE_LOG(LogPakFile, Error, TEXT("Hash mismatch for \"%s\"."), *It.Filename());
				ErrorCount++;
			}
			else
			{
				UE_LOG(LogPakFile, Display, TEXT("\"%s\" OK."), *It.Filename());
			}
			FMemory::Free(FileContents);
		}
		if (ErrorCount == 0)
		{
			UE_LOG(LogPakFile, Display, TEXT("Pak file \"%s\" healthy, %d files checked."), Filename, FileCount);
		}
		else
		{
			UE_LOG(LogPakFile, Display, TEXT("Pak file \"%s\" corrupted (%d errors ouf of %d files checked.)."), Filename, ErrorCount, FileCount);
		}
		return (ErrorCount == 0);
	}
	else
	{
		UE_LOG(LogPakFile, Error, TEXT("Unable to open pak file \"%s\"."), Filename);
		return false;
	}
}
Beispiel #3
0
bool ListFilesInPak(const TCHAR * InPakFilename)
{
	FPakFile PakFile(InPakFilename, FParse::Param(FCommandLine::Get(), TEXT("signed")));
	int32 FileCount = 0;
	int64 FileSize = 0;

	if (PakFile.IsValid())
	{
		TArray<FPakFile::FFileIterator> Records;

		for (FPakFile::FFileIterator It(PakFile); It; ++It)
		{
			Records.Add(It);
		}

		struct FOffsetSort
		{
			FORCEINLINE bool operator()(const FPakFile::FFileIterator& A, const FPakFile::FFileIterator& B) const
			{
				return A.Info().Offset < B.Info().Offset;
			}
		};

		Records.Sort(FOffsetSort());

		for (auto It : Records)
		{
			const FPakEntry& Entry = It.Info();
			UE_LOG(LogPakFile, Display, TEXT("\"%s\" offset: %lld, size: %d bytes."), *It.Filename(), Entry.Offset, Entry.Size);
			FileSize += Entry.Size;
			FileCount++;
		}
		UE_LOG(LogPakFile, Display, TEXT("%d files (%lld bytes)."), FileCount, FileSize);

		return true;
	}
	else
	{
		UE_LOG(LogPakFile, Error, TEXT("Unable to open pak file \"%s\"."), InPakFilename);
		return false;
	}
}
Beispiel #4
0
libPak::libPak(QIODevice *dev):_dev(dev), _type(PakUnknown) {
    // Store IODevice original position
    QIODevice::Offset lastOffset = _dev->at();

    /* Get type */
    _dev->reset();
    _dev->readBlock(_magic, 8);

    if (qstrncmp(_magic, "SceeWhPk", 8) == 0) {
        _type = PakPK;
    } else if (qstrncmp(_magic, "SceeWhPC", 8) == 0)
        // This type has CRC information along with files
        _type = PakPC;

    if (_type != PakUnknown) {
        /* Get date and time */
        char dateTime[20];
        _dev->readBlock(dateTime, 20);
        // TODO: Parse date and time
        //_dateTime.fromString(dateTime,

        /* Get files header size and number of files */
        _dev->readBlock((char*)&_headSize, 4);
        _dev->readBlock((char*)&_nFiles, 4);

        /* Get extensions */
        _dev->at(0x0114);
        char exts[0x84];
        _dev->readBlock(exts, 0x84);
        QStringList extsList;
        for (int j = 0; j < 0x84; j += 4) {
            if (exts[j])
                extsList.append(QCString(exts+j));
        }

        /* Get files */
        char filesBuf[_headSize];
        _dev->readBlock(filesBuf, _headSize);
        register int offset = 0;

        // TODO: Find a better way to reserve space on the list!
        for (unsigned int j = 0; j < _nFiles; j++) {
            _files.push_back(PakFile());
        }
        QString last("");
        for (unsigned int j = 0; j < _nFiles; j++) {
            _files[j].offset = (*(unsigned int *)(filesBuf+offset) & 0x00FFFFFF) * 0x800;
            offset += 3;
            unsigned int save = *(unsigned char *)(filesBuf+offset);
            unsigned int strLen = filesBuf[offset + 1] - 1;
            // Unknown use!
            unsigned int dir = *(unsigned short *)(filesBuf+offset + 2);
            offset += 4;
            _files[j].size = *(unsigned int *)(filesBuf+offset);
            offset += 4;
            if (_type == PakPC) {
                _files[j].CRC = *(unsigned int *)(filesBuf+offset);
                offset += 4;
            }
            last = _files[j].filename = last.left(save).append(QCString(filesBuf+offset, strLen + 1));
            offset += strLen;
            _files[j].filename.append("." + extsList[*(unsigned char*)(filesBuf + offset++) - 1]).prepend("\\");
            _filenamesOnly.push_back(_files[j].filename);
        }
    }

    // Restore original position
    _dev->at(lastOffset);
}
Beispiel #5
0
bool ExtractFilesFromPak(const TCHAR* InPakFilename, const TCHAR* InDestPath, bool bUseMountPoint = false)
{
	FPakFile PakFile(InPakFilename, FParse::Param(FCommandLine::Get(), TEXT("signed")));
	if (PakFile.IsValid())
	{
		FString DestPath(InDestPath);
		FArchive& PakReader = *PakFile.GetSharedReader(NULL);
		const int64 BufferSize = 8 * 1024 * 1024; // 8MB buffer for extracting
		void* Buffer = FMemory::Malloc(BufferSize);
		int64 CompressionBufferSize = 0;
		uint8* PersistantCompressionBuffer = NULL;
		int32 ErrorCount = 0;
		int32 FileCount = 0;

		FString PakMountPoint = bUseMountPoint ? PakFile.GetMountPoint().Replace( TEXT("../../../"), TEXT("")) : TEXT("");

		for (FPakFile::FFileIterator It(PakFile); It; ++It, ++FileCount)
		{
			const FPakEntry& Entry = It.Info();
			PakReader.Seek(Entry.Offset);
			uint32 SerializedCrcTest = 0;
			FPakEntry EntryInfo;
			EntryInfo.Serialize(PakReader, PakFile.GetInfo().Version);
			if (EntryInfo == Entry)
			{
				FString DestFilename(DestPath / PakMountPoint /  It.Filename());

				TAutoPtr<FArchive> FileHandle(IFileManager::Get().CreateFileWriter(*DestFilename));
				if (FileHandle.IsValid())
				{
					if (Entry.CompressionMethod == COMPRESS_None)
					{
						BufferedCopyFile(*FileHandle, PakReader, Entry, Buffer, BufferSize);
					}
					else
					{
						UncompressCopyFile(*FileHandle, PakReader, Entry, PersistantCompressionBuffer, CompressionBufferSize);
					}
					UE_LOG(LogPakFile, Display, TEXT("Extracted \"%s\" to \"%s\"."), *It.Filename(), *DestFilename);
				}
				else
				{
					UE_LOG(LogPakFile, Error, TEXT("Unable to create file \"%s\"."), *DestFilename);
					ErrorCount++;
				}
			}
			else
			{
				UE_LOG(LogPakFile, Error, TEXT("Serialized hash mismatch for \"%s\"."), *It.Filename());
				ErrorCount++;
			}
		}
		FMemory::Free(Buffer);
		FMemory::Free(PersistantCompressionBuffer);

		UE_LOG(LogPakFile, Error, TEXT("Finished extracting %d files (including %d errors)."), FileCount, ErrorCount);

		return true;
	}
	else
	{
		UE_LOG(LogPakFile, Error, TEXT("Unable to open pak file \"%s\"."), InPakFilename);
		return false;
	}
}
bool FAssetStreamer::StreamPackage(const FString& PakFileName, IAssetStreamerListener* AssetStreamerListener, EAssetStreamingMode::Type DesiredMode, const TCHAR* CmdLine)
{
    Lock();
    Listener = NULL;

    const bool bRemote = (DesiredMode == EAssetStreamingMode::Remote);
    if (!(bRemote && UseRemote(CmdLine) || !bRemote && UseLocal(CmdLine)))
    {
        Unlock();
        return false;
    }
    CurrentMode = DesiredMode;
    FPlatformFileManager::Get().SetPlatformFile(*PakPlatform);

    // Now Get the path and start the streaming
    const FString FilePath = bRemote ? ResolveRemotePath(PakFileName) : ResolveLocalPath(PakFileName);

    // Make sure the Pak file is actually there
    FPakFile PakFile(*FilePath, bSigned);
    if (!PakFile.IsValid())
    {
        Unlock();
        UE_LOG(LogAsyncPackageStreamer, Error, TEXT("Invalid pak file: %s"), *FilePath);
        return false;
    }

    // TODO: Do we need to mount it into the engine dir? Creare a DLC dir instead?
    PakFile.SetMountPoint(*FPaths::EngineContentDir());
    const int32 PakOrder = 0;
    if (!PakPlatform->Mount(*FilePath, PakOrder, *FPaths::EngineContentDir()))
    {
        Unlock();
        UE_LOG(LogAsyncPackageStreamer, Error, TEXT("Failed to mount pak file: %s"), *FilePath);
        return false;
    }

    // Load all assets contained in this Pak file
    TSet<FString> FileList;
    PakFile.FindFilesAtPath(FileList, *PakFile.GetMountPoint(), true, false, true);

    // Discover assets within the PakFile
    StreamedAssets.Empty();
    for (TSet<FString>::TConstIterator FileItem(FileList); FileItem; ++FileItem)
    {
        FString AssetName = *FileItem;
        if (AssetName.EndsWith(FPackageName::GetAssetPackageExtension()) ||
            AssetName.EndsWith(FPackageName::GetMapPackageExtension()))
        {
            // TODO: Set path relative to mountpoint for remote streaming?
            StreamedAssets.Add(AssetName);
        }
    }

    // Once we started the async work assign listener
    Listener = AssetStreamerListener;

    // Tell the listener which assets we are about to stream
    if (Listener)
    {
        Listener->OnPrepareAssetStreaming(StreamedAssets);
    }

    // IF we have not yet a StreamableManager setup (Arrr...) abort
    if (StreamableManager == nullptr)
    {
        Unlock();
        UE_LOG(LogAsyncPackageStreamer, Error, TEXT("No StreamableManager registered, did you missed to call initialize?"));
        return false;
    }

    StreamableManager->RequestAsyncLoad(StreamedAssets, FStreamableDelegate::CreateRaw(this, &FAssetStreamer::OnStreamingCompleteDelegate));
    return true;
}