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

📄 mod_irc_connection.erl

📁 ejabberd-0.7.5 分布式Jabber服务器
💻 ERL
📖 第 1 页 / 共 3 页
字号:
			Res = lists:concat(				lists:map(				  fun(S) ->					  io_lib:format("PRIVMSG ~s :~s\r\n",							[Nick, S])				  end, Strings)),			?SEND(Res)		end;	    "error" ->		stop;	    _ ->		StateData	end,    if	NewStateData == stop ->	    {stop, normal, StateData};	true ->	    {next_state, StateName, NewStateData}    end;handle_info({route_nick, Nick, Packet}, StateName, StateData) ->    {next_state, StateName, StateData};handle_info({ircstring, [$P, $I, $N, $G, $  | ID]}, StateName, StateData) ->    send_text(StateData, "PONG " ++ ID ++ "\r\n"),    {next_state, StateName, StateData};handle_info({ircstring, [$: | String]}, StateName, StateData) ->    Words = string:tokens(String, " "),    NewStateData =	case Words of	    [_, "353" | Items] ->		process_channel_list(StateData, Items);	    [_, "332", Nick, [$# | Chan] | _] ->		process_channel_topic(StateData, Chan, String),		StateData;	    [From, "PRIVMSG", [$# | Chan] | _] ->		process_chanprivmsg(StateData, Chan, From, String),		StateData;	    [From, "NOTICE", [$# | Chan] | _] ->		process_channotice(StateData, Chan, From, String),		StateData;	    [From, "PRIVMSG", Nick, ":\001VERSION\001" | _] ->		process_version(StateData, Nick, From),		StateData;	    [From, "PRIVMSG", Nick | _] ->		process_privmsg(StateData, Nick, From, String),		StateData;	    [From, "NOTICE", Nick | _] ->		process_notice(StateData, Nick, From, String),		StateData;	    [From, "TOPIC", [$# | Chan] | _] ->		process_topic(StateData, Chan, From, String),		StateData;	    [From, "PART", [$# | Chan] | _] ->		process_part(StateData, Chan, From, String);	    [From, "QUIT" | _] ->		process_quit(StateData, From, String);	    [From, "JOIN", Chan | _] ->		process_join(StateData, Chan, From, String);	    [From, "MODE", [$# | Chan], "+o", Nick | _] ->		process_mode_o(StateData, Chan, From, Nick,			       "admin", "moderator"),		StateData;	    [From, "MODE", [$# | Chan], "-o", Nick | _] ->		process_mode_o(StateData, Chan, From, Nick,			       "member", "participant"),		StateData;	    [From, "KICK", [$# | Chan], Nick | _] ->		process_kick(StateData, Chan, From, Nick),		StateData;	    [From, "NICK", Nick | _] ->		process_nick(StateData, From, Nick);	    _ ->		?DEBUG("unknown irc command '~s'~n", [String]),		StateData	end,    NewStateData1 =	case StateData#state.outbuf of	    "" ->		NewStateData;	    Data ->		send_text(NewStateData, Data),		NewStateData#state{outbuf = ""}	end,    {next_state, stream_established, NewStateData1};handle_info({ircstring, [$E, $R, $R, $O, $R | _] = String},	    StateName, StateData) ->    process_error(StateData, String),    {next_state, StateName, StateData};handle_info({ircstring, String}, StateName, StateData) ->    ?DEBUG("unknown irc command '~s'~n", [String]),    {next_state, StateName, StateData};handle_info({send_text, Text}, StateName, StateData) ->    send_text(StateData, Text),    {next_state, StateName, StateData};handle_info({tcp, Socket, Data}, StateName, StateData) ->    Buf = StateData#state.inbuf ++ binary_to_list(Data),    {ok, Strings} = regexp:split([C || C <- Buf, C /= $\r], "\n"),    ?DEBUG("strings=~p~n", [Strings]),    NewBuf = process_lines(StateData#state.encoding, Strings),    {next_state, StateName, StateData#state{inbuf = NewBuf}};handle_info({tcp_closed, Socket}, StateName, StateData) ->    gen_fsm:send_event(self(), closed),    {next_state, StateName, StateData};handle_info({tcp_error, Socket, Reason}, StateName, StateData) ->    gen_fsm:send_event(self(), closed),    {next_state, StateName, StateData}.%%----------------------------------------------------------------------%% Func: terminate/3%% Purpose: Shutdown the fsm%% Returns: any%%----------------------------------------------------------------------terminate(Reason, StateName, StateData) ->    mod_irc:closed_conection(StateData#state.user,			     StateData#state.server),    bounce_messages("Server Connect Failed"),    lists:foreach(      fun(Chan) ->	      ejabberd_router:route(		jlib:make_jid(		  lists:concat([Chan, "%", StateData#state.server]),		  StateData#state.myname, StateData#state.nick),		StateData#state.user,		{xmlelement, "presence", [{"type", "error"}],		 [{xmlelement, "error", [{"code", "502"}],		   [{xmlcdata, "Server Connect Failed"}]}]})      end, dict:fetch_keys(StateData#state.channels)),    case StateData#state.socket of	undefined ->	    ok;	Socket ->	    gen_tcp:close(Socket)    end,    ok.%%%----------------------------------------------------------------------%%% Internal functions%%%----------------------------------------------------------------------receiver(Socket, C2SPid) ->    XMLStreamPid = xml_stream:start(C2SPid),    receiver(Socket, C2SPid, XMLStreamPid).receiver(Socket, C2SPid, XMLStreamPid) ->    case gen_tcp:recv(Socket, 0) of        {ok, Text} ->	    xml_stream:send_text(XMLStreamPid, Text),	    receiver(Socket, C2SPid, XMLStreamPid);        {error, Reason} ->	    exit(XMLStreamPid, closed),	    gen_fsm:send_event(C2SPid, closed),	    ok    end.send_text(#state{socket = Socket, encoding = Encoding}, Text) ->    CText = iconv:convert("utf-8", Encoding, lists:flatten(Text)),    %?DEBUG("IRC OUTu: ~s~nIRC OUTk: ~s~n", [Text, CText]),    gen_tcp:send(Socket, CText).%send_queue(Socket, Q) ->%    case queue:out(Q) of%	{{value, El}, Q1} ->%	    send_element(Socket, El),%	    send_queue(Socket, Q1);%	{empty, Q1} ->%	    ok%    end.bounce_messages(Reason) ->    receive	{send_element, El} ->	    {xmlelement, Name, Attrs, SubTags} = El,	    case xml:get_attr_s("type", Attrs) of	        "error" ->	            ok;	        _ ->	            Err = jlib:make_error_reply(El,	        				"502", Reason),		    From = jlib:string_to_jid(xml:get_attr_s("from", Attrs)),		    To = jlib:string_to_jid(xml:get_attr_s("to", Attrs)),		    ejabberd_router:route(To, From, Err)	    end,	    bounce_messages(Reason)    after 0 ->	    ok    end.route_chan(Pid, Channel, Resource, Packet) ->    Pid ! {route_chan, Channel, Resource, Packet}.route_nick(Pid, Nick, Packet) ->    Pid ! {route_nick, Nick, Packet}.process_lines(Encoding, [S]) ->    S;process_lines(Encoding, [S | Ss]) ->    self() ! {ircstring, iconv:convert(Encoding, "utf-8", S)},    process_lines(Encoding, Ss).process_channel_list(StateData, Items) ->    process_channel_list_find_chan(StateData, Items).process_channel_list_find_chan(StateData, []) ->    StateData;process_channel_list_find_chan(StateData, [[$# | Chan] | Items]) ->    process_channel_list_users(StateData, Chan, Items);process_channel_list_find_chan(StateData, [_ | Items]) ->    process_channel_list_find_chan(StateData, Items).process_channel_list_users(StateData, Chan, []) ->    StateData;process_channel_list_users(StateData, Chan, [User | Items]) ->    NewStateData = process_channel_list_user(StateData, Chan, User),    process_channel_list_users(NewStateData, Chan, Items).process_channel_list_user(StateData, Chan, User) ->    User1 = case User of		[$: | U1] -> U1;		_ -> User	    end,    {User2, Affiliation, Role} =	case User1 of	    [$@ | U2] -> {U2, "admin", "moderator"};	    [$+ | U2] -> {U2, "member", "participant"};	    _ -> {User1, "member", "participant"}	end,    ejabberd_router:route(      jlib:make_jid(lists:concat([Chan, "%", StateData#state.server]),		    StateData#state.myname, User2),      StateData#state.user,      {xmlelement, "presence", [],       [{xmlelement, "x", [{"xmlns", ?NS_MUC_USER}],	 [{xmlelement, "item",	   [{"affiliation", Affiliation},	    {"role", Role}],	   []}]}]}),    case catch dict:update(Chan,			   fun(Ps) ->				   ?SETS:add_element(User2, Ps)			   end, StateData#state.channels) of	{'EXIT', _} ->	    StateData;	NS ->	    StateData#state{channels = NS}    end.process_channel_topic(StateData, Chan, String) ->    FromUser = "someone",    {ok, Msg, _} = regexp:sub(String, ".*332[^:]*:", ""),    Msg1 = lists:filter(	     fun(C) ->		     if (C < 32) and			(C /= 9) and			(C /= 10) and			(C /= 13) ->			     false;			true -> true		     end	     end, Msg),    ejabberd_router:route(      jlib:make_jid(	lists:concat([Chan, "%", StateData#state.server]),	StateData#state.myname, FromUser),      StateData#state.user,      {xmlelement, "message", [{"type", "groupchat"}],       [{xmlelement, "subject", [], [{xmlcdata, Msg1}]}]}).process_chanprivmsg(StateData, Chan, From, String) ->    [FromUser | _] = string:tokens(From, "!"),    {ok, Msg, _} = regexp:sub(String, ".*PRIVMSG[^:]*:", ""),    Msg1 = case Msg of	       [1, $A, $C, $T, $I, $O, $N, $  | Rest] ->		   "/me " ++ Rest;	       _ ->		   Msg	   end,    Msg2 = lists:filter(	     fun(C) ->		     if (C < 32) and			(C /= 9) and			(C /= 10) and			(C /= 13) ->			     false;			true -> true		     end	     end, Msg1),    ejabberd_router:route(      jlib:make_jid(lists:concat([Chan, "%", StateData#state.server]),		    StateData#state.myname, FromUser),      StateData#state.user,      {xmlelement, "message", [{"type", "groupchat"}],       [{xmlelement, "body", [], [{xmlcdata, Msg2}]}]}).process_channotice(StateData, Chan, From, String) ->    [FromUser | _] = string:tokens(From, "!"),    {ok, Msg, _} = regexp:sub(String, ".*NOTICE[^:]*:", ""),    Msg1 = case Msg of	       [1, $A, $C, $T, $I, $O, $N, $  | Rest] ->		   "/me " ++ Rest;	       _ ->		   Msg	   end,    Msg2 = lists:filter(	     fun(C) ->		     if (C < 32) and			(C /= 9) and			(C /= 10) and			(C /= 13) ->			     false;			true -> true		     end	     end, Msg1),    ejabberd_router:route(      jlib:make_jid(lists:concat([Chan, "%", StateData#state.server]),		    StateData#state.myname, FromUser),      StateData#state.user,      {xmlelement, "message", [{"type", "groupchat"}],       [{xmlelement, "body", [], [{xmlcdata, "NOTICE: " ++ Msg2}]}]}).process_privmsg(StateData, Nick, From, String) ->    [FromUser | _] = string:tokens(From, "!"),    {ok, Msg, _} = regexp:sub(String, ".*PRIVMSG[^:]*:", ""),    Msg1 = case Msg of	       [1, $A, $C, $T, $I, $O, $N, $  | Rest] ->		   "/me " ++ Rest;	       _ ->		   Msg	   end,    Msg2 = lists:filter(	     fun(C) ->		     if (C < 32) and			(C /= 9) and			(C /= 10) and			(C /= 13) ->			     false;			true -> true		     end

⌨️ 快捷键说明

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