⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 mod_muc_room.erl

📁 ejabberd-0.7.5 分布式Jabber服务器
💻 ERL
📖 第 1 页 / 共 5 页
字号:
				  add_online_user(From, Nick, Role, StateData)),			    send_new_presence(From, NewState),			    send_existing_presences(From, NewState),			    Shift = count_stanza_shift(Nick, Els, NewState),			    case send_history(From, Shift, NewState) of				true ->				    ok;				_ ->				    send_subject(From, Lang, StateData)			    end,			    case NewState#state.just_created of				true ->				    NewState#state{just_created = false};				false ->				    NewState			    end;			nopass ->			    ErrText = "Password required to enter this room",			    Err = jlib:make_error_reply(				    Packet, ?ERRT_NOT_AUTHORIZED(Lang, ErrText)),			    ejabberd_router:route( % TODO: s/Nick/""/			      jlib:jid_replace_resource(				StateData#state.jid, Nick),			      From, Err),			    StateData;			_ ->			    ErrText = "Incorrect password",			    Err = jlib:make_error_reply(				    Packet, ?ERRT_NOT_AUTHORIZED(Lang, ErrText)),			    ejabberd_router:route( % TODO: s/Nick/""/			      jlib:jid_replace_resource(				StateData#state.jid, Nick),			      From, Err),			    StateData		    end	    end    end.check_password(owner, _Els, _StateData) ->    true;check_password(_Affiliation, Els, StateData) ->    case (StateData#state.config)#config.password_protected of	false ->	    true;	true ->	    Pass = extract_password(Els),	    case Pass of		false ->		    nopass;		_ ->		    case (StateData#state.config)#config.password of			Pass ->			    true;			_ ->			false		    end	    end    end.extract_password([]) ->    false;extract_password([{xmlelement, _Name, Attrs, _SubEls} = El | Els]) ->    case xml:get_attr_s("xmlns", Attrs) of	?NS_MUC ->	    case xml:get_subtag(El, "password") of		false ->		    false;		SubEl ->		    xml:get_tag_cdata(SubEl)	    end;	_ ->	    extract_password(Els)    end;extract_password([_ | Els]) ->    extract_password(Els).count_stanza_shift(Nick, Els, StateData) ->    HL = lqueue_to_list(StateData#state.history),    Since = extract_history(Els, "since"),    Shift0 = case Since of		 false ->		     0;		 _ ->		     Sin = calendar:datetime_to_gregorian_seconds(Since),		     count_seconds_shift(Sin, HL)	     end,    Seconds = extract_history(Els, "seconds"),    Shift1 = case Seconds of		 false ->		     0;		 _ ->		     Sec = calendar:datetime_to_gregorian_seconds(			     calendar:now_to_universal_time(now())) - Seconds,		     count_seconds_shift(Sec, HL)	     end,    MaxStanzas = extract_history(Els, "maxstanzas"),    Shift2 = case MaxStanzas of		 false ->		     0;		 _ ->		     count_maxstanzas_shift(MaxStanzas, HL)	     end,    MaxChars = extract_history(Els, "maxchars"),    Shift3 = case MaxChars of		 false ->		     0;		 _ ->		     count_maxchars_shift(Nick, MaxChars, HL)	     end,       lists:max([Shift0, Shift1, Shift2, Shift3]).count_seconds_shift(Seconds, HistoryList) ->    lists:sum(      lists:map(	fun({_Nick, _Packet, _HaveSubject, TimeStamp, _Size}) ->	    T = calendar:datetime_to_gregorian_seconds(TimeStamp),	    if		T < Seconds ->		    1;		true ->		    0	    end	end, HistoryList)).count_maxstanzas_shift(MaxStanzas, HistoryList) ->    S = length(HistoryList) - MaxStanzas,    if	S =< 0 ->	    0;	true ->	    S    end.count_maxchars_shift(Nick, MaxSize, HistoryList) ->    NLen = string:len(Nick) + 1,    Sizes = lists:map(	      fun({_Nick, _Packet, _HaveSubject, _TimeStamp, Size}) ->		  Size + NLen	      end, HistoryList),    calc_shift(MaxSize, Sizes).calc_shift(MaxSize, Sizes) ->    Total = lists:sum(Sizes),    calc_shift(MaxSize, Total, 0, Sizes).calc_shift(_MaxSize, _Size, Shift, []) ->    Shift;calc_shift(MaxSize, Size, Shift, [S | TSizes]) ->    if	MaxSize >= Size ->	    Shift;	true ->	    calc_shift(MaxSize, Size - S, Shift + 1, TSizes)    end.extract_history([], _Type) ->    false;extract_history([{xmlelement, _Name, Attrs, _SubEls} = El | Els], Type) ->    case xml:get_attr_s("xmlns", Attrs) of	?NS_MUC ->	    AttrVal = xml:get_path_s(El,		       [{elem, "history"}, {attr, Type}]),	    case Type of		"since" ->		    case jlib:datetime_string_to_timestamp(AttrVal) of			undefined ->			    false;			TS ->			    calendar:now_to_universal_time(TS)		    end;		_ ->		    case catch list_to_integer(AttrVal) of			IntVal when is_integer(IntVal) and IntVal >= 0 ->			    IntVal;			_ ->			    false		    end	    end;	_ ->	    extract_history(Els, Type)    end;extract_history([_ | Els], Type) ->    extract_history(Els, Type).send_update_presence(JID, StateData) ->    LJID = jlib:jid_tolower(JID),    LJIDs = case LJID of		{U, S, ""} ->		    ?DICT:fold(		       fun(J, _, Js) ->			       case J of				   {U, S, _} ->				       [J | Js];				   _ ->				       Js			       end		       end, [], StateData#state.users);		_ ->		    case ?DICT:is_key(LJID, StateData#state.users) of			true ->			    [LJID];			_ ->			    []		    end	    end,    lists:foreach(fun(J) ->			  send_new_presence(J, StateData)		  end, LJIDs).send_new_presence(NJID, StateData) ->    {ok, #user{jid = RealJID,	       nick = Nick,	       role = Role,	       last_presence = Presence}} =	?DICT:find(jlib:jid_tolower(NJID), StateData#state.users),    Affiliation = get_affiliation(NJID, StateData),    SAffiliation = affiliation_to_list(Affiliation),    SRole = role_to_list(Role),    lists:foreach(      fun({_LJID, Info}) ->	      ItemAttrs =		  case (Info#user.role == moderator) orelse		      ((StateData#state.config)#config.anonymous == false) of		      true ->			  [{"jid", jlib:jid_to_string(RealJID)},			   {"affiliation", SAffiliation},			   {"role", SRole}];		      _ ->			  [{"affiliation", SAffiliation},			   {"role", SRole}]		  end,	      Status = case StateData#state.just_created of			   true ->			       [{xmlelement, "status", [{"code", "201"}], []}];			   false ->			       []		       end,	      Packet = append_subtags(			 Presence,			 [{xmlelement, "x", [{"xmlns", ?NS_MUC_USER}],			   [{xmlelement, "item", ItemAttrs, []} | Status]}]),	      ejabberd_router:route(		jlib:jid_replace_resource(StateData#state.jid, Nick),		Info#user.jid,		Packet)      end, ?DICT:to_list(StateData#state.users)).send_existing_presences(ToJID, StateData) ->    LToJID = jlib:jid_tolower(ToJID),    {ok, #user{jid = RealToJID,	       role = Role}} =	?DICT:find(LToJID, StateData#state.users),    lists:foreach(      fun({LJID, #user{jid = FromJID,		       nick = FromNick,		       role = FromRole,		       last_presence = Presence		      }}) ->	      case RealToJID of		  FromJID ->		      ok;		  _ ->		      FromAffiliation = get_affiliation(LJID, StateData),		      ItemAttrs =			  case (Role == moderator) orelse			      ((StateData#state.config)#config.anonymous ==			       false) of			      true ->				  [{"jid", jlib:jid_to_string(FromJID)},				   {"affiliation",				    affiliation_to_list(FromAffiliation)},				   {"role", role_to_list(FromRole)}];			      _ ->				  [{"affiliation",				    affiliation_to_list(FromAffiliation)},				   {"role", role_to_list(FromRole)}]			  end,		      Packet = append_subtags(				 Presence,				 [{xmlelement, "x", [{"xmlns", ?NS_MUC_USER}],				   [{xmlelement, "item", ItemAttrs, []}]}]),		      ejabberd_router:route(			jlib:jid_replace_resource(			  StateData#state.jid, FromNick),			RealToJID,			Packet)	      end      end, ?DICT:to_list(StateData#state.users)).append_subtags({xmlelement, Name, Attrs, SubTags1}, SubTags2) ->    {xmlelement, Name, Attrs, SubTags1 ++ SubTags2}.change_nick(JID, Nick, StateData) ->    LJID = jlib:jid_tolower(JID),    {ok, #user{nick = OldNick}} =	?DICT:find(LJID, StateData#state.users),    Users =	?DICT:update(	   LJID,	   fun(#user{} = User) ->		   User#user{nick = Nick}	   end, StateData#state.users),    NewStateData = StateData#state{users = Users},    send_nick_changing(JID, OldNick, NewStateData),    NewStateData.send_nick_changing(JID, OldNick, StateData) ->    {ok, #user{jid = RealJID,	       nick = Nick,	       role = Role,	       last_presence = Presence}} =	?DICT:find(jlib:jid_tolower(JID), StateData#state.users),    Affiliation = get_affiliation(JID, StateData),    SAffiliation = affiliation_to_list(Affiliation),    SRole = role_to_list(Role),    lists:foreach(      fun({_LJID, Info}) ->	      ItemAttrs1 =		  case (Info#user.role == moderator) orelse		      ((StateData#state.config)#config.anonymous == false) of		      true ->			  [{"jid", jlib:jid_to_string(RealJID)},			   {"affiliation", SAffiliation},			   {"role", SRole},			   {"nick", Nick}];		      _ ->			  [{"affiliation", SAffiliation},			   {"role", SRole},			   {"nick", Nick}]		  end,	      ItemAttrs2 =		  case (Info#user.role == moderator) orelse		      ((StateData#state.config)#config.anonymous == false) of		      true ->			  [{"jid", jlib:jid_to_string(RealJID)},			   {"affiliation", SAffiliation},			   {"role", SRole}];		      _ ->			  [{"affiliation", SAffiliation},			   {"role", SRole}]		  end,	      Packet1 =		  {xmlelement, "presence", [{"type", "unavailable"}],		   [{xmlelement, "x", [{"xmlns", ?NS_MUC_USER}],		     [{xmlelement, "item", ItemAttrs1, []},		      {xmlelement, "status", [{"code", "303"}], []}]}]},	      Packet2 = append_subtags(			  Presence,			  [{xmlelement, "x", [{"xmlns", ?NS_MUC_USER}],			    [{xmlelement, "item", ItemAttrs2, []}]}]),	      ejabberd_router:route(		jlib:jid_replace_resource(StateData#state.jid, OldNick),		Info#user.jid,		Packet1),	      ejabberd_router:route(		jlib:jid_replace_resource(StateData#state.jid, Nick),		Info#user.jid,		Packet2)      end, ?DICT:to_list(StateData#state.users)).lqueue_new(Max) ->    #lqueue{queue = queue:new(),	    len = 0,	    max = Max}.lqueue_in(Item, #lqueue{queue = Q1, len = Len, max = Max}) ->    Q2 = queue:in(Item, Q1),    if	Len >= Max ->	    Q3 = lqueue_cut(Q2, Len - Max + 1),	    #lqueue{queue = Q3, len = Max, max = Max};	true ->	    #lqueue{queue = Q2, len = Len + 1, max = Max}    end.lqueue_cut(Q, 0) ->    Q;lqueue_cut(Q, N) ->    {_, Q1} = queue:out(Q),    lqueue_cut(Q1, N - 1).lqueue_to_list(#lqueue{queue = Q1}) ->    queue:to_list(Q1).add_message_to_history(FromNick, Packet, StateData) ->    HaveSubject = case xml:get_subtag(Packet, "subject") of		      false ->			  false;		      _ ->			  true		  end,    TimeStamp = calendar:now_to_universal_time(now()),    TSPacket = append_subtags(Packet,			      [jlib:timestamp_to_xml(TimeStamp)]),    SPacket = jlib:replace_from_to(		jlib:jid_replace_resource(StateData#state.jid, FromNick),		StateData#state.jid,		TSPacket),    Size = lists:flatlength(xml:element_to_string(SPacket)),    Q1 = lqueue_in({FromNick, TSPacket, HaveSubject, TimeStamp, Size},		   StateData#state.history),    StateData#state{history = Q1}.send_history(JID, Shift, StateData) ->    lists:foldl(      fun({Nick, Packet, HaveSubject, _TimeStamp, _Size}, B) ->	      ejabberd_router:route(		jlib:jid_replace_resource(StateData#state.jid, Nick),		JID,		Packet),	      B or HaveSubject      end, false, lists:nthtail(Shift, lqueue_to_list(StateData#state.history))).send_subject(JID, Lang, StateData) ->    case StateData#state.subject_author of	"" ->	    ok;	Nick ->	    Subject = StateData#state.subject,	    Packet = {xmlelement, "message", [{"type", "groupchat"}],		      [{xmlelement, "subject", [], [{xmlcdata, Subject}]},		       {xmlelement, "body", [],			[{xmlcdata,			  Nick ++			  translate:translate(Lang,					      " has set the subject to: ") ++			  Subject}]}]},	    ejabberd_router:route(	      StateData#state.jid,	      JID,	      Packet)    end.check_subject(Packet) ->    case xml:get_subtag(Packet, "subject") of	false ->	    false;	SubjEl ->	    xml:get_tag_cdata(SubjEl)    end.can_change_subject(Role, StateData) ->    case (StateData#state.config)#config.allow_change_subj of	true ->	    (Role == moderator) orelse (Role == participant);	_ ->	    Role == moderator    end.%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -