#include "PatchClient.h" #include "Configuration.h" #include #include #include #include #include "zlib.h" #include "BtClient.h" #pragma comment(lib, "Psapi.lib") GSEINIT_SYSTEM(GSEERROR_SCREEN_MASK); GSEINIT_COMMUNICATION(); #define MB (1024 * 1024) CPatchClient::CPatchClient(CPatchCliEvent* pPatchCliEvent) : m_PatchCliEvent(pPatchCliEvent), m_CurPartFile(NULL), m_TcpClient(NULL), m_PatchConnected(false) { m_PatchHash.clear(); m_PatchSession.SetOwner(this); m_TcpClient = GSECCreateApplicationClient(&m_PatchSession, GSECOMMUNICATION_SELECT); m_InBuf = GSEMemNew CCircularBuf(MAX_NET_BUF); m_OutBuf = GSEMemNew CCircularBuf(MAX_NET_BUF); m_Thread = 0; m_LauncherProcessID = 0; m_bPrep = false; m_PrepDownloadCtrl = NULL; m_CanDoPrepDownload = false; m_DownloadEvent = NULL; m_IsInit = false; m_ClientState = INVALID_STATE; m_InitiativeBroken = false; m_NeedUpateLauncher = true; m_pBtClient = NULL; m_TaskID = 0; m_BtFileSize = 0; } CPatchClient::CPatchClient(CDownloadEvent* pDownloadEvent) { m_PatchSession.SetOwner(this); m_PatchCliEvent = NULL; m_TcpClient = GSECCreateApplicationClient(&m_PatchSession, GSECOMMUNICATION_SELECT); m_InBuf = GSEMemNew CCircularBuf(MAX_NET_BUF); m_OutBuf = GSEMemNew CCircularBuf(MAX_NET_BUF); m_DownloadEvent = pDownloadEvent; m_IsInit = false; m_ClientState = INVALID_STATE; m_InitiativeBroken = false; m_NeedUpateLauncher = false; m_pBtClient = NULL; m_TaskID = 0; m_BtFileSize = 0; } CPatchClient::~CPatchClient() { if (m_PatchConnected) { m_TcpClient->Disconnect(); } if (m_TcpClient) { GSECDestroyApplication(m_TcpClient); m_TcpClient = NULL; } if (m_InBuf) { GSEMemDelete m_InBuf; } if (m_OutBuf) { GSEMemDelete m_OutBuf; } m_ClientState = INVALID_STATE; } int CPatchClient::StartUp(const char* szIp, unsigned short usPort, bool bPrep) { m_IsInit = true; m_NeedUpateLauncher = true; m_InitiativeBroken = false; if (bPrep) { m_PrepDownloadCtrl = GSEMemNew CPrepDownloadCtrl(*this); m_PrepDownloadCtrl->Start(); } m_CanDoPrepDownload = bPrep; m_PatchIp = szIp; m_PatchPort = usPort; m_bPrep = bPrep; SetCurPorcessID(); RegisterHandler(); //通知客户端版本号 m_CliVersion = g_Configuration.m_CliVersion; m_PatchCliEvent->OnCliVersion(m_CliVersion); m_PatchList.clear(); m_PatchSession.SetFlag(); m_Thread = GSECreateThread(this, false); //创建业务处理线程 if (_access(g_Configuration.GetPatchDir().c_str(), 0)) { _mkdir(g_Configuration.GetPatchDir().c_str()); } //创建网络线程 return 0; } int CPatchClient::CleanUp() { m_InitiativeBroken = true; if (!m_IsInit) { return 0; } if (m_bPrep) { m_PrepDownloadCtrl->Stop(); GSEMemDelete m_PrepDownloadCtrl; m_PrepDownloadCtrl = NULL; } m_PatchSession.Quit(); if (m_pBtClient) { if (m_TaskID > 0) { m_pBtClient->EndTask(m_TaskID); m_pBtClient->Stop(); delete m_pBtClient; m_pBtClient = NULL; } } GSEDestroyThread(m_Thread); m_Thread = 0; m_HandlerMap.clear(); m_IsInit = false; return 0; } int CPatchClient::ReqServerVersion() { //先请求BtServer信息 ReqBtServerInfo(); //请求服务器版本信息 PatchServer::CPServerVersionReq cpServerVersionReq; memset(&cpServerVersionReq, 0, sizeof(PatchServer::CPServerVersionReq)); if (m_bPrep) { cpServerVersionReq.Version.VersionMajor = 0; cpServerVersionReq.Version.VersionMin = 0; cpServerVersionReq.Version.VersionAddition = 0; } else { cpServerVersionReq.Version.VersionMajor = g_Configuration.m_CliVersion.MajorVersion; cpServerVersionReq.Version.VersionMin = g_Configuration.m_CliVersion.MinVersion; cpServerVersionReq.Version.VersionAddition = g_Configuration.m_CliVersion.AdditionVersion; } //发送到服务器 char* pPack = GSEMemAlloc(char, sizeof(PatchServer::CPServerVersionReq) + sizeof(MSGHEADER)); PMSGHEADER pmsgHeader = reinterpret_cast(pPack); PatchServer::CPServerVersionReq* pCPServerVersionReq = reinterpret_cast(pPack + sizeof(MSGHEADER)); size_t nEnCodeLen = m_Protocol.EnCode(cpServerVersionReq.wCmd, &cpServerVersionReq, (char*)pCPServerVersionReq, sizeof(cpServerVersionReq)); if (nEnCodeLen == -1) { GSEMemFree(pPack); return 0; } pmsgHeader->PackCmd = PatchServer::CPServerVersionReq::wCmd; pmsgHeader->PackType = 0; pmsgHeader->PackLen = nEnCodeLen + sizeof(MSGHEADER); m_SendQue.push_back(pPack); return 0; } int CPatchClient::RegisterHandler() { m_HandlerMap[PatchServer::PCServerVersionResp::wCmd] = MSGHANDLER(&CPatchClient::ProcServerVersion); m_HandlerMap[PatchServer::PCPatchFileInfoResp::wCmd] = MSGHANDLER(&CPatchClient::ProcPatchFileInfoResp); m_HandlerMap[PatchServer::PCDownloadResp::wCmd] = MSGHANDLER(&CPatchClient::ProcDownloadData); m_HandlerMap[PatchServer::PCDownloadFile::wCmd] = MSGHANDLER(&CPatchClient::ProcDownloadFile); m_HandlerMap[PatchServer::PCLauncherVersionInfo::wCmd] = MSGHANDLER(&CPatchClient::ProcLauncherVersionInfo); m_HandlerMap[PatchServer::PCBtServerInfo::wCmd] = MSGHANDLER(&CPatchClient::ProcBtServerInfo); m_HandlerMap[PatchServer::PCTorrentInfoResp::wCmd] = MSGHANDLER(&CPatchClient::ProcTorrentInfo); m_HandlerMap[PatchServer::PCCliVerifyResp::wCmd] = MSGHANDLER(&CPatchClient::ProcCliVerifyInfo); m_HandlerMap[PatchServer::PCFileInfoResp::wCmd] = MSGHANDLER(&CPatchClient::ProcFileInfoResp); return 0; } //处理服务器返回的版本信息 int CPatchClient::ProcServerVersion(char* pData, unsigned short usDataLen) { DealPlayerPkgPre(PatchServer::PCServerVersionResp, pPCServerVersionResp, pData, usDataLen, m_Protocol); m_SvrVersion.MajorVersion = pPCServerVersionResp->Version.VersionMajor; m_SvrVersion.MinVersion = pPCServerVersionResp->Version.VersionMin; m_SvrVersion.AdditionVersion = pPCServerVersionResp->Version.VersionAddition; m_PatchList.clear(); for (int nIndex = 0; nIndex < pPCServerVersionResp->PatchNum; nIndex++) { CPatchVersion patchVersion(pPCServerVersionResp->PatchList[nIndex].VersionMajor, pPCServerVersionResp->PatchList[nIndex].VersionMin , pPCServerVersionResp->PatchList[nIndex].VersionAddition); m_PatchList.push_back(patchVersion); string strHash; strHash.append((char*)pPCServerVersionResp->PatchList[nIndex].FileHash.HashValue, pPCServerVersionResp->PatchList[nIndex].FileHash.HashLen); m_PatchHash.push_back(strHash); } /* 在服务器返回的补丁包中,开始认为是都要下载的,所以需要遍历下载目录,如果发现该补丁已经下载过了,需要把补丁进行hash,并且发送到服务器进行验证,如果验证也正确,则认为这个包可以安装 否则,都认为需要下载 */ for (size_t nIndex = 0; nIndex < m_PatchList.size(); nIndex++) { CPatchVersion patchVersion = m_PatchList[nIndex]; string strFileName(patchVersion.VersionToFileName()); if (IsPatchExist((strFileName + PATCHFILE_POST).c_str())) { //检查是否是未下载完成的文件,如果是,放进下载列表中 if (!IsPatchExist((strFileName + DOWNLOAD_POST).c_str())) { VerifyHash(nIndex); } else { m_DownloadQue.push_back(patchVersion); } } else { //放进下载列表 m_DownloadQue.push_back(patchVersion); } } if (m_bPrep) { m_PatchCliEvent->OnServerVersion(m_SvrVersion, m_DownloadQue.size()); } else { m_PatchCliEvent->OnServerVersion(m_SvrVersion, pPCServerVersionResp->PatchNum); } return 0; } //在发现版本不一致时调用 int CPatchClient::CheckVersion() { if (m_SvrVersion.MajorVersion == m_CliVersion.MajorVersion && m_SvrVersion.MinVersion == m_CliVersion.MinVersion && m_SvrVersion.AdditionVersion == m_CliVersion.AdditionVersion) { //版本已经是最新的 return 0; } if (m_DownloadQue.size() == 0) { if (!m_bPrep) { UpdateVersion(); } } else { StartDownload(); } if (m_DownloadQue.size() != 0 && m_bPrep) { return MUXPREPPATCH_HAVEPATCH; } return 0; } int CPatchClient::StartDownload() { if (m_DownloadQue.size() == 0) { return 0; } PATCHVERSION patchVersion; m_DownloadQue[0].GetVersionInfo(patchVersion.MajorVersion, patchVersion.MinVersion, patchVersion.AdditionVersion); m_CurPartFile = GSEMemNew CPartFile(m_DownloadQue[0], *this); m_CurPartFile->InitDownload(); //if (m_pBtClient) //{ // ReqTorrentInfo(m_DownloadQue[0]); //} //else //{ // //选择第一个补丁进行下载 // PATCHVERSION patchVersion; // m_DownloadQue[0].GetVersionInfo(patchVersion.MajorVersion, patchVersion.MinVersion, patchVersion.AdditionVersion); // m_CurPartFile = GSEMemNew CPartFile(m_DownloadQue[0], *this); // m_CurPartFile->InitDownload(); //} return 0; } bool CPatchClient::IsPatchExist(const char *szFileName) { char szBuf[MAX_FILE_NAME]; getcwd(szBuf, MAX_FILE_NAME); chdir(g_Configuration.GetPatchDir().c_str()); _finddata_t c_filedata; long hFile =_findfirst(szFileName, &c_filedata); bool bExist = hFile != -1; _findclose(hFile); chdir(szBuf); return bExist; } bool VersionCmp (CPatchVersion Version, CPatchVersion Version2 ) { return Version < Version2; } int CPatchClient::UpdateVersion() { //断掉与服务器的连接 m_PatchSession.Quit(); ::sort(m_UpdateQue.begin(), m_UpdateQue.end(), VersionCmp); //为线程创建消息队列 MSG msg; bool bRet = PeekMessage(&msg, NULL, 0, 0, PM_NOREMOVE); for (size_t nIndex = 0; nIndex < m_UpdateQue.size(); nIndex++) { CPatchVersion patchVersion = m_UpdateQue[nIndex]; string strFileName = patchVersion.VersionToFileName(); string strFullFileName = g_Configuration.GetPatchDir() + PATH_DELIMITER + strFileName + PATCHFILE_POST; int nRet = ProcUpdateMsg(nIndex, patchVersion, strFullFileName.c_str()); if (nRet) { break; } } m_UpdateQue.clear(); return 0; } int CPatchClient::ProcUpdateMsg(int nIndex, CPatchVersion patchVersion, const char* szPatchFileName) { float fPercent = 1.00 / m_UpdateQue.size(); float fBaseStage = nIndex * fPercent; int nSpan = 0; PATCHVERSION PatchVersion; patchVersion.GetVersionInfo(PatchVersion.MajorVersion, PatchVersion.MinVersion, PatchVersion.AdditionVersion); MSG msg; HANDLE hUpdateProcess = NULL; bool bNormalExit = false; int nWaitCount = 0; while (true) { bool bRet = PeekMessage(&msg, NULL, 0, 0, PM_REMOVE); if (bRet) { switch(msg.message) { case WM_MUXPATCHUPDATE: { //m_PatchCliEvent->OnInstallProgress(PatchVersion, WM_MUXPATCHUPDATE, msg.lParam); } break; case MUXPATCH_UPDATE_INIT: { nSpan = (int)((fBaseStage + fPercent * msg.lParam * 0.25 / 100.00f) * 100); m_PatchCliEvent->OnInstallProgress(PatchVersion, MUXPATCH_UPDATE_INIT, nSpan); } break; case MUXPATCH_UPDATE_PATCHING: { nSpan = (int)((fBaseStage + fPercent * (1 + msg.lParam / 100.00f) * 0.25) * 100); m_PatchCliEvent->OnInstallProgress(PatchVersion, MUXPATCH_UPDATE_PATCHING, nSpan); } break; case MUXPATCH_UPDATE_FINISHING: { nSpan = (int)((fBaseStage + fPercent * (2 + msg.lParam / 100.00f) * 0.25) * 100); m_PatchCliEvent->OnInstallProgress(PatchVersion, MUXPATCH_UPDATE_FINISHING, nSpan); } break; case MUXPATCH_FINISH: { nSpan = (int)((fBaseStage + fPercent * (3 + msg.lParam / 100.00f) * 0.25) * 100); m_PatchCliEvent->OnInstallProgress(PatchVersion, MUXPATCH_FINISH, nSpan); bNormalExit = true; if (hUpdateProcess) { if (WaitForSingleObject(hUpdateProcess, INFINITE) == WAIT_OBJECT_0) { CloseHandle(hUpdateProcess); return 0; } } } break; case MUXPATCH_ERROR_INIT: case MUXPATCH_ERROR_CONTENTVERSION: case MUXPATCH_ERROR_UPDATEFAIL: case MUXPATCH_ERROR_FINISHING: case MUXPATCH_ERROR_ALREADYEXIST: { bNormalExit = true; m_PatchCliEvent->OnError(msg.message); if (hUpdateProcess) { if (WaitForSingleObject(hUpdateProcess, 10000) == WAIT_OBJECT_0) { CloseHandle(hUpdateProcess); return -1; } else { TerminateProcess(hUpdateProcess, 0); CloseHandle(hUpdateProcess); return -1; } } } break; default: break; } } else if(!hUpdateProcess) { STARTUPINFO si; PROCESS_INFORMATION pi; memset(&si, 0, sizeof(si)); si.cb = sizeof(si); memset(&pi, 0, sizeof(pi)); char szCmdLine[MAX_PATH]; char szCurDir[MAX_PATH]; _getcwd(szCurDir, MAX_PATH); sprintf(szCmdLine, "\"%s\" \"%s/%u/%u\"", szPatchFileName, szCurDir, GetCurrentThreadId(), m_LauncherProcessID); if (CreateProcess(NULL, szCmdLine, NULL, NULL, FALSE, NORMAL_PRIORITY_CLASS, NULL, NULL, &si, &pi)) { hUpdateProcess = pi.hProcess; CloseHandle(pi.hThread); } else { DWORD dwErrCode = GetLastError(); ::MessageBox(NULL, "启动补丁进程失败", "Failed", MB_OK); return 0; } } else { if (WaitForSingleObject(hUpdateProcess, 1000) == WAIT_OBJECT_0) { if (!bNormalExit) { if (nWaitCount >= 10) { CloseHandle(hUpdateProcess); hUpdateProcess = NULL; nWaitCount = 0; m_PatchCliEvent->OnError(MUXPATCH_ERROR_UPDATEFAIL); return -1; } Sleep(100); nWaitCount++; } } } } return 0; } int CPatchClient::ReqPatchFileInfo(CPatchVersion patchVersion) { PatchServer::CPPatchFileInfoReq cpPatchFileInfoReq; patchVersion.GetVersionInfo(cpPatchFileInfoReq.Version.VersionMajor, cpPatchFileInfoReq.Version.VersionMin, cpPatchFileInfoReq.Version.VersionAddition); cpPatchFileInfoReq.Version.FileHash.HashLen = MAX_HASHVALUE_LEN; //cpPatchFileInfoReq.Version.FileHash.HashValue //向服务器发送消息 char* pPack = GSEMemAlloc(char, sizeof(PatchServer::CPPatchFileInfoReq) + sizeof(MSGHEADER)); PMSGHEADER pmsgHeader = reinterpret_cast(pPack); PatchServer::CPPatchFileInfoReq* pCPPatchFileInfoReq = reinterpret_cast(pPack + sizeof(MSGHEADER)); size_t nEnCodeLen = m_Protocol.EnCode(cpPatchFileInfoReq.wCmd, &cpPatchFileInfoReq, (char*)pCPPatchFileInfoReq, sizeof(cpPatchFileInfoReq)); if (nEnCodeLen == -1) { GSEMemFree(pPack); return 0; } pmsgHeader->PackCmd = PatchServer::CPPatchFileInfoReq::wCmd; pmsgHeader->PackType = 0; pmsgHeader->PackLen = nEnCodeLen + sizeof(MSGHEADER); m_SendQue.push_back(pPack); return 0; } int CPatchClient::ProcPatchFileInfoResp(char* pData, unsigned short usDataLen) { DealPlayerPkgPre(PatchServer::PCPatchFileInfoResp, pPCPatchFileInfoResp, pData, usDataLen, m_Protocol); if (m_CurPartFile) { CPatchVersion patchVersion(pPCPatchFileInfoResp->Version.VersionMajor, pPCPatchFileInfoResp->Version.VersionMin, pPCPatchFileInfoResp->Version.VersionAddition); m_CurPartFile->SetPatchInfo(patchVersion, pPCPatchFileInfoResp->FileSize, (uint8*)pPCPatchFileInfoResp->FileHash.HashValue); for (int nIndex = 0; nIndex < pPCPatchFileInfoResp->HashCount; nIndex++) { m_CurPartFile->AddPartHash((uint8*)pPCPatchFileInfoResp->PartHash[nIndex].HashValue); } m_CurPartFile->OnPartComplete(); } else { //报告错误 } return 0; } int CPatchClient::VerifyHash(int nIndex) { CPatchVersion patchVersion = m_PatchList[nIndex]; string strFileName(g_Configuration.GetPatchDir() + PATH_DELIMITER + patchVersion.VersionToFileName() + PATCHFILE_POST); CPatchFile patchFile(strFileName.c_str()); patchFile.LoadPatchFile(strFileName.c_str()); if (memcmp(patchFile.GetFileKeys()->GetFileKey()->GetKey(), m_PatchHash[nIndex].c_str(), MAX_HASHVALUE_LEN) != 0) { //因为Hash值不同,表示本地文件已经损坏,进入下载列表 m_DownloadQue.push_back(patchVersion); } else { m_UpdateQue.push_back(patchVersion); } return 0; } int CPatchClient::OnPatchConnected() { m_LastSendTime = time(NULL); m_PatchConnected = true; m_ClientState = CONNECTED_STATE; //验证Luancher版本 if (m_NeedUpateLauncher) { ReqLauncherVersion(0); } return 0; } int CPatchClient::OnPatchClose() { m_PatchConnected = false; if (!m_InitiativeBroken) { m_InitiativeBroken = true; m_PatchSession.Quit(); m_PatchCliEvent->OnError(MUXPATCH_DOWNLOAD_NETBREAKDOWN); } return 0; } int CPatchClient::OnError(int nErrCode) { return 0; } int CPatchClient::OnInitRecv(char *&pszBuf, int &nLen) { pszBuf = m_InBuf->GetWritePtr(); nLen = m_InBuf->GetContiguousFreeSize(1); return 0; } int CPatchClient::OnInitSend(char *&pszBuf, int &nLen) { { //GSEGuard gseGuard(&m_SendQueLock); //把要发送的数据写入Out缓冲区中 while (m_SendQue.size() > 0) { char* pData = m_SendQue.front(); PMSGHEADER pmsgHeader = reinterpret_cast(pData); if (pmsgHeader->PackLen > m_OutBuf->GetFreeSize()) { break; } m_OutBuf->WriteData(pData, pmsgHeader->PackLen); GSEMemFree(pData); m_SendQue.pop_front(); } } //通知网络模块要发送的数据 pszBuf = m_OutBuf->GetReadPtr(); nLen = m_OutBuf->GetContiguousFreeSize(0); return 0; } bool CPatchClient::OnReadMask() { return true; } bool CPatchClient::OnWriteMask() { HeatBeat(); if (m_pBtClient) { m_pBtClient->DoEvents(); if (m_TaskID > 0) { if (GetTickCount() - m_LastBtTime > 500) { m_LastBtTime = GetTickCount(); P2PTaskInfo p2pTaskInfo; m_pBtClient->GetTaskInfo(m_TaskID, p2pTaskInfo); int nIndex = m_UpdateQue.size() + 1; float fPos = p2pTaskInfo.fPercent; float fFileSize = m_BtFileSize * 1.0f / MB; if (fFileSize < 0.1) { fFileSize = 0.1; } PATCHVERSION patchVersion; m_DownloadQue[0].GetVersionInfo(patchVersion.MajorVersion, patchVersion.MinVersion, patchVersion.AdditionVersion); //经测试得知,nstate为2 正在验证上次没有下载完的文件,3为正在下载 if (p2pTaskInfo.nState == 3) { m_PatchCliEvent->OnDownloadProgress(patchVersion, nIndex, (int)fPos, 0, 0, fFileSize); } //已经下载完成 if (p2pTaskInfo.n64TotalDownSize == m_BtFileSize) { m_pBtClient->EndTask(m_TaskID); m_TaskID = 0; m_LastBtTime = 0; m_BtFileSize = 0; m_UpdateQue.push_back(m_DownloadQue[0]); m_DownloadQue.erase(m_DownloadQue.begin()); if (m_DownloadQue.size() > 0) { StartDownload(); } else if (!m_bPrep) { UpdateVersion(); } } } } P2PNatInfo p2pNatInfo; m_pBtClient->GetNatInfo(p2pNatInfo); } if(m_CurPartFile && m_CurPartFile->IsSaved()) { if (m_CurPartFile->OnComplete() == 0) { m_UpdateQue.push_back(m_CurPartFile->GetDownloadVerson()); //从下载队列中删除 assert(m_DownloadQue.size() != 0); assert(m_DownloadQue[0] == m_CurPartFile->GetDownloadVerson()); m_DownloadQue.erase(m_DownloadQue.begin()); } GSEMemDelete m_CurPartFile; m_CurPartFile = NULL; if (m_DownloadQue.size() != 0) { StartDownload(); } else if (!m_bPrep) { UpdateVersion(); } } return m_OutBuf->GetContiguousFreeSize(0) > 0 || m_SendQue.size() > 0; } int CPatchClient::OnRecv(char *pszData, int nLen) { m_InBuf->UpdateWrite(nLen); ParseData(); return 0; } int CPatchClient::OnSend(char* pszData, int nLen) { m_LastSendTime = time(NULL); m_OutBuf->UpdateRead(nLen); return 0; } int CPatchClient::ParseData() { while (m_InBuf->GetUsedSize() >= sizeof(MSGHEADER)) { MSGHEADER msgHeader; m_InBuf->SoftReadData((char*)&msgHeader, sizeof(MSGHEADER)); if (msgHeader.PackLen <= m_InBuf->GetUsedSize()) { char* pData = GSEMemAlloc(char, msgHeader.PackLen); memset(pData, 0, msgHeader.PackLen); m_InBuf->ReadData(pData, msgHeader.PackLen); ProcData(pData); GSEMemFree(pData); } else { break; } } return 0; } int CPatchClient::ProcData(char* pData) { int nRet = 0; PMSGHEADER pmsgHeader = reinterpret_cast(pData); HANDLERMAP::iterator Ite = m_HandlerMap.find(pmsgHeader->PackCmd); if (Ite != m_HandlerMap.end()) { nRet = (this->*Ite->second.handler)(pData + sizeof(MSGHEADER), pmsgHeader->PackLen - sizeof(MSGHEADER)); } return nRet; } int CPatchClient::Download() { if (m_bPrep && !m_CanDoPrepDownload) { return 0; } PATCHVERSION patchVersion; m_CurPartFile->GetDownloadVerson().GetVersionInfo(patchVersion.MajorVersion, patchVersion.MinVersion, patchVersion.AdditionVersion); uint32 nStartPos, nEndPos; m_CurPartFile->GetDownloadPos(nStartPos, nEndPos); int nIndex = m_UpdateQue.size() + 1; float fPos = m_CurPartFile->GetTransferSize() * 100.00f / m_CurPartFile->GetFileSize(); float fFileSize = m_CurPartFile->GetFileSize() * 1.0f / MB; if (fFileSize < 0.1) { fFileSize = 0.1; } m_PatchCliEvent->OnDownloadProgress(patchVersion, nIndex, (int)fPos, 0, 0, fFileSize); //未下载完 if (nStartPos != nEndPos) { PatchServer::CPDownloadReq cpDownloadReq; m_CurPartFile->GetDownloadVerson().GetVersionInfo(cpDownloadReq.Version.VersionMajor, cpDownloadReq.Version.VersionMin, cpDownloadReq.Version.VersionAddition); cpDownloadReq.Version.FileHash.HashLen = MAX_HASHVALUE_LEN; //memcpy(cpDownloadReq.Version.FileHash.HashValue, m_CurPartFile->) cpDownloadReq.StartPos = nStartPos; cpDownloadReq.EndPos = nEndPos; //向服务器发送消息 char* pPack = GSEMemAlloc(char, sizeof(PatchServer::CPDownloadReq) + sizeof(MSGHEADER)); PMSGHEADER pmsgHeader = reinterpret_cast(pPack); PatchServer::CPDownloadReq* pCPDownloadReq = reinterpret_cast(pPack + sizeof(MSGHEADER)); size_t nEnCodeLen = m_Protocol.EnCode(cpDownloadReq.wCmd, &cpDownloadReq, (char*)pCPDownloadReq, sizeof(PatchServer::CPDownloadReq)); if (nEnCodeLen == -1) { GSEMemFree(pPack); return 0; } pmsgHeader->PackCmd = PatchServer::CPDownloadReq::wCmd; pmsgHeader->PackType = 0; pmsgHeader->PackLen = nEnCodeLen + sizeof(MSGHEADER); m_SendQue.push_back(pPack); } return 0; } int CPatchClient::ProcDownloadData(char* pData, unsigned short usDataLen) { DealPlayerPkgPre(PatchServer::PCDownloadResp, pPCDownloadResp, pData, usDataLen, m_Protocol); if (m_CurPartFile) { PMSGHEADER pmsgHeader = (PMSGHEADER)(pData - sizeof(MSGHEADER)); char szBuf[MAX_PATCHDATALEN]; uint32 nRealDataLen = MAX_PATCHDATALEN; if (pmsgHeader->PackType != 0) { int nUncompressRet = uncompress((Bytef*)szBuf, (uLongf*)&nRealDataLen, (Bytef*)pPCDownloadResp->PatchData, (uLongf)pPCDownloadResp->DataLen); if (nUncompressRet != Z_OK) { memcpy(szBuf, pPCDownloadResp->PatchData, pPCDownloadResp->DataLen); nRealDataLen = pPCDownloadResp->DataLen; } } else { memcpy(szBuf, pPCDownloadResp->PatchData, pPCDownloadResp->DataLen); nRealDataLen = pPCDownloadResp->DataLen; } m_CurPartFile->UpdateDownload(pPCDownloadResp->StartPos, nRealDataLen, szBuf); Download(); } else { //报告错误 } return 0; } void CPatchClient::ThreadProc() { //建立连接 if (!m_PatchConnected) { try { m_TcpClient->Connect(m_PatchIp.c_str(), m_PatchPort); } catch (GSEException&) { m_PatchCliEvent->OnError(MUXPATCH_DOWNLOAD_SERVERNOTFOUND); } } } void CPatchClient::Terminate() { } int CPatchClient::ProcError(char* pData, unsigned short usDataLen) { DealPlayerPkgPre(PatchServer::PCError, pPCError, pData, usDataLen, m_Protocol); m_PatchCliEvent->OnError(MUXPATCH_DOWNLOAD_PATCHNOTFOUND); return 0; } int CPatchClient::GetServerInfo() { HINTERNET hInternet = NULL; //查询http代理情况 DWORD dwOptLen = 0; BOOL bSucc = InternetQueryOption(NULL, INTERNET_OPTION_PROXY, NULL, &dwOptLen); if (dwOptLen > 0) { char* pData = new char[dwOptLen]; memset(pData, 0, dwOptLen); InternetQueryOption(NULL, INTERNET_OPTION_PROXY, pData, &dwOptLen); INTERNET_PROXY_INFO* pProxyInfo = reinterpret_cast(pData); if (pProxyInfo->dwAccessType == INTERNET_OPEN_TYPE_PROXY) { hInternet = InternetOpen("PatchClient/1.0", INTERNET_OPEN_TYPE_PROXY, pProxyInfo->lpszProxy, pProxyInfo->lpszProxyBypass, 0); } else { hInternet = InternetOpen("PatchClient/1.0", pProxyInfo->dwAccessType, NULL, NULL, 0); } delete [] pData; } if (hInternet == NULL) { return -1; } //代理用户名 InternetQueryOption(NULL, INTERNET_OPTION_PROXY_USERNAME, NULL, &dwOptLen); if (dwOptLen > 0) { char* pData = new char[dwOptLen]; memset(pData, 0, dwOptLen); InternetQueryOption(NULL, INTERNET_OPTION_PROXY_USERNAME, pData, &dwOptLen); if (dwOptLen > 0) { InternetSetOption(hInternet, INTERNET_OPTION_PROXY_USERNAME, pData, dwOptLen); } delete [] pData; } //代理密码 InternetQueryOption(NULL, INTERNET_OPTION_PROXY_PASSWORD, NULL, &dwOptLen); if (dwOptLen > 0) { char* pData = new char[dwOptLen]; memset(pData, 0, dwOptLen); InternetQueryOption(hInternet, INTERNET_OPTION_PROXY_PASSWORD, pData, &dwOptLen); if (dwOptLen > 0) { InternetSetOption(hInternet, INTERNET_OPTION_PROXY_PASSWORD, pData, dwOptLen); } delete [] pData; } HINTERNET hSession = InternetOpenUrl(hInternet, g_Configuration.m_HttpAddr.c_str(), NULL, 0, INTERNET_FLAG_RELOAD, 0); if (hSession == NULL) { InternetCloseHandle(hInternet); return -1; } DWORD dwHttpStatus = 0; DWORD dwHttpStatusSize = sizeof(dwHttpStatus); if (!HttpQueryInfo(hSession, HTTP_QUERY_STATUS_CODE | HTTP_QUERY_FLAG_NUMBER, &dwHttpStatus, &dwHttpStatusSize, 0)) { InternetCloseHandle(hSession); InternetCloseHandle(hInternet); return -1; } if (dwHttpStatus != HTTP_STATUS_OK) { InternetCloseHandle(hSession); InternetCloseHandle(hInternet); return -1; } DWORD dwTotalBytes = 0; if (!InternetQueryDataAvailable(hSession, &dwTotalBytes, 0, 0)) { DWORD dwErr = GetLastError(); InternetCloseHandle(hSession); InternetCloseHandle(hInternet); return -1; } FILE* pFile = NULL; pFile = fopen(".\\ServerConfig.xml", "w+b"); if (!pFile) { InternetCloseHandle(hSession); InternetCloseHandle(hInternet); return -1; } char szBuf[1024]; DWORD dwRead = 0; while (true) { if (!InternetReadFile(hSession, szBuf, sizeof(szBuf), &dwRead)) { break; } if (dwRead == 0) { break; } fwrite(szBuf, dwRead, 1, pFile); } fclose(pFile); InternetCloseHandle(hSession); InternetCloseHandle(hInternet); //解析下载的文件 g_Configuration.LoadServerConfig(); remove(".\\ServerConfig.xml"); return 0; } PCATINFO CPatchClient::GetCatInfo(unsigned char& ucNum) { PCATINFO pCatInfo = NULL; ucNum = g_Configuration.m_CatInfos.size(); if (ucNum == 0) { return pCatInfo; } pCatInfo = new CATINFO[ucNum]; memset(pCatInfo, 0, ucNum * sizeof(CATINFO)); for (int nIndex = 0; nIndex < ucNum; nIndex++) { pCatInfo[nIndex].nCatID = g_Configuration.m_CatInfos[nIndex].nCatID; strcpy(pCatInfo[nIndex].szCatName, g_Configuration.m_CatInfos[nIndex].szCatName); } return pCatInfo; } PAREAINFO CPatchClient::GetAreaInfo(unsigned int nCatID, unsigned char &ucNum) { PAREAINFO pAreaInfo = NULL; vector vectAreaInfo; for (size_t nIndex = 0; nIndex < g_Configuration.m_AreasInfo.size(); nIndex++) { if (g_Configuration.m_AreasInfo[nIndex].nCatID == nCatID) { vectAreaInfo.push_back(g_Configuration.m_AreasInfo[nIndex]); } } ucNum = vectAreaInfo.size(); if (ucNum == 0) { return pAreaInfo; } pAreaInfo = new AREAINFO[ucNum]; memset(pAreaInfo, 0, ucNum * sizeof(AREAINFO)); for (size_t nIndex = 0; nIndex < vectAreaInfo.size(); nIndex++) { pAreaInfo[nIndex].nCatID = nCatID; pAreaInfo[nIndex].nAreaID = vectAreaInfo[nIndex].nAreaID; strcpy(pAreaInfo[nIndex].szAreaName, vectAreaInfo[nIndex].szAreaName); } return pAreaInfo; } PSERVERINFO CPatchClient::GetRegionInfo(unsigned int nAreaID, unsigned char &ucNum) { PSERVERINFO pServerInfo = NULL; vector vetctServerInfo; for (size_t nIndex = 0; nIndex < g_Configuration.m_ServerInfos.size(); nIndex++) { if (g_Configuration.m_ServerInfos[nIndex].nAreaID == nAreaID) { vetctServerInfo.push_back(g_Configuration.m_ServerInfos[nIndex]); } } ucNum = vetctServerInfo.size(); if (ucNum == 0) { return pServerInfo; } pServerInfo = new SERVERINFO[ucNum]; memset(pServerInfo, 0, ucNum * sizeof(SERVERINFO)); for (size_t nIndex = 0; nIndex < vetctServerInfo.size(); nIndex++) { pServerInfo[nIndex].nAreaID = nAreaID; pServerInfo[nIndex].nServerID = vetctServerInfo[nIndex].nServerID; pServerInfo[nIndex].PatchPort = vetctServerInfo[nIndex].PatchPort; pServerInfo[nIndex].ServerPort = vetctServerInfo[nIndex].ServerPort; strcpy(pServerInfo[nIndex].szServerName, vetctServerInfo[nIndex].szServerName); strcpy(pServerInfo[nIndex].szServerIp, vetctServerInfo[nIndex].szServerIp); strcpy(pServerInfo[nIndex].szPatchIp, vetctServerInfo[nIndex].szPatchIp); PingStatus ps = m_Pinger.Ping(pServerInfo[nIndex].szServerIp); pServerInfo[nIndex].PintValue = ps.success ? ps.delay : -1; } return pServerInfo; } int CPatchClient::AddConstrlMask(CONTROL_MASK mask, int nValue) { assert(m_bPrep); m_PrepDownloadCtrl->AddCtrl(mask, nValue); return 0; } int CPatchClient::RemoveControlMask(CONTROL_MASK mask) { assert(m_bPrep); m_PrepDownloadCtrl->RemoveCtrl(mask); return 0; } int CPatchClient::OnTimeOut() { /* */ return 0; } void CPatchClient::OnControl(bool bInControl) { //只允许在预下载时进行控制 assert(m_bPrep); //不进行控制 if (!m_CanDoPrepDownload && !bInControl) { if (m_pBtClient && m_TaskID > 0) { m_pBtClient->SetDownloadRate(m_TaskID, 1024 * 1024 * 100); } if (m_CurPartFile) { Download(); } } else { if (m_pBtClient && m_TaskID > 0) { m_pBtClient->SetDownloadRate(m_TaskID, 512); } } m_CanDoPrepDownload = !bInControl; } void CPatchClient::GetRecommendServer(unsigned int& nCatID, unsigned int& nAreaID, unsigned int& nServerID) { nCatID = g_Configuration.m_RecommendCatID; nAreaID = g_Configuration.m_RecommendAreaID; nServerID = g_Configuration.m_RecommendServerID; } int CPatchClient::ProcDownloadFile(char *pData, unsigned short usDataLen) { DealPlayerPkgPre(PatchServer::PCDownloadFile, pPCDownloadFile, pData, usDataLen, m_Protocol); PMSGHEADER pmsgHeader = (PMSGHEADER)(pData - sizeof(MSGHEADER)); char szBuf[MAX_PATCHDATALEN]; uint32 nRealDataLen = MAX_PATCHDATALEN; if (pmsgHeader->PackType != 0) { int nUncompressRet = uncompress((Bytef*)szBuf, (uLongf*)&nRealDataLen, (Bytef*)pPCDownloadFile->FileData, (uLongf)pPCDownloadFile->DataLen); if (nUncompressRet != Z_OK) { memcpy(szBuf, pPCDownloadFile->FileData, pPCDownloadFile->DataLen); nRealDataLen = pPCDownloadFile->DataLen; } } else { memcpy(szBuf, pPCDownloadFile->FileData, pPCDownloadFile->DataLen); nRealDataLen = pPCDownloadFile->DataLen; } memcpy(m_CurDownloadFile.pFileData + m_CurDownloadFile.nOffset2, szBuf, nRealDataLen); m_CurDownloadFile.nOffset2 += nRealDataLen; if (m_CurDownloadFile.nOffset2 < m_CurDownloadFile.nFileSize) { DownloadFile(); } else { if (m_ClientState == REQLUANCHERVERSION_STATE) { FILE* pFile = NULL; pFile = fopen(m_CurDownloadFile.strFileName.c_str(), "w+b"); if (pFile != NULL) { fwrite(m_CurDownloadFile.pFileData, 1, m_CurDownloadFile.nFileSize, pFile); fclose(pFile); pFile = NULL; if (VerifyLuancherVersion(m_CurDownloadFile.strFileName.c_str()) != 0) { //下载Luancher补丁 ReqLauncherVersion(1); m_ClientState = DOWNLOADLUANCHERUPDATE_STATE; } else { if (!m_DownloadEvent) { ReqServerVersion(); } } } delete [] m_CurDownloadFile.pFileData; m_CurDownloadFile.pFileData = NULL; } else if (m_ClientState == DOWNLOADLUANCHERUPDATE_STATE) { //安装Luancher补丁 FILE* pFile = NULL; pFile = fopen(m_CurDownloadFile.strFileName.c_str(), "w+b"); if (pFile != NULL) { fwrite(m_CurDownloadFile.pFileData, 1, m_CurDownloadFile.nFileSize, pFile); fclose(pFile); pFile = NULL; STARTUPINFO si; PROCESS_INFORMATION pi; memset(&si, 0, sizeof(si)); si.cb = sizeof(si); memset(&pi, 0, sizeof(pi)); char szCmdLine[MAX_PATH]; char szCurDir[MAX_PATH]; _getcwd(szCurDir, MAX_PATH); sprintf(szCmdLine, "\"%s\" \"%s/%u\"", m_CurDownloadFile.strFileName.c_str(), szCurDir, m_LauncherProcessID); if (CreateProcess(NULL, szCmdLine, NULL, NULL, FALSE, NORMAL_PRIORITY_CLASS, NULL, NULL, &si, &pi)) { CloseHandle(pi.hProcess); CloseHandle(pi.hThread); } } } else if (m_ClientState == NORMAL_STATE) { m_DownloadEvent->OnDownloadFinished(m_CurDownloadFile.strFileName.c_str(), m_CurDownloadFile.nOffset1, m_CurDownloadFile.pFileData); } delete [] m_CurDownloadFile.pFileData; m_CurDownloadFile.pFileData = NULL; } return 0; } int CPatchClient::Init(const char *szIp, unsigned short usPort) { m_PatchIp = szIp; m_PatchPort = usPort; m_InitiativeBroken = false; m_NeedUpateLauncher = false; SetCurPorcessID(); RegisterHandler(); m_PatchSession.SetFlag(); m_Thread = GSECreateThread(this, false); m_IsInit = true; return 0; } int CPatchClient::Finit() { m_InitiativeBroken = true; if (!m_IsInit) { return 0; } m_PatchSession.Quit(); GSEDestroyThread(m_Thread); m_Thread = 0; m_HandlerMap.clear(); m_IsInit = false; return 0; } int CPatchClient::DownloadFile(const char* szFileName, unsigned int nOffset, unsigned int nFileSize) { m_CurDownloadFile.strFileName = szFileName; m_CurDownloadFile.nOffset1 = nOffset; m_CurDownloadFile.nOffset2 = 0; m_CurDownloadFile.nFileSize = nFileSize; m_CurDownloadFile.pFileData = new char[nFileSize]; memset(m_CurDownloadFile.pFileData, 0, nFileSize); DownloadFile(); return 0; } //发送请求下载文件 int CPatchClient::DownloadFile() { PatchServer::CPDownloadFile cpDownloadFile; // cpDownloadFile.FileNameLen = m_CurDownloadFile.strFileName.length(); memcpy(cpDownloadFile.FileName, m_CurDownloadFile.strFileName.c_str(), cpDownloadFile.FileNameLen); cpDownloadFile.Offset1 = m_CurDownloadFile.nOffset1; cpDownloadFile.Offset2 = m_CurDownloadFile.nOffset2; cpDownloadFile.DataLen = m_CurDownloadFile.nFileSize - cpDownloadFile.Offset2; //向服务器发送消息 char* pPack = GSEMemAlloc(char, sizeof(PatchServer::CPDownloadFile) + sizeof(MSGHEADER)); PMSGHEADER pmsgHeader = reinterpret_cast(pPack); PatchServer::CPDownloadFile* pCPDownloadFile = reinterpret_cast(pPack + sizeof(MSGHEADER)); size_t nEnCodeLen = m_Protocol.EnCode(cpDownloadFile.wCmd, &cpDownloadFile, (char*)pCPDownloadFile, sizeof(PatchServer::CPDownloadFile)); if (nEnCodeLen == -1) { GSEMemFree(pPack); return 0; } pmsgHeader->PackCmd = PatchServer::CPDownloadFile::wCmd; pmsgHeader->PackType = 0; pmsgHeader->PackLen = nEnCodeLen + sizeof(MSGHEADER); m_SendQue.push_back(pPack); return 0; } int CPatchClient::ControlPreDownload(bool bPause) { if (!(m_bPrep && m_IsInit)) { return 0; } OnControl(bPause); return 0; } int CPatchClient::ReqLauncherVersion(int nType) { PatchServer::CPVerifyLauncherVersion cpVerifyLauncherVersion; cpVerifyLauncherVersion.ReqType = nType; //向服务器发送消息 char* pPack = GSEMemAlloc(char, sizeof(PatchServer::CPVerifyLauncherVersion) + sizeof(MSGHEADER)); PMSGHEADER pmsgHeader = reinterpret_cast(pPack); PatchServer::CPVerifyLauncherVersion* pCPVerifyLauncherVersion = reinterpret_cast(pPack + sizeof(MSGHEADER)); size_t nEnCodeLen = m_Protocol.EnCode(cpVerifyLauncherVersion.wCmd, &cpVerifyLauncherVersion, (char*)pCPVerifyLauncherVersion, sizeof(PatchServer::CPVerifyLauncherVersion)); if (nEnCodeLen == -1) { GSEMemFree(pPack); return 0; } m_ClientState = REQLUANCHERVERSION_STATE; pmsgHeader->PackCmd = PatchServer::CPVerifyLauncherVersion::wCmd; pmsgHeader->PackType = 0; pmsgHeader->PackLen = nEnCodeLen + sizeof(MSGHEADER); m_SendQue.push_back(pPack); return 0; } int CPatchClient::ProcLauncherVersionInfo(char* pData, unsigned short usDataLen) { DealPlayerPkgPre(PatchServer::PCLauncherVersionInfo, pPCLauncherVersionInfo, pData, usDataLen, m_Protocol); DownloadFile(pPCLauncherVersionInfo->FileName, 0, pPCLauncherVersionInfo->FileSize); return 0; } int CPatchClient::VerifyLuancherVersion(const char *szFileName) { vector vectFileInfo; ifstream iFile; iFile.open(szFileName); string strLine; int nLineIndex = 0; while (getline(iFile, strLine)) { if (strLine[strLine.length() - 1] == '\r') { vectFileInfo.push_back(strLine.substr(0, strLine.length() - 1)); } else { vectFileInfo.push_back(strLine); } } iFile.close(); //需要删除此文件 remove(szFileName); if (vectFileInfo.size() % 2) { return 1; } char szCurDir[MAX_PATH]; ZeroMemory(szCurDir, MAX_PATH); GetCurrentDirectory(MAX_PATH, szCurDir); strcpy(szCurDir + strlen(szCurDir), "\\"); string strFileName(szCurDir); for (size_t nIndex = 0; nIndex < vectFileInfo.size(); nIndex += 2) { DWORD dwLen = 0; dwLen = GetFileVersionInfoSize((strFileName + vectFileInfo[nIndex]).c_str(), NULL); if (dwLen == 0) { DWORD dwErr = GetLastError(); return 1; } char* pData = new char[dwLen]; BOOL bSucc = GetFileVersionInfo((strFileName + vectFileInfo[nIndex]).c_str(), NULL, dwLen, pData); if (!bSucc) { delete [] pData; return 1; } LPVOID lpBuf = NULL; UINT dwVersionLen = 0; bSucc = VerQueryValue(pData, "\\", &lpBuf, &dwVersionLen); if (!bSucc) { delete [] pData; return 1; } VS_FIXEDFILEINFO* pVerInfo = reinterpret_cast(lpBuf); USHORT usVer1, usVer2, usVer3, usVer4; usVer2 = HIWORD(pVerInfo->dwProductVersionMS); usVer1 = LOWORD(pVerInfo->dwProductVersionMS); usVer3 = HIWORD(pVerInfo->dwProductVersionLS); usVer4 = LOWORD(pVerInfo->dwProductVersionLS); char szBuf[MAX_PATH]; sprintf(szBuf, "%d.%d.%d.%d", usVer2, usVer1, usVer3, usVer4); if (strcmp(szBuf, vectFileInfo[nIndex + 1].c_str())) { delete [] pData; return 1; } delete [] pData; } return 0; } int CPatchClient::HeatBeat() { time_t ttCur = time(NULL); if(ttCur - m_LastSendTime < 10) { return 0; } m_LastSendTime = ttCur; PatchServer::CPHeartBeat cpHeartBeat; cpHeartBeat.HeartID = GetTickCount(); cpHeartBeat.HeartTime = GetTickCount(); //向服务器发送消息 char* pPack = GSEMemAlloc(char, sizeof(PatchServer::CPHeartBeat) + sizeof(MSGHEADER)); PMSGHEADER pmsgHeader = reinterpret_cast(pPack); PatchServer::CPHeartBeat* pCPHeartBeat = reinterpret_cast(pPack + sizeof(MSGHEADER)); size_t nEnCodeLen = m_Protocol.EnCode(cpHeartBeat.wCmd, &cpHeartBeat, (char*)pCPHeartBeat, sizeof(PatchServer::CPHeartBeat)); if (nEnCodeLen == -1) { GSEMemFree(pPack); return 0; } m_ClientState = REQLUANCHERVERSION_STATE; pmsgHeader->PackCmd = PatchServer::CPHeartBeat::wCmd; pmsgHeader->PackType = 0; pmsgHeader->PackLen = nEnCodeLen + sizeof(MSGHEADER); m_SendQue.push_back(pPack); return 0; } void CPatchClient::SetCurPorcessID() { m_LauncherProcessID = GetCurrentProcessId(); if (m_LauncherProcessID == 0) { char szBuf[MAX_PATH]; GetModuleFileName(NULL, szBuf, MAX_PATH); char* pExeName = strrchr(szBuf, '\\') + 1; HANDLE hSnapShot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0); PROCESSENTRY32 pe32; pe32.dwSize = sizeof( PROCESSENTRY32 ); Process32First( hSnapShot, &pe32 ); do { if (stricmp(pExeName, pe32.szExeFile) == 0) { m_LauncherProcessID = pe32.th32ProcessID; break; } } while(Process32Next(hSnapShot, &pe32)); CloseHandle(hSnapShot); } if (m_LauncherProcessID == 0) { ::MessageBox(NULL, "进程ID获得不到!", "PatchClient", MB_OK); } } int CPatchClient::QueryCliHashFileInfo() { PatchServer::CPCliVerifyReq cpCliVerifyReq; //向服务器发送消息 char* pPack = GSEMemAlloc(char, sizeof(PatchServer::CPCliVerifyReq) + sizeof(MSGHEADER)); PMSGHEADER pmsgHeader = reinterpret_cast(pPack); PatchServer::CPCliVerifyReq* pCPCliVerifyReq = reinterpret_cast(pPack + sizeof(MSGHEADER)); size_t nEnCodeLen = m_Protocol.EnCode(cpCliVerifyReq.wCmd, &cpCliVerifyReq, (char*)pCPCliVerifyReq, sizeof(PatchServer::CPCliVerifyReq)); if (nEnCodeLen == -1) { GSEMemFree(pPack); return 0; } m_ClientState = REQLUANCHERVERSION_STATE; pmsgHeader->PackCmd = PatchServer::CPCliVerifyReq::wCmd; pmsgHeader->PackType = 0; pmsgHeader->PackLen = nEnCodeLen + sizeof(MSGHEADER); m_SendQue.push_back(pPack); return 0; } int CPatchClient::QueryFileSizeByName(const char *szFileName) { PatchServer::CPQueryFileInfo cpQueryFileInfo; cpQueryFileInfo.FileNameLen = strlen(szFileName); strcpy(cpQueryFileInfo.FileName, szFileName); //向服务器发送消息 char* pPack = GSEMemAlloc(char, sizeof(PatchServer::CPQueryFileInfo) + sizeof(MSGHEADER)); PMSGHEADER pmsgHeader = reinterpret_cast(pPack); PatchServer::CPQueryFileInfo* pCPQueryFileInfo = reinterpret_cast(pPack + sizeof(MSGHEADER)); size_t nEnCodeLen = m_Protocol.EnCode(cpQueryFileInfo.wCmd, &cpQueryFileInfo, (char*)pCPQueryFileInfo, sizeof(PatchServer::CPQueryFileInfo)); if (nEnCodeLen == -1) { GSEMemFree(pPack); return 0; } m_ClientState = REQLUANCHERVERSION_STATE; pmsgHeader->PackCmd = PatchServer::CPQueryFileInfo::wCmd; pmsgHeader->PackType = 0; pmsgHeader->PackLen = nEnCodeLen + sizeof(MSGHEADER); m_SendQue.push_back(pPack); return 0; } int CPatchClient::ReqBtServerInfo() { PatchServer::CPReqBtServerInfo cpReqBtServerInfo; //向服务器发送消息 char* pPack = GSEMemAlloc(char, sizeof(PatchServer::CPReqBtServerInfo) + sizeof(MSGHEADER)); PMSGHEADER pmsgHeader = reinterpret_cast(pPack); PatchServer::CPReqBtServerInfo* pCPReqBtServerInfo = reinterpret_cast(pPack + sizeof(MSGHEADER)); size_t nEnCodeLen = m_Protocol.EnCode(cpReqBtServerInfo.wCmd, &cpReqBtServerInfo, (char*)pCPReqBtServerInfo, sizeof(PatchServer::CPReqBtServerInfo)); if (nEnCodeLen == -1) { GSEMemFree(pPack); return 0; } m_ClientState = REQLUANCHERVERSION_STATE; pmsgHeader->PackCmd = PatchServer::CPReqBtServerInfo::wCmd; pmsgHeader->PackType = 0; pmsgHeader->PackLen = nEnCodeLen + sizeof(MSGHEADER); m_SendQue.push_back(pPack); return 0; } int CPatchClient::ProcBtServerInfo(char* pData, unsigned short usDataLen) { DealPlayerPkgPre(PatchServer::PCBtServerInfo, pPCBtServerInfo, pData, usDataLen, m_Protocol); //把Bt服务器信息传递给PartFile类 if (m_pBtClient == NULL) { m_pBtClient = new CBtClient(pPCBtServerInfo->UdpXServer, pPCBtServerInfo->UdpEServer, "BtConfig.ini", pPCBtServerInfo->StatisticServer, pPCBtServerInfo->StatisticServerPort, pPCBtServerInfo->TrackerServer); //启动bt模块 if (m_pBtClient->Start() != 0) { m_pBtClient->Stop(); delete m_pBtClient; m_pBtClient = NULL; return -1; } } return 0; } int CPatchClient::ReqTorrentInfo(CPatchVersion patchVersion) { PatchServer::CPReqTorrentInfo cpReqTorrentInfo; patchVersion.GetVersionInfo(cpReqTorrentInfo.Version.VersionMajor, cpReqTorrentInfo.Version.VersionMin, cpReqTorrentInfo.Version.VersionAddition); cpReqTorrentInfo.Version.FileHash.HashLen = MAX_HASHVALUE_LEN; //向服务器发送消息 char* pPack = GSEMemAlloc(char, sizeof(PatchServer::CPReqTorrentInfo) + sizeof(MSGHEADER)); PMSGHEADER pmsgHeader = reinterpret_cast(pPack); PatchServer::CPReqTorrentInfo* pCPReqTorrentInfo = reinterpret_cast(pPack + sizeof(MSGHEADER)); size_t nEnCodeLen = m_Protocol.EnCode(PatchServer::CPReqTorrentInfo::wCmd, &cpReqTorrentInfo, (char*)pCPReqTorrentInfo, sizeof(PatchServer::CPReqTorrentInfo)); if (nEnCodeLen == -1) { GSEMemFree(pPack); return 0; } m_ClientState = REQLUANCHERVERSION_STATE; pmsgHeader->PackCmd = PatchServer::CPReqTorrentInfo::wCmd; pmsgHeader->PackType = 0; pmsgHeader->PackLen = nEnCodeLen + sizeof(MSGHEADER); m_SendQue.push_back(pPack); return 0; } int CPatchClient::ProcTorrentInfo(char* pData, unsigned short usDataLen) { DealPlayerPkgPre(PatchServer::PCTorrentInfoResp, pPCTorrentInfoResp, pData, usDataLen, m_Protocol); CPatchVersion patchVersion; patchVersion.SetVersion(pPCTorrentInfoResp->Version.VersionMajor, pPCTorrentInfoResp->Version.VersionMin, pPCTorrentInfoResp->Version.VersionAddition); string strTorrentUrl(pPCTorrentInfoResp->TorrentUrl); strTorrentUrl += patchVersion.VersionToFileName(); strTorrentUrl += ".torrent"; string strFileUrl(pPCTorrentInfoResp->PatchUrl); //Bt方式下载文件 m_LastBtTime = 0; m_TaskID = m_pBtClient->BeginTask(strTorrentUrl.c_str(), strFileUrl.c_str(), (g_Configuration.GetPatchDir() + "\\").c_str()); m_BtFileSize = pPCTorrentInfoResp->FileSize; assert(m_TaskID > 0); return 0; } int CPatchClient::ProcCliVerifyInfo(char *pData, unsigned short usDataLen) { DealPlayerPkgPre(PatchServer::PCCliVerifyResp, pPCCliVerifyResp, pData, usDataLen, m_Protocol); if (m_DownloadEvent) { m_DownloadEvent->OnCliHashFileInfo(pPCCliVerifyResp->FileName, pPCCliVerifyResp->FileSize, pPCCliVerifyResp->CliPath); } return 0; } int CPatchClient::ProcFileInfoResp(char* pData, unsigned short usDataLen) { DealPlayerPkgPre(PatchServer::PCFileInfoResp, pPCFileInfoResp, pData, usDataLen, m_Protocol); if (m_DownloadEvent) { m_DownloadEvent->OnFileInfo(pPCFileInfoResp->FileName, pPCFileInfoResp->FileSize); } return 0; } CPatchCliIntf* CreatePatchIntf(CPatchCliEvent* pPatchCliEvent) { return GSEMemNew CPatchClient(pPatchCliEvent); } void DeletePatchIntf(CPatchCliIntf* pIntf) { if (pIntf) { GSEMemDelete pIntf; pIntf = 0; } } CDirectDownloadIntf* CreateDownloadIntf(CDownloadEvent* pEvent) { return GSEMemNew CPatchClient(pEvent); } void DeleteDownloadIntf(CDirectDownloadIntf* pIntf) { if (pIntf) { GSEMemDelete pIntf; pIntf = 0; } }