mp: Implement whisper_friends_only option in GUI1 lobby with a periodic warning

This option was already implemented in the GUI2 lobby (without a
warning), which resulted in a misleading advanced preferences entry.
(Forum thread: <http://r.wesnoth.org/t42423>)

The warning works as follows: you get alerted of individual clients
trying to contact you while you have this option enabled, but you'll
only get the alerts every 5 minutes. This seems like a fair compromise
between dealing with abuse and reminding people that this option is
enabled in case they accidentally did so or only intended to do so
temporarily. Also, if the sender is in the ignore list, this will not
produce a warning.
This commit is contained in:
Ignacio R. Morelle 2015-06-05 00:17:33 -03:00
parent 7339dc9a12
commit 7be7e3ce8c
4 changed files with 57 additions and 1 deletions

View file

@ -11,6 +11,9 @@ Version 1.12.2+dev:
* Multiplayer:
* Removed the Silver Mage from the available leaders for the Rebels faction
in Age of Heroes.
* Fixed "Accept whispers from friends only" not working with the default
lobby UI, and added a warning every 5 minutes for individual rejected
senders.
* User interface:
* Fixed minimap buttons appearing without contents or in the wrong state
during WML start events until they are interacted with or control is given

View file

@ -12,6 +12,9 @@ Version 1.12.2+dev:
* Multiplayer:
* Removed the Silver Mage from the available leaders for the Rebels faction
in Age of Heroes.
* Fixed "Accept whispers from friends only" not working with the default
lobby UI, and added a warning every 5 minutes for individual rejected
senders.
* User interface:
* Fixed minimap buttons appearing without contents or in the wrong state

View file

@ -185,7 +185,8 @@ ui::ui(game_display& disp, const std::string& title, const config& cfg, chat& c,
result_(CONTINUE),
gamelist_refresh_(false),
lobby_clock_(0)
lobby_clock_(0),
whisper_warnings_()
{
const SDL_Rect area = create_rect(0
, 0
@ -412,6 +413,53 @@ void ui::process_message(const config& msg, const bool whisper) {
if (!preferences::parse_should_show_lobby_join(sender, message)) return;
if (preferences::is_ignored(sender)) return;
// Warn about people trying to whisper a player with the
// whisper_friends_only option enabled.
if (whisper &&
preferences::whisper_friends_only() &&
sender != "server" &&
sender.find(' ') == std::string::npos && // "server message from foo"
!preferences::is_friend(sender))
{
LOG_NW << "Accepting whispers from friends only, ignored whisper from " << sender << '\n';
typedef std::map<std::string, time_t> timetable;
timetable::const_iterator i = whisper_warnings_.find(sender);
time_t last_warning = 0;
const time_t cur_time = time(NULL);
static const time_t warning_duration = 5 * 60;
if (i != whisper_warnings_.end()) {
last_warning = i->second;
}
//
// Don't warn if it's been less than warning_duration seconds since
// the last warning. Also, make sure the clock isn't running backwards,
// warn anyway if it is.
//
// We don't need to hande the case where preferences change between
// whispers because the lobby instance gets recreated along with the
// table after closing the preferences dialog.
//
if (last_warning && last_warning < cur_time && cur_time - last_warning < warning_duration) {
return;
}
utils::string_map symbols;
symbols["sender"] = sender;
chat_.add_message(cur_time,
"server",
VGETTEXT("$sender is messaging you, and you accept whispers from friends only.", symbols));
chat_.update_textbox(chat_textbox_);
whisper_warnings_[sender] = cur_time;
return;
}
preferences::parse_admin_authentication(sender, message);
if (whisper || utils::word_match(message, preferences::login())) {

View file

@ -239,6 +239,8 @@ private:
Uint32 lobby_clock_;
std::map<std::string, time_t> whisper_warnings_;
public:
enum user_relation { ME, FRIEND, NEUTRAL, IGNORED };
enum user_state { LOBBY, GAME, SEL_GAME };