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

📄 mod_muc_room.erl

📁 ejabberd-0.7.5 分布式Jabber服务器
💻 ERL
📖 第 1 页 / 共 5 页
字号:
				    ejabberd_router:route(					jlib:jid_replace_resource(					    StateData#state.jid,					    ToNick),					From, Err);				ToJID ->				    {ok, #user{nick = FromNick}} =					?DICT:find(jlib:jid_tolower(From),						StateData#state.users),				    ejabberd_router:route(					jlib:jid_replace_resource(					    StateData#state.jid,					    FromNick),					ToJID, Packet)			    end		    end;		_ ->		    ErrText = "Only occupants are allowed to send messages to the conference",		    Err = jlib:make_error_reply(			    Packet, ?ERRT_NOT_ACCEPTABLE(Lang, ErrText)),		    ejabberd_router:route(			jlib:jid_replace_resource(			    StateData#state.jid,			    ToNick),			From, Err)	    end,	    {next_state, normal_state, StateData}    end;normal_state({route, From, ToNick,	      {xmlelement, "iq", Attrs, _Els} = Packet},	     StateData) ->    Lang = xml:get_attr_s("xml:lang", Attrs),    case {(StateData#state.config)#config.allow_query_users,	  is_user_online(From, StateData)} of	{true, true} ->	    case find_jid_by_nick(ToNick, StateData) of		false ->		    case jlib:iq_query_info(Packet) of			reply ->			    ok;			_ ->			    ErrText = "Recipient is not in the conference room",			    Err = jlib:make_error_reply(				    Packet, ?ERRT_ITEM_NOT_FOUND(Lang, ErrText)),			    ejabberd_router:route(			      jlib:jid_replace_resource(				StateData#state.jid, ToNick),			      From, Err)		    end;		ToJID ->		    {ok, #user{nick = FromNick}} =			?DICT:find(jlib:jid_tolower(From),				   StateData#state.users),		    ejabberd_router:route(		      jlib:jid_replace_resource(StateData#state.jid, FromNick),		      ToJID, Packet)	    end;	{_, false} ->	    case jlib:iq_query_info(Packet) of		reply ->		    ok;		_ ->		    ErrText = "Only occupants are allowed to send queries to the conference",		    Err = jlib:make_error_reply(			    Packet, ?ERRT_NOT_ACCEPTABLE(Lang, ErrText)),		    ejabberd_router:route(		      jlib:jid_replace_resource(StateData#state.jid, ToNick),		      From, Err)	    end;	_ ->	    case jlib:iq_query_info(Packet) of		reply ->		    ok;		_ ->		    ErrText = "Queries to the conference members are not allowed in this room",		    Err = jlib:make_error_reply(			    Packet, ?ERRT_NOT_ALLOWED(Lang, ErrText)),		    ejabberd_router:route(		      jlib:jid_replace_resource(StateData#state.jid, ToNick),		      From, Err)	    end    end,    {next_state, normal_state, StateData};normal_state(Event, StateData) ->    io:format("MUC: unknown event ~p~n", [Event]),    {next_state, normal_state, StateData}.%%----------------------------------------------------------------------%% Func: handle_event/3%% Returns: {next_state, NextStateName, NextStateData}          |%%          {next_state, NextStateName, NextStateData, Timeout} |%%          {stop, Reason, NewStateData}                         %%----------------------------------------------------------------------handle_event({service_message, Msg}, _StateName, StateData) ->    MessagePkt = {xmlelement, "message",		  [{"type", "groupchat"}],		  [{xmlelement, "body", [], [{xmlcdata, Msg}]}]},    lists:foreach(      fun({_LJID, Info}) ->	      ejabberd_router:route(		StateData#state.jid,		Info#user.jid,		MessagePkt)      end,      ?DICT:to_list(StateData#state.users)),    NSD = add_message_to_history("",				 MessagePkt,				 StateData),    {next_state, normal_state, NSD};handle_event(_Event, StateName, StateData) ->    {next_state, StateName, StateData}.%%----------------------------------------------------------------------%% Func: handle_sync_event/4%% Returns: {next_state, NextStateName, NextStateData}            |%%          {next_state, NextStateName, NextStateData, Timeout}   |%%          {reply, Reply, NextStateName, NextStateData}          |%%          {reply, Reply, NextStateName, NextStateData, Timeout} |%%          {stop, Reason, NewStateData}                          |%%          {stop, Reason, Reply, NewStateData}                    %%----------------------------------------------------------------------handle_sync_event({get_disco_item, JID, Lang}, _From, StateName, StateData) ->    FAffiliation = get_affiliation(JID, StateData),    FRole = get_role(JID, StateData),    Tail =	case ((StateData#state.config)#config.public_list == true) orelse	    (FRole /= none) orelse	    (FAffiliation == admin) orelse	    (FAffiliation == owner) of	    true ->		Desc = case (StateData#state.config)#config.public of			   true ->			       "";			   _ ->			       translate:translate(Lang, "private, ")		       end,		Len = length(?DICT:to_list(StateData#state.users)),		" (" ++ Desc ++ integer_to_list(Len) ++ ")";	    _ ->		""	end,    Reply = case ((StateData#state.config)#config.public == true) orelse		(FRole /= none) orelse		(FAffiliation == admin) orelse		(FAffiliation == owner) of		true ->		    {item, get_title(StateData) ++ Tail};		_ ->		    false	    end,    {reply, Reply, StateName, StateData};handle_sync_event(_Event, _From, StateName, StateData) ->    Reply = ok,    {reply, Reply, StateName, StateData}.code_change(_OldVsn, StateName, StateData, _Extra) ->    {ok, StateName, StateData}.%%----------------------------------------------------------------------%% Func: handle_info/3%% Returns: {next_state, NextStateName, NextStateData}          |%%          {next_state, NextStateName, NextStateData, Timeout} |%%          {stop, Reason, NewStateData}                         %%----------------------------------------------------------------------handle_info(_Info, StateName, StateData) ->    {next_state, StateName, StateData}.%%----------------------------------------------------------------------%% Func: terminate/3%% Purpose: Shutdown the fsm%% Returns: any%%----------------------------------------------------------------------terminate(_Reason, _StateName, StateData) ->    mod_muc:room_destroyed(StateData#state.room),    ok.%%%----------------------------------------------------------------------%%% Internal functions%%%----------------------------------------------------------------------route(Pid, From, ToNick, Packet) ->    gen_fsm:send_event(Pid, {route, From, ToNick, Packet}).is_user_online(JID, StateData) ->    LJID = jlib:jid_tolower(JID),    ?DICT:is_key(LJID, StateData#state.users).role_to_list(Role) ->    case Role of	moderator ->   "moderator";	participant -> "participant";	visitor ->     "visitor";	none ->        "none"    end.affiliation_to_list(Affiliation) ->    case Affiliation of	owner ->   "owner";	admin ->   "admin";	member ->  "member";	outcast -> "outcast";	none ->    "none"    end.list_to_role(Role) ->    case Role of	"moderator" ->   moderator;	"participant" -> participant;	"visitor" ->     visitor;	"none" ->        none    end.list_to_affiliation(Affiliation) ->    case Affiliation of	"owner" ->   owner;	"admin" ->   admin;	"member" ->  member;	"outcast" -> outcast;	"none" ->    none    end.set_affiliation(JID, Affiliation, StateData) ->    LJID = jlib:jid_remove_resource(jlib:jid_tolower(JID)),    Affiliations = case Affiliation of		       none ->			   ?DICT:erase(LJID,				       StateData#state.affiliations);		       _ ->			   ?DICT:store(LJID,				       Affiliation,				       StateData#state.affiliations)		   end,    StateData#state{affiliations = Affiliations}.get_affiliation(JID, StateData) ->    {_AccessRoute, _AccessCreate, AccessAdmin} = StateData#state.access,    case acl:match_rule(AccessAdmin, JID) of	allow ->	    owner;	_ ->	    LJID = jlib:jid_remove_resource(jlib:jid_tolower(JID)),	    case ?DICT:find(LJID, StateData#state.affiliations) of		{ok, Affiliation} ->		    Affiliation;		_ ->		    none	    end    end.set_role(JID, Role, 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,    Users = case Role of		none ->		    lists:foldl(fun(J, Us) ->					?DICT:erase(J,						    Us)				end, StateData#state.users, LJIDs);		_ ->		    lists:foldl(fun(J, Us) ->					{ok, User} = ?DICT:find(J, Us),					?DICT:store(J,						    User#user{role = Role},						    Us)				end, StateData#state.users, LJIDs)	    end,    StateData#state{users = Users}.get_role(JID, StateData) ->    LJID = jlib:jid_tolower(JID),    case ?DICT:find(LJID, StateData#state.users) of	{ok, #user{role = Role}} ->	    Role;	_ ->	    none    end.get_default_role(Affiliation, StateData) ->    case Affiliation of	owner ->   moderator;	admin ->   moderator;	member ->  participant;	outcast -> none;	none ->	    case (StateData#state.config)#config.members_only of		true ->		    none;		_ ->		    case (StateData#state.config)#config.members_by_default of			true ->			    participant;			_ ->			    visitor		    end	    end    end.add_online_user(JID, Nick, Role, StateData) ->    LJID = jlib:jid_tolower(JID),    Users = ?DICT:store(LJID,			#user{jid = JID,			      nick = Nick,			      role = Role},			StateData#state.users),    StateData#state{users = Users}.remove_online_user(JID, StateData) ->    LJID = jlib:jid_tolower(JID),    Users = ?DICT:erase(LJID, StateData#state.users),    StateData#state{users = Users}.filter_presence({xmlelement, "presence", Attrs, Els}) ->    FEls = lists:filter(	     fun(El) ->		     case El of			 {xmlcdata, _} ->			     false;			 {xmlelement, Name1, _Attrs1, _Els1} ->			     XMLNS = xml:get_attr_s("xmlns", Attrs),			     case {Name1, XMLNS} of				 {"show", ""} ->				     true;				 {"status", ""} ->				     true;				 _ ->				     false			     end		     end	     end, Els),    {xmlelement, "presence", Attrs, FEls}.add_user_presence(JID, Presence, StateData) ->    LJID = jlib:jid_tolower(JID),    FPresence = filter_presence(Presence),    Users =	?DICT:update(	   LJID,	   fun(#user{} = User) ->		   User#user{last_presence = FPresence}	   end, StateData#state.users),    StateData#state{users = Users}.add_user_presence_un(JID, Presence, StateData) ->    LJID = jlib:jid_tolower(JID),    FPresence = filter_presence(Presence),    Users =	?DICT:update(	   LJID,	   fun(#user{} = User) ->		   User#user{last_presence = FPresence,			     role = none}	   end, StateData#state.users),    StateData#state{users = Users}.is_nick_exists(Nick, StateData) ->    ?DICT:fold(fun(_, #user{nick = N}, B) ->		       B orelse (N == Nick)	       end, false, StateData#state.users).find_jid_by_nick(Nick, StateData) ->    ?DICT:fold(fun(_, #user{jid = JID, nick = N}, R) ->		       case Nick of			   N -> JID;			   _ -> R		       end	       end, false, StateData#state.users).is_nick_change(JID, Nick, StateData) ->    LJID = jlib:jid_tolower(JID),    case Nick of	"" ->	    false;	_ ->	    {ok, #user{nick = OldNick}} =		?DICT:find(LJID, StateData#state.users),	    Nick /= OldNick    end.add_new_user(From, Nick, {xmlelement, _, Attrs, Els} = Packet, StateData) ->    Lang = xml:get_attr_s("xml:lang", Attrs),    case {is_nick_exists(Nick, StateData),	  mod_muc:can_use_nick(From, Nick)} of	{true, _} ->	    ErrText = "Nickname is already in use by another occupant",	    Err = jlib:make_error_reply(Packet, ?ERRT_CONFLICT(Lang, ErrText)),	    ejabberd_router:route(	      % TODO: s/Nick/""/	      jlib:jid_replace_resource(StateData#state.jid, Nick),	      From, Err),	    StateData;	{_, false} ->	    ErrText = "Nickname is registered by another person",	    Err = jlib:make_error_reply(Packet, ?ERRT_CONFLICT(Lang, ErrText)),	    ejabberd_router:route(	      % TODO: s/Nick/""/	      jlib:jid_replace_resource(StateData#state.jid, Nick),	      From, Err),	    StateData;	_ ->	    Affiliation = get_affiliation(From, StateData),	    Role = get_default_role(Affiliation, StateData),	    case Role of		none ->		    Err = jlib:make_error_reply(			    Packet,			    case Affiliation of				outcast ->				    ErrText = "You have been banned from this room",				    ?ERRT_FORBIDDEN(Lang, ErrText);				_ ->				    ErrText = "Membership required to enter this room",				    ?ERRT_REGISTRATION_REQUIRED(Lang, ErrText)			    end),		    ejabberd_router:route( % TODO: s/Nick/""/		      jlib:jid_replace_resource(StateData#state.jid, Nick),		      From, Err),		    StateData;		_ ->		    case check_password(Affiliation, Els, StateData) of			true ->			    NewState =				add_user_presence(				  From, Packet,

⌨️ 快捷键说明

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