📄 mod_muc_room.erl
字号:
case FAffiliation of owner -> {xmlelement, Name, Attrs, Els} = SubEl, case xml:remove_cdata(Els) of [{xmlelement, "x", Attrs1, Els1} = XEl] -> case {xml:get_tag_attr_s("xmlns", XEl), xml:get_tag_attr_s("type", XEl)} of {?NS_XDATA, "cancel"} -> {result, [], StateData}; {?NS_XDATA, "submit"} -> set_config(XEl, StateData); _ -> {error, ?ERR_BAD_REQUEST} end; [{xmlelement, "destroy", Attrs1, Els1}] -> destroy_room(Els1, StateData); Items -> process_admin_items_set(From, Items, Lang, StateData) end; _ -> ErrText = "Owner privileges required", {error, ?ERRT_FORBIDDEN(Lang, ErrText)} end;process_iq_owner(From, get, Lang, SubEl, StateData) -> FAffiliation = get_affiliation(From, StateData), case FAffiliation of owner -> {xmlelement, Name, Attrs, Els} = SubEl, case xml:remove_cdata(Els) of [] -> get_config(Lang, StateData); [Item] -> case xml:get_tag_attr("affiliation", Item) of false -> {error, ?ERR_BAD_REQUEST}; {value, StrAffiliation} -> case catch list_to_affiliation(StrAffiliation) of {'EXIT', _} -> ErrText = io_lib:format( translate:translate( Lang, "Invalid affiliation: ~s"), [StrAffiliation]), {error, ?ERRT_NOT_ACCEPTABLE(Lang, ErrText)}; SAffiliation -> Items = items_with_affiliation( SAffiliation, StateData), {result, Items, StateData} end end; _ -> {error, ?ERR_FEATURE_NOT_IMPLEMENTED} end; _ -> ErrText = "Owner privileges required", {error, ?ERRT_FORBIDDEN(Lang, ErrText)} end.-define(XFIELD(Type, Label, Var, Val), {xmlelement, "field", [{"type", Type}, {"label", translate:translate(Lang, Label)}, {"var", Var}], [{xmlelement, "value", [], [{xmlcdata, Val}]}]}).-define(BOOLXFIELD(Label, Var, Val), ?XFIELD("boolean", Label, Var, case Val of true -> "1"; _ -> "0" end)).-define(STRINGXFIELD(Label, Var, Val), ?XFIELD("text-single", Label, Var, Val)).-define(PRIVATEXFIELD(Label, Var, Val), ?XFIELD("text-private", Label, Var, Val)).get_config(Lang, StateData) -> Config = StateData#state.config, Res = [{xmlelement, "title", [], [{xmlcdata, translate:translate(Lang, "Configuration for ") ++ jlib:jid_to_string(StateData#state.jid)}]}, ?STRINGXFIELD("Room title", "title", Config#config.title), ?BOOLXFIELD("Allow users to change subject?", "allow_change_subj", Config#config.allow_change_subj), ?BOOLXFIELD("Allow users to query other users?", "allow_query_users", Config#config.allow_query_users), ?BOOLXFIELD("Allow users to send private messages?", "allow_private_messages", Config#config.allow_private_messages), ?BOOLXFIELD("Make room public searchable?", "public", Config#config.public), ?BOOLXFIELD("Make participants list public?", "public_list", Config#config.public_list), ?BOOLXFIELD("Make room persistent?", "persistent", Config#config.persistent), ?BOOLXFIELD("Make room moderated?", "moderated", Config#config.moderated), ?BOOLXFIELD("Default users as members?", "members_by_default", Config#config.members_by_default), ?BOOLXFIELD("Make room members only?", "members_only", Config#config.members_only), ?BOOLXFIELD("Allow users to send invites?", "allow_user_invites", Config#config.allow_user_invites), ?BOOLXFIELD("Make room password protected?", "password_protected", Config#config.password_protected), ?PRIVATEXFIELD("Password", "password", case Config#config.password_protected of true -> Config#config.password; false -> "" end), ?BOOLXFIELD("Make room anonymous?", "anonymous", Config#config.anonymous), ?BOOLXFIELD("Enable logging?", "logging", Config#config.logging) ], {result, [{xmlelement, "instructions", [], [{xmlcdata, translate:translate( Lang, "You need an x:data capable client to configure room")}]}, {xmlelement, "x", [{"xmlns", ?NS_XDATA}], Res}], StateData}.set_config(XEl, StateData) -> XData = jlib:parse_xdata_submit(XEl), case XData of invalid -> {error, ?ERR_BAD_REQUEST}; _ -> case set_xoption(XData, StateData#state.config) of #config{} = Config -> change_config(Config, StateData); Err -> Err end end.-define(SET_BOOL_XOPT(Opt, Val), case Val of "0" -> set_xoption(Opts, Config#config{Opt = false}); "1" -> set_xoption(Opts, Config#config{Opt = true}); _ -> {error, ?ERR_BAD_REQUEST} end).-define(SET_STRING_XOPT(Opt, Val), set_xoption(Opts, Config#config{Opt = Val})).set_xoption([], Config) -> Config;set_xoption([{"title", [Val]} | Opts], Config) -> ?SET_STRING_XOPT(title, Val);set_xoption([{"allow_change_subj", [Val]} | Opts], Config) -> ?SET_BOOL_XOPT(allow_change_subj, Val);set_xoption([{"allow_query_users", [Val]} | Opts], Config) -> ?SET_BOOL_XOPT(allow_query_users, Val);set_xoption([{"allow_private_messages", [Val]} | Opts], Config) -> ?SET_BOOL_XOPT(allow_private_messages, Val);set_xoption([{"public", [Val]} | Opts], Config) -> ?SET_BOOL_XOPT(public, Val);set_xoption([{"public_list", [Val]} | Opts], Config) -> ?SET_BOOL_XOPT(public_list, Val);set_xoption([{"persistent", [Val]} | Opts], Config) -> ?SET_BOOL_XOPT(persistent, Val);set_xoption([{"moderated", [Val]} | Opts], Config) -> ?SET_BOOL_XOPT(moderated, Val);set_xoption([{"members_by_default", [Val]} | Opts], Config) -> ?SET_BOOL_XOPT(members_by_default, Val);set_xoption([{"members_only", [Val]} | Opts], Config) -> ?SET_BOOL_XOPT(members_only, Val);set_xoption([{"allow_user_invites", [Val]} | Opts], Config) -> ?SET_BOOL_XOPT(allow_user_invites, Val);set_xoption([{"password_protected", [Val]} | Opts], Config) -> ?SET_BOOL_XOPT(password_protected, Val);set_xoption([{"password", [Val]} | Opts], Config) -> ?SET_STRING_XOPT(password, Val);set_xoption([{"anonymous", [Val]} | Opts], Config) -> ?SET_BOOL_XOPT(anonymous, Val);set_xoption([{"logging", [Val]} | Opts], Config) -> ?SET_BOOL_XOPT(logging, Val);set_xoption([_ | Opts], Config) -> {error, ?ERR_BAD_REQUEST}.change_config(Config, StateData) -> NSD = StateData#state{config = Config}, case {(StateData#state.config)#config.persistent, Config#config.persistent} of {_, true} -> mod_muc:store_room(NSD#state.room, make_opts(NSD)); {true, false} -> mod_muc:forget_room(NSD#state.room); {false, false} -> ok end, {result, [], NSD}.-define(CASE_CONFIG_OPT(Opt), Opt -> StateData#state{ config = (StateData#state.config)#config{Opt = Val}}).set_opts([], StateData) -> StateData;set_opts([{Opt, Val} | Opts], StateData) -> NSD = case Opt of ?CASE_CONFIG_OPT(title); ?CASE_CONFIG_OPT(allow_change_subj); ?CASE_CONFIG_OPT(allow_query_users); ?CASE_CONFIG_OPT(allow_private_messages); ?CASE_CONFIG_OPT(public); ?CASE_CONFIG_OPT(public_list); ?CASE_CONFIG_OPT(persistent); ?CASE_CONFIG_OPT(moderated); ?CASE_CONFIG_OPT(members_by_default); ?CASE_CONFIG_OPT(members_only); ?CASE_CONFIG_OPT(allow_user_invites); ?CASE_CONFIG_OPT(password_protected); ?CASE_CONFIG_OPT(password); ?CASE_CONFIG_OPT(anonymous); ?CASE_CONFIG_OPT(logging); affiliations -> StateData#state{affiliations = ?DICT:from_list(Val)}; subject -> StateData#state{subject = Val}; subject_author -> StateData#state{subject_author = Val}; _ -> StateData end, set_opts(Opts, NSD).-define(MAKE_CONFIG_OPT(Opt), {Opt, Config#config.Opt}).make_opts(StateData) -> Config = StateData#state.config, [ ?MAKE_CONFIG_OPT(title), ?MAKE_CONFIG_OPT(allow_change_subj), ?MAKE_CONFIG_OPT(allow_query_users), ?MAKE_CONFIG_OPT(allow_private_messages), ?MAKE_CONFIG_OPT(public), ?MAKE_CONFIG_OPT(public_list), ?MAKE_CONFIG_OPT(persistent), ?MAKE_CONFIG_OPT(moderated), ?MAKE_CONFIG_OPT(members_by_default), ?MAKE_CONFIG_OPT(members_only), ?MAKE_CONFIG_OPT(allow_user_invites), ?MAKE_CONFIG_OPT(password_protected), ?MAKE_CONFIG_OPT(password), ?MAKE_CONFIG_OPT(anonymous), ?MAKE_CONFIG_OPT(logging), {affiliations, ?DICT:to_list(StateData#state.affiliations)}, {subject, StateData#state.subject}, {subject_author, StateData#state.subject_author} ].destroy_room(DEls, StateData) -> lists:foreach( fun({LJID, Info}) -> Nick = Info#user.nick, ItemAttrs = [{"affiliation", "none"}, {"role", "none"}], Packet = {xmlelement, "presence", [{"type", "unavailable"}], [{xmlelement, "x", [{"xmlns", ?NS_MUC_USER}], [{xmlelement, "item", ItemAttrs, []}, {xmlelement, "destroy", [], DEls}]}]}, ejabberd_router:route( jlib:jid_replace_resource(StateData#state.jid, Nick), Info#user.jid, Packet) end, ?DICT:to_list(StateData#state.users)), case (StateData#state.config)#config.persistent of true -> mod_muc:forget_room(StateData#state.room); false -> ok end, {result, [], stop}.%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% Disco-define(FEATURE(Var), {xmlelement, "feature", [{"var", Var}], []}).-define(CONFIG_OPT_TO_FEATURE(Opt, Fiftrue, Fiffalse), case Opt of true -> ?FEATURE(Fiftrue); false -> ?FEATURE(Fiffalse) end).process_iq_disco_info(From, set, Lang, StateData) -> {error, ?ERR_NOT_ALLOWED};process_iq_disco_info(From, get, Lang, StateData) -> Config = StateData#state.config, {result, [{xmlelement, "identity", [{"category", "conference"}, {"type", "text"}, {"name", get_title(StateData)}], []}, {xmlelement, "feature", [{"var", ?NS_MUC}], []}, ?CONFIG_OPT_TO_FEATURE(Config#config.public, "muc_public", "muc_hidden"), ?CONFIG_OPT_TO_FEATURE(Config#config.persistent, "muc_persistent", "muc_temporary"), ?CONFIG_OPT_TO_FEATURE(Config#config.members_only, "muc_membersonly", "muc_open"), ?CONFIG_OPT_TO_FEATURE(Config#config.anonymous, "muc_semianonymous", "muc_nonanonymous"), ?CONFIG_OPT_TO_FEATURE(Config#config.moderated, "muc_moderated", "muc_unmoderated"), ?CONFIG_OPT_TO_FEATURE(Config#config.password_protected, "muc_passwordprotected", "muc_unsecured") ], StateData}.process_iq_disco_items(From, set, Lang, StateData) -> {error, ?ERR_NOT_ALLOWED};process_iq_disco_items(From, get, Lang, StateData) -> FAffiliation = get_affiliation(From, StateData), FRole = get_role(From, StateData), case ((StateData#state.config)#config.public_list == true) orelse (FRole /= none) orelse (FAffiliation == admin) orelse (FAffiliation == owner) of true -> UList = lists:map( fun({LJID, Info}) -> Nick = Info#user.nick, {xmlelement, "item", [{"jid", jlib:jid_to_string( {StateData#state.room, StateData#state.host, Nick})}, {"name", Nick}], []} end, ?DICT:to_list(StateData#state.users)), {result, UList, StateData}; _ -> {error, ?ERR_FORBIDDEN} end.get_title(StateData) -> case (StateData#state.config)#config.title of "" -> StateData#state.room; Name -> Name end.%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% Invitation supportcheck_invitation(From, Els, StateData) -> FAffiliation = get_affiliation(From, StateData), CanInvite = (StateData#state.config)#config.allow_user_invites orelse (FAffiliation == admin) orelse (FAffiliation == owner), case xml:remove_cdata(Els) of [{xmlelement, "x", Attrs1, Els1} = XEl] -> case xml:get_tag_attr_s("xmlns", XEl) of ?NS_MUC_USER -> case xml:remove_cdata(Els1) of [{xmlelement, "invite", Attrs2, Els2} = InviteEl] -> case jlib:string_to_jid( xml:get_attr_s("to", Attrs2)) of error -> error; JID -> case CanInvite of true -> Reason = xml:get_path_s( InviteEl, [{elem, "reason"}, cdata]), IEl = [{xmlelement, "invite", [{"from", jlib:jid_to_string(From)}], [{xmlelement, "reason", [], [{xmlcdata, Reason}]}]}], PasswdEl = case (StateData#state.config)#config.password_protected of true -> [{xmlelement, "password", [], [{xmlcdata, (StateData#state.config)#config.password}]}]; _ -> [] end, Msg = {xmlelement, "message", [{"type", "normal"}], [{xmlelement, "x", [{"xmlns", ?NS_MUC_USER}], IEl ++ PasswdEl}, {xmlelement, "x", [{"xmlns", ?NS_XCONFERENCE}, {"jid", jlib:jid_to_string( {StateData#state.room, StateData#state.host, ""})}], [{xmlcdata, Reason}]}]}, ejabberd_router:route( StateData#state.jid, JID, Msg), JID; _ -> error end end; _ -> error end; _ -> error end; _ -> error end.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -