summaryrefslogtreecommitdiff
path: root/src/map
diff options
context:
space:
mode:
authorNathanael Sensfelder <SpamShield0@MultiAgentSystems.org>2018-08-04 10:21:51 +0200
committerNathanael Sensfelder <SpamShield0@MultiAgentSystems.org>2018-08-04 10:21:51 +0200
commitb49e7e895b941ae8b5331ccb1d0868afbd8e5516 (patch)
tree62bf2640dc3122b46bf36a624ea6b9dca8dc28e5 /src/map
parent586c75d06f0e6102c997f56f0c64777417413122 (diff)
Lets the user save their map.
Diffstat (limited to 'src/map')
-rw-r--r--src/map/query/map_update.erl175
-rw-r--r--src/map/struct/map_map.erl39
2 files changed, 213 insertions, 1 deletions
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)
+ }.