|
@@ -1,31 +1,21 @@
|
|
-module(game_session).
|
|
-module(game_session).
|
|
-behaviour(gen_server).
|
|
-behaviour(gen_server).
|
|
-
|
|
|
|
-include_lib("server/include/requests.hrl").
|
|
-include_lib("server/include/requests.hrl").
|
|
-include_lib("server/include/settings.hrl").
|
|
-include_lib("server/include/settings.hrl").
|
|
-
|
|
|
|
-compile(export_all).
|
|
-compile(export_all).
|
|
-export([init/1, handle_call/3, handle_cast/2, handle_info/2, terminate/2, code_change/3]).
|
|
-export([init/1, handle_call/3, handle_cast/2, handle_info/2, terminate/2, code_change/3]).
|
|
|
|
|
|
--record(state, {
|
|
|
|
- user = undefined,
|
|
|
|
- rpc, %% rpc process
|
|
|
|
- rpc_mon, %% rpc monitor referense
|
|
|
|
- games = [],
|
|
|
|
- rels_notif_channel = undefined,
|
|
|
|
- rels_players =[]
|
|
|
|
- }).
|
|
|
|
-
|
|
|
|
|
|
+-record(state, { user = undefined, rpc, rpc_mon, games = [] }).
|
|
-record(participation, {
|
|
-record(participation, {
|
|
- game_id :: 'GameId'(), %% generated by id_generator
|
|
|
|
- reg_num :: integer(),
|
|
|
|
- rel_module :: atom(),
|
|
|
|
- rel_pid :: pid(), %% relay, which handles communication gameman maps game_id onto pid
|
|
|
|
- tab_module :: atom(),
|
|
|
|
- tab_pid :: pid(),
|
|
|
|
- ref :: any(), %% monitor reference to relay
|
|
|
|
- role = viewer :: atom() %% [viewer, player, ghost]
|
|
|
|
- }).
|
|
|
|
|
|
+ game_id :: 'GameId'(),
|
|
|
|
+ reg_num :: integer(),
|
|
|
|
+ rel_module :: atom(),
|
|
|
|
+ rel_pid :: pid(), %% relay, which handles communication gameman maps game_id onto pid
|
|
|
|
+ tab_module :: atom(),
|
|
|
|
+ tab_pid :: pid(),
|
|
|
|
+ ref :: any(), %% monitor reference to relay
|
|
|
|
+ role = viewer :: atom() %% [viewer, player, ghost]
|
|
|
|
+ }).
|
|
|
|
|
|
start_link(RPC) when is_pid(RPC) -> gen_server:start_link(?MODULE, [RPC], []).
|
|
start_link(RPC) when is_pid(RPC) -> gen_server:start_link(?MODULE, [RPC], []).
|
|
bot_session_attach(Pid, UserInfo) -> gen_server:cast(Pid, {bot_session_attach, UserInfo}).
|
|
bot_session_attach(Pid, UserInfo) -> gen_server:cast(Pid, {bot_session_attach, UserInfo}).
|
|
@@ -72,15 +62,52 @@ handle_info(Info, State) ->
|
|
gas:info(?MODULE,"Unrecognized info: ~p", [Info]),
|
|
gas:info(?MODULE,"Unrecognized info: ~p", [Info]),
|
|
{noreply, State}.
|
|
{noreply, State}.
|
|
|
|
|
|
-terminate(Reason, #state{rels_notif_channel = RelsChannel}) ->
|
|
|
|
|
|
+terminate(Reason, #state{}) ->
|
|
gas:info(?MODULE,"Terminating session: ~p", [Reason]),
|
|
gas:info(?MODULE,"Terminating session: ~p", [Reason]),
|
|
- if RelsChannel =/= undefined -> nsm_mq_channel:close(RelsChannel);
|
|
|
|
- true -> do_nothing end,
|
|
|
|
ok.
|
|
ok.
|
|
|
|
|
|
code_change(_OldVsn, State, _Extra) ->
|
|
code_change(_OldVsn, State, _Extra) ->
|
|
{ok, State}.
|
|
{ok, State}.
|
|
|
|
|
|
|
|
+
|
|
|
|
+%% Register User
|
|
|
|
+
|
|
|
|
+register_user_by_module(RPC,User,GameId,#state{games=Games} = State) ->
|
|
|
|
+ UserId = User#'PlayerInfo'.id,
|
|
|
|
+ case game:get_relay_mod_pid(GameId) of
|
|
|
|
+ {FLMod, FLPid} ->
|
|
|
|
+ gas:info(?MODULE,"Found the game: ~p by module ~p Trying to register...",[FLPid,FLMod]),
|
|
|
|
+ case FLMod:reg(FLPid, User) of
|
|
|
|
+ {ok, {RegNum, {RMod, RPid}, {TMod, TPid}}} ->
|
|
|
|
+ gas:info(?MODULE,"join to game relay: ~p",[{RMod, RPid}]),
|
|
|
|
+ {ok, _SubscrId} = RMod:subscribe(RPid, self(), UserId, RegNum),
|
|
|
|
+ Ref = erlang:monitor(process, RPid),
|
|
|
|
+ Part = #participation{
|
|
|
|
+ ref = Ref, game_id = GameId, reg_num = RegNum,
|
|
|
|
+ rel_module = RMod, rel_pid = RPid,
|
|
|
|
+ tab_module = TMod, tab_pid = TPid, role = player},
|
|
|
|
+ NewGames = game:plist_setkey(GameId,#participation.game_id,Games,Part),
|
|
|
|
+ {reply, ok, State#state{games = NewGames}};
|
|
|
|
+ {error, finished} ->
|
|
|
|
+ gas:info(?MODULE,"The game is finished: ~p.",[GameId]),
|
|
|
|
+ ok = send_message_to_player(RPC, #disconnect{reason_id = <<"gameFinished">>, reason = null}),
|
|
|
|
+ {reply, {error, finished}, State};
|
|
|
|
+ {error, out} ->
|
|
|
|
+ gas:info(?MODULE,"Out of the game: ~p.",[GameId]),
|
|
|
|
+ ok = send_message_to_player(RPC, #disconnect{reason_id = <<"disconnected">>,reason = null}),
|
|
|
|
+ {reply, {error, out}, State};
|
|
|
|
+ {error, not_allowed} ->
|
|
|
|
+ gas:error(?MODULE,"Not allowed to connect: ~p.",[GameId]),
|
|
|
|
+ ok = send_message_to_player(RPC, #disconnect{reason_id = <<"notAllowed">>,reason = null}),
|
|
|
|
+ {reply, {error, not_allowed}, State}
|
|
|
|
+ end;
|
|
|
|
+ undefined ->
|
|
|
|
+ gas:error(?MODULE,"Game not found: ~p.",[GameId]),
|
|
|
|
+ ok = send_message_to_player(RPC, #disconnect{reason_id = <<"notExists">>, reason = null}),
|
|
|
|
+ {reply, {error, not_exists}, State}
|
|
|
|
+ end.
|
|
|
|
+
|
|
|
|
+
|
|
%%===================================================================
|
|
%%===================================================================
|
|
|
|
|
|
handle_client_request(#session_attach{token = Token}, _From, #state{user = undefined} = State) ->
|
|
handle_client_request(#session_attach{token = Token}, _From, #state{user = undefined} = State) ->
|
|
@@ -146,46 +173,8 @@ handle_client_request(#join_game{game = GameId}, _From,
|
|
UserId = User#'PlayerInfo'.id,
|
|
UserId = User#'PlayerInfo'.id,
|
|
gas:info(?MODULE,"Join game ~p user ~p from ~p", [GameId, UserId,_From]),
|
|
gas:info(?MODULE,"Join game ~p user ~p from ~p", [GameId, UserId,_From]),
|
|
case get_relay(GameId, Games) of
|
|
case get_relay(GameId, Games) of
|
|
- #participation{} ->
|
|
|
|
- {reply, {error, already_joined}, State};
|
|
|
|
- false ->
|
|
|
|
- gas:info(?MODULE,"Requesting main relay info...",[]),
|
|
|
|
- case game:get_relay_mod_pid(GameId) of
|
|
|
|
- {FLMod, FLPid} ->
|
|
|
|
- gas:info(?MODULE,"Found the game: ~p. Trying to register...",[{FLMod, FLPid}]),
|
|
|
|
- case FLMod:reg(FLPid, User) of
|
|
|
|
- {ok, {RegNum, {RMod, RPid}, {TMod, TPid}}} ->
|
|
|
|
- gas:info(?MODULE,"join to game relay: ~p",[{RMod, RPid}]),
|
|
|
|
- {ok, _SubscrId} = RMod:subscribe(RPid, self(), UserId, RegNum),
|
|
|
|
- Ref = erlang:monitor(process, RPid),
|
|
|
|
- Part = #participation{ref = Ref, game_id = GameId, reg_num = RegNum,
|
|
|
|
- rel_module = RMod, rel_pid = RPid,
|
|
|
|
- tab_module = TMod, tab_pid = TPid, role = player},
|
|
|
|
- {reply, ok, State#state{games = [Part | State#state.games]}};
|
|
|
|
- {error, finished} ->
|
|
|
|
- gas:info(?MODULE,"The game is finished: ~p.",[GameId]),
|
|
|
|
- ok = send_message_to_player(RPC, #disconnect{reason_id = <<"gameFinished">>,
|
|
|
|
- reason = null}),
|
|
|
|
- {reply, {error, finished}, State};
|
|
|
|
- {error, out} ->
|
|
|
|
- gas:info(?MODULE,"Out of the game: ~p.",[GameId]),
|
|
|
|
- ok = send_message_to_player(RPC, #disconnect{reason_id = <<"disconnected">>,
|
|
|
|
- reason = null}),
|
|
|
|
- {reply, {error, out}, State};
|
|
|
|
- {error, not_allowed} ->
|
|
|
|
- gas:error(?MODULE,"Not allowed to connect: ~p.",[GameId]),
|
|
|
|
- ok = send_message_to_player(RPC, #disconnect{reason_id = <<"notAllowed">>,
|
|
|
|
- reason = null}),
|
|
|
|
- {reply, {error, not_allowed}, State}
|
|
|
|
- end;
|
|
|
|
- undefined ->
|
|
|
|
- gas:error(?MODULE,"Game not found: ~p.",[GameId]),
|
|
|
|
- ok = send_message_to_player(RPC, #disconnect{reason_id = <<"notExists">>,
|
|
|
|
- reason = null}),
|
|
|
|
- {reply, {error, not_exists}, State}
|
|
|
|
- end
|
|
|
|
- end;
|
|
|
|
-
|
|
|
|
|
|
+ #participation{} -> {reply, {error, already_joined}, State};
|
|
|
|
+ false -> register_user_by_module(RPC,User,GameId,State) end;
|
|
|
|
|
|
handle_client_request(#game_action{game = GameId} = Msg, _From, State) ->
|
|
handle_client_request(#game_action{game = GameId} = Msg, _From, State) ->
|
|
gas:info(?MODULE,"Game action ~p", [{GameId,Msg,_From}]),
|
|
gas:info(?MODULE,"Game action ~p", [{GameId,Msg,_From}]),
|
|
@@ -242,42 +231,7 @@ handle_relay_message(Msg, _SubscrId, #state{rpc = RPC} = State) ->
|
|
handle_relay_kick({rejoin, GameId}, _SubscrId,
|
|
handle_relay_kick({rejoin, GameId}, _SubscrId,
|
|
#state{user = User, games = Games, rpc = RPC} = State) ->
|
|
#state{user = User, games = Games, rpc = RPC} = State) ->
|
|
gas:info(?MODULE,"Requesting main relay info...",[]),
|
|
gas:info(?MODULE,"Requesting main relay info...",[]),
|
|
- UserId = User#'PlayerInfo'.id,
|
|
|
|
- case game:get_relay_mod_pid(GameId) of
|
|
|
|
- {FLMod, FLPid} ->
|
|
|
|
- gas:info(?MODULE,"Found the game: ~p. Trying to register...",[{FLMod, FLPid}]),
|
|
|
|
- case FLMod:reg(FLPid, User) of
|
|
|
|
- {ok, {RegNum, {RMod, RPid}, {TMod, TPid}}} ->
|
|
|
|
- gas:info(?MODULE,"Join to game relay: ~p",[{RMod, RPid}]),
|
|
|
|
- {ok, _NewSubscrId} = RMod:subscribe(RPid, self(), UserId, RegNum),
|
|
|
|
- Ref = erlang:monitor(process, RPid),
|
|
|
|
- Part = #participation{ref = Ref, game_id = GameId, reg_num = RegNum,
|
|
|
|
- rel_module = RMod, rel_pid = RPid,
|
|
|
|
- tab_module = TMod, tab_pid = TPid, role = player},
|
|
|
|
- NewGames = lists:keyreplace(GameId, #participation.game_id, Games, Part),
|
|
|
|
- {noreply, State#state{games = NewGames}};
|
|
|
|
- {error, finished} ->
|
|
|
|
- gas:info(?MODULE,"The game is finished: ~p.",[GameId]),
|
|
|
|
- send_message_to_player(RPC, #disconnect{reason_id = <<"gameFinished">>,
|
|
|
|
- reason = null}),
|
|
|
|
- {stop, normal, State};
|
|
|
|
- {error, out} ->
|
|
|
|
- gas:info(?MODULE,"Out of the game: ~p.",[GameId]),
|
|
|
|
- send_message_to_player(RPC, #disconnect{reason_id = <<"kicked">>,
|
|
|
|
- reason = null}),
|
|
|
|
- {stop, normal, State};
|
|
|
|
- {error, not_allowed} ->
|
|
|
|
- gas:error(?MODULE,"Not allowed to connect: ~p.",[GameId]),
|
|
|
|
- send_message_to_player(RPC, #disconnect{reason_id = <<"notAllowed">>,
|
|
|
|
- reason = null}),
|
|
|
|
- {stop, {error, not_allowed_to_join}, State}
|
|
|
|
- end;
|
|
|
|
- undefined ->
|
|
|
|
- gas:error(?MODULE,"Game not found: ~p.",[GameId]),
|
|
|
|
- send_message_to_player(RPC, #disconnect{reason_id = <<"notExists">>,
|
|
|
|
- reason = null}),
|
|
|
|
- {stop, {error, game_not_found}, State}
|
|
|
|
- end;
|
|
|
|
|
|
+ register_user_by_module(RPC,User,GameId,State);
|
|
|
|
|
|
handle_relay_kick(Reason, _SubscrId, #state{rpc = RPC} = State) ->
|
|
handle_relay_kick(Reason, _SubscrId, #state{rpc = RPC} = State) ->
|
|
{ReasonId, ReasonText} =
|
|
{ReasonId, ReasonText} =
|
|
@@ -294,4 +248,3 @@ handle_relay_kick(Reason, _SubscrId, #state{rpc = RPC} = State) ->
|
|
|
|
|
|
get_relay(GameId, GameList) ->
|
|
get_relay(GameId, GameList) ->
|
|
lists:keyfind(GameId, #participation.game_id, GameList).
|
|
lists:keyfind(GameId, #participation.game_id, GameList).
|
|
-
|
|
|