Some cleanup to GUI2 MP Lobby auxiliary code

This commit is contained in:
Charles Dang 2016-08-28 17:00:55 +11:00
parent e8ca1439be
commit cfed64dd4f
2 changed files with 126 additions and 197 deletions

View file

@ -176,8 +176,7 @@ game_info::game_info(const config& game, const config& game_config)
, vision()
, status()
, time_limit()
, vacant_slots(lexical_cast_default<int>(game["slots"],
0)) // Can't use to_int() here.
, vacant_slots(lexical_cast_default<int>(game["slots"], 0)) // Can't use to_int() here.
, current_turn(0)
, reloaded(game["savegame"].to_bool())
, started(false)
@ -197,8 +196,7 @@ game_info::game_info(const config& game, const config& game_config)
{
std::string turn = game["turn"];
if(!game["mp_era"].empty()) {
const config& era_cfg
= game_config.find_child("era", "id", game["mp_era"]);
const config& era_cfg = game_config.find_child("era", "id", game["mp_era"]);
utils::string_map symbols;
symbols["era_id"] = game["mp_era"];
if(era_cfg) {
@ -222,10 +220,9 @@ game_info::game_info(const config& game, const config& game_config)
if(!game.child_or_empty("modification").empty()) {
for(const config &cfg : game.child_range("modification")) {
if (cfg["require_modification"].to_bool(false)) {
const config &mod = game_config.find_child("modification", "id",
cfg["id"]);
if (!mod) {
if(cfg["require_modification"].to_bool(false)) {
const config &mod = game_config.find_child("modification", "id", cfg["id"]);
if(!mod) {
have_all_mods = false;
break;
}
@ -240,8 +237,7 @@ game_info::game_info(const config& game, const config& game_config)
if(map_data.empty()) {
map_info += " — ??×??";
} else {
try
{
try {
gamemap map(std::make_shared<terrain_type_data>(game_config), map_data);
// mini_map = image::getMinimap(minimap_size_, minimap_size_, map,
// 0);
@ -249,48 +245,38 @@ game_info::game_info(const config& game, const config& game_config)
msi << map.w() << utils::unicode_multiplication_sign << map.h();
map_size_info = msi.str();
map_info += "" + map_size_info;
}
catch(incorrect_map_format_error& e)
{
} catch(incorrect_map_format_error& e) {
ERR_CF << "illegal map: " << e.message << std::endl;
verified = false;
}
catch(twml_exception& e)
{
} catch(twml_exception& e) {
ERR_CF << "map could not be loaded: " << e.dev_message << '\n';
verified = false;
}
}
map_info += " ";
if(!game["mp_scenario"].empty()) {
// check if it's a multiplayer scenario
const config* level_cfg = &game_config.find_child("multiplayer",
"id",
game["mp_scenario"]);
// Check if it's a multiplayer scenario
const config* level_cfg = &game_config.find_child("multiplayer", "id", game["mp_scenario"]);
if(!*level_cfg) {
// check if it's a user map
level_cfg = &game_config.find_child("generic_multiplayer",
"id",
game["mp_scenario"]);
// Check if it's a user map
level_cfg = &game_config.find_child("generic_multiplayer", "id", game["mp_scenario"]);
}
if(*level_cfg) {
scenario = (*level_cfg)["name"].str();
map_info += scenario;
// reloaded games do not match the original scenario hash,
// so it makes no sense to test them, they always would appear
// as remote scenarios
// Reloaded games do not match the original scenario hash, so it makes no sense
// to test them, since they always would appear as remote scenarios
if(!reloaded) {
if(const config& hashes
= game_config.child("multiplayer_hashes")) {
if(const config& hashes = game_config.child("multiplayer_hashes")) {
std::string hash = game["hash"];
bool hash_found = false;
for(const auto & i : hashes.attribute_range())
{
for(const auto & i : hashes.attribute_range()) {
if(i.first == game["mp_scenario"] && i.second == hash) {
hash_found = true;
break;
}
}
if(!hash_found) {
remote_scenario = true;
map_info += "";
@ -311,6 +297,7 @@ game_info::game_info(const config& game, const config& game_config)
map_info += scenario;
verified = false;
}
if(reloaded) {
map_info += "";
map_info += _("Reloaded game");
@ -328,9 +315,7 @@ game_info::game_info(const config& game, const config& game_config)
} else {
started = false;
if(vacant_slots > 0) {
status = std::string(
_n("Vacant Slot:", "Vacant Slots:", vacant_slots))
+ " " + game["slots"];
status = std::string(_n("Vacant Slot:", "Vacant Slots:", vacant_slots)) + " " + game["slots"];
}
}
@ -345,6 +330,7 @@ game_info::game_info(const config& game, const config& game_config)
} else {
vision = _("none");
}
if(game["mp_countdown"].to_bool()) {
time_limit = game["mp_countdown_init_time"].str() + "+"
+ game["mp_countdown_turn_bonus"].str() + "/"
@ -361,8 +347,7 @@ bool game_info::can_join() const
bool game_info::can_observe() const
{
return (have_era && have_all_mods && observers)
|| preferences::is_authenticated();
return (have_era && have_all_mods && observers) || preferences::is_authenticated();
}
const char* game_info::display_status_string() const
@ -377,8 +362,7 @@ const char* game_info::display_status_string() const
case game_info::UPDATED:
return "updated";
default:
ERR_CF << "BAD display_status " << display_status << " in game "
<< id << "\n";
ERR_CF << "BAD display_status " << display_status << " in game " << id << "\n";
return "?";
}
}
@ -389,8 +373,7 @@ game_filter_stack::game_filter_stack() : filters_()
game_filter_stack::~game_filter_stack()
{
for(auto f : filters_)
{
for(auto f : filters_) {
delete f;
}
}
@ -402,20 +385,21 @@ void game_filter_stack::append(game_filter_base* f)
void game_filter_stack::clear()
{
for(auto f : filters_)
{
for(auto f : filters_) {
delete f;
}
filters_.clear();
}
bool game_filter_and_stack::match(const game_info& game) const
{
for(auto f : filters_)
{
if(!f->match(game))
for(auto f : filters_) {
if(!f->match(game)) {
return false;
}
}
return true;
}
@ -423,14 +407,8 @@ bool game_filter_general_string_part::match(const game_info& game) const
{
const std::string& s1 = game.map_info;
const std::string& s2 = game.name;
return std::search(s1.begin(),
s1.end(),
value_.begin(),
value_.end(),
chars_equal_insensitive) != s1.end()
|| std::search(s2.begin(),
s2.end(),
value_.begin(),
value_.end(),
chars_equal_insensitive) != s2.end();
return std::search(s1.begin(), s1.end(), value_.begin(), value_.end(),
chars_equal_insensitive) != s1.end()
|| std::search(s2.begin(), s2.end(), value_.begin(), value_.end(),
chars_equal_insensitive) != s2.end();
}

View file

@ -25,14 +25,11 @@
#include "wesnothd_connection.hpp"
#include <iterator>
static lg::log_domain log_config("config");
#define ERR_CF LOG_STREAM(err, log_config)
static lg::log_domain log_engine("engine");
#define WRN_NG LOG_STREAM(warn, log_engine)
static lg::log_domain log_lobby("lobby");
#define DBG_LB LOG_STREAM(debug, log_lobby)
#define LOG_LB LOG_STREAM(info, log_lobby)
#define WRN_LB LOG_STREAM(warn, log_lobby)
#define ERR_LB LOG_STREAM(err, log_lobby)
#define SCOPE_LB log_scope2(log_lobby, __func__)
@ -63,8 +60,7 @@ lobby_info::~lobby_info()
void lobby_info::delete_games()
{
for(const auto & v : games_by_id_)
{
for(const auto & v : games_by_id_) {
delete v.second;
}
}
@ -75,8 +71,7 @@ namespace
std::string dump_games_map(const lobby_info::game_info_map& games)
{
std::stringstream ss;
for(const auto & v : games)
{
for(const auto & v : games) {
const game_info& game = *v.second;
ss << "G" << game.id << "(" << game.name << ") "
<< game.display_status_string() << " ";
@ -88,8 +83,7 @@ std::string dump_games_map(const lobby_info::game_info_map& games)
std::string dump_games_config(const config& gamelist)
{
std::stringstream ss;
for(const auto & c : gamelist.child_range("game"))
{
for(const auto & c : gamelist.child_range("game")) {
ss << "g" << c["id"] << "(" << c["name"] << ") "
<< c[config::diff_track_attribute] << " ";
}
@ -106,86 +100,88 @@ void lobby_info::process_gamelist(const config& data)
gamelist_initialized_ = true;
delete_games();
games_by_id_.clear();
for(const auto & c : gamelist_.child("gamelist").child_range("game"))
{
for(const auto & c : gamelist_.child("gamelist").child_range("game")) {
game_info* game = new game_info(c, game_config_);
games_by_id_[game->id] = game;
}
DBG_LB << dump_games_map(games_by_id_);
DBG_LB << dump_games_config(gamelist_.child("gamelist"));
process_userlist();
}
bool lobby_info::process_gamelist_diff(const config& data)
{
SCOPE_LB;
if(!gamelist_initialized_)
if(!gamelist_initialized_) {
return false;
DBG_LB << "prediff " << dump_games_config(gamelist_.child("gamelist"));
try
{
gamelist_.apply_diff(data, true);
}
catch(config::error& e)
{
DBG_LB << "prediff " << dump_games_config(gamelist_.child("gamelist"));
try {
gamelist_.apply_diff(data, true);
} catch(config::error& e) {
ERR_LB << "Error while applying the gamelist diff: '" << e.message
<< "' Getting a new gamelist.\n";
<< "' Getting a new gamelist.\n";
wesnothd_connection_.send_data(config("refresh_lobby"));
return false;
}
DBG_LB << "postdiff " << dump_games_config(gamelist_.child("gamelist"));
DBG_LB << dump_games_map(games_by_id_);
for(config& c : gamelist_.child("gamelist").child_range("game")) {
DBG_LB << "data process: " << c["id"] << " ("
<< c[config::diff_track_attribute] << ")\n";
int game_id = c["id"];
DBG_LB << "data process: " << c["id"] << " (" << c[config::diff_track_attribute] << ")\n";
const int game_id = c["id"];
if(game_id == 0) {
ERR_LB << "game with id 0 in gamelist config" << std::endl;
wesnothd_connection_.send_data(config("refresh_lobby"));
return false;
}
game_info_map::iterator current_i = games_by_id_.find(game_id);
const std::string& diff_result = c[config::diff_track_attribute];
if(diff_result == "new" || diff_result == "modified") {
if(current_i == games_by_id_.end()) {
games_by_id_.insert(std::make_pair(
game_id, new game_info(c, game_config_)));
} else {
// had a game with that id, so update it and mark it as such
*(current_i->second) = game_info(c, game_config_);
current_i->second->display_status = game_info::UPDATED;
games_by_id_.insert({game_id, new game_info(c, game_config_)});
continue;
}
// Had a game with that id, so update it and mark it as such
*(current_i->second) = game_info(c, game_config_);
current_i->second->display_status = game_info::UPDATED;
} else if(diff_result == "deleted") {
if(current_i == games_by_id_.end()) {
WRN_LB << "Would have to delete a game that I don't have: "
<< game_id << "\n";
WRN_LB << "Would have to delete a game that I don't have: " << game_id << "\n";
continue;
}
if(current_i->second->display_status == game_info::NEW) {
// This means the game never made it through to the user interface,
// so just deleting it is fine
games_by_id_.erase(current_i);
} else {
if(current_i->second->display_status == game_info::NEW) {
// this means the game never made it through to the user
// interface
// so just deleting it is fine
games_by_id_.erase(current_i);
} else {
current_i->second->display_status = game_info::DELETED;
}
current_i->second->display_status = game_info::DELETED;
}
}
}
DBG_LB << dump_games_map(games_by_id_);
try
{
try {
gamelist_.clear_diff_track(data);
}
catch(config::error& e)
{
} catch(config::error& e) {
ERR_LB << "Error while applying the gamelist diff (2): '" << e.message
<< "' Getting a new gamelist.\n";
wesnothd_connection_.send_data(config("refresh_lobby"));
return false;
}
DBG_LB << "postclean " << dump_games_config(gamelist_.child("gamelist"));
process_userlist();
return true;
}
@ -193,29 +189,30 @@ void lobby_info::process_userlist()
{
SCOPE_LB;
users_.clear();
for(const auto & c : gamelist_.child_range("user"))
{
for(const auto & c : gamelist_.child_range("user")) {
users_.push_back(user_info(c));
}
for(auto & ui : users_)
{
if(ui.game_id != 0) {
game_info* g = get_game_by_id(ui.game_id);
if(g == nullptr) {
WRN_NG << "User " << ui.name
<< " has unknown game_id: " << ui.game_id << "\n";
} else {
switch(ui.relation) {
case user_info::FRIEND:
g->has_friends = true;
break;
case user_info::IGNORED:
g->has_ignored = true;
break;
default:
break;
}
}
for(auto & ui : users_) {
if(ui.game_id == 0) {
continue;
}
game_info* g = get_game_by_id(ui.game_id);
if(!g) {
WRN_NG << "User " << ui.name << " has unknown game_id: " << ui.game_id << "\n";
continue;
}
switch(ui.relation) {
case user_info::FRIEND:
g->has_friends = true;
break;
case user_info::IGNORED:
g->has_ignored = true;
break;
default:
break;
}
}
}
@ -224,48 +221,49 @@ void lobby_info::sync_games_display_status()
{
DBG_LB << "lobby_info::sync_games_display_status";
DBG_LB << "games_by_id_ size: " << games_by_id_.size();
game_info_map::iterator i = games_by_id_.begin();
while(i != games_by_id_.end()) {
if(i->second->display_status == game_info::DELETED) {
games_by_id_.erase(i++);
for(auto& game : games_by_id_) {
if(game.second->display_status == game_info::DELETED) {
games_by_id_.erase(game.first);
} else {
i->second->display_status = game_info::CLEAN;
++i;
game.second->display_status = game_info::CLEAN;
}
}
DBG_LB << " -> " << games_by_id_.size() << "\n";
make_games_vector();
}
game_info* lobby_info::get_game_by_id(int id)
{
std::map<int, game_info*>::iterator i = games_by_id_.find(id);
game_info_map::iterator i = games_by_id_.find(id);
return i == games_by_id_.end() ? nullptr : i->second;
}
const game_info* lobby_info::get_game_by_id(int id) const
{
std::map<int, game_info*>::const_iterator i = games_by_id_.find(id);
game_info_map::const_iterator i = games_by_id_.find(id);
return i == games_by_id_.end() ? nullptr : i->second;
}
room_info* lobby_info::get_room(const std::string& name)
{
for(auto & r : rooms_)
{
for(auto & r : rooms_) {
if(r.name() == name)
return &r;
}
return nullptr;
}
const room_info* lobby_info::get_room(const std::string& name) const
{
for(const auto & r : rooms_)
{
if(r.name() == name)
for(const auto & r : rooms_) {
if(r.name() == name) {
return &r;
}
}
return nullptr;
}
@ -288,10 +286,8 @@ void lobby_info::open_room(const std::string& name)
void lobby_info::close_room(const std::string& name)
{
room_info* r = get_room(name);
DBG_LB << "lobby info: closing room " << name << " "
<< static_cast<void*>(r) << "\n";
if(r) {
DBG_LB << "lobby info: closing room " << name << "\n";
if(room_info* r = get_room(name)) {
rooms_.erase(rooms_.begin() + (r - &rooms_[0]));
}
}
@ -321,8 +317,8 @@ void lobby_info::make_games_vector()
games_filtered_.clear();
games_visibility_.clear();
games_.clear();
for(const auto & v : games_by_id_)
{
for(const auto & v : games_by_id_) {
games_.push_back(v.second);
}
}
@ -331,13 +327,14 @@ void lobby_info::apply_game_filter()
{
games_filtered_.clear();
games_visibility_.clear();
for(auto g : games_)
{
for(auto g : games_) {
game_info& gi = *g;
bool show = game_filter_.match(gi);
if(game_filter_invert_) {
show = !show;
}
games_visibility_.push_back(show);
if(show) {
games_filtered_.push_back(&gi);
@ -347,72 +344,26 @@ void lobby_info::apply_game_filter()
void lobby_info::update_user_statuses(int game_id, const room_info* room)
{
for(auto & user : users_)
{
for(auto & user : users_) {
user.update_state(game_id, room);
}
}
struct user_sorter_name
{
bool operator()(const user_info& u1, const user_info& u2)
{
return u1.name < u2.name;
}
bool operator()(const user_info* u1, const user_info* u2)
{
return operator()(*u1, *u2);
}
};
struct user_sorter_relation
{
bool operator()(const user_info& u1, const user_info& u2)
{
return static_cast<int>(u1.relation) < static_cast<int>(u2.relation);
}
bool operator()(const user_info* u1, const user_info* u2)
{
return operator()(*u1, *u2);
}
};
struct user_sorter_relation_name
{
bool operator()(const user_info& u1, const user_info& u2)
{
return static_cast<int>(u1.relation) < static_cast<int>(u2.relation)
|| (u1.relation == u2.relation && u1.name < u2.name);
}
bool operator()(const user_info* u1, const user_info* u2)
{
return operator()(*u1, *u2);
}
};
void lobby_info::sort_users(bool by_name, bool by_relation)
{
users_sorted_.clear();
for(auto & u : users_)
{
for(auto& u : users_) {
users_sorted_.push_back(&u);
}
if(by_name) {
if(by_relation) {
std::sort(users_sorted_.begin(),
users_sorted_.end(),
user_sorter_relation_name());
} else {
std::sort(users_sorted_.begin(),
users_sorted_.end(),
user_sorter_name());
// TODO: is this the simplest way to represent the sorting method?
std::sort(users_sorted_.begin(), users_sorted_.end(), [&](const user_info* u1, const user_info* u2) {
if(by_name && by_relation) {
return u1->relation < u2->relation || (u1->relation == u2->relation && u1->name < u2->name);
}
} else if(by_relation) {
std::sort(users_sorted_.begin(),
users_sorted_.end(),
user_sorter_relation());
}
return (by_name ? u1->name < u2->name : true) && (by_relation ? u1->relation < u2->relation : true);
});
}
const std::vector<user_info*>& lobby_info::users_sorted() const