mirror of
https://github.com/wesnoth/wesnoth
synced 2025-05-14 00:41:17 +00:00
initial framework for server-side lobby room support
This commit is contained in:
parent
026b608dec
commit
22d9a73991
@ -425,6 +425,7 @@ SET(wesnothd_SRC
|
||||
server/player_network.cpp
|
||||
server/proxy.cpp
|
||||
server/room.cpp
|
||||
server/room_manager.cpp
|
||||
server/server.cpp
|
||||
server/simple_wml.cpp
|
||||
server/user_handler.cpp
|
||||
|
@ -250,6 +250,7 @@ wesnothd_SOURCES = \
|
||||
server/player_network.cpp \
|
||||
server/proxy.cpp \
|
||||
server/room.cpp \
|
||||
server/room_manager.cpp \
|
||||
server/server.cpp \
|
||||
server/simple_wml.cpp \
|
||||
server/user_handler.cpp \
|
||||
|
@ -364,6 +364,7 @@ wesnothd_sources = Split("""
|
||||
server/player_network.cpp
|
||||
server/proxy.cpp
|
||||
server/room.cpp
|
||||
server/room_manager.cpp
|
||||
server/sample_user_handler.cpp
|
||||
server/simple_wml.cpp
|
||||
server/user_handler.cpp
|
||||
|
@ -16,8 +16,9 @@
|
||||
|
||||
#include "player.hpp"
|
||||
|
||||
player::player(const std::string& n, simple_wml::node& cfg, bool registered,
|
||||
const size_t max_messages, const size_t time_period, const bool sp)
|
||||
wesnothd::player::player(const std::string& n, simple_wml::node& cfg,
|
||||
bool registered, const size_t max_messages,
|
||||
const size_t time_period, const bool sp)
|
||||
: name_(n)
|
||||
, cfg_(cfg)
|
||||
, selective_ping_(sp)
|
||||
@ -33,19 +34,22 @@ player::player(const std::string& n, simple_wml::node& cfg, bool registered,
|
||||
}
|
||||
|
||||
// keep 'available' and game name ('location') for backward compatibility
|
||||
void player::mark_available(const int game_id, const std::string location)
|
||||
void wesnothd::player::mark_available(const int game_id,
|
||||
const std::string location)
|
||||
{
|
||||
cfg_.set_attr("available", (game_id == 0) ? "yes" : "no");
|
||||
cfg_.set_attr_dup("game_id", lexical_cast<std::string>(game_id).c_str());
|
||||
cfg_.set_attr_dup("location", location.c_str());
|
||||
}
|
||||
|
||||
void player::mark_registered(bool registered) {
|
||||
void wesnothd::player::mark_registered(bool registered)
|
||||
{
|
||||
cfg_.set_attr("registered", registered ? "yes" : "no");
|
||||
registered_ = registered;
|
||||
}
|
||||
|
||||
bool player::is_message_flooding() {
|
||||
bool wesnothd::player::is_message_flooding()
|
||||
{
|
||||
const time_t now = time(NULL);
|
||||
if (flood_start_ == 0) {
|
||||
flood_start_ = now;
|
||||
@ -60,6 +64,5 @@ bool player::is_message_flooding() {
|
||||
} else if (messages_since_flood_start_ == MaxMessages) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
@ -15,13 +15,18 @@
|
||||
#ifndef PLAYER_HPP_INCLUDED
|
||||
#define PLAYER_HPP_INCLUDED
|
||||
|
||||
#include <ctime>
|
||||
|
||||
#include "../config.hpp"
|
||||
#include "simple_wml.hpp"
|
||||
|
||||
#include <ctime>
|
||||
#include <set>
|
||||
#include <string>
|
||||
|
||||
namespace wesnothd {
|
||||
|
||||
class game;
|
||||
|
||||
class player
|
||||
{
|
||||
public:
|
||||
@ -43,6 +48,19 @@ public:
|
||||
bool silenced() const { return messages_since_flood_start_ > MaxMessages; }
|
||||
bool is_message_flooding();
|
||||
|
||||
/**
|
||||
* @return true iff the player is in a game
|
||||
*/
|
||||
bool in_game() const { return get_game() != NULL; }
|
||||
|
||||
/**
|
||||
* @return a pointer to the game the player is in, or NULL if he/she is not
|
||||
* in a game at the moment
|
||||
*/
|
||||
const game* get_game() const;
|
||||
|
||||
void set_game(game* g);
|
||||
|
||||
private:
|
||||
const std::string name_;
|
||||
simple_wml::node& cfg_;
|
||||
@ -54,6 +72,9 @@ private:
|
||||
unsigned int messages_since_flood_start_;
|
||||
const size_t MaxMessages;
|
||||
const time_t TimePeriod;
|
||||
game* game_;
|
||||
};
|
||||
|
||||
} //namespace wesnothd
|
||||
|
||||
#endif
|
||||
|
@ -25,11 +25,16 @@ static lg::log_domain log_server("server");
|
||||
|
||||
namespace wesnothd {
|
||||
|
||||
room::room()
|
||||
: members_()
|
||||
room::room(const std::string& name)
|
||||
: members_(), name_(name)
|
||||
{
|
||||
}
|
||||
|
||||
const std::string& room::name() const
|
||||
{
|
||||
return name_;
|
||||
}
|
||||
|
||||
bool room::add_player(network::connection player)
|
||||
{
|
||||
if (is_member(player)) {
|
||||
@ -98,33 +103,6 @@ void room::send_server_message(const char* message,
|
||||
void room::process_message(simple_wml::document& data,
|
||||
const player_map::iterator user)
|
||||
{
|
||||
if (user->second.silenced()) {
|
||||
return;
|
||||
} else if (user->second.is_message_flooding()) {
|
||||
send_server_message(
|
||||
"Warning: you are sending too many messages too fast. "
|
||||
"Your message has not been relayed.", user->first);
|
||||
return;
|
||||
}
|
||||
|
||||
simple_wml::node* const message = data.root().child("message");
|
||||
assert(message);
|
||||
message->set_attr_dup("sender", user->second.name().c_str());
|
||||
|
||||
const simple_wml::string_span& msg = (*message)["message"];
|
||||
chat_message::truncate_message(msg, *message);
|
||||
|
||||
if (msg.size() >= 3 && simple_wml::string_span(msg.begin(), 4) == "/me ") {
|
||||
LOG_ROOM << network::ip_address(user->first)
|
||||
<< "\t<" << user->second.name()
|
||||
<< simple_wml::string_span(msg.begin() + 3, msg.size() - 3)
|
||||
<< ">\n";
|
||||
} else {
|
||||
LOG_ROOM << network::ip_address(user->first) << "\t<"
|
||||
<< user->second.name() << "> " << msg << "\n";
|
||||
}
|
||||
|
||||
send_data(data, user->first, "message");
|
||||
}
|
||||
|
||||
} //end namespace wesnothd
|
||||
|
@ -22,7 +22,7 @@
|
||||
namespace wesnothd {
|
||||
|
||||
typedef std::vector<network::connection> connection_vector;
|
||||
|
||||
typedef std::map<network::connection,player> player_map;
|
||||
class game;
|
||||
|
||||
/**
|
||||
@ -33,7 +33,9 @@ public:
|
||||
/**
|
||||
* Construct a room
|
||||
*/
|
||||
room();
|
||||
room(const std::string& name);
|
||||
|
||||
const std::string& name() const;
|
||||
|
||||
/**
|
||||
* Return the number of players in this room
|
||||
@ -107,7 +109,9 @@ public:
|
||||
void send_server_message(const char* message, network::connection sock,
|
||||
simple_wml::document* docptr = NULL) const;
|
||||
|
||||
|
||||
private:
|
||||
std::string name_;
|
||||
connection_vector members_;
|
||||
};
|
||||
|
||||
|
188
src/server/room_manager.cpp
Normal file
188
src/server/room_manager.cpp
Normal file
@ -0,0 +1,188 @@
|
||||
/* $Id$ */
|
||||
/*
|
||||
Copyright (C) 2009 by Tomasz Sniatowski <kailoran@gmail.com>
|
||||
Part of the Battle for Wesnoth Project http://www.wesnoth.org/
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License version 2
|
||||
or at your option any later version.
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY.
|
||||
|
||||
See the COPYING file for more details.
|
||||
*/
|
||||
|
||||
#include "player_network.hpp"
|
||||
#include "room_manager.hpp"
|
||||
#include "../foreach.hpp"
|
||||
#include "../log.hpp"
|
||||
static lg::log_domain log_server_lobby("server/lobby");
|
||||
#define ERR_LOBBY LOG_STREAM(err, log_server_lobby)
|
||||
#define WRN_LOBBY LOG_STREAM(warn, log_server_lobby)
|
||||
#define LOG_LOBBY LOG_STREAM(info, log_server_lobby)
|
||||
#define DBG_LOBBY LOG_STREAM(debug, log_server_lobby)
|
||||
|
||||
namespace wesnothd {
|
||||
|
||||
room_manager::room_manager(player_map &all_players)
|
||||
: all_players_(all_players), lobby_(NULL)
|
||||
{
|
||||
lobby_ = create_room("lobby");
|
||||
}
|
||||
|
||||
room_manager::~room_manager()
|
||||
{
|
||||
// this assumes the server is shutting down, so there's no need to
|
||||
// send the actual room-quit messages to clients
|
||||
foreach (t_rooms_by_name_::value_type i, rooms_by_name_) {
|
||||
delete i.second;
|
||||
}
|
||||
}
|
||||
|
||||
room* room_manager::get_room(const std::string &name)
|
||||
{
|
||||
t_rooms_by_name_::iterator i = rooms_by_name_.find(name);
|
||||
if (i != rooms_by_name_.end()) {
|
||||
return i->second;
|
||||
} else {
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
bool room_manager::room_exists(const std::string &name) const
|
||||
{
|
||||
return rooms_by_name_.find(name) != rooms_by_name_.end();
|
||||
}
|
||||
|
||||
room* room_manager::create_room(const std::string &name)
|
||||
{
|
||||
if (room_exists(name)) {
|
||||
DBG_LOBBY << "Requested creation of already existing room '" << name << "'\n";
|
||||
return NULL;
|
||||
}
|
||||
room* r = new room(name);
|
||||
rooms_by_name_.insert(std::make_pair(name, r));
|
||||
return r;
|
||||
}
|
||||
|
||||
void room_manager::delete_room(const std::string &name)
|
||||
{
|
||||
room* r = get_room(name);
|
||||
if (r == NULL) {
|
||||
DBG_LOBBY << "Requested deletion of nonexistant room '" << name << "'\n";
|
||||
return;
|
||||
}
|
||||
simple_wml::document doc;
|
||||
simple_wml::node& exit = doc.root().add_child("exit_room");
|
||||
exit.set_attr_dup("room", name.c_str());
|
||||
exit.set_attr("reason", "room deleted");
|
||||
r->send_data(doc);
|
||||
rooms_by_name_.erase(name);
|
||||
foreach (network::connection p, r->members()) {
|
||||
rooms_by_player_[p].erase(r);
|
||||
}
|
||||
}
|
||||
|
||||
void room_manager::enter_lobby(network::connection player)
|
||||
{
|
||||
lobby_->add_player(player);
|
||||
}
|
||||
|
||||
void room_manager::enter_lobby(const wesnothd::game &game)
|
||||
{
|
||||
lobby_->add_players(game);
|
||||
}
|
||||
|
||||
void room_manager::exit_lobby(network::connection player)
|
||||
{
|
||||
lobby_->remove_player(player);
|
||||
}
|
||||
|
||||
bool room_manager::in_lobby(network::connection player) const
|
||||
{
|
||||
return lobby_->is_member(player);
|
||||
}
|
||||
|
||||
void room_manager::remove_player(network::connection player)
|
||||
{
|
||||
lobby_->remove_player(player);
|
||||
t_rooms_by_player_::iterator i = rooms_by_player_.find(player);
|
||||
if (i != rooms_by_player_.end()) {
|
||||
foreach (room* r, i->second) {
|
||||
r->remove_player(player);
|
||||
}
|
||||
}
|
||||
rooms_by_player_.erase(player);
|
||||
}
|
||||
|
||||
void room_manager::player_joins_room(network::connection player, wesnothd::room *room)
|
||||
{
|
||||
room->add_player(player);
|
||||
rooms_by_player_[player].insert(room);
|
||||
simple_wml::document doc;
|
||||
simple_wml::node& join = doc.root().add_child("join");
|
||||
join.set_attr_dup("room", room->name().c_str());
|
||||
player_map::const_iterator i = all_players_.find(player);
|
||||
if (i == all_players_.end()) {
|
||||
WRN_LOBBY << "player " << player << " joins room but is not in all_players\n";
|
||||
return;
|
||||
}
|
||||
join.set_attr_dup("player", i->second.name().c_str());
|
||||
room->send_data(doc, player);
|
||||
foreach (network::connection m, room->members()) {
|
||||
simple_wml::node& member = join.add_child("member");
|
||||
player_map::const_iterator mi = all_players_.find(m);
|
||||
if (mi != all_players_.end()) {
|
||||
member.set_attr_dup("name", mi->second.name().c_str());
|
||||
}
|
||||
}
|
||||
send_to_one(doc, player);
|
||||
}
|
||||
|
||||
void room_manager::player_quits_room(network::connection player, wesnothd::room *room)
|
||||
{
|
||||
room->remove_player(player);
|
||||
rooms_by_player_[player].erase(room);
|
||||
simple_wml::document doc;
|
||||
simple_wml::node& quit = doc.root().add_child("quit");
|
||||
quit.set_attr_dup("room", room->name().c_str());
|
||||
player_map::const_iterator i = all_players_.find(player);
|
||||
if (i == all_players_.end()) {
|
||||
WRN_LOBBY << "player " << player << " quits room but is not in all_players\n";
|
||||
return;
|
||||
}
|
||||
quit.set_attr_dup("player", i->second.name().c_str());
|
||||
room->send_data(doc);
|
||||
}
|
||||
|
||||
void room_manager::process_message(simple_wml::document &data, const player_map::iterator user)
|
||||
{
|
||||
if (user->second.silenced()) {
|
||||
return;
|
||||
} else if (user->second.is_message_flooding()) {
|
||||
lobby_->send_server_message(
|
||||
"Warning: you are sending too many messages too fast. "
|
||||
"Your message has not been relayed.", user->first);
|
||||
return;
|
||||
}
|
||||
simple_wml::node* const message = data.root().child("message");
|
||||
assert (message);
|
||||
message->set_attr_dup("sender", user->second.name().c_str());
|
||||
std::string room_name = message->attr("room").to_string();
|
||||
//todo: dispatch to the appropriate room, check if the player is in that room ...
|
||||
const simple_wml::string_span& msg = (*message)["message"];
|
||||
chat_message::truncate_message(msg, *message);
|
||||
if (msg.size() >= 3 && simple_wml::string_span(msg.begin(), 4) == "/me ") {
|
||||
LOG_LOBBY << network::ip_address(user->first)
|
||||
<< "\t<" << user->second.name()
|
||||
<< simple_wml::string_span(msg.begin() + 3, msg.size() - 3)
|
||||
<< ">\n";
|
||||
} else {
|
||||
LOG_LOBBY << network::ip_address(user->first) << "\t<"
|
||||
<< user->second.name() << "> " << msg << "\n";
|
||||
}
|
||||
lobby_->send_data(data, user->first, "message");
|
||||
}
|
||||
|
||||
|
||||
} //namespace wesnothd
|
111
src/server/room_manager.hpp
Normal file
111
src/server/room_manager.hpp
Normal file
@ -0,0 +1,111 @@
|
||||
/* $Id$ */
|
||||
/*
|
||||
Copyright (C) 2009 by Tomasz Sniatowski <kailoran@gmail.com>
|
||||
Part of the Battle for Wesnoth Project http://www.wesnoth.org/
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License version 2
|
||||
or at your option any later version.
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY.
|
||||
|
||||
See the COPYING file for more details.
|
||||
*/
|
||||
|
||||
#include "room.hpp"
|
||||
|
||||
#include <boost/utility.hpp>
|
||||
|
||||
#ifndef SERVER_ROOM_MANAGER_HPP_INCLUDED
|
||||
#define SERVER_ROOM_MANAGER_HPP_INCLUDED
|
||||
|
||||
namespace wesnothd {
|
||||
|
||||
/**
|
||||
* The room manager manages the lobby and other rooms in the server, and related
|
||||
* client message processing.
|
||||
* The lobby represents players that are on the server, but not in any game.
|
||||
*/
|
||||
class room_manager : private boost::noncopyable
|
||||
{
|
||||
public:
|
||||
room_manager(player_map& all_players);
|
||||
~room_manager();
|
||||
|
||||
/**
|
||||
* Get a room by name, or NULL if it does not exist
|
||||
*/
|
||||
room* get_room(const std::string& name);
|
||||
|
||||
/**
|
||||
* @param name the room name to check
|
||||
* @return true iif the room existst
|
||||
*/
|
||||
bool room_exists(const std::string& name) const;
|
||||
|
||||
/**
|
||||
* Create room named "name" if it does not exist already.
|
||||
*/
|
||||
room* create_room(const std::string& name);
|
||||
|
||||
/**
|
||||
* Delete a room. Players in the room are kicked from it.
|
||||
*/
|
||||
void delete_room(const std::string& name);
|
||||
|
||||
/**
|
||||
* @return true iif the player is in the lobby
|
||||
*/
|
||||
bool in_lobby(network::connection player) const;
|
||||
|
||||
/**
|
||||
* Player-enters-lobby action. Will auto(re)join the default room(s)
|
||||
*/
|
||||
void enter_lobby(network::connection player);
|
||||
|
||||
/**
|
||||
* All players from a game re-enter the lobby
|
||||
*/
|
||||
void enter_lobby(const game& game);
|
||||
|
||||
/**
|
||||
* Player exits lobby.
|
||||
* TODO: should it remove information about the rooms the player is in?
|
||||
*/
|
||||
void exit_lobby(network::connection player);
|
||||
|
||||
/**
|
||||
* Remove info abut given player from all rooms
|
||||
*/
|
||||
void remove_player(network::connection player);
|
||||
|
||||
void process_message(simple_wml::document& data, const player_map::iterator user);
|
||||
|
||||
const room& lobby() const { return *lobby_; }
|
||||
private:
|
||||
/**
|
||||
* Adds a player to a room, notifies current members
|
||||
*/
|
||||
void player_joins_room(network::connection player, room* room);
|
||||
|
||||
/**
|
||||
* Removes a player from a room, notifies remaining members
|
||||
*/
|
||||
void player_quits_room(network::connection player, room* room);
|
||||
|
||||
|
||||
|
||||
player_map& all_players_;
|
||||
room* lobby_;
|
||||
typedef std::map<std::string, room*> t_rooms_by_name_;
|
||||
t_rooms_by_name_ rooms_by_name_;
|
||||
typedef std::map<network::connection, std::set<room*> > t_rooms_by_player_;
|
||||
t_rooms_by_player_ rooms_by_player_;
|
||||
|
||||
|
||||
};
|
||||
|
||||
} //namespace wesnothd
|
||||
|
||||
|
||||
#endif
|
@ -297,7 +297,7 @@ server::server(int port, const std::string& config_file, size_t min_threads,
|
||||
ghost_players_(),
|
||||
games_(),
|
||||
not_logged_in_(),
|
||||
lobby_(),
|
||||
rooms_(players_),
|
||||
input_(),
|
||||
config_file_(config_file),
|
||||
cfg_(read_config()),
|
||||
@ -530,7 +530,7 @@ void server::dump_stats(const time_t& now) {
|
||||
<< "\tnumber_of_games = " << games_.size()
|
||||
<< "\tnumber_of_users = " << players_.size()
|
||||
<< "\tnumber_of_ghost_users = " << ghost_players_.size()
|
||||
<< "\tlobby_users = " << lobby_.size() << "\n";
|
||||
<< "\trooms_users = " << rooms_.lobby().size() << "\n";
|
||||
}
|
||||
|
||||
void server::clean_user_handler(const time_t& now) {
|
||||
@ -754,7 +754,7 @@ void server::run() {
|
||||
simple_wml::document diff;
|
||||
if(make_delete_diff(games_and_users_list_.root(), NULL, "user",
|
||||
pl_it->second.config_address(), diff)) {
|
||||
lobby_.send_data(diff, e.socket);
|
||||
rooms_.lobby().send_data(diff, e.socket);
|
||||
}
|
||||
|
||||
games_and_users_list_.root().remove_child("user",index);
|
||||
@ -763,8 +763,8 @@ void server::run() {
|
||||
<< pl_it->second.name() << " in games_and_users_list_.\n";
|
||||
}
|
||||
// Was the player in the lobby or a game?
|
||||
if (lobby_.is_member(e.socket)) {
|
||||
lobby_.remove_player(e.socket);
|
||||
if (rooms_.in_lobby(e.socket)) {
|
||||
rooms_.remove_player(e.socket);
|
||||
LOG_SERVER << ip << "\t" << pl_it->second.name()
|
||||
<< "\thas logged off. (socket: " << e.socket << ")\n";
|
||||
|
||||
@ -839,7 +839,7 @@ void server::process_data(const network::connection sock,
|
||||
process_nickserv(sock, *nickserv);
|
||||
} else if (simple_wml::node* whisper = root.child("whisper")) {
|
||||
process_whisper(sock, *whisper);
|
||||
} else if (lobby_.is_member(sock)) {
|
||||
} else if (rooms_.in_lobby(sock)) {
|
||||
process_data_lobby(sock, data);
|
||||
} else {
|
||||
process_data_game(sock, data);
|
||||
@ -1059,30 +1059,30 @@ void server::process_login(const network::connection sock,
|
||||
send_doc(join_lobby_response_, sock);
|
||||
|
||||
simple_wml::node& player_cfg = games_and_users_list_.root().add_child("user");
|
||||
const player new_player(username, player_cfg, registered, default_max_messages_,
|
||||
default_time_period_, selective_ping );
|
||||
const wesnothd::player new_player(username, player_cfg, registered,
|
||||
default_max_messages_, default_time_period_, selective_ping);
|
||||
|
||||
// If the new player does not have selective ping enabled, immediately
|
||||
// add the player to the ghost player's list. This ensures a client won't
|
||||
// have to wait as long as x2 the current ping delay; which could cause
|
||||
// a client-side disconnection.
|
||||
players_.insert(std::pair<network::connection,player>(sock, new_player));
|
||||
players_.insert(std::make_pair(sock, new_player));
|
||||
if( !selective_ping )
|
||||
ghost_players_.insert(sock) ;
|
||||
|
||||
not_logged_in_.erase(sock);
|
||||
lobby_.add_player(sock);
|
||||
rooms_.enter_lobby(sock);
|
||||
// Send the new player the entire list of games and players
|
||||
send_doc(games_and_users_list_, sock);
|
||||
|
||||
if (motd_ != "") {
|
||||
lobby_.send_server_message(motd_.c_str(), sock);
|
||||
rooms_.lobby().send_server_message(motd_.c_str(), sock);
|
||||
}
|
||||
|
||||
// Send other players in the lobby the update that the player has joined
|
||||
simple_wml::document diff;
|
||||
make_add_diff(games_and_users_list_.root(), NULL, "user", diff);
|
||||
lobby_.send_data(diff, sock);
|
||||
rooms_.lobby().send_data(diff, sock);
|
||||
|
||||
LOG_SERVER << network::ip_address(sock) << "\t" << username
|
||||
<< "\thas logged on" << (registered ? " to a registered account" : "")
|
||||
@ -1099,7 +1099,7 @@ void server::process_login(const network::connection sock,
|
||||
<< username << std::endl;
|
||||
admins_.insert(sock);
|
||||
// This string is parsed by the client!
|
||||
lobby_.send_server_message("You are now recognized as an administrator. "
|
||||
rooms_.lobby().send_server_message("You are now recognized as an administrator. "
|
||||
"If you no longer want to be automatically authenticated use '/query signout'.", sock);
|
||||
}
|
||||
|
||||
@ -1172,7 +1172,7 @@ void server::process_query(const network::connection sock,
|
||||
} else {
|
||||
response << "Error: unrecognized query: '" << command << "'\n" << help_msg;
|
||||
}
|
||||
lobby_.send_server_message(response.str().c_str(), sock);
|
||||
rooms_.lobby().send_server_message(response.str().c_str(), sock);
|
||||
}
|
||||
|
||||
void server::start_new_server() {
|
||||
@ -1251,7 +1251,7 @@ std::string server::process_command(const std::string& query, const std::string&
|
||||
out << "Number of games = " << games_.size()
|
||||
<< "\nTotal number of users = " << players_.size()
|
||||
<< "\nNumber of ghost users = " << ghost_players_.size()
|
||||
<< "\nNumber of users in the lobby = " << lobby_.size();
|
||||
<< "\nNumber of users in the lobby = " << rooms_.lobby().size();
|
||||
return out.str();
|
||||
} else if (command == "metrics") {
|
||||
out << metrics_;
|
||||
@ -1301,7 +1301,7 @@ std::string server::process_command(const std::string& query, const std::string&
|
||||
if (parameters == "") {
|
||||
return "You must type a message.";
|
||||
}
|
||||
lobby_.send_server_message_to_all(parameters.c_str());
|
||||
rooms_.lobby().send_server_message_to_all(parameters.c_str());
|
||||
if (command == "msg") {
|
||||
for (std::vector<wesnothd::game*>::const_iterator g = games_.begin(); g != games_.end(); ++g) {
|
||||
(*g)->send_server_message_to_all(parameters.c_str());
|
||||
@ -1578,7 +1578,7 @@ void server::process_nickserv(const network::connection sock, simple_wml::node&
|
||||
|
||||
// Check if this server allows nick registration at all
|
||||
if(!user_handler_) {
|
||||
lobby_.send_server_message("This server does not allow username registration.", sock);
|
||||
rooms_.lobby().send_server_message("This server does not allow username registration.", sock);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -1592,7 +1592,7 @@ void server::process_nickserv(const network::connection sock, simple_wml::node&
|
||||
// Warn that providing an email address might be a good idea
|
||||
((*data.child("register"))["mail"].empty() ?
|
||||
" It is recommended that you provide an email address for password recovery." : "");
|
||||
lobby_.send_server_message(msg.str().c_str(), sock);
|
||||
rooms_.lobby().send_server_message(msg.str().c_str(), sock);
|
||||
|
||||
// Mark the player as registered and send the other clients
|
||||
// an update to dislpay this change
|
||||
@ -1601,10 +1601,10 @@ void server::process_nickserv(const network::connection sock, simple_wml::node&
|
||||
simple_wml::document diff;
|
||||
make_change_diff(games_and_users_list_.root(), NULL,
|
||||
"user", pl->second.config_address(), diff);
|
||||
lobby_.send_data(diff);
|
||||
rooms_.lobby().send_data(diff);
|
||||
|
||||
} catch (user_handler::error e) {
|
||||
lobby_.send_server_message(("There was an error registering your username. The error message was: "
|
||||
rooms_.lobby().send_server_message(("There was an error registering your username. The error message was: "
|
||||
+ e.message).c_str(), sock);
|
||||
}
|
||||
return;
|
||||
@ -1613,7 +1613,7 @@ void server::process_nickserv(const network::connection sock, simple_wml::node&
|
||||
// A user requested to update his password or mail
|
||||
if(data.child("set")) {
|
||||
if(!(user_handler_->user_exists(pl->second.name()))) {
|
||||
lobby_.send_server_message("You are not registered. Please register first.",
|
||||
rooms_.lobby().send_server_message("You are not registered. Please register first.",
|
||||
sock);
|
||||
return;
|
||||
}
|
||||
@ -1623,10 +1623,10 @@ void server::process_nickserv(const network::connection sock, simple_wml::node&
|
||||
try {
|
||||
user_handler_->set_user_detail(pl->second.name(), set["detail"].to_string(), set["value"].to_string());
|
||||
|
||||
lobby_.send_server_message("Your details have been updated.", sock);
|
||||
rooms_.lobby().send_server_message("Your details have been updated.", sock);
|
||||
|
||||
} catch (user_handler::error e) {
|
||||
lobby_.send_server_message(("There was an error updating your details. The error message was: "
|
||||
rooms_.lobby().send_server_message(("There was an error updating your details. The error message was: "
|
||||
+ e.message).c_str(), sock);
|
||||
}
|
||||
|
||||
@ -1635,7 +1635,7 @@ void server::process_nickserv(const network::connection sock, simple_wml::node&
|
||||
|
||||
// A user requested information about another user
|
||||
if(data.child("details")) {
|
||||
lobby_.send_server_message(("Valid details for this server are: " +
|
||||
rooms_.lobby().send_server_message(("Valid details for this server are: " +
|
||||
user_handler_->get_valid_details()).c_str(), sock);
|
||||
return;
|
||||
}
|
||||
@ -1644,9 +1644,9 @@ void server::process_nickserv(const network::connection sock, simple_wml::node&
|
||||
if(data.child("info")) {
|
||||
try {
|
||||
std::string res = user_handler_->user_info((*data.child("info"))["name"].to_string());
|
||||
lobby_.send_server_message(res.c_str(), sock);
|
||||
rooms_.lobby().send_server_message(res.c_str(), sock);
|
||||
} catch (user_handler::error e) {
|
||||
lobby_.send_server_message(("There was an error looking up the details of the user '" +
|
||||
rooms_.lobby().send_server_message(("There was an error looking up the details of the user '" +
|
||||
(*data.child("info"))["name"].to_string() + "'. " +" The error message was: "
|
||||
+ e.message).c_str(), sock);
|
||||
}
|
||||
@ -1656,7 +1656,7 @@ void server::process_nickserv(const network::connection sock, simple_wml::node&
|
||||
// A user requested to delete his nick
|
||||
if(data.child("drop")) {
|
||||
if(!(user_handler_->user_exists(pl->second.name()))) {
|
||||
lobby_.send_server_message("You are not registered.",
|
||||
rooms_.lobby().send_server_message("You are not registered.",
|
||||
sock);
|
||||
return;
|
||||
}
|
||||
@ -1665,14 +1665,14 @@ void server::process_nickserv(const network::connection sock, simple_wml::node&
|
||||
// registerd username without the password we should never get
|
||||
// to call this
|
||||
if(!(pl->second.registered())) {
|
||||
lobby_.send_server_message("You are not logged in.",
|
||||
rooms_.lobby().send_server_message("You are not logged in.",
|
||||
sock);
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
user_handler_->remove_user(pl->second.name());
|
||||
lobby_.send_server_message("Your username has been dropped.", sock);
|
||||
rooms_.lobby().send_server_message("Your username has been dropped.", sock);
|
||||
|
||||
// Mark the player as not registered and send the other clients
|
||||
// an update to dislpay this change
|
||||
@ -1681,9 +1681,9 @@ void server::process_nickserv(const network::connection sock, simple_wml::node&
|
||||
simple_wml::document diff;
|
||||
make_change_diff(games_and_users_list_.root(), NULL,
|
||||
"user", pl->second.config_address(), diff);
|
||||
lobby_.send_data(diff);
|
||||
rooms_.lobby().send_data(diff);
|
||||
} catch (user_handler::error e) {
|
||||
lobby_.send_server_message(("There was an error dropping your username. The error message was: "
|
||||
rooms_.lobby().send_server_message(("There was an error dropping your username. The error message was: "
|
||||
+ e.message).c_str(), sock);
|
||||
}
|
||||
return;
|
||||
@ -1760,7 +1760,7 @@ void server::process_data_lobby(const network::connection sock,
|
||||
if (graceful_restart) {
|
||||
static simple_wml::document leave_game_doc("[leave_game]\n[/leave_game]\n", simple_wml::INIT_COMPRESSED);
|
||||
send_doc(leave_game_doc, sock);
|
||||
lobby_.send_server_message("This server is shutting down. You aren't allowed to make new games. Please reconnect to the new server.", sock);
|
||||
rooms_.lobby().send_server_message("This server is shutting down. You aren't allowed to make new games. Please reconnect to the new server.", sock);
|
||||
send_doc(games_and_users_list_, sock);
|
||||
return;
|
||||
}
|
||||
@ -1777,11 +1777,11 @@ void server::process_data_lobby(const network::connection sock,
|
||||
}
|
||||
|
||||
data.root().child("create_game")->copy_into(g.level().root());
|
||||
lobby_.remove_player(sock);
|
||||
rooms_.exit_lobby(sock);
|
||||
simple_wml::document diff;
|
||||
if(make_change_diff(games_and_users_list_.root(), NULL,
|
||||
"user", pl->second.config_address(), diff)) {
|
||||
lobby_.send_data(diff);
|
||||
rooms_.lobby().send_data(diff);
|
||||
}
|
||||
return;
|
||||
}
|
||||
@ -1801,7 +1801,7 @@ void server::process_data_lobby(const network::connection sock,
|
||||
WRN_SERVER << network::ip_address(sock) << "\t" << pl->second.name()
|
||||
<< "\tattempted to join unknown game:\t" << game_id << ".\n";
|
||||
send_doc(leave_game_doc, sock);
|
||||
lobby_.send_server_message("Attempt to join unknown game.", 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()) {
|
||||
@ -1809,7 +1809,7 @@ void server::process_data_lobby(const network::connection sock,
|
||||
<< "\tattempted to join uninitialized game:\t\"" << (*g)->name()
|
||||
<< "\" (" << game_id << ").\n";
|
||||
send_doc(leave_game_doc, sock);
|
||||
lobby_.send_server_message("Attempt to join an uninitialized game.", sock);
|
||||
rooms_.lobby().send_server_message("Attempt to join an uninitialized game.", sock);
|
||||
send_doc(games_and_users_list_, sock);
|
||||
return;
|
||||
} else if (admin) {
|
||||
@ -1819,7 +1819,7 @@ void server::process_data_lobby(const network::connection sock,
|
||||
<< pl->second.name() << "\tfrom game:\t\"" << (*g)->name()
|
||||
<< "\" (" << game_id << ").\n";
|
||||
send_doc(leave_game_doc, sock);
|
||||
lobby_.send_server_message("You are banned from this game.", 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)) {
|
||||
@ -1827,7 +1827,7 @@ void server::process_data_lobby(const network::connection sock,
|
||||
<< "\tattempted to join game:\t\"" << (*g)->name() << "\" ("
|
||||
<< game_id << ") with bad password\n";
|
||||
send_doc(leave_game_doc, sock);
|
||||
lobby_.send_server_message("Incorrect password.", sock);
|
||||
rooms_.lobby().send_server_message("Incorrect password.", sock);
|
||||
send_doc(games_and_users_list_, sock);
|
||||
return;
|
||||
}
|
||||
@ -1849,11 +1849,11 @@ void server::process_data_lobby(const network::connection sock,
|
||||
<< "\tattempted to observe game:\t\"" << (*g)->name() << "\" ("
|
||||
<< game_id << ") which doesn't allow observers.\n";
|
||||
send_doc(leave_game_doc, sock);
|
||||
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);
|
||||
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);
|
||||
send_doc(games_and_users_list_, sock);
|
||||
return;
|
||||
}
|
||||
lobby_.remove_player(sock);
|
||||
rooms_.exit_lobby(sock);
|
||||
(*g)->describe_slots();
|
||||
|
||||
//send notification of changes to the game and user
|
||||
@ -1863,14 +1863,16 @@ void server::process_data_lobby(const network::connection sock,
|
||||
bool diff2 = make_change_diff(games_and_users_list_.root(), NULL,
|
||||
"user", pl->second.config_address(), diff);
|
||||
if (diff1 || diff2) {
|
||||
lobby_.send_data(diff);
|
||||
rooms_.lobby().send_data(diff);
|
||||
}
|
||||
}
|
||||
|
||||
//TODO: process room joins/quits
|
||||
|
||||
// See if it's a message, in which case we add the name of the sender,
|
||||
// and forward it to all players in the lobby.
|
||||
if (data.child("message")) {
|
||||
lobby_.process_message(data, pl);
|
||||
rooms_.process_message(data, pl);
|
||||
}
|
||||
|
||||
// Player requests update of lobby content,
|
||||
@ -1919,7 +1921,7 @@ void server::process_data_game(const network::connection sock,
|
||||
std::stringstream msg;
|
||||
msg << "This server does not support games with more than "
|
||||
<< gamemap::MAX_PLAYERS << " sides.";
|
||||
lobby_.send_server_message(msg.str().c_str(), sock);
|
||||
rooms_.lobby().send_server_message(msg.str().c_str(), sock);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -2002,7 +2004,7 @@ void server::process_data_game(const network::connection sock,
|
||||
// Send the update of the game description to the lobby.
|
||||
simple_wml::document diff;
|
||||
make_add_diff(*games_and_users_list_.child("gamelist"), "gamelist", "game", diff);
|
||||
lobby_.send_data(diff);
|
||||
rooms_.lobby().send_data(diff);
|
||||
|
||||
/** @todo FIXME: Why not save the level data in the history_? */
|
||||
return;
|
||||
@ -2033,7 +2035,7 @@ void server::process_data_game(const network::connection sock,
|
||||
std::stringstream msg;
|
||||
msg << "This server does not support games with more than "
|
||||
<< gamemap::MAX_PLAYERS << " sides.";
|
||||
lobby_.send_server_message(msg.str().c_str(), sock);
|
||||
rooms_.lobby().send_server_message(msg.str().c_str(), sock);
|
||||
return;
|
||||
}
|
||||
const simple_wml::node& s = *data.child("store_next_scenario");
|
||||
@ -2114,7 +2116,7 @@ void server::process_data_game(const network::connection sock,
|
||||
delete_game(itor);
|
||||
} else {
|
||||
g->remove_player(sock);
|
||||
lobby_.add_player(sock);
|
||||
rooms_.enter_lobby(sock);
|
||||
g->describe_slots();
|
||||
|
||||
// Send all other players in the lobby the update to the gamelist.
|
||||
@ -2124,7 +2126,7 @@ void server::process_data_game(const network::connection sock,
|
||||
bool diff2 = make_change_diff(games_and_users_list_.root(), NULL,
|
||||
"user", pl->second.config_address(), diff);
|
||||
if (diff1 || diff2) {
|
||||
lobby_.send_data(diff, sock);
|
||||
rooms_.lobby().send_data(diff, sock);
|
||||
}
|
||||
|
||||
// Send the player who has quit the gamelist.
|
||||
@ -2179,7 +2181,7 @@ void server::process_data_game(const network::connection sock,
|
||||
(ban ? g->ban_user(*data.child("ban"), pl)
|
||||
: g->kick_member(*data.child("kick"), pl));
|
||||
if (user) {
|
||||
lobby_.add_player(user);
|
||||
rooms_.enter_lobby(user);
|
||||
if (g->describe_slots()) {
|
||||
update_game_in_lobby(g, user);
|
||||
}
|
||||
@ -2195,7 +2197,7 @@ void server::process_data_game(const network::connection sock,
|
||||
make_change_diff(games_and_users_list_.root(), NULL, "user",
|
||||
pl2->second.config_address(), diff);
|
||||
}
|
||||
lobby_.send_data(diff, sock);
|
||||
rooms_.lobby().send_data(diff, sock);
|
||||
// Send the removed user the lobby game list.
|
||||
send_doc(games_and_users_list_, user);
|
||||
}
|
||||
@ -2247,7 +2249,7 @@ void server::delete_game(std::vector<wesnothd::game*>::iterator game_it) {
|
||||
simple_wml::document diff;
|
||||
if(make_delete_diff(*gamelist, "gamelist", "game",
|
||||
(*game_it)->description(), diff)) {
|
||||
lobby_.send_data(diff);
|
||||
rooms_.lobby().send_data(diff);
|
||||
}
|
||||
|
||||
// Delete the game from the games_and_users_list_.
|
||||
@ -2274,7 +2276,7 @@ void server::delete_game(std::vector<wesnothd::game*>::iterator game_it) {
|
||||
simple_wml::document udiff;
|
||||
if (make_change_diff(games_and_users_list_.root(), NULL,
|
||||
"user", pl->second.config_address(), udiff)) {
|
||||
lobby_.send_data(udiff);
|
||||
rooms_.lobby().send_data(udiff);
|
||||
}
|
||||
} else {
|
||||
ERR_SERVER << "ERROR: delete_game(): Could not find user in players_. (socket: "
|
||||
@ -2286,7 +2288,7 @@ void server::delete_game(std::vector<wesnothd::game*>::iterator game_it) {
|
||||
static simple_wml::document leave_game_doc("[leave_game]\n[/leave_game]\n", simple_wml::INIT_COMPRESSED);
|
||||
(*game_it)->send_data(leave_game_doc);
|
||||
// Put the remaining users back in the lobby.
|
||||
lobby_.add_players(**game_it);
|
||||
rooms_.enter_lobby(**game_it);
|
||||
|
||||
(*game_it)->send_data(games_and_users_list_);
|
||||
|
||||
@ -2298,7 +2300,7 @@ void server::update_game_in_lobby(const wesnothd::game* g, network::connection e
|
||||
{
|
||||
simple_wml::document diff;
|
||||
if(make_change_diff(*games_and_users_list_.root().child("gamelist"), "gamelist", "game", g->description(), diff)) {
|
||||
lobby_.send_data(diff, exclude);
|
||||
rooms_.lobby().send_data(diff, exclude);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -4,7 +4,7 @@
|
||||
#include "../network.hpp"
|
||||
#include "ban.hpp"
|
||||
#include "player.hpp"
|
||||
#include "room.hpp"
|
||||
#include "room_manager.hpp"
|
||||
#include "simple_wml.hpp"
|
||||
#include "user_handler.hpp"
|
||||
#include <boost/scoped_ptr.hpp>
|
||||
@ -40,8 +40,7 @@ private:
|
||||
std::vector<wesnothd::game*> games_;
|
||||
std::set<network::connection> not_logged_in_;
|
||||
|
||||
/** The lobby is implemented as a room. */
|
||||
wesnothd::room lobby_;
|
||||
wesnothd::room_manager rooms_;
|
||||
|
||||
/** server socket/fifo. */
|
||||
boost::scoped_ptr<input_stream> input_;
|
||||
|
Loading…
x
Reference in New Issue
Block a user