PageRenderTime 56ms CodeModel.GetById 20ms RepoModel.GetById 1ms app.codeStats 0ms

/controller/download.php

https://gitlab.com/protoneutron/xbtbb3cker
PHP | 692 lines | 526 code | 117 blank | 49 comment | 144 complexity | 34c1584da22e5ddf95dbbf62df73900d MD5 | raw file
  1. <?php
  2. /**
  3. *
  4. * @package xbtBB3cker
  5. * @copyright (c) 2015 PPK
  6. * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2
  7. *
  8. *
  9. */
  10. namespace ppk\xbtbb3cker\controller;
  11. class download
  12. {
  13. /** @var \phpbb\auth\auth */
  14. protected $auth;
  15. /** @var \phpbb\db\driver\driver_interface */
  16. protected $db;
  17. /** @var \phpbb\template\template */
  18. protected $template;
  19. /** @var \phpbb\request\request_interface */
  20. protected $request;
  21. /** @var \phpbb\user */
  22. protected $user;
  23. /** @var \phpbb\controller\helper */
  24. protected $helper;
  25. /** @var \phpbb\config\config */
  26. protected $config;
  27. /** @var string phpbb_root_path */
  28. protected $phpbb_root_path;
  29. /** @var string phpEx */
  30. protected $php_ext;
  31. /** @var string table_prefix */
  32. protected $table_prefix;
  33. /** @var \phpbb\cache\service */
  34. protected $cache;
  35. /** @var \ppk\xbtbb3cker\core\xbtbb3cker */
  36. protected $xbt_functions;
  37. protected $torrent;
  38. public function __construct(\phpbb\auth\auth $auth, \phpbb\db\driver\driver_interface $db, \phpbb\template\template $template, \phpbb\request\request_interface $request, \phpbb\user $user, \phpbb\controller\helper $helper, \phpbb\config\config $config, $phpbb_root_path, $php_ext, $table_prefix, \phpbb\cache\service $cache, \ppk\xbtbb3cker\core\xbtbb3cker $functions)
  39. {
  40. $this->auth = $auth;
  41. $this->db = $db;
  42. $this->template = $template;
  43. $this->request = $request;
  44. $this->user = $user;
  45. $this->helper = $helper;
  46. $this->config = $config;
  47. $this->phpbb_root_path = $phpbb_root_path;
  48. $this->php_ext = $php_ext;
  49. $this->cache = $cache;
  50. $this->xbt_functions = $functions;
  51. }
  52. public function main()
  53. {
  54. $this->user->add_lang('viewtopic');
  55. // Thank you sun.
  56. if (isset($_SERVER['CONTENT_TYPE']))
  57. {
  58. if ($this->request->server('CONTENT_TYPE') === 'application/x-java-archive')
  59. {
  60. exit;
  61. }
  62. }
  63. else if ($this->request->server('HTTP_USER_AGENT') && strpos($this->request->server('HTTP_USER_AGENT'), 'Java') !== false)
  64. {
  65. exit;
  66. }
  67. require($this->phpbb_root_path . 'includes/functions_download' . '.' . $this->php_ext);
  68. $attach_id = $this->request->variable('id', 0);
  69. $mode = $this->request->variable('mode', '');
  70. $type=$this->request->variable('type', '');
  71. in_array($type, array('magnet', 'hash')) ? '' : $type='';
  72. if($this->user->data['is_bot'])
  73. {
  74. trigger_error('BOTS_NOT_ALLOWED');
  75. }
  76. if (!$this->config['allow_attachments'] && !$this->config['allow_pm_attach'])
  77. {
  78. send_status_line(404, 'Not Found');
  79. trigger_error('ATTACHMENT_FUNCTIONALITY_DISABLED');
  80. }
  81. if (!$attach_id)
  82. {
  83. send_status_line(404, 'Not Found');
  84. trigger_error('NO_ATTACHMENT_SELECTED');
  85. }
  86. $sql = 'SELECT attach_id, post_msg_id, topic_id, in_message, poster_id, is_orphan, physical_filename, real_filename, extension, mimetype, filesize, filetime
  87. FROM ' . ATTACHMENTS_TABLE . "
  88. WHERE attach_id = $attach_id";
  89. $result = $this->db->sql_query($sql);
  90. $attachment = $this->db->sql_fetchrow($result);
  91. $this->db->sql_freeresult($result);
  92. $forum_tracker=0;
  93. $dt=time();
  94. if (!$attachment)
  95. {
  96. send_status_line(404, 'Not Found');
  97. trigger_error('ERROR_NO_ATTACHMENT');
  98. }
  99. else if (!download_allowed())
  100. {
  101. send_status_line(403, 'Forbidden');
  102. trigger_error($this->user->lang['LINKAGE_FORBIDDEN']);
  103. }
  104. else
  105. {
  106. $attachment['physical_filename'] = utf8_basename($attachment['physical_filename']);
  107. if (!$attachment['in_message'] && !$this->config['allow_attachments'] || $attachment['in_message'] && !$this->config['allow_pm_attach'])
  108. {
  109. send_status_line(404, 'Not Found');
  110. trigger_error('ATTACHMENT_FUNCTIONALITY_DISABLED');
  111. }
  112. if ($attachment['is_orphan'])
  113. {
  114. // We allow admins having attachment permissions to see orphan attachments...
  115. $own_attachment = ($this->auth->acl_get('a_attach') || $attachment['poster_id'] == $this->user->data['user_id']) ? true : false;
  116. if (!$own_attachment || ($attachment['in_message'] && !$this->auth->acl_get('u_pm_download')) || (!$attachment['in_message'] && !$this->auth->acl_get('u_download')))
  117. {
  118. send_status_line(404, 'Not Found');
  119. trigger_error('ERROR_NO_ATTACHMENT');
  120. }
  121. // Obtain all extensions...
  122. $extensions = $this->cache->obtain_attach_extensions(true);
  123. }
  124. else
  125. {
  126. if (!$attachment['in_message'])
  127. {
  128. phpbb_download_handle_forum_auth($this->db, $this->auth, $attachment['topic_id']);
  129. $sql = 'SELECT p.forum_id, p.post_visibility, t.torrent_status, t.torrent_reqratio, t.torrent_requpload, t.topic_poster, f.forum_tracker
  130. FROM ' . POSTS_TABLE . ' p, ' . TOPICS_TABLE . ' t, ' . FORUMS_TABLE . ' f
  131. WHERE p.post_id = ' . (int) $attachment['post_msg_id'] . '
  132. AND p.topic_id=t.topic_id AND p.forum_id = f.forum_id';
  133. $result = $this->db->sql_query($sql);
  134. $post_row = $this->db->sql_fetchrow($result);
  135. $this->db->sql_freeresult($result);
  136. if (!$post_row || ($post_row['post_visibility'] != ITEM_APPROVED && !$this->auth->acl_get('m_approve', $post_row['forum_id'])))
  137. {
  138. // Attachment of a soft deleted post and the user is not allowed to see the post
  139. send_status_line(404, 'Not Found');
  140. trigger_error('ERROR_NO_ATTACHMENT');
  141. }
  142. $forum_tracker=$post_row['forum_tracker']==1 ? 1 : 0;
  143. if(!$forum_tracker)
  144. {
  145. trigger_error('NOT_IN_TRACKER');
  146. }
  147. if($attachment['extension']!='torrent' || $attachment['mimetype']!='application/x-bittorrent')
  148. {
  149. trigger_error('NOT_TORRENT_EXTENSION');
  150. }
  151. $sql="SELECT x.fid id, x.info_hash, x.size, x.ctime added, u.username FROM ".XBT_FILES." x LEFT JOIN ".USERS_TABLE." u ON(x.poster_id=u.user_id) WHERE x.fid='{$attachment['attach_id']}' AND x.post_msg_id='{$attachment['post_msg_id']}' LIMIT 1";
  152. $result = $this->db->sql_query($sql);
  153. $this->torrent = $this->db->sql_fetchrow($result);
  154. $this->db->sql_freeresult($result);
  155. if(!$this->torrent)
  156. {
  157. trigger_error('TORRENT_NOT_REGISTERED');
  158. }
  159. $attachment['username']=$this->torrent['username'];
  160. $attachment['info_hash']=$this->torrent['info_hash'];
  161. $attachment['added']=$this->torrent['added'];
  162. $attachment['info_hash']=substr($attachment['info_hash'], 0, 20);
  163. $attachment['forum_id']=$post_row['forum_id'];
  164. if(!$this->user->data['is_registered'])
  165. {
  166. $is_candowntorr = $this->auth->acl_get('u_candowntorr') && $this->auth->acl_get('f_candowntorr', $post_row['forum_id']) ? 1 : 0;
  167. $this->config['ppkbb_trestricts_options'][5] && $this->torrent['size'] < $this->config['ppkbb_trestricts_options'][5] ? $is_candowntorr=1 : '';
  168. }
  169. else
  170. {
  171. $is_candowntorr=1;
  172. if($this->user->data['user_id']!=$post_row['topic_poster'])
  173. {
  174. $is_candowntorr=$this->auth->acl_get('u_candowntorr') && $this->auth->acl_get('f_candowntorr', $post_row['forum_id']) ? 1 : 0;
  175. }
  176. }
  177. if(!$is_candowntorr)
  178. {
  179. trigger_error('CANT_DOWN_TORRENT');
  180. }
  181. $register_link=append_sid("{$this->phpbb_root_path}ucp.{$this->php_ext}", "mode=register", false);
  182. $login_link=append_sid("{$this->phpbb_root_path}ucp.{$this->php_ext}", "mode=login", false);
  183. if(!$this->config['enable_mod_rewrite'])
  184. {
  185. /*$this->config['enable_mod_rewrite'] ? '' : */$register_link='./../..'.$register_link;
  186. /*$this->config['enable_mod_rewrite'] ? '' : */$login_link='./../..'.$login_link;
  187. }
  188. $torrent_statuses=$this->xbt_functions->get_torrent_statuses();
  189. if(isset($torrent_statuses['STATUS_MARK'][$post_row['torrent_status']]))
  190. {
  191. $is_cansetstatus = $this->user->data['is_registered'] && $this->auth->acl_get('u_cansetstatus') && $this->auth->acl_get('f_cansetstatus', $post_row['forum_id']) ? 1 : 0;
  192. if($is_cansetstatus || $post_row['torrent_status'] < 1 || ($this->user->data['user_id']==$attachment['poster_id'] && $post_row['torrent_status'] > 0 && in_array($post_row['torrent_status'], $this->config['ppkbb_tcauthor_candown'])))
  193. {
  194. }
  195. else
  196. {
  197. trigger_error(sprintf($this->user->lang['CANTDOWN_TORRENT_STATUS'], $torrent_statuses['STATUS_REASON'][$post_row['torrent_status']]));
  198. }
  199. if(!$this->user->data['is_registered'] && $post_row['torrent_status'] < 1 && in_array($post_row['torrent_status'], $this->config['ppkbb_tcguest_cantdown']))
  200. {
  201. trigger_error(sprintf($this->user->lang['LOGORREG_DOWNLOAD'], $register_link, $login_link));
  202. }
  203. }
  204. // $post_row['torrent_status'] > 0 ? $attachment['info_hash']=substr($attachment['info_hash'], 0, 20) : '';
  205. if($this->user->data['is_registered'])
  206. {
  207. if($this->config['ppkbb_trestricts_options'][0])
  208. {
  209. $sql = 'SELECT downloaded user_downloaded, uploaded user_uploaded
  210. FROM '.XBT_USERS."
  211. WHERE uid={$this->user->data['user_id']}";
  212. $result = $this->db->sql_query($sql);
  213. $user_data = $this->db->sql_fetchrow($result);
  214. $this->db->sql_freeresult($result);
  215. $is_canskiprequpratio = $this->user->data['user_id']!=$attachment['poster_id'] ? (($this->auth->acl_get('u_canskiprequpratio') && $this->auth->acl_get('f_canskiprequpratio', $post_row['forum_id'])) ? 1 : 0) : 1;
  216. if(!$is_canskiprequpratio)
  217. {
  218. if($post_row['torrent_requpload'] && $user_data['user_uploaded'] < $post_row['torrent_requpload'])
  219. {
  220. trigger_error(sprintf($this->user->lang['TORRENT_REQUPLOAD_ERROR'], get_formatted_filesize($post_row['torrent_requpload']), get_formatted_filesize($user_data['user_uploaded'])));
  221. }
  222. $user_ratio=$this->xbt_functions->get_ratio($user_data['user_uploaded'], $user_data['user_downloaded'], $this->config['ppkbb_tcratio_start']);
  223. if($post_row['torrent_reqratio']!=0.000 && $user_ratio!='None.' && ($user_ratio < $post_row['torrent_reqratio'] || $user_ratio=='Leech.' || $user_ratio=='Inf.'))
  224. {
  225. trigger_error(sprintf($this->user->lang['TORRENT_REQRATIO_ERROR'], $post_row['torrent_reqratio'], $this->xbt_functions->get_ratio_alias($user_ratio)));
  226. }
  227. }
  228. }
  229. if($this->config['ppkbb_trestricts_options'][1] && $this->config['ppkbb_trestricts_options'][2])
  230. {
  231. $is_canskiptrestricts = $this->user->data['user_id']!=$attachment['poster_id'] ? ($this->auth->acl_get('u_canskiptrestricts') ? 1 : 0) : 1;
  232. if(!$is_canskiptrestricts)
  233. {
  234. $user_restricts=unserialize($this->user->data['user_trestricts']);
  235. if(isset($user_restricts['wait_time']) && isset($user_restricts['include_torrent']))
  236. {
  237. if($dt - $attachment['added'] < $user_restricts['wait_time'])
  238. {
  239. trigger_error(sprintf($this->user->lang['USER_WAIT_TIME'], $this->xbt_functions->my_date_diff(0, $user_restricts['wait_time'], true)));
  240. }
  241. }
  242. if(isset($user_restricts['days_limit']))
  243. {
  244. $sql='SELECT COUNT(*) dl_count FROM '.TRACKER_DOWNLOADS_TABLE." WHERE downloader_id='{$this->user->data['user_id']}' AND dl_date='".date('Ymd', $dt)."'";
  245. $result=$this->db->sql_query($sql);
  246. $dl_count=$this->db->sql_fetchfield('dl_count');
  247. $this->db->sql_freeresult($result);
  248. if($dl_count >= $user_restricts['days_limit'])
  249. {
  250. trigger_error(sprintf($this->user->lang['USER_RESTRICT_DOWNLOADS_LIMIT'], $user_restricts['days_limit']));
  251. }
  252. }
  253. }
  254. }
  255. if($this->user->data['user_type']!=USER_FOUNDER)
  256. {
  257. if($this->config['ppkbb_trestricts_options'][4])
  258. {
  259. $sql='SELECT COUNT(*) dl_count FROM '.TRACKER_DOWNLOADS_TABLE." WHERE downloader_id='{$this->user->data['user_id']}' AND dl_date='".date('Ymd', $dt)."'";
  260. $result=$this->db->sql_query($sql);
  261. $dl_count=$this->db->sql_fetchfield('dl_count');
  262. $this->db->sql_freeresult($result);
  263. if($dl_count >= $this->config['ppkbb_trestricts_options'][4])
  264. {
  265. trigger_error($this->user->lang['USER_DOWNLOADS_LIMIT']);
  266. }
  267. }
  268. if($this->config['ppkbb_trestricts_options'][7])
  269. {
  270. $sql='SELECT COUNT(*) dl_count FROM '.TRACKER_DOWNLOADS_TABLE." WHERE downloader_id!='1' AND dl_date='".date('Ymd', $dt)."' AND dl_ip='{$this->user->ip}'";
  271. $result=$this->db->sql_query($sql);
  272. $dl_count=$this->db->sql_fetchfield('dl_count');
  273. $this->db->sql_freeresult($result);
  274. if($dl_count >= $this->config['ppkbb_trestricts_options'][7])
  275. {
  276. trigger_error($this->user->lang['USER_DOWNLOADS_IPLIMIT']);
  277. }
  278. }
  279. }
  280. }
  281. else
  282. {
  283. if($this->config['ppkbb_trestricts_options'][3])
  284. {
  285. $sql='SELECT COUNT(*) dl_count FROM '.TRACKER_DOWNLOADS_TABLE." WHERE downloader_id='1' AND dl_date='".date('Ymd', $dt)."'";
  286. $result=$this->db->sql_query($sql);
  287. $dl_count=$this->db->sql_fetchfield('dl_count');
  288. $this->db->sql_freeresult($result);
  289. if($dl_count >= $this->config['ppkbb_trestricts_options'][3])
  290. {
  291. trigger_error(sprintf($this->user->lang['GUEST_DOWNLOADS_LIMIT'], $register_link, $login_link));
  292. }
  293. }
  294. if($this->config['ppkbb_trestricts_options'][6])
  295. {
  296. $sql='SELECT COUNT(*) dl_count FROM '.TRACKER_DOWNLOADS_TABLE." WHERE downloader_id='1' AND dl_date='".date('Ymd', $dt)."' AND dl_ip='{$this->user->data['session_ip']}'";
  297. $result=$this->db->sql_query($sql);
  298. $dl_count=$this->db->sql_fetchfield('dl_count');
  299. $this->db->sql_freeresult($result);
  300. if($dl_count >= $this->config['ppkbb_trestricts_options'][6])
  301. {
  302. trigger_error($this->user->lang['GUEST_DOWNLOADS_IPLIMIT']);
  303. }
  304. }
  305. }
  306. }
  307. else
  308. {
  309. trigger_error('NO_TORRENTS_IN_PM');
  310. // Attachment is in a private message.
  311. $post_row = array('forum_id' => false);
  312. phpbb_download_handle_pm_auth($this->db, $this->auth, $this->user->data['user_id'], $attachment['post_msg_id']);
  313. }
  314. $extensions = array();
  315. if (!extension_allowed($post_row['forum_id'], $attachment['extension'], $extensions))
  316. {
  317. send_status_line(403, 'Forbidden');
  318. trigger_error(sprintf($this->user->lang['EXTENSION_DISABLED_AFTER_POSTING'], $attachment['extension']));
  319. }
  320. }
  321. $download_mode = (int) $extensions[$attachment['extension']]['download_mode'];
  322. $display_cat = $extensions[$attachment['extension']]['display_cat'];
  323. $this->send_torrent_to_browser($attachment, $this->config['upload_path'], $display_cat, $type, $dt);
  324. file_gc();
  325. }
  326. }
  327. # /includes/functions_download.php
  328. public function send_torrent_to_browser($attachment, $upload_dir, $category, $type, $dt)
  329. {
  330. $confirm=$this->request->variable('confirm', '');
  331. if($this->user->data['is_registered'])
  332. {
  333. $this->torrent_link=$this->config['ppkbb_torrent_downlink'][0]==1 || $this->config['ppkbb_torrent_downlink'][0]==3 ? true : false;
  334. $magnet_link=$this->config['ppkbb_torrent_downlink'][1]==1 || $this->config['ppkbb_torrent_downlink'][1]==3 ? true : false;
  335. $hash_link=$this->config['ppkbb_torrent_downlink'][2]==1 || $this->config['ppkbb_torrent_downlink'][2]==3 ? true : false;
  336. }
  337. else
  338. {
  339. $this->torrent_link=$this->config['ppkbb_torrent_downlink'][0]==2 || $this->config['ppkbb_torrent_downlink'][0]==3 ? true : false;
  340. $magnet_link=$this->config['ppkbb_torrent_downlink'][1]==2 || $this->config['ppkbb_torrent_downlink'][1]==3 ? true : false;
  341. $hash_link=$this->config['ppkbb_torrent_downlink'][2]==2 || $this->config['ppkbb_torrent_downlink'][2]==3 ? true : false;
  342. }
  343. if($type=='magnet')
  344. {
  345. !$magnet_link ? trigger_error('MAGNET_DOWNLOADS_DISABLED') : '';
  346. }
  347. else if($type=='hash')
  348. {
  349. !$hash_link ? trigger_error('HASH_DOWNLOADS_DISABLED') : '';
  350. }
  351. else
  352. {
  353. !$this->torrent_link ? trigger_error('TORRENT_DOWNLOADS_DISABLED') : '';
  354. }
  355. $filename = $this->phpbb_root_path . $upload_dir . '/' . $attachment['physical_filename'];
  356. if (!@file_exists($filename))
  357. {
  358. send_status_line(404, 'Not Found');
  359. trigger_error('ERROR_NO_ATTACHMENT');
  360. }
  361. // if(!$this->user->data['is_registered'] && !$this->config['ppkbb_xcanonymous_announce'])
  362. // {
  363. // trigger_error('TRGUESTS_DISABLED');
  364. // }
  365. if($this->user->data['is_registered'])
  366. {
  367. $sql = 'SELECT uid, torrent_pass user_passkey, downloaded user_downloaded, uploaded user_uploaded
  368. FROM '.XBT_USERS."
  369. WHERE uid={$this->user->data['user_id']}";
  370. $result = $this->db->sql_query($sql);
  371. $this->user_data = $this->db->sql_fetchrow($result);
  372. $this->db->sql_freeresult($result);
  373. $this->user->data['user_passkey']=$this->user_data['user_passkey'];
  374. }
  375. else
  376. {
  377. $this->user->data['user_passkey']='';
  378. }
  379. $this->config['ppkbb_xclisten_port'] ? '' : $this->config['ppkbb_xclisten_port']=2710;
  380. $tracker_url=generate_board_url($this->config['ppkbb_phpannounce_enabled'] && $this->config['ppkbb_phpannounce_url'] ? false : true);
  381. if(!$this->config['ppkbb_announce_url'])
  382. {
  383. $this->config['ppkbb_announce_url']=$tracker_url.($this->config['ppkbb_phpannounce_enabled'] && $this->config['ppkbb_phpannounce_url'] ? '' : ':'.$this->config['ppkbb_xclisten_port']);
  384. }
  385. else
  386. {
  387. $this->config['ppkbb_announce_url']=($this->config['ppkbb_phpannounce_enabled'] && $this->config['ppkbb_phpannounce_url'] ? $tracker_url : $this->config['ppkbb_announce_url'].':'.$this->config['ppkbb_xclisten_port']);
  388. }
  389. if($type)
  390. {
  391. $this->template->assign_vars(array(
  392. 'TRACKER_EXT_PATH' => $this->config['enable_mod_rewrite'] ? '../' : '../../',
  393. )
  394. );
  395. }
  396. if((!$this->user->data['is_registered'] && $this->config['ppkbb_addit_options'][1]==2) || $type=='hash' || ($type=='magnet' && !$confirm) || !$this->config['ppkbb_addit_options'][1] || $this->user->data['user_id']==$attachment['poster_id'])
  397. {
  398. }
  399. else
  400. {
  401. $sql='SELECT id, dl_ip FROM '.TRACKER_DOWNLOADS_TABLE." WHERE dl_date='".date('Ymd', $dt)."' AND downloader_id='{$this->user->data['user_id']}' AND attach_id='{$attachment['attach_id']}' LIMIT 1";
  402. $result=$this->db->sql_query($sql);
  403. $row=$this->db->sql_fetchrow($result);
  404. $this->db->sql_freeresult($result);
  405. if(!$row || (!$this->user->data['is_registered'] && $row['dl_ip']!=$this->user->ip))
  406. {
  407. $sql="INSERT INTO ".TRACKER_DOWNLOADS_TABLE."(downloader_id, dl_time, dl_ip, attach_id, post_msg_id, dl_date) VALUES('{$this->user->data['user_id']}', '{$dt}', '".$this->db->sql_escape($this->user->ip)."', '{$attachment['attach_id']}', '{$attachment['post_msg_id']}', '".date('Ymd', $dt)."')";
  408. $result=$this->db->sql_query($sql);
  409. }
  410. }
  411. if($type=='hash')
  412. {
  413. trigger_error(sprintf($this->user->lang['TORRENT_HASH_DLINK'], bin2hex($attachment['info_hash'])).$this->user->lang['TRACKER_RETURN_BACK']);
  414. }
  415. else if($type=='magnet')
  416. {
  417. $this->torrent_basename=utf8_basename(urldecode($attachment['real_filename']));
  418. if($this->user->data['is_registered'])
  419. {
  420. $rtracks=$this->config['ppkbb_announce_url'].($this->config['ppkbb_phpannounce_enabled'] && $this->config['ppkbb_phpannounce_url'] ? $this->config['ppkbb_phpannounce_url'].'?passkey='.$this->user->data['user_passkey'] : '/'.$this->user->data['user_passkey'].'/announce');
  421. }
  422. else
  423. {
  424. $ppkbb_rtrack_enable=$this->config['ppkbb_rtrack_enable'];
  425. $ppkbb_rtrack_enable[1]=0;
  426. $this->config['ppkbb_rtrack_enable']=$ppkbb_rtrack_enable;
  427. $rtracks=$this->config['ppkbb_announce_url'].($this->config['ppkbb_phpannounce_enabled'] && $this->config['ppkbb_phpannounce_url'] ? $this->config['ppkbb_phpannounce_url'].'?passkey=' : '/announce');
  428. }
  429. $rtracks=urlencode($rtracks);
  430. if($this->config['ppkbb_rtrack_enable'][0] || $this->config['ppkbb_rtrack_enable'][1])
  431. {
  432. include("{$this->phpbb_root_path}ext/ppk/xbtbb3cker/include/rtrackfunc.{$this->php_ext}");
  433. $forb_rtracks=$this->get_forb_rtrack();
  434. $rtrack=get_rtrack($this->user->ip, $this->config['ppkbb_rtrack_enable'][0], $this->config['ppkbb_rtrack_enable'][1], $this->torrent['id'], $forb_rtracks);
  435. $rtracks=benc_rtrack_url($rtrack, $this->config['ppkbb_rtrack_enable'][2], true);
  436. }
  437. $magnet_src_link="magnet:?xt=urn:btih:".bin2hex($this->torrent['info_hash'])."&dn=".urlencode($this->torrent_basename)."&xl={$this->torrent['size']}&tr={$rtracks}";
  438. if($confirm)
  439. {
  440. header("Location: {$magnet_src_link}");
  441. }
  442. else
  443. {
  444. $download_url=$this->helper->route('ppk_xbtbb3cker_controller_download');
  445. $download_amp=strpos($download_url, '?')!==false ? '&amp;' : '?';
  446. $magnet_src_link=$download_url.$download_amp."id={$attachment['attach_id']}&amp;type={$type}&amp;confirm=1";
  447. }
  448. trigger_error(sprintf($this->user->lang['TORRENT_MAGNET_DLINK'], $magnet_src_link).($confirm ? sprintf($this->user->lang['RETURN_BACK'], append_sid("{$this->phpbb_root_path}viewtopic.{$this->php_ext}", 'p='.$attachment['post_msg_id']).'#p'.$attachment['post_msg_id']) : $this->user->lang['TRACKER_RETURN_BACK']));
  449. }
  450. if($this->config['ppkbb_append_tfile']/* && stristr($attachment['real_filename'], "[{$this->config['server_name']}]")===false*/)
  451. {
  452. $p_array=explode('.', $attachment['real_filename']);
  453. unset($p_array[count($p_array)-1]);
  454. $attachment['real_filename']=implode('.', $p_array);
  455. $this->config['ppkbb_append_tfile']=preg_replace("#[\\/:*?\"<>|]#i", '', $this->config['ppkbb_append_tfile']);
  456. $attachment['real_filename']=urldecode(str_replace(array('{DOMAIN}', '{TOPICID}', '{FILENAME}'), array($this->config['server_name'], $attachment['topic_id'], $attachment['real_filename']), $this->config['ppkbb_append_tfile'])).'.'.$attachment['extension'];
  457. }
  458. // Correct the mime type - we force application/octetstream for all files, except images
  459. // Please do not change this, it is a security precaution
  460. if ($category != ATTACHMENT_CATEGORY_IMAGE || strpos($attachment['mimetype'], 'image') !== 0)
  461. {
  462. $attachment['mimetype'] = (strpos(strtolower($this->user->browser), 'msie') !== false || strpos(strtolower($this->user->browser), 'opera') !== false) ? 'application/octetstream' : 'application/octet-stream';
  463. }
  464. if (@ob_get_length())
  465. {
  466. @ob_end_clean();
  467. }
  468. // Now send the File Contents to the Browser
  469. $size = @filesize($filename);
  470. // To correctly display further errors we need to make sure we are using the correct headers for both (unsetting content-length may not work)
  471. // Check if headers already sent or not able to get the file contents.
  472. if (headers_sent() || !@file_exists($filename) || !@is_readable($filename))
  473. {
  474. // PHP track_errors setting On?
  475. if (!empty($php_errormsg))
  476. {
  477. send_status_line(500, 'Internal Server Error');
  478. trigger_error($this->user->lang['UNABLE_TO_DELIVER_FILE'] . '<br />' . sprintf($this->user->lang['TRACKED_PHP_ERROR'], $php_errormsg));
  479. }
  480. send_status_line(500, 'Internal Server Error');
  481. trigger_error('UNABLE_TO_DELIVER_FILE');
  482. }
  483. // Make sure the database record for the filesize is correct
  484. if ($size > 0 && $size != $attachment['filesize'])
  485. {
  486. // Update database record
  487. $sql = 'UPDATE ' . ATTACHMENTS_TABLE . '
  488. SET filesize = ' . (int) $size . '
  489. WHERE attach_id = ' . (int) $attachment['attach_id'];
  490. $this->db->sql_query($sql);
  491. }
  492. // Now the tricky part... let's dance
  493. header('Cache-Control: public');
  494. // Send out the Headers. Do not set Content-Disposition to inline please, it is a security measure for users using the Internet Explorer.
  495. header('Content-Type: ' . $attachment['mimetype']);
  496. if (phpbb_is_greater_ie_version($this->user->browser, 7))
  497. {
  498. header('X-Content-Type-Options: nosniff');
  499. }
  500. if (empty($this->user->browser) || ((strpos(strtolower($this->user->browser), 'msie') !== false) && !phpbb_is_greater_ie_version($this->user->browser, 7)))
  501. {
  502. header('Content-Disposition: attachment; ' . header_filename(htmlspecialchars_decode($attachment['real_filename'])));
  503. if (empty($this->user->browser) || (strpos(strtolower($this->user->browser), 'msie 6.0') !== false))
  504. {
  505. header('Expires: ' . gmdate('D, d M Y H:i:s', $dt) . ' GMT');
  506. }
  507. }
  508. else
  509. {
  510. header('Content-Disposition: ' . ((strpos($attachment['mimetype'], 'image') === 0) ? 'inline' : 'attachment') . '; ' . header_filename(htmlspecialchars_decode($attachment['real_filename'])));
  511. if (phpbb_is_greater_ie_version($this->user->browser, 7) && (strpos($attachment['mimetype'], 'image') !== 0))
  512. {
  513. header('X-Download-Options: noopen');
  514. }
  515. }
  516. include("{$this->phpbb_root_path}ext/ppk/xbtbb3cker/include/bencoding.{$this->php_ext}");
  517. $dict = bdecode_f($filename, $size);
  518. $dict['comment']=$dict['comment.utf-8']="{$this->user->lang['TORRENT_CREATED_FOR']}: {$this->config['server_name']}\r\n"
  519. ."{$this->user->lang['TORRENT_SUBJECT']}: {$tracker_url}/viewtopic.{$this->php_ext}?f={$attachment['forum_id']}&t={$attachment['topic_id']}&p={$attachment['post_msg_id']}#p{$attachment['post_msg_id']}\r\n"
  520. ."{$this->user->lang['AUTHOR']}: {$attachment['username']} {$tracker_url}/memberlist.$this->php_ext?mode=viewprofile&u={$attachment['poster_id']}\r\n"
  521. ."{$this->user->lang['DOWNLOAD_FOR']}: {$this->user->data['username']} {$tracker_url}/memberlist.$this->php_ext?mode=viewprofile&u={$this->user->data['user_id']}";
  522. $dict['publisher-url']=$dict['publisher-url.utf-8']="{$tracker_url}/viewtopic.{$this->php_ext}?f={$attachment['forum_id']}&t={$attachment['topic_id']}&p={$attachment['post_msg_id']}#p{$attachment['post_msg_id']}";
  523. if($this->user->data['is_registered'])
  524. {
  525. $announce_url=$this->config['ppkbb_announce_url'].($this->config['ppkbb_phpannounce_enabled'] && $this->config['ppkbb_phpannounce_url'] ? $this->config['ppkbb_phpannounce_url'].'?passkey='.$this->user->data['user_passkey'] : '/'.$this->user->data['user_passkey'].'/announce');
  526. }
  527. else
  528. {
  529. $announce_url=$this->config['ppkbb_announce_url'].($this->config['ppkbb_phpannounce_enabled'] && $this->config['ppkbb_phpannounce_url'] ? $this->config['ppkbb_phpannounce_url'].'?passkey=' : '/announce');
  530. }
  531. $dict['announce'] = $announce_url;
  532. if($this->config['ppkbb_rtrack_enable'][0] || $this->config['ppkbb_rtrack_enable'][1])
  533. {
  534. //unset($dict['announce']);
  535. require($this->phpbb_root_path.'ext/ppk/xbtbb3cker/include/rtrackfunc.'.$this->php_ext);
  536. $forb_rtracks=$this->get_forb_rtrack();
  537. $rtrack=get_rtrack($this->user->ip, $this->config['ppkbb_rtrack_enable'][0], $this->config['ppkbb_rtrack_enable'][1], $attachment['attach_id'], $forb_rtracks);
  538. $dict['announce-list']=benc_rtrack_url($rtrack, $this->config['ppkbb_rtrack_enable'][2]);
  539. /*if($this->config['ppkbb_rtrack_enable'][2])
  540. {
  541. unset($dict['announce']);
  542. $dict['announce']='';
  543. }*/
  544. }
  545. // Close the db connection before sending the file
  546. $this->db->sql_close();
  547. $enc_file=bencode($dict);
  548. $size=strlen($enc_file);
  549. if (!set_modified_headers($attachment['filetime'], $this->user->browser))
  550. {
  551. if ($size)
  552. {
  553. header("Content-Length: $size");
  554. }
  555. // Try to deliver in chunks
  556. @set_time_limit(0);
  557. echo $enc_file;
  558. flush();
  559. }
  560. file_gc(false);
  561. exit;
  562. }
  563. public function get_forb_rtrack()
  564. {
  565. $forb_rtracks=array();
  566. $sql='SELECT rs.id, rs.rtracker_url rtrack_url, rt.rtracker_forb rtrack_forb, rt.forb_type FROM '.TRACKER_RTRACK_TABLE." rt, ".TRACKER_RTRACKERS_TABLE." rs WHERE rt.rtracker_id=rs.id AND rt.rtracker_enabled='1' AND rt.user_torrent_zone='0' AND rt.rtracker_remote!='0' AND rt.rtracker_type='s' AND rt.rtracker_forb!='0'";
  567. $result=$this->db->sql_query($sql, 86400);
  568. while($row=$this->db->sql_fetchrow($result))
  569. {
  570. $forb_rtracks[]=$row;
  571. }
  572. $this->db->sql_freeresult($result);
  573. return $forb_rtracks;
  574. }
  575. }