1 #include "MERCListingModel.h"
2 #include "JsonObject.h"
3 #include "Soldier_Control.h"
4 #include <set>
5 #include <string_theory/format>
6 #include <utility>
7
MERCListingModel(uint8_t index_,uint8_t profileID_,uint8_t bioIndex_,uint32_t minTotalSpending_,uint32_t minDays_,std::vector<SpeckQuote> quotes_)8 MERCListingModel::MERCListingModel(uint8_t index_, uint8_t profileID_, uint8_t bioIndex_,
9 uint32_t minTotalSpending_, uint32_t minDays_,
10 std::vector<SpeckQuote> quotes_
11 ) : index(index_), profileID(profileID_), bioIndex(bioIndex_),
12 minTotalSpending(minTotalSpending_), minDays(minDays_),
13 quotes(std::move(quotes_)) {}
14
isAvailableAtStart() const15 bool MERCListingModel::isAvailableAtStart() const
16 {
17 return this->minDays == 0 && this->minTotalSpending == 0;
18 }
19
getQuotesByType(SpeckQuoteType type) const20 std::vector<SpeckQuote> MERCListingModel::getQuotesByType(SpeckQuoteType type) const
21 {
22 std::vector<SpeckQuote> filtered;
23 for (auto q : quotes)
24 {
25 if (q->type == type) filtered.push_back(q);
26 }
27 return filtered;
28 }
29
SpeckQuoteTypefromString(std::string s)30 static SpeckQuoteType SpeckQuoteTypefromString(std::string s)
31 {
32 if (s == "ADVERTISE") return SpeckQuoteType::ADVERTISE;
33 if (s == "MERC_DEAD") return SpeckQuoteType::MERC_DEAD;
34 if (s == "CROSS_SELL") return SpeckQuoteType::CROSS_SELL;
35
36 throw std::runtime_error("unsupported quote type: " + s);
37 }
38
deserialize(uint8_t index,const rapidjson::Value & json)39 MERCListingModel* MERCListingModel::deserialize(uint8_t index, const rapidjson::Value& json)
40 {
41 std::vector<SpeckQuote> quotes;
42 for (auto& elem : json["quotes"].GetArray())
43 {
44 JsonObjectReader r(elem);
45 auto quote = std::make_shared<MERCSpeckQuote>(
46 r.GetUInt("quoteID"),
47 SpeckQuoteTypefromString(r.GetString("type")),
48 static_cast<uint8_t>(r.getOptionalInt("profileID"))
49 );
50 quotes.push_back(quote);
51 }
52
53 JsonObjectReader r(json);
54 return new MERCListingModel(
55 index,
56 r.GetUInt("profileID"),
57 r.GetUInt("bioIndex"),
58 r.getOptionalInt("minTotalSpending"),
59 r.getOptionalInt("minDays"),
60 quotes
61 );
62
63 }
64
validateData(const std::vector<const MERCListingModel * > & models)65 void MERCListingModel::validateData(const std::vector<const MERCListingModel*>& models)
66 {
67 std::set<uint8_t> uniqueProfileIDs;
68 for (auto m : models)
69 {
70 if (m->profileID == 0 || m->profileID >= NO_PROFILE)
71 {
72 ST::string err = ST::format("Invalid profileID '{}'", m->profileID);
73 throw std::runtime_error(err.to_std_string());
74 }
75
76 // Check if we have duplicates
77 if (uniqueProfileIDs.find(m->profileID) != uniqueProfileIDs.end())
78 {
79 ST::string err = ST::format("profileID {} has been listed more than once", m->profileID);
80 throw std::runtime_error(err.to_std_string());
81 }
82 uniqueProfileIDs.insert(m->profileID);
83 }
84
85 for (auto m : models)
86 {
87 for (const auto& quote : m->getQuotesByType(SpeckQuoteType::CROSS_SELL))
88 {
89 // Check if related merc is set
90 if (!quote->relatedMercID)
91 {
92 ST::string err = ST::format("No related merc ID set for a CROSS_SELL quote ({})", m->profileID);
93 throw std::runtime_error(err.to_std_string());
94 }
95 }
96 }
97 }