From e4e78a167fe1e6e816ce48223dbb413f4121cfa5 Mon Sep 17 00:00:00 2001 From: Mikko Ahlroth Date: Sat, 22 Jun 2013 23:48:33 +0300 Subject: [PATCH] Altnick implementation, initial stuff for handler --- lib/nulform.ex | 4 +-- lib/nulform/connection.ex | 63 ++++++++++++++++++++++++++++----------- lib/nulform/handler.ex | 11 +++++++ 3 files changed, 59 insertions(+), 19 deletions(-) create mode 100644 lib/nulform/handler.ex diff --git a/lib/nulform.ex b/lib/nulform.ex index 868b2ac..e545cc4 100644 --- a/lib/nulform.ex +++ b/lib/nulform.ex @@ -2,8 +2,8 @@ defmodule Nulform do def run() do connection = spawn Nulform.Connection, :run, [] - connection <- {:nulform, :connect, 'irc.quakenet.org', 6667, "Nulform", - nil, "nulform", "␀form"} + connection <- {:nulform, :connect, 'irc.quakenet.org', 6667, "Nicd", + "kummitus", "nulform", "␀form"} IO.puts("Sent message") receive do diff --git a/lib/nulform/connection.ex b/lib/nulform/connection.ex index 48084fc..f8583e3 100644 --- a/lib/nulform/connection.ex +++ b/lib/nulform/connection.ex @@ -1,31 +1,37 @@ defmodule Nulform.Connection do @moduledoc """ - Connection is a module to handle a single IRC connection to an IRC server. + Connection is a module to handle a single IRC connection to an IRC + server. + + Connection automatically handles using an altnick (but only one) and + responding to pings. """ def run() do - run nil, nil, nil, nil, nil, nil, nil + run nil, nil, nil, nil, nil, nil, nil, nil end - def run(sock, host, port, nick, altnick, username, realname) do + def run(sock, handler, host, port, nick, altnick, username, realname) do receive do {:nulform, :connect, host, port, nick, altnick, username, realname} -> {:ok, sock} = connect host, port + # TODO: Do we need to delay here on some networks? + send sock, "NICK " <> nick + send sock, "USER " <> username <> " 8 * :" <> realname + + {:nulform, :set_parent, handler} -> + nil + + {:nulform, :msg_out, msg} -> + send sock, msg + {:tcp, sock, msg} -> stripped = String.rstrip msg IO.puts stripped + tell_handler handler, stripped - case stripped do - "NOTICE AUTH :*** Looking up your hostname" -> - send sock, "NICK " <> nick - send sock, "USER " <> username <> " 8 * :" <> realname - - _ -> - - end - - + # Handle PING responses case String.split stripped, ":" do ["PING " | rest] when is_list rest -> concat_list = fn @@ -39,14 +45,25 @@ defmodule Nulform.Connection do send sock, "PONG :" <> concat_list.(concat_list, rest, ":") - _ -> end - tuple when is_tuple(tuple) and elem(tuple, 0) == :nulform -> Nulform.Utils.hn(tuple) + # Change to altnick when nick is already in use + # TODO: May not work on all networks + # We change the altnick to avoid an infinite loop + # TODO: New altnick is predictable, no seeding + case String.split stripped do + [_, "433" | _] -> + send sock, "NICK " <> altnick + uniqid = to_binary :random.uniform(9999) + altnick = String.slice(altnick, 0, 10) <> "-" <> uniqid + _ -> + end + + tuple when is_tuple(tuple) and elem(tuple, 0) == :nulform -> Nulform.Utils.hn tuple end - run sock, host, port, nick, altnick, username, realname + run sock, handler, host, port, nick, altnick, username, realname end defp connect(host, port) do @@ -55,8 +72,20 @@ defmodule Nulform.Connection do ] end - def send(sock, msg) do + defp disconnect(sock) do + :gen_tcp.close sock + end + + defp send(sock, msg) do :ok = :gen_tcp.send sock, msg <> "\r\n" IO.puts("<- " <> msg) end + + defp tell_handler(handler, msg) when is_pid handler do + handler <- {:nulform, :msg_in, msg} + end + + defp tell_handler(_, msg) do + nil + end end diff --git a/lib/nulform/handler.ex b/lib/nulform/handler.ex new file mode 100644 index 0000000..76a4b1e --- /dev/null +++ b/lib/nulform/handler.ex @@ -0,0 +1,11 @@ +defmodule Nulform.Handler do + @moduledoc """ + A handler manages plugins for a connection or other IRC message source. + It takes in messages from the IRC server and relays them to plugins. It + also starts up the plugins and manages their lifetime. + """ + + def run() do + + end +end