arvidn / libtorrent

an efficient feature complete C++ bittorrent implementation
http://libtorrent.org
Other
5.23k stars 992 forks source link

Created torrent file, incomplete message #4463

Closed zbooa closed 4 years ago

zbooa commented 4 years ago

I create a test.torrent file with the code.

if (h.has_metadata()) {
    std::shared_ptr<lt::torrent_info const> ti = h.torrent_file();
    lt::create_torrent ct(*ti);
    lt::entry te = ct.generate();
    std::vector<char> buffer;
    bencode(std::back_inserter(buffer), te);
    FILE* f = std::fopen("test.torrent", "wb+");
    if (f) {
        fwrite(&buffer[0], 1, buffer.size(), f);
        fclose(f);
    }
}

Yep, Succ. test.torrent be create, and it can download somefiles. it is working. But this .torrent file have file-list, file-size, No Nodes, No Trackers, No Seeds Message. The size of test.torrent than src torrent file smaller. why ? Something is lost ?

MassaRoddel commented 4 years ago

You only create the info section of the torrent, no tracker etc. You need to add evrything else too. Here is my (german) code:

CVersionsInfo Version; entry Torrent(entry::dictionary_t); boost::shared_array MD(m_Torrent.torrent_file()->metadata()); entry TorrentInfoDaten(bdecode(MD.get(), MD.get() + m_Torrent.torrent_file()->metadata_size())); std::vector Tracker(m_Torrent.trackers()); if (Tracker.size()) { Torrent["announce"] = Tracker.front().url; if (Tracker.size()>1) { std::list<std::pair<int, std::list>> TL; for (std::vector::iterator T(Tracker.begin());T!=Tracker.end();++T) { bool Gefunden = false; for (std::list<std::pair<int, std::list>>::iterator i(TL.begin());i!=TL.end();++i) { if (T->tier==i->first) { i->second.push_back(T); Gefunden = true; break; } } if (Gefunden) continue; std::list AE; AE.push_back(T); TL.push_back(std::make_pair(T->tier, AE)); } entry::list_type L1, L2; for (std::list<std::pair<int, std::list>>::iterator i(TL.begin());i!=TL.end();++i) { L1.clear(); for (std::list::iterator T(i->second.begin());T!=i->second.end();++T) { L1.push_back(T->url); } L2.push_back(L1); } Torrent["announce-list"] = L2; } } std::string Kommentar; if (Peers.empty()) { Kommentar = "Received metadata"; } else { Kommentar = "Received metadata from "; for (size_t i=0;i<Peers.size();++i) { if (i>0) Kommentar+=", "; Kommentar+=Peers[i]; } } if (MetaDatenSuche.Schluesselwort.IsEmpty()) Torrent["comment"] = Kommentar; else Torrent["comment"] = Kommentar + ", matched keyword: " + wchar_utf8(MetaDatenSuche.Schluesselwort); Torrent["created by"] = wchar_utf8((LPCTSTR)(MooPoliceClientName + (L" " + Version.VersionAlsString()))).c_str(); boost::posix_time::ptime Jetzt(boost::posix_time::second_clock::universal_time()); boost::posix_time::ptime Start(boost::posix_time::ptime(boost::gregorian::date(1970, boost::date_time::Jan, 1))); Torrent["creation date"] = (Jetzt - Start).total_seconds(); Torrent["info"] = TorrentInfoDaten;

    if (TorrentDateiPfad.IsEmpty()) TorrentDateiPfad = m_SpeicherPfad + m_TorrentDateiName;
    std::vector<char> Daten;
    bencode(std::back_inserter(Daten), Torrent);
    CFile Datei(TorrentDateiPfad, CFile::modeWrite | CFile::modeCreate);
    Datei.Write(&Daten.front(), UINT(Daten.size()));
    Datei.Close();
arvidn commented 4 years ago

the lt::create_torrent object has member functions to add trackers and DHT nodes.

zbooa commented 4 years ago

