26 #define ERR_LOBBY LOG_STREAM(err, log_server_lobby)
27 #define WRN_LOBBY LOG_STREAM(warn, log_server_lobby)
28 #define LOG_LOBBY LOG_STREAM(info, log_server_lobby)
29 #define DBG_LOBBY LOG_STREAM(debug, log_server_lobby)
32 #define ERR_SERVER LOG_STREAM(err, log_server)
33 #define WRN_SERVER LOG_STREAM(warn, log_server)
34 #define LOG_SERVER LOG_STREAM(info, log_server)
35 #define DBG_SERVER LOG_STREAM(debug, log_server)
42 : all_players_(all_players)
46 , player_stored_rooms_()
48 , compress_stored_rooms_(true)
49 , new_room_policy_(PP_EVERYONE)
66 if (str ==
"everyone") {
68 }
else if (str ==
"registered") {
70 }
else if (str ==
"admins") {
72 }
else if (str ==
"nobody") {
101 ERR_LOBBY <<
"Duplicate room ignored in stored rooms: "
102 << r->
name() <<
"\n";
124 const room&
r = *
v.second;
157 DBG_LOBBY <<
"Requested creation of already existing room '" << name <<
"'\n";
169 bool can_create =
false;
178 can_create = i->second.registered();
186 can_create = i->second.is_moderator();
226 for (
room*
r : i->second) {
245 for (
room*
r : i->second) {
255 const char *log_string)
260 WRN_LOBBY <<
"Player " << user->second.name()
261 <<
" (conn " << user->first <<
")"
262 <<
" attempted to " << log_string
263 <<
"a nonexistent room '" << room_name <<
"'\n";
271 const char *log_string)
274 if (r ==
nullptr)
return nullptr;
277 WRN_LOBBY <<
"Player " << user->second.name()
278 <<
" (conn " << user->first <<
")"
279 <<
" attempted to " << log_string
280 <<
"room '" << room_name <<
"', but is not a member of that room\n";
310 if (i->second.size() < 1) {
315 std::set<std::string>&
store = it->second;
316 for (
room*
r : i->second) {
317 store.insert(r->
name());
337 join_msg.
set_attr_dup(
"player", user->second.name().c_str());
341 LOG_LOBBY <<
"Player " << user->second.name() <<
" unable to rejoin room " << room_name <<
"\n";
350 send_to_one(doc, user->first);
358 message->
set_attr_dup(
"sender", user->second.name().c_str());
363 std::stringstream ss;
364 ss <<
"You are not a member of the room '" << room_name <<
"'. "
365 <<
"Your message has not been relayed.";
369 if (user->second.is_message_flooding()) {
371 "Warning: you are sending too many messages too fast. "
372 "Your message has not been relayed.", user->first);
380 <<
"\t<" << user->second.name()
385 << user->second.name() <<
"> " << msg <<
"\n";
388 r->
send_data(data, user->first,
"message");
404 msg->
set_attr_dup(
"player", user->second.name().c_str());
409 send_to_one(data, user->first);
422 if (r ==
nullptr)
return;
424 msg->
set_attr_dup(
"player", user->second.name().c_str());
427 LOG_LOBBY <<
"Last player left room " << room_name <<
". Deleting room.\n";
431 send_to_one(data, user->first);
441 q = msg->
child(
"rooms");
444 send_to_one(doc, user->first);
452 if (r ==
nullptr)
return;
454 q = msg->
child(
"names");
457 send_to_one(doc, user->first);
460 q = msg->
child(
"persist");
462 if (user->second.is_moderator()) {
463 WRN_LOBBY <<
"Attempted room set persistent by non-moderator";
467 resp.
set_attr(
"message",
"Room is persistent.");
469 resp.
set_attr(
"message",
"Room is not persistent.");
473 resp.
set_attr(
"message",
"Room set as persistent.");
477 resp.
set_attr(
"message",
"Room set as not persistent.");
480 send_to_one(doc, user->first);
484 q = msg->
child(
"logged");
486 if (user->second.is_moderator()) {
487 WRN_LOBBY <<
"Attempted room set logged by non-moderator.";
491 resp.
set_attr(
"message",
"Room is logged.");
493 resp.
set_attr(
"message",
"Room is not logged.");
497 resp.
set_attr(
"message",
"Room set as logged.");
501 resp.
set_attr(
"message",
"Room set as not logged.");
504 send_to_one(doc, user->first);
508 q = msg->
child(
"topic");
512 send_to_one(doc, user->first);
514 if (user->second.is_moderator()) {
515 WRN_LOBBY <<
"Attempted room set topic by non-moderator.";
518 resp.
set_attr(
"message",
"Room topic changed.");
519 send_to_one(doc, user->first);
530 const room&
r = *tr.second;
node & add_child(const char *name)
void process_room_part(simple_wml::document &data, const player_map::iterator user)
Process a player's request to leave a room.
child_itors child_range(const std::string &key)
void process_message(simple_wml::document &data, const player_map::iterator user)
Process a message (chat message) sent to a room.
static lg::log_domain log_server("server")
t_rooms_by_name_ rooms_by_name_
static PRIVILEGE_POLICY pp_from_string(const std::string &str)
void write(const config &cfg)
std::string to_string() const
void set_logged(bool v)
Set the room's logged flag.
const std::string & topic() const
This room's topic/motd, sent to all joining players.
room * lobby_
The lobby-room, treated separetely.
void fill_member_list(const room *room, simple_wml::node &root)
Fill a wml node (message) with members of a room.
bool is_member(network::connection player) const
Membership checker.
const std::string & name() const
The name of this room.
void unstore_player_rooms(const player_map::iterator user)
Unstores (rejoins) player's rooms that were previously stored.
void player_exits_room(network::connection player, room *room)
Removes a player from a room, maintaining internal consistency.
void send_server_message(const char *message, network::connection sock, simple_wml::document *docptr=nullptr) const
Prepare a text message and/or send it to a player.
node & set_attr(const char *key, const char *value)
std::string filename_
Persistent room storage filename.
const user_vector all_game_users() const
Adds players and observers into one vector and returns that.
void store_player_rooms(network::connection player)
Stores the room names (other than lobby) of the given player for future use (rejoin) ...
GLint GLenum GLsizei GLint GLsizei const GLvoid * data
void fill_room_list(simple_wml::node &root)
Fill a wml node (message) with a room list.
room_manager(player_map &all_players)
Room manager constructor.
void read_gz(config &cfg, std::istream &file, abstract_validator *validator)
might throw a std::ios_base::failure especially a gzip_error
bool in_lobby(network::connection player) const
std::map< network::connection, player > player_map
~room_manager()
Room manager destructor.
GLdouble GLdouble GLdouble GLdouble q
node * child(const char *name)
room * get_room(const std::string &name)
Get a room by name, or nullptr if it does not exist.
static lg::log_domain log_server_lobby("server/lobby")
void remove_player(network::connection player)
Leaving the room.
room * require_member(const std::string &room_name, const player_map::iterator user, const char *log_string="use")
Check if the room exists and if the player is a member, log failures.
void truncate_message(const simple_wml::string_span &str, simple_wml::node &message)
Function to ensure a text message is within the allowed length.
t_rooms_by_player_ rooms_by_player_
A room is a group of players that can communicate via messages.
void read_rooms()
Reads stored rooms from a file on disk, or returns immediately if load_config was not called before o...
void send_data(simple_wml::document &data, const network::connection exclude=0, std::string packet_type="") const
Convenience function for sending a wml document to all (or all except one) members.
Class for writing a config out to a file in pieces.
void process_room_join(simple_wml::document &data, const player_map::iterator user)
Process a player's request to join a room.
bool add_player(network::connection player)
Joining the room.
void remove_child(const char *name, size_t index)
std::istream * istream_file(const std::string &fname, bool treat_failure_as_error=true)
bool compress_stored_rooms_
Flag controlling whether to compress the stored rooms or not.
std::ostream * ostream_file(std::string const &fname, bool create_directory=true)
room * get_create_room(const std::string &name, network::connection player)
Get a room by name or create that room if it does not exist and creating rooms is allowed...
config & add_child(const std::string &key)
Templates and utility-routines for strings and numbers.
PRIVILEGE_POLICY new_room_policy_
Policy regarding who can create new rooms.
void exit_lobby(network::connection player)
Player exits lobby.
void set_persistent(bool v)
Set the persistent flag for this room.
room * require_room(const std::string &room_name, const player_map::iterator user, const char *log_string="use")
Check if the room exists, log failures.
void load_config(const config &cfg)
Load settings from the main config file.
node & set_attr_dup(const char *key, const char *value)
void write_rooms()
Writes rooms to the storage file or returns immediately if load_config was not called beforethe stora...
void process_room_query(simple_wml::document &data, const player_map::iterator user)
Process a general room query.
static void msg(const char *act, debug_info &i, const char *to="", const char *result="")
void write(config &cfg) const
Write room info to a config.
Declarations for File-IO.
void read(config &cfg, std::istream &in, abstract_validator *validator)
static int writer(lua_State *L, const void *b, size_t size, void *B)
bool to_bool(bool default_value=false) const
GLdouble GLdouble GLdouble r
player_map & all_players_
Reference to the all players map.
const char * begin() const
GLuint const GLchar * name
bool dirty_
'Dirty' flag with regards to room info that will be stored on disk
void remove_player(network::connection player)
Remove info abut given player from all rooms.
std::string ip_address(connection connection_num)
Function to get the remote ip address of a socket.
static const char *const lobby_name_
The main (lobby) room name.
bool player_enters_room(network::connection player, room *room)
Adds a player to a room, maintaining internal consistency Will send appropriate error messages to the...
Standard logging facilities (interface).
bool persistent() const
Whether this room should be 'persistent', i.e.
void enter_lobby(network::connection player)
Player-enters-lobby action.
GLsizei GLenum GLuint GLuint GLsizei char * message
bool room_exists(const std::string &name) const
A config object defines a single node in a WML file, with access to child nodes.
bool logged() const
Whether the room is logged (and might end up in e.g.
bool empty() const
Return true iif the room is empty.
bool file_exists(const std::string &name)
Returns true if a file or directory with such name already exists.
void set_topic(const std::string &v)
Set the topic for this room.
GLsizei const GLcharARB ** string
t_player_stored_rooms_ player_stored_rooms_
const string_span & attr(const char *key) const
const std::vector< network::connection > & members() const
Return the members of this room.
room * create_room(const std::string &name)
Create room named "name" if it does not exist already.