Totoka

PKO - PHP Bag manager

Oct 4th, 2016
308
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
PHP 12.05 KB | None | 0 0
  1. # By @Totoka at pkodev.net
  2.  
  3. class Item
  4. {
  5.     protected $id           = 0;
  6.     protected $count        = 0;
  7.     protected $min_endure   = 0;
  8.     protected $max_endure   = 0;
  9.     protected $min_energy   = 0;
  10.     protected $max_energy   = 0;
  11.     protected $forge_level  = 0;
  12.     protected $dbid         = 0;
  13.     protected $dbparam1     = 0;
  14.     protected $dbparam2     = 0;
  15.     protected $instance     = 0; # 0 | 1
  16.     # if is an item instance == 1 {
  17.     protected $attr_id      = []; # array of attribute ids
  18.     protected $attr_value   = []; # array of attribute values
  19.     # }
  20.  
  21.     private function __construct()
  22.     {
  23.  
  24.     }
  25.  
  26.     public static function Create($itemid, $count)
  27.     {
  28.         $item = new Item;
  29.         $item->id = $itemid;
  30.         $item->count = $count;
  31.         return $item;
  32.     }
  33.  
  34.     public static function fromString($rawitem)
  35.     {
  36.         $value = explode(',', $rawitem);
  37.         $count = count($value);
  38.  
  39.         $item = new Item;
  40.         if( $count > 10 )
  41.         {
  42.             $item->id           = $value[ 0];
  43.             $item->count        = $value[ 1];
  44.             $item->min_endure   = $value[ 2];
  45.             $item->max_endure   = $value[ 3];
  46.             $item->min_energy   = $value[ 4];
  47.             $item->max_energy   = $value[ 5];
  48.             $item->forge_level  = $value[ 6];
  49.             $item->dbid         = $value[ 7];
  50.             $item->dbparam1     = $value[ 8];
  51.             $item->dbparam2     = $value[ 9];
  52.             $item->instance     = $value[10];
  53.  
  54.             for( $i=11; $i<$count; $i+=2 )
  55.             {
  56.                 $item->attr_id[]    = $value[ $i + 0 ];
  57.                 $item->attr_value[] = $value[ $i + 1 ];
  58.             }
  59.         } return $item;
  60.     }
  61.  
  62.     public function id()
  63.     {
  64.         return $this->id;
  65.     }
  66.  
  67.     public function count()
  68.     {
  69.         return $this->count;
  70.     }
  71.  
  72.     public function setEndure($min,$max)
  73.     {
  74.         $this->min_endure = $min;
  75.         $this->max_endure = $max;
  76.     }
  77.  
  78.     # returns an object with max and min properties
  79.     # $obj->min | $obj->max
  80.     public function endure()
  81.     {
  82.         return (object)[
  83.             'min'=>$this->min_endure,
  84.             'max'=>$this->max_endure
  85.         ];
  86.     }
  87.  
  88.     public function setEnergy($min,$max)
  89.     {
  90.         $this->min_energy = $min;
  91.         $this->max_energy = $max;
  92.     }
  93.  
  94.     # returns an object with max and min properties
  95.     # $obj->min | $obj->max
  96.     public function energy()
  97.     {
  98.         return (object)[
  99.             'min'=>$this->min_energy,
  100.             'max'=>$this->max_energy
  101.         ];
  102.     }
  103.  
  104.  
  105.     public function setForgeLv($lv)
  106.     {
  107.         $this->forge_level = $lv;
  108.     }
  109.  
  110.  
  111.     public function forgeLv()
  112.     {
  113.         return $this->forge_level;
  114.     }
  115.  
  116.  
  117.     public function setDbID($id)
  118.     {
  119.         $this->dbid = $id;
  120.     }
  121.  
  122.  
  123.     public function dbid()
  124.     {
  125.         return $this->dbid;
  126.     }
  127.  
  128.     public function setParam1($param)
  129.     {
  130.         $this->dbparam1 = $param;
  131.     }
  132.  
  133.     public function param1()
  134.     {
  135.         return $this->dbparam1;
  136.     }
  137.  
  138.     public function setParam2($param)
  139.     {
  140.         $this->dbparam2 = $param;
  141.     }
  142.  
  143.     public function param2()
  144.     {
  145.         return $this->dbparam2;
  146.     }
  147.  
  148.     # return false if @index is out of range [ 0 - 4 ]
  149.     public function setAttr($index,$attrid,$value)
  150.     {
  151.         # instanced items can hold up to 5 attributes
  152.         if($index<0||$index>4) return false;
  153.         if(!$this->instance) {
  154.             $this->attr_id[0] = $this->attr_value[0] = 0;
  155.             $this->attr_id[1] = $this->attr_value[1] = 0;
  156.             $this->attr_id[2] = $this->attr_value[2] = 0;
  157.             $this->attr_id[3] = $this->attr_value[3] = 0;
  158.             $this->attr_id[4] = $this->attr_value[4] = 0;
  159.         } $this->instance = 1;
  160.         $this->attr_id[$index] = $attrid;
  161.         $this->attr_value[$index] = $value;
  162.         return true;
  163.     }
  164.  
  165.     # if @index exists
  166.     #  returns an object with properties id and value
  167.     # return null if this index not exists, or is not used.
  168.     # or false if @index is out of range [ 0 - 4 ]
  169.     #  $obj->id
  170.     #  $obj->value
  171.     public function attr($index)
  172.     {
  173.         if($index<0||$index>4) return false;
  174.         if(isset($this->attr_id[$index]))
  175.         {
  176.             return (object)[
  177.                 'id'    => $this->attr_id[$index],
  178.                 'value' => $this->attr_value[$index]
  179.             ];
  180.         } return null;
  181.     }
  182.  
  183.     public function getCRC32()
  184.     {
  185.         return sprintf("%d",
  186.             $this->id
  187.             + $this->count
  188.             + $this->min_endure
  189.             + $this->max_endure
  190.             + $this->min_energy
  191.             + $this->max_energy
  192.             + $this->forge_level
  193.             + $this->dbid
  194.             + $this->dbparam1
  195.             + $this->dbparam2
  196.             + array_sum($this->attr_id)
  197.             + array_sum($this->attr_value));
  198.     }
  199.  
  200.     public function Serialize()
  201.     {
  202.         $str = sprintf("%d,%d,%d,%d,%d,%d,%d,%d,%d,%d",
  203.             $this->id,   #  ^  ^  ^  ^  ^  ^  ^  ^  ^
  204.             $this->count,   #  |  |  |  |  |  |  |  |
  205.             $this->min_endure, #  |  |  |  |  |  |  |
  206.             $this->max_endure,    #  |  |  |  |  |  |
  207.             $this->min_energy,       #  |  |  |  |  |
  208.             $this->max_energy,          #  |  |  |  |
  209.             $this->forge_level,            #  |  |  |
  210.             $this->dbid,                      #  |  |
  211.             $this->dbparam1,                     #  |
  212.             $this->dbparam2                         #
  213.         );
  214.  
  215.         $count = count($this->attr_id);
  216.  
  217.         # if has any attribute
  218.         # flag this item as an special instance.
  219.         $str.=sprintf(",%d",($count > 0? '1' : '0'));
  220.  
  221.         for( $i=0; $i<$count; $i++ )
  222.         {
  223.             $str.=sprintf(",%d,%d",
  224.                 $this->attr_id[ $i ],
  225.                 $this->attr_value[ $i ]
  226.             );
  227.         } return $str;
  228.     }
  229. }
  230.  
  231. class Bag
  232. {
  233.     # decrypted bag
  234.     # used by constructor, Parse & Serialize
  235.     protected $rawdec;
  236.  
  237.     # flag
  238.     protected $is_empty = true;
  239.     protected $crc32_ok = false;
  240.  
  241.     # raw content header
  242.     protected $capacity = 0;
  243.     protected $version  = 0;
  244.     protected $page     = 0;
  245.     protected $count    = 0;
  246.     protected $items    = 0;
  247.  
  248.     # @rawbag = sql @content field from @resource table.
  249.     public function __construct($rawbag)
  250.     {
  251.         # decrypt
  252.         $key = '19800216';
  253.         $hlh = strpos($rawbag, '#') + 1;
  254.         $len = strlen($rawbag) - $hlh;
  255.  
  256.         $this->rawdec = substr($rawbag, 0, $hlh);
  257.         for($i=0; $i<$len; $i++)
  258.         {
  259.             $chc = substr($rawbag,$i+$hlh,1);
  260.             $chk = substr($key,$i%8,1);
  261.             $this->rawdec .= chr( ord($chc) - ord($chk) );
  262.         }
  263.     }
  264.  
  265.     # uses previously loaded @rawdec within the constructor
  266.     public function parse()
  267.     {
  268.         # sets the bag defaults to be empty
  269.         $this->is_empty = true;
  270.  
  271.         # reset the item counter
  272.         $this->count = 0;
  273.  
  274.         # retreive bag capacity
  275.         $capacity = explode('@', $this->rawdec, 2);
  276.         if(count($capacity) < 2) {
  277.             return false;
  278.         } $this->capacity = $capacity[0];
  279.  
  280.         # retreive bag version
  281.         $version = explode('#', $capacity[1], 2); # dangerous index 1
  282.         if(count($version) < 2) {
  283.             return false;
  284.         } $this->version = $version[0];
  285.  
  286.         # retreive bag page
  287.         $page = explode(';', $version[1], 3); # dangerous index 1
  288.         if(count($page) < 3) {
  289.             return false;
  290.         } $this->page = $page[0];
  291.  
  292.         # retrieve items count, and data
  293.         $items = explode(';', $page[2]); # dangerous index 2
  294.         $count = count($items);
  295.        
  296.         # initialize the array of items.
  297.         $this->items = array_fill(0, $this->capacity, false);
  298.        
  299.         # will return on empty bags
  300.         # 2 elements are required as minimum to continue
  301.         if( $count < 2 ) {
  302.             # true if empty, false on error
  303.             return $count - 1 == $page[1];
  304.         }
  305.  
  306.         # checks the minimum amount of parsed elements within the array
  307.         if( $count - 1 != $page[1] ) {
  308.             return false;
  309.         }
  310.        
  311.         for( $i=0; $i<$count-1; $i++)
  312.         {
  313.             $index = explode(',', $items[$i], 2);
  314.             if( $index < 2 ) {
  315.                 continue;
  316.             }
  317.             $item = Item::fromString( $index[1] );
  318.             if( $item->getCRC32() ) {
  319.                 $this->items[ $index[0] ] = $item;
  320.             } $this->count++;
  321.         }
  322.  
  323.         $this->is_empty = $this->count == 0;
  324.  
  325.         # return true if the computed CRC32 is same as
  326.         # the retreived one from the resource.
  327.         return $this->crc32_ok
  328.             = $items[ $count - 1 ] == $this->getCRC32();
  329.     }
  330.  
  331.     # Returns maximum capacity of items
  332.     public function capacity()
  333.     {
  334.         return $this->capacity;
  335.     }
  336.  
  337.     # Retrieve raw list of item.
  338.     # Do not modify the array itself, instead, modify its items;
  339.     public function items()
  340.     {
  341.         return $this->items;
  342.     }
  343.  
  344.     # Tries to add an @item to our bag.
  345.     # It returns true on success
  346.     public function push(Item $item)
  347.     {
  348.         $ret = false;
  349.  
  350.         for($i=0;$i<$this->capacity;$i++)
  351.         {
  352.             if($this->items[$i] == false)
  353.             {
  354.                 $this->items[$i] = $item;
  355.                 $this->count++;
  356.                 $ret = true;
  357.                 break;
  358.             }
  359.         } return $ret;
  360.     }
  361.  
  362.     # Return true if removed with success
  363.     public function pop($index)
  364.     {
  365.         $ret = false;
  366.         for($i=$index;$i<$this->capacity;$i++)
  367.         {
  368.             if($this->items[$i] != false)
  369.             {
  370.                 $this->items[$i] = false;
  371.                 $this->count--;
  372.                 $ret = true;
  373.                 break;
  374.             }
  375.         } return $ret;
  376.     }
  377.  
  378.     # Returns amount of free slots
  379.     public function getFreeSlots()
  380.     {
  381.         $n = 0;
  382.         for($i=0;$i<$this->capacity;$i++)
  383.         {
  384.             if($this->items[$i] == false)
  385.             {
  386.                 $n++;
  387.             }
  388.         } return $n;
  389.     }
  390.  
  391.     # calculate the CRC32 bag within it's items
  392.     public function getCRC32()
  393.     {
  394.         $n = $this->page;
  395.         $tmp = 0;
  396.         for($i=0;$i<$this->capacity;$i++)
  397.         {
  398.             if($this->items[$i])
  399.             {
  400.                 $tmp = $this->items[$i]->getCRC32();
  401.                 $n += $tmp;
  402.             }
  403.         } return sprintf("%d",$n);
  404.     }
  405.  
  406.     # turns this object into an string
  407.     public function Serialize()
  408.     {
  409.         $str = $this->capacity;
  410.         $str.= '@'. $this->version;
  411.         $str.= '#'. $this->page;
  412.         $str.= ';'. $this->count;
  413.  
  414.         for($i=0;$i<$this->capacity;$i++)
  415.         {
  416.             if($this->items[$i])
  417.             {
  418.                 $str.= ';'. $i;
  419.                 $str.= ','. $this->items[$i]->Serialize();
  420.             }
  421.         }
  422.  
  423.         $str.= ';'. $this->getCRC32();
  424.         return $this->rawdec = $str;
  425.     }
  426.  
  427.     public function Encrypt()
  428.     {
  429.         $key = '19800216';
  430.         $hlh = strpos($this->rawdec, '#') + 1;
  431.         $len = strlen($this->rawdec) - $hlh;
  432.  
  433.         $ret = substr($this->rawdec, 0, $hlh);
  434.         for($i=0; $i<$len; $i++)
  435.         {
  436.             $chc = substr($this->rawdec,$i+$hlh,1);
  437.             $chk = substr($key,$i%8,1);
  438.             $ret .= chr( ord($chc) + ord($chk) );
  439.         } return $ret;
  440.     }
  441. };
  442.  
  443. #################################################################
  444. # USAGE
  445. #################################################################
  446. # create our bag based on an entry from gamedb resource->content
  447. # decryption is performed at construction time
  448. $bag = new Bag( '24@114#btik`^gfakda\b]f]id`\b]f]id`\bllail' );
  449.  
  450. ##################################
  451. # parse previously decrypted data
  452. if( $bag->parse() == false ) {
  453.     die('parsing error, malformed or not supported data.');
  454. }
  455.  
  456. ##################################
  457. # bag information
  458. echo '= Bag Information =' . PHP_EOL;
  459. echo '= Free slots: '. $bag->getFreeSlots() . PHP_EOL;
  460. echo '= CRC32: '. $bag->getCRC32() . PHP_EOL . PHP_EOL;
  461.  
  462. ##################################
  463. # inserting items:
  464. # it does not check against an iteminfo.txt
  465. # becareful using count, and others attributes.
  466. $item = Item::Create(
  467.     /*ID    */   1, // id short sword
  468.     /*COUNT */   1);
  469.  
  470. ##################################
  471. # give it min/max duration
  472. # ~ ratio 50/1
  473. $item->setEndure(50*200,50*200);
  474.  
  475. ##################################
  476. # give also some strength
  477. # use attribute slot 0 [ 0 - 4 ]
  478. # with attribute id 26 ( STR )
  479. # and value 100
  480. $item->setAttr(0,26,100);
  481.  
  482. ##################################
  483. # add 3 sockets
  484. $item->setParam1(3000000000);
  485.  
  486. ##################################
  487. # add previous created item to our bag
  488. if( $bag->push($item) == false )
  489. {
  490.     die('unable to add an item, the bag is full');
  491. }
  492.  
  493. ##################################
  494. # iterate through each items within the bag
  495. $bagItems = $bag->items();
  496. foreach ($bagItems as $index => $slot) {
  497.     # check if there is an item within this slot
  498.     if( $slot )
  499.     { # it will be false if there is no item.
  500.         # print item's information
  501.         $x = null;
  502.         echo '= Item is being printed =' . PHP_EOL;
  503.         echo '= Slot #: '. $index . PHP_EOL;
  504.         echo '= ID: '. $slot->id() . PHP_EOL;
  505.         echo '= Count: '. $slot->count() . PHP_EOL;
  506.         $x=$slot->endure();
  507.         echo '= Endure: '. $x->min . '/' . $x->max . PHP_EOL;
  508.         $x=$slot->energy();
  509.         echo '= Energy: '. $x->min . '/' . $x->max . PHP_EOL;
  510.         echo '= Forge Level: '. $slot->forgeLv() . PHP_EOL;
  511.         echo '= DBID: '. $slot->dbid() . PHP_EOL;
  512.         echo '= DBParam1: '. $slot->param1() . PHP_EOL;
  513.         echo '= DBParam2: '. $slot->param2() . PHP_EOL;
  514.  
  515.         if( $slot->id() == 1234 )
  516.         {
  517.             # removes item from bag
  518.             # with id 1234
  519.             if($bag->pop($index) == false)
  520.             {
  521.                 die('= Item can not be removed');
  522.             }
  523.         } echo PHP_EOL;
  524.     }
  525. }
  526.  
  527. ##################################
  528. # turn the bag into string
  529. echo '= BAG To string: '. $bag->Serialize() . PHP_EOL . PHP_EOL;
  530.  
  531. ##################################
  532. # bag encryption
  533. die( '= BAG Encrypted: '. $bag->Encrypt() );
  534. #################################################################
Add Comment
Please, Sign In to add comment