new lobby: Treat the game id as an int that it is,
...add status icons to player list (icons from patch/bug #11726 by megane), add server support for differentiating between players playing and observing a game.
BIN
data/core/images/lobby/status-idle-f.png
Normal file
After Width: | Height: | Size: 323 B |
BIN
data/core/images/lobby/status-idle-i.png
Normal file
After Width: | Height: | Size: 326 B |
BIN
data/core/images/lobby/status-idle-n.png
Normal file
After Width: | Height: | Size: 247 B |
BIN
data/core/images/lobby/status-idle-s.png
Normal file
After Width: | Height: | Size: 256 B |
BIN
data/core/images/lobby/status-lobby-f.png
Normal file
After Width: | Height: | Size: 328 B |
BIN
data/core/images/lobby/status-lobby-i.png
Normal file
After Width: | Height: | Size: 336 B |
BIN
data/core/images/lobby/status-lobby-n.png
Normal file
After Width: | Height: | Size: 247 B |
BIN
data/core/images/lobby/status-lobby-s.png
Normal file
After Width: | Height: | Size: 249 B |
BIN
data/core/images/lobby/status-obs-f.png
Normal file
After Width: | Height: | Size: 265 B |
BIN
data/core/images/lobby/status-obs-i.png
Normal file
After Width: | Height: | Size: 268 B |
BIN
data/core/images/lobby/status-obs-n.png
Normal file
After Width: | Height: | Size: 200 B |
BIN
data/core/images/lobby/status-playing-f.png
Normal file
After Width: | Height: | Size: 297 B |
BIN
data/core/images/lobby/status-playing-i.png
Normal file
After Width: | Height: | Size: 299 B |
BIN
data/core/images/lobby/status-playing-n.png
Normal file
After Width: | Height: | Size: 217 B |
|
@ -203,11 +203,20 @@
|
|||
definition = "default"
|
||||
[grid]
|
||||
[row]
|
||||
[column]
|
||||
border = "all"
|
||||
border_size = 1
|
||||
[image]
|
||||
id = "main_icon"
|
||||
definition = "default"
|
||||
label = ""
|
||||
[/image]
|
||||
[/column]
|
||||
[column]
|
||||
grow_factor = 1
|
||||
horizontal_grow = "true"
|
||||
border = "all"
|
||||
border_size = 5
|
||||
border = "top,right,bottom"
|
||||
border_size = 3
|
||||
[label]
|
||||
id = "player"
|
||||
definition = "default"
|
||||
|
|
|
@ -194,7 +194,7 @@ tlobby_main::tlobby_main(const config& game_config, lobby_info& info)
|
|||
, gamelistbox_(NULL), chat_log_container_(NULL)
|
||||
, chat_input_(NULL), window_(NULL)
|
||||
, lobby_info_(info), preferences_callback_(NULL)
|
||||
, open_windows_(), active_window_(0)
|
||||
, open_windows_(), active_window_(0), selected_game_id_()
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -230,6 +230,11 @@ void set_visible_if_exists(tgrid* grid, const char* id, bool visible)
|
|||
}
|
||||
}
|
||||
|
||||
std::string colorize(const std::string& str, const std::string& color)
|
||||
{
|
||||
return "<span color=\"" + color +"\">" + str + "</span>";
|
||||
}
|
||||
|
||||
} //end anonymous namespace
|
||||
|
||||
void tlobby_main::update_gamelist()
|
||||
|
@ -309,11 +314,50 @@ void tlobby_main::update_gamelist()
|
|||
}
|
||||
}
|
||||
update_selected_game();
|
||||
|
||||
lobby_info_.update_user_statuses(selected_game_id_, active_window_room());
|
||||
userlistbox_->clear();
|
||||
foreach (const user_info& user, lobby_info_.users())
|
||||
{
|
||||
std::map<std::string, string_map> data;
|
||||
add_label_data(data, "player", user.name);
|
||||
std::stringstream icon_ss;
|
||||
std::string name = user.name;
|
||||
icon_ss << "lobby/status";
|
||||
switch (user.state) {
|
||||
case user_info::SEL_ROOM:
|
||||
/* fall through */
|
||||
case user_info::LOBBY:
|
||||
icon_ss << "-lobby";
|
||||
break;
|
||||
case user_info::SEL_GAME:
|
||||
name = colorize(name, "cyan");
|
||||
icon_ss << (user.observing ? "-obs" : "-playing");
|
||||
break;
|
||||
case user_info::GAME:
|
||||
name = colorize(name, "red");
|
||||
icon_ss << (user.observing ? "-obs" : "-playing"); break;
|
||||
default:
|
||||
ERR_NG << "Bad user state in lobby: " << user.state << "\n";
|
||||
}
|
||||
switch (user.relation) {
|
||||
case user_info::ME:
|
||||
/* fall through */
|
||||
case user_info::NEUTRAL:
|
||||
icon_ss << "-n";
|
||||
break;
|
||||
case user_info::FRIEND:
|
||||
icon_ss << "-f";
|
||||
break;
|
||||
case user_info::IGNORED:
|
||||
icon_ss << "-i";
|
||||
break;
|
||||
default:
|
||||
ERR_NG << "Bad user relation in lobby: " << user.relation << "\n";
|
||||
}
|
||||
icon_ss << ".png";
|
||||
add_label_data(data, "player", name);
|
||||
add_label_data(data, "main_icon", icon_ss.str());
|
||||
|
||||
userlistbox_->add_row(data);
|
||||
}
|
||||
window_->invalidate_layout();
|
||||
|
@ -327,6 +371,9 @@ void tlobby_main::update_selected_game()
|
|||
const game_info& game = *lobby_info_.games_filtered()[idx];
|
||||
can_observe = game.can_observe();
|
||||
can_join = game.can_join();
|
||||
selected_game_id_ = game.id;
|
||||
} else {
|
||||
selected_game_id_ = 0;
|
||||
}
|
||||
window_->get_widget<tbutton>("observe_global", false).set_active(can_observe);
|
||||
window_->get_widget<tbutton>("join_global", false).set_active(can_join);
|
||||
|
@ -392,6 +439,12 @@ void tlobby_main::post_show(twindow& /*window*/)
|
|||
window_ = NULL;
|
||||
}
|
||||
|
||||
room_info* tlobby_main::active_window_room()
|
||||
{
|
||||
const tlobby_chat_window& t = open_windows_[active_window_];
|
||||
if (t.whisper) return NULL;
|
||||
return lobby_info_.get_room(t.name);
|
||||
}
|
||||
|
||||
tlobby_chat_window* tlobby_main::room_window_open(const std::string& room, bool open_new)
|
||||
{
|
||||
|
@ -735,7 +788,7 @@ bool tlobby_main::do_game_join(int idx, bool observe)
|
|||
}
|
||||
config response;
|
||||
config& join = response.add_child("join");
|
||||
join["id"] = game.id;
|
||||
join["id"] = lexical_cast<std::string>(game.id);
|
||||
join["observe"] = observe ? "yes" : "no";
|
||||
if (join && game.password_required) {
|
||||
std::string password;
|
||||
|
|
|
@ -115,6 +115,12 @@ private:
|
|||
*/
|
||||
legacy_result legacy_result_;
|
||||
|
||||
/**
|
||||
* Get the room* corresponding to the currently active window, or NULL
|
||||
* if a whisper window is active at the moment
|
||||
*/
|
||||
room_info* active_window_room();
|
||||
|
||||
/**
|
||||
* Check if a room window for "room" is open, if open_new is true
|
||||
* then it will be created if not found.
|
||||
|
@ -300,6 +306,8 @@ private:
|
|||
ttoggle_button* filter_invert_;
|
||||
|
||||
ttext_box* filter_text_;
|
||||
|
||||
int selected_game_id_;
|
||||
};
|
||||
|
||||
} // namespace gui2
|
||||
|
|
|
@ -96,15 +96,17 @@ user_info::user_info()
|
|||
, relation(ME)
|
||||
, state(LOBBY)
|
||||
, registered()
|
||||
, observing()
|
||||
{
|
||||
}
|
||||
|
||||
user_info::user_info(const config& c)
|
||||
: name(c["name"])
|
||||
, game_id(c["game_id"])
|
||||
, game_id(lexical_cast_default<int>(c["game_id"]))
|
||||
, relation(ME)
|
||||
, state(c["available"] == "no" ? GAME : LOBBY)
|
||||
, state(game_id == 0 ? LOBBY : GAME)
|
||||
, registered(utils::string_bool(c["registered"]))
|
||||
, observing(c["status"] == "observing")
|
||||
{
|
||||
if (name == preferences::login()) {
|
||||
relation = ME;
|
||||
|
@ -117,12 +119,20 @@ user_info::user_info(const config& c)
|
|||
}
|
||||
}
|
||||
|
||||
void user_info::update_state(const std::string& selected_game_id, const room_info* current_room /*= NULL*/)
|
||||
void user_info::update_state(int selected_game_id, const room_info* current_room /*= NULL*/)
|
||||
{
|
||||
if (!game_id.empty() && game_id == selected_game_id) {
|
||||
state = SEL_GAME;
|
||||
} else if (state == LOBBY && current_room != NULL && current_room->is_member(name)) {
|
||||
state = SEL_ROOM;
|
||||
if (game_id != 0) {
|
||||
if (game_id == selected_game_id) {
|
||||
state = SEL_GAME;
|
||||
} else {
|
||||
state = GAME;
|
||||
}
|
||||
} else if (state == LOBBY) {
|
||||
if (current_room != NULL && current_room->is_member(name)) {
|
||||
state = SEL_ROOM;
|
||||
} else {
|
||||
state = LOBBY;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -178,7 +188,7 @@ std::string make_short_name(const std::string long_name)
|
|||
|
||||
game_info::game_info(const config& game, const config& game_config)
|
||||
: mini_map()
|
||||
, id(game["id"])
|
||||
, id(lexical_cast_default<int>(game["id"]))
|
||||
, map_data(game["map_data"])
|
||||
, name(game["name"])
|
||||
, scenario()
|
||||
|
@ -456,8 +466,8 @@ void lobby_info::parse_gamelist()
|
|||
games_by_id_.insert(std::make_pair(gi.id, &gi));
|
||||
}
|
||||
foreach (user_info& ui, users_) {
|
||||
if (!ui.game_id.empty()) {
|
||||
std::map<std::string, game_info*>::iterator i = games_by_id_.find(ui.game_id);
|
||||
if (ui.game_id != 0) {
|
||||
std::map<int, game_info*>::iterator i = games_by_id_.find(ui.game_id);
|
||||
if (i == games_by_id_.end()) {
|
||||
WRN_NG << "User " << ui.name << " has unknown game_id: " << ui.game_id << "\n";
|
||||
} else {
|
||||
|
@ -551,3 +561,10 @@ void lobby_info::apply_game_filter()
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
void lobby_info::update_user_statuses(int game_id, const room_info *room)
|
||||
{
|
||||
foreach (user_info& user, users_) {
|
||||
user.update_state(game_id, room);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -88,7 +88,7 @@ struct user_info
|
|||
user_info();
|
||||
user_info(const config& c);
|
||||
|
||||
void update_state(const std::string& selected_game_id, const room_info* current_room = NULL);
|
||||
void update_state(int selected_game_id, const room_info* current_room = NULL);
|
||||
|
||||
enum user_relation { ME, FRIEND, NEUTRAL, IGNORED };
|
||||
enum user_state { LOBBY, SEL_ROOM, GAME, SEL_GAME };
|
||||
|
@ -96,10 +96,11 @@ struct user_info
|
|||
bool operator> (const user_info& b) const;
|
||||
|
||||
std::string name;
|
||||
std::string game_id;
|
||||
int game_id;
|
||||
user_relation relation;
|
||||
user_state state;
|
||||
bool registered;
|
||||
bool observing;
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -114,7 +115,7 @@ struct game_info
|
|||
bool can_observe() const;
|
||||
|
||||
surface mini_map;
|
||||
std::string id;
|
||||
int id;
|
||||
std::string map_data;
|
||||
std::string name;
|
||||
std::string scenario;
|
||||
|
@ -269,6 +270,8 @@ public:
|
|||
|
||||
chat_log& get_whisper_log(const std::string& name);
|
||||
|
||||
void update_user_statuses(int game_id, const room_info* room);
|
||||
|
||||
const std::vector<room_info>& rooms() const { return rooms_; }
|
||||
const std::vector<game_info>& games() const { return games_; }
|
||||
const std::vector<game_info*>& games_filtered();
|
||||
|
@ -281,7 +284,7 @@ private:
|
|||
bool gamelist_initialized_;
|
||||
std::vector<room_info> rooms_;
|
||||
std::vector<game_info> games_;
|
||||
std::map<std::string, game_info*> games_by_id_;
|
||||
std::map<int, game_info*> games_by_id_;
|
||||
std::vector<game_info*> games_filtered_;
|
||||
std::vector<user_info> users_;
|
||||
std::map<std::string, chat_log> whispers_;
|
||||
|
|
|
@ -74,7 +74,7 @@ game::game(player_map& players, const network::connection host,
|
|||
}
|
||||
// Mark the host as unavailable in the lobby.
|
||||
pl->second.mark_available(id_, name_);
|
||||
p1->second.set_status(player::PLAYING);
|
||||
pl->second.set_status(player::PLAYING);
|
||||
}
|
||||
|
||||
game::~game()
|
||||
|
@ -277,7 +277,7 @@ void game::update_side_data() {
|
|||
// * Find the username.
|
||||
// * Find the side this username corresponds to.
|
||||
for (user_vector::const_iterator user = users.begin(); user != users.end(); ++user) {
|
||||
const player_map::const_iterator info = player_info_->find(*user);
|
||||
player_map::iterator info = player_info_->find(*user);
|
||||
if (info == player_info_->end()) {
|
||||
ERR_GAME << "Game: " << id_
|
||||
<< " ERROR: unable to find user info for connection: "
|
||||
|
@ -343,7 +343,7 @@ void game::transfer_side_control(const network::connection sock, const simple_wm
|
|||
|
||||
const simple_wml::string_span& newplayer_name = cfg["player"];
|
||||
const network::connection old_player = sides_[side_num - 1];
|
||||
const player_map::const_iterator oldplayer = player_info_->find(old_player);
|
||||
const player_map::iterator oldplayer = player_info_->find(old_player);
|
||||
if (oldplayer == player_info_->end()) {
|
||||
WRN_GAME << "Could not find old player in player_info_. (socket: "
|
||||
<< old_player << ")\n";
|
||||
|
@ -380,7 +380,7 @@ void game::transfer_side_control(const network::connection sock, const simple_wm
|
|||
return;
|
||||
}
|
||||
//find the player that is passed control
|
||||
player_map::const_iterator newplayer;
|
||||
player_map::iterator newplayer;
|
||||
for (newplayer = player_info_->begin(); newplayer != player_info_->end(); newplayer++) {
|
||||
if (newplayer_name == newplayer->second.name().c_str()) {
|
||||
break;
|
||||
|
@ -1044,7 +1044,7 @@ bool game::remove_player(const network::connection player, const bool disconnect
|
|||
if (*side != player) continue;
|
||||
if (side_controllers_[side_num] == "ai") ai_transfer = true;
|
||||
|
||||
player_map::const_iterator o = player_info_->find(owner_);
|
||||
player_map::iterator o = player_info_->find(owner_);
|
||||
const std::string owner_name = (o != player_info_->end() ? o->second.name() : "(unknown)");
|
||||
change_controller(side_num, owner_, owner_name);
|
||||
// Check whether the host is actually a player and make him one if not.
|
||||
|
|