wrapped most of the output_compressed() calls in a try-catch block...

...with trivial error handling and refactored some code along the way
This commit is contained in:
Gunter Labes 2009-09-02 16:40:40 +00:00
parent 2cf3a7ad9c
commit dbe1a5f46d
5 changed files with 80 additions and 68 deletions

View file

@ -196,10 +196,21 @@ void game::start_game(const player_map::const_iterator starter) {
send_observerjoins();
}
bool game::send_taken_side(simple_wml::document& cfg, const simple_wml::node::child_list::const_iterator side) const
{
const size_t side_num = (**side)["side"].to_int();
if (side_num < 1 || side_num > gamemap::MAX_PLAYERS) return false;
if (sides_[side_num - 1] != 0) return false;
// We expect that the host will really use our proposed side number. (He could do different...)
cfg.root().set_attr_dup("side", (**side)["side"]);
// Tell the host which side the new player should take.
return wesnothd::send_to_one(cfg, owner_);
}
bool game::take_side(const player_map::const_iterator user)
{
DBG_GAME << "take_side...\n";
DBG_GAME << debug_player_info();
if (started_) return false;
@ -209,7 +220,6 @@ bool game::take_side(const player_map::const_iterator user)
cfg.root().set_attr("leader", "random");
cfg.root().set_attr("gender", "random");
size_t side_num;
// Check if we can figure out a fitting side.
const simple_wml::node::child_list& sides = level_.root().children("side");
for(simple_wml::node::child_list::const_iterator side = sides.begin(); side != sides.end(); ++side) {
@ -217,33 +227,13 @@ bool game::take_side(const player_map::const_iterator user)
&& ((**side)["save_id"] == user->second.name().c_str()
|| (**side)["current_player"] == user->second.name().c_str()))
{
side_num = (**side)["side"].to_int();
if (side_num < 1 || side_num > gamemap::MAX_PLAYERS) continue;
if (sides_[side_num - 1] != 0) continue;
cfg.root().set_attr_dup("side", (**side)["side"]);
// Tell the host which side the new player should take.
simple_wml::string_span data = cfg.output_compressed();
network::send_raw_data(data.begin(), data.size(), owner_, cfg.root().first_child().to_string());
DBG_GAME << "take_side: took side " << side_num << " because the name matched\n";
DBG_GAME << debug_player_info();
return true;
if (send_taken_side(cfg, side)) return true;
}
}
// If there was no fitting side just take the first available.
for(simple_wml::node::child_list::const_iterator side = sides.begin(); side != sides.end(); ++side) {
if((**side)["controller"] == "network") {
side_num = (**side)["side"].to_int();
if (side_num < 1 || side_num > gamemap::MAX_PLAYERS) continue;
if (sides_[side_num - 1] != 0) continue;
// we expect that the host will really use our proposed side number (he could do different)
cfg.root().set_attr_dup("side", (**side)["side"]);
// Tell the host which side the new player should take.
simple_wml::string_span data = cfg.output_compressed();
network::send_raw_data(data.begin(), data.size(), owner_, cfg.root().first_child().to_string());
DBG_GAME << "take_side: took the first free network side which was " << side_num << "\n";
DBG_GAME << debug_player_info();
return true;
if (send_taken_side(cfg, side)) return true;
}
}
DBG_GAME << "take_side: there are no more sides available\n";
@ -483,10 +473,11 @@ void game::notify_new_host(){
// Why do we send the new host his own name?
cfg_host_transfer.set_attr("name", owner_name.c_str());
cfg_host_transfer.set_attr("value", "1");
const simple_wml::string_span data = cfg.output_compressed();
network::send_raw_data(data.begin(), data.size(), owner_,cfg.root().first_child().to_string());
send_and_record_server_message((owner_name
+ " has been chosen as the new host.").c_str());
std::string message = owner_name + " has been chosen as the new host.";
if (!wesnothd::send_to_one(cfg, owner_)) {
message += " But an internal error occured. You probably have to abandon this game.";
}
send_and_record_server_message(message.c_str());
}
bool game::describe_slots() {
@ -624,6 +615,12 @@ void game::unmute_observer(const simple_wml::node& unmute,
send_and_record_server_message((username.to_string() + " has been unmuted.").c_str());
}
void game::send_leave_game(network::connection user) const
{
static simple_wml::document leave_game("[leave_game]\n[/leave_game]\n", simple_wml::INIT_COMPRESSED);
wesnothd::send_to_one(leave_game, user);
}
network::connection game::kick_member(const simple_wml::node& kick,
const player_map::const_iterator kicker)
{
@ -650,9 +647,7 @@ network::connection game::kick_member(const simple_wml::node& kick,
send_and_record_server_message((username.to_string() + " has been kicked.").c_str());
// Tell the user to leave the game.
static simple_wml::document leave_game("[leave_game]\n[/leave_game]\n", simple_wml::INIT_COMPRESSED);
static const simple_wml::string_span leave_game_data = leave_game.output_compressed();
network::send_raw_data(leave_game_data.begin(), leave_game_data.size(), user->first,leave_game.root().first_child().to_string());
send_leave_game(user->first);
remove_player(user->first);
return user->first;
}
@ -687,9 +682,7 @@ network::connection game::ban_user(const simple_wml::node& ban,
send_and_record_server_message((username.to_string() + " has been banned.").c_str());
if (is_member(user->first)) {
//tell the user to leave the game.
static simple_wml::document leave_game("[leave_game]\n[/leave_game]\n", simple_wml::INIT_COMPRESSED);
static const simple_wml::string_span leave_game_data = leave_game.output_compressed();
network::send_raw_data(leave_game_data.begin(), leave_game_data.size(), user->first,leave_game.root().first_child().to_string());
send_leave_game(user->first);
remove_player(user->first);
return user->first;
}
@ -832,7 +825,7 @@ bool game::process_turn(simple_wml::document& data, const player_map::const_iter
simple_wml::document doc;
simple_wml::node& rs = doc.root().add_child("random_seed");
rs.set_attr_int("seed", seed);
send_to_one(doc, user->first, "game replay");
wesnothd::send_to_one(doc, user->first, "game replay");
}
}
if (turn->no_children()) {
@ -956,13 +949,12 @@ bool game::add_player(const network::connection player, bool observer) {
DBG_GAME << debug_player_info();
// Send the user the game data.
//std::cerr << "SENDING LEVEL {{{" << level_.output() << "}}}\n";
simple_wml::string_span level_data = level_.output_compressed();
network::send_raw_data(level_data.begin(), level_data.size(), player,"game_level");
if (!wesnothd::send_to_one(level_, player)) return false;
if(started_) {
//tell this player that the game has started
static simple_wml::document start_game_doc("[start_game]\n[/start_game]\n", simple_wml::INIT_COMPRESSED);
static const simple_wml::string_span start_game = start_game_doc.output_compressed();
network::send_raw_data(start_game.begin(), start_game.size(), player,start_game_doc.root().first_child().to_string());
if (!wesnothd::send_to_one(start_game_doc, player)) return false;
// Send observer join of all the observers in the game to the new player
// only once the game started. The client forgets about it anyway
// otherwise.
@ -1096,8 +1088,7 @@ void game::load_next_scenario(const player_map::const_iterator user) const {
send_server_message_to_all((user->second.name() + " advances to the next scenario").c_str(), user->first);
simple_wml::document cfg_scenario;
level_.root().copy_into(cfg_scenario.root().add_child("next_scenario"));
simple_wml::string_span data = cfg_scenario.output_compressed();
network::send_raw_data(data.begin(), data.size(), user->first, cfg_scenario.root().first_child().to_string());
if (!wesnothd::send_to_one(cfg_scenario, user->first)) return;
// Send the player the history of the game to-date.
send_history(user->first);
// Send observer join of all the observers in the game to the user.
@ -1176,8 +1167,7 @@ void game::send_observerjoins(const network::connection sock) const {
send_data(cfg, *ob);
} else {
// Send to the (new) user.
const simple_wml::string_span& data = cfg.output_compressed();
network::send_raw_data(data.begin(), data.size(), sock);
wesnothd::send_to_one(cfg, sock);
}
}
}
@ -1218,7 +1208,7 @@ void game::send_history(const network::connection sock) const
history_.clear();
history_.push_back(doc);
} catch (simple_wml::error& e) {
WRN_CONFIG << "simple_wml error: " << e.message << std::endl;
WRN_CONFIG << __func__ << ": simple_wml error: " << e.message << std::endl;
}
}
@ -1276,7 +1266,7 @@ void game::save_replay() {
ERR_GAME << "Could not save replay! (" << filename << ")\n";
}
} catch (simple_wml::error& e) {
WRN_CONFIG << "simple_wml error: " << e.message << std::endl;
WRN_CONFIG << __func__ << ": simple_wml error: " << e.message << std::endl;
}
}
@ -1392,7 +1382,7 @@ void game::send_server_message(const char* message, network::connection sock, si
}
if(sock) {
send_to_one(doc, sock, "message");
wesnothd::send_to_one(doc, sock, "message");
}
}
}
} // namespace wesnothd

