root/announce.php

Revision 336, 15.3 kB (checked in by Nafania, 1 year ago)

Мелкие баг-фиксы. Поддержка сфинкса (корявая) в поиске торрентов. sphinxapi.php надо использовать свой - тот что лежит, только для примера.
Список файлов показывается напрямую из торрент файла, а не из базы, но таблицы пока оставлены - на всякий случай.

Line 
1 <?php</span>
2 <span class="code-lang">define('IN_ANNOUNCE', true);
3 $root_path = './';</span>
4 <span class="code-lang">require ($root_path . 'include/config.php');
5 require ($root_path . 'include/functions_announce.php');
6 require ($root_path . '/languages/lang_' . $config['default_lang'] . '/lang_announce.php');
7
8
9 $db->sql_return_on_error(true);
10
11 $updateset = $events_ary = array();
12 $current_time = time();
13 $completedat = 0;
14
15 //start receive and check main data from peer
16 $agent = ( isset($_SERVER['HTTP_USER_AGENT']) ? $_SERVER['HTTP_USER_AGENT'] : getenv('HTTP_USER_AGENT') );</span>
17 <span class="code-lang">
18 foreach ( array('passkey','info_hash','peer_id') AS $_null => $x) {
19     if( isset($_GET[$x]) ) {
20         $$x = (STRIP) ? stripslashes($_GET[$x]) : $_GET[$x];
21      }
22 }
23
24 if ( strpos($passkey, '?') ) {
25     $tmp = substr($passkey, strpos($passkey, '?'));
26     $passkey = substr($passkey, 0, strpos($passkey, '?'));
27     $tmpname = substr($tmp, 1, strpos($tmp, '=')-1);
28     $tmpvalue = substr($tmp, strpos($tmp, '=')+1);
29     $$tmpname = $tmpvalue;
30 }
31
32 if ( defined('USE_XBTT') ) {
33     benc_resp_raw('Please redownload torrent from tracker');
34 }
35
36 foreach ( array('passkey','info_hash','peer_id') AS $_null => $x ) {
37     if( !isset($$x) ) {
38          err(sprintf($lang['announce_missing_key'], $x) );
39      }
40 }
41
42 foreach ( array('port','downloaded','uploaded','left') AS $_null => $x ) {
43     if ( isset($_GET[$x]) ) {
44          $$x = 0 + $_GET[$x];
45      }
46     else {
47          err(sprintf($lang['announce_missing_key'], $x) );
48      }
49 }
50
51 preg_match_all('/event=([^&]*)/i', $_SERVER['QUERY_STRING'], $matches);</span>
52 <span class="code-lang">if ( sizeof($matches[1]) ) {
53     $events_ary = $matches[1];
54 }
55
56 $compact = ( isset($_GET['compact']) ? 1 : 0 );
57
58 $no_peer_id = ( isset($_GET['no_peer_id']) ? 1 : 0 );
59
60 $rsize = 50;</span>
61 <span class="code-lang">
62 foreach( array('num want', 'numwant', 'num_want') AS $_null => $x ) {
63     if ( isset($_GET[$x]) ) {
64         $rsize = (int) $_GET[$x];
65           break;
66      }
67 }
68
69 if ( !$port || $port > 0xffff ) {
70     err($lang['announce_invalid_port']);
71 }
72
73 foreach ( array('info_hash','peer_id') AS $_null => $x ) {
74     if ( strlen($$x) != 20 ) {
75             err(sprintf($lang['announce_invalid_parametr'], $x, strlen($$x), urlencode($$x)));
76         }
77 }
78
79 if ( strlen($passkey) != 32 ) {
80     err(sprintf($lang['announce_invalid_passkey'], strlen($passkey), $passkey));
81 }
82 //end receive and check main data from peer</span>
83 <span class="code-comment">
84 //start check bad clients
85 $bad_agents_arr = array('Gecko', 'Opera', 'MSIE', 'Links', 'Lynx', 'Mozilla', '0P3R4H');</span>
86 <span class="code-lang">for ( $i = 0; $i < sizeof($bad_agents_arr); ++$i ) {
87     if ( strpos($agent, $bad_agents_arr[$i]) !== false ) {
88         err($lang['announce_bad_client']);
89     }
90 }
91
92 if ( strpos($peer_id, 'Torrent/3') && $agent == '0' ) {
93     err($lang['announce_bad_client']);
94 }
95
96 if(substr($peer_id, 0, 4) == 'exbc' || substr($peer_id, 0, 3) == '-BC' || substr($peer_id, 1, 2) == 'TS' || substr($peer_id,-4) == 'UDP0' || substr($peer_id, 0, 3) == '-FG') {
97     err($lang['announce_client_banned']);
98 }
99 if(substr($peer_id, 0, 1) == 'A') {
100      if(substr($peer_id, 1, 3) < 300) {
101             err($lang['announce_plz_update_client']);
102      }
103 }
104 // start anti trackerpro (cheaters)
105 if ($_SERVER['HTTP_ACCEPT_ENCODING'] == 'identity' && substr($peer_id, 0, 6) == 'M4-1-3') {</span>
106 <span class="code-keyword">    err($lang['announce_bad_client']);
107 }
108 // end anti trackerpro (cheaters)</span>
109 <span class="code-comment">
110 //end check bad clients
111
112 $sql_priority = ($db_type == 'mysql') ? ' LOW_PRIORITY' : '';
113
114 //start select userdata for user
115 $sql = 'SELECT uid, uploaded, downloaded, class, hiddentorrents, parked, can_leech, torrents_limit, enabled FROM ' . USERS_TABLE . ' WHERE torrent_pass = ' . "'" . $db->sql_escape($passkey) . "'";</span>
116 <span class="code-lang">if( !($result = $db->sql_query($sql)) ) {
117         err('user select error');
118 }
119 if ( !($userdata = $db->sql_fetchrow($result)) || !$userdata['enabled'] ) {
120     err('Unknown passkey. Please redownload torrent from tracker');
121 }
122 $db->sql_freeresult($result);
123 //end select userdata for user</span>
124 <span class="code-comment">
125 //start select data for torrent
126 $sql = 'SELECT fid, banned, seeders + leechers AS numpeers, seeders, ctime, hidden, free FROM ' . TORRENTS_TABLE . ' WHERE ' . hash_where('info_hash', $info_hash);</span>
127 <span class="code-lang">if( !($result = $db->sql_query($sql)) ) {
128         err('torrent select error');
129 }
130 if ( !($torrentdata = $db->sql_fetchrow($result)) ) {
131     err('Torrent not registered with this tracker');
132 }
133 $db->sql_freeresult($result);
134 //end select data for torrent
135
136 $fields = 'peer_id, `left`, ip, port, uploaded, downloaded, uid, mtime';</span>
137 <span class="code-lang">
138 if ( $torrentdata['numpeers'] ) {
139
140     $limit = ( $torrentdata['numpeers'] > $rsize ? ' LIMIT ' . $rsize : '' );
141
142     $sql = 'SELECT ' . $fields . ' FROM ' . PEERS_TABLE . ' WHERE fid = ' . $torrentdata['fid'] . $limit;
143     if( !($result = $db->sql_query($sql)) ) {
144         err('peer select error');
145     }
146
147     $resp = 'd' . benc_str('interval') . 'i' . $config['announce_interval'] . 'e' . benc_str('min interval') . 'i' . $config['min_announce_interval'] . ( !$compact ? 'e' . benc_str('peers') . 'l' : 'e5:peers');
148     $peer = array();
149     $peer_num = 0;
150     while ( $row = $db->sql_fetchrow($result) ) {
151         $row['peer_id'] = hash_pad($row['peer_id']);
152         $peer_id_replaced = str_replace(' ', '', $row['peer_id']);
153         if ( $row['peer_id'] == $peer_id || $peer_id_replaced == $peer_id ) {
154             $self = $row;
155             continue;
156         }
157         if( !$compact ) {
158             $resp .= 'd' . benc_str('ip') . benc_str($row['ip']);
159             if ( !$no_peer_id ) {
160                 $resp .= benc_str('peer id') . benc_str($row['peer_id']);
161             }
162             $resp .= benc_str('port') . 'i' . $row['port'] . 'ee';
163         }
164         else {
165             $peer_ip = explode('.', $row['ip']);
166             $peer_ip = pack('C*', $peer_ip[0], $peer_ip[1], $peer_ip[2], $peer_ip[3]);
167             $peer_port = pack('n*', intval($row['port']));
168             $time = intval(($current_time % 7680) / 60);
169             if( !$left ) {
170                 $time += 128;
171             }
172             $time = pack('C', $time);
173             $peer[] = $time . $peer_ip . $peer_port;
174             $peer_num++;
175         }
176     }
177     $db->sql_freeresult($result);
178
179     if ( !$compact ) {
180         $resp .= 'ee';
181     }
182     else {
183         $o = '';
184         for( $i = 0; $i < $peer_num; $i++ ) {
185             $o .= substr($peer[$i], 1, 6);
186         }
187         $resp .= benc_str($o) . 'e';
188     }
189 }
190 else {
191     $resp = 'd' . benc_str('interval') . 'i' . $config['announce_interval'] . 'e' . benc_str('min interval') . 'i' . $config['min_announce_interval'] . ( !$compact ? 'e' . benc_str('peers') . 'l' : 'e5:peers0:e');
192 }
193 $selfwhere = 'fid = ' . $torrentdata['fid'] . ' AND ' . hash_where('peer_id', $peer_id);</span>
194 <span class="code-lang">
195 if ( !isset($self) ) {
196     $sql = 'SELECT ' . $fields . ' FROM ' . PEERS_TABLE . ' WHERE ' . $selfwhere;
197         if( !$result = $db->sql_query($sql) ) {
198                 err('peer select error');
199         }
200         if ( $row = $db->sql_fetchrow($result) ) {
201                 $self = $row;
202         }
203         $db->sql_freeresult($result);
204 }
205
206 if ( in_array('completed', $events_ary) ) {
207     $completedat = $current_time;
208     $updateset[] = 'completed = completed + 1';
209 }
210
211 //start user not in peers table, it's first connect. let's insert data
212 if ( !isset($self) ) {</span>
213 <span class="code-keyword">    //start hidden torrent check
214     if ( $torrentdata['hidden'] && ( !$userdata['hiddentorrents'] && $userdata['class'] < UC_MODERATOR ) ) {
215         err('Hash not recognized with user! Hide!');
216     }
217     //end hidden torrent check
218
219     //start seed & leech limits check
220     /*$leech_count = $seed_count = 0;
221     $sql = 'SELECT `left`, COUNT(*) AS c FROM ' . PEERS_TABLE . ' WHERE uid = ' . $userdata['uid'] . ' GROUP BY fid';
222     $result = $db->sql_query($sql);
223     if ( $row = $db->sql_fetchrow($result) ) {
224         do {
225             if ( $row['left'] ) {
226                 $leech_count = $leech_count + $row['c'];
227             }
228             else {
229                 $seed_count = $seed_count + $row['c'];
230             }
231         }
232         while ( $row = $db->sql_fetchrow($result) );
233     }
234     $db->sql_freeresult($result);
235
236     if ( $left ) {
237         if ( !empty($userdata['torrents_limit']) && $userdata['can_leech'] && ( $leech_count >= $userdata['torrents_limit'] ) ) {
238             err('Vi kachaete slishkom mnogo torrentov! Odnovremenno mozhno kachat ' . $userdata['torrents_limit'] . ' torrentov');
239         }
240      }
241     elseif ( !empty($config['max_torrent_allow_seed']) && ( $seed_count >= $config['max_torrent_allow_seed'] ) && $userdata['class'] < UC_UPLOADER ) {
242         err('Vi sidiruete slishkom mnogo torrentov. Odnovremenno mozhno sidirovat ' . $config['max_torrent_allow_seed'] . ' torrentov');
243      }*/
244     //end seed & leech limits check
245
246     //start wait time check
247     if ( $config['waittime'] && $left && $userdata['class'] < UC_VIP ) {
248          $gigs = $userdata['uploaded'] / (1024*1024*1024);
249         $elapsed = floor(($current_time - $torrentdata['ctime']) / 3600);
250         $ratio = (($userdata['downloaded'] > 0) ? ($userdata['uploaded'] / $userdata['downloaded']) : 1);
251         if ($ratio < 0.5 || $gigs < 5) {
252             $wait = 48;
253         }
254         elseif ($ratio < 0.65 || $gigs < 6.5) {
255             $wait = 24;
256         }
257         elseif ($ratio < 0.8 || $gigs < 8) {
258             $wait = 12;
259         }
260         elseif ($ratio < 0.95 || $gigs < 9.5) {
261             $wait = 6;
262         }
263         else {
264              $wait = 0;
265         }
266         if ( $elapsed < $wait ) {
267             err('Vam nado podozhdat (' . ($wait - $elapsed) . ' chasov) - Prochtite FAQ!');
268         }
269     }
270      //end wait time check
271
272     //start parked check
273     if ( $userdata['parked'] ) {
274         err('Error, your account is parked! Please read the FAQ!');
275      }
276      //end parked check
277
278      //start can leech check
279      if ( !$userdata['can_leech'] && $left ) {
280          err('Vi ne mozhete kachat torrenti.');
281      }
282      //end can leech check
283
284     //start insert data into peers table
285     $sql = 'INSERT INTO ' . PEERS_TABLE . ' ' . $db->sql_build_array('INSERT', array(
286             'fid'           => $torrentdata['fid'],
287             'peer_id'       => $peer_id,
288             'ip'        => $user_ip,
289             'port'      => $port,
290             'uploaded'      => $uploaded,
291             'downloaded'    => $downloaded,
292             '`left`'    => $left,
293             'started'       => $current_time,
294             'mtime'     => $current_time,
295             'uid'       => $userdata['uid'],
296             'useragent'     => $agent ));
297
298     if ( $db->sql_query($sql) ) {
299         if ( !$left ) {
300             $updateset[] = 'seeders = seeders + 1';
301             if ( !$torrentdata['seeders'] ) {
302                 $updateset[] = 'visible = 1';
303             }
304         }
305         else {
306             $updateset[] = 'leechers = leechers + 1';
307         }
308     }
309     else {
310         err('Insert peers error');
311     }
312     //end insert data into peers table
313
314
315     //only for mysql
316
317     $sql = 'INSERT INTO ' . SNATCHED_TABLE . ' ' . $db->sql_build_array('INSERT', array(
318             'torrentid'     => $torrentdata['fid'],
319             'userid'    => $userdata['uid'],
320             'uploaded'      => $uploaded,
321             'downloaded'    => $downloaded,
322             'last_action'   => $current_time,
323             'completedat' => $completedat,
324         )) .
325         ' ON DUPLICATE KEY UPDATE
326         last_action = VALUES(last_action),
327         uploaded = uploaded + VALUES(uploaded),
328         downloaded = downloaded + VALUES(downloaded),
329         completedat = if(values(completedat) = 0, completedat, ' . $current_time . ')';
330     if ( !$db->sql_query($sql) ) {
331         $error = $db->sql_error();
332         err('Update snatched error');
333     }
334
335 }
336 //end user not in peers table, it's first connect. let's insert data</span>
337 <span class="code-comment">
338 //start user already in peers table, it's first connect. let's update data
339 else {</span>
340 <span class="code-keyword">    $user_uploaded = $upthis = max(0, $uploaded - $self['uploaded']);
341     $user_downloaded = $downthis = max(0, $downloaded - $self['downloaded']);
342     $current_total_time = 0;
343     if ( $torrentdata['free'] ) {
344         switch ( $torrentdata['free'] ) {
345             case 1:
346                 $user_downloaded = 0;
347             break;
348             case 2:
349                 $user_downloaded = round($user_downloaded * 0.50);
350             break;
351             case 4:
352                 $user_downloaded = round($user_downloaded * 0.75);
353             break;
354         }
355     }
356
357     if ( $userdata['class'] == UC_VIP ) {
358         $user_uploaded = 0;
359         $user_downloaded = 0;
360     }
361
362     if ( !$left && $self['mtime'] < $current_time ) {
363         $sql = 'SELECT COUNT(*) AS count FROM ' . PEERS_TABLE . ' WHERE `left` = 0 AND uid = ' . $userdata['uid'];
364         $result = $db->sql_query($sql);
365         $count = ( $row = $db->sql_fetchrow($result) ) ? $row['count'] : 0;
366         if ( $count ) {
367             $current_total_time = round( ( ( $current_time - $self['mtime'] ) / $count ) );
368         }
369     }
370
371     if ( $user_uploaded > 0 || $user_downloaded > 0 || $current_total_time > 0 ) {
372         $sql = 'UPDATE' . $sql_priority . ' ' . USERS_TABLE . ' SET
373                 uploaded = uploaded + ' $user_uploaded . ',
374                 downloaded = downloaded + ' . $user_downloaded . ',
375                 total_seed_time = total_seed_time + ' . $current_total_time . '
376                 WHERE uid = ' . $userdata['uid'];
377         if( !$db->sql_query($sql) ) {
378             err('Up/Down Stats Error');
379         }
380         // Initial sanity check xMB/s for 1 second
381         if( $upthis > 2097152 && $self['mtime'] < $current_time ) {
382             //Work out time difference
383             $endtime = $current_time;
384             $starttime = $self['mtime'];
385             $diff = ($endtime - $starttime);
386             //Normalise to prevent divide by zero.
387             $rate = ($upthis / ($diff + 1));
388             //Currently 2MB/s. Increase to 5MB/s once finished testing.
389             if ($rate > 2097152) {
390                 if ($userdata['class'] < UC_MODERATOR) {
391                     $sql = 'INSERT INTO ' . CHEATERS_TABLE . ' ' . $db->sql_build_array('INSERT', array(
392                            'added'     => $current_time,
393                            'userid'    => $userdata['uid'],
394                            'rate'      => $rate,
395                            'beforeup'      => $userdata['uploaded'],
396                            'upthis'    => $upthis,
397                            'timediff'      => $diff,
398                            'userip'    => $user_ip,
399                            'torrentid'     => $torrentdata['fid'],
400                            'che_useragent' => $agent,
401                            'che_peer_id'   => $peer_id));
402                     if( !($db->sql_query($sql)) ) {
403                         err('Check Error');
404                     }
405                 }
406             }
407         }
408     }
409
410     $upd_sql =  ( $upthis ? 'uploaded = uploaded + ' $upthis . ',' : '' );
411     $upd_sql .= ( $downthis ? 'downloaded = downloaded + ' . $downthis . ',' : '' );
412     $upd_sql .= ( $completedat ? 'completedat = ' . $completedat . ',' : '' );
413     $sql = 'UPDATE' . $sql_priority . ' ' . SNATCHED_TABLE . ' SET ' . $upd_sql . ' last_action = ' . $current_time . ' WHERE torrentid = ' . $torrentdata['fid'] . ' AND userid = ' . $userdata['uid'];
414
415     if( !$db->sql_query($sql) ) {
416         err('Update snatched error');
417     }
418
419     if ( in_array('stopped', $events_ary) ) {
420         $sql = 'DELETE FROM ' . PEERS_TABLE . ' WHERE ' . $selfwhere;
421         $result = $db->sql_query($sql);
422         if ( $db->sql_affectedrows($result) ) {
423             if ( !$self['left'] ) {
424                 $updateset[] = 'seeders = seeders - 1';
425                 if ( $torrentdata['seeders'] == 1 ) {
426                     $updateset[] = 'visible = 0';
427                 }
428             }
429             else {
430                 $updateset[] = 'leechers = leechers - 1';
431             }
432         }
433      }
434     else {
435         $secs = $current_time - $self['mtime'];
436         $uprate = ( $secs ? round($upthis / $secs) : 0 ); //we calculate upl speed for last session
437         $downrate = ( $left ? ( $secs ? round($downthis / $secs) : 0 ) : 0 ); //we calculate down speed for last session
438
439         $sql = 'UPDATE ' . PEERS_TABLE . ' SET ' . $db->sql_build_array('UPDATE', array(
440                'uploaded'   => $uploaded,
441                'upspeed'    => $uprate,
442                'downloaded' => $downloaded,
443                'downspeed'  => $downrate,
444                'port'       => $port,
445                '`left`'     => $left,
446                'mtime'      => $current_time )) .
447                ' WHERE ' . $selfwhere;
448
449         if( !$db->sql_query($sql) ) {
450             err('Update peers error');
451         }
452         if ( $db->sql_affectedrows() && $self['left'] != $left && !$left ) {
453             $updateset[] = 'seeders = seeders + 1';
454             $updateset[] = 'leechers = leechers - 1';
455             if ( !$torrentdata['seeders'] ) {
456                 $updateset[] = 'visible = 1';
457             }
458         }
459     }
460 }
461 //end user already in peers table, it's first connect. let's update data
462
463 if ( !$left ) {</span>
464 <span class="code-keyword">    $updateset[] = 'mtime = ' . $current_time;
465 }
466
467 if ( sizeof($updateset) ) {
468     $sql = 'UPDATE' . $sql_priority . ' ' . TORRENTS_TABLE . ' SET ' . implode(',', $updateset) . ' WHERE fid = ' . $torrentdata['fid'];
469     if( !($db->sql_query($sql)) ) {
470         err('Update torrents error');
471     }
472 }
473 benc_resp_raw($resp);
474 ?>
475
Note: See TracBrowser for help on using the browser.