public function requestListing($app) { if (!$app->user->isLoggedIn()) { $app->output->redirect('/account/login'); } try { if (isset($_SERVER["CONTENT_LENGTH"])) { if ($_SERVER["CONTENT_LENGTH"] > (int) ini_get('post_max_size') * 1024 * 1024) { throw new Listing_InvalidDetails('Your request has exceeded file limits. Try to limit screenshots to under 2MB each.'); } } // Loop through storage bots to make sure one has enough space $bots = Bot::find('all', array('conditions' => array('type = ? AND status = ?', Bot::TYPE_STORAGE, Bot::STATUS_ACTIVE))); $flag = false; foreach ($bots as $idx => $bot) { // Too many API calls makes this too volatile to be viable // $bot_inventory = $app->steam->getInventory($bot->id, true); $bot_inventory = Listing::count('all', array('conditions' => array('bot_id = ? AND stage = ?', $bot->id, Listing::STAGE_LIST))); if ($bot_inventory + 1 < $app->config->get('steam.maxInventory')) { $flag = true; break; } } if (!$flag) { throw new Listing_StorageFull(); } // Grab item information from user's inventory $userid = $app->user->id; $inventory = $app->steam->getInventory($userid, true); $request = $app->router->flight->request(); $itemid = $request->data->item_id ?: -1; if (!isset($inventory[$itemid])) { throw new Listing_MissingItem(); } $item = $inventory[$itemid]; $flag = Listing::find('all', array('conditions' => array('item_id = ? AND user_id = ? AND stage = ?', $itemid, $userid, Listing::STAGE_REQUEST))); $flag = !empty($flag); if ($flag) { throw new Listing_Duplicate(); } // Inspect HTTP request for POST vars to add into DB $price = $request->data->price ?: 0; $message = $request->data->message ?: ''; if (!empty($item->desc->price_preset)) { $price = $item->desc->price_preset; } if ($price == 0) { throw new Listing_InvalidDetails('You must include a price for your listing'); } if ($item->desc->stackable == 1) { // Stackable items don't require screenshots $details = array('screenshot_playside' => null, 'screenshot_backside' => null, 'note_playside' => null, 'note_backside' => null); } else { $details = array('screenshot_playside' => $request->data->screenshot_playside ?: null, 'screenshot_backside' => $request->data->screenshot_backside ?: null, 'note_playside' => $request->data->note_playside ?: null, 'note_backside' => $request->data->note_backside ?: null, 'inspect_url' => preg_replace(array('/%owner_steamid%/', '/%assetid%/'), array($userid, $item->asset_id), $item->desc->inspect_url_template)); if (empty($details['screenshot_playside']) || empty($details['note_playside'])) { throw new Listing_InvalidDetails('You must provide a playside screenshot and pattern description'); } // 2MB = 2000000B limit on screenshots since POST request vars are limited // Added a bit for wiggle room since base64 encoding adds 33% size if ((int) (strlen(rtrim($details['screenshot_playside'], '=')) * 3 / 4) > 2100000) { throw new Listing_InvalidDetails('You have uploaded a playside screenshot that is too large'); } if (!empty($details['screenshot_backside']) && (int) (strlen(rtrim($details['screenshot_backside'], '=')) * 3 / 4) > 2100000) { throw new Listing_InvalidDetails('You have uploaded a backside screenshot that is too large'); } // Upload screenshots to imgur if (!empty($details['screenshot_playside'])) { $play = $app->imgur->upload()->string($details['screenshot_playside'])['data']; if (isset($play['error'])) { throw new ImgurAPIException($play['error']); } $details['screenshot_playside'] = isset($play['link']) ? $play['link'] : null; } if (!empty($details['screenshot_backside'])) { $back = $app->imgur->upload()->string($details['screenshot_backside'])['data']; if (isset($back['error'])) { throw new ImgurAPIException($back['error']); } $details['screenshot_backside'] = isset($back['link']) ? $back['link'] : null; } } // Create listing $listing = Listing::create(array_merge(['user_id' => $userid, 'item_id' => (string) $item->id, 'description_id' => $item->desc->id, 'price' => $price, 'message' => $message], $details)); $app->pusher->trigger('bots', 'requestListing', array('listing_id' => (string) $listing->id, 'user_id' => (string) $userid, 'item_id' => (string) $item->id)); $notification = Notification::create(['user_id' => $listing->user_id, 'receiver_id' => $listing->user_id, 'title' => 'APPROVAL', 'body' => '**Listing #' . $app->hashids->encrypt($listing->id) . ' (' . $listing->description->name . ') has been requested!** A bot will send you a trade offer shortly to store your item.']); $app->output->json(array('error' => false, 'listing_id' => $app->hashids->encrypt($listing->id))); } catch (Exception $e) { $app->logger->log('Could not request Listing (' . get_class($e) . ')', 'ERROR', array('pathway' => 'requestListing', 'exception' => $e), 'user'); if ($e instanceof SteamAPIException) { $app->output->json(array('error' => true, 'type' => 'warning', 'message' => 'Steam API could not be reached.'), 503); } else { if ($e instanceof ImgurAPIException) { $app->output->json(array('error' => true, 'type' => 'warning', 'message' => 'imgur API did not accept the uploaded files (' . $e->getMessage() . ').'), 400); } else { if ($e instanceof Listing_MissingItem) { $app->output->json(array('error' => true, 'type' => 'warning', 'message' => 'Inventory item does not exist.'), 400); } else { if ($e instanceof Listing_Duplicate) { $app->output->json(array('error' => true, 'type' => 'warning', 'message' => 'A listing for that item exists.'), 400); } else { if ($e instanceof Listing_StorageFull) { $app->output->json(array('error' => true, 'type' => 'warning', 'message' => 'There is not enough room in a single storage bot to store your items.'), 400); } else { if ($e instanceof Listing_InvalidDetails) { $app->output->json(array('error' => true, 'type' => 'warning', 'message' => 'Your listing request is invalid: ' . $e->getMessage() . '.'), 400); } else { throw $e; } } } } } } } }
public function storageBots($app) { $request = $app->router->flight->request(); if ($request->method != 'POST') { $this->error($app, 'Invalid entry'); } $this->authorize($app, $request->data->key, $request->query->sig, $request->data); $bots = Bot::find('all', array('conditions' => array('type = ? AND status = ?', Bot::TYPE_STORAGE, Bot::STATUS_ACTIVE))); $bots = array_map(function ($b) { return $b->id; }, $bots); $app->output->json(array('error' => false, 'bot_ids' => $bots)); }