public void PieceDataReceived(PeerId peer, PieceMessage message) { Piece piece; if (_picker.ValidatePiece(peer, message.PieceIndex, message.StartOffset, message.RequestLength, out piece)) { PeerId id = peer; TorrentManager manager = id.TorrentManager; Block block = piece.Blocks [message.StartOffset / Piece.BlockSize]; long offset = (long)message.PieceIndex * id.TorrentManager.Torrent.PieceLength + message.StartOffset; id.LastBlockReceived = DateTime.Now; id.TorrentManager.PieceManager.RaiseBlockReceived(new BlockEventArgs(manager, block, piece, id)); id.TorrentManager.Engine.DiskManager.QueueWrite(manager, offset, message.Data, message.RequestLength, delegate { piece.Blocks[message.StartOffset / Piece.BlockSize].Written = true; ClientEngine.BufferManager.FreeBuffer(ref message.Data); // If we haven't written all the pieces to disk, there's no point in hash checking if (!piece.AllBlocksWritten) { return; } // Hashcheck the piece as we now have all the blocks. id.Engine.DiskManager.BeginGetHash(id.TorrentManager, piece.Index, delegate(object o) { byte[] hash = (byte[])o; bool result = hash == null ? false : id.TorrentManager.Torrent.Pieces.IsValid(hash, piece.Index); id.TorrentManager.Bitfield[message.PieceIndex] = result; ClientEngine.MainLoop.Queue(delegate { id.TorrentManager.PieceManager.UnhashedPieces[piece.Index] = false; id.TorrentManager.HashedPiece(new PieceHashedEventArgs(id.TorrentManager, piece.Index, result)); var peers = new List <PeerId>(piece.Blocks.Length); foreach (var b in piece.Blocks.Where(b => b.RequestedOff != null && !peers.Contains(b.RequestedOff))) { peers.Add(b.RequestedOff); } foreach (var p in peers.Where(p => p.Connection != null)) { p.Peer.HashedPiece(result); if (p.Peer.TotalHashFails == 5) { p.ConnectionManager.CleanupSocket(id, "Too many hash fails"); } } // If the piece was successfully hashed, enqueue a new "have" message to be sent out if (result) { id.TorrentManager.FinishedPieces.Enqueue(piece.Index); } }); }); }); if (piece.AllBlocksReceived) { _unhashedPieces[message.PieceIndex] = true; } } }
public virtual bool ValidatePiece(PeerId peer, int pieceIndex, int startOffset, int length, out Piece piece) { CheckOverriden(); return(picker.ValidatePiece(peer, pieceIndex, startOffset, length, out piece)); }