View file

@ -187,6 +187,7 @@ private:
bool all_observers_muted() const { return all_observers_muted_; }
void send_muted_observers(const player_map::const_iterator user) const;
bool send_taken_side(simple_wml::document& cfg, const simple_wml::node::child_list::const_iterator side) const;
/**
* Figures out which side to take and tells that side to the game owner.
*
@ -208,6 +209,7 @@ private:
const bool player_left = true,
const std::string& controller = "");
void transfer_ai_sides(const network::connection player);
void send_leave_game(network::connection user) const;
void send_data_team(simple_wml::document& data, const simple_wml::string_span& team,
const network::connection exclude=0, std::string packet_type = "") const;
void send_data_observers(simple_wml::document& data, const network::connection exclude=0, std::string packet_type = "") const;

View file

@ -14,6 +14,10 @@
*/
#include "player_network.hpp"
#include "../log.hpp"
static lg::log_domain log_config("config");
#define WRN_CONFIG LOG_STREAM(warn, log_config)
namespace wesnothd {
@ -48,12 +52,18 @@ player_map::const_iterator find_user(const player_map& all_players,
return all_players.end();
}
void send_to_one(simple_wml::document& data, const network::connection sock, std::string packet_type)
bool send_to_one(simple_wml::document& data, const network::connection sock, std::string packet_type)
{
if (packet_type.empty())
packet_type = data.root().first_child().to_string();
simple_wml::string_span s = data.output_compressed();
network::send_raw_data(s.begin(), s.size(), sock, packet_type);
try {
simple_wml::string_span s = data.output_compressed();
network::send_raw_data(s.begin(), s.size(), sock, packet_type);
} catch (simple_wml::error& e) {
WRN_CONFIG << __func__ << ": simple_wml error: " << e.message << std::endl;
return false;
}
return true;
}
void send_to_many(simple_wml::document& data, const connection_vector& vec,
@ -61,11 +71,15 @@ void send_to_many(simple_wml::document& data, const connection_vector& vec,
{
if (packet_type.empty())
packet_type = data.root().first_child().to_string();
simple_wml::string_span s = data.output_compressed();
for(connection_vector::const_iterator i = vec.begin(); i != vec.end(); ++i) {
if (*i != exclude) {
network::send_raw_data(s.begin(), s.size(), *i, packet_type);
try {
simple_wml::string_span s = data.output_compressed();
for(connection_vector::const_iterator i = vec.begin(); i != vec.end(); ++i) {
if (*i != exclude) {
network::send_raw_data(s.begin(), s.size(), *i, packet_type);
}
}
} catch (simple_wml::error& e) {
WRN_CONFIG << __func__ << ": simple_wml error: " << e.message << std::endl;
}
}
@ -75,11 +89,15 @@ void send_to_many(simple_wml::document& data, const connection_vector& vec,
{
if (packet_type.empty())
packet_type = data.root().first_child().to_string();
simple_wml::string_span s = data.output_compressed();
for(connection_vector::const_iterator i = vec.begin(); i != vec.end(); ++i) {
if ((*i != exclude) && pred(*i)) {
network::send_raw_data(s.begin(), s.size(), *i, packet_type);
try {
simple_wml::string_span s = data.output_compressed();
for(connection_vector::const_iterator i = vec.begin(); i != vec.end(); ++i) {
if ((*i != exclude) && pred(*i)) {
network::send_raw_data(s.begin(), s.size(), *i, packet_type);
}
}
} catch (simple_wml::error& e) {
WRN_CONFIG << __func__ << ": simple_wml error: " << e.message << std::endl;
}
}

View file

@ -50,7 +50,7 @@ player_map::const_iterator find_user(const player_map& all_players,
* @param sock the socket id to send to
* @param packet_type the packet type, if empty the root node name is used
*/
void send_to_one(simple_wml::document& data,
bool send_to_one(simple_wml::document& data,
const network::connection sock,
std::string packet_type = "");

View file

@ -152,8 +152,12 @@ void send_doc(simple_wml::document& doc, network::connection connection, std::st
{
if (type.empty())
type = doc.root().first_child().to_string();
simple_wml::string_span s = doc.output_compressed();
network::send_raw_data(s.begin(), s.size(), connection, type);
try {
simple_wml::string_span s = doc.output_compressed();
network::send_raw_data(s.begin(), s.size(), connection, type);
} catch (simple_wml::error& e) {
WRN_CONFIG << __func__ << ": simple_wml error: " << e.message << std::endl;
}
}
void make_add_diff(const simple_wml::node& src, const char* gamelist,
@ -264,7 +268,8 @@ std::string player_status(wesnothd::player_map::const_iterator pl) {
return out.str();
}
}
} // namespace
class fps_limiter {
size_t start_ticks_;
size_t ms_per_frame_;
@ -356,16 +361,14 @@ void server::send_error(network::connection sock, const char* msg, const char* e
simple_wml::document doc;
doc.root().add_child("error").set_attr("message", msg);
if(strlen(error_code)) (*(doc.root().child("error"))).set_attr("error_code", error_code);
simple_wml::string_span output = doc.output_compressed();
network::send_raw_data(output.begin(), output.size(), sock, "error");
send_doc(doc, sock, "error");
}
void server::send_error_dup(network::connection sock, const std::string& msg) const
{
simple_wml::document doc;
doc.root().add_child("error").set_attr_dup("message", msg.c_str());
simple_wml::string_span output = doc.output_compressed();
network::send_raw_data(output.begin(), output.size(), sock, "error");
send_doc(doc, sock, "error");
}
void server::send_password_request(network::connection sock, const char* msg,
@ -393,8 +396,7 @@ void server::send_password_request(network::connection sock, const char* msg,
force_confirmation ? "yes" : "no");
if(strlen(error_code)) (*(doc.root().child("error"))).set_attr("error_code", error_code);
simple_wml::string_span output = doc.output_compressed();
network::send_raw_data(output.begin(), output.size(), sock);
send_doc(doc, sock, "error");
}
config server::read_config() const {