Advertisement
4455544

Untitled

Jun 28th, 2015
193
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
PHP 14.62 KB | None | 0 0
  1. class Torrent
  2. {
  3.     public $torrent;
  4.     public $info;
  5.     public $error;
  6.    
  7.     public function load( &$data )
  8.     {
  9.         $this->torrent = BEncode_new::decode( $data );
  10.  
  11.         if ( $this->torrent->get_type() == 'error' )
  12.         {
  13.             $this->error = $this->torrent->get_plain();
  14.             return false;
  15.         }
  16.         else if ( $this->torrent->get_type() != 'dictionary' )
  17.         {
  18.             $this->error = 'The file was not a valid torrent file.';
  19.             return false;
  20.         }
  21.        
  22.         $this->info = $this->torrent->get_value('info');
  23.         if ( !$this->info )
  24.         {
  25.             $this->error = 'Could not find info dictionary.';
  26.             return false;
  27.         }
  28.        
  29.         return true;
  30.     }
  31.    
  32.     public function loadPost( &$post )
  33.     {
  34.         // Decode
  35.         if ( $this->load( base64_decode( $post['raw'] ) ) == false ) {
  36.             return false;
  37.         }
  38.        
  39.         $this->setComment( $post['comment'] );
  40.         $this->setCreatedBy( $post['created_by'] );
  41.         $this->setPrivate( $post['private'] );
  42.        
  43.         if ( isset( $post['creation_date'] ) )
  44.         {
  45.             @list( $date, $time ) = explode( ' ', $post['creation_date'] );
  46.             @list( $month, $day, $year ) = explode( '/', $date );
  47.             @list( $hour, $minute, $second ) = explode( ':', $time );
  48.             $this->setCreationDate( @mktime( $hour, $minute, $second, $month, $day, $year ) );
  49.         } else
  50.         {
  51.             $this->setCreationDate( null );
  52.         }
  53.        
  54.         // Set Directory
  55.         if ( isset( $_POST['name'] ) )
  56.         {
  57.             $string = new BEncode_String( $_POST['name'] );
  58.             $this->info->set( 'name', $string );
  59.         }
  60.  
  61.         // Load files
  62.         $files = array();
  63.         while ( list( $key, $value) = each( $post ) )
  64.         {
  65.             @list( $name, $num ) = explode( '_', $key );
  66.             if ( $name == 'file' )
  67.             {
  68.                 array_push( $files, $value );
  69.             }
  70.         }
  71.         $this->setFiles( $files );
  72.  
  73.         // Load tracker list
  74.         $trackerlist = array();
  75.        
  76.         reset( $post );
  77.         while ( list( $key, $value) = each( $post ) )
  78.         {
  79.             @list( $name, $num ) = explode( '_', $key );
  80.             if ( $name == 'tracker' )
  81.             {
  82.                 if ( $value )
  83.                 {
  84.                     array_push( $trackerlist, $value );
  85.                 }
  86.             }
  87.         }
  88.         $this->setTrackers( $trackerlist );
  89.        
  90.         return true;
  91.     }
  92.    
  93.     public function getComment() {
  94.         return $this->torrent->get_value('comment') ? $this->torrent->get_value('comment')->get_plain() : null;
  95.     }
  96.    
  97.     public function getCreationDate() {
  98.         return  $this->torrent->get_value('creation date') ? $this->torrent->get_value('creation date')->get_plain() : null;
  99.     }
  100.    
  101.     public function getCreatedBy() {
  102.         return $this->torrent->get_value('created by') ? $this->torrent->get_value('created by')->get_plain() : null;
  103.     }
  104.    
  105.     public function getName() {
  106.         return $this->info->get_value('name')->get_plain();
  107.     }
  108.    
  109.     public function getPieceLength() {
  110.         return $this->info->get_value('piece length')->get_plain();
  111.     }
  112.    
  113.     public function getPieces() {
  114.         return $this->info->get_value('pieces')->get_plain();
  115.     }
  116.    
  117.     public function getPrivate() {
  118.         if ( $this->info->get_value('private') )
  119.         {
  120.             return $this->info->get_value('private')->get_plain();
  121.         }
  122.         return -1;
  123.     }
  124.    
  125.     public function getFiles() {
  126.         // Load files
  127.         $filelist = array();
  128.         $length = $this->info->get_value('length');
  129.        
  130.         if ( $length )
  131.         {
  132.             $file = new Torrent_File();
  133.             $file->name = $this->info->get_value('name')->get_plain();
  134.             $file->length =  $this->info->get_value('length')->get_plain();
  135.             array_push( $filelist, $file );
  136.         }
  137.         else if ( $this->info->get_value('files') )
  138.         {
  139.             $files = $this->info->get_value('files')->get_plain();
  140.             while ( list( $key, $value ) = each( $files ) )
  141.             {
  142.                 $file = new Torrent_File();
  143.  
  144.                 $path = $value->get_value('path')->get_plain();
  145.                 while ( list( $key, $value2 ) = each( $path ) )
  146.                 {
  147.                     $file->name .= "/" . $value2->get_plain();
  148.                 }
  149.                 $file->name = ltrim( $file->name, '/' );
  150.                 $file->length =  $value->get_value('length')->get_plain();
  151.  
  152.                 array_push( $filelist, $file );
  153.             }
  154.         }
  155.        
  156.         return $filelist;
  157.     }
  158.    
  159.    
  160.     ////////////
  161.     // SET
  162.     ///////////
  163.    
  164.     public function setTrackers( $trackerlist )
  165.     {
  166.         if ( count( $trackerlist ) >= 1 )
  167.         {
  168.             $this->torrent->remove('announce-list');
  169.             $string = new BEncode_String( $trackerlist[0] );
  170.             $this->torrent->set( 'announce', $string );
  171.         }
  172.            
  173.         if ( count( $trackerlist ) > 1 )
  174.         {
  175.             $list = new BEncode_List();
  176.            
  177.  
  178.             while ( list( $key, $value ) = each( $trackerlist ) )
  179.             {
  180.                 $list2 = new BEncode_List();
  181.                 $string = new BEncode_String( $value );
  182.                 $list2->add( $string );
  183.                 $list->add( $list2 );
  184.             }
  185.            
  186.             $this->torrent->set( 'announce-list', $list );
  187.         }
  188.     }
  189.    
  190.     public function setFiles( $filelist )
  191.     {
  192.         // Load files
  193.         $length = $this->info->get_value('length');
  194.  
  195.         if ( $length )
  196.         {
  197.             $filelist[0] = str_replace( '\\', '/', $filelist[0] );
  198.             $string = new BEncode_String( $filelist[0] );
  199.             $this->info->set( 'name', $string );
  200.         }
  201.         else if ( $this->info->get_value('files') )
  202.         {
  203.             $files = $this->info->get_value('files')->get_plain();
  204.             for ( $i = 0; $i < count( $files ); ++$i )
  205.             {
  206.                 $file_parts = split( '/', $filelist[$i] );
  207.                 $path = new BEncode_List();
  208.                 foreach ( $file_parts as $part )
  209.                 {
  210.                     $string = new BEncode_String( $part );
  211.                     $path->add( $string );
  212.                 }
  213.                 $files[$i]->set( 'path', $path );
  214.             }
  215.         }
  216.     }
  217.    
  218.     public function setComment( $value )
  219.     {
  220.         $type = 'comment';
  221.         $key = $this->torrent->get_value( $type );
  222.         if ( $value == '' ) {
  223.             $this->torrent->remove( $type );
  224.         } elseif ( $key ) {
  225.             $key->set( $value );
  226.         } else {
  227.             $string = new BEncode_String( $value );
  228.             $this->torrent->set( $type, $string );
  229.         }
  230.     }
  231.    
  232.     public function setCreatedBy( $value )
  233.     {
  234.         $type = 'created by';
  235.         $key = $this->torrent->get_value( $type );
  236.         if ( $value == '' ) {
  237.             $this->torrent->remove( $type );
  238.         } elseif ( $key ) {
  239.             $key->set( $value );
  240.         } else {
  241.             $string = new BEncode_String( $value );
  242.             $this->torrent->set( $type, $string );
  243.         }
  244.     }
  245.    
  246.     public function setCreationDate( $value )
  247.     {
  248.         $type = 'creation date';
  249.         $key = $this->torrent->get_value( $type );
  250.         if ( $value == '' ) {
  251.             $this->torrent->remove( $type );
  252.         } elseif ( $key ) {
  253.             $key->set( $value );
  254.         } else {
  255.             $int = new BEncode_Int( $value );
  256.             $this->torrent->set( $type, $int );
  257.         }
  258.     }
  259.    
  260.     public function setPrivate( $value )
  261.     {
  262.         if ( $value == -1 ) {
  263.             $this->info->remove( 'private' );
  264.         } else {
  265.             $int = new BEncode_Int( $value );
  266.             $this->info->set( 'private', $int );
  267.         }
  268.     }
  269.    
  270.     public function bencode()
  271.     {
  272.         return $this->torrent->encode();
  273.     }
  274.    
  275.     public function get_hash()
  276.     {
  277.         return strtoupper( sha1( $this->info->encode() ) );
  278.     }
  279. }
  280.  
  281. class Torrent_File
  282. {
  283.     public $name;
  284.     public $length;
  285. }
  286.  
  287. class BEncode_new
  288. {
  289.     public static function &decode( &$raw, &$offset=0 )
  290.     {  
  291.         if ( $offset >= strlen( $raw ) )
  292.         {
  293.             return new BEncode_Error( "Decoder exceeded max length." ) ;
  294.         }
  295.        
  296.         $char = $raw[$offset];
  297.         switch ( $char )
  298.         {
  299.             case 'i':
  300.                 $int = new BEncode_Int();
  301.                 $int->decode( $raw, $offset );
  302.                 return $int;
  303.                
  304.             case 'd':
  305.                 $dict = new BEncode_Dictionary();
  306.  
  307.                 if ( $check = $dict->decode( $raw, $offset ) )
  308.                 {
  309.                     return $check;
  310.                 }
  311.                 return $dict;
  312.                
  313.             case 'l':
  314.                 $list = new BEncode_List();
  315.                 $list->decode( $raw, $offset );
  316.                 return $list;
  317.                
  318.             case 'e':
  319.                 return new BEncode_End();
  320.                
  321.             case '0':
  322.             case is_numeric( $char ):
  323.                 $str = new BEncode_String();
  324.                 $str->decode( $raw, $offset );
  325.                 return $str;
  326.  
  327.             default:
  328.                 return new BEncode_Error( "Decoder encountered unknown char '$char' at offset $offset." );
  329.         }
  330.     }
  331. }
  332.  
  333. class BEncode_End
  334. {
  335.     public function get_type()
  336.     {
  337.         return 'end';
  338.     }
  339. }
  340.  
  341. class BEncode_Error
  342. {
  343.     private $error;
  344.    
  345.     public function BEncode_Error( $error )
  346.     {
  347.         $this->error = $error;
  348.     }
  349.    
  350.     public function get_plain()
  351.     {
  352.         return $this->error;
  353.     }
  354.    
  355.     public function get_type()
  356.     {
  357.         return 'error';
  358.     }
  359. }
  360.  
  361. class BEncode_Int
  362. {
  363.     private $value;
  364.    
  365.     public function BEncode_Int( $value = null )
  366.     {
  367.         $this->value = $value;
  368.     }
  369.  
  370.     public function decode( &$raw, &$offset )
  371.     {
  372.             $end = strpos( $raw, 'e', $offset );
  373.             $this->value = substr( $raw, ++$offset, $end - $offset );
  374.             $offset += ( $end - $offset );
  375.     }
  376.  
  377.     public function get_plain()
  378.     {
  379.         return $this->value;
  380.     }
  381.  
  382.     public function get_type()
  383.     {
  384.         return 'int';
  385.     }
  386.    
  387.     public function encode()
  388.     {
  389.         return "i{$this->value}e";
  390.     }
  391.    
  392.     public function set( $value )
  393.     {
  394.         $this->value = $value;
  395.     }
  396. }
  397.  
  398. class BEncode_Dictionary
  399. {
  400.     public $value = array();
  401.    
  402.     public function decode( &$raw, &$offset )
  403.     {
  404.             $dictionary = array();
  405.  
  406.             while ( true )
  407.             {
  408.                 $name = BEncode_new::decode( $raw, ++$offset );
  409.  
  410.                 if ( $name->get_type() == 'end' )
  411.                 {
  412.                     break;
  413.                 }
  414.                 else if ( $name->get_type() == 'error' )
  415.                 {
  416.                     return $name;
  417.                 }
  418.                 else if ( $name->get_type() != 'string' )
  419.                 {
  420.                     return new BEncode_Error( "Key name in dictionary was not a string." );
  421.                 }
  422.  
  423.                 $value = BEncode_new::decode( $raw, ++$offset );
  424.  
  425.                 if ( $value->get_type() == 'error' )
  426.                 {
  427.                     return $value;
  428.                 }
  429.  
  430.                 $dictionary[$name->get_plain()] = $value;
  431.             }
  432.  
  433.             $this->value = $dictionary;
  434.     }
  435.    
  436.     public function get_value( $key )
  437.     {
  438.         if ( isset( $this->value[$key] ) )
  439.         {
  440.             return $this->value[$key];
  441.         }
  442.         else
  443.         {
  444.             return null;
  445.         }
  446.     }
  447.    
  448.     public function encode()
  449.     {
  450.         $this->sort();
  451.  
  452.         $encoded = 'd';
  453.         while ( list( $key, $value ) = each( $this->value ) )
  454.         {
  455.             $bstr = new BEncode_String();
  456.             $bstr->set( $key );
  457.             $encoded .= $bstr->encode();
  458.             $encoded .= $value->encode();
  459.         }
  460.         $encoded .= 'e';
  461.         return $encoded;
  462.     }
  463.  
  464.     public function get_type()
  465.     {
  466.         return 'dictionary';
  467.     }
  468.    
  469.     public function remove( $key )
  470.     {
  471.         unset( $this->value[$key] );
  472.     }
  473.    
  474.     public function set( $key, $value )
  475.     {
  476.         $this->value[$key] = $value;
  477.     }
  478.    
  479.     private function sort()
  480.     {
  481.         ksort( $this->value );
  482.     }
  483.    
  484.     public function count()
  485.     {
  486.         return count( $this->value );
  487.     }
  488. }
  489.  
  490. class BEncode_List
  491. {
  492.     private $value = array();
  493.    
  494.     public function add( $bval )
  495.     {
  496.         array_push( $this->value, $bval );
  497.     }
  498.  
  499.     public function decode( &$raw, &$offset )
  500.     {
  501.             $list = array();
  502.  
  503.             while ( true )
  504.             {
  505.                 $value = BEncode_new::decode( $raw, ++$offset );
  506.  
  507.                 if ( $value->get_type() == 'end' )
  508.                 {
  509.                     break;
  510.                 }
  511.                 else if ( $value->get_type() == 'error' )
  512.                 {
  513.                     return $value;
  514.                 }
  515.                 array_push( $list, $value );
  516.             }
  517.  
  518.             $this->value = $list;
  519.     }
  520.    
  521.     public function encode()
  522.     {
  523.         $encoded = 'l';
  524.        
  525.         for ( $i = 0; $i < count( $this->value ); ++$i )
  526.         {
  527.             $encoded .= $this->value[$i]->encode();
  528.         }
  529.         $encoded .= 'e';
  530.         return $encoded;
  531.     }
  532.    
  533.     public function get_plain()
  534.     {
  535.         return $this->value;
  536.     }
  537.  
  538.     public function get_type()
  539.     {
  540.         return 'list';
  541.     }
  542. }
  543.  
  544. class BEncode_String
  545. {
  546.     private $value;
  547.    
  548.     public function BEncode_String( $value = null )
  549.     {
  550.         $this->value = $value;
  551.     }
  552.    
  553.     public function decode( &$raw, &$offset )
  554.     {
  555.             $end = strpos( $raw, ':', $offset );
  556.             $len = substr( $raw, $offset, $end - $offset );
  557.             $offset += ($len + ($end - $offset));
  558.             $end++;
  559.             $this->value = substr( $raw, $end, $len );
  560.     }
  561.    
  562.     public function get_plain()
  563.     {
  564.         return $this->value;
  565.     }
  566.    
  567.     public function get_type()
  568.     {
  569.         return 'string';
  570.     }
  571.    
  572.     public function encode()
  573.     {
  574.         $len = strlen($this->value);
  575.         return  "$len:{$this->value}";
  576.     }
  577.    
  578.     public function set( $value )
  579.     {
  580.         $this->value = $value;
  581.     }
  582. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement