diff --git a/lib/ircked_elixir/chat_group.ex b/lib/ircked_elixir/chat_group.ex new file mode 100644 index 0000000..9947a0f --- /dev/null +++ b/lib/ircked_elixir/chat_group.ex @@ -0,0 +1,69 @@ +defmodule IrckedElixir.ChatGroup do + use GenServer + + alias IrckedElixir.Chatter.Message, as: Message + alias IrckedElixir.Chatter.Privmsg, as: Privmsg + + @server_address "localhost" + @server_port 6667 + @base_nick "functism" + @chatters 3 + + @impl true + def init(chatters) do + 1..@chatters + |> Enum.to_list + |> Enum.map( + fn n -> + %{ + id: "chatter"<>to_string(n), + start: {IrckedElixir.Chatter, :start_link, [%IrckedElixir.Chatter.State{ip: @server_address, port: @server_port, nick: @base_nick <> to_string(n), reporter: n == 1}]} + } + end + ) + |> Enum.each( + fn child -> + DynamicSupervisor.start_child(IrckedElixir.DynamicSupervisor, child) + end + ) + {:ok, chatters} + end + + @impl true + def handle_info({:checkin, nick, chatter}, chatters) do + chatters = Map.put(chatters, nick, chatter) + {:noreply, chatters} + end + + def handle_info({:report, msg}, chatters) do + case msg.command do + "PRIVMSG" -> + pm = Privmsg.parse(msg) + IO.puts(inspect pm) + case pm.body do + ".cunny" -> send_all(chatters, pm.to, "cunny!") + _ -> "" + end + + "" -> "" + _ -> IO.puts(inspect msg) + end + {:noreply, chatters} + end + + def start_link(chatters) do + GenServer.start_link(__MODULE__, chatters, name: :chatgroup) + end + + def send_all(chatters, to, body) do + chatters + |> Map.keys + |> Enum.each( + fn chatter -> + send(String.to_atom(chatter), {:sendprivmsg, to, body}) + IO.puts("LOL, "<>inspect(chatter)) + end + ) + end + +end diff --git a/lib/ircked_elixir/chatter.ex b/lib/ircked_elixir/chatter.ex index 6286e20..cf46937 100644 --- a/lib/ircked_elixir/chatter.ex +++ b/lib/ircked_elixir/chatter.ex @@ -6,36 +6,40 @@ defmodule IrckedElixir.Chatter do @impl true def init(starting_state) do - {:ok, socket} = :gen_tcp.connect(to_charlist(starting_state.ip), starting_state.port, [:binary, active: false]) - IO.puts(inspect starting_state) + {:ok, socket} = :gen_tcp.connect(to_charlist(starting_state.ip), starting_state.port, [:binary, active: true]) starting_state = %{starting_state | sock: socket} - IO.puts(inspect starting_state) - IO.puts(inspect socket) :gen_tcp.send(socket, ["USER ", starting_state.nick, " 0 * :", starting_state.nick, "\r\n"]) :gen_tcp.send(socket, ["NICK ", starting_state.nick, "\r\n"]) - send(self(), {:run, starting_state}) + send(:chatgroup, {:checkin, starting_state.nick, self()}) {:ok, starting_state} end @impl true - def handle_info({:sendmsg, to, body}, state) do - Privmsg.construct(state.nick, to, body).message |> Message.send(state.sock) + def handle_info({:tcp, _, data}, state) do + String.split(data, "\r\n") |> Enum.each(fn raw -> handle(Message.parse(raw), state) end) {:noreply, state} end - @impl true - def handle_info({:run, start_state}, _state) do - run(start_state) - {:noreply, start_state} + def handle_info({:tcp_closed, _}, state) do + {:stop, :normal, state} + end + + def handle_info({:tcp_error, _}, state) do + {:stop, :normal, state} + end + + def handle_info({:sendprivmsg, to, body}, state) do + Privmsg.construct(state.nick, to, body).message |> Message.send(state.sock) + {:noreply, state} end def start_link(starting_state) do - GenServer.start_link(__MODULE__, starting_state) + GenServer.start_link(__MODULE__, starting_state, name: starting_state.nick |> String.to_atom) end - def sendmsg(to, body) do - send(self(), {:sendmsg, to, body}) + def sendpm(to, body) do + send(self(), {:sendprivmsg, to, body}) end def run(state) do @@ -45,20 +49,20 @@ defmodule IrckedElixir.Chatter do end def handle(msg, state) do + if state.reporter do + send(:chatgroup, {:report, msg}) + end case msg.command do "PING" -> Message.construct("", "PONG", msg.parameters) |> Message.send(state.sock) "001" -> Message.construct("", "JOIN", ["#qrs"]) |> Message.send(state.sock) "PRIVMSG" -> pm = Privmsg.parse(msg) - IO.puts(inspect pm) case pm.body do - ".bots" -> Privmsg.construct("functism", pm.to, "https://github.com/kurisufriend/ircked_elixir").message |> Message.send(state.sock) - ".hello" -> Privmsg.construct("functism", pm.to, "hai").message |> Message.send(state.sock) _ -> "" end "" -> "" - _ -> IO.puts(inspect msg) + _ -> "" end end end diff --git a/lib/ircked_elixir/chatter/state.ex b/lib/ircked_elixir/chatter/state.ex index 77ed928..a00b7c4 100644 --- a/lib/ircked_elixir/chatter/state.ex +++ b/lib/ircked_elixir/chatter/state.ex @@ -1,3 +1,3 @@ defmodule IrckedElixir.Chatter.State do - defstruct ip: "", port: 0, nick: "", sock: nil + defstruct ip: "", port: 0, nick: "", sock: nil, reporter: false end diff --git a/lib/ircked_elixir/overseer.ex b/lib/ircked_elixir/overseer.ex index ae680fc..f658826 100644 --- a/lib/ircked_elixir/overseer.ex +++ b/lib/ircked_elixir/overseer.ex @@ -1,18 +1,16 @@ defmodule IrckedElixir.Overseer do use Supervisor - @server_address "localhost" - @server_port 6667 - @base_nick "functism" - @chatters 20 - def start_link(opts) do Supervisor.start_link(__MODULE__, :ok, opts) end @impl true def init(:ok) do - children = 1..@chatters |> Enum.to_list |> Enum.map(fn n -> %{id: "chatter"<>to_string(n), start: {IrckedElixir.Chatter, :start_link, [%IrckedElixir.Chatter.State{ip: @server_address, port: @server_port, nick: @base_nick <> to_string(n)}]}} end) + children = [ + {DynamicSupervisor, strategy: :one_for_one, name: IrckedElixir.DynamicSupervisor}, + {IrckedElixir.ChatGroup, %{}} + ] Supervisor.init(children, strategy: :one_for_one) end end