2025-06-13 19:02:30 -06:00

189 lines
4.4 KiB
Gleam

import app/clients/host_client
import app/clients/new_user_client
import app/clients/player_client
import config
import gleam/erlang/process
import gleam/float
import gleam/int
import gleam/io
import gleam/json
import player_manager
import session_manager
import socket_manager
pub type Error {
InvalidToken
}
pub type Context {
Context(
config: config.Config,
sessions: session_manager.SessionManager,
players: player_manager.PlayerManager,
socket_manager: socket_manager.SocketManager(String),
)
}
pub type ClientState {
Host(host_client.HostState)
Player(player_client.PlayerState)
NewUser(new_user_client.NewUserState)
}
pub type SocketState {
SocketState(
ctx: Context,
id: Int,
subject: process.Subject(String),
state: ClientState,
)
}
pub fn handle_client_msg(
socket_state: SocketState,
msg: String,
) -> #(SocketState, String) {
case socket_state.state {
Host(state) -> handle_host(socket_state, state, msg)
NewUser(state) -> handle_new_user(socket_state, state, msg)
Player(state) -> handle_player(socket_state, state, msg)
}
}
fn handle_player(
socket_state: SocketState,
player_state: player_client.PlayerState,
msg: String,
) -> #(SocketState, String) {
let assert Ok(msg) =
json.parse(msg, player_client.player_client_messages_decoder())
case msg {
player_client.BuzzIn(time) -> {
io.println(
"Got buzz in from "
<> int.to_string(player_state.user_id)
<> " at "
<> float.to_string(time),
)
let assert Ok(_) =
session_manager.buzz_in_player(
socket_state.ctx.sessions,
player_state.game_id,
player_state.user_id,
time,
)
#(
socket_state,
json.to_string(player_client.encode_player_server_messages(
player_client.Ack,
)),
)
}
}
}
fn handle_new_user(
socket_state: SocketState,
_new_user_state: new_user_client.NewUserState,
msg: String,
) -> #(SocketState, String) {
let assert Ok(msg) =
json.parse(msg, new_user_client.new_user_client_messages_decoder())
let #(socket_state, new_user_msg) = case msg {
new_user_client.JoinAsHost(token, user_id, game_id) -> {
let assert Ok(_) =
player_manager.attack_socket_to_player(
socket_state.ctx.players,
user_id,
socket_state.id,
token,
)
#(
SocketState(
..socket_state,
state: Host(host_client.HostState(user_id:, game_id:)),
),
new_user_client.HostRegisterResponse,
)
}
new_user_client.JoinAsPlayer(token, user_id, game_id) -> {
let assert Ok(_) =
player_manager.attack_socket_to_player(
socket_state.ctx.players,
user_id,
socket_state.id,
token,
)
#(
SocketState(
..socket_state,
state: Player(player_client.PlayerState(user_id:, game_id:)),
),
new_user_client.RegisterResponse,
)
}
}
#(
socket_state,
json.to_string(new_user_client.encode_new_user_server_messages(new_user_msg)),
)
}
fn handle_host(
socket_state: SocketState,
host_state: host_client.HostState,
msg: String,
) -> #(SocketState, String) {
let assert Ok(msg) =
json.parse(msg, host_client.host_client_messages_decoder())
let #(socket_state, resp) = case msg {
host_client.ResetAllBuzers -> {
let assert Ok(_) =
session_manager.reset_all_buzzers(
socket_state.ctx.sessions,
host_state.game_id,
)
#(socket_state, host_client.Ack)
}
host_client.ResetPlayerBuzzer(id) -> {
let assert Ok(_) =
session_manager.reset_player_buzzer(
socket_state.ctx.sessions,
host_state.game_id,
id,
)
#(socket_state, host_client.Ack)
}
host_client.UpdateScore(id, score) -> {
let assert Ok(_) =
session_manager.updater_player_score(
socket_state.ctx.sessions,
host_state.game_id,
id,
score,
)
#(socket_state, host_client.Ack)
}
host_client.EndGame -> {
let assert Ok(_) =
session_manager.end_game(socket_state.ctx.sessions, host_state.game_id)
#(socket_state, host_client.Ack)
}
}
let resp = json.to_string(host_client.encode_host_server_messages(resp))
#(socket_state, resp)
}