32 using namespace std::chrono_literals;
35 #define DBG_NW LOG_STREAM(debug, log_network)
36 #define ERR_NW LOG_STREAM(err, log_network)
44 , player_name_(player_name)
45 , connection_(connection)
47 , wait_for_response_(wait_for_response)
49 register_label(
"title",
true,
VGETTEXT(
"Match History — $player", {{
"player", player_name_}}));
52 void mp_match_history::pre_show(
window& win)
56 button& newer_history = find_widget<button>(&win,
"newer_history",
false);
57 button& older_history = find_widget<button>(&win,
"older_history",
false);
61 button& search = find_widget<button>(&win,
"search",
false);
64 text_box& search_player = find_widget<text_box>(&win,
"search_player",
false);
67 std::vector<config> content_types;
68 content_types.emplace_back(
"label",
_(
"Scenario"));
69 content_types.emplace_back(
"label",
_(
"Era"));
70 content_types.emplace_back(
"label",
_(
"Modification"));
72 find_widget<menu_button>(&win,
"search_content_type",
false).set_values(content_types);
77 void mp_match_history::new_search()
79 int old_offset = offset_;
80 std::string old_player_name = player_name_;
85 if(!update_display()) {
87 player_name_ = old_player_name;
94 void mp_match_history::newer_history_offset()
98 if(!update_display()) {
103 void mp_match_history::older_history_offset()
107 if(!update_display()) {
119 if(std::string
s = val.
str(); !
s.empty()) {
127 bool mp_match_history::update_display()
129 const config history = request_history();
132 if(history.
child_count(
"game_history_results") == 0) {
136 listbox* history_box = find_widget<listbox>(
get_window(),
"history",
false,
true);
137 history_box->
clear();
147 dynamic_cast<label*
>(history_grid.
find(
"game_name",
false))->set_label(key_with_fallback(
game[
"game_name"]));
148 dynamic_cast<label*
>(history_grid.
find(
"scenario_name",
false))->set_label(key_with_fallback(
game[
"scenario_name"]));
149 dynamic_cast<label*
>(history_grid.
find(
"era_name",
false))->set_label(
"<span color='#baac7d'>" +
_(
"Era: ") +
"</span>" + key_with_fallback(
game[
"era_name"]));
150 dynamic_cast<label*
>(history_grid.
find(
"game_start",
false))->set_label(key_with_fallback(
game[
"game_start"]) +
_(
" UTC+0"));
151 dynamic_cast<label*
>(history_grid.
find(
"version",
false))->set_label(key_with_fallback(
game[
"version"]));
153 button* replay_download =
dynamic_cast<button*
>(history_grid.
find(
"replay_download",
false));
154 std::string replay_url =
game[
"replay_url"].str();
155 if(!replay_url.empty()) {
156 std::string filename =
utils::split(replay_url,
'/').back();
164 std::vector<std::string> player_list;
165 std::vector<std::string> player_faction_list;
166 for(
const config& player :
game.child_range(
"player")) {
168 player_faction_list.emplace_back(player[
"faction"].str());
171 label* players =
dynamic_cast<label*
>(history_grid.
find(
"players",
false));
174 label* factions =
dynamic_cast<label*
>(history_grid.
find(
"player_factions",
false));
180 const auto& children =
game.child_range(
"modification");
181 if(!children.empty()) {
182 std::vector<std::string> modifications_list;
184 for(
const config& modification :
game.child_range(
"modification")) {
200 button* newer_history = find_widget<button>(
get_window(),
"newer_history",
false,
true);
203 button* newer_history = find_widget<button>(
get_window(),
"newer_history",
false,
true);
209 if(history.
child_count(
"game_history_result") < 11) {
210 button* older_history = find_widget<button>(
get_window(),
"older_history",
false,
true);
213 button* older_history = find_widget<button>(
get_window(),
"older_history",
false,
true);
220 const config mp_match_history::request_history()
224 child[
"offset"] = offset_;
225 child[
"search_player"] = player_name_;
226 child[
"search_game_name"] = find_widget<text_box>(
get_window(),
"search_game_name",
false).get_value();
227 child[
"search_content_type"] = find_widget<menu_button>(
get_window(),
"search_content_type",
false).get_value();
228 child[
"search_content"] = find_widget<text_box>(
get_window(),
"search_content",
false).get_value();
230 connection_.send_data(request);
232 int times_waited = 0;
242 if(connection_.receive_data(response)) {
243 if(response.
child_count(
"game_history_results") == 0) {
244 DBG_NW <<
"Received non-history data: " << response.
debug();
245 if(!response[
"error"].str().empty()) {
246 ERR_NW <<
"Received error from server: " << response[
"error"].str();
251 DBG_NW <<
"Player has no game history data.";
255 DBG_NW <<
"Received history data: " << response.
debug();
259 DBG_NW <<
"Received no data";
262 if(times_waited > 20 || !wait_for_response_) {
263 ERR_NW <<
"Timed out waiting for history data, returning nothing";
264 if(wait_for_response_) {
271 std::this_thread::sleep_for(250ms);
274 DBG_NW <<
"Something else happened while waiting for history data, returning nothing";
279 void mp_match_history::tab_switch_callback()
281 listbox* history_box = find_widget<listbox>(
get_window(),
"history",
false,
true);
290 }
else if(tab == 1) {
293 }
else if(tab == 2) {
Variant for storing WML attributes.
std::string str(const std::string &fallback="") const
A config object defines a single node in a WML file, with access to child nodes.
config & mandatory_child(config_key_type key, int n=0)
Returns the nth child with the given key, or throws an error if there is none.
std::size_t child_count(config_key_type key) const
child_itors child_range(config_key_type key)
std::string debug() const
config & add_child(config_key_type key)
Abstract base class for all modal dialogs.
widget * find(const std::string &id, const bool must_be_active) override
See widget::find.
A label displays text that can be wrapped but no scrollbars are provided.
grid & add_row(const widget_item &item, const int index=-1)
When an item in the list is selected by the user we need to update the state.
const grid * get_row_grid(const unsigned row) const
Returns the grid of the wanted row.
void clear()
Removes all the rows in the listbox, clearing it.
int get_selected_row() const
Returns the first selected row.
unsigned get_item_count() const
Returns the number of items in the listbox.
std::string get_value() const
virtual void set_value(const std::string &text)
The set_value is virtual for the password_box class.
Class for a single line text area.
base class of top level items, the only item which needs to store the final canvases to draw on.
void set_enter_disabled(const bool enter_disabled)
Disable the enter key.
A class that represents a TCP/IP connection to the wesnothd server.
Declarations for File-IO.
static std::string _(const char *str)
static lg::log_domain log_network("network")
#define REGISTER_DIALOG(window_id)
Wrapper for REGISTER_DIALOG2.
std::string get_saves_dir()
const std::string unicode_em_dash
const std::string unicode_bullet
void connect_signal_notify_modified(dispatcher &dispatcher, const signal_notification &signal)
Connects a signal handler for getting a notification upon modification.
void connect_signal_mouse_left_click(dispatcher &dispatcher, const signal &signal)
Connects a signal handler for a left mouse button click.
std::map< std::string, widget_item > widget_data
void show_error_message(const std::string &msg, bool message_use_markup)
Shows an error message to the user.
void download(const std::string &url, const std::string &local_path)
Initiates a standalone download of a single file from an HTTPS URL.
const std::vector< std::string > & modifications(bool mp)
std::string join(const T &v, const std::string &s=",")
Generates a new string joining container items in a list.
std::vector< std::string > split(const config_attribute_value &val)
SDL_Window * get_window()
static map_location::DIRECTION s