| summaryrefslogtreecommitdiff | 
diff options
| author | nsensfel <SpamShield0@noot-noot.org> | 2018-07-11 17:54:14 +0200 | 
|---|---|---|
| committer | nsensfel <SpamShield0@noot-noot.org> | 2018-07-11 17:54:14 +0200 | 
| commit | fde827cba1ff3d889135c74ee1978098465fd200 (patch) | |
| tree | d6022f800aa8226bf79a26a19189965c8cbfb2fe /src/battle/query/btl_character_turn.erl | |
| parent | df59024199c387903e3d4a901171939a358489d3 (diff) | |
"Battlemap" -> "Battle".
Diffstat (limited to 'src/battle/query/btl_character_turn.erl')
| -rw-r--r-- | src/battle/query/btl_character_turn.erl | 282 | 
1 files changed, 282 insertions, 0 deletions
| diff --git a/src/battle/query/btl_character_turn.erl b/src/battle/query/btl_character_turn.erl new file mode 100644 index 0000000..c232ab0 --- /dev/null +++ b/src/battle/query/btl_character_turn.erl @@ -0,0 +1,282 @@ +-module(btl_character_turn). + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% TYPES %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +-include("../../../include/yaws_api.hrl"). + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% EXPORTS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +-export([out/1]). + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% LOCAL FUNCTIONS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +%-spec send_to_database (list(database_diff:type()), character_turn_request:type()) -> 'ok'. + + +%%%% REQUEST DECODING %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +-spec decode_request (binary()) -> btl_character_turn_request:type(). +decode_request (BinaryRequest) -> +   JSONMap = jiffy:decode(BinaryRequest, [return_maps]), + +   btl_character_turn_request:decode(JSONMap). + +%%%% USER AUTHENTICATION %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +-spec authenticate_user (btl_character_turn_request:type()) -> 'ok'. +authenticate_user (Request) -> +   PlayerID = btl_character_turn_request:get_player_id(Request), +   SessionToken = btl_character_turn_request:get_session_token(Request), + +   btl_security:assert_identity(PlayerID, SessionToken), +   btl_security:lock_queries(PlayerID), + +   ok. + +%%%% MAIN LOGIC %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +-spec fetch_data +   ( +      btl_character_turn_request:type() +   ) +   -> btl_character_turn_data:type(). +fetch_data (Request) -> +   PlayerID = btl_character_turn_request:get_player_id(Request), +   BattleID = btl_character_turn_request:get_battle_id(Request), +   CharacterIX = btl_character_turn_request:get_character_ix(Request), +   Battle = sh_timed_cache:fetch(battle_db, PlayerID, BattleID), + +   btl_character_turn_data:new(Battle, CharacterIX). + +%%%% ASSERTS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +-spec assert_user_is_current_player +   ( +      btl_character_turn_data:type(), +      btl_character_turn_request:type() +   ) -> 'ok'. +assert_user_is_current_player (Data, Request) -> +   PlayerID = btl_character_turn_request:get_player_id(Request), +   Battle = btl_character_turn_data:get_battle(Data), +   CurrentPlayerTurn = btl_battle:get_current_player_turn(Battle), +   CurrentPlayerIX = btl_player_turn:get_player_ix(CurrentPlayerTurn), +   CurrentPlayer = btl_battle:get_player(CurrentPlayerIX, Battle), + +   true = (PlayerID == btl_player:get_id(CurrentPlayer)), + +   ok. + +-spec assert_user_owns_played_character +   ( +      btl_character_turn_data:type(), +      btl_character_turn_request:type() +   ) -> 'ok'. +assert_user_owns_played_character (Data, Request) -> +   PlayerID = btl_character_turn_request:get_player_id(Request), +   Battle = btl_character_turn_data:get_battle(Data), +   Players = btl_battle:get_players(Battle), +   Character = btl_character_turn_data:get_character(Data), +   CharacterPlayerIX = btl_character:get_player_index(Character), +   CharacterPlayer = array:get(CharacterPlayerIX, Players), +   CharacterPlayerID = btl_player:get_id(CharacterPlayer), + +   true = (PlayerID == CharacterPlayerID), + +   ok. + +-spec assert_character_can_be_played (btl_character_turn_data:type()) -> 'ok'. +assert_character_can_be_played (Data) -> +   Character = btl_character_turn_data:get_character(Data), + +   true = btl_character:get_is_active(Character), + +   ok. + +-spec assert_user_permissions +   ( +      btl_character_turn_data:type(), +      btl_character_turn_request:type() +   ) -> 'ok'. +assert_user_permissions (Data, Request) -> +   assert_user_is_current_player(Data, Request), +   assert_user_owns_played_character(Data, Request), +   assert_character_can_be_played(Data), + +   ok. + +%%%% QUERY LOGIC HANDLING %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +-spec finalize_character +   ( +      btl_character_turn_update:type() +   ) +   -> btl_character_turn_update:type(). +finalize_character (Update) -> +   Data = btl_character_turn_update:get_data(Update), +   Character = btl_character_turn_data:get_character(Data), + +   DisabledCharacter = btl_character:set_is_active(false, Character), +   UpdatedData = btl_character_turn_data:set_character(DisabledCharacter, Data), +   FinalizedData = btl_character_turn_data:clean_battle(UpdatedData), + +   DBQuery = +      sh_db_query:update_indexed +      ( +         btl_battle:get_characters_field(), +         btl_character_turn_data:get_character_ix(Data), +         [ sh_db_query:set_field(btl_character:get_is_active_field(), false) ] +      ), + +   S0Update = btl_character_turn_update:set_data(FinalizedData, Update), +   S1Update = btl_character_turn_update:add_to_db(DBQuery, S0Update), + +   S1Update. + +-spec handle_actions +   ( +      btl_character_turn_data:type(), +      btl_character_turn_request:type() +   ) +   -> btl_character_turn_update:type(). +handle_actions (Data, Request) -> +   Actions = btl_character_turn_request:get_actions(Request), + +   EmptyUpdate = btl_character_turn_update:new(Data), +   PostActionsUpdate = +      lists:foldl(fun btl_turn_actions:handle/2, EmptyUpdate, Actions), + +   finalize_character(PostActionsUpdate). + +-spec update_timeline +   ( +      btl_character_turn_update:type() +   ) +   -> btl_character_turn_update:type(). +update_timeline (Update) -> +   NewTimelineElements = btl_character_turn_update:get_timeline(Update), +   Data = btl_character_turn_update:get_data(Update), +   Battle = btl_character_turn_data:get_battle(Data), +   PlayerTurn = btl_battle:get_current_player_turn(Battle), +   PlayerIX = btl_player_turn:get_player_ix(PlayerTurn), +   Player = btl_battle:get_player(PlayerIX, Battle), + +   UpdatedPlayer = btl_player:add_to_timeline(NewTimelineElements, Player), +   UpdatedBattle = btl_battle:set_player(PlayerIX, UpdatedPlayer, Battle), +   UpdatedData = btl_character_turn_data:set_battle(UpdatedBattle, Data), + +   DBQuery = +      sh_db_query:update_indexed +      ( +         btl_battle:get_players_field(), +         PlayerIX, +         [ +            sh_db_query:add_to_field +            ( +               btl_player:get_timeline_field(), +               NewTimelineElements, +               true % We add those to the start of the list +            ) +         ] +      ), + +   S0Update = btl_character_turn_update:set_data(UpdatedData, Update), +   S1Update = btl_character_turn_update:add_to_db(DBQuery, S0Update), + +   S1Update. + + +-spec update_data +   ( +      btl_character_turn_data:type(), +      btl_character_turn_request:type() +   ) +   -> btl_character_turn_update:type(). +update_data (Data, Request) -> +   PostActionsUpdate = handle_actions(Data, Request), +   PostCharacterTurnUpdate = update_timeline(PostActionsUpdate), + +   btl_next_turn:update_if_needed(PostCharacterTurnUpdate). + +%%%% DATABASE UPDATES %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +-spec send_to_database +   ( +      btl_character_turn_update:type(), +      btl_character_turn_request:type() +   ) +   -> 'ok'. +send_to_database (Update, Request) -> +   PlayerID = btl_character_turn_request:get_player_id(Request), +   BattleID = btl_character_turn_request:get_battle_id(Request), +   Ops = btl_character_turn_update:get_db(Update), +   Query = sh_db_query:new(battle_db, BattleID, {user, PlayerID}, Ops), + +   sh_database:commit(Query), + +   ok. + +-spec send_to_cache +   ( +      btl_character_turn_update:type(), +      btl_character_turn_request:type() +   ) +   -> 'ok'. +send_to_cache (Update, Request) -> +   PlayerID = btl_character_turn_request:get_player_id(Request), +   BattleID = btl_character_turn_request:get_battle_id(Request), +   Data = btl_character_turn_update:get_data(Update), +   Battle = btl_character_turn_data:get_battle(Data), + +   sh_timed_cache:update(battle_db, PlayerID, BattleID, Battle), + +   ok. + +-spec commit_update +   ( +      btl_character_turn_update:type(), +      btl_character_turn_request:type() +   ) +   -> 'ok'. +commit_update (Update, Request) -> +   send_to_database(Update, Request), +   send_to_cache(Update, Request), + +   ok. + +%%%% USER DISCONNECTION %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +-spec disconnect_user (btl_character_turn_request:type()) -> 'ok'. +disconnect_user (Request) -> +   PlayerID = btl_character_turn_request:get_player_id(Request), + +   btl_security:unlock_queries(PlayerID), + +   ok. + +%%%% REPLY GENERATION %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +-spec generate_reply (btl_character_turn_update:type()) -> binary(). +generate_reply (Update) -> +   NewTimelineItems = btl_character_turn_update:get_timeline(Update), + +   TurnResultReply = btl_turn_results:generate(NewTimelineItems), + +   jiffy:encode([TurnResultReply]). + +%%%% MAIN LOGIC %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +-spec handle (binary()) -> binary(). +handle (EncodedRequest) -> +   Request = decode_request(EncodedRequest), +   authenticate_user(Request), +   Data = fetch_data(Request), +   assert_user_permissions(Data, Request), +   Update = update_data(Data, Request), +   commit_update(Update, Request), +   disconnect_user(Request), +   generate_reply(Update). + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% EXPORTED FUNCTIONS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +out(A) -> +   { +      content, +      "application/json; charset=UTF-8", +      handle(A#arg.clidata) +   }. | 


