can play game

This commit is contained in:
2026-03-02 13:39:18 -07:00
parent 9955a7f90c
commit 0dae393d0d
27 changed files with 856 additions and 474 deletions

View File

@@ -0,0 +1,118 @@
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
)
current_state = Backend.GameState.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()}")
socket =
socket
|> assign(:player_name, name)
|> assign(:keys_pressed, MapSet.new())
Backend.GameState.add_player(name)
{:reply, :ok, socket}
end
@impl true
def handle_in("key_down", %{"key" => key}, socket) do
case socket.assigns[:player_name] do
nil ->
Logger.warning("Key down attempted without joining game")
{:noreply, socket}
player_name ->
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.GameState.update_player_keys(player_name, MapSet.to_list(keys_pressed))
{:noreply, socket}
end
end
@impl true
def handle_in("key_up", %{"key" => key}, socket) do
case socket.assigns[:player_name] do
nil ->
Logger.warning("Key up attempted without joining game")
{:noreply, socket}
player_name ->
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.GameState.update_player_keys(player_name, MapSet.to_list(keys_pressed))
{:noreply, socket}
end
end
@impl true
def terminate(_reason, socket) do
case socket.assigns[:player_name] do
nil ->
Logger.info("WebSocket disconnected from #{node()}")
player_name ->
Logger.info("Player '#{player_name}' disconnected from #{node()}")
Backend.GameState.remove_player(player_name)
end
:ok
end
end