Oppaitime's version of Gazelle
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

bencodetorrent.class.php 4.6KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170
  1. <?php
  2. /**
  3. * Torrent class that contains some convenient functions related to torrent meta data
  4. */
  5. class BencodeTorrent extends BencodeDecode
  6. {
  7. private $PathKey = 'path';
  8. public $Files = [];
  9. public $Size = 0;
  10. /**
  11. * Create a list of the files in the torrent and their sizes as well as the total torrent size
  12. *
  13. * @return array with a list of files and file sizes
  14. */
  15. public function file_list()
  16. {
  17. if (empty($this->Dec)) {
  18. return false;
  19. }
  20. $InfoDict =& $this->Dec['info'];
  21. if (!isset($InfoDict['files'])) {
  22. // Single-file torrent
  23. $this->Size = (Int64::is_int($InfoDict['length'])
  24. ? Int64::get($InfoDict['length'])
  25. : $InfoDict['length']);
  26. $Name = (isset($InfoDict['name.utf-8'])
  27. ? $InfoDict['name.utf-8']
  28. : $InfoDict['name']);
  29. $this->Files[] = array($this->Size, $Name);
  30. } else {
  31. if (isset($InfoDict['path.utf-8']['files'][0])) {
  32. $this->PathKey = 'path.utf-8';
  33. }
  34. foreach ($InfoDict['files'] as $File) {
  35. $TmpPath = [];
  36. foreach ($File[$this->PathKey] as $SubPath) {
  37. $TmpPath[] = $SubPath;
  38. }
  39. $CurSize = (Int64::is_int($File['length'])
  40. ? Int64::get($File['length'])
  41. : $File['length']);
  42. $this->Files[] = array($CurSize, implode('/', $TmpPath));
  43. $this->Size += $CurSize;
  44. }
  45. uasort($this->Files, function ($a, $b) {
  46. return strnatcasecmp($a[1], $b[1]);
  47. });
  48. }
  49. return array($this->Size, $this->Files);
  50. }
  51. /**
  52. * Find out the name of the torrent
  53. *
  54. * @return string torrent name
  55. */
  56. public function get_name()
  57. {
  58. if (empty($this->Dec)) {
  59. return false;
  60. }
  61. if (isset($this->Dec['info']['name.utf-8'])) {
  62. return $this->Dec['info']['name.utf-8'];
  63. }
  64. return $this->Dec['info']['name'];
  65. }
  66. /**
  67. * Find out the total size of the torrent
  68. *
  69. * @return string torrent size
  70. */
  71. public function get_size()
  72. {
  73. if (empty($this->Files)) {
  74. if (empty($this->Dec)) {
  75. return false;
  76. }
  77. $FileList = $this->file_list();
  78. }
  79. return $FileList[0];
  80. }
  81. /**
  82. * Checks if the "private" flag is present in the torrent
  83. *
  84. * @return true if the "private" flag is set
  85. */
  86. public function is_private()
  87. {
  88. if (empty($this->Dec)) {
  89. return false;
  90. }
  91. return isset($this->Dec['info']['private']) && Int64::get($this->Dec['info']['private']) == 1;
  92. }
  93. /**
  94. * Add the "private" flag to the torrent
  95. *
  96. * @return true if a change was required
  97. */
  98. public function make_private()
  99. {
  100. if (empty($this->Dec)) {
  101. return false;
  102. }
  103. if ($this->is_private()) {
  104. return false;
  105. }
  106. $this->Dec['info']['private'] = Int64::make(1);
  107. ksort($this->Dec['info']);
  108. return true;
  109. }
  110. /**
  111. * Add the "source" field to the torrent
  112. *
  113. * @return true if a change was required
  114. */
  115. public function make_sourced()
  116. {
  117. $Sources = Users::get_upload_sources();
  118. if (empty($this->Dec)) {
  119. return false;
  120. }
  121. if (isset($this->Dec['info']['source']) && ($this->Dec['info']['source'] == $Sources[0] || $this->Dec['info']['source'] == $Sources[1])) {
  122. return false;
  123. }
  124. $this->Dec['info']['source'] = $Sources[0];
  125. ksort($this->Dec['info']);
  126. return true;
  127. }
  128. /**
  129. * Calculate the torrent's info hash
  130. *
  131. * @return info hash in hexadecimal form
  132. */
  133. public function info_hash()
  134. {
  135. if (empty($this->Dec) || !isset($this->Dec['info'])) {
  136. return false;
  137. }
  138. return sha1($this->encode(false, 'info'));
  139. }
  140. /**
  141. * Add the announce URL to a torrent
  142. */
  143. public static function add_announce_url($Data, $Url)
  144. {
  145. return 'd8:announce'.strlen($Url).':'.$Url.substr($Data, 1);
  146. }
  147. /**
  148. * Add list of announce URLs to a torrent
  149. */
  150. public static function add_announce_list($Data, $Urls)
  151. {
  152. $r = 'd13:announce-listl';
  153. for ($i = 0; $i < count($Urls); $i++) {
  154. $r .= 'l';
  155. for ($j = 0; $j < count($Urls[$i]); $j++) {
  156. $r .= strlen($Urls[$i][$j]).':'.$Urls[$i][$j];
  157. }
  158. $r .= 'e';
  159. }
  160. return $r.'e'.substr($Data, 1);
  161. }
  162. }