diff --git a/src/oro/api_nap.cpp b/src/oro/api_nap.cpp index a7be2fc..f257d05 100644 --- a/src/oro/api_nap.cpp +++ b/src/oro/api_nap.cpp @@ -21,6 +21,9 @@ #include "duckhandy/int_conv.hpp" #include +namespace sjd = simdjson::dom; +namespace sj = simdjson; + namespace oro { namespace { @@ -50,14 +53,21 @@ void fill_base_json (const simdjson::dom::element& doc, BaseJsonReply& out) { out.version = static_cast(doc["version"].get_int64()); } -template -std::optional get_optional (const simdjson::dom::element& elem, const char* name) { +template +std::optional get_optional (const sj::simdjson_result& elem) { + typedef std::optional RetType; + T retval; - simdjson::error_code error = elem[name].get(retval); - if (not error) - return {static_cast(retval)}; - else - return {}; + const simdjson::error_code error = elem.get(retval); + return (not error ? RetType{static_cast(retval)} : RetType{}); +} + +template +R get_or_default (const sj::simdjson_result& elem, R def) { + T retval; + const simdjson::error_code error = elem.get(retval); + return (not error ? static_cast(retval) : def); +} } } //unnamed namespace @@ -111,9 +121,9 @@ std::pair ApiNap::items_list() { new_entry.unique_name = item["unique_name"]; new_entry.name = item["name"]; new_entry.type = item["type"].get_string(); - new_entry.subtype = get_optional(item, "subtype"); + new_entry.subtype = get_optional(item["subtype"]); new_entry.npc_price = static_cast(item["npc_price"].get_uint64()); - new_entry.slots = get_optional(item, "slots"); + new_entry.slots = get_optional(item["slots"]); out.items.push_back(std::move(new_entry)); } } @@ -137,6 +147,53 @@ std::pair ApiNap::items_icons() { } std::pair ApiNap::market_list() { + return fetch_and_parse( + g_endpoint_market_list, + [](const simdjson::dom::element& doc, Shops& out) { + auto shops = doc["shops"].get_array(); + out.shops.reserve(shops.size()); + for (auto shop : shops) { + Shop new_shop; + new_shop.title = shop["title"]; + new_shop.owner = shop["owner"]; + new_shop.creation_date = std::string(shop["creation_date"]); + new_shop.type = shop["type"].get_string(); + { + auto loc = shop["location"]; + new_shop.location.map = loc["map"]; + new_shop.location.x = static_cast(loc["x"].get_int64()); + new_shop.location.y = static_cast(loc["y"].get_int64()); + } + { + auto items = shop["items"].get_array(); + new_shop.items.reserve(items.size()); + for (auto item : items) { + ShopItem new_item; + new_item.item_id = static_cast(item["item_id"].get_uint64()); + new_item.amount = static_cast(item["amount"].get_uint64()); + new_item.price = static_cast(item["price"].get_uint64()); + new_item.refine = get_or_default(item["refine"], 0); + new_item.star_crumbs = get_or_default(item["star_crumbs"], 0); + new_item.element = get_optional(item["element"]); + new_item.creator = get_optional(item["creator"]); + new_item.beloved = get_optional(item["beloved"]); + + auto item_cards = item["cards"]; + if (item_cards.is_array()) { + auto cards = item_cards.get_array(); + new_item.cards.reserve(cards.size()); + for (uint64_t card : cards) { + new_item.cards.push_back(static_cast(card)); + } + } + + new_shop.items.push_back(std::move(new_item)); + } + } + out.shops.push_back(std::move(new_shop)); + } + } + ); } std::pair ApiNap::fame_list() { diff --git a/src/oro/shops.cpp b/src/oro/shops.cpp index 4288060..a5ab12c 100644 --- a/src/oro/shops.cpp +++ b/src/oro/shops.cpp @@ -28,6 +28,10 @@ ShopTypeWrapper::ShopTypeWrapper (const std::string& str) { *this = str; } +ShopTypeWrapper::ShopTypeWrapper (std::string_view str) { + *this = str; +} + ShopTypeWrapper& ShopTypeWrapper::operator= (int val) { if (static_cast(ShopType::Vending) == val) value = ShopType::Vending; @@ -39,12 +43,16 @@ ShopTypeWrapper& ShopTypeWrapper::operator= (int val) { } ShopTypeWrapper& ShopTypeWrapper::operator= (const std::string& str) { + return this->operator=(std::string_view(str)); +} + +ShopTypeWrapper& ShopTypeWrapper::operator= (std::string_view str) { if ("V" == str) value = ShopType::Vending; else if ("B" == str) value = ShopType::Buying; else - throw std::runtime_error("Unknown shop type '" + str + "'"); + throw std::runtime_error("Unknown shop type '" + std::string(str) + "'"); return *this; } diff --git a/src/oro/shops.hpp b/src/oro/shops.hpp index fb43985..99a9c2d 100644 --- a/src/oro/shops.hpp +++ b/src/oro/shops.hpp @@ -20,6 +20,7 @@ #include "datatypes.hpp" #include #include +#include #include namespace oro { @@ -33,8 +34,10 @@ namespace oro { ShopTypeWrapper() = default; ShopTypeWrapper (int val); ShopTypeWrapper (const std::string& str); + ShopTypeWrapper (std::string_view str); ShopTypeWrapper& operator= (int val); ShopTypeWrapper& operator= (const std::string& str); + ShopTypeWrapper& operator= (std::string_view str); operator ShopType() const {return value;} ShopType value {ShopType::Unknown}; };