Closed xiaokaixuan closed 5 years ago
package main import ( "encoding/hex" "encoding/json" "fmt" "net/http" _ "net/http/pprof" "os" "github.com/shiyanhui/dht" md "github.com/bttown/metadata" ) type file struct { Path []interface{} `json:"path"` Length int `json:"length"` } type bitTorrent struct { InfoHash string `json:"infohash"` Name string `json:"name"` Files []file `json:"files,omitempty"` Length int `json:"length,omitempty"` } func IsExist(path string) bool { _, err := os.Stat(path) return err == nil || os.IsExist(err) } func main() { go func() { http.ListenAndServe(":6060", nil) }() w := dht.NewWire(65536, 1024, 256) go func() { for resp := range w.Response() { metadata, err := dht.Decode(resp.MetadataInfo) if err != nil { continue } torrent := &md.Torrent{} md.NewTorrentFromMetadata(resp.MetadataInfo, torrent) fileName := hex.EncodeToString(resp.InfoHash) if IsExist(fileName + ".torrent") { continue } f, _ := os.Create(fileName + ".torrent") defer f.Close() f.Write(torrent.Bytes()) info := metadata.(map[string]interface{}) if _, ok := info["name"]; !ok { continue } bt := bitTorrent{ InfoHash: hex.EncodeToString(resp.InfoHash), Name: info["name"].(string), } if v, ok := info["files"]; ok { files := v.([]interface{}) bt.Files = make([]file, len(files)) for i, item := range files { f := item.(map[string]interface{}) bt.Files[i] = file{ Path: f["path"].([]interface{}), Length: f["length"].(int), } } } else if _, ok := info["length"]; ok { bt.Length = info["length"].(int) } data, err := json.Marshal(bt) if err == nil { fmt.Printf("%s\n\n", data) } } }() go w.Run() config := dht.NewCrawlConfig() config.OnAnnouncePeer = func(infoHash, ip string, port int) { w.Request([]byte(infoHash), ip, port) } d := dht.New(config) d.Run() }