)
// Currently doesn't really queue, but should in the future.
- func (cl *Client) queuePieceCheck(t *torrent, pieceIndex pp.Integer) {
+ func (cl *Client) queuePieceCheck(t *torrent, pieceIndex int) {
piece := &t.Pieces[pieceIndex]
if piece.QueuedForHash {
return
}
piece.QueuedForHash = true
t.publishPieceChange(int(pieceIndex))
- go cl.verifyPiece(t, pieceIndex)
+ go cl.verifyPiece(t, int(pieceIndex))
}
// Queue a piece check if one isn't already queued, and the piece has never
if p.EverHashed || p.Hashing || p.QueuedForHash || t.pieceComplete(piece) {
return
}
- cl.queuePieceCheck(t, pp.Integer(piece))
+ cl.queuePieceCheck(t, piece)
}
// Clients contain zero or more Torrents. A client manages a blocklist, the
}
// Returns a handle to the given torrent, if it's present in the client.
-func (cl *Client) Torrent(ih InfoHash) (T Torrent, ok bool) {
+func (cl *Client) Torrent(ih InfoHash) (T Download, ok bool) {
cl.mu.Lock()
defer cl.mu.Unlock()
t, ok := cl.torrents[ih]
})
}
if torrent.haveAnyPieces() {
- conn.Post(pp.Message{
- Type: pp.Bitfield,
- Bitfield: torrent.bitfield(),
- })
+ conn.Bitfield(torrent.bitfield())
} else if me.extensionBytes.SupportsFast() && conn.PeerExtensionBytes.SupportsFast() {
conn.Post(pp.Message{
Type: pp.HaveNone,
return
}
var (
- k peersKey
+ k PeersKey
p Peer
)
for k, p = range t.Peers {
}
go func() {
for i := range t.Pieces {
- cl.verifyPiece(t, pp.Integer(i))
+ cl.verifyPiece(t, i)
}
}()
}
t = &torrent{
InfoHash: ih,
chunkSize: defaultChunkSize,
- Peers: make(map[peersKey]Peer),
+ Peers: make(map[PeersKey]Peer),
closing: make(chan struct{}),
ceasingNetworking: make(chan struct{}),
// trackers will be merged with the existing ones. If the Info isn't yet
// known, it will be set. The display name is replaced if the new spec
// provides one. Returns new if the torrent wasn't already in the client.
-func (cl *Client) AddTorrentSpec(spec *TorrentSpec) (T Torrent, new bool, err error) {
+func (cl *Client) AddTorrentSpec(spec *TorrentSpec) (D Download, new bool, err error) {
+ T := Torrent{}
T.cl = cl
+ D = &T
cl.mu.Lock()
defer cl.mu.Unlock()
for trIndex, tr := range tier {
numTrackersTried++
err := cl.announceTorrentSingleTracker(tr, &req, t)
- if err != nil && missinggo.CryHeard() {
- log.Printf("%s: error announcing to %s: %s", t, tr, err)
+ if err != nil {
continue
}
// Float the successful announce to the top of the tier. If
// It's important that the piece is potentially queued before we check if
// the piece is still wanted, because if it is queued, it won't be wanted.
if piece.numPendingChunks() == 0 {
- me.queuePieceCheck(t, req.Index)
+ me.queuePieceCheck(t, int(req.Index))
}
if !t.wantPiece(int(req.Index)) {
for _, c := range t.Conns {
return
}
- func (me *Client) pieceHashed(t *torrent, piece pp.Integer, correct bool) {
+ func (me *Client) pieceHashed(t *torrent, piece int, correct bool) {
p := &t.Pieces[piece]
if p.EverHashed {
// Don't score the first time a piece is hashed, it could be an
me.pieceChanged(t, int(piece))
}
- // TODO: Check this isn't called more than once for each piece being correct.
func (me *Client) pieceChanged(t *torrent, piece int) {
correct := t.pieceComplete(piece)
p := &t.Pieces[piece]
}
for _, conn := range t.Conns {
if correct {
- conn.Post(pp.Message{
- Type: pp.Have,
- Index: pp.Integer(piece),
- })
- // TODO: Cancel requests for this piece.
+ conn.Have(piece)
for r := range conn.Requests {
if int(r.Index) == piece {
conn.Cancel(r)
me.event.Broadcast()
}
- func (cl *Client) verifyPiece(t *torrent, index pp.Integer) {
+ func (cl *Client) verifyPiece(t *torrent, piece int) {
cl.mu.Lock()
defer cl.mu.Unlock()
- p := &t.Pieces[index]
+ p := &t.Pieces[piece]
for p.Hashing || t.data == nil {
cl.event.Wait()
}
p.QueuedForHash = false
- if t.isClosed() || t.pieceComplete(int(index)) {
+ if t.isClosed() || t.pieceComplete(piece) {
return
}
p.Hashing = true
cl.mu.Unlock()
- sum := t.hashPiece(index)
+ sum := t.hashPiece(piece)
cl.mu.Lock()
select {
case <-t.closing:
default:
}
p.Hashing = false
- cl.pieceHashed(t, index, sum == p.Hash)
+ cl.pieceHashed(t, piece, sum == p.Hash)
}
// Returns handles to all the torrents loaded in the Client.
-func (me *Client) Torrents() (ret []Torrent) {
+func (me *Client) Torrents() (ret []Download) {
me.mu.Lock()
for _, t := range me.torrents {
ret = append(ret, Torrent{me, t})
return
}
-func (me *Client) AddMagnet(uri string) (T Torrent, err error) {
+func (me *Client) AddMagnet(uri string) (T Download, err error) {
spec, err := TorrentSpecFromMagnetURI(uri)
if err != nil {
return
return
}
-func (me *Client) AddTorrent(mi *metainfo.MetaInfo) (T Torrent, err error) {
+func (me *Client) AddTorrent(mi *metainfo.MetaInfo) (T Download, err error) {
T, _, err = me.AddTorrentSpec(TorrentSpecFromMetaInfo(mi))
return
}
-func (me *Client) AddTorrentFromFile(filename string) (T Torrent, err error) {
+func (me *Client) AddTorrentFromFile(filename string) (T Download, err error) {
mi, err := metainfo.LoadFromFile(filename)
if err != nil {
return