You only create the info section of the torrent, no tracker etc. You need to add evrything else too. Here is my (german) code:

  CVersionsInfo Version;
  entry Torrent(entry::dictionary_t);
  boost::shared_array<char> MD(m_Torrent.torrent_file()->metadata());
  entry TorrentInfoDaten(bdecode(MD.get(), MD.get() + m_Torrent.torrent_file()->metadata_size()));
  std::vector<announce_entry> Tracker(m_Torrent.trackers());
  if (Tracker.size())
  {   Torrent["announce"] = Tracker.front().url;
      if (Tracker.size()>1)
      {   std::list<std::pair<int, std::list<announce_entry>>> TL;
          for (std::vector<announce_entry>::iterator T(Tracker.begin());T!=Tracker.end();++T)
          {   bool Gefunden = false;
              for (std::list<std::pair<int, std::list<announce_entry>>>::iterator i(TL.begin());i!=TL.end();++i)
              {   if (T->tier==i->first)
                  {   i->second.push_back(*T);
                      Gefunden = true;
                      break;
                  }
              }
              if (Gefunden) continue;
              std::list<announce_entry> AE;
              AE.push_back(*T);
              TL.push_back(std::make_pair(T->tier, AE));
          }
          entry::list_type L1, L2;
          for (std::list<std::pair<int, std::list<announce_entry>>>::iterator i(TL.begin());i!=TL.end();++i)
          {   L1.clear();
              for (std::list<announce_entry>::iterator T(i->second.begin());T!=i->second.end();++T)
              {   L1.push_back(T->url);
              }
              L2.push_back(L1);
          }
          Torrent["announce-list"] = L2;
      }
  }
  std::string Kommentar;
  if (Peers.empty())
  {   Kommentar = "Received metadata";
  }
  else
  {   Kommentar = "Received metadata from ";
      for (size_t i=0;i<Peers.size();++i)
      {   if (i>0) Kommentar+=", ";
          Kommentar+=Peers[i];
      }
  }
  if (MetaDatenSuche.Schluesselwort.IsEmpty()) Torrent["comment"] = Kommentar;
  else Torrent["comment"] = Kommentar + ", matched keyword: " + wchar_utf8(MetaDatenSuche.Schluesselwort);
  Torrent["created by"] = wchar_utf8((LPCTSTR)(MooPoliceClientName + (L" " + Version.VersionAlsString()))).c_str();
  boost::posix_time::ptime Jetzt(boost::posix_time::second_clock::universal_time());
  boost::posix_time::ptime Start(boost::posix_time::ptime(boost::gregorian::date(1970, boost::date_time::Jan, 1)));
  Torrent["creation date"] = (Jetzt - Start).total_seconds();
  Torrent["info"] = TorrentInfoDaten;

  if (TorrentDateiPfad.IsEmpty()) TorrentDateiPfad = m_SpeicherPfad + m_TorrentDateiName;
  std::vector<char> Daten;
  bencode(std::back_inserter(Daten), Torrent);
  CFile Datei(TorrentDateiPfad, CFile::modeWrite | CFile::modeCreate);
  Datei.Write(&Daten.front(), UINT(Daten.size()));
  Datei.Close();

how to get the "Peers"? you use mfc ?

zbooa commented 4 years ago

the lt::create_torrent object has member functions to add trackers and DHT nodes.

i see. but i think i shoud get the "peers" first.

arvidn commented 4 years ago

I don't know what you want to. there is no field in torrent files for peers

MassaRoddel commented 4 years ago

Peers in my code does not refer to Nodes which you would put into the torrent. Peers come from my modified libtorrent version and is a list of all peers which did send the metadata to my client. As you can see Peers is only used to create the comment entry. Example: comment = "Received metadata from 88.187.131.17 (qBittorrent/4.1.2 ut_metadata), 66.75.96.70 (BitTorrent 7.10.4 ut_metadata)"

zbooa commented 4 years ago

Peers in my code does not refer to Nodes which you would put into the torrent. Peers come from my modified libtorrent version and is a list of all peers which did send the metadata to my client. As you can see Peers is only used to create the comment entry. Example: comment = "Received metadata from 88.187.131.17 (qBittorrent/4.1.2 ut_metadata), 66.75.96.70 (BitTorrent 7.10.4 ut_metadata)"

Sorry, I'm not creating a new seed here. I'm saving the handle as a .torrent file. I'm going to find the original .torrent file and add them to the new ones.

zbooa commented 4 years ago

Peers in my code does not refer to Nodes which you would put into the torrent. Peers come from my modified libtorrent version and is a list of all peers which did send the metadata to my client. As you can see Peers is only used to create the comment entry. Example: comment = "Received metadata from 88.187.131.17 (qBittorrent/4.1.2 ut_metadata), 66.75.96.70 (BitTorrent 7.10.4 ut_metadata)"

Thank you for your code. Now you can find the tracker in the handle. But nodes and web seed still don't. I want to read it and add it to the new .torrent file.