BOOL CPackFiles::RecurseUnpack(CFileNodePackFileNode* pcNode, char* szDestination) { CChars szFileName; CFileNodePackFileNode* pcChild; int i; CPackFileNode* pcFile; BOOL bResult; CPackFile* pcPackFile; CFileCopier cCopier; CDiskFile cDiskFile; CFileUtil cFileUtil; if (pcNode->IsDirectory()) { bResult = TRUE; for (i = 0; i < pcNode->Directory()->maNodeFiles.NumElements(); i++) { pcChild = (CFileNodePackFileNode*)pcNode->Directory()->maNodeFiles.Get(i); bResult &= RecurseUnpack(pcChild, szDestination); } return bResult; } else if (pcNode->IsFile()) { szFileName.Init(szDestination); szFileName.Append('/'); pcNode->GetFullName(&szFileName); szFileName.Replace('/', FILE_SEPARATOR[0]); pcFile = pcNode->File(); pcPackFile = PackFile(this, pcFile); if (!pcPackFile) { szFileName.Kill(); return FALSE; } cDiskFile.Init(szFileName.Text()); cFileUtil.RemoveLastFromPath(&szFileName); cFileUtil.MakeDir(szFileName.Text()); bResult = cCopier.Copy(pcPackFile, &cDiskFile); cDiskFile.Kill(); szFileName.Kill(); return bResult; } return FALSE; }
CPackFile* CFiles::GetPackFile(CPackFileOffset* pcPackFiles, char* szFullName) { CFileNodePackFileNode* pcNode; CPackFile* pcPackFile; CChars sz; sz.Init(szFullName, pcPackFiles->mszOffset.Length()+1); pcNode = pcPackFiles->mcPackFiles.GetNode(sz.Text()); sz.Kill(); if (pcNode) { pcPackFile = PackFile(&pcPackFiles->mcPackFiles, pcNode->File()); return pcPackFile; } else { return NULL; } }
CPackFile* CPackFiles::ReadOpen(char* szFileName) { CFileNodePackFileNode* pcFileNode; CPackFile* pcFile; BOOL bResult; filePos iPosition; if (meMode == PFM_Read) { pcFileNode = GetNode(szFileName); if ((pcFileNode == NULL) || (!pcFileNode->IsFile())) { return NULL; } iPosition = maReads.GetReadPos(pcFileNode->File()); if (iPosition != 0) { return NULL; } maReads.BeginReadPos(pcFileNode->File()); pcFile = PackFile(this, pcFileNode->File()); bResult = pcFile->Open(EFM_Read); if (!bResult) { return NULL; } if (mpsLastAccessed != NULL) { if (!ChangeReadFiles(pcFileNode->File())) { return NULL; } } return pcFile; } return NULL; }
PackFile* PackFile::open(const Char* path) { LASSERT(NULL != path); FILE* f = NULL; #if defined(_WIN32) || defined(_WIN64) fopen_s(&f, path, "rb"); #else f = fopen(path, "r"); #endif //lcore::Log("PackFile::open %s %s", path, (NULL==f)?"false":"true"); if(NULL == f){ return NULL; } PackHeader header; if(0>=fread(&header, sizeof(PackHeader), 1, f)){ fclose(f); return NULL; } FileEntry* entries = LIME_NEW FileEntry[header.numFiles_]; if(0>=fread(entries, sizeof(FileEntry)*header.numFiles_, 1, f)){ LIME_DELETE_ARRAY(entries); fclose(f); return NULL; } //ファイル先頭からのオフセットに変換 s32 dataTop = ftell(f); for(s32 i=0; i<header.numFiles_; ++i){ entries[i].offset_ += dataTop; } PackFile* packFile = LIME_NEW PackFile(); packFile->numFiles_ = header.numFiles_; packFile->entries_ = entries; packFile->file_ = LIME_NEW File(f); packFile->file_->addRef(); return packFile; }
CPackFile* CPackFiles::WriteOpen(char* szFileName) { CFileNodePackFileNode* pcFileNode; CPackFile* pcFile; BOOL bResult; if (mpsLastAccessed != NULL) { //Can only write to one file at a time; return NULL; } if (meMode == PFM_Write) { pcFileNode = GetNode(szFileName); if (pcFileNode != NULL) { //Can't write to an existing file. return NULL; } pcFileNode = AddFile(szFileName); if (pcFileNode) { pcFile = PackFile(this, pcFileNode->File()); bResult = pcFile->Open(EFM_Write_Create); if (!bResult) { return NULL; } mpsLastAccessed = pcFileNode->File(); return pcFile; } } return NULL; }
/* =========== CopyQFiles =========== */ void CopyQFiles (int blocknum) { int i, p; char srcfile[1024]; char destfile[1024]; char name[1024]; packheader_t header; int dirlen; unsigned short crc; // create a pak file pf = pfiles; sprintf (destfile, "%spak%i.pak", gamedir, blocknum); packhandle = SafeOpenWrite (destfile); SafeWrite (packhandle, &header, sizeof(header)); blocknum++; for (i=0 ; i<numsounds ; i++) { if (precache_sounds_block[i] != blocknum) continue; sprintf (name, "sound/%s", precache_sounds[i]); sprintf (srcfile,"%s%s",gamedir, name); PackFile (srcfile, name); } for (i=0 ; i<nummodels ; i++) { if (precache_models_block[i] != blocknum) continue; sprintf (srcfile,"%s%s",gamedir, precache_models[i]); PackFile (srcfile, precache_models[i]); } for (i=0 ; i<numfiles ; i++) { if (precache_files_block[i] != blocknum) continue; sprintf (srcfile,"%s%s",gamedir, precache_files[i]); PackFile (srcfile, precache_files[i]); } header.id[0] = 'P'; header.id[1] = 'A'; header.id[2] = 'C'; header.id[3] = 'K'; dirlen = (byte *)pf - (byte *)pfiles; header.dirofs = LittleLong(ftell (packhandle)); header.dirlen = LittleLong(dirlen); SafeWrite (packhandle, pfiles, dirlen); fseek (packhandle, 0, SEEK_SET); SafeWrite (packhandle, &header, sizeof(header)); fclose (packhandle); // do a crc of the file CRC_Init (&crc); for (i=0 ; i<dirlen ; i++) CRC_ProcessByte (&crc, ((byte *)pfiles)[i]); i = pf - pfiles; printf ("%i files packed in %i bytes (%i crc)\n",i, packbytes, crc); }