aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorMaxim Ignatenko <gelraen.ua@gmail.com>2011-07-28 20:40:46 +0300
committerMaxim Ignatenko <gelraen.ua@gmail.com>2011-09-26 11:16:28 +0300
commit5921f9c506f2a2c11160a7465a70a24d3cb2be5f (patch)
tree6862ea7d58613480dc93271262dcb4b7417bdbe9 /src
parentVoice approvement support (diff)
Simple rate control
Visitor allowed to send new voice request only after specified amount of time (or after rejoining).
Diffstat (limited to 'src')
-rw-r--r--src/mod_muc/mod_muc_room.erl67
-rw-r--r--src/mod_muc/mod_muc_room.hrl1
2 files changed, 58 insertions, 10 deletions
diff --git a/src/mod_muc/mod_muc_room.erl b/src/mod_muc/mod_muc_room.erl
index 3e61f80d8..c54af83d2 100644
--- a/src/mod_muc/mod_muc_room.erl
+++ b/src/mod_muc/mod_muc_room.erl
@@ -298,23 +298,39 @@ normal_state({route, From, "",
end
end;
IsVoiceRequest ->
- case is_visitor(From, StateData) of
+ NewStateData = case is_visitor(From, StateData) of
true ->
- send_voice_request(From, StateData);
+ MinInterval = 1800,
+ FromNick = find_nick_by_jid(From, StateData),
+ LastTime = last_voice_request_time(FromNick, StateData),
+ {MegaSecs, Secs, _} = erlang:now(),
+ Now = MegaSecs * 1000000 + Secs,
+ if
+ timer:now_diff(LastTime, erlang:now()) > MinInterval*1000000 ->
+ send_voice_request(From, StateData),
+ update_voice_request_time(FromNick, StateData);
+ true ->
+ ErrText = "Please, wait for a while before sending new voice request",
+ Err = jlib:make_error_reply(
+ Packet, ?ERRT_NOT_ACCEPTABLE(Lang, ErrText)),
+ ejabberd_router:route(
+ StateData#state.jid, From, Err),
+ StateData
+ end;
_ ->
ErrText = "Only visitors allowed to request voice",
Err = jlib:make_error_reply(
Packet, ?ERRT_NOT_ALLOWED(Lang, ErrText)),
ejabberd_router:route(
- StateData#state.jid, From, Err)
+ StateData#state.jid, From, Err),
+ StateData
end,
- {next_state, normal_state, StateData};
+ {next_state, normal_state, NewStateData};
IsVoiceApprovement ->
NewStateData = case is_moderator(From, StateData) of
true ->
case extract_jid_from_voice_approvement(Els) of
{error, X} ->
- ?ERROR_MSG("Failed to extract JID from voice approvement: ~n~p", [X]),
ErrText = "Failed to extract JID from your voice request approvement",
Err = jlib:make_error_reply(
Packet, ?ERRT_BAD_REQUEST(Lang, ErrText)),
@@ -1533,7 +1549,9 @@ remove_online_user(JID, StateData, Reason) ->
error ->
StateData#state.nicks
end,
- StateData#state{users = Users, nicks = Nicks}.
+ LastTimes = ?DICT:erase(Nick, StateData#state.last_voice_request_time),
+ StateData#state{users = Users, nicks = Nicks,
+ last_voice_request_time = LastTimes}.
filter_presence({xmlelement, "presence", Attrs, Els}) ->
@@ -1641,6 +1659,12 @@ get_priority_from_presence(PresencePacket) ->
end
end.
+find_nick_by_jid(Jid, StateData) ->
+ [{_, #user{nick = Nick}}] = lists:filter(
+ fun({_, #user{jid = FJid}}) -> FJid == Jid end,
+ ?DICT:to_list(StateData#state.users)),
+ Nick.
+
is_nick_change(JID, Nick, StateData) ->
LJID = jlib:jid_tolower(JID),
case Nick of
@@ -2169,7 +2193,18 @@ change_nick(JID, Nick, StateData) ->
?DICT:store(OldNick, OldNickUsers -- [LJID],
StateData#state.nicks))
end,
- NewStateData = StateData#state{users = Users, nicks = Nicks},
+ LastTimes =
+ case ?DICT:find(OldNick, StateData#state.last_voice_request_time) of
+ {ok, Time} ->
+ ?DICT:store(
+ Nick, Time,
+ ?DICT:erase(OldNick, StateData#state.last_voice_request_time)
+ );
+ error ->
+ StateData#state.last_voice_request_time
+ end,
+ NewStateData = StateData#state{users = Users, nicks = Nicks,
+ last_voice_request_time = LastTimes},
send_nick_changing(JID, OldNick, NewStateData, SendOldUnavailable, SendNewAvailable),
add_to_log(nickchange, {OldNick, Nick}, StateData),
NewStateData.
@@ -3737,9 +3772,7 @@ prepare_request_form(Requester, Nick, Lang) ->
send_voice_request(From, StateData) ->
Moderators = search_role(moderator, StateData),
- [{_, #user{nick = FromNick}}] = lists:filter(
- fun({_, #user{jid = Jid}}) -> Jid == From end,
- ?DICT:to_list(StateData#state.users)),
+ FromNick = find_nick_by_jid(From, StateData),
lists:map(
fun({_, User}) ->
ejabberd_router:route(
@@ -3826,6 +3859,20 @@ extract_jid_from_voice_approvement(Els) ->
{error, X}
end.
+last_voice_request_time(Nick, StateData) ->
+ case ?DICT:find(Nick, StateData#state.last_voice_request_time) of
+ {ok, Value} ->
+ Value;
+ error ->
+ 0
+ end.
+
+update_voice_request_time(Nick, StateData) ->
+ {MegaSecs, Secs, _} = erlang:now(),
+ Time = MegaSecs * 1000000 + Secs,
+ NewDict = ?DICT:store(Nick, Time, StateData#state.last_voice_request_time),
+ StateData#state{last_voice_request_time = NewDict}.
+
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Invitation support
diff --git a/src/mod_muc/mod_muc_room.hrl b/src/mod_muc/mod_muc_room.hrl
index 10120cba6..abbc1870e 100644
--- a/src/mod_muc/mod_muc_room.hrl
+++ b/src/mod_muc/mod_muc_room.hrl
@@ -69,6 +69,7 @@
jid,
config = #config{},
users = ?DICT:new(),
+ last_voice_request_time = ?DICT:new(),
robots = ?DICT:new(),
nicks = ?DICT:new(),
affiliations = ?DICT:new(),