本文共 12094 字,大约阅读时间需要 40 分钟。
UINT ThreadFunc(LPVOID lpParam) { threadInfo* pInfo=(threadInfo*)lpParam; //sess.SetOption(INTERNET_OPTION_CONNECT_TIMEOUT,6000); //sess.SetOption(INTERNET_OPTION_CONNECT_BACKOFF,500); //sess.SetOption(INTERNET_OPTION_CONNECT_RETRIES, 5); for(UINT n = 0; n < pInfo->vecUrlFile.size(); n++) { EnterCriticalSection(&g_mutex); CInternetSession sess; //CInternetSession::SetCookie(pInfo->vecUrlFile[n].GetBuffer(),_T("tt"),_T("tt")); DWORD dwFlag = INTERNET_FLAG_TRANSFER_BINARY | INTERNET_FLAG_DONT_CACHE | INTERNET_FLAG_RELOAD; CHttpFile* pHttpFile = (CHttpFile* )sess.OpenURL(pInfo->vecUrlFile[n].GetBuffer(), 1, dwFlag); //? if (!pHttpFile) { AfxMessageBox(_T("下载失败")); return -1; } DWORD dwHttpStatus = 0; if(!pHttpFile-> QueryInfoStatusCode(dwHttpStatus)) { AfxMessageBox(_T("下载失败2")); return -1; } if(dwHttpStatus < 200 || dwHttpStatus >= 300) { AfxMessageBox(_T("下载失败3")); return -1; } DWORD dwFileSize; pHttpFile->QueryInfo(HTTP_QUERY_CONTENT_LENGTH, dwFileSize); //DWORD = pInfo->dwFileSize; LeaveCriticalSection(&g_mutex); char* pbuff = new char[4096]; CString sFilePath = pInfo->strFilePath + pInfo->vecFile[n]; CFile file(sFilePath.GetBuffer(),CFile::modeWrite|CFile::typeBinary|CFile::modeCreate);//下载服务器更新包到本地// //FILE* file = _wfsopen(sFilePath.GetBuffer(),L"wb",_SH_DENYRD); //assert(file); //pHttpFile->SetReadBufferSize(4096); MultiThread Concurrent Download //EnterCriticalSection(&g_mutex); int tt = 0; while(dwFileSize > 4096) { pHttpFile->Read(pbuff,4096); file.Write(pbuff,4096);// //fwrite(pbuff,1,4096,file); pInfo->dwCurSize += 4096; dwFileSize -= 4096; tt++; if(tt > 3000) { //Sleep(1); tt = 0; } } if(dwFileSize > 0) { pHttpFile->Read(pbuff,dwFileSize); file.Write(pbuff,dwFileSize);// //fwrite(pbuff,1,dwFileSize,file); pInfo->dwCurSize += dwFileSize; } //LeaveCriticalSection(&g_mutex); file.Close();// //fclose(file); //EnterCriticalSection(&g_mutex); pHttpFile->Close(); delete pHttpFile; sess.Close(); //LeaveCriticalSection(&g_mutex); delete []pbuff; Sleep(1); } pInfo->bFinish = true; return 0; } UINT ThreadFunc2(LPVOID lpParam) { threadInfo* pInfo=(threadInfo*)lpParam; CInternetSession sess; //==============================读取config文件================================ const char* chName; //-------------------------------read-client----------------------------- CreateDirectory(_T("Version"),NULL);//when version doesn't exist create this directory. MeXmlDocument xCMeXml; if ( !xCMeXml.LoadFile("Version/Version.cfg", 1 ) ) //读本地版本 { cstrCVersion = ""; // return false; } else { MeXmlElement* pCRoot = xCMeXml.FirstChildElement( "Project" ); if ( pCRoot == NULL ) { AfxMessageBox(_T("读取project失败")); return false; } if((chName = pCRoot->Attribute("Version")) == NULL) //需不需要判断空?? { AfxMessageBox(_T("读取Version失败")); return false; } cstrCVersion = chName; } //================================================================================================== DWORD dwFlag = INTERNET_FLAG_TRANSFER_BINARY | INTERNET_FLAG_DONT_CACHE | INTERNET_FLAG_RELOAD; DWORD strLength; CHttpFile* pHttpFile = (CHttpFile* )sess.OpenURL(_T("http://192.168.1.55/test/Version.cfg"), 1, dwFlag); //下载服务器版本 if (!pHttpFile) { AfxMessageBox(_T("下载服务器版本失败")); return -1; } DWORD dwHttpStatus = 0; if(!pHttpFile-> QueryInfoStatusCode(dwHttpStatus)) { AfxMessageBox(_T("下载服务器版本失败2")); return -1; } if(dwHttpStatus < 200 || dwHttpStatus >= 300) { AfxMessageBox(_T("下载服务器版本失败3")); return -1; } pHttpFile->QueryInfo(HTTP_QUERY_CONTENT_LENGTH, strLength); char* pbuff = new char[strLength+1]; pHttpFile->Read(pbuff,strLength); pHttpFile->Close(); delete pHttpFile; pbuff[strLength] = 0; char* pbk = new char[strLength+1]; memcpy(pbk,pbuff,strLength+1); MeXmlDocument doc; doc.Parse(pbk); MeXmlElement* pSRoot = doc.FirstChildElement( "Project" ); if ( pSRoot == NULL ) { AfxMessageBox(_T("读取project失败2")); return false; } if((chName = pSRoot->Attribute("Version")) == NULL) { AfxMessageBox(_T("读取Version失败2")); return false; } cstrSVersion = chName; delete[]pbk; 写入临时本地版本 //CFile file(_T("Version/TmpVersion.cfg"),CFile::modeWrite|CFile::typeBinary|CFile::modeCreate);//下载服务器版本到本地 //file.Write(pbuff,strLength); //file.Flush(); //file.Close(); //==============================读取config文件================================ -------------------------------read-server------------------------------------- //MeXmlDocument xSMeXml; // if ( !xSMeXml.LoadFile("Version/TmpVersion.cfg", 1 ) ) // { // return false; //} //----------------------------------------------------- //================================================================================================== // if((dCVersion-dSVersion)<0.0001&&(dCVersion-dSVersion)>-0.0001) //比较本地版本与服务器版本 // if(strCVersion == strSVersion))//比较本地版本与服务器版本 if(cstrCVersion.Compare(cstrSVersion) == 0)//比较本地版本与服务器版本 { //允许进入游戏。 CButton* pbut = (CButton*)pInfo->pDlg->GetDlgItem(IDOK); // pbut->SetWindowText(_T("启动")); pbut->EnableWindow(TRUE); pInfo->pDlg->GetDlgItem(IDCANCEL)->EnableWindow(TRUE);//ENABLE CANCEL pbut->UpdateWindow(); pInfo->pDlg->UpdateWindow(); //m_btn.EnableWindow(); //不能再调用以下 //m_bmpBtn.LoadBitmaps(IDB_BIT_UP,IDB_BIT_DOWN,0,IDB_BIT_DSA);//,IDB_BMP_FOCUS,IDB_BMP_DISABLE //m_bmpBtn.SubclassDlgItem(IDOK ,pInfo->pDlg );//(CStandardDialog*) //m_bmpBtn.SizeToContent(); } else { //先下载更新后方可进入游戏 unsigned _int64 dwTotalSize = 0; //--------------- DownList(); if(mapFile.size() == 0) { AfxMessageBox(_T("DownList失败")); return -1; } //----------------------- threadInfo* tInfo = new threadInfo[MAXTHREADNUM]; for(int y=0;y<MAXTHREADNUM;y++) { threadInfo* pti = &tInfo[y]; pti->dwCurSize = 0; pti->dwFileSize = 0; pti->bFinish = false; //tInfo[l].bFinish = false;? pti->strFilePath = cstrRootDir; } int iNum = 0; std::map<CString,SFileName>::iterator it = mapFile.begin(); for(;it != mapFile.end();++it) { if(cstrRemType == it->second.strFlag) { continue; } int idx = iNum % MAXTHREADNUM; threadInfo* pti = &tInfo[idx]; iNum++; CInternetSession sess; DWORD dwFlag = INTERNET_FLAG_TRANSFER_BINARY | INTERNET_FLAG_DONT_CACHE | INTERNET_FLAG_RELOAD; CString sAddress = cstrRootURL + cstrCVersion + _T("-") + cstrSVersion + _T("/") + it->first;//1.0-3.0 // CString sAddress = cstrRootURL + vecFile[l]; CHttpFile* pHttpFile = (CHttpFile* )sess.OpenURL(sAddress.GetBuffer(), 1, dwFlag); if (!pHttpFile) { AfxMessageBox(_T("获取文件大小失败")); assert(0); return -1; } DWORD dwHttpStatus = 0; if(!pHttpFile-> QueryInfoStatusCode(dwHttpStatus)) { AfxMessageBox(_T("获取文件大小失败2")); return -1; } if(dwHttpStatus < 200 || dwHttpStatus >= 300) { AfxMessageBox(_T("获取文件大小失败3")); return -1; } DWORD strLength; pHttpFile->QueryInfo(HTTP_QUERY_CONTENT_LENGTH, strLength); dwTotalSize += strLength; pHttpFile->Close(); delete pHttpFile; pti->dwFileSize += strLength; //? //pti->pHttpFile = pHttpFile; //pti->strUrlFilePath = pti->vecUrlFile.push_back(sAddress); pti->vecFile.push_back(it->first); } pInfo->pctrlProgress->SetRange32(0,dwTotalSize); for(int y=0;y<MAXTHREADNUM;y++) { threadInfo* pti = &tInfo[y]; if(pti->vecUrlFile.size() > 0) { AfxBeginThread(ThreadFunc,static_cast<LPVOID>(pti)); } } while(1) { bool bfinish = true; DWORD dwsize = 0; for (int t = 0; t < MAXTHREADNUM; ++t) { if(tInfo[t].vecUrlFile.size() == 0) continue; if(!tInfo[t].bFinish) { bfinish = false; } dwsize += tInfo[t].dwCurSize; } if(bfinish) { break; } else { pInfo->pctrlProgress->SetPos(dwsize); } Sleep(10); } delete []tInfo; //在这里全部文件下载完成。 kwFilePath path; //把新加文件拷贝到游戏目录 //把已有文件进行合并 for(it = mapFile.begin();it != mapFile.end();++it) { if(it->second.strFlag == L"Dec") { IPacketLib* pLib = g_CreatePackLib(); pLib->Decompress("Client\\");//释放Client.patch包里面的文件到Client目录 g_ReleasePackLib(pLib); } if(it->second.strFlag == L"Mod") { path.Split(it->second.name.c_str()); std::string share = "Data\\"; share += path.GetFileName(); IPacketLib* pLib = g_CreatePackLib(); std::string strSrcFile = share; strSrcFile += ".pkt"; pLib->OpenPacket(strSrcFile.c_str()); share = "Version\\"; std::string strDstFile = share + it->second.name; pLib->MegrePacketFile(strDstFile.c_str()); g_ReleasePackLib(pLib); } } it = mapFile.begin(); for(;it != mapFile.end();++it) { if(it->second.strFlag == L"Add") { //合并type属性为Add的文件 std::string src = "Version\\"; std::string dst = "Data\\"; std::string strSrcFile = src + it->second.name; std::string strDstFile = dst + it->second.name; if(::_access(strDstFile.c_str(),0) == 0) { ::DeleteFileA(strDstFile.c_str()); } assert(::MoveFileA(strSrcFile.c_str(),strDstFile.c_str())); } } //删除本地文件 it = mapFile.begin(); for(;it != mapFile.end();++it) { if(it->second.strFlag == L"Rem") { //删除type属性为Rem的文件 std::string dst = "Data\\"; std::string strDstFile = dst + it->second.name; if(::_access(strDstFile.c_str(),0) == 0) { ::DeleteFileA(strDstFile.c_str()); } //assert(::DeleteFileA(strDstFile.c_str())); } if(it->second.strFlag == L"Mod") { std::string src2 = "Version\\"; std::string strDstFile2 = src2 + it->second.name; if(::_access(strDstFile2.c_str(),0) == 0) { ::DeleteFileA(strDstFile2.c_str()); } } } //delete FileList.cfg if(::_access("Version\\FileList.cfg",0) == 0) { ::DeleteFileA("Version\\FileList.cfg"); } //最后更新本地版本与服务器版本一致 //CFile file(_T("Version/Version.cfg"),CFile::modeWrite|CFile::typeBinary|CFile::modeCreate);//下载服务器版本到本地 //file.Write(pbuff,strLength); //file.Flush(); //file.Close(); CButton* pbut = (CButton*)pInfo->pDlg->GetDlgItem(IDOK); //pbut->SetWindowText(_T("启动")); isWndDisable = pbut->EnableWindow(TRUE); m_btn2.SetIcon(IDI_STAO,IDI_STAN); //pInfo->pDlg->GetDlgItem(IDCANCEL)->EnableWindow(TRUE);//ENABLE CANCEL pbut->UpdateWindow(); pInfo->pDlg->UpdateWindow(); //m_btn.EnableWindow(); } delete[]pbuff; return 0; } void DownList() { CInternetSession sess; DWORD dwFlag = INTERNET_FLAG_TRANSFER_BINARY | INTERNET_FLAG_DONT_CACHE | INTERNET_FLAG_RELOAD; CString csDir = cstrRootURL + cstrCVersion + _T("-") + cstrSVersion + _T("/FileList.cfg");//1.0-3.0 DWORD strLength; CHttpFile* pHttpList = (CHttpFile* )sess.OpenURL(csDir, 1, dwFlag); if (!pHttpList) { AfxMessageBox(_T("下载FileList失败")); return; } DWORD dwHttpStatus = 0; if(!pHttpList-> QueryInfoStatusCode(dwHttpStatus)) { AfxMessageBox(_T("下载FileList失败2")); return ; } if(dwHttpStatus < 200 || dwHttpStatus >= 300) { AfxMessageBox(_T("下载FileList失败3")); return ; } pHttpList->QueryInfo(HTTP_QUERY_CONTENT_LENGTH, strLength); char* pbuff = new char[strLength]; pHttpList->Read(pbuff,strLength); pHttpList->Close(); delete pHttpList; //写入临时本地版本 //CreateDirectory(_T("Updates"),NULL);//when version doesn't exist create this directory. CFile file(_T("Version/FileList.cfg"),CFile::modeWrite|CFile::typeBinary|CFile::modeCreate);//下载服务器版本到本地 file.Write(pbuff,strLength); file.Flush(); file.Close(); //==============================读取config文件================================ //-------------------------------read-server------------------------------------- const char* chName; MeXmlDocument xSMeXml; if ( !xSMeXml.LoadFile("Version/FileList.cfg", 1 ) ) { AfxMessageBox(_T("读取FileList失败")); return ; } MeXmlElement* pSRoot = xSMeXml.FirstChildElement( "Project" ); if ( pSRoot == NULL ) { AfxMessageBox(_T("读取Project失败3")); return ; } MeXmlElement* pCountry = pSRoot->FirstChildElement( "File" ); if ( pCountry == NULL ) { return ; } //--------------------- //----------read-patch-to-download-------------------- //std::vector<CString> vecFile; while( pCountry != NULL ) { if ( (chName = pCountry->Attribute( "Name")) == NULL ) { AfxMessageBox(_T("读取Nmae失败")); return ; } SFileName sfn; CString strName; strName = chName; sfn.name = chName; if( (chName = pCountry->Attribute( "Type")) == NULL ) { AfxMessageBox(_T("读取Type失败")); return; } CString strType; strType = chName; //if(strType == "Rem") //{ //}else //{ // //vecFile.push_back(str); //} sfn.strFlag = strType; mapFile[strName] = sfn; pCountry = pCountry->NextSiblingElement(); } // //----------------------------------------------------- // for(int i=0;i<vecType.size();i++) // { // if(cstrRemType == vecType[i]) // { CFile::Remove(cstrRootDir+vecFile[i]);//if the file doesn't exist? // } // } delete[]pbuff; //================================================================================================== }转载地址:http://kvfci.baihongyu.com/