2.2 KiB · text History 4b6fe3b
defmodule OhMyExOhIrcd.IRC.Broadcast do
  @moduledoc """
  Cluster-wide operator + server broadcasts.

  Three PubSub topics, used like newsgroups:

    * `"opers"`  — receives WALLOPS (also delivered to `+w` users) and
                   GLOBOPS (opers only).
    * `"wallops"` — `+w` user-mode subscribers; tagged separately from
                    opers so we can deliver WALLOPS to both groups
                    without duplicating to plain ops.
    * `"all"`    — every connected client; used for global notices
                   (the irssi-style `[Global Notice]` lines from an
                   oper to the network).

  Connections subscribe / unsubscribe via the helpers here as their
  oper / `+w` status changes.
  """

  @pubsub OhMyExOhIrcd.PubSub

  @opers_topic "opers"
  @wallops_topic "wallops"
  @all_topic "all"

  def opers_topic, do: @opers_topic
  def wallops_topic, do: @wallops_topic
  def all_topic, do: @all_topic

  def subscribe_opers, do: Phoenix.PubSub.subscribe(@pubsub, @opers_topic)
  def unsubscribe_opers, do: Phoenix.PubSub.unsubscribe(@pubsub, @opers_topic)

  def subscribe_wallops, do: Phoenix.PubSub.subscribe(@pubsub, @wallops_topic)
  def unsubscribe_wallops, do: Phoenix.PubSub.unsubscribe(@pubsub, @wallops_topic)

  def subscribe_all, do: Phoenix.PubSub.subscribe(@pubsub, @all_topic)
  def unsubscribe_all, do: Phoenix.PubSub.unsubscribe(@pubsub, @all_topic)

  @doc """
  WALLOPS from `sender` (typically an oper nick). Delivered to every
  oper *and* every `+w` user as a `WALLOPS :<text>` line.
  """
  def wallops(sender, text) do
    msg = {:irc_wallops, sender, text}
    Phoenix.PubSub.broadcast(@pubsub, @opers_topic, msg)
    Phoenix.PubSub.broadcast(@pubsub, @wallops_topic, msg)
  end

  @doc """
  GLOBOPS — oper-only broadcast. Receivers render it as a NOTICE from
  the sender (irssi etc. show it in the server window).
  """
  def globops(sender, text) do
    Phoenix.PubSub.broadcast(@pubsub, @opers_topic, {:irc_globops, sender, text})
  end

  @doc """
  Global notice from `sender` to every connected user — what the
  channel called a "Global Notice" / staff broadcast.
  """
  def global_notice(sender, text) do
    Phoenix.PubSub.broadcast(@pubsub, @all_topic, {:irc_global_notice, sender, text})
  end
end