Ejemplo n.º 1
0
//将磁盘上一个目录加入到包中
bool PakMaker::addDiskFold(const char* szFoldInDisk, const char* szFoldInPak, const char* szExtFilter, bool bRecursive)
{
	assert(szFoldInDisk );
	if(!szFoldInDisk || szFoldInDisk[0]==0 ) 
	{
		setLastError(AXP_ERR_PARAM);
		return false;
	}

	//check is path exist
	if(!PathFileExists(szFoldInDisk))
	{
		setLastError(AXP_ERR_FILE_NOTFOUND, "%s", szFoldInDisk);
		return false;
	}

	//分割后缀过滤器
	std::vector< std::string > vExtFilter;
	convertStringToVector(szExtFilter, vExtFilter, ";", true, true);

	std::set< std::string > sExtFilter;
	for(int i=0; i<(int)vExtFilter.size(); i++)
	{
		sExtFilter.insert(normaliseName(vExtFilter[i], true, false));
	}

	//调用内部递归函数
	return _addDiskFold(szFoldInDisk, sExtFilter, szFoldInPak, bRecursive);
}
Ejemplo n.º 2
0
void normalizeVersion(const char* szVersion, char* szNormalizeBuf, int bufSize)
{
	std::vector< std::string > vTemp;

	//按照'.'分解
	convertStringToVector(szVersion, vTemp, ".", true, true);

	int nSecNum = min((int)vTemp.size(), 4);
	while(nSecNum < 4)
	{
		vTemp.insert(vTemp.begin(), "0");
		nSecNum++;
	}

	_snprintf(szNormalizeBuf, bufSize, "%05d.%05d.%05d.%05d", 
		atoi(vTemp[0].c_str()), atoi(vTemp[1].c_str()), atoi(vTemp[2].c_str()), atoi(vTemp[3].c_str()));
}
Ejemplo n.º 3
0
/********************************************
添加一个Patch升级包到升级操作中,后添加的后操作
*********************************************/
bool Updater::addPatchFile(const char* szPatchFile)
{
	//参数检查
	assert(szPatchFile);
	if(!szPatchFile || szPatchFile[0]==0)
	{
		setLastError(AXP_ERR_PARAM);
		return false;
	}

	//已经加入过
	if(m_mapPatchFile.find(normaliseName(szPatchFile)) != m_mapPatchFile.end()) 
	{
		//Log something...
		return true;
	}

	//打开zip文件,根据是否是加密后文件自动选择是否需要使用自定义文件读取接口
	zzip_error_t zzipError;
	ZZIP_DIR* mZzipDir = zzip_dir_open_ext_io(szPatchFile, &zzipError, 0, 
		(zzip_plugin_io_t)getEncryptZipPluginIO(szPatchFile));

	if (zzipError != ZZIP_NO_ERROR) 
	{
		setLastError(AXP_ERR_ZIPFILE, "ziperr=%d", zzipError);
		return false;
	}

	//保存zip文件句柄
	m_mapPatchFile.insert(std::make_pair(normaliseName(szPatchFile), (void*)mZzipDir));

	//打开(command)文件
	char* pCmdFile=0;
	unsigned int nCmdFileSize = 0;
	if(!_readContentsFromZip(szPatchFile, PatchMaker::PATCH_COMMAND, 0, &pCmdFile, nCmdFileSize))
		return false;

	//分解command文件
	std::vector< std::string > vCommand;
	convertStringToVector(pCmdFile, vCommand, "\r\n", true, true);

	//空的更新包文件
	if(vCommand.empty())
	{
		//Log some thing...
		return true;
	}

	//逐行分析命令
	for(int i=0; i<(int)vCommand.size(); i++)
	{
		const char* szCmdLine = vCommand[i].c_str();

		std::vector< std::string > vFileCmd;
		convertStringToVector(vCommand[i].c_str(), vFileCmd, "|", true, false);

		if(vFileCmd.size() != 3)
		{
			//Log some thing...
			continue;
		}

		UPDATE_FILE fileCmd;
		fileCmd.process = (UPDATE_PROCESS)atoi(vFileCmd[0].c_str());
		fileCmd.strPakFileName = vFileCmd[1];
		fileCmd.strFileName = vFileCmd[2];
		fileCmd.strSourceZip = szPatchFile;

		//规范后的文件名
		std::string strNorFileName = normaliseName(fileCmd.strFileName);
		std::string strNorPakFile = normaliseName(fileCmd.strPakFileName);
		const char* szNorExt = ::PathFindExtension(strNorFileName.c_str());

		//散文件
		if(fileCmd.strPakFileName.empty())
		{
			m_scatteredFiles[strNorFileName] = fileCmd;

			//如果这个文件本身是一个pak文件
			if(szNorExt && strcmp(szNorExt, PackFile::PAKFILE_EXT) == 0)
			{
				//说明该包被删除或者重新添加, 重置对该pak包的所有操作
				m_pakFiles.erase(strNorFileName);
			}
		}
		//pak包内文件
		else
		{
			//获得目前该包的操作集合
			UPDATE_PAKFILES::iterator itPak = m_pakFiles.find(strNorPakFile);
			if(itPak == m_pakFiles.end())
			{
				//尚未对该pak进行任何操作,创建
				m_pakFiles.insert(std::make_pair(strNorPakFile, UPDATE_FILES()));
				itPak = m_pakFiles.find(strNorPakFile);
			}
			assert(itPak != m_pakFiles.end());

			//加入操作
			itPak->second[strNorFileName] = fileCmd;
		}
	}

	return true;
}
Ejemplo n.º 4
0
//将加入的文件和现有的pak文件作内容比较,用于程序测试
bool PakMaker::comparePakFile(const char* szPakFileName, AXP_PAKMAKER_COMPARECALLBACK callbackFunc)
{
	assert(szPakFileName && callbackFunc);
	if(!szPakFileName || szPakFileName[0]==0 || callbackFunc==0)
	{
		setLastError(AXP_ERR_PARAM);
		return false;
	}

	//Pak文件
	PackFile pakFile;
	if(!pakFile.openPakFile(szPakFileName, true)) return false;

	//保存已经检测的文件
	typedef std::set< std::string > FILENAME_SET;
	FILENAME_SET setFileProcessed;

	//加入文件
	FileNodeBuf::iterator it;
	for(it=m_AllFiles.begin(); it!=m_AllFiles.end(); it++)
	{
		FileNode& file = it->second;
		char szTempFileName[1024] = {0};

		//打开文件
		IStream* pStream = pakFile.openFile(file.strFileInPak.c_str());

		//调用Callback
		if(!callbackFunc(file.strFileInDisk.c_str(), pStream))
		{
			setLastError(AXP_ERR_FILE_DIFF, "%s", file.strFileInPak.c_str());
			if(pStream) pStream->close();
			return false;
		}

		if(pStream)
		{
			setFileProcessed.insert(normaliseName(file.strFileInPak));
			//关闭stream
			pStream->close();
		}
	}

	//是否还有尚未检测的文件存在

	//打开List文件
	IStream* pListStream = pakFile.openFile(PackFile::LIST_FILENAME);
	if(!pListStream) return false;

	//skip first line
	pListStream->skipLine();
	
	//read second line
	char szTempLine[MAX_PATH*4] = {0};
	int nLineSize = pListStream->readLine(szTempLine, MAX_PATH*4);
	int nFileCount = atoi(szTempLine);

	while (!pListStream->eof())
	{
		int nLineLength = pListStream->readLine(szTempLine, MAX_PATH*4);
		if(0 == nLineLength) 
		{
			pListStream->close();
			setLastError(AXP_ERR_FILE_FORMAT, "list file second line=0");
			return false;
		}

		//分析文件描述
		std::vector< std::string > vStringVec;
		convertStringToVector(szTempLine, vStringVec, "|", true, false);
		if(vStringVec.size() != 3) 
		{
			pListStream->close();
			setLastError(AXP_ERR_FILE_FORMAT, "list file=%s", szTempLine);
			return false;
		}

		//获得文件信息
		if(setFileProcessed.find(normaliseName(vStringVec[0])) == setFileProcessed.end())
		{
			pListStream->close();
			setLastError(AXP_ERR_FILE_DIFF, "redufile=%s", vStringVec[0].c_str());
			return false;
		}
	}

	pListStream->close();
	return true;
}
Ejemplo n.º 5
0
//文件自检功能
bool PackFile::selfCheck(SELFCHECK_CALLBACK callBack)
{
	if(0==m_hPakFile) 
	{
		setLastError(AXP_ERR_PARAM);
		return false;
	}

	//编辑模式错误
	if(m_fileHead.nEditFlag != 0)
	{
		setLastError(AXP_ERR_FILE_EDITMODE);
		return false;
	}

	//打开List文件
	IStream* pListStream = openFile(LIST_FILENAME);
	if(!pListStream) return false;

	//skip first line
	pListStream->skipLine();

	//read second line
	char szTempLine[MAX_PATH*4] = {0};
	int nLineSize = pListStream->readLine(szTempLine, MAX_PATH*4);
	int nFileCount = atoi(szTempLine);

	//记录已经检查过的HashNode索引
	std::set< unsigned int > setHashNode;
	//记录已经检查过的BlockNode索引
	std::set< unsigned int > setBlockNode;

	//逐行读文件
	int nFileListSize = 0;
	while (!pListStream->eof())
	{
		int nLineLength = pListStream->readLine(szTempLine, MAX_PATH*4);
		if(0 == nLineLength) 
		{
			pListStream->close();
			setLastError(AXP_ERR_FILE_FORMAT, "list file second line=0");
			return false;
		}

		//分析文件描述
		std::vector< std::string > vStringVec;
		convertStringToVector(szTempLine, vStringVec, "|", true, false);
		if(vStringVec.size() != 3) 
		{
			pListStream->close();
			setLastError(AXP_ERR_FILE_FORMAT, "list file=%s", szTempLine);
			return false;
		}

		//获得文件信息
		std::string& strFileName = vStringVec[0];
		unsigned int nFileSize, nFileCRC;
		sscanf(vStringVec[1].c_str(), "%08X", &(nFileSize));
		sscanf(vStringVec[2].c_str(), "%08X", &(nFileCRC));

		//读入文件
		IStream* pFileStream = openFile(strFileName.c_str());	//打开文件
		if(!pFileStream)
		{
			pListStream->close();
			return false;
		}

		unsigned int nStreamSize = pFileStream->size();
		if(nStreamSize != nFileSize)
		{
			pFileStream->close();
			pListStream->close();
			setLastError(AXP_ERR_FILE_FORMAT, "file=%s, sizedif(%d!=%d)", 
				strFileName.c_str(), nStreamSize, nFileSize);
			return false;
		}

		char* pTempBuf = new char[nStreamSize];
		if(nStreamSize != pFileStream->read(pTempBuf, nStreamSize))
		{
			pFileStream->close();
			pListStream->close();
			setLastError(AXP_ERR_FILE_READ, "file=%s", strFileName.c_str());
		}
		pFileStream->close(); pFileStream=0;

		//计算文件实际crc
		unsigned int  nStreamCRC;
		crcMemory32(pTempBuf, nStreamSize, nStreamCRC);
		delete[] pTempBuf; pTempBuf=0;

		if(nStreamCRC != nFileCRC)
		{
//			pFileStream->close();
			pListStream->close();
			setLastError(AXP_ERR_FILE_FORMAT, "file=%s, crcdif(%d!=%d)", 
				strFileName.c_str(), nStreamCRC, nFileCRC);
			return false;
		}

		//保存分析过的文件Hash和Block数据

		//得到Hash数据
		int nHashPos = getStringPosInHashTable(normaliseName(strFileName).c_str());
		setHashNode.insert(nHashPos);

		//得到Block数据
		unsigned int nBlockIndex = getHashNodeBlockIndex(m_hashTable[nHashPos]);
		setBlockNode.insert(nBlockIndex);

		nFileListSize++;
	};
	pListStream->close(); pListStream=0;

	//文件个数检查
	if(nFileListSize != nFileCount)
	{
		setLastError(AXP_ERR_FILE_FORMAT, "file countdif(%d!=%d)", nFileListSize, nFileCount);
		return false;
	}

	//得到(list)的Hash数据
	int nListFileHashPos = getStringPosInHashTable(LIST_FILENAME);
	//得到(list)的Block数据
	unsigned int nListFileBlockIndex = getHashNodeBlockIndex(m_hashTable[nListFileHashPos]);

	//检查是否有未引用的Hash数据
	for(int i=0; i<HASH_TABLE_SIZE; i++)
	{
		const FILE_HASHNODE& hashNode = m_hashTable[i];
		if(!getHashNodeExists(hashNode)) continue;

		if(setHashNode.find(i) != setHashNode.end()) continue;
		if(i==nListFileHashPos) continue;

		//未引用的Hash数据
		setLastError(AXP_ERR_FILE_FORMAT, "unref hashnode(%d)", i);
		return false;
	}

	//检查是否有未引用的BlockNode数据
	for(int i=0; i<(int)m_blockTable.size(); i++)
	{
		const FILE_BLOCKNODE& blockNode = m_blockTable[i];
		if(!getBlockNodeUsed(blockNode)) continue;
		if(setBlockNode.find(i) != setBlockNode.end()) continue;
		if(i==nListFileBlockIndex) continue;

		//未引用的Hash数据
		setLastError(AXP_ERR_FILE_FORMAT, "unref blocknode(%d)", i);
		return false;
	}

	return true;
}