defmodule A2S.UDP do
@moduledoc """
GenServer wrapper over `:gen_udp`, responsible for sending packets to game-servers and routing received packets to the appropriate `A2S.Statem` process.
"""
use GenServer
## API
def start_link(opts) do
GenServer.start_link(__MODULE__, opts, [name: __MODULE__])
end
## Callbacks
@impl true
def init([port: port]) do
case :gen_udp.open(port, [:binary, active: true]) do
{:error, reason} -> {:stop, reason}
{:ok, socket} -> {:ok, socket}
end
end
@doc """
Forward received packets to the appropriate `A2S.Statem`.
"""
@impl true
def handle_info({:udp, _socket, ip, port, packet}, socket) do
GenServer.cast(via_registry({ip, port}), packet)
{:noreply, socket}
end
@doc """
Send the given `msg` packet to the game server.
"""
@impl true
def handle_call({address, packet}, _from, socket) do
with :ok <- :gen_udp.send(socket, address, packet) do
{:reply, :ok, socket}
else
err -> {:reply, err, socket}
end
end
## Functions
defp via_registry(name), do: {:via, Registry, {:a2s_registry, name}}
end