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();
148 dynamic_cast<label*
>(history_grid.
find(
"game_name",
false))->set_label(key_with_fallback(
game[
"game_name"]));
149 dynamic_cast<label*
>(history_grid.
find(
"scenario_name",
false))->set_label(key_with_fallback(
game[
"scenario_name"]));
150 dynamic_cast<label*
>(history_grid.
find(
"era_name",
false))->set_label(
"<span color='#baac7d'>" +
_(
"Era: ") +
"</span>" + key_with_fallback(
game[
"era_name"]));
151 dynamic_cast<label*
>(history_grid.
find(
"game_start",
false))->set_label(key_with_fallback(
game[
"game_start"]) +
_(
" UTC+0"));
152 dynamic_cast<label*
>(history_grid.
find(
"version",
false))->set_label(key_with_fallback(
game[
"version"]));
154 button* replay_download =
dynamic_cast<button*
>(history_grid.
find(
"replay_download",
false));
155 std::string replay_url =
game[
"replay_url"].str();
156 if(!replay_url.empty()) {
165 std::vector<std::string> player_list;
166 std::vector<std::string> player_faction_list;
167 for(
const config& player :
game.child_range(
"player")) {
169 player_faction_list.emplace_back(player[
"faction"].str());
172 label* players =
dynamic_cast<label*
>(history_grid.
find(
"players",
false));
175 label* factions =
dynamic_cast<label*
>(history_grid.
find(
"player_factions",
false));
180 label* modifications =
dynamic_cast<label*
>(history_grid.
find(
"modifications",
false));
181 const auto& children =
game.child_range(
"modification");
182 if(!children.empty()) {
183 std::vector<std::string> modifications_list;
185 for(
const config& modification :
game.child_range(
"modification")) {
201 button* newer_history = find_widget<button>(
get_window(),
"newer_history",
false,
true);
204 button* newer_history = find_widget<button>(
get_window(),
"newer_history",
false,
true);
210 if(history.
child_count(
"game_history_result") < 11) {
211 button* older_history = find_widget<button>(
get_window(),
"older_history",
false,
true);
214 button* older_history = find_widget<button>(
get_window(),
"older_history",
false,
true);
221 const config mp_match_history::request_history()
225 child[
"offset"] = offset_;
226 child[
"search_player"] = player_name_;
227 child[
"search_game_name"] = find_widget<text_box>(
get_window(),
"search_game_name",
false).get_value();
228 child[
"search_content_type"] = find_widget<menu_button>(
get_window(),
"search_content_type",
false).get_value();
229 child[
"search_content"] = find_widget<text_box>(
get_window(),
"search_content",
false).get_value();
231 connection_.send_data(request);
233 int times_waited = 0;
243 if(connection_.receive_data(response)) {
244 if(response.
child_count(
"game_history_results") == 0) {
245 DBG_NW <<
"Received non-history data: " << response.
debug();
246 if(!response[
"error"].str().empty()) {
247 ERR_NW <<
"Received error from server: " << response[
"error"].str();
252 DBG_NW <<
"Player has no game history data.";
256 DBG_NW <<
"Received history data: " << response.
debug();
260 DBG_NW <<
"Received no data";
263 if(times_waited > 20 || !wait_for_response_) {
264 ERR_NW <<
"Timed out waiting for history data, returning nothing";
265 if(wait_for_response_) {
272 std::this_thread::sleep_for(250ms);
275 DBG_NW <<
"Something else happened while waiting for history data, returning nothing";
280 void mp_match_history::tab_switch_callback()
282 listbox* history_box = find_widget<listbox>(
get_window(),
"history",
false,
true);
291 }
else if(tab == 1) {
294 }
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.
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.
bool select_row(const unsigned row, const bool select=true)
Selects a 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.
A widget that allows the user to input text in single line.
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.
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()
std::string filename
Filename.
static map_location::DIRECTION s