94 lines
2.8 KiB
Elixir
94 lines
2.8 KiB
Elixir
defmodule BackendWeb.ConnectedUserChannel do
|
|
@moduledoc """
|
|
Manages requests that come in from browser
|
|
"""
|
|
use BackendWeb, :channel
|
|
require Logger
|
|
|
|
@impl true
|
|
def join("user:" <> user_name, _params, %{assigns: %{user_name: socket_user}} = socket)
|
|
when user_name == socket_user do
|
|
Logger.info("WebSocket connected to #{node()}, user: #{user_name}")
|
|
Phoenix.PubSub.subscribe(Backend.PubSub, "game_state")
|
|
Phoenix.PubSub.subscribe(Backend.PubSub, "user_sessions:#{user_name}")
|
|
|
|
# Notify other sessions for this user
|
|
Phoenix.PubSub.broadcast_from(
|
|
Backend.PubSub,
|
|
self(),
|
|
"user_sessions:#{user_name}",
|
|
:new_browser_connection
|
|
)
|
|
|
|
socket =
|
|
socket
|
|
|> assign(:player_name, socket_user)
|
|
|> assign(:keys_pressed, MapSet.new())
|
|
|
|
current_state = Backend.GameRunner.get_state()
|
|
{:ok, %{game_state: current_state}, socket}
|
|
end
|
|
|
|
def join("user:" <> user_name, _params, %{assigns: %{user_name: socket_user}}) do
|
|
Logger.warning("User #{socket_user} attempted to join channel for #{user_name}")
|
|
{:error, %{reason: "unauthorized"}}
|
|
end
|
|
|
|
def join(_topic, _params, _socket) do
|
|
{:error, %{reason: "authentication required"}}
|
|
end
|
|
|
|
@impl true
|
|
def handle_info({:game_state_updated, state}, socket) do
|
|
push(socket, "game_state", %{game_state: state})
|
|
{:noreply, socket}
|
|
end
|
|
|
|
@impl true
|
|
def handle_info(:new_browser_connection, socket) do
|
|
Logger.warning("New browser connection detected for user: #{socket.assigns.user_name}")
|
|
push(socket, "new_browser_connection", %{})
|
|
{:noreply, socket}
|
|
end
|
|
|
|
@impl true
|
|
def handle_in("join_game", %{"name" => name}, socket) do
|
|
Logger.info("Player '#{name}' joining game on #{node()}")
|
|
|
|
Backend.GameRunner.add_player(name)
|
|
|
|
{:reply, :ok, socket}
|
|
end
|
|
|
|
@impl true
|
|
def handle_in("key_down", %{"key" => key}, %{assigns: %{player_name: player_name}} = socket) do
|
|
keys_pressed = MapSet.put(socket.assigns[:keys_pressed] || MapSet.new(), key)
|
|
socket = assign(socket, :keys_pressed, keys_pressed)
|
|
|
|
Logger.debug(
|
|
"Player '#{player_name}' key down: #{key}, keys: #{inspect(MapSet.to_list(keys_pressed))}"
|
|
)
|
|
|
|
Backend.GameRunner.update_player_keys(
|
|
player_name,
|
|
MapSet.to_list(keys_pressed)
|
|
)
|
|
|
|
{:noreply, socket}
|
|
end
|
|
|
|
@impl true
|
|
def handle_in("key_up", %{"key" => key}, %{assigns: %{player_name: player_name}} = socket) do
|
|
keys_pressed = MapSet.delete(socket.assigns[:keys_pressed] || MapSet.new(), key)
|
|
socket = assign(socket, :keys_pressed, keys_pressed)
|
|
|
|
Logger.debug(
|
|
"Player '#{player_name}' key up: #{key}, keys: #{inspect(MapSet.to_list(keys_pressed))}"
|
|
)
|
|
|
|
Backend.GameRunner.update_player_keys(player_name, MapSet.to_list(keys_pressed))
|
|
|
|
{:noreply, socket}
|
|
end
|
|
end
|