/**
  * Show the form for editing the specified room.
  *
  * @param int $id
  * @param int $channelId
  * @return Response
  */
 public function getMap($id, $channelId)
 {
     $room = Room::find($id);
     $channelSettings = PropertiesChannel::getSettings($channelId, Property::getLoggedId());
     $channel = ChannelFactory::create($channelSettings);
     $result = $channel->getInventoryList();
     //todo temp
     //        file_put_contents('1.txt', serialize($result));
     //        $result = unserialize(file_get_contents('1.txt'));
     //add Inventories and Plans to DB//TODO move to another place
     //delete exist maps
     Inventory::where(['channel_id' => $channelId, 'property_id' => $channelSettings->property_id])->delete();
     //delete exist plan maps
     InventoryPlan::where(['channel_id' => $channelId, 'property_id' => $channelSettings->property_id])->delete();
     if ($result) {
         foreach ($result as $inventory) {
             Inventory::create(['code' => $inventory['code'], 'name' => $inventory['name'], 'channel_id' => $channelId, 'property_id' => $channelSettings->property_id]);
             if ($inventory['plans']) {
                 foreach ($inventory['plans'] as $plan) {
                     InventoryPlan::create(['code' => $plan['code'], 'name' => $plan['name'], 'channel_id' => $channelId, 'inventory_code' => $inventory['code'], 'property_id' => $channelSettings->property_id]);
                 }
             }
         }
     }
     $existMapping = [];
     //        $mapCollection = InventoryMap::where(
     //            [
     //                'channel_id' => $channelId,
     //                'property_id' => $channelSettings->property_id
     //            ]
     //        )
     ////            ->where('room_id', '<>', $id)
     //            ->lists('inventory_code', 'room_id');
     //        if ($mapCollection) {
     //            foreach ($mapCollection as $map) {
     //                $existMapping[] = $map;
     //            }
     //        }>F
     $inventories = Channel::find($channelId)->inventory()->where('property_id', Property::getLoggedId());
     $inventoryList = [];
     $inventoryPlans = [];
     foreach ($inventories->get() as $inventory) {
         //            if (in_array($inventory->code, $existMapping)) {
         //                continue;
         //            }
         $inventoryList[$inventory->code] = $inventory->name;
         $plans = $inventory->plans()->get(['name', 'code']);
         for ($i = 0; $i < count($plans); $i++) {
             //TODO rewrite to ONE query
             $plans[$i]->selected = InventoryMap::getByKeys($channelId, $channelSettings->property_id, $id, $plans[$i]['code'])->first() ? true : false;
         }
         $inventoryPlans[$inventory->code] = $plans;
     }
     $inventoryPlans = json_encode($inventoryPlans);
     $mapping = InventoryMap::getByKeys($channelId, $channelSettings->property_id, $id)->first();
     return View::make('rooms.map', compact('room', 'channel', 'inventoryList', 'inventoryPlans', 'channelId', 'mapping'));
 }
Esempio n. 2
0
 /**
  * Update the specified resource in storage.
  *
  * @param  int  $id
  * @return Response
  */
 public function update()
 {
     $input = Input::all();
     $id = $input['rowId'];
     $data = array('product_id' => $input['edit_pro_name'], 'eng_no' => $input['editEngineNo'], 'chs_no' => $input['edit_chs_no'], 'color' => $input['edit_pro_color'], 'buy_rate' => $input['edit_pro_buy_rate'], 'sell_rate' => $input['edit_pro_sell_rate']);
     $update = Inventory::where('id', '=', $id)->update($data);
     if ($update) {
         return json_encode(array('error' => 0, 'success' => 1));
     } else {
         return json_encode(array('error' => 1, 'success' => 0));
     }
 }
 public function Set_Player_Inventory($db_id, $input)
 {
     if (Cache::has($this->class_name . "_" . $db_id . "_Inventory_MD5")) {
         //check the input MD5 against this
         if (md5($input) == Cache::get($this->class_name . "_" . $db_id . "_Inventory_MD5")) {
             return true;
         }
     } else {
         //If we have gotten to this point than we either don't have a cache on file or the data is not the same so update/insert and build cache
         $last_inventory_update = Inventory::where(function ($query) use($db_id) {
             $query->where('db_id', '=', $db_id);
             $query->where(DB::raw('DATE(updated_at)'), '=', $this->date_only);
         })->order_by('id', 'desc')->first('id');
         try {
             if ($last_inventory_update) {
                 $query_update_inv = "UPDATE `inventories` SET `inventory` = ?, updated_at = ? WHERE `id` = ?";
                 $bindings_update_inventory = array(gzcompress(json_encode($input), 5), $this->date, $last_inventory_update->id);
                 if (DB::query($query_update_inv, $bindings_update_inventory) === false) {
                     throw new Exception('Error updating inventory.');
                 }
             } else {
                 $inv = new Inventory();
                 $inv->db_id = $db_id;
                 $inv->inventory = gzcompress(json_encode($input), 5);
                 if (!$inv->save()) {
                     throw new Exception('Add inventory query failed:');
                 }
             }
         } catch (Exception $e) {
             Log::info($log_header . $e->getMessage());
             file_put_contents($this->logpath . $this->logdate . '_bad_player.json', json_encode($input));
             return false;
         }
     }
     //set cache file and cache MD5 file
     Cache::forever($this->class_name . "_" . $db_id . "_Inventory", json_encode($input));
     Cache::forever($this->class_name . "_" . $db_id . "_Inventory_MD5", md5($input));
     return true;
 }
 public function changeInventory()
 {
     $inventory = Inventory::where('product_id', Input::get('id'))->first();
     $inventory->xsmall = Input::get('xsmall_inv');
     $inventory->small = Input::get('small_inv');
     $inventory->medium = Input::get('medium_inv');
     $inventory->large = Input::get('large_inv');
     $inventory->xlarge = Input::get('xlarge_inv');
     $inventory->xxlarge = Input::get('xxlarge_inv');
     $inventory->xxxlarge = Input::get('xxxlarge_inv');
     $inventory->onesize = Input::get('onesize_inv');
     $inventory->save();
     return 'success!';
 }
function parseFile($filePath)
{
    global $arrConditionValues;
    if (!file_exists($filePath)) {
        //
        return false;
    }
    /*
     */
    $file = fopen($filePath, "r");
    $line = fgets($file);
    $fields = explode("\t", $line);
    $records = array();
    while ($line = fgets($file)) {
        $record = explode("\t", $line);
        foreach ($record as $key => $val) {
            $record[$key] = $val = str_replace('"', "", $val);
        }
        //array_push($records, $record);
        $it = new InventoryTrack();
        $inv;
        foreach ($fields as $key => $field) {
            if ($field == "add-delete") {
                $it->action = is_null($record[$key]) || $record[$key] == '' ? "u" : $record[$key];
            } else {
                if ($field == "item-name") {
                    $it->name = $record[$key];
                } else {
                    if ($field == "item-description") {
                        $it->description = $record[$key];
                    } else {
                        if ($field == "sku") {
                            $sku = $record[$key];
                            /*
                            	Inventory....
                            */
                            $inv = Inventory::where("sku", $sku)->first();
                            if (is_null($inv)) {
                                $inv = new Inventory();
                            }
                            $it->sku = $inv->sku = $sku;
                        } else {
                            if ($field == "quantity") {
                                $it->quantity = $record[$key];
                                if ($it->action == "u") {
                                    $inv->quantity += $it->quantity;
                                } else {
                                    if ($it->action == "d") {
                                        $inv->quantity -= $it->quantity;
                                    } else {
                                        if ($it->action == "a") {
                                            $inv->quantity = $it->quantity;
                                        }
                                    }
                                }
                            } else {
                                if ($field == "item-note") {
                                    $it->note = $record[$key];
                                } else {
                                    if ($field == "will-ship-internationally") {
                                        $it->will_ship = $record[$key];
                                    } else {
                                        if ($field == "product-id") {
                                            $it->isbn = $record[$key];
                                        } else {
                                            if ($field == "upc") {
                                                $it->upc = $record[$key];
                                            } else {
                                                if ($field == "price") {
                                                    $it->price = $record[$key];
                                                } else {
                                                    if ($field == "expedited-shipping") {
                                                        $it->expedited_shipping = $record[$key];
                                                    } else {
                                                        if ($field == "item-condition") {
                                                            $it->condition = $record[$key];
                                                        } else {
                                                            if ($field == "image-url") {
                                                                $it->image_url = $record[$key];
                                                            } else {
                                                                if ($field == "browse-path") {
                                                                    $it->browse_path = $record[$key];
                                                                } else {
                                                                    if ($field == "fulfillment-center-id") {
                                                                        $it->fulfillment_center_id = $record[$key];
                                                                    } else {
                                                                        if ($field == "location") {
                                                                            $it->location = $record[$key];
                                                                        } else {
                                                                            if ($field == "author") {
                                                                                $it->author = $record[$key];
                                                                            } else {
                                                                                if ($field == "publisher") {
                                                                                    $it->publisher = $record[$key];
                                                                                } else {
                                                                                    if ($field == "condition-id") {
                                                                                        $it->condition_id = $record[$key];
                                                                                        $inv->condition = $arrConditionValues[$it->condition_id];
                                                                                    } else {
                                                                                        if ($field == "cost") {
                                                                                            $it->cost = $record[$key];
                                                                                        } else {
                                                                                            if ($field == "source") {
                                                                                                $it->source = $record[$key];
                                                                                            } else {
                                                                                                if ($field == "open_date") {
                                                                                                    $it->open_date = $record[$key];
                                                                                                }
                                                                                            }
                                                                                        }
                                                                                    }
                                                                                }
                                                                            }
                                                                        }
                                                                    }
                                                                }
                                                            }
                                                        }
                                                    }
                                                }
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
        $inv->isbn = $it->isbn;
        $inv->price = $it->price;
        $inv->image = $it->image_url;
        $inv->location = $it->location;
        $inv->author = $it->author;
        $inv->publisher = $it->publisher;
        $inv->cost = $it->cost;
        $inv->name = $it->name;
        $inv->description = $it->description;
        $inv->dirty = 1;
        //$inv->shopify_id = 0;
        $inv->save();
        $it->save();
    }
    return true;
}
function submit_products()
{
    $start = 0;
    while (true) {
        $inventories = Inventory::where('dirty', 1)->take(100)->get();
        $cnt = count($inventories);
        if ($cnt == 0) {
            break;
        }
        foreach ($inventories as $inventory) {
            if ($inventory->image == '') {
                $inventory->dirty = -3;
                $inventory->save();
                continue;
            }
            $inventory = Inventory::where('isbn', $inventory->isbn)->orderBy('price', 'asc')->first();
            Inventory::where('isbn', $inventory->isbn)->update(['dirty' => 0]);
            if ($inventory->shopify_id == NULL) {
                $amzInfo = AmazonInfo::where("inventory_id", $inventory->id)->first();
                $collection = Collection::where("name", $amzInfo->category1)->first();
                if ($amzInfo->url == null || $amzInfo->description == null) {
                    continue;
                }
                $dimension = $amzInfo->width . 'W x ' . $amzInfo->height . 'H x ' . $amzInfo->length . 'L (in)';
                $result = create_product($inventory->name, $amzInfo->description, 'Bellwether', 'Book', $inventory->sku, $inventory->price, $inventory->quantity, $inventory->image, $inventory->isbn, $amzInfo->list_price, $inventory->condition, $inventory->author, $inventory->publisher, $dimension, $amzInfo->pages, $amzInfo->url);
                print_r($result);
                if ($result['success'] == 'true') {
                    $inventory->dirty = 0;
                    $sid = $result['product']['id'];
                    $inventory->shopify_id = $sid;
                    $inventory->shopify_var_id = $result['variants'][0]['id'];
                    $inventory->save();
                    echo 'Added Product - ', "ID ", $sid, ", ", $inventory->name, "\r\n";
                    /*
                    	Add collection...
                    */
                    if ($collection != NULL) {
                        add_product_to_collection($result['product']['id'], $collection->shopify_id);
                        echo 'Added to Collection - ' . $collection->name . "\r\n";
                    }
                } else {
                    echo 'Failed Product - ', "ID ", $sid, ", ", $inventory->name, "\r\n";
                    $inventory->dirty = -1;
                    $inventory->save();
                }
            } else {
                if ($amzInfo->url == null || $amzInfo->description == null) {
                    continue;
                }
                $result = update_product_content($inventory->shopify_id, $inventory->name, $amzInfo->description, $inventory->sku, $inventory->price, $inventory->quantity, $inventory->isbn, $amzInfo->list_price, $inventory->condition, $inventory->author, $inventory->publisher, $dimension, $amzInfo->pages, $amzInfo->url);
                if ($result['success'] == 'true') {
                    $inventory->dirty = 0;
                    $inventory->save();
                    echo 'Updated Product - ' . $inventory->name . "\r\n";
                } else {
                    echo 'Failed to update Product - ' . $inventory->name . "\r\n";
                    echo json_encode($result), "r\n";
                    $inventory->dirty = -2;
                    $inventory->save();
                }
            }
            //usleep(100);
        }
        $start += $cnt;
    }
}
Esempio n. 7
0
 public function get_player_profile($name = NULL)
 {
     //searching by name, null name = no buenos
     if ($name == NULL) {
         return Response::error('404');
     } else {
         $input_name = urldecode($name);
     }
     //Look up the player, latest to account for deletes with the same name
     $player = Player::where('name', '=', $input_name)->order_by('created_at', 'DESC')->first();
     //no player found, why not search?
     if (!$player) {
         return Response::error('404');
     }
     /*
     if( $player->name == 'Thehink' ) {
         return View::make('player.player_profile_banned')
         ->with('title', 'Player Profile for ' . $player->name)
         ->with(compact('player'));
     }
     */
     //But wait there's more, let's see if we know where that player has been
     $locations = false;
     /*Location::where('db_id','=',$player->db_id)
       ->order_by('created_at','DESC')
       ->first();*/
     //provide the spotters name if a location has been sighted
     if ($locations) {
         $spotter = Player::where('db_id', '=', $locations->spotter_db_id)->only('name');
     } else {
         $spotter = NULL;
     }
     //calculate the players closest POI
     if ($locations) {
         if (!Cache::has('poi_lookup')) {
             Cache::forever('poi_lookup', PointOfInterest::get(array('name', 'coord_x', 'coord_y')));
         }
         $pois = Cache::get('poi_lookup');
         $poi_locs = $pois;
         $poi_lastx = round($locations->coord_x);
         $poi_lasty = round($locations->coord_y);
         $poi_nearest = [999999, 'n/a'];
         foreach ($poi_locs as $pois) {
             $xs = 0;
             $ys = 0;
             $xs = $poi_lastx - intval($pois->coord_x);
             $xs = $xs * $xs;
             $ys = $poi_lasty - intval($pois->coord_y);
             $ys = $ys * $ys;
             $distance = round(sqrt($xs + $ys));
             if ($distance < $poi_nearest[0]) {
                 $poi_nearest = [$distance, $pois->name];
             }
         }
         $nearestloc = $poi_nearest[1];
     } else {
         $nearestloc = NULL;
     }
     //Does the player have an army?
     $army = Army::where('armyId', '=', $player->armyid)->order_by('created_at', 'DESC')->first();
     //escape for output in title
     $playerName = htmlentities($player->name);
     //Player website preferences
     $web_prefs = WebsitePref::where('db_id', '=', $player->db_id)->first();
     if (isset($web_prefs->attributes)) {
         $web_prefs = $web_prefs->attributes;
     }
     if (isset($web_prefs['show_inventory'])) {
         if ($web_prefs['show_inventory'] == 1) {
             $inventory = Inventory::where('db_id', '=', $player->db_id)->order_by('updated_at', 'DESC')->first();
         } else {
             $inventory = null;
         }
     } else {
         $inventory = Inventory::where('db_id', '=', $player->db_id)->order_by('updated_at', 'DESC')->first();
     }
     /*
     			Mappings:
     				local c_RawToRefinedConversion = {
     					["78014"] = "77703", --Copper
     					["78015"] = "77704", --Iron
     					["78016"] = "77705", --Aluminum
     					["78017"] = "77706", --Carbon
     					["78018"] = "77707", --Silicate
     					["78019"] = "77708", --Ceramics
     					["78020"] = "77709", --Methine
     					["78021"] = "77710", --Octine
     					["78022"] = "77711", --Nitrine
     					["82420"] = "82419", --Radine
     					["78023"] = "77713", --Petrochemical
     					["78024"] = "77714", --Biopolymer
     					["78025"] = "77715", --Xenografts
     					["78026"] = "77716", --Toxins
     					["78027"] = "77736", --Regenics
     					["78028"] = "77737", --Anabolics
     				}
     				local c_RefinedToRawConversion = {
     					["77703"] = "78014", --Copper
     					["77704"] = "78015", --Iron
     					["77705"] = "78016", --Aluminum
     					["77706"] = "78017", --Carbon
     					["77707"] = "78018", --Silicate
     					["77708"] = "78019", --Ceramics
     					["77709"] = "78020", --Methine
     					["77710"] = "78021", --Octine
     					["77711"] = "78022", --Nitrine
     					["82419"] = "82420", --Radine
     					["77713"] = "78023", --Petrochemical
     					["77714"] = "78024", --Biopolymer
     					["77715"] = "78025", --Xenografts
     					["77716"] = "78026", --Toxins
     					["77736"] = "78027", --Regenics
     					["77737"] = "78028", --Anabolics
     				}
     				local c_ResourceIds = {
     					["10"] = "Crystite",
     					["80404"] = "AMPS",
     					["30412"] = "CHITS",
     					["30404"] = "SiftedEarth",
     					["77703"] = "Metal",
     					["77704"] = "Metal",
     					["77705"] = "Metal",
     					["77706"] = "Carbon",
     					["77707"] = "Carbon",
     					["77708"] = "Carbon",
     					["77709"] = "Ceramic",
     					["77710"] = "Ceramic",
     					["77711"] = "Ceramic",
     					["77713"] = "Biomaterial",
     					["77714"] = "Biomaterial",
     					["77715"] = "Biomaterial",
     					["77716"] = "Polymer",
     					["77736"] = "Polymer",
     					["77737"] = "Polymer",
     					["82419"] = "Ceramic",
     				}
     */
     if ($inventory) {
         $inventory = unserialize($inventory->inventory);
         if (isset($inventory->{10})) {
             $player_crystite_amount = $inventory->{10};
         } else {
             $player_crystite_amount = 0;
         }
         $cache_key_inventory = $player->db_id . "_inventory";
         if (Cache::Get($cache_key_inventory) != $inventory) {
             $raw_resource_names = array('Copper', 'Iron', 'Aluminum', 'Carbon', 'Silicate', 'Ceramics', 'Methine', 'Octine', 'Nitrine', 'Radine', 'Petrochemical', 'Biopolymer', 'Xenografts', 'Toxins', 'Regenics', 'Anabolics');
             $raw_resource_ids = array(78014, 78015, 78016, 78017, 78018, 78019, 78020, 78021, 78022, 82420, 78023, 78024, 78025, 78026, 78027, 78028);
             $refined_resource_ids = array(77703, 77704, 77705, 77706, 77707, 77708, 77709, 77710, 77711, 82419, 77713, 77714, 77715, 77716, 77736, 77737);
             //Convert inventory to an array
             $inventory = (array) $inventory;
             //Get a cache (or make one) of all the resource item image paths
             if (!Cache::has('resource_asset_paths_dump')) {
                 $resource_ids = array_merge($raw_resource_ids, $refined_resource_ids);
                 $resource_icons = hWebIcon::where(function ($query) use($resource_ids) {
                     $query->where('version', '=', Base_Controller::getVersionDate());
                     $query->where_in('itemTypeId', $resource_ids);
                 })->get(array('itemtypeid', 'asset_path'));
                 Cache::forever('resource_asset_paths_dump', $resource_icons);
             } else {
                 $resource_icons = Cache::Get('resource_asset_paths_dump');
             }
             $player_raw_resources = array();
             $player_refined_resources = array();
             $counter_raw = 0;
             $counter_refined = 0;
             foreach ($inventory as $key => $value) {
                 if (in_array($key, $raw_resource_ids)) {
                     $player_raw_resources[$counter_raw]['name'] = $raw_resource_names[array_search($key, $raw_resource_ids)];
                     $player_raw_resources[$counter_raw]['id'] = $key;
                     $player_raw_resources[$counter_raw]['amt'] = $value;
                     for ($i = 0; $i < count($resource_icons); $i++) {
                         if ($resource_icons[$i]->attributes['itemtypeid'] == $key) {
                             $player_raw_resources[$counter_raw]['asset_path'] = $resource_icons[$i]->attributes['asset_path'];
                         }
                     }
                     $counter_raw++;
                 }
                 if (in_array($key, $refined_resource_ids)) {
                     $player_refined_resources[$counter_refined]['name'] = $raw_resource_names[array_search($key, $refined_resource_ids)];
                     $player_refined_resources[$counter_refined]['id'] = $key;
                     $player_refined_resources[$counter_refined]['amt'] = $value;
                     for ($i = 0; $i < count($resource_icons); $i++) {
                         if ($resource_icons[$i]->attributes['itemtypeid'] == $key) {
                             $player_refined_resources[$counter_refined]['asset_path'] = $resource_icons[$i]->attributes['asset_path'];
                         }
                     }
                     $counter_refined++;
                 }
             }
             //set some cache
             Cache::forever($cache_key_inventory . "_refined_resources", $player_refined_resources);
             Cache::forever($cache_key_inventory . "_raw_resources", $player_raw_resources);
         } else {
             $player_refined_resources = Cache::Get($cache_key_inventory . "_refined_resources");
             $player_raw_resources = Cache::Get($cache_key_inventory . "_raw_resources");
         }
         //set inventory to 1, we don't need everything else exposed on the players page
         $inventory = 1;
     }
     //loadouts
     /*
         Mappings:
             $loadout->Gear[$i] = Currently equipped items array
             $loadout->Gear[$i]->slot_index
             $loadout->Gear[$i]->info->durability->pool
             $loadout->Gear[$i]->info->durability->current
             $loadout->Gear[$i]->info->attribute_modifiers[$k] = array of custom attributes for this item
             $loadout->Gear[$i]->info->quality = The quality of the crafted item
             $loadout->Gear[$i]->info->creator_guid = the creators unique player ID
             $loadout->Gear[$i]->info->item_sdb_id = The root item this was crafted from
     
             $loadout->Weapons[$i] = Currently equiped weapons array
             $loadout->Weapons[$i]->info->durability->pool
             $loadout->Weapons[$i]->info->durability->current
             $loadout->Weapons[$i]->info->attribute_modifiers[$k]
             $loadout->Weapons[$i]->info->quality
             $loadout->Weapons[$i]->info->creator_guid
             $loadout->Weapons[$i]->info->item_sdb_id
             $loadout->Weapons[$i]->allocated_power
             $loadout->Weapons[$i]->slot_index = Weapon slot, 0 is main hand, 1 is alt weapon
     */
     /*
         Attribute modifiers mapping:
             5   = Jet Energy Recharge
             6   = health
             7   = health regen
             12  = Run Speed
             29  = weapon splash radius
             35  = Energy (for jetting)
             37  = Jump Height
             950 = Max durability pool
             951 = Mass (unmodified - YOU MUST take the abs of this to get it to display correctly!)
             952 = Power (unmodified - YOU MUST take the abs of this to get it to display correctly!)
             953 = CPU (unmodified - YOU MUST take the abs of this to get it to display correctly!)
             956 = clip size
             954 = damage per round
             977 = Damage
             978 = Debuff Duration
             1121= Air Sprint
     
             Defaults for weapons are set in the "hstats" table.
     */
     if (isset($web_prefs['show_loadout'])) {
         if ($web_prefs['show_loadout'] == 1) {
             $loadout = Loadout::where('db_id', '=', $player->db_id)->first();
         } else {
             $loadout = null;
         }
     } else {
         $loadout = Loadout::where('db_id', '=', $player->db_id)->first();
     }
     if ($loadout) {
         //Lets play the cache game, where all the stuff is stored locally and the points don't matter!
         $loadout = unserialize($loadout->entry);
         //VERSION 0.6 CHECKING (Array = Good, Object = BAD!)
         if (gettype($loadout) == "object") {
             //This is from version 0.6, we can no longer use this data.
             $loadout = null;
         }
         $cache_key_loadouts = $player->db_id . "_loadouts";
         $loadout_md5 = md5(serialize($loadout));
         if (Cache::Get($cache_key_loadouts . '_md5') != $loadout_md5 && $loadout != null) {
             //Oh I am playing the game, the one that will take me to my end.
             //Make sure this isnt a terrible send
             if (isset($loadout[0]->Gear)) {
                 for ($k = 0; $k < count($loadout); $k++) {
                     if ($loadout[$k]->Chassis_ID == 77733 || $loadout[$k]->Chassis_ID == 82394 || $loadout[$k]->Chassis_ID == 31334) {
                         //ignore the training frame
                     } else {
                         //Break each loadout into its own cache
                         Cache::forever($cache_key_loadouts . '_' . $loadout[$k]->Chassis_ID, $loadout[$k]);
                     }
                 }
                 //Cache the loadout md5 so we can call it again later
                 Cache::forever($cache_key_loadouts . '_md5', $loadout_md5);
                 //and finally set loadout=1 so we know to display equipped gear data
                 $loadout = 1;
             }
         }
     }
     //progress (feat. obama)
     if (isset($web_prefs['show_progress'])) {
         if ($web_prefs['show_progress'] == 1) {
             $progress = Progress::where('db_id', '=', $player->db_id)->order_by('updated_at', 'DESC')->first();
         } else {
             $progress = null;
         }
     } else {
         $progress = Progress::where('db_id', '=', $player->db_id)->order_by('updated_at', 'DESC')->first();
     }
     /*
         Mappings:
             $progress->xp[$i].sdb_id = ItemTypeId for chassis
             $progress->xp[$i].name = battle frame name
             $progress->xp[$i].lifetime_xp = amount of xp gained overall
             $progress->xp[$i].current_xp = currently allocated XP (WARNING: key may not exist!)
             $progress->chassis_id = current chassis ID, use this to identify what battleframe the player was last using
             $progress->unlocks.array() = certificate array for currently equipped chassis
     */
     if ($progress) {
         //Progression graph builder
         $player_progresses_cache_key = $player->db_id . "_graph";
         $player_id = $player->db_id;
         $frame_progress_javascript = array();
         if (Cache::has($player_progresses_cache_key)) {
             //pull from cache
             $frame_progress_javascript = Cache::get($player_progresses_cache_key);
         } else {
             //don't cache the query, that wont help us; cache the javascript output for highcharts instead.
             $player_progresses = DB::query('SELECT DISTINCT(`db_id`),`entry`,unix_timestamp(`updated_at`) AS `updated_at` FROM `progresses` WHERE db_id= ' . $player_id . '  AND `created_at` > DATE_SUB(CURDATE(), INTERVAL 7 DAY) GROUP BY `created_at` ORDER BY `updated_at` ASC LIMIT 7');
             //check chassis_id exists
             if (!empty($player_progresses)) {
                 $check_chassis = unserialize($player_progresses[0]->entry);
             } else {
                 $check_chassis = "";
                 $check_chassis_id = false;
             }
             if (!isset($check_chassis->chassis_id)) {
                 $check_chassis_id = false;
             } else {
                 $check_chassis_id = true;
             }
             if ($player_progresses && $check_chassis_id) {
                 $frame_progress = array();
                 for ($i = 0; $i < count($player_progresses); $i++) {
                     $day_progress = unserialize($player_progresses[$i]->entry);
                     unset($day_progress->unlocks);
                     foreach ($day_progress->xp as $key => $value) {
                         if ($value->sdb_id == 77733 || $value->sdb_id == 82394 || $value->sdb_id == 31334) {
                             //ignore training frame
                         } else {
                             $frame_progress[$value->name][$player_progresses[$i]->updated_at] = $value->lifetime_xp;
                         }
                     }
                 }
                 //Make it json datas
                 $frame_progress_javascript = array();
                 foreach ($frame_progress as $battle_frame_name => $value) {
                     $xp_data_string = "[";
                     foreach ($value as $day => $xp_amt) {
                         $xp_data_string .= "[" . $day * 1000 . "," . $xp_amt . "],";
                         $frame_progress_javascript[$battle_frame_name] = rtrim($xp_data_string, ",") . "]";
                     }
                 }
             } else {
                 $frame_progress_javascript = null;
                 $progress = false;
             }
             //build cache
             Cache::put($player_progresses_cache_key, $frame_progress_javascript, 30);
         }
     } else {
         $frame_progress_javascript = null;
         $progress = false;
     }
     //Frames & Unlocks
     if ($progress) {
         $cache_key_progress = $player->db_id . "_progress";
         $progress = $progress->entry;
         $progress_md5 = md5($progress);
         if (Cache::Get($cache_key_progress . "_md5") != $progress_md5) {
             $progress = unserialize($progress);
             if (isset($progress->xp)) {
                 $battle_frame_id_list = array();
                 for ($i = 0; $i < count($progress->xp); $i++) {
                     $battle_frame_id_list[$i] = $progress->xp[$i]->sdb_id;
                 }
                 $battle_frame_images = hWebIcon::where(function ($query) use($battle_frame_id_list) {
                     $query->where('version', '=', Base_Controller::getVersionDate());
                     $query->where_in('itemTypeId', $battle_frame_id_list);
                 })->get();
                 //set some cache
                 Cache::forever($cache_key_progress . "_battleframe_images", $battle_frame_images);
             } else {
                 $battle_frame_images = null;
             }
             if (isset($web_prefs['show_unlocks'])) {
                 $show_unlocks = $web_prefs['show_unlocks'];
             } else {
                 //Assume show unlocks is 1
                 $show_unlocks = 1;
             }
             if (isset($progress->unlocks) && $show_unlocks == 1) {
                 //VERSION 0.6 CHECK (Array = BAD, Object = Good!)
                 if (gettype($progress->unlocks) == "array") {
                     //NOPE.
                     $battle_frame_unlocks = null;
                 } else {
                     if (gettype($progress->unlocks) == "object") {
                         //Looks like 0.7+ to me!
                         //Create a cache for each frame unlock set
                         foreach ($progress->unlocks as $chassis_id => $cert_array) {
                             if ($chassis_id == 77733 || $chassis_id == 82394 || $chassis_id == 31334) {
                                 //ignore training frame
                             } else {
                                 Cache::forever($cache_key_progress . "_" . $chassis_id, $cert_array);
                             }
                         }
                     }
                 }
             }
             //Cache the progress variable so we can do a quick compare on a later load
             Cache::forever($cache_key_progress, $progress);
             Cache::forever($cache_key_progress . "_md5", $progress_md5);
         } else {
             //Assign cache values to local variable names.
             $battle_frame_images = Cache::Get($cache_key_progress . "_battleframe_images");
             $progress = Cache::Get($cache_key_progress);
         }
     } else {
         $battle_frame_unlocks = null;
     }
     return View::make('player.player_profile')->with('title', 'Player Profile for ' . $playerName)->with(compact('player'))->with(compact('locations'))->with(compact('nearestloc'))->with(compact('army'))->with(compact('inventory'))->with(compact('player_raw_resources'))->with(compact('player_refined_resources'))->with(compact('player_crystite_amount'))->with(compact('loadout'))->with(compact('battle_frame_unlocks'))->with(compact('progress'))->with(compact('frame_progress_javascript'))->with(compact('battle_frame_images'))->with(compact('web_prefs'))->with(compact('spotter'));
 }
Esempio n. 8
0
 public function post_player()
 {
     $log_header = "addon_v2.php@player [" . $this->user_ip . "] - ({$this->logdate}): ";
     $line = Input::json();
     if ($this->savedata) {
         file_put_contents($this->logpath . $this->logdate . '_player.json', serialize($line));
     }
     $datlog = new DatLog();
     $datlog->ip = ip2long($this->user_ip);
     $datlog->db_id = isset($line->Player_ID) ? $line->Player_ID : NULL;
     $datlog->name = isset($line->Player_Name) ? $line->Player_Name : NULL;
     $datlog->category = 'player';
     $datlog->save();
     try {
         /*
          ********************************
          ** Validate Minimum Keys Exist**
          ********************************
          *  # Fail if invalid
          */
         //Minimum keys
         if (!isset($line->Inventory) || !isset($line->Progress) || !isset($line->Website_Prefs) || !isset($line->Player_ID) || !isset($line->Player_Name) || !isset($line->Player_Instance) || !isset($line->Loadouts) || !isset($line->Player_EID) || !isset($line->Player_Coords) || !isset($line->ArmyID) || !isset($line->Battle_Frame)) {
             throw new Exception('Player did not send all keys.');
         }
         /*
          ********************************
          ** Validate Player ID (db_id) **
          ********************************
          *  # Fail if invalid
          *  @ sets $player_db_id
          *
          *  -check digits only
          *  -19 characters long
          *  -Begins with a 9
          */
         //Digits only?
         if (preg_match('/[^0-9]/', $line->Player_ID)) {
             throw new Exception("Player ID was more than just numbers: " . $line->Player_ID);
         }
         //19 Characters long?
         if (strlen($line->Player_ID) !== 19) {
             throw new Exception("Player ID was not 19 characters: " . $line->Player_ID);
         }
         //Starts with a 9?
         if (substr($line->Player_ID, 0, 1) !== '9') {
             throw new Exception("Player ID did not start with a 9: " . $line->Player_ID);
         }
         $player_db_id = $line->Player_ID;
         /*
          **********************************
          ** Validate Player Name/Army Tag**
          **********************************
          *  # Warn if invalid
          *  @ sets $player_name
          *  @ sets $player_army_tag
          *
          *  -15 + 6 characters or less ~23 to be safe
          *  -We don't care about character content as much as FF does
          */
         //Check if name is way too long, or too short
         if (strlen($line->Player_Name) > 30 || trim(strlen($line->Player_Name)) < 3) {
             throw new Exception("Player ({$player_db_id}) name was longer than 30 characters, should be <= 23: " . $line->Player_Name);
         }
         //Warn if longer than expected (that's what she said)
         //But allow for armytag length too
         if (strlen($line->Player_Name) > 27) {
             Log::warn("Player ({$player_db_id}) sent a character name longer than max expected length of 27: " . $line->Player_Name);
         }
         //Name is ok, but does it have an army tag?  Does it blend?
         if (strpos($line->Player_Name, ']')) {
             $last = strripos($line->Player_Name, ']') + 1;
             $player_army_tag = substr($line->Player_Name, 0, $last);
             $player_name = trim(substr($line->Player_Name, $last));
         } else {
             $player_army_tag = NULL;
             $player_name = $line->Player_Name;
         }
         /*
          ***********************************
          ** Check existing name/db_id     **
          ***********************************
          *  Does the db_id exist?
          *  Does the submitted name match existing?
          */
         $check_existing_sql = Player::where('db_id', '=', $player_db_id)->order_by('created_at', 'DESC')->first();
         if ($check_existing_sql) {
             if ($check_existing_sql->name != $player_name) {
                 throw new Exception("Existing db_id does not match existing name: (player sent:{$player_db_id}|{$player_name};existing:{$check_existing_sql->db_id}|{$check_existing_sql->name};)");
                 Log::warn("Existing db_id does not match existing name({$player_db_id}|in:{$player_name}|existing:{$check_existing_sql->name})");
             }
         }
         /*
          ********************************
          ** Validate Website Prefs     **
          ********************************
          *  # Allow, but only if valid
          *  @ (self contained)
          *
          *  -Contain all keys
          *  -Only 0 or 1 values
          */
         //Minimum keys
         if (isset($line->Website_Prefs) && isset($line->Website_Prefs->show_loadout) && isset($line->Website_Prefs->show_inventory) && isset($line->Website_Prefs->show_progress) && isset($line->Website_Prefs->show_unlocks) && isset($line->Website_Prefs->show_pve_kills) && isset($line->Website_Prefs->show_pve_stats) && isset($line->Website_Prefs->show_pve_events) && isset($line->Website_Prefs->show_location)) {
             //Get ready to save, check for boolean digit values only
             $save_prefs = true;
             foreach ($line->Website_Prefs as $pref) {
                 //allowed values 1|0
                 if ($pref !== 0 && $pref !== 1) {
                     $save_prefs = false;
                 }
             }
             //because not everyone uses the latest version
             $show_workbench = isset($line->Website_Prefs->show_workbench) ? $line->Website_Prefs->show_workbench : 0;
             $show_craftables = isset($line->Website_Prefs->show_craftables) ? $line->Website_Prefs->show_craftables : 0;
             $show_market_listings = isset($line->Website_Prefs->show_market_listings) ? $line->Website_Prefs->show_market_listings : 0;
             //IF Website Prefs are appropriate, right click, save as
             if ($save_prefs) {
                 $prefs = $line->Website_Prefs;
                 $query_webpref = 'INSERT INTO `websiteprefs` (db_id, ';
                 $query_webpref .= 'show_loadout, show_progress, show_inventory, show_unlocks, ';
                 $query_webpref .= 'show_pve_kills, show_pve_stats, show_pve_events, show_location, ';
                 $query_webpref .= 'show_workbench, show_craftables, show_market_listings, ';
                 $query_webpref .= 'created_at, updated_at) VALUES ';
                 $query_webpref .= '(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?) ON DUPLICATE KEY UPDATE ';
                 $query_webpref .= '`show_loadout` = ?, `show_progress` = ?, `show_inventory` = ?, show_unlocks = ?, ';
                 $query_webpref .= '`show_pve_kills` = ?, `show_pve_stats` = ?, `show_pve_events` = ?, `show_location` = ?, ';
                 $query_webpref .= '`show_workbench` = ?, `show_craftables` = ?, `show_market_listings` = ?, ';
                 $query_webpref .= '`updated_at` = ?';
                 $bindings_webpref = array($player_db_id, $prefs->show_loadout, $prefs->show_progress, $prefs->show_inventory, $prefs->show_unlocks, $prefs->show_pve_kills, $prefs->show_pve_stats, $prefs->show_pve_events, $prefs->show_location, $show_workbench, $show_craftables, $show_market_listings, $this->date, $this->date, $prefs->show_loadout, $prefs->show_progress, $prefs->show_inventory, $prefs->show_unlocks, $prefs->show_pve_kills, $prefs->show_pve_stats, $prefs->show_pve_events, $prefs->show_location, $show_workbench, $show_craftables, $show_market_listings, $this->date);
                 DB::query($query_webpref, $bindings_webpref);
             } else {
                 Log::warn("Player ({$player_db_id}) sent invalid Website Prefs values: " . implode(',', (array) $line->Website_Prefs));
             }
         } else {
             Log::warn($log_header . "Player ({$player_db_id}) did not send all website prefs or correct keys: ");
         }
         /*
          **********************************
          ** Validate Instance ID         **
          **********************************
          *  # Fail if not numeric, or 9|10 long
          *  @ sets $player_instance_id
          *
          *  -Greater than 0
          *  -Expected length 9 or 10, but others possible
          */
         //Not negative 1 for some reason
         if ($line->Player_Instance === -1) {
             throw new Exception("Player ({$player_db_id}) Instance ID was -1: " . $line->Player_Instance);
         }
         //Sending only digits
         if (preg_match('/[^0-9]/', $line->Player_Instance)) {
             throw new Exception("Player ({$player_db_id}) Instance ID contained something other than a number: " . $line->Player_Instance);
         }
         //Log if non regular instanceid (can be legit)
         if (strlen($line->Player_Instance) < 5) {
             Log::warn("Player ({$player_db_id}) Instance ID was less than 5 digits long: " . $line->Player_Instance);
         }
         $player_instance_id = $line->Player_Instance;
         /*
          **********************************
          ** Validate Player EID          **
          **********************************
          *  # Fail is non numeric, NULL otherwise
          *  @ sets $player_eid
          *
          *  -Greater than 0
          *  -Expected length 9 or 10, but others possible
          */
         //Sent only numbers
         if (preg_match('/[^0-9]/', $line->Player_EID)) {
             throw new Exception("Player ({$player_db_id}) EID contained something other than a number: " . $line->Player_EID);
         }
         //EID should be as long as a db_id
         if (strlen($line->Player_EID) !== 19) {
             Log::warn("Player ({$player_db_id}) EID was not the expected 19 digits long: " . $line->Player_EID);
             $line->Player_EID = NULL;
         }
         $player_eid = $line->Player_EID;
         /*
          **********************************
          ** Validate Army ID             **
          **********************************
          *  # Fail if set and not nil or numeric
          *  @ sets $player_army_id
          *
          *  -Greater than 0
          *  -Expected length 9 or 10, but others possible
          */
         //ArmyID nil -> null
         if (isset($line->ArmyID)) {
             if ($line->ArmyID == 'nil' || $line->ArmyID == false) {
                 $player_army_id = NULL;
             } else {
                 //Numbers only plx
                 if (preg_match('/[^0-9]/', $line->ArmyID)) {
                     throw new Exception("Player ({$player_db_id}) ArmyID was not numeric and not nil: " . $line->ArmyID);
                 } else {
                     $player_army_id = $line->ArmyID;
                 }
             }
         } else {
             $player_army_id = NULL;
         }
         /*
          **********************************
          ** Validate Current Archetype   **
          **********************************
          *  # Fail to null
          *  @ sets $player_current_archetype
          *
          *  -in array expected
          *  -guardian,recon,medic,bunker,berzerker,unknown,NULL
          */
         $expected_archetypes = array('guardian', 'recon', 'medic', 'bunker', 'berzerker', 'unknown');
         //Valid archetype?  I don't know what I expected
         if (!in_array($line->Battle_Frame, $expected_archetypes)) {
             $player_current_archetype = NULL;
             Log::warn("Player ({$player_db_id}) sent unexpected battleframe: " . $line->Battle_Frame);
         } else {
             $player_current_archetype = $line->Battle_Frame;
         }
         /*
          **********************************
          ** Validate Player Region       **
          **********************************
          *  # Fail to null
          *  @ sets $player_region
          *
          *  Is alpha/-/num..
          */
         //Valid region; but not the nether region
         if (isset($line->Player_Region)) {
             $player_region = preg_replace('/[^A-Z0-9\\-]/i', '', $line->Player_Region);
         } else {
             $player_region = "";
         }
         /*
          **********************************
          ** Validate Player Coords       **
          **********************************
          *  # Fail if out of bounds
          *  @ sets $player_coord_x
          *  @ sets $player_coord_y
          *  @ sets $player_coord_z
          *  @ sets $spotter_db_id
          *
          *  -check keys (x,y,z)
          *  -coords within 0->3328 +/-
          *  -spotter_db_id is db_id
          */
         /*
                     $spotter_db_id = $player_db_id;
         
                     //Minimum keys
                     if(
                         !isset($line->Player_Coords->x) ||
                         !isset($line->Player_Coords->y) ||
                         !isset($line->Player_Coords->z) ||
                         !isset($line->Player_Coords->chunkX) ||
                         !isset($line->Player_Coords->chunkY)
                     ) { throw new Exception("Player ($player_db_id) didn't send all location keys");
         
                     }else{
         
                         $save_loc = true;
                         $log_loc = false;
                         foreach ($line->Player_Coords as $k => $v)
                         {
                             //float values for locations
                             if( $k == 'x' || $k == 'y' || $k == 'z' ) {
                                 if( !is_float($v) && $v !== 0 ) {
                                     $log_loc = true;
                                 }
                             }else{
                             //integers for chunks
                                 if( !is_numeric($v) ) {
                                     $log_loc = true;
                                 }
                             }
                         }
         
                         //We're going to allow all locations, but log unexpected ones
                         if( $save_loc ) {
                             $loc =  new Location;
                                 $loc->db_id = $player_db_id;
                                 $loc->spotter_db_id = $spotter_db_id;
                                 $loc->name = $player_name;
                                 $loc->instanceId = $player_instance_id;
                                 $loc->current_archetype = $player_current_archetype;
                                 $loc->coord_x = $line->Player_Coords->x;
                                 $loc->coord_y = $line->Player_Coords->y;
                                 $loc->coord_z = $line->Player_Coords->z;
                                 $loc->chunkX = $line->Player_Coords->chunkX;
                                 $loc->chunkY = $line->Player_Coords->chunkY;
         
                                 $loc->save();
         
                                 if($log_loc) {
                                     Log::warn("Player ($player_db_id) sent unexpected coordinates: (locid: {$loc->id}) " . implode(',', (array) $line->Player_Coords) );
                                 }
                         }else{
                             Log::warn("Player ($player_db_id) sent out of bounds coordinates: " . implode(',', (array) $line->Player_Coords) );
                         }
         
                     }
         */
         //-------------------------------------------------------------------------------------------------------------
         //  UPDATE/INSERT PLAYER, FOLLOW WITH INVENTORY/PROGRESS/LOADOUTS ON SUCCESS ----------------------------------
         //-------------------------------------------------------------------------------------------------------------
         $is_addon_user = 1;
         $query_add_player = "INSERT INTO `players` ";
         $query_add_player .= "(name, armyTag, instanceId, db_id, e_id,";
         $query_add_player .= "armyId, current_archetype, region, ";
         $query_add_player .= "created_at, updated_at) ";
         $query_add_player .= "VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?) ";
         $query_add_player .= "ON DUPLICATE KEY UPDATE ";
         $query_add_player .= "name = ?, armyTag = ?, instanceId = ?, armyId = ?, ";
         $query_add_player .= "e_id = ?, current_archetype = ?, addon_user = ?, region = ?, ";
         $query_add_player .= "updated_at = ?";
         $bindings = array($player_name, $player_army_tag, $player_instance_id, $player_db_id, $player_eid, $player_army_id, $player_current_archetype, $player_region, $this->date, $this->date, $player_name, $player_army_tag, $player_instance_id, $player_army_id, $player_eid, $player_current_archetype, $is_addon_user, $player_region, $this->date);
         try {
             if (!DB::query($query_add_player, $bindings)) {
                 throw new Exception('Add/Update player query failed');
             }
             /*
              **********************************
              ** Set Inventory If Not Empty   **
              **********************************
              */
             if (!empty($line->Inventory)) {
                 //Check the last send for inventory, see if we need to update, or make a new row
                 $last_inventory_update = Inventory::where(function ($query) use($player_db_id) {
                     $query->where('db_id', '=', $player_db_id);
                     $query->where(DB::raw('DATE(updated_at)'), '=', $this->date_only);
                 })->order_by('id', 'desc')->first('id');
                 if ($last_inventory_update) {
                     $query_update_inv = "UPDATE `inventories` SET `inventory` = ?, updated_at = ? WHERE `id` = ?";
                     $bindings_update_inventory = array(serialize($line->Inventory), $this->date, $last_inventory_update->id);
                     if (DB::query($query_update_inv, $bindings_update_inventory) === false) {
                         throw new Exception('Error updating inventory.');
                     }
                 } else {
                     $inv = new Inventory();
                     $inv->db_id = $player_db_id;
                     $inv->inventory = serialize($line->Inventory);
                     if (!$inv->save()) {
                         throw new Exception('Add inventory query failed:');
                     }
                 }
             }
             //not empty inventory
             /*
              **********************************
              ** Set Progress If Not Empty   **
              **********************************
              */
             if (!empty($line->Progress)) {
                 //Check the last send for progress, see if we need to update, or make a new row
                 $last_progress_update = Progress::where(function ($query) use($player_db_id) {
                     $query->where('db_id', '=', $player_db_id);
                     $query->where(DB::raw('DATE(updated_at)'), '=', $this->date_only);
                 })->order_by('id', 'desc')->first('id');
                 if ($last_progress_update) {
                     $query_update_prog = "UPDATE `progresses` SET `entry` = ?, updated_at = ? WHERE `id` = ?";
                     $bindings_update_progress = array(serialize($line->Progress), $this->date, $last_progress_update->id);
                     if (DB::query($query_update_prog, $bindings_update_progress) === false) {
                         throw new Exception('Error updating progress.');
                     }
                 } else {
                     $progress = new Progress();
                     $progress->db_id = $player_db_id;
                     $progress->entry = serialize($line->Progress);
                     if (!$progress->save()) {
                         throw new Exception('Add progress query failed:');
                     }
                 }
             }
             //not empty progress
             /*
              **********************************
              ** Set Loadouts If Not Empty   **
              **********************************
              */
             if (!empty($line->Loadouts)) {
                 $query_add_loadout = "INSERT INTO `loadouts` ";
                 $query_add_loadout .= "(db_id, entry, created_at, updated_at) ";
                 $query_add_loadout .= "VALUES (?, ?, ?, ?) ";
                 $query_add_loadout .= "ON DUPLICATE KEY UPDATE ";
                 $query_add_loadout .= "entry = ?, updated_at = ?";
                 $loadout_entry = serialize($line->Loadouts);
                 $bindings = array($player_db_id, $loadout_entry, $this->date, $this->date, $loadout_entry, $this->date);
                 if (!DB::query($query_add_loadout, $bindings)) {
                     throw new Exception('Add loadout query failed:');
                 }
             }
         } catch (Exception $e) {
             Log::info($log_header . $e->getMessage());
             file_put_contents($this->logpath . $this->logdate . '_bad_player.json', serialize($line));
         }
     } catch (Exception $e) {
         Log::info($log_header . $e->getMessage());
         file_put_contents($this->logpath . $this->logdate . '_bad_player.json', serialize($line));
     }
     return Response::json(array('ThumpDumpDB', '(Player) Thanks'));
 }