The Battle for Wesnoth  1.13.4+dev
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
multiplayer_ui.cpp
Go to the documentation of this file.
1 /*
2  Copyright (C) 2005 - 2016 by David White <[email protected]>
3  Part of the Battle for Wesnoth Project http://www.wesnoth.org
4 
5  This program is free software; you can redistribute it and/or modify
6  it under the terms of the GNU General Public License as published by
7  the Free Software Foundation; either version 2 of the License, or
8  (at your option) any later version.
9  This program is distributed in the hope that it will be useful,
10  but WITHOUT ANY WARRANTY.
11 
12  See the COPYING file for more details.
13 */
14 
15 #include "global.hpp"
16 
17 #include "construct_dialog.hpp"
18 #include "video.hpp"
19 #include "game_preferences.hpp"
20 #include "gettext.hpp"
23 #include "lobby_preferences.hpp"
24 #include "log.hpp"
25 #include "marked-up_text.hpp"
26 #include "menu_events.hpp"
27 #include "multiplayer.hpp"
28 #include "multiplayer_ui.hpp"
29 #include "multiplayer_lobby.hpp" //needed for dynamic cast when implementing the lobby_sounds preference
30 #include "mp_ui_alerts.hpp"
31 #include "wml_separators.hpp"
32 #include "formula/string_utils.hpp"
35 #include "team.hpp"
36 #include "sdl/utils.hpp"
37 #include "sdl/rect.hpp"
38 #include "wesnothd_connection.hpp"
39 
40 static lg::log_domain log_config("config");
41 #define ERR_CF LOG_STREAM(err, log_config)
42 
43 static lg::log_domain log_network("network");
44 #define LOG_NW LOG_STREAM(info, log_network)
45 #define ERR_NW LOG_STREAM(err, log_network)
46 
47 static lg::log_domain log_mp("mp/main");
48 #define DBG_MP LOG_STREAM(debug, log_mp)
49 
50 namespace {
51  /** The maximum number of messages in the chat history. */
52  const size_t max_messages = 256;
53 
54  class user_menu_style : public gui::menu::imgsel_style {
55  public:
56  user_menu_style() : gui::menu::imgsel_style("dialogs/selection", false,
57  0x000000, 0x4a4440, 0x999999,
58  0.0, 0.2, 0.2),
59  item_size_(sdl::empty_rect)
60  {}
61  virtual void init();
62  virtual SDL_Rect item_size(const std::string& /*item*/) const { return item_size_; }
63  void set_width(const int width) { item_size_.w = width; }
64  private:
65  SDL_Rect item_size_;
66  };
67 
69  {
71  item_size_.h = font::get_max_height(font_size_);
72  scale_images(-1, item_size_.h);
73  item_size_.h += 2 * thickness_;
74  }
75 
76  user_menu_style umenu_style;
77 
78 } // anon namespace
79 
80 namespace mp {
81 
83 {
86  if(name != game_config::team_rgb_name.end()){
87  return prefix + name->second;
88  }else{
89  return prefix + _("Invalid Color");
90  }
91 }
92 
94 {
97  bool has_color = i_color != game_config::team_rgb_range.end();
98  bool has_name= i_name != game_config::team_rgb_name.end();
99 
100  return rgb2highlight(has_color ? i_color->second.mid() : 0x00FF0000) + (has_name ? std::string(i_name->second) : _("Invalid Color"));
101 }
102 
104  message_history_(),
105  last_update_()
106 {
107 }
108 
109 void chat::add_message(const time_t& time, const std::string& user,
110  const std::string& message)
111 {
112  message_history_.push_back(msg(time, user, message));
113 
114  while (message_history_.size() > max_messages) {
115  message_history_.pop_front();
116 
117  if (last_update_ > 0)
118  last_update_--;
119  }
120 }
121 
123 {
124  for(msg_hist::const_iterator itor = message_history_.begin();
125  itor != message_history_.end(); ++itor) {
126  textbox.append_text(format_message(*itor), true, color_message(*itor));
127  }
128 
130 }
131 
133 {
134  //DBG_MP << "update_textbox...\n";
135  for(msg_hist::const_iterator itor = message_history_.begin() + last_update_;
136  itor != message_history_.end(); ++itor) {
137  textbox.append_text(format_message(*itor), true, color_message(*itor));
138  }
139  //DBG_MP << "update_textbox end\n";
140 
142 }
143 
145 {
146  message_history_.clear();
147  last_update_ = 0;
148 }
149 
151 {
152  std::string msg_text = message.message;
153  if(message.user == "server"
154  || message.user.substr(0,29) == "whisper: server message from ") {
155  std::string::const_iterator after_markup =
156  font::parse_markup(message.message.begin(), message.message.end(), nullptr, nullptr, nullptr);
157 
158  msg_text = std::string(after_markup,message.message.end());
159  }
160  if(message.message.substr(0,3) == "/me") {
161  return preferences::get_chat_timestamp(message.time) + "<" + message.user
162  + msg_text.substr(3) + ">\n";
163  } else {
164  return preferences::get_chat_timestamp(message.time) + "<" + message.user
165  + "> " + msg_text + "\n";
166  }
167 }
168 
169 SDL_Color chat::color_message(const msg& message) {
170  SDL_Color c = font::NORMAL_COLOR;
171  // Normal users are not allowed to color their messages
172  if(message.user == "server"
173  || message.user.substr(0,29) == "whisper: server message from ") {
174  font::parse_markup(message.message.begin(), message.message.end(), nullptr, &c, nullptr);
175  // Highlight private messages too
176  } else if(message.user.substr(0,8) == "whisper:") {
177  c = font::LABEL_COLOR;
178  }
179  return c;
180 }
181 
182 ui::ui(CVideo& video, twesnothd_connection* wesnothd_connection, const std::string& title, const config& cfg, chat& c, config& gamelist) :
183  gui::widget(video),
184  video_(video),
185  wesnothd_connection_(wesnothd_connection),
186  initialized_(false),
187  gamelist_initialized_(false),
188 
189  game_config_(cfg),
190  chat_(c),
191  gamelist_(gamelist),
192 
193  title_(video_, title, font::SIZE_LARGE, font::TITLE_COLOR),
194  entry_textbox_(video_, 100),
195  chat_textbox_(video_, 100, "", false),
196  users_menu_(video_, std::vector<std::string>(), false, -1, -1, nullptr, &umenu_style),
197 
198  user_list_(),
199  selected_game_(""),
200  selected_user_(""),
201  selected_user_changed_(false),
202 
203  result_(CONTINUE),
204  gamelist_refresh_(false),
205  lobby_clock_(0),
206  whisper_warnings_(),
207  plugins_context_(nullptr)
208 {
209  const SDL_Rect area = sdl::create_rect(0
210  , 0
211  , video.getx()
212  , video.gety());
214  set_location(area);
215 }
216 
218 {
219  config data;
220  if(receive_from_server(data)) {
221  process_network_data(data);
222  }
223 
224  //apply diffs at a set interval
226  {
227  const cursor::setter cursor_setter(cursor::WAIT);
228  gamelist_updated(false);
229  gamelist_refresh_ = false;
230  lobby_clock_ = SDL_GetTicks();
231  }
232 }
233 
235 {
236  return result_;
237 }
238 
240 {
241  result_ = res;
242  return res;
243 }
244 
245 const int ui::xscale_base = 1024;
246 const int ui::yscale_base = 768;
247 
248 int ui::xscale(int x) const
249 {
250  return (x * width())/ui::xscale_base;
251 }
252 
253 int ui::yscale(int y) const
254 {
255  return (y * height())/ui::yscale_base;
256 }
257 
258 SDL_Rect ui::client_area() const
259 {
260  SDL_Rect res;
261 
262  res.x = xscale(10) + 10;
263  res.y = yscale(38) + 10;
264  res.w = xscale(828) > 12 ? xscale(828) - 12 : 0;
265  res.h = yscale(520) > 12 ? yscale(520) - 12 : 0;
266 
267  return res;
268 }
269 
270 const config& ui::game_config() const
271 {
272  return game_config_;
273 }
274 
276 {
277  hide_children();
278 
279  surface background(image::get_image("misc/lobby.png"));
280  background = scale_surface(background, video().getx(), video().gety());
281  if(background == nullptr)
282  return;
283  sdl_blit(background, nullptr, video().getSurface(), nullptr);
284  hide_children(false);
285 }
286 
287 void ui::set_location(const SDL_Rect& rect)
288 {
289  hide_children();
290  widget::set_location(rect);
291  layout_children(rect);
292  if(!initialized_) {
293  chat_textbox_.set_wrap(true);
296  initialized_ = true;
297  }
298  hide_children(false);
299 }
300 
302 {
303 }
304 
305 void ui::handle_event(const SDL_Event& event)
306 {
308  return;
309  }
311 
312  if (event.type == SDL_WINDOWEVENT && event.window.event == SDL_WINDOWEVENT_RESIZED) {
313  SDL_Rect new_location;
314  new_location.x = 0;
315  new_location.y = 0;
316  new_location.w = event.window.data1;
317  new_location.h = event.window.data2;
318  set_location(new_location);
319  }
320 
321  if(event.type == SDL_KEYDOWN) {
322  handle_key_event(event.key);
323  }
326  Uint32 show_time = SDL_GetTicks();
327 
328  // Hack: for some reason the help string stays visible for ever
329  /** @todo find out why the help string stays visible and fix it */
331 
332  gui2::tmp_cmd_wrapper dlg(_("Selected user: ") + usr_text);
333  dlg.show(video());
334 
335  std::stringstream msg;
336  switch(dlg.get_retval()) {
337  case -1:
338  if(!dlg.message().empty()) msg << "/msg " << usr_text << ' ' << dlg.message();
339  break;
340  case 1:
341  msg << "/friend " << usr_text;
342  break;
343  case 2:
344  msg << "/ignore " << usr_text;
345  break;
346  case 3:
347  msg << "/remove " << usr_text;
348  break;
349  case 4:
350  msg << "/query status " << usr_text;
351  break;
352  case 5:
353  msg << "/query kick " << usr_text;
354  if(!dlg.reason().empty()) msg << ' ' << dlg.reason();
355  break;
356  case 6:
357  msg << "/query kban " << usr_text;
358  if(!dlg.time().empty()) msg << ' ' << dlg.time();
359  if(!dlg.reason().empty()) msg << ' ' << dlg.reason();
360  }
361 
362  chat_handler::do_speak(msg.str());
363 
364  if(show_time + 60000 < SDL_GetTicks()) {
365  //if the dialog has been open for a long time, refresh the lobby
366  config request;
367  request.add_child("refresh_lobby");
368  send_to_server(request);
369  }
370  }
371  if(users_menu_.selection() > 0 // -1 indicates an invalid selection
374  selected_user_changed_ = true;
375  }
376 }
377 
378 void ui::add_chat_message(const time_t& time, const std::string& speaker, int /*side*/, const std::string& message, events::chat_handler::MESSAGE_TYPE /*type*/)
379 {
380  chat_.add_message(time, speaker, message);
382 }
383 
384 void ui::send_chat_message(const std::string& message, bool /*allies_only*/)
385 {
386  config data, msg;
387  msg["message"] = message;
388  msg["sender"] = preferences::login();
389  data.add_child("message", msg);
390 
391  add_chat_message(time(nullptr), preferences::login(),0, message); //local echo
392  send_to_server(data);
393 }
394 
395 void ui::handle_key_event(const SDL_KeyboardEvent& event)
396 {
397  //On enter, adds the current chat message to the chat textbox.
398  if((event.keysym.sym == SDLK_RETURN || event.keysym.sym == SDLK_KP_ENTER) && !entry_textbox_.text().empty()) {
399 
400  chat_handler::do_speak(entry_textbox_.text());
402  // nick tab-completion
403  } else if(event.keysym.sym == SDLK_TAB ) {
405  std::vector<std::string> matches = user_list_;
406  // Exclude own nick from tab-completion.
407  matches.erase(std::remove(matches.begin(), matches.end(),
408  preferences::login()), matches.end());
409  const bool line_start = utils::word_completion(text, matches);
410 
411  if (matches.empty()) return;
412 
413  if (matches.size() == 1) {
414  text.append(line_start ? ": " : " ");
415  } else {
416  std::string completion_list = utils::join(matches, " ");
417  chat_.add_message(time(nullptr), "", completion_list);
419  }
420  entry_textbox_.set_text(text);
421  }
422 }
423 
424 void ui::process_message(const config& msg, const bool whisper) {
425  const std::string& sender = msg["sender"];
426  const std::string& message = msg["message"];
427  std::string room = msg["room"];
428  if (!preferences::parse_should_show_lobby_join(sender, message)) return;
429  if (preferences::is_ignored(sender)) return;
430 
431  // Warn about people trying to whisper a player with the
432  // whisper_friends_only option enabled.
433  if (whisper &&
435  sender != "server" &&
436  sender.find(' ') == std::string::npos && // "server message from foo"
437  !preferences::is_friend(sender))
438  {
439  LOG_NW << "Accepting whispers from friends only, ignored whisper from " << sender << '\n';
440 
441  typedef std::map<std::string, time_t> timetable;
442  timetable::const_iterator i = whisper_warnings_.find(sender);
443 
444  time_t last_warning = 0;
445  const time_t cur_time = time(nullptr);
446  static const time_t warning_duration = 5 * 60;
447 
448  if (i != whisper_warnings_.end()) {
449  last_warning = i->second;
450  }
451 
452  //
453  // Don't warn if it's been less than warning_duration seconds since
454  // the last warning. Also, make sure the clock isn't running backwards,
455  // warn anyway if it is.
456  //
457  // We don't need to hande the case where preferences change between
458  // whispers because the lobby instance gets recreated along with the
459  // table after closing the preferences dialog.
460  //
461  if (last_warning && last_warning < cur_time && cur_time - last_warning < warning_duration) {
462  return;
463  }
464 
465  utils::string_map symbols;
466  symbols["sender"] = sender;
467 
468  chat_.add_message(cur_time,
469  "server",
470  VGETTEXT("$sender is messaging you, and you accept whispers from friends only.", symbols));
472 
473  whisper_warnings_[sender] = cur_time;
474 
475  return;
476  }
477 
479 
480  bool is_lobby = dynamic_cast<mp::lobby*>(this) != nullptr;
481 
482  if (whisper || utils::word_match(message, preferences::login())) {
483  mp_ui_alerts::private_message(is_lobby, sender, message);
484  } else if (preferences::is_friend(sender)) {
485  mp_ui_alerts::friend_message(is_lobby, sender, message);
486  } else if (sender == "server") {
487  mp_ui_alerts::server_message(is_lobby, sender, message);
488  } else {
489  mp_ui_alerts::public_message(is_lobby, sender, message);
490  }
491 
492  std::string prefix;
493 
494  if(whisper) {
495  utils::string_map symbols;
496  symbols["sender"] = msg["sender"].str();
497  prefix = VGETTEXT("whisper: $sender", symbols);
498  }
499  else {
500  prefix = msg["sender"].str();
501  }
502 
503  if (!room.empty()) room = room + ": ";
504 
505  chat_.add_message(time(nullptr), room + prefix, msg["message"]);
507 
508  config temp = msg;
509  temp["whisper"] = whisper;
510  plugins_manager::get()->notify_event("chat", temp); //notify plugins of the network message
511 }
512 
514 {
515  if (const config &c = data.child("error")) {
516  throw wesnothd_error(c["message"]);
517  } else if (const config &c = data.child("message")) {
519  } else if (const config &c = data.child("whisper")) {
520  process_message(c, true);
521  } else if(data.child("gamelist")) {
522  const cursor::setter cursor_setter(cursor::WAIT);
523  gamelist_initialized_ = true;
524  gamelist_ = data;
525  gamelist_updated(false);
526  gamelist_refresh_ = false;
527  lobby_clock_ = SDL_GetTicks();
528  } else if (const config &c = data.child("gamelist_diff")) {
530  try {
532  } catch(config::error& e) {
533  ERR_CF << "Error while applying the gamelist diff: '"
534  << e.message << "' Getting a new gamelist.\n";
535  send_to_server(config("refresh_lobby"));
536  }
537  gamelist_refresh_ = true;
538  }
539  } else if (const config &c = data.child("room_join")) {
540  if (c["player"] == preferences::login()) {
541  chat_.add_message(time(nullptr), "server",
542  "You have joined the room '" + c["room"].str() + "'");
543  } else {
544  chat_.add_message(time(nullptr), "server",
545  c["player"].str() + " has joined the room '" + c["room"].str() + "'");
546  }
548  } else if (const config &c = data.child("room_part")) {
549  if (c["player"] == preferences::login()) {
550  chat_.add_message(time(nullptr), "server",
551  "You have left the room '" + c["room"].str() + "'");
552  } else {
553  chat_.add_message(time(nullptr), "server",
554  c["player"].str() + " has left the room '" + c["room"].str() + "'");
555  }
557  } else if (const config &c = data.child("room_query_response")) {
558  if (const config &ms = c.child("members")) {
559  std::stringstream ss;
560  ss << "Room " << c["room"].str() << " members: ";
561  for (const config& m : ms.child_range("member")) {
562  ss << m["name"] << " ";
563  }
564  chat_.add_message(time(nullptr), "server", ss.str());
566  }
567  if (const config &rs = c.child("rooms")) {
568  std::stringstream ss;
569  ss << "Rooms: ";
570  for (const config& r : rs.child_range("room")) {
571  ss << r["name"].str() << "(" << r["size"].str() << ") ";
572  }
573  chat_.add_message(time(nullptr), "server", ss.str());
575  }
576  }
577 }
578 
579 void ui::hide_children(bool hide)
580 {
581  title_.hide(hide);
582  chat_textbox_.hide(hide);
583  entry_textbox_.hide(hide);
584  users_menu_.hide(hide);
585 }
586 
587 void ui::layout_children(const SDL_Rect& /*rect*/)
588 {
589  title_.set_location(xscale(12) + 8, yscale(38) + 8);
590  umenu_style.set_width(xscale(159));
596  chat_textbox_.set_location(xscale(11) + 4, yscale(573) + 4);
597  chat_textbox_.set_measurements(xscale(833) - 8, yscale(143) - 8);
598  entry_textbox_.set_location(xscale(11) + 4, yscale(732));
599  entry_textbox_.set_width(xscale(833) - 8);
600 }
601 
603 {
604  //FIXME: to cmpare names, use translation::compare from gettext.hpp
605  user_info const& a = *this;
606 
607  // ME always on top
608  if (a.relation == ME) {
609  return true;
610  }
611  if (b.relation == ME) {
612  return false;
613  }
614 
615  // friends next, sorted by location
616  if ((a.relation == FRIEND) && (b.relation == FRIEND)) {
617  if (a.state != b.state) {
618  return a.state < b.state;
619  }
620  return a.name < b.name;
621  }
622  if (a.relation == FRIEND) {
623  return true;
624  }
625  if (b.relation == FRIEND) {
626  return false;
627  }
628 
629  // players in the selected game next, sorted by relation (friends/neutral/ignored)
630  if ((a.state == SEL_GAME) && (b.state == SEL_GAME)) {
631  if (a.relation != b.relation) {
632  return a.relation < b.relation;
633  }
634  return a.name < b.name;
635  }
636  if (a.state == SEL_GAME) {
637  return true;
638  }
639  if (b.state == SEL_GAME) {
640  return false;
641  }
642 
643  // all others grouped by relation
644  if (a.relation != b.relation) {
645  return a.relation < b.relation;
646  }
647  if (a.state != b.state) {
648  return a.state < b.state;
649  }
650  return a.name < b.name;
651 }
652 
653 void ui::gamelist_updated(bool silent)
654 {
655  std::list<user_info> u_list;
656 
657  for (const config &user : gamelist_.child_range("user"))
658  {
659  user_info u_elem;
660  u_elem.name = user["name"].str();
661  u_elem.state = user["available"].to_bool(true) ? LOBBY : GAME;
662  u_elem.registered = user["registered"].to_bool();
663  u_elem.game_id = user["game_id"].str();
664  u_elem.location = user["location"].str();
665  if (!u_elem.game_id.empty() && u_elem.game_id == selected_game_) {
666  u_elem.state = SEL_GAME;
667  }
668  if (u_elem.name == preferences::login()) {
669  u_elem.relation = ME;
670  } else if (preferences::is_ignored(u_elem.name)) {
671  u_elem.relation = IGNORED;
672  } else if (preferences::is_friend(u_elem.name)) {
673  u_elem.relation = FRIEND;
674  } else {
675  u_elem.relation = NEUTRAL;
676  }
677  u_list.push_back(u_elem);
678  }
679 
680  if (preferences::sort_list()) {
681  u_list.sort(std::greater<user_info>());
682  }
683 
684  // can't use the bold tag here until the menu code
685  // calculates a correct ellipsis for it
686  const std::string lobby_color_tag = "";
687  const std::string ingame_color_tag = "#";
688  const std::string selgame_color_tag = "<0,191,255>";
689 
690  // for now I just disregard the above till I know something better,
691  // it works for me anyways
692  const std::string registered_user_tag = "~";
693 
694  std::string const imgpre = IMAGE_PREFIX + std::string("misc/status-");
695  std::vector<std::string> user_strings;
696  std::vector<std::string> menu_strings;
697 
698  std::list<user_info>::const_iterator u_itor = u_list.begin();
699  while (u_itor != u_list.end()) {
700  const std::string name_str = u_itor->name +
701  ((u_itor->state == LOBBY) ? "" : " (" + u_itor->location + ")");
702  std::string img_str = "";
703  std::string color_str = "";
704  std::string reg_str = "";
705  switch (u_itor->state) {
706  case LOBBY: color_str = lobby_color_tag; break;
707  case GAME: color_str = ingame_color_tag; break;
708  case SEL_GAME: color_str = selgame_color_tag; break;
709  }
711  switch (u_itor->relation) {
712  case NEUTRAL: img_str = imgpre + "neutral.png" + IMG_TEXT_SEPARATOR; break;
713  case IGNORED: img_str = imgpre + "ignore.png" + IMG_TEXT_SEPARATOR; break;
714  case FRIEND: img_str = imgpre + "friend.png" + IMG_TEXT_SEPARATOR; break;
715  case ME: img_str = imgpre + "self.png" + IMG_TEXT_SEPARATOR; break;
716  }
717  }
718  reg_str = u_itor->registered ? registered_user_tag : "";
719  user_strings.push_back(u_itor->name);
720  menu_strings.push_back(img_str + reg_str + color_str + name_str + HELP_STRING_SEPARATOR + name_str);
721  ++u_itor;
722  }
723 
724  set_user_list(user_strings, silent);
725  set_user_menu_items(menu_strings);
726 }
727 
728 void ui::set_selected_game(const std::string& game_id)
729 {
730  // reposition the player list to show the players in the selected game
731  if (preferences::sort_list() && (selected_game_ != game_id)) {
733  }
734  selected_game_ = game_id;
735 }
736 
737 void ui::set_user_menu_items(const std::vector<std::string>& list)
738 {
739  users_menu_.set_items(list,true,true);
740 
741  // Try to keep selected player
742  std::vector<std::string>::const_iterator i =
744  if(i != user_list_.end()) {
746  }
747 }
748 
749 void ui::set_user_list(const std::vector<std::string>& list, bool silent)
750 {
751  if(!silent) {
752  bool is_lobby = dynamic_cast<mp::lobby*>(this) != nullptr;
753 
754  if(list.size() < user_list_.size()) {
755  mp_ui_alerts::player_leaves(is_lobby);
756  } else if(list.size() > user_list_.size()) {
757  mp_ui_alerts::player_joins(is_lobby);
758  }
759  }
760 
761  user_list_ = list;
762 }
763 
765 {
766  const config &u = gamelist_.find_child("user", "name", selected_user_);
767  if (u) return u["game_id"];
768  return std::string();
769 }
770 
771 void ui::append_to_title(const std::string& text) {
772  title_.set_text(title_.get_text() + text);
773 }
774 
775 const gui::label& ui::title() const
776 {
777  return title_;
778 }
779 
781 {
782  return plugins_context_.get();
783 }
784 
785 void ui::send_to_server(const config& cfg)
786 {
787  if (wesnothd_connection_) {
789  }
790 }
791 
793 {
795 }
796 
797 }// namespace mp
An error occured during when trying to coommunicate with the wesnothd server.
surface get_image(const image::locator &i_locator, TYPE type)
function to get the surface corresponding to an image.
Definition: image.cpp:878
child_itors child_range(const std::string &key)
Definition: config.cpp:613
gui::textbox entry_textbox_
bool initialized_
Definition: font.cpp:609
char const IMG_TEXT_SEPARATOR
chat & chat_
void set_numeric_keypress_selection(bool value)
Definition: menu.cpp:761
virtual void handle_key_event(const SDL_KeyboardEvent &event)
virtual void draw_contents()
static std::string get_side_highlight(int side)
Definition: team.cpp:853
const SDL_Color TITLE_COLOR
Definition: font.cpp:573
std::vector< std::string > user_list_
int get_retval() const
Definition: dialog.hpp:161
std::map< std::string, color_range > team_rgb_range
const std::string & set_text(const std::string &text)
Definition: label.cpp:35
void set_edit_target(textbox *target)
Definition: textbox.cpp:719
virtual void init()
Definition: menu.hpp:81
static lg::log_domain log_network("network")
Graphical text output.
const GLfloat * c
Definition: glew.h:12741
static lg::log_domain log_config("config")
bool show(CVideo &video, const unsigned auto_close_time=0)
Shows the window.
Definition: dialog.cpp:34
boost::scoped_ptr< plugins_context > plugins_context_
ui(CVideo &v, twesnothd_connection *wesnothd_connection, const std::string &title, const config &cfg, chat &c, config &gamelist)
Definition: video.hpp:58
std::map< std::string, time_t > whisper_warnings_
const SDL_Rect empty_rect
Definition: rect.cpp:26
user_relation relation
virtual void layout_children(const SDL_Rect &rect)
Lays the children out.
result get_result()
Returns the result of the current widget.
#define LOG_NW
General purpose widgets.
void parse_admin_authentication(const std::string &sender, const std::string &message)
virtual SDL_Rect item_size(const std::string &item) const
Definition: menu_style.cpp:347
bool receive_data(config &result)
void set_width(int w)
Definition: widget.cpp:119
void set_text(const std::string &text, const SDL_Color &color=font::NORMAL_COLOR)
Definition: textbox.cpp:76
STL namespace.
std::string get_color_string(int id)
GLint GLint GLint GLint GLint GLint y
Definition: glew.h:1220
void add_message(const time_t &time, const std::string &user, const std::string &message)
surface scale_surface(const surface &surf, int w, int h)
Definition: utils.cpp:443
const std::string text() const
Definition: textbox.cpp:69
gui::label title_
-file sdl_utils.hpp
GLint GLenum GLsizei GLint GLsizei const GLvoid * data
Definition: glew.h:1347
std::string user
const SDL_Color NORMAL_COLOR
Definition: font.cpp:564
std::string format_message(const msg &message)
-file util.hpp
unsigned thickness_
The thickness of the line.
Definition: canvas.cpp:293
bool whisper_friends_only()
msg_hist::size_type last_update_
char const IMAGE_PREFIX
void init_textbox(gui::textbox &textbox)
virtual void process_network_data(const config &data)
Processes any pending network data.
virtual void hide_children(bool hide=true)
Hides or shows all gui::widget children of this widget.
void set_measurements(int w, int h)
Definition: widget.cpp:129
void send_data(const configr_of &request)
msg_hist message_history_
GLdouble GLdouble GLdouble b
Definition: glew.h:6966
This module controls the multiplayer lobby.
Uint32 lobby_clock_
void friend_message(bool is_lobby, const std::string &sender, const std::string &message)
std::string selected_user_
static UNUSEDNOWARN std::string _(const char *str)
Definition: gettext.hpp:82
GLuint GLuint end
Definition: glew.h:1221
std::map< std::string, t_string > string_map
bool is_friend(const std::string &nick)
A class that represents a TCP/IP connection to the wesnothd server.
result set_result(result res)
Sets the result of this dialog, to be checked by get_result().
void move_selection_keeping_viewport(size_t id)
Definition: menu.cpp:575
void set_wrap(bool val)
Definition: textbox.cpp:277
char const HELP_STRING_SEPARATOR
plugins_context * get_plugins_context()
int gety() const
Definition: video.cpp:481
static const int xscale_base
void private_message(bool is_lobby, const std::string &sender, const std::string &message)
const config & game_config() const
Returns the main game config, as defined by loading the preprocessed WML files.
const config & game_config_
The main game configuration, as defined by loading the preprocessed WML files.
std::string selected_game_
virtual void hide(bool value=true)
Definition: widget.cpp:162
void add_chat_message(const time_t &time, const std::string &speaker, int side, const std::string &message, events::chat_handler::MESSAGE_TYPE type=events::chat_handler::MESSAGE_PRIVATE)
Override chat_handler.
GLboolean GLboolean GLboolean GLboolean a
Definition: glew.h:7319
const gui::label & title() const
virtual void process_event()
config & add_child(const std::string &key)
Definition: config.cpp:743
static bool displaying()
Definition: loadscreen.hpp:49
void send_to_server(const config &cfg) override
int yscale(int y) const
void set_max_width(const int new_max_width)
Definition: menu.cpp:485
std::string message
static lg::log_domain log_mp("mp/main")
void apply_diff(const config &diff, bool track=false)
A function to apply a diff config onto this config object.
Definition: config.cpp:1252
bool initialized_
Set to true when the widgets are initialized.
void init()
Initializes the gui subsystems.
Definition: registry.cpp:482
void append_text(const std::string &text, bool auto_scroll=false, const SDL_Color &color=font::NORMAL_COLOR)
Definition: textbox.cpp:88
CVideo & video()
bool registered
True if this user is registered on the server.
void process_message(const config &msg, const bool whisper=false)
Process chat messages.
#define ERR_CF
int get_max_height(int size)
Definition: font.cpp:960
bool is_ignored(const std::string &nick)
const std::string & get_text() const
Definition: label.cpp:50
void append_to_title(const std::string &name)
std::string join(T const &v, const std::string &s=",")
Generates a new string joining container items in a list.
bool gamelist_refresh_
virtual void set_items(const std::vector< std::string > &items, bool strip_spaces=true, bool keep_viewport=false)
Set new items to show and redraw/recalculate everything.
Definition: menu.cpp:446
std::string::const_iterator parse_markup(std::string::const_iterator i1, std::string::const_iterator i2, int *font_size, SDL_Color *color, int *style)
Parses the markup-tags at the front of a string.
std::string login()
void move_selection(size_t id)
Definition: menu.cpp:567
gui::textbox chat_textbox_
gui::menu users_menu_
virtual void handle_event(const SDL_Event &event)
GLuint res
Definition: glew.h:9258
void send_chat_message(const std::string &message, bool allies_only=false)
void clear_history()
std::map< std::string, tfilter >::iterator itor
Definition: filter.cpp:199
SDL_Rect client_area() const
void update_textbox(gui::textbox &textbox)
int getx() const
Definition: video.cpp:472
SDL_Color color_message(const msg &message)
config & gamelist_
#define VGETTEXT(msgid, symbols)
const SDL_Color LABEL_COLOR
Definition: font.cpp:574
void public_message(bool is_lobby, const std::string &sender, const std::string &message)
void set_user_list(const std::vector< std::string > &, bool silent)
Sets the user list.
const std::string & time() const
void clear()
Definition: textbox.cpp:127
size_t i
Definition: function.cpp:1057
static void msg(const char *act, debug_info &i, const char *to="", const char *result="")
Definition: debugger.cpp:112
GLint GLint GLint GLint GLint x
Definition: glew.h:1220
void server_message(bool is_lobby, const std::string &sender, const std::string &message)
GLdouble GLdouble GLdouble r
Definition: glew.h:1374
bool gamelist_initialized_
int font_size_
Definition: font.cpp:604
bool double_clicked()
Definition: menu.cpp:749
virtual void hide(bool value=true)
Definition: scrollarea.cpp:78
-file mapgen.hpp
int xscale(int x) const
GLuint const GLchar * name
Definition: glew.h:1782
const int SIZE_LARGE
Definition: font.hpp:66
void player_leaves(bool is_lobby)
SDL_Rect create_rect(const int x, const int y, const int w, const int h)
Creates an empty SDL_Rect.
Definition: rect.cpp:28
void set_user_menu_items(const std::vector< std::string > &list)
result result_
Contains the SDL_Rect helper code.
const GLdouble * m
Definition: glew.h:6968
bool selected_user_changed_
bool find(E event, F functor)
Tests whether an event handler is available.
cl_event event
Definition: glew.h:3070
void set_selected_game(const std::string &game_name)
Sets the name of the selected game which is used to highlight the names of the players which have joi...
std::string get_chat_timestamp(const time_t &t)
config & child(const std::string &key, int n=0)
Returns the nth child with the given key, or a reference to an invalid config if there is none...
Definition: config.cpp:658
void process_network()
Asks the multiplayer_ui to pump some data from the network, and then to process it.
void player_joins(bool is_lobby)
unsigned lobby_refresh
Definition: game_config.cpp:46
config & find_child(const std::string &key, const std::string &name, const std::string &value)
Returns the first child of tag key with a name attribute containing value.
Definition: config.cpp:1010
Standard logging facilities (interface).
const std::string & message() const
std::string message
Definition: exceptions.hpp:29
void clear_all_help_strings()
Definition: video.cpp:664
void set_location(const SDL_Rect &rect)
Hides children, moves them (using layout_children), then shows them.
twesnothd_connection * wesnothd_connection_
GLsizei GLenum GLuint GLuint GLsizei char * message
Definition: glew.h:2499
#define c
Definition: glew.h:12743
virtual void set_location(SDL_Rect const &rect)
Definition: widget.cpp:85
bool parse_should_show_lobby_join(const std::string &sender, const std::string &message)
std::string rgb2highlight(Uint32 rgb)
Converts a color value to WML text markup syntax for highlighting.
const std::string remove
remove directive
GLint GLint GLint GLint GLint GLint GLsizei width
Definition: glew.h:1220
#define e
virtual void handle_event(SDL_Event const &)
Definition: widget.cpp:345
this class memorizes a chat session.
int width() const
Definition: widget.cpp:134
static const int yscale_base
void sdl_blit(const surface &src, SDL_Rect *src_rect, surface &dst, SDL_Rect *dst_rect)
Definition: utils.hpp:112
std::string get_selected_user_game()
std::string::const_iterator iterator
Definition: tokenizer.hpp:21
A config object defines a single node in a WML file, with access to child nodes.
Definition: config.hpp:83
void notify_event(const std::string &name, const config &data)
Definition: manager.cpp:147
bool receive_from_server(config &dst)
void set_height(int h)
Definition: widget.cpp:124
std::map< std::string, t_string > team_rgb_name
bool operator>(const user_info &b) const
friend class imgsel_style
Definition: menu.hpp:115
GLsizei const GLcharARB ** string
Definition: glew.h:4503
void set_max_height(const int new_max_height)
Set a new max height for this menu.
Definition: menu.cpp:477
bool word_completion(std::string &text, std::vector< std::string > &wordlist)
Try to complete the last word of 'text' with the 'wordlist'.
int selection() const
Definition: menu.cpp:369
const std::string & reason() const
static plugins_manager * get()
Definition: manager.cpp:61
virtual void gamelist_updated(bool silent=true)
Called each time the gamelist_ variable is updated.
int height() const
Definition: widget.cpp:139
bool word_match(const std::string &message, const std::string &word)
Check if a message contains a word.