public void DownLoadThread() { while (m_bRun) { while (m_ThreadList.HasItem()) { MultiFileOK mfo = m_ThreadList.GetItem(); if (mfo.Drd.ResType == ResType.MAX) { //新的客户端 if (!SaveClient(mfo)) { LogMgr.Log("客户端保存失败."); m_bError = true; return; } } else { if (!SaveRes(mfo)) { LogMgr.Log("资源保存失败:" + mfo.Drd.ResType); m_bError = true; return; } } ++m_SaveCount; } System.Threading.Thread.Sleep(10); } }
void SaveDownloadData(DownloadData dd) { MultiFileDownData mfdd = (MultiFileDownData)dd.Data; for (; mfdd.OutsideRecvIndex < mfdd.RecvCount; ++mfdd.OutsideRecvIndex) { MultiFileOK mfo = mfdd.CompletionList[mfdd.OutsideRecvIndex]; m_ThreadList.AddItem(mfo); continue; if (mfo.Drd.ResType == ResType.MAX) { //新的客户端 if (!SaveClient(mfo)) { LogMgr.Log("客户端保存失败."); m_bError = true; } } else { if (!SaveRes(mfo)) { LogMgr.Log("资源保存失败:" + mfo.Drd.ResType); m_bError = true; } } } }
bool SaveClient(MultiFileOK dd) { //验证crc DownResData drd = dd.Drd; if (drd.ResSize != dd.Data.Length) { LogMgr.Log("Client:" + drd.ResType + "大小不匹配,localSize:" + dd.Data.Length + ", serverSize:" + drd.ResSize); return(false); } uint crc = Crc.Crc32(dd.Data, 0, dd.Data.Length); if (crc != drd.ResCrc) { LogMgr.Log("Client:" + drd.ResType + "资源检验失败, size:" + dd.Data.Length + ", localCrc:" + crc + ", serverCrc:" + drd.ResCrc); return(false); } if (RuntimeInfo.GetPlatform() == GamePlatformType.Windows) { SaveWindowClientRes(dd.Data); return(true); } string path = GetClientPath(); try { File.Delete(path); } catch { } FileStream fs = File.Create(path); if (fs == null) { LogMgr.Log("Client文件创建失败:" + drd.ResType); return(false); } fs.Write(dd.Data, 0, dd.Data.Length); fs.Flush(); fs.Close(); return(true); }
bool DownMultiFiles(DownloadData dd) { MultiFileDownData mfdd = (MultiFileDownData)dd.Data; List <DownChunkData> chunkList = new List <DownChunkData>(); List <DownChunkData> waitList = new List <DownChunkData>(); List <DownChunkData> retryList = new List <DownChunkData>(); List <CheckServerIP> serverList = new List <CheckServerIP>(); bool bHasNoYD = false; for (byte i = 0; i < mfdd.FTPIPList.Count; ++i) { CheckServerIP ssi = new CheckServerIP(i); if (mfdd.FTPIPList[i].ISP == (byte)ISPType.ISP_YD) { ssi.FailedCount = (uint)(MAX_CHUNK_COUNT * 2); } serverList.Add(ssi); if (mfdd.FTPIPList[i].ISP != (byte)ISPType.ISP_YD) { bHasNoYD = true; } } //1.划分Chunk //================================ uint tick = Utility.GetTickCount(); byte ipidx = 0; int CHUNK_SIZE2 = CHUNK_SIZE << 1; uint chunkIdx = 0; for (byte i = 0; i < mfdd.FileList.Count; ++i) { int resSize = (int)mfdd.FileList[i].ResSize; int resOffset = 0; while (resSize > 0) { DownChunkData dcd = new DownChunkData(); dcd.FileIdx = i; if (resSize >= CHUNK_SIZE2) { dcd.Length = CHUNK_SIZE; } else { dcd.Length = resSize; } dcd.ChunkIdx = chunkIdx++; dcd.Offset = resOffset; dcd.RecvSize = 0; dcd.RecvTick = 0; resOffset += dcd.Length; resSize -= dcd.Length; if (chunkList.Count < MAX_CHUNK_COUNT) { do { ipidx = (byte)((ipidx + 1) % serverList.Count); } while (bHasNoYD && mfdd.FTPIPList[ipidx].ISP == (byte)ISPType.ISP_YD); dcd.checkServer = serverList[ipidx]; dcd.checkServer.BeginUse(); if (!InitChunk(dd, dcd, mfdd.FTPIPList[ipidx])) { return(false); } dcd.RecvTick = tick; chunkList.Add(dcd); } else { waitList.Add(dcd); } } } //1.接收Chunk //================================ while (true) { tick = Utility.GetTickCount(); for (int i = 0; i < chunkList.Count;) { DownChunkData chunk = chunkList[i]; if (!DownChunk(dd, chunk, tick)) { CloseSocket(chunk); chunk.checkServer.EndUse(chunk.State != ChunkState.CHUNK_CONNECT && chunk.RecvSize != 0); if (chunk.State == ChunkState.CHUNK_RECV_DATA) { //将接收的数据coy到data CopyBuffToData(mfdd, chunk); chunk.Offset += chunk.RecvSize; chunk.Length -= chunk.RecvSize; chunk.RecvSize = 0; ++chunk.RetryCount; chunk.SendCmdData = null; } if (chunk.RetryCount >= MAX_RETRY_COUNT) { //split if ((chunk.Length > MAX_XOR_SIZE || chunk.XOR == 1) && chunk.Length > 16) { DownChunkData dcd1, dcd2; SplitChunk(ref chunkIdx, chunk, out dcd1, out dcd2); waitList.Add(dcd1); waitList.Add(dcd2); } else { chunk.RetryCount = 0; chunk.XOR = 1; chunk.SendCmdData = null; retryList.Add(chunk); } } else { retryList.Add(chunk); } Utility.ListRemoveAt(chunkList, i); continue; } else if (chunk.State == ChunkState.CHUNK_COMPLETION) { CopyBuffToData(mfdd, chunk); CloseSocket(chunk); chunk.checkServer.EndUse(true); RecvFileDataFlag cfd = mfdd.RecvFileList[chunk.FileIdx]; if (cfd.RecvSize == cfd.FileData.Length) { //完成 MultiFileOK mfo = new MultiFileOK(); mfo.Data = cfd.FileData; mfo.Drd = mfdd.FileList[chunk.FileIdx]; mfdd.CompletionList[mfdd.RecvCount] = mfo; if (++mfdd.RecvCount == mfdd.FileList.Count) { Debug.Log("所有文件完成!"); return(true); } } Utility.ListRemoveAt(chunkList, i); continue; } ++i; }//end for if (chunkList.Count < MAX_CHUNK_COUNT) { tick = Utility.GetTickCount(); DownChunkData dcd = null; if (waitList.Count > 0) { dcd = waitList[0]; waitList.RemoveAt(0); } else if (retryList.Count > 0) { dcd = retryList[0]; retryList.RemoveAt(0); } if (dcd != null) { serverList.Sort(SortCheckServer); serverList[0].BeginUse(); dcd.checkServer = serverList[0]; if (!InitChunk(dd, dcd, mfdd.FTPIPList[dcd.checkServer.ServerIdx])) { return(false); } dcd.RecvTick = Utility.GetTickCount(); chunkList.Add(dcd); } } if (mfdd.RecvCount == mfdd.FileList.Count) { break; } Thread.Sleep(1); } ; //end while return(true); }
void DownMultiFile_OldFTP(DownloadData dd) { byte[] buffer = new byte[65536]; MultiFileDownData mfdd = (MultiFileDownData)dd.Data; for (int i = 0; i < mfdd.FTPIPList.Count; ++i) { ServerIPData sid = mfdd.FTPIPList[i]; if (sid.ISP == (int)ISPType.ISP_DX) { LogMgr.Log("<电信FTP:" + sid.IP + ">"); } else if (sid.ISP == (int)ISPType.ISP_LT) { LogMgr.Log("<联通FTP:" + sid.IP + ">"); } else { LogMgr.Log("<移动FTP:" + sid.IP + ">"); } int retryCount = 0; while (mfdd.RecvCount < mfdd.FileList.Count) { DownResData drd = mfdd.FileList[mfdd.RecvCount]; string url = "ftp://" + sid.IP + "/" + drd.ResUrl; int readSize = 0; try { FtpWebRequest ftpRequest = (FtpWebRequest)FtpWebRequest.Create(url); if (ftpRequest == null) { if (retryCount >= MAX_RETRY_COUNT) { break; } else { ++retryCount; Thread.Sleep(500); continue; } } ftpRequest.Method = WebRequestMethods.Ftp.DownloadFile; ftpRequest.UseBinary = true; ftpRequest.KeepAlive = false; FtpWebResponse response = (FtpWebResponse)ftpRequest.GetResponse(); Stream ftpStream = null; if (response == null || (ftpStream = response.GetResponseStream()) == null) { if (retryCount >= MAX_RETRY_COUNT) { break; } else { ++retryCount; Thread.Sleep(500); continue; } } MemoryStream ms = new MemoryStream(); while (true) { int s = ftpStream.Read(buffer, 0, buffer.Length); if (s <= 0) { break; } ms.Write(buffer, 0, s); readSize += s; mfdd.CurrentRecvSize += s; dd.DownloadBytes += (uint)s; } try { ftpStream.Close(); response.Close(); } catch { } if (mfdd.CurrentRecvSize == drd.ResSize) { MultiFileOK mfo = new MultiFileOK(); mfo.Data = ms.ToArray(); mfo.Drd = mfdd.FileList[mfdd.RecvCount]; mfdd.CompletionList[mfdd.RecvCount] = mfo; ++mfdd.RecvCount; if (mfdd.RecvCount == mfdd.FileList.Count) { dd.DownState = DownloadState.DS_DOWNLOADED_OK; if (dd.Type != DownloadType.DOWNLOAD_DEFAULT) { m_CompletionList.AddItem(dd); } return; } else { mfdd.CurrentRecvSize = 0; } } } catch (System.Exception e) { dd.DownloadBytes -= (uint)readSize; LogMgr.Log("OLD_FTP下载失败:" + e.ToString()); if (retryCount >= MAX_RETRY_COUNT) { break; } else { ++retryCount; Thread.Sleep(500); continue; } } } } dd.DownState = DownloadState.DS_DOWNLOADED_ERROR; if (dd.Type != DownloadType.DOWNLOAD_DEFAULT) { m_CompletionList.AddItem(dd); } }
bool SaveRes(MultiFileOK dd) { //验证crc DownResData drd = dd.Drd; if (drd.ResSize != dd.Data.Length) { LogMgr.Log("Res:" + drd.ResType + " 大小不匹配,localSize:" + dd.Data.Length + ", serverSize:" + drd.ResSize); return(false); } uint crc = Crc.Crc32(dd.Data, 0, dd.Data.Length); if (crc != drd.ResCrc) { LogMgr.Log("Res:" + drd.ResType + "资源检验失败, size:" + dd.Data.Length + ", localCrc:" + crc + ", serverCrc:" + drd.ResCrc); return(false); } System.Random rr = new System.Random(); int name = rr.Next(100, 10000); string tempFile = RuntimeInfo.GetLocalPath(drd.ResType + name.ToString() + "_temp.dat"); string path = RuntimeInfo.GetResPersistentPath(drd.ResType); try { File.Delete(tempFile); } catch { } try { File.Delete(path); } catch { } try { FileStream fsTemp = File.Create(tempFile); if (fsTemp == null) { LogMgr.Log("RES文件创建失败:" + drd.ResType); return(false); } //解压 fsTemp.Write(dd.Data, 0, dd.Data.Length); fsTemp.Flush(); fsTemp.Close(); fsTemp = null; LZMA.DecompressFile(tempFile, path); } catch (System.Exception e) { ReportException.Instance.AddException("文件解压失败:" + e.ToString()); } try { File.Delete(tempFile); } catch { } if (File.Exists(path) == false) { LogMgr.Log("RES文件解压失败:" + drd.ResType); return(false); } ResManager.Instance.VersionMgr.SetResVersion(drd.ResType, drd.ResCrc, drd.ResUnzipSize); return(ResManager.Instance.VersionMgr.SaveVersion()); }