This repository was archived by the owner on Aug 19, 2022. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 98
/
Copy pathitemsmanager.cpp
202 lines (174 loc) · 7.16 KB
/
itemsmanager.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
/*
Copyright 2014 Ilya Zhuravlev
This file is part of Acquisition.
Acquisition is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Acquisition is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Acquisition. If not, see <http://www.gnu.org/licenses/>.
*/
#include "itemsmanager.h"
#include <QThread>
#include <stdexcept>
#include "application.h"
#include "buyoutmanager.h"
#include "datastore.h"
#include "itemsmanagerworker.h"
#include "porting.h"
#include "rapidjson_util.h"
#include "shop.h"
#include "util.h"
#include "mainwindow.h"
#include "filters.h"
ItemsManager::ItemsManager(Application &app) :
auto_update_timer_(std::make_unique<QTimer>()),
data_(app.data()),
bo_manager_(app.buyout_manager()),
shop_(app.shop()),
app_(app)
{
auto_update_interval_ = std::stoi(data_.Get("autoupdate_interval", "30"));
auto_update_ = data_.GetBool("autoupdate", true);
SetAutoUpdateInterval(auto_update_interval_);
connect(auto_update_timer_.get(), SIGNAL(timeout()), this, SLOT(OnAutoRefreshTimer()));
}
ItemsManager::~ItemsManager() {
thread_->quit();
thread_->wait();
}
void ItemsManager::Start() {
thread_ = std::make_unique<QThread>();
worker_ = std::make_unique<ItemsManagerWorker>(app_, thread_.get());
connect(thread_.get(), SIGNAL(started()), worker_.get(), SLOT(Init()));
connect(this, SIGNAL(UpdateSignal(TabSelection::Type, const std::vector<ItemLocation> &)), worker_.get(), SLOT(Update(TabSelection::Type, const std::vector<ItemLocation> &)));
connect(worker_.get(), &ItemsManagerWorker::StatusUpdate, this, &ItemsManager::OnStatusUpdate);
connect(worker_.get(), SIGNAL(ItemsRefreshed(Items, std::vector<ItemLocation>, bool)), this, SLOT(OnItemsRefreshed(Items, std::vector<ItemLocation>, bool)));
worker_->moveToThread(thread_.get());
thread_->start();
}
void ItemsManager::OnStatusUpdate(const CurrentStatusUpdate &status) {
emit StatusUpdate(status);
}
void ItemsManager::ApplyAutoTabBuyouts() {
// Can handle everything related to auto-tab pricing here.
// 1. First format we need to honor is ascendency pricing formats which is top priority and overrides other types
// 2. Second priority is to honor manual user pricing
// 3. Third priority it to apply pricing based on ideally user specified formats (doesn't exist yet)
// Loop over all tabs, create buyout based on tab name which applies auto-pricing policies
auto &bo = app_.buyout_manager();
for (auto const &loc: bo_manager_.GetStashTabLocations()) {
auto tab_label = loc.get_tab_label();
Buyout buyout = bo.StringToBuyout(tab_label);
if (buyout.IsActive()) {
bo.SetTab(loc.GetUniqueHash(), buyout);
}
}
// Need to compress tab buyouts here, as the tab names change we accumulate and save BO's
// for tabs that no longer exist I think.
bo.CompressTabBuyouts();
}
void ItemsManager::ApplyAutoItemBuyouts() {
// Loop over all items, check for note field with pricing and apply
auto &bo = app_.buyout_manager();
for (auto const& item: items_) {
auto const ¬e = item->note();
if (!note.empty()) {
Buyout buyout = bo.StringToBuyout(note);
// This line may look confusing, buyout returns an active buyout if game
// pricing was found or a default buyout (inherit) if it was not.
// If there is a currently valid note we want to apply OR if
// old note no longer is valid (so basically clear pricing)
if (buyout.IsActive() || bo.Get(*item).IsGameSet()) {
bo.Set(*item, buyout);
}
}
}
// Commenting this out for robustness (iss381) to make it as unlikely as possible that users
// pricing data will be removed. Side effect is that stale pricing data will pile up and
// could be applied to future items with the same hash (which includes tab name).
// bo.CompressItemBuyouts(items_);
}
void ItemsManager::PropagateTabBuyouts() {
auto &bo = app_.buyout_manager();
bo.ClearRefreshLocks();
for (auto &item_ptr : items_) {
Item &item = *item_ptr;
std::string hash = item.location().GetUniqueHash();
auto item_bo = bo.Get(item);
auto tab_bo = bo.GetTab(hash);
if (item_bo.IsInherited()) {
if (tab_bo.IsActive()) {
// Any propagation from tab price to item price should include this bit set
tab_bo.inherited = true;
tab_bo.last_update = QDateTime::currentDateTime();
bo.Set(item, tab_bo);
} else {
// This effectively 'clears' buyout by setting back to 'inherit' state.
bo.Set(item, Buyout());
}
}
// If any savable bo's are set on an item or the tab then lock
// the refresh state.
if (bo.Get(item).RequiresRefresh() || tab_bo.RequiresRefresh()) {
bo.SetRefreshLocked(item.location());
}
}
}
void ItemsManager::OnItemsRefreshed(const Items &items, const std::vector<ItemLocation> &tabs, bool initial_refresh) {
items_ = items;
bo_manager_.SetStashTabLocations(tabs);
MigrateBuyouts();
ApplyAutoTabBuyouts();
ApplyAutoItemBuyouts();
PropagateTabBuyouts();
UpdateCategories();
emit ItemsRefreshed(initial_refresh);
}
void ItemsManager::UpdateCategories() {
categories_.clear();
for (auto const &item: items_) {
QString tmp;
for (auto const &level: item->category_vector()) {
tmp = tmp.isEmpty() ? level.c_str(): tmp + "." + level.c_str();
categories_.insert(tmp);
}
}
// Need a 'default' string option for unconstrained search
categories_.insert(CategorySearchFilter::k_Default.c_str());
}
void ItemsManager::Update(TabSelection::Type type, const std::vector<ItemLocation> &locations) {
emit UpdateSignal(type, locations);
}
void ItemsManager::SetAutoUpdate(bool update) {
data_.SetBool("autoupdate", update);
auto_update_ = update;
if (!auto_update_)
auto_update_timer_->stop();
else
// to start timer
SetAutoUpdateInterval(auto_update_interval_);
}
void ItemsManager::SetAutoUpdateInterval(int minutes) {
data_.Set("autoupdate_interval", std::to_string(minutes));
auto_update_interval_ = minutes;
if (auto_update_)
auto_update_timer_->start(auto_update_interval_ * 60 * 1000);
}
void ItemsManager::OnAutoRefreshTimer() {
Update(TabSelection::Checked);
}
void ItemsManager::MigrateBuyouts() {
int db_version = data_.GetInt("db_version");
// Don't migrate twice
if (db_version == 4)
return;
for (auto &item : items_)
bo_manager_.MigrateItem(*item);
bo_manager_.Save();
data_.SetInt("db_version", 4);
}