summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authornsensfel <SpamShield0@noot-noot.org>2018-06-06 15:54:18 +0200
committernsensfel <SpamShield0@noot-noot.org>2018-06-06 15:54:18 +0200
commitee9c2ac044cc77b80f30420c8f0788cad4281084 (patch)
tree6ce9c45b6c0f0c556839b6f462f84eab06e26594 /src/battlemap/query
parent97f7511e61cebae3676a83aa9c0dc2efb15d8d8c (diff)
Figuring out how to organize the src folder(s)...
Diffstat (limited to 'src/battlemap/query')
-rw-r--r--src/battlemap/query/bm_character_turn.erl250
-rw-r--r--src/battlemap/query/bm_load_state.erl111
2 files changed, 361 insertions, 0 deletions
diff --git a/src/battlemap/query/bm_character_turn.erl b/src/battlemap/query/bm_character_turn.erl
new file mode 100644
index 0000000..26b8dce
--- /dev/null
+++ b/src/battlemap/query/bm_character_turn.erl
@@ -0,0 +1,250 @@
+-module(bm_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()) -> bm_character_turn_request:type().
+decode_request (BinaryRequest) ->
+ JSONMap = jiffy:decode(BinaryRequest, [return_maps]),
+
+ bm_character_turn_request:decode(JSONMap).
+
+%%%% USER AUTHENTICATION %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+-spec authenticate_user (bm_character_turn_request:type()) -> 'ok'.
+authenticate_user (Request) ->
+ PlayerID = bm_character_turn_request:get_player_id(Request),
+ SessionToken = bm_character_turn_request:get_session_token(Request),
+
+ bm_security:assert_identity(PlayerID, SessionToken),
+ bm_security:lock_queries(PlayerID),
+
+ ok.
+
+%%%% MAIN LOGIC %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+-spec fetch_data
+ (
+ bm_character_turn_request:type()
+ )
+ -> bm_character_turn_data:type().
+fetch_data (Request) ->
+ PlayerID = bm_character_turn_request:get_player_id(Request),
+ BattleID = bm_character_turn_request:get_battle_id(Request),
+ CharacterIX = bm_character_turn_request:get_character_ix(Request),
+ Battle = sh_timed_cache:fetch(battle_db, PlayerID, BattleID),
+
+ bm_character_turn_data:new(Battle, CharacterIX).
+
+%%%% ASSERTS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+-spec assert_user_is_current_player
+ (
+ bm_character_turn_data:type(),
+ bm_character_turn_request:type()
+ ) -> 'ok'.
+assert_user_is_current_player (Data, Request) ->
+ PlayerID = bm_character_turn_request:get_player_id(Request),
+ Battle = bm_character_turn_data:get_battle(Data),
+ CurrentPlayerTurn = bm_battle:get_current_player_turn(Battle),
+ CurrentPlayerIX = bm_player_turn:get_player_ix(CurrentPlayerTurn),
+ CurrentPlayer = bm_battle:get_player(CurrentPlayerIX, Battle),
+
+ true = (PlayerID == bm_player:get_id(CurrentPlayer)),
+
+ ok.
+
+-spec assert_user_owns_played_character
+ (
+ bm_character_turn_data:type(),
+ bm_character_turn_request:type()
+ ) -> 'ok'.
+assert_user_owns_played_character (Data, Request) ->
+ PlayerID = bm_character_turn_request:get_player_id(Request),
+ Character = bm_character_turn_data:get_character(Data),
+ CharacterOwnerID = bm_character:get_owner_id(Character),
+
+ true = (PlayerID == CharacterOwnerID),
+
+ ok.
+
+-spec assert_character_can_be_played (bm_character_turn_data:type()) -> 'ok'.
+assert_character_can_be_played (Data) ->
+ Character = bm_character_turn_data:get_character(Data),
+
+ true = bm_character:get_is_active(Character),
+
+ ok.
+
+-spec assert_user_permissions
+ (
+ bm_character_turn_data:type(),
+ bm_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
+ (
+ bm_character_turn_update:type()
+ )
+ -> bm_character_turn_update:type().
+finalize_character (Update) ->
+ Data = bm_character_turn_update:get_data(Update),
+ Character = bm_character_turn_data:get_character(Data),
+
+ DisabledCharacter = bm_character:set_is_active(false, Character),
+ UpdatedData = bm_character_turn_data:set_character(DisabledCharacter, Data),
+ FinalizedData = bm_character_turn_data:clean_battle(UpdatedData),
+
+ bm_character_turn_update:set_data(FinalizedData, Update).
+
+-spec handle_actions
+ (
+ bm_character_turn_data:type(),
+ bm_character_turn_request:type()
+ )
+ -> bm_character_turn_update:type().
+handle_actions (Data, Request) ->
+ Actions = bm_character_turn_request:get_actions(Request),
+
+ EmptyUpdate = bm_character_turn_update:new(Data),
+ PostActionsUpdate =
+ lists:foldl(fun bm_turn_actions:handle/2, EmptyUpdate, Actions),
+
+ finalize_character(PostActionsUpdate).
+
+-spec update_timeline
+ (
+ bm_character_turn_update:type()
+ )
+ -> bm_character_turn_update:type().
+update_timeline (Update) ->
+ NewTimelineElements = bm_character_turn_update:get_timeline(Update),
+ Data = bm_character_turn_update:get_data(Update),
+ Battle = bm_character_turn_data:get_battle(Data),
+ PlayerTurn = bm_battle:get_current_player_turn(Battle),
+ PlayerIX = bm_player_turn:get_player_ix(PlayerTurn),
+ Player = bm_battle:get_player(PlayerIX, Battle),
+
+ UpdatedPlayer = bm_player:add_to_timeline(NewTimelineElements, Player),
+ UpdatedBattle = bm_battle:set_player(PlayerIX, UpdatedPlayer, Battle),
+ UpdatedData = bm_character_turn_data:set_battle(UpdatedBattle, Data),
+
+ bm_character_turn_update:set_data(UpdatedData, Update).
+
+-spec update_data
+ (
+ bm_character_turn_data:type(),
+ bm_character_turn_request:type()
+ )
+ -> bm_character_turn_update:type().
+update_data (Data, Request) ->
+ PostActionsUpdate = handle_actions(Data, Request),
+ PostCharacterTurnUpdate = update_timeline(PostActionsUpdate),
+
+ bm_next_turn:update_if_needed(PostCharacterTurnUpdate).
+
+%%%% DATABASE UPDATES %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+-spec send_to_database
+ (
+ bm_character_turn_update:type(),
+ bm_character_turn_request:type()
+ )
+ -> 'ok'.
+send_to_database (Update, Request) ->
+ PlayerID = bm_character_turn_request:get_player_id(Request),
+ BattleID = bm_character_turn_request:get_battle_id(Request),
+ Ops = bm_character_turn_update:get_db(Update),
+ Query = sh_db_query:new(battle_db, BattleID, {user, PlayerID}, Ops),
+
+ % TODO: send queries to an actual DB...
+
+ sh_database:commit(Query),
+
+ ok.
+
+-spec send_to_cache
+ (
+ bm_character_turn_update:type(),
+ bm_character_turn_request:type()
+ )
+ -> 'ok'.
+send_to_cache (Update, Request) ->
+ PlayerID = bm_character_turn_request:get_player_id(Request),
+ BattleID = bm_character_turn_request:get_battle_id(Request),
+ Data = bm_character_turn_update:get_data(Update),
+ Battle = bm_character_turn_data:get_battle(Data),
+
+ sh_timed_cache:update(battle_db, PlayerID, BattleID, Battle),
+
+ ok.
+
+-spec commit_update
+ (
+ bm_character_turn_update:type(),
+ bm_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 (bm_character_turn_request:type()) -> 'ok'.
+disconnect_user (Request) ->
+ PlayerID = bm_character_turn_request:get_player_id(Request),
+
+ bm_security:unlock_queries(PlayerID),
+
+ ok.
+
+%%%% REPLY GENERATION %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+-spec generate_reply (bm_character_turn_update:type()) -> binary().
+generate_reply (Update) ->
+ NewTimelineItems = bm_character_turn_update:get_timeline(Update),
+
+ TurnResultReply = bm_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)
+ }.
diff --git a/src/battlemap/query/bm_load_state.erl b/src/battlemap/query/bm_load_state.erl
new file mode 100644
index 0000000..b580b9f
--- /dev/null
+++ b/src/battlemap/query/bm_load_state.erl
@@ -0,0 +1,111 @@
+-module(bm_load_state).
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%% TYPES %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+-include("../../../include/yaws_api.hrl").
+
+-record
+(
+ input,
+ {
+ player_id :: bm_player:id(),
+ session_token :: binary(),
+ battle_id :: binary()
+ }
+).
+
+-record
+(
+ query_state,
+ {
+ battle :: bm_battle:type()
+ }
+).
+
+-type input() :: #input{}.
+-type query_state() :: #query_state{}.
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%% EXPORTS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+-export([out/1]).
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%% LOCAL FUNCTIONS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+-spec parse_input (binary()) -> input().
+parse_input (Req) ->
+ JSONReqMap = jiffy:decode(Req, [return_maps]),
+ PlayerID = maps:get(<<"pid">>, JSONReqMap),
+ SessionToken = maps:get(<<"stk">>, JSONReqMap),
+ BattleID = maps:get(<<"bmi">>, JSONReqMap),
+
+ #input
+ {
+ player_id = PlayerID,
+ session_token = SessionToken,
+ battle_id = BattleID
+ }.
+
+-spec fetch_data (input()) -> query_state().
+fetch_data (Input) ->
+ PlayerID = Input#input.player_id,
+ BattleID = Input#input.battle_id,
+
+ Battle = timed_cache:fetch (battle_db, PlayerID, BattleID),
+
+ #query_state
+ {
+ battle = Battle
+ }.
+
+-spec generate_reply(query_state(), input()) -> binary().
+generate_reply (QueryState, Input) ->
+ PlayerID = Input#input.player_id,
+ Battle = QueryState#query_state.battle,
+
+ jiffy:encode
+ (
+ [
+ bm_set_timeline:generate
+ (
+ bm_battle:get_encoded_last_turns_effects(Battle)
+ ),
+ bm_set_map:generate(bm_battle:get_battlemap(Battle))
+ |
+ array:sparse_to_list
+ (
+ array:map
+ (
+ fun (IX, Character) ->
+ bm_add_char:generate(IX, Character, PlayerID)
+ end,
+ bm_battle:get_characters(Battle)
+ )
+ )
+ ]
+ ).
+
+-spec handle (binary()) -> binary().
+handle (Req) ->
+ Input = parse_input(Req),
+ bm_security:assert_identity
+ (
+ Input#input.player_id,
+ Input#input.session_token
+ ),
+ bm_security:lock_queries(Input#input.player_id),
+ QueryState = fetch_data(Input),
+ bm_security:unlock_queries(Input#input.player_id),
+ generate_reply(QueryState, Input).
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%% EXPORTED FUNCTIONS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+out(A) ->
+ {
+ content,
+ "application/json; charset=UTF-8",
+ handle(A#arg.clidata)
+ }.