1 /*
2    Copyright (C) 2009 - 2018 by Tomasz Sniatowski <kailoran@gmail.com>
3    Part of the Battle for Wesnoth Project https://www.wesnoth.org/
4 
5    This program is free software; you can redistribute it and/or modify
6    it under the terms of the GNU General Public License as published by
7    the Free Software Foundation; either version 2 of the License, or
8    (at your option) any later version.
9    This program is distributed in the hope that it will be useful,
10    but WITHOUT ANY WARRANTY.
11 
12    See the COPYING file for more details.
13 */
14 
15 #pragma once
16 
17 #include "config.hpp"
18 #include "game_initialization/lobby_data.hpp"
19 
20 #include <boost/dynamic_bitset.hpp>
21 
22 #include <memory>
23 
24 namespace mp
25 {
26 /**
27  * This class represents the collective information the client has
28  * about the players and games on the server
29  */
30 class lobby_info
31 {
32 public:
33 	explicit lobby_info(const std::vector<std::string>& installed_addons);
34 
35 	typedef std::map<int, game_info> game_info_map;
36 
37 	/** Process a full game list. Current info is discarded. */
38 	void process_gamelist(const config& data);
39 
40 	/**
41 	 * Process a gamelist diff.
42 	 *
43 	 * @param data            Raw game list data, usually received from the MP server.
44 	 *
45 	 * @returns               True on success, false on failure (e.g. when the diff did
46 	 *                        not apply correctly).
47 	 */
48 	bool process_gamelist_diff(const config& data);
49 
50 	bool process_gamelist_diff_impl(const config& data);
51 
52 	void sync_games_display_status();
53 
54 	/**
55 	 * Generates a new vector of game pointers from the ID/game map.
56 	 * The games will be referenced in ascending order by ID.
57 	 */
58 	void make_games_vector();
59 
60 	/** Returns the raw game list config data. */
gamelist() const61 	const config& gamelist() const
62 	{
63 		return gamelist_;
64 	}
65 
66 	using game_filter_func = std::function<bool(const game_info&)>;
67 
68 	/** Adds a new filter function to be considered when @ref apply_game_filter is called. */
add_game_filter(game_filter_func func)69 	void add_game_filter(game_filter_func func)
70 	{
71 		game_filters_.push_back(func);
72 	}
73 
74 	/** Clears all game filter functions. */
clear_game_filter()75 	void clear_game_filter()
76 	{
77 		game_filters_.clear();
78 	}
79 
80 	/** Sets whether the result of each game filter should be inverted. */
set_game_filter_invert(bool value)81 	void set_game_filter_invert(bool value)
82 	{
83 		game_filter_invert_ = value;
84 	}
85 
86 	/** Generates a new list of games that match the current filter functions and inversion setting. */
87 	void apply_game_filter();
88 
89 	/** Returns info on a game with the given game ID. */
90 	game_info* get_game_by_id(int id);
91 
92 	/** Const overload of @ref get_game_by_id. */
93 	const game_info* get_game_by_id(int id) const;
94 
95 	/** Open a new chat room with the given name. */
96 	void open_room(const std::string& name);
97 
98 	/** Close the chat room with the given name. */
99 	void close_room(const std::string& name);
100 
101 	/** Returns whether a room with the given name has been opened. */
102 	bool has_room(const std::string& name) const;
103 
104 	/** Returns info on room with the given name, or nullptr if it doesn't exist. */
105 	room_info* get_room(const std::string& name);
106 
107 	/** Const overload of @ref get_room. */
108 	const room_info* get_room(const std::string& name) const;
109 
110 	/** Returns info on the user with the given name, or nullptr if they don't eixst. */
111 	user_info* get_user(const std::string& name);
112 
get_whisper_log(const std::string & name)113 	chat_session& get_whisper_log(const std::string& name)
114 	{
115 		return whispers_[name];
116 	}
117 
118 	void update_user_statuses(int game_id, const room_info* room);
119 
rooms() const120 	const std::vector<room_info>& rooms() const
121 	{
122 		return rooms_;
123 	}
124 
games() const125 	const std::vector<game_info*>& games() const
126 	{
127 		return games_;
128 	}
129 
games_visibility() const130 	const boost::dynamic_bitset<>& games_visibility() const
131 	{
132 		return games_visibility_;
133 	}
134 
users() const135 	const std::vector<user_info>& users() const
136 	{
137 		return users_;
138 	}
139 
users()140 	std::vector<user_info>& users()
141 	{
142 		return users_;
143 	}
144 
gamelist_initialized() const145 	bool gamelist_initialized() const
146 	{
147 		return gamelist_initialized_;
148 	}
149 private:
150 	void process_userlist();
151 
152 	const std::vector<std::string>& installed_addons_;
153 
154 	config gamelist_;
155 
156 	bool gamelist_initialized_;
157 
158 	std::vector<room_info> rooms_;
159 
160 	game_info_map games_by_id_;
161 
162 	std::vector<game_info*> games_;
163 
164 	std::vector<user_info> users_;
165 
166 	std::map<std::string, chat_session> whispers_;
167 
168 	std::vector<game_filter_func> game_filters_;
169 
170 	bool game_filter_invert_;
171 
172 	boost::dynamic_bitset<> games_visibility_;
173 };
174 
175 enum notify_mode {
176 	NOTIFY_NONE,
177 	NOTIFY_MESSAGE,
178 	NOTIFY_MESSAGE_OTHER_WINDOW,
179 	NOTIFY_SERVER_MESSAGE,
180 	NOTIFY_OWN_NICK,
181 	NOTIFY_FRIEND_MESSAGE,
182 	NOTIFY_WHISPER,
183 	NOTIFY_WHISPER_OTHER_WINDOW,
184 	NOTIFY_LOBBY_JOIN,
185 	NOTIFY_LOBBY_QUIT,
186 	NOTIFY_GAME_CREATED
187 };
188 
189 void do_notify(notify_mode mode, const std::string& sender = "", const std::string& message = "");
190 }
191