Merge pull request #340 from gfgtdf/wesnothd_sides
use boost::ptr_vector for wesnothd::game::history_ use boost::ptr_vector for wesnotd::server::games_
This commit is contained in:
commit
6844e4334a
4 changed files with 129 additions and 135 deletions
|
@ -1446,10 +1446,8 @@ void game::send_history(const network::connection sock) const
|
|||
//concatenating the buffers.
|
||||
//TODO: Work out how to concentate buffers without decompressing.
|
||||
std::string buf;
|
||||
for(std::vector<simple_wml::document*>::iterator i = history_.begin();
|
||||
i != history_.end(); ++i) {
|
||||
buf += (*i)->output();
|
||||
delete *i;
|
||||
for(t_history::iterator i = history_.begin(); i != history_.end(); ++i) {
|
||||
buf += i->output();
|
||||
}
|
||||
|
||||
try {
|
||||
|
@ -1477,14 +1475,11 @@ void game::save_replay() {
|
|||
if (!save_replays_ || !started_ || history_.empty()) return;
|
||||
|
||||
std::string replay_commands;
|
||||
for(std::vector<simple_wml::document*>::iterator i = history_.begin();
|
||||
i != history_.end(); ++i) {
|
||||
const simple_wml::node::child_list& turn_list = (*i)->root().children("turn");
|
||||
for (simple_wml::node::child_list::const_iterator turn = turn_list.begin();
|
||||
turn != turn_list.end(); ++turn) {
|
||||
for(t_history::iterator i = history_.begin(); i != history_.end(); ++i) {
|
||||
const simple_wml::node::child_list& turn_list = i->root().children("turn");
|
||||
for (simple_wml::node::child_list::const_iterator turn = turn_list.begin(); turn != turn_list.end(); ++turn) {
|
||||
replay_commands += simple_wml::node_to_string(**turn);
|
||||
}
|
||||
delete *i;
|
||||
}
|
||||
history_.clear();
|
||||
|
||||
|
@ -1535,9 +1530,6 @@ void game::record_data(simple_wml::document* data) {
|
|||
|
||||
void game::clear_history() {
|
||||
if (history_.empty()) return;
|
||||
for(std::vector<simple_wml::document*>::iterator i = history_.begin(); i != history_.end(); ++i) {
|
||||
delete *i;
|
||||
}
|
||||
history_.clear();
|
||||
}
|
||||
|
||||
|
|
|
@ -25,6 +25,7 @@
|
|||
|
||||
#include "../mt_rng.hpp"
|
||||
|
||||
#include <boost/ptr_container/ptr_vector.hpp>
|
||||
//class player;
|
||||
|
||||
namespace wesnothd {
|
||||
|
@ -378,7 +379,8 @@ private:
|
|||
simple_wml::document level_;
|
||||
|
||||
/** Replay data. */
|
||||
mutable std::vector<simple_wml::document*> history_;
|
||||
typedef boost::ptr_vector<simple_wml::document> t_history;
|
||||
mutable t_history history_;
|
||||
|
||||
/** Pointer to the game's description in the games_and_users_list_. */
|
||||
simple_wml::node* description_;
|
||||
|
@ -401,7 +403,7 @@ private:
|
|||
|
||||
struct game_is_member {
|
||||
game_is_member(network::connection sock) : sock_(sock) {}
|
||||
bool operator()(const game* g) const { return g->is_owner(sock_) || g->is_member(sock_); }
|
||||
bool operator()(const game& g) const { return g.is_owner(sock_) || g.is_member(sock_); }
|
||||
|
||||
private:
|
||||
network::connection sock_;
|
||||
|
@ -409,7 +411,7 @@ private:
|
|||
|
||||
struct game_id_matches {
|
||||
game_id_matches(int id) : id_(id) {}
|
||||
bool operator()(const game* g) const { return g->id() == id_; }
|
||||
bool operator()(const game& g) const { return g.id() == id_; }
|
||||
|
||||
private:
|
||||
int id_;
|
||||
|
|
|
@ -866,18 +866,18 @@ void server::run() {
|
|||
<< "\thas logged off. (socket: " << e.socket << ")\n";
|
||||
|
||||
} else {
|
||||
for (std::vector<wesnothd::game*>::iterator g = games_.begin();
|
||||
for (t_games::iterator g = games_.begin();
|
||||
g != games_.end(); ++g)
|
||||
{
|
||||
if (!(*g)->is_member(e.socket)) {
|
||||
if (!g->is_member(e.socket)) {
|
||||
continue;
|
||||
}
|
||||
// Did the last player leave?
|
||||
if ((*g)->remove_player(e.socket, true)) {
|
||||
if (g->remove_player(e.socket, true)) {
|
||||
delete_game(g);
|
||||
break;
|
||||
} else {
|
||||
(*g)->describe_slots();
|
||||
g->describe_slots();
|
||||
|
||||
update_game_in_lobby(*g, e.socket);
|
||||
}
|
||||
|
@ -1252,9 +1252,9 @@ void server::process_login(const network::connection sock,
|
|||
<< "\thas logged on" << (registered ? " to a registered account" : "")
|
||||
<< ". (socket: " << sock << ")\n";
|
||||
|
||||
for (std::vector<wesnothd::game*>::const_iterator g = games_.begin(); g != games_.end(); ++g) {
|
||||
for (t_games::const_iterator g = games_.begin(); g != games_.end(); ++g) {
|
||||
// Note: This string is parsed by the client to identify lobby join messages!
|
||||
(*g)->send_server_message_to_all(username + " has logged into the lobby");
|
||||
g->send_server_message_to_all(username + " has logged into the lobby");
|
||||
}
|
||||
|
||||
if(user_handler_ && user_handler_->user_is_moderator(username)) {
|
||||
|
@ -1607,8 +1607,8 @@ void server::msg_handler(const std::string& /*issuer_name*/, const std::string&
|
|||
}
|
||||
|
||||
rooms_.lobby().send_server_message_to_all(parameters);
|
||||
for (std::vector<wesnothd::game*>::const_iterator g = games_.begin(); g != games_.end(); ++g) {
|
||||
(*g)->send_server_message_to_all(parameters);
|
||||
for (t_games::const_iterator g = games_.begin(); g != games_.end(); ++g) {
|
||||
g->send_server_message_to_all(parameters);
|
||||
}
|
||||
|
||||
LOG_SERVER << "<server" << (parameters.find("/me ") == 0
|
||||
|
@ -2201,11 +2201,11 @@ void server::process_whisper(const network::connection sock,
|
|||
continue;
|
||||
}
|
||||
|
||||
std::vector<wesnothd::game*>::const_iterator g;
|
||||
t_games::const_iterator g;
|
||||
for (g = games_.begin(); g != games_.end(); ++g) {
|
||||
if (!(*g)->is_member(i->first)) continue;
|
||||
if (!g->is_member(i->first)) continue;
|
||||
// Don't send to players in a running game the sender is part of.
|
||||
dont_send = ((*g)->started() && (*g)->is_player(i->first) && (*g)->is_member(sock));
|
||||
dont_send = (g->started() && g->is_player(i->first) && g->is_member(sock));
|
||||
break;
|
||||
}
|
||||
if (dont_send) {
|
||||
|
@ -2257,7 +2257,7 @@ void server::process_data_lobby(const network::connection sock,
|
|||
// Create the new game, remove the player from the lobby
|
||||
// and set the player as the host/owner.
|
||||
games_.push_back(new wesnothd::game(players_, sock, game_name, save_replays_, replay_save_path_));
|
||||
wesnothd::game& g = *games_.back();
|
||||
wesnothd::game& g = games_.back();
|
||||
if(game_password.empty() == false) {
|
||||
g.set_password(game_password);
|
||||
}
|
||||
|
@ -2278,7 +2278,7 @@ void server::process_data_lobby(const network::connection sock,
|
|||
const std::string& password = (*join)["password"].to_string();
|
||||
int game_id = (*join)["id"].to_int();
|
||||
|
||||
const std::vector<wesnothd::game*>::iterator g =
|
||||
const t_games::iterator g =
|
||||
std::find_if(games_.begin(), games_.end(), wesnothd::game_id_matches(game_id));
|
||||
|
||||
static simple_wml::document leave_game_doc("[leave_game]\n[/leave_game]\n", simple_wml::INIT_COMPRESSED);
|
||||
|
@ -2289,9 +2289,9 @@ void server::process_data_lobby(const network::connection sock,
|
|||
rooms_.lobby().send_server_message("Attempt to join unknown game.", sock);
|
||||
send_doc(games_and_users_list_, sock);
|
||||
return;
|
||||
} else if (!(*g)->level_init()) {
|
||||
} else if (!g->level_init()) {
|
||||
WRN_SERVER << network::ip_address(sock) << "\t" << pl->second.name()
|
||||
<< "\tattempted to join uninitialized game:\t\"" << (*g)->name()
|
||||
<< "\tattempted to join uninitialized game:\t\"" << g->name()
|
||||
<< "\" (" << game_id << ").\n";
|
||||
send_doc(leave_game_doc, sock);
|
||||
rooms_.lobby().send_server_message("Attempt to join an uninitialized game.", sock);
|
||||
|
@ -2299,17 +2299,17 @@ void server::process_data_lobby(const network::connection sock,
|
|||
return;
|
||||
} else if (pl->second.is_moderator()) {
|
||||
// Admins are always allowed to join.
|
||||
} else if ((*g)->player_is_banned(sock)) {
|
||||
} else if (g->player_is_banned(sock)) {
|
||||
DBG_SERVER << network::ip_address(sock) << "\tReject banned player: "
|
||||
<< pl->second.name() << "\tfrom game:\t\"" << (*g)->name()
|
||||
<< pl->second.name() << "\tfrom game:\t\"" << g->name()
|
||||
<< "\" (" << game_id << ").\n";
|
||||
send_doc(leave_game_doc, sock);
|
||||
rooms_.lobby().send_server_message("You are banned from this game.", sock);
|
||||
send_doc(games_and_users_list_, sock);
|
||||
return;
|
||||
} else if(!observer && !(*g)->password_matches(password)) {
|
||||
} else if(!observer && !g->password_matches(password)) {
|
||||
WRN_SERVER << network::ip_address(sock) << "\t" << pl->second.name()
|
||||
<< "\tattempted to join game:\t\"" << (*g)->name() << "\" ("
|
||||
<< "\tattempted to join game:\t\"" << g->name() << "\" ("
|
||||
<< game_id << ") with bad password\n";
|
||||
send_doc(leave_game_doc, sock);
|
||||
rooms_.lobby().send_server_message("Incorrect password.", sock);
|
||||
|
@ -2318,20 +2318,20 @@ void server::process_data_lobby(const network::connection sock,
|
|||
}
|
||||
// Hack to work around problems of players not getting properly removed
|
||||
// from a game. Still need to figure out actual cause...
|
||||
const std::vector<wesnothd::game*>::iterator g2 =
|
||||
const t_games::iterator g2 =
|
||||
std::find_if(games_.begin(), games_.end(), wesnothd::game_is_member(sock));
|
||||
if (g2 != games_.end()) {
|
||||
WRN_SERVER << network::ip_address(sock) << "\t" << pl->second.name()
|
||||
<< "\tattempted to join a second game. He's already in game:\t\""
|
||||
<< (*g2)->name() << "\" (" << (*g2)->id()
|
||||
<< g2->name() << "\" (" << g2->id()
|
||||
<< ") and the lobby. (socket: " << sock << ")\n"
|
||||
<< "Removing him from that game to fix the inconsistency...\n";
|
||||
(*g2)->remove_player(sock);
|
||||
g2->remove_player(sock);
|
||||
}
|
||||
bool joined = (*g)->add_player(sock, observer);
|
||||
bool joined = g->add_player(sock, observer);
|
||||
if (!joined) {
|
||||
WRN_SERVER << network::ip_address(sock) << "\t" << pl->second.name()
|
||||
<< "\tattempted to observe game:\t\"" << (*g)->name() << "\" ("
|
||||
<< "\tattempted to observe game:\t\"" << g->name() << "\" ("
|
||||
<< game_id << ") which doesn't allow observers.\n";
|
||||
send_doc(leave_game_doc, sock);
|
||||
rooms_.lobby().send_server_message("Attempt to observe a game that doesn't allow observers. (You probably joined the game shortly after it filled up.)", sock);
|
||||
|
@ -2339,12 +2339,12 @@ void server::process_data_lobby(const network::connection sock,
|
|||
return;
|
||||
}
|
||||
rooms_.exit_lobby(sock);
|
||||
(*g)->describe_slots();
|
||||
g->describe_slots();
|
||||
|
||||
//send notification of changes to the game and user
|
||||
simple_wml::document diff;
|
||||
bool diff1 = make_change_diff(*games_and_users_list_.child("gamelist"),
|
||||
"gamelist", "game", (*g)->description(), diff);
|
||||
"gamelist", "game", g->description(), diff);
|
||||
bool diff2 = make_change_diff(games_and_users_list_.root(), NULL,
|
||||
"user", pl->second.config_address(), diff);
|
||||
if (diff1 || diff2) {
|
||||
|
@ -2391,7 +2391,7 @@ void server::process_data_game(const network::connection sock,
|
|||
return;
|
||||
}
|
||||
|
||||
const std::vector<wesnothd::game*>::iterator itor =
|
||||
const t_games::iterator itor =
|
||||
std::find_if(games_.begin(), games_.end(), wesnothd::game_is_member(sock));
|
||||
if (itor == games_.end()) {
|
||||
ERR_SERVER << "ERROR: Could not find game for player: "
|
||||
|
@ -2399,54 +2399,54 @@ void server::process_data_game(const network::connection sock,
|
|||
return;
|
||||
}
|
||||
|
||||
wesnothd::game* g = *itor;
|
||||
wesnothd::game& g = *itor;
|
||||
|
||||
// If this is data describing the level for a game.
|
||||
if (data.child("snapshot") || data.child("scenario")) {
|
||||
if (!g->is_owner(sock)) {
|
||||
if (!g.is_owner(sock)) {
|
||||
return;
|
||||
}
|
||||
// If this game is having its level data initialized
|
||||
// for the first time, and is ready for players to join.
|
||||
// We should currently have a summary of the game in g->level().
|
||||
// We should currently have a summary of the game in g.level().
|
||||
// We want to move this summary to the games_and_users_list_, and
|
||||
// place a pointer to that summary in the game's description.
|
||||
// g->level() should then receive the full data for the game.
|
||||
if (!g->level_init()) {
|
||||
// g.level() should then receive the full data for the game.
|
||||
if (!g.level_init()) {
|
||||
LOG_SERVER << network::ip_address(sock) << "\t" << pl->second.name()
|
||||
<< "\tcreated game:\t\"" << g->name() << "\" ("
|
||||
<< g->id() << ").\n";
|
||||
<< "\tcreated game:\t\"" << g.name() << "\" ("
|
||||
<< g.id() << ").\n";
|
||||
// Update our config object which describes the open games,
|
||||
// and save a pointer to the description in the new game.
|
||||
simple_wml::node* const gamelist = games_and_users_list_.child("gamelist");
|
||||
assert(gamelist != NULL);
|
||||
simple_wml::node& desc = gamelist->add_child("game");
|
||||
g->level().root().copy_into(desc);
|
||||
g.level().root().copy_into(desc);
|
||||
if (const simple_wml::node* m = data.child("multiplayer")) {
|
||||
m->copy_into(desc);
|
||||
} else {
|
||||
WRN_SERVER << network::ip_address(sock) << "\t" << pl->second.name()
|
||||
<< "\tsent scenario data in game:\t\"" << g->name() << "\" ("
|
||||
<< g->id() << ") without a 'multiplayer' child.\n";
|
||||
<< "\tsent scenario data in game:\t\"" << g.name() << "\" ("
|
||||
<< g.id() << ") without a 'multiplayer' child.\n";
|
||||
// Set the description so it can be removed in delete_game().
|
||||
g->set_description(&desc);
|
||||
g.set_description(&desc);
|
||||
delete_game(itor);
|
||||
rooms_.lobby().send_server_message("The scenario data is missing the [multiplayer] tag which contains the game settings. Game aborted.", sock);
|
||||
return;
|
||||
}
|
||||
|
||||
g->set_description(&desc);
|
||||
desc.set_attr_dup("id", lexical_cast_default<std::string>(g->id()).c_str());
|
||||
g.set_description(&desc);
|
||||
desc.set_attr_dup("id", lexical_cast_default<std::string>(g.id()).c_str());
|
||||
} else {
|
||||
WRN_SERVER << network::ip_address(sock) << "\t" << pl->second.name()
|
||||
<< "\tsent scenario data in game:\t\"" << g->name() << "\" ("
|
||||
<< g->id() << ") although it's already initialized.\n";
|
||||
<< "\tsent scenario data in game:\t\"" << g.name() << "\" ("
|
||||
<< g.id() << ") although it's already initialized.\n";
|
||||
return;
|
||||
}
|
||||
|
||||
assert(games_and_users_list_.child("gamelist")->children("game").empty() == false);
|
||||
|
||||
simple_wml::node& desc = *g->description();
|
||||
simple_wml::node& desc = *g.description();
|
||||
// Update the game's description.
|
||||
// If there is no shroud, then tell players in the lobby
|
||||
// what the map looks like
|
||||
|
@ -2471,13 +2471,13 @@ void server::process_data_game(const network::connection sock,
|
|||
desc.child("modification")->set_attr("require_modification", "yes");
|
||||
}
|
||||
|
||||
// Record the full scenario in g->level()
|
||||
g->level().swap(data);
|
||||
// Record the full scenario in g.level()
|
||||
g.level().swap(data);
|
||||
// The host already put himself in the scenario so we just need
|
||||
// to update_side_data().
|
||||
//g->take_side(sock);
|
||||
g->update_side_data();
|
||||
g->describe_slots();
|
||||
//g.take_side(sock);
|
||||
g.update_side_data();
|
||||
g.describe_slots();
|
||||
|
||||
assert(games_and_users_list_.child("gamelist")->children("game").empty() == false);
|
||||
|
||||
|
@ -2489,40 +2489,40 @@ void server::process_data_game(const network::connection sock,
|
|||
/** @todo FIXME: Why not save the level data in the history_? */
|
||||
return;
|
||||
// Everything below should only be processed if the game is already intialized.
|
||||
} else if (!g->level_init()) {
|
||||
} else if (!g.level_init()) {
|
||||
WRN_SERVER << network::ip_address(sock) << "\tReceived unknown data from: "
|
||||
<< pl->second.name() << " (socket:" << sock
|
||||
<< ") while the scenario wasn't yet initialized.\n" << data.output();
|
||||
return;
|
||||
// If the host is sending the next scenario data.
|
||||
} else if (const simple_wml::node* scenario = data.child("store_next_scenario")) {
|
||||
if (!g->is_owner(sock)) return;
|
||||
if (!g->level_init()) {
|
||||
if (!g.is_owner(sock)) return;
|
||||
if (!g.level_init()) {
|
||||
WRN_SERVER << network::ip_address(sock) << "\tWarning: "
|
||||
<< pl->second.name() << "\tsent [store_next_scenario] in game:\t\""
|
||||
<< g->name() << "\" (" << g->id()
|
||||
<< g.name() << "\" (" << g.id()
|
||||
<< ") while the scenario is not yet initialized.";
|
||||
return;
|
||||
}
|
||||
g->save_replay();
|
||||
// Record the full scenario in g->level()
|
||||
g->level().clear();
|
||||
scenario->copy_into(g->level().root());
|
||||
g.save_replay();
|
||||
// Record the full scenario in g.level()
|
||||
g.level().clear();
|
||||
scenario->copy_into(g.level().root());
|
||||
|
||||
if (g->description() == NULL) {
|
||||
if (g.description() == NULL) {
|
||||
ERR_SERVER << network::ip_address(sock) << "\tERROR: \""
|
||||
<< g->name() << "\" (" << g->id()
|
||||
<< g.name() << "\" (" << g.id()
|
||||
<< ") is initialized but has no description_.\n";
|
||||
return;
|
||||
}
|
||||
simple_wml::node& desc = *g->description();
|
||||
simple_wml::node& desc = *g.description();
|
||||
// Update the game's description.
|
||||
if (const simple_wml::node* m = scenario->child("multiplayer")) {
|
||||
m->copy_into(desc);
|
||||
} else {
|
||||
WRN_SERVER << network::ip_address(sock) << "\t" << pl->second.name()
|
||||
<< "\tsent scenario data in game:\t\"" << g->name() << "\" ("
|
||||
<< g->id() << ") without a 'multiplayer' child.\n";
|
||||
<< "\tsent scenario data in game:\t\"" << g.name() << "\" ("
|
||||
<< g.id() << ") without a 'multiplayer' child.\n";
|
||||
delete_game(itor);
|
||||
rooms_.lobby().send_server_message("The scenario data is missing the [multiplayer] tag which contains the game settings. Game aborted.", sock);
|
||||
return;
|
||||
|
@ -2530,7 +2530,7 @@ void server::process_data_game(const network::connection sock,
|
|||
|
||||
// If there is no shroud, then tell players in the lobby
|
||||
// what the map looks like.
|
||||
const simple_wml::node& s = *wesnothd::game::starting_pos(g->level().root());
|
||||
const simple_wml::node& s = *wesnothd::game::starting_pos(g.level().root());
|
||||
desc.set_attr_dup("map_data", s["mp_shroud"].to_bool() ? "" :
|
||||
s["map_data"]);
|
||||
if (const simple_wml::node* e = data.child("era")) {
|
||||
|
@ -2547,7 +2547,7 @@ void server::process_data_game(const network::connection sock,
|
|||
static simple_wml::document notify_next_scenario(
|
||||
"[notify_next_scenario]\n[/notify_next_scenario]\n",
|
||||
simple_wml::INIT_COMPRESSED);
|
||||
g->send_data(notify_next_scenario, sock);
|
||||
g.send_data(notify_next_scenario, sock);
|
||||
|
||||
// Send the update of the game description to the lobby.
|
||||
update_game_in_lobby(g);
|
||||
|
@ -2555,41 +2555,41 @@ void server::process_data_game(const network::connection sock,
|
|||
return;
|
||||
// A mp client sends a request for the next scenario of a mp campaign.
|
||||
} else if (data.child("load_next_scenario")) {
|
||||
g->load_next_scenario(pl);
|
||||
g.load_next_scenario(pl);
|
||||
return;
|
||||
} else if (data.child("start_game")) {
|
||||
if (!g->is_owner(sock)) return;
|
||||
if (!g.is_owner(sock)) return;
|
||||
//perform controller tweaks, assigning sides as human for their owners etc.
|
||||
g->perform_controller_tweaks();
|
||||
g.perform_controller_tweaks();
|
||||
// Send notification of the game starting immediately.
|
||||
// g->start_game() will send data that assumes
|
||||
// g.start_game() will send data that assumes
|
||||
// the [start_game] message has been sent
|
||||
g->send_data(data, sock);
|
||||
g->start_game(pl);
|
||||
g.send_data(data, sock);
|
||||
g.start_game(pl);
|
||||
|
||||
//update the game having changed in the lobby
|
||||
update_game_in_lobby(g);
|
||||
return;
|
||||
} else if (data.child("update_game")) {
|
||||
g->update_game();
|
||||
g.update_game();
|
||||
update_game_in_lobby(g);
|
||||
return;
|
||||
} else if (data.child("leave_game")) {
|
||||
// May be better to just let remove_player() figure out when a game ends.
|
||||
if ((g->is_player(sock) && g->nplayers() == 1)
|
||||
|| (g->is_owner(sock) && (!g->started() || g->nplayers() == 0))) {
|
||||
if ((g.is_player(sock) && g.nplayers() == 1)
|
||||
|| (g.is_owner(sock) && (!g.started() || g.nplayers() == 0))) {
|
||||
// Remove the player in delete_game() with all other remaining
|
||||
// ones so he gets the updated gamelist.
|
||||
delete_game(itor);
|
||||
} else {
|
||||
g->remove_player(sock);
|
||||
g.remove_player(sock);
|
||||
rooms_.enter_lobby(sock);
|
||||
g->describe_slots();
|
||||
g.describe_slots();
|
||||
|
||||
// Send all other players in the lobby the update to the gamelist.
|
||||
simple_wml::document diff;
|
||||
bool diff1 = make_change_diff(*games_and_users_list_.child("gamelist"),
|
||||
"gamelist", "game", g->description(), diff);
|
||||
"gamelist", "game", g.description(), diff);
|
||||
bool diff2 = make_change_diff(games_and_users_list_.root(), NULL,
|
||||
"user", pl->second.config_address(), diff);
|
||||
if (diff1 || diff2) {
|
||||
|
@ -2602,63 +2602,63 @@ void server::process_data_game(const network::connection sock,
|
|||
return;
|
||||
// If this is data describing side changes by the host.
|
||||
} else if (const simple_wml::node* diff = data.child("scenario_diff")) {
|
||||
if (!g->is_owner(sock)) return;
|
||||
g->level().root().apply_diff(*diff);
|
||||
if (!g.is_owner(sock)) return;
|
||||
g.level().root().apply_diff(*diff);
|
||||
const simple_wml::node* cfg_change = diff->child("change_child");
|
||||
if (cfg_change
|
||||
/*&& cfg_change->child("side") it is very likeley that
|
||||
the diff changes a side so this check isn't that important.
|
||||
Note that [side] is not at toplevel but inside
|
||||
[scenario] or [snapshot] */) {
|
||||
g->update_side_data();
|
||||
g.update_side_data();
|
||||
}
|
||||
if (g->describe_slots()) {
|
||||
if (g.describe_slots()) {
|
||||
update_game_in_lobby(g);
|
||||
}
|
||||
g->send_data(data, sock);
|
||||
g.send_data(data, sock);
|
||||
return;
|
||||
// If a player changes his faction.
|
||||
} else if (data.child("change_faction")) {
|
||||
g->send_data(data, sock);
|
||||
g.send_data(data, sock);
|
||||
return;
|
||||
// If the owner of a side is changing the controller.
|
||||
} else if (const simple_wml::node *change = data.child("change_controller")) {
|
||||
g->transfer_side_control(sock, *change);
|
||||
if (g->describe_slots()) {
|
||||
g.transfer_side_control(sock, *change);
|
||||
if (g.describe_slots()) {
|
||||
update_game_in_lobby(g);
|
||||
}
|
||||
return;
|
||||
// If all observers should be muted. (toggles)
|
||||
} else if (data.child("muteall")) {
|
||||
if (!g->is_owner(sock)) {
|
||||
g->send_server_message("You cannot mute: not the game host.", sock);
|
||||
if (!g.is_owner(sock)) {
|
||||
g.send_server_message("You cannot mute: not the game host.", sock);
|
||||
return;
|
||||
}
|
||||
g->mute_all_observers();
|
||||
g.mute_all_observers();
|
||||
return;
|
||||
// If an observer should be muted.
|
||||
} else if (const simple_wml::node* mute = data.child("mute")) {
|
||||
g->mute_observer(*mute, pl);
|
||||
g.mute_observer(*mute, pl);
|
||||
return;
|
||||
// If an observer should be unmuted.
|
||||
} else if (const simple_wml::node* unmute = data.child("unmute")) {
|
||||
g->unmute_observer(*unmute, pl);
|
||||
g.unmute_observer(*unmute, pl);
|
||||
return;
|
||||
// The owner is kicking/banning someone from the game.
|
||||
} else if (data.child("kick") || data.child("ban")) {
|
||||
bool ban = (data.child("ban") != NULL);
|
||||
const network::connection user =
|
||||
(ban ? g->ban_user(*data.child("ban"), pl)
|
||||
: g->kick_member(*data.child("kick"), pl));
|
||||
(ban ? g.ban_user(*data.child("ban"), pl)
|
||||
: g.kick_member(*data.child("kick"), pl));
|
||||
if (user) {
|
||||
rooms_.enter_lobby(user);
|
||||
if (g->describe_slots()) {
|
||||
if (g.describe_slots()) {
|
||||
update_game_in_lobby(g, user);
|
||||
}
|
||||
// Send all other players in the lobby the update to the gamelist.
|
||||
simple_wml::document diff;
|
||||
make_change_diff(*games_and_users_list_.child("gamelist"),
|
||||
"gamelist", "game", g->description(), diff);
|
||||
"gamelist", "game", g.description(), diff);
|
||||
const wesnothd::player_map::iterator pl2 = players_.find(user);
|
||||
if (pl2 == players_.end()) {
|
||||
ERR_SERVER << "ERROR: Could not find kicked player in players_."
|
||||
|
@ -2673,15 +2673,15 @@ void server::process_data_game(const network::connection sock,
|
|||
}
|
||||
return;
|
||||
} else if (const simple_wml::node* unban = data.child("unban")) {
|
||||
g->unban_user(*unban, pl);
|
||||
g.unban_user(*unban, pl);
|
||||
return;
|
||||
// If info is being provided about the game state.
|
||||
} else if (const simple_wml::node* info = data.child("info")) {
|
||||
if (!g->is_player(sock)) return;
|
||||
if (!g.is_player(sock)) return;
|
||||
if ((*info)["type"] == "termination") {
|
||||
g->set_termination_reason((*info)["condition"].to_string());
|
||||
g.set_termination_reason((*info)["condition"].to_string());
|
||||
if ((*info)["condition"].to_string() == "out of sync") {
|
||||
g->send_server_message_to_all(pl->second.name() + " reports out of sync errors.");
|
||||
g.send_server_message_to_all(pl->second.name() + " reports out of sync errors.");
|
||||
}
|
||||
}
|
||||
return;
|
||||
|
@ -2689,24 +2689,24 @@ void server::process_data_game(const network::connection sock,
|
|||
// Notify the game of the commands, and if it changes
|
||||
// the description, then sync the new description
|
||||
// to players in the lobby.
|
||||
if (g->process_turn(data, pl)) {
|
||||
if (g.process_turn(data, pl)) {
|
||||
update_game_in_lobby(g);
|
||||
}
|
||||
return;
|
||||
} else if (data.child("whiteboard")) {
|
||||
g->process_whiteboard(data,pl);
|
||||
g.process_whiteboard(data,pl);
|
||||
return;
|
||||
} else if (data.child("change_controller_wml")) {
|
||||
g->process_change_controller_wml(data,pl);
|
||||
g.process_change_controller_wml(data,pl);
|
||||
return;
|
||||
} else if (data.child("require_random")) {
|
||||
g->require_random(data,pl);
|
||||
g.require_random(data,pl);
|
||||
return;
|
||||
} else if (data.child("message")) {
|
||||
g->process_message(data, pl);
|
||||
g.process_message(data, pl);
|
||||
return;
|
||||
} else if (data.child("stop_updates")) {
|
||||
g->send_data(data, sock);
|
||||
g.send_data(data, sock);
|
||||
return;
|
||||
// Data to ignore.
|
||||
} else if (data.child("error")
|
||||
|
@ -2719,11 +2719,11 @@ void server::process_data_game(const network::connection sock,
|
|||
|
||||
WRN_SERVER << network::ip_address(sock) << "\tReceived unknown data from: "
|
||||
<< pl->second.name() << " (socket:" << sock << ") in game: \""
|
||||
<< g->name() << "\" (" << g->id() << ")\n" << data.output();
|
||||
<< g.name() << "\" (" << g.id() << ")\n" << data.output();
|
||||
}
|
||||
|
||||
void server::delete_game(std::vector<wesnothd::game*>::iterator game_it) {
|
||||
metrics_.game_terminated((*game_it)->termination_reason());
|
||||
void server::delete_game(t_games::iterator game_it) {
|
||||
metrics_.game_terminated(game_it->termination_reason());
|
||||
|
||||
simple_wml::node* const gamelist = games_and_users_list_.child("gamelist");
|
||||
assert(gamelist != NULL);
|
||||
|
@ -2731,24 +2731,24 @@ void server::delete_game(std::vector<wesnothd::game*>::iterator game_it) {
|
|||
// Send a diff of the gamelist with the game deleted to players in the lobby
|
||||
simple_wml::document diff;
|
||||
if(make_delete_diff(*gamelist, "gamelist", "game",
|
||||
(*game_it)->description(), diff)) {
|
||||
game_it->description(), diff)) {
|
||||
rooms_.lobby().send_data(diff);
|
||||
}
|
||||
|
||||
// Delete the game from the games_and_users_list_.
|
||||
const simple_wml::node::child_list& games = gamelist->children("game");
|
||||
const simple_wml::node::child_list::const_iterator g =
|
||||
std::find(games.begin(), games.end(), (*game_it)->description());
|
||||
std::find(games.begin(), games.end(), game_it->description());
|
||||
if (g != games.end()) {
|
||||
const size_t index = g - games.begin();
|
||||
gamelist->remove_child("game", index);
|
||||
} else {
|
||||
// Can happen when the game ends before the scenario was transferred.
|
||||
LOG_SERVER << "Could not find game (" << (*game_it)->id()
|
||||
LOG_SERVER << "Could not find game (" << game_it->id()
|
||||
<< ") to delete in games_and_users_list_.\n";
|
||||
}
|
||||
|
||||
const wesnothd::user_vector& users = (*game_it)->all_game_users();
|
||||
const wesnothd::user_vector& users = game_it->all_game_users();
|
||||
// Set the availability status for all quitting users.
|
||||
for (wesnothd::user_vector::const_iterator user = users.begin();
|
||||
user != users.end(); ++user)
|
||||
|
@ -2769,20 +2769,19 @@ void server::delete_game(std::vector<wesnothd::game*>::iterator game_it) {
|
|||
|
||||
//send users in the game a notification to leave the game since it has ended
|
||||
static simple_wml::document leave_game_doc("[leave_game]\n[/leave_game]\n", simple_wml::INIT_COMPRESSED);
|
||||
(*game_it)->send_data(leave_game_doc);
|
||||
game_it->send_data(leave_game_doc);
|
||||
// Put the remaining users back in the lobby.
|
||||
rooms_.enter_lobby(**game_it);
|
||||
rooms_.enter_lobby(*game_it);
|
||||
|
||||
(*game_it)->send_data(games_and_users_list_);
|
||||
game_it->send_data(games_and_users_list_);
|
||||
|
||||
delete *game_it;
|
||||
games_.erase(game_it);
|
||||
}
|
||||
|
||||
void server::update_game_in_lobby(const wesnothd::game* g, network::connection exclude)
|
||||
void server::update_game_in_lobby(const wesnothd::game& g, network::connection exclude)
|
||||
{
|
||||
simple_wml::document diff;
|
||||
if (make_change_diff(*games_and_users_list_.child("gamelist"), "gamelist", "game", g->description(), diff)) {
|
||||
if (make_change_diff(*games_and_users_list_.child("gamelist"), "gamelist", "game", g.description(), diff)) {
|
||||
rooms_.lobby().send_data(diff, exclude);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -27,7 +27,7 @@
|
|||
|
||||
#include "utils/boost_function_guarded.hpp"
|
||||
#include <boost/scoped_ptr.hpp>
|
||||
|
||||
#include <boost/ptr_container/ptr_vector.hpp>
|
||||
class server
|
||||
{
|
||||
public:
|
||||
|
@ -94,7 +94,8 @@ private:
|
|||
wesnothd::player_map players_;
|
||||
std::set<network::connection> ghost_players_;
|
||||
|
||||
std::vector<wesnothd::game*> games_;
|
||||
typedef boost::ptr_vector<wesnothd::game> t_games;
|
||||
t_games games_;
|
||||
std::set<network::connection> not_logged_in_;
|
||||
|
||||
wesnothd::room_manager rooms_;
|
||||
|
@ -177,9 +178,9 @@ private:
|
|||
simple_wml::document& data);
|
||||
void process_data_game(const network::connection sock,
|
||||
simple_wml::document& data);
|
||||
void delete_game(std::vector<wesnothd::game*>::iterator game_it);
|
||||
void delete_game(t_games::iterator game_it);
|
||||
|
||||
void update_game_in_lobby(const wesnothd::game* g, network::connection exclude=0);
|
||||
void update_game_in_lobby(const wesnothd::game& g, network::connection exclude=0);
|
||||
|
||||
void start_new_server();
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue