Просмотр исходного кода

merge kick and join requests in game session

Maxim Sokhatsky 11 лет назад
Родитель
Сommit
8f2fcc7e2d

BIN
apps/face/priv/static/doc/Kakaranet-Scene.sketch/Data


+ 5 - 0
apps/server/src/game.erl

@@ -517,3 +517,8 @@ get_player_info(_,User) ->
         games=Games,
         reveals=Reveals#reveal_log.stats,
         protocol=Protocol#protocol_log.stats}.
+
+plist_setkey(Name,Pos,List,New) ->
+    case lists:keyfind(Name,Pos,List) of
+        false -> [New|List];
+        Element -> lists:keyreplace(Name,Pos,List,New) end.

+ 53 - 100
apps/server/src/game_session.erl

@@ -1,31 +1,21 @@
 -module(game_session).
 -behaviour(gen_server).
-
 -include_lib("server/include/requests.hrl").
 -include_lib("server/include/settings.hrl").
-
 -compile(export_all).
 -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, {
-          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], []).
 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]),
     {noreply, State}.
 
-terminate(Reason, #state{rels_notif_channel = RelsChannel}) ->
+terminate(Reason, #state{}) ->
     gas:info(?MODULE,"Terminating session: ~p", [Reason]),
-    if RelsChannel =/= undefined -> nsm_mq_channel:close(RelsChannel);
-       true -> do_nothing end,
     ok.
 
 code_change(_OldVsn, State, _Extra) ->
     {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) ->
@@ -146,46 +173,8 @@ handle_client_request(#join_game{game = GameId}, _From,
     UserId = User#'PlayerInfo'.id,
     gas:info(?MODULE,"Join game ~p user ~p from ~p", [GameId, UserId,_From]),
     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) ->
     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,
                   #state{user = User, games = Games, rpc = RPC} = State) ->
     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) ->
     {ReasonId, ReasonText} =
@@ -294,4 +248,3 @@ handle_relay_kick(Reason, _SubscrId, #state{rpc = RPC} = State) ->
 
 get_relay(GameId, GameList) ->
     lists:keyfind(GameId, #participation.game_id, GameList).
-