This repository has been archived on 2025-08-18. You can view files and clone it, but you cannot make any changes to it's state, such as pushing and creating new issues, pull requests or comments.
GGS/src/ggs_player.erl
2011-02-22 03:11:35 +01:00

66 lines
2.7 KiB
Erlang

-module(ggs_player).
-export([start_link/1, notify/3, get_token/1, stop/2]).
-record(pl_state,
{token, % Player's token
socket, % Player's socket
table}). % Player's table
%% @doc This module handles communication between a player and GGS. This module is
%%responsible for:
%% * The storage of the player socket, player token and a table token.
%% * Ability to fetch a player token.
%% * Forwarding messages from players to the game
%% * Remove a player from GGS
%% @doc Spawns a process representing the player in GGS. Takes the player socket as
%% an argument for storage and later usage. Creates a unique player token
%% identifying the player.
%% @spec start_link(Socket::socket()) -> {ok, Pid} | {error, Reason}
start_link(Socket) ->
% The socket is in 'active' mode, and that means we are pushed any data
% that arrives on it, we do not need to recv() manually. Since the socket
% was opened in our parent process, we need to change the owner of it to
% us, otherwise these messages end up in our parent.
erlang:port_connect(Socket, self()),
{ok, Token} = ggs_coordinator:join_lobby(),
TableStatus = ggs_coordinator:join_table(1337),
case TableStatus of
{ok, Table} ->
loop(#pl_state{socket = Socket, token = Token, table = Table});
{error, no_such_table} ->
ggs_coordinator:create_table({force, 1337}),
{ok, Table} = ggs_coordinator:join_table(1337),
loop(#pl_state{socket = Socket, token = Token, table = Table})
end.
%% @doc Handles incoming messages from the GGS and forwards them through the player
%% socket to the player.
%% @spec notify(Player::Pid(), From::Pid(),
%% {Command::String(), Message::string()}) -> ok
notify(Player, From, Message) ->
Player ! {notify, From, Message}.
%% @doc Get the player token uniquely representing the player.
%% @spec get_token() -> string()
get_token(_Player) ->
ggs_logger:not_implemented().
%% @doc Properly terminates the player process. The player token will be lost
%% together with the table token. It should also close the player socket and the
%% process should return in the end.
%% @spec stop(Table::pid()) -> Reason::string()
stop(_Player,_Table) ->
ggs_logger:not_implemented().
%% Internals
loop(#pl_state{token = Token, socket = Socket, table = Table} = State) ->
receive
{tcp, Socket, Data} -> % Just echo for now..
io:format("Notifying table..~n"),
ggs_table:notify_game(Table, Token, Data),
loop(State);
{notify, _From, Message} ->
gen_tcp:send(Socket, Message),
loop(State)
end.