CreatedBy string `bencode:"created by,omitempty"`
Encoding string `bencode:"encoding,omitempty"`
UrlList UrlList `bencode:"url-list,omitempty"` // BEP 19 WebSeeds
- // BEP 52 (BitTorrent v2): Keys are file merkle roots (pieces root?), and the values are the
+ // BEP 52 (BitTorrent v2): Keys are file merkle roots ("pieces root"s), and the values are the
// concatenated hashes of the merkle tree layer that corresponds to the piece length.
PieceLayers map[string]string `bencode:"piece layers,omitempty"`
}
return metainfo.MetaInfo{
CreationDate: time.Now().Unix(),
Comment: "dynamic metainfo from client",
- CreatedBy: "go.torrent",
+ CreatedBy: "https://github.com/anacrolix/torrent",
AnnounceList: t.metainfo.UpvertedAnnounceList().Clone(),
InfoBytes: func() []byte {
if t.haveInfo() {
}
return ret
}(),
+ PieceLayers: t.pieceLayers(),
}
}
}
return nil
}
+
+func (t *Torrent) pieceLayers() (pieceLayers map[string]string) {
+ if t.files == nil {
+ return
+ }
+ files := *t.files
+ g.MakeMapWithCap(&pieceLayers, len(files))
+file:
+ for _, f := range files {
+ if !f.piecesRoot.Ok {
+ continue
+ }
+ key := f.piecesRoot.Value
+ var value strings.Builder
+ for i := f.BeginPieceIndex(); i < f.EndPieceIndex(); i++ {
+ hashOpt := t.piece(i).hashV2
+ if !hashOpt.Ok {
+ // All hashes must be present. This implementation should handle missing files, so move on to the next file.
+ continue file
+ }
+ value.Write(hashOpt.Value[:])
+ }
+ if value.Len() == 0 {
+ // Non-empty files are not recorded in piece layers.
+ continue
+ }
+ // If multiple files have the same root that shouldn't matter.
+ pieceLayers[string(key[:])] = value.String()
+ }
+ return
+}