summaryrefslogtreecommitdiff |
diff options
-rw-r--r-- | conf/yaws.conf.m4 | 2 | ||||
-rw-r--r-- | src/map/query/map_update.erl | 175 | ||||
-rw-r--r-- | src/map/struct/map_map.erl | 39 | ||||
-rw-r--r-- | src/shared/reply/shr_okay.erl | 25 |
4 files changed, 239 insertions, 2 deletions
diff --git a/conf/yaws.conf.m4 b/conf/yaws.conf.m4 index 0e96a29..d108c73 100644 --- a/conf/yaws.conf.m4 +++ b/conf/yaws.conf.m4 @@ -110,6 +110,6 @@ keepalive_timeout = 30000 listen = 0.0.0.0 docroot = __MAKEFILE_WWW_DIR auth_log = true - appmods = btl_character_turn btl_load map_load + appmods = btl_character_turn btl_load map_load map_update start_mod = qry_handler </server> diff --git a/src/map/query/map_update.erl b/src/map/query/map_update.erl new file mode 100644 index 0000000..258a516 --- /dev/null +++ b/src/map/query/map_update.erl @@ -0,0 +1,175 @@ +-module(map_update). + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% TYPES %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +-include("../../../include/yaws_api.hrl"). + +-record +( + input, + { + player_id :: binary(), + session_token :: binary(), + map_id :: binary(), + w :: non_neg_integer(), + h :: non_neg_integer(), + t :: list(list(non_neg_integer())) + } +). + +-record +( + query_state, + { + map :: map_map: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), + MapID = maps:get(<<"mid">>, JSONReqMap), + MapWidth = maps:get(<<"w">>, JSONReqMap), + MapHeight = maps:get(<<"h">>, JSONReqMap), + MapContent = maps:get(<<"t">>, JSONReqMap), + + true = (MapWidth > 0), + true = (MapHeight > 0), + true = (length(MapContent) == MapWidth * MapHeight), + true = + lists:all + ( + fun (T) -> + [M|[V|B]] = T, + ( + (M > 0) + and (V >= 0) + and ((length(B) rem 2) == 0) + and + lists:all + ( + fun (Bo) -> + %% FIXME: this does not prevent "Error" tiles. + (Bo >= 0) + end, + B + ) + ) + end, + MapContent + ), + + #input + { + player_id = PlayerID, + session_token = SessionToken, + map_id = MapID, + w = MapWidth, + h = MapHeight, + t = MapContent + }. + +-spec fetch_data (input()) -> query_state(). +fetch_data (Input) -> + PlayerID = Input#input.player_id, + MapID = Input#input.map_id, + + Map = shr_timed_cache:fetch(map_db, PlayerID, MapID), + + #query_state + { + map = Map + }. + +-spec update_data (query_state(), input()) -> query_state(). +update_data (QueryState, Input) -> + QueryState#query_state + { + map = + map_map:update_from_list + ( + QueryState#query_state.map, + Input#input.w, + Input#input.h, + Input#input.t + ) + }. + +-spec commit_update (query_state(), input()) -> 'ok'. +commit_update (QueryState, Input) -> + PlayerID = Input#input.player_id, + MapID = Input#input.map_id, + Map = QueryState#query_state.map, + + Query = + shr_db_query:new + ( + map_db, + MapID, + {user, PlayerID}, + [ + shr_db_query:set_field + ( + map_map:get_height_field(), + Input#input.h + ), + shr_db_query:set_field + ( + map_map:get_width_field(), + Input#input.w + ), + shr_db_query:set_field + ( + map_map:get_tile_instances_field(), + map_map:get_tile_instances(Map) + ) + ] + ), + + shr_database:commit(Query), + shr_timed_cache:update(map_db, PlayerID, MapID, Map), + + 'ok'. + +-spec generate_reply () -> binary(). +generate_reply () -> + jiffy:encode([shr_okay:generate()]). + +-spec handle (binary()) -> binary(). +handle (Req) -> + Input = parse_input(Req), + shr_security:assert_identity + ( + Input#input.player_id, + Input#input.session_token + ), + shr_security:lock_queries(Input#input.player_id), + QueryState = fetch_data(Input), + Update = update_data(QueryState, Input), + commit_update(Update, Input), + shr_security:unlock_queries(Input#input.player_id), + generate_reply(). + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% EXPORTED FUNCTIONS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +out(A) -> + { + content, + "application/json; charset=UTF-8", + handle(A#arg.clidata) + }. diff --git a/src/map/struct/map_map.erl b/src/map/struct/map_map.erl index 3c25034..46e501f 100644 --- a/src/map/struct/map_map.erl +++ b/src/map/struct/map_map.erl @@ -40,7 +40,17 @@ -export ( [ - from_list/5 + get_width_field/0, + get_height_field/0, + get_tile_instances_field/0 + ] +). + +-export +( + [ + from_list/5, + update_from_list/4 ] ). @@ -85,6 +95,15 @@ get_tile_instance (Location, Map) -> TileIX = location_to_array_index(Map#map.width, Location), array:get(TileIX, Map#map.tile_instances). +-spec get_width_field () -> non_neg_integer(). +get_width_field () -> #map.width. + +-spec get_height_field () -> non_neg_integer(). +get_height_field () -> #map.height. + +-spec get_tile_instances_field () -> non_neg_integer(). +get_tile_instances_field () -> #map.tile_instances. + -spec from_list ( non_neg_integer(), @@ -105,3 +124,21 @@ from_list (ID, Owner, Width, Height, List) -> height = Height, tile_instances = array:from_list(TileInstances) }. + +-spec update_from_list + ( + type(), + non_neg_integer(), + non_neg_integer(), + list(list(non_neg_integer())) + ) + -> type(). +update_from_list (Map, Width, Height, List) -> + TileInstances = lists:map(fun map_tile:instance_from_ints/1, List), + + Map#map + { + width = Width, + height = Height, + tile_instances = array:from_list(TileInstances) + }. diff --git a/src/shared/reply/shr_okay.erl b/src/shared/reply/shr_okay.erl new file mode 100644 index 0000000..29fed43 --- /dev/null +++ b/src/shared/reply/shr_okay.erl @@ -0,0 +1,25 @@ +-module(shr_okay). + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% TYPES %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% EXPORTS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +-export([generate/0]). + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% LOCAL FUNCTIONS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% EXPORTED FUNCTIONS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +-spec generate () -> {list(any())}. +generate () -> + { + [ + {<<"msg">>, <<"okay">>} + ] + }. |