From ff5dd0eb5df2aa55dc5306eefbd851da8e8e6f4c Mon Sep 17 00:00:00 2001 From: nsensfel Date: Mon, 10 Sep 2018 17:27:16 +0200 Subject: character -> roster --- src/character/chr_handler.erl | 40 ------ src/character/chr_shim.erl | 25 ---- src/character/query/chr_load.erl | 116 ---------------- src/character/query/chr_update.erl | 155 --------------------- src/character/reply/chr_add_char.erl | 39 ------ src/character/struct/chr_character.erl | 238 --------------------------------- src/character/struct/chr_roster.erl | 127 ------------------ src/query/qry_handler.erl | 1 + src/roster/query/rst_load.erl | 116 ++++++++++++++++ src/roster/query/rst_update.erl | 155 +++++++++++++++++++++ src/roster/reply/rst_add_char.erl | 39 ++++++ src/roster/rst_handler.erl | 35 +++++ src/roster/rst_shim.erl | 25 ++++ src/roster/struct/rst_character.erl | 238 +++++++++++++++++++++++++++++++++ src/roster/struct/rst_roster.erl | 127 ++++++++++++++++++ src/shared/reply/shr_disconnected.erl | 1 + 16 files changed, 737 insertions(+), 740 deletions(-) delete mode 100644 src/character/chr_handler.erl delete mode 100644 src/character/chr_shim.erl delete mode 100644 src/character/query/chr_load.erl delete mode 100644 src/character/query/chr_update.erl delete mode 100644 src/character/reply/chr_add_char.erl delete mode 100644 src/character/struct/chr_character.erl delete mode 100644 src/character/struct/chr_roster.erl create mode 100644 src/roster/query/rst_load.erl create mode 100644 src/roster/query/rst_update.erl create mode 100644 src/roster/reply/rst_add_char.erl create mode 100644 src/roster/rst_handler.erl create mode 100644 src/roster/rst_shim.erl create mode 100644 src/roster/struct/rst_character.erl create mode 100644 src/roster/struct/rst_roster.erl (limited to 'src') diff --git a/src/character/chr_handler.erl b/src/character/chr_handler.erl deleted file mode 100644 index 7697bcd..0000000 --- a/src/character/chr_handler.erl +++ /dev/null @@ -1,40 +0,0 @@ --module(chr_handler). - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%% TYPES %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%% EXPORTS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% --export([start/1]). - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%% LOCAL FUNCTIONS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%% EXPORTED FUNCTIONS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% --spec start (pid()) -> 'ok'. -start (TimedCachesManagerPid) -> - case shr_database:fetch(char_roster_db, <<"0">>, admin) of - {ok, _} -> ok; - not_found -> - shr_database:insert_at - ( - char_roster_db, - <<"0">>, - any, - any, - chr_shim:generate_random_character_roster() - ) - end, - shr_timed_caches_manager:new_cache - ( - TimedCachesManagerPid, - char_roster_db, - none - ), - - ok. diff --git a/src/character/chr_shim.erl b/src/character/chr_shim.erl deleted file mode 100644 index 04b3708..0000000 --- a/src/character/chr_shim.erl +++ /dev/null @@ -1,25 +0,0 @@ --module(chr_shim). - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%% TYPES %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%% EXPORTS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% --export([generate_random_character_roster/0]). - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%% LOCAL FUNCTIONS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%% EXPORTED FUNCTIONS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% --spec generate_random_character_roster () -> chr_roster:type(). -generate_random_character_roster () -> - Result = chr_roster:new(<<"0">>, <<"0">>), - - %% TODO [DEBUG][REQUIRED]: unimplemented. - - Result. diff --git a/src/character/query/chr_load.erl b/src/character/query/chr_load.erl deleted file mode 100644 index 3c269d6..0000000 --- a/src/character/query/chr_load.erl +++ /dev/null @@ -1,116 +0,0 @@ --module(chr_load). - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%% TYPES %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% --include("../../../include/yaws_api.hrl"). - --record -( - input, - { - player_id :: binary(), - session_token :: binary() - } -). - --record -( - query_state, - { - player :: shr_player:type(), - inventory :: shr_inventory:type(), - roster :: chr_roster: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), - - #input - { - player_id = PlayerID, - session_token = SessionToken - }. - --spec authenticate_user (input()) -> ({'ok', shr_player:type()} | 'error'). -authenticate_user (Input) -> - PlayerID = Input#input.player_id, - SessionToken = Input#input.session_token, - - Player = shr_timed_cache:fetch(player_db, any, PlayerID), - - case shr_security:credentials_match(SessionToken, Player) of - true -> {ok, Player}; - _ -> error - end. - --spec fetch_data (shr_player:type(), input()) -> query_state(). -fetch_data (Player, Input) -> - PlayerID = Input#input.player_id, - RosterID = shr_player:get_roster_id(Player), - InventoryID = shr_player:get_inventory_id(Player), - - Roster = shr_timed_cache:fetch(char_roster_db, PlayerID, RosterID), - Inventory = shr_timed_cache:fetch(char_roster_db, PlayerID, InventoryID), - - #query_state - { - player = Player, - roster = Roster, - inventory = Inventory - }. - --spec generate_reply(query_state()) -> binary(). -generate_reply (QueryState) -> - Roster = QueryState#query_state.roster, - Inventory = QueryState#query_state.inventory, - - RosterCharacters = chr_roster:get_characters(Roster), - SetInventory = shr_set_inventory:generate(Inventory), - EncodedRoster = - array:to_list - ( - array:sparse_map(fun chr_add_char:generate/2, RosterCharacters) - ), - - Output = jiffy:encode([SetInventory|EncodedRoster]), - - Output. - --spec handle (binary()) -> binary(). -handle (Req) -> - Input = parse_input(Req), - case authenticate_user(Input) of - {ok, Player} -> - shr_security:lock_queries(Input#input.player_id), - QueryState = fetch_data(Player, Input), - shr_security:unlock_queries(Input#input.player_id), - generate_reply(QueryState); - - error -> jiffy:encode([shr_disconnected:generate()]) - end. - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%% EXPORTED FUNCTIONS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -out(A) -> - { - content, - "application/json; charset=UTF-8", - handle(A#arg.clidata) - }. diff --git a/src/character/query/chr_update.erl b/src/character/query/chr_update.erl deleted file mode 100644 index 568a749..0000000 --- a/src/character/query/chr_update.erl +++ /dev/null @@ -1,155 +0,0 @@ --module(chr_update). - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%% TYPES %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% --include("../../../include/yaws_api.hrl"). - --record -( - input, - { - player_id :: binary(), - session_token :: binary(), - character_ix :: non_neg_integer(), - character :: chr_character:type() - } -). - --record -( - query_state, - { - player :: shr_player:type(), - inventory :: shr_inventory:type(), - roster :: chr_roster: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), - CharacterIX = maps:get(<<"cix">>, JSONReqMap), - EncodedCharacter = maps:get(<<"chr">>, JSONReqMap), - - Character = chr_character:decode(EncodedCharacter), - - #input - { - player_id = PlayerID, - session_token = SessionToken, - character_ix = CharacterIX, - character = Character - }. - --spec authenticate_user (input()) -> ({'ok', shr_player:type()} | 'error'). -authenticate_user (Input) -> - PlayerID = Input#input.player_id, - SessionToken = Input#input.session_token, - - Player = shr_timed_cache:fetch(player_db, any, PlayerID), - - case shr_security:credentials_match(SessionToken, Player) of - true -> {ok, Player}; - _ -> error - end. - --spec fetch_data (shr_player:type(), input()) -> query_state(). -fetch_data (Player, Input) -> - PlayerID = Input#input.player_id, - RosterID = shr_player:get_roster_id(Player), - InventoryID = shr_player:get_inventory_id(Player), - - Roster = shr_timed_cache:fetch(char_roster_db, PlayerID, RosterID), - Inventory = shr_timed_cache:fetch(char_roster_db, PlayerID, InventoryID), - - #query_state - { - player = Player, - roster = Roster, - inventory = Inventory - }. - --spec update_data (query_state(), input()) -> query_state(). -update_data (QueryState, Input) -> - Inventory = QueryState#query_state.inventory, - Character = Input#input.character, - - chr_character:validate(Inventory, Character), - - %% TODO [FUNCTION: chr][REQUIRED]: unimplemented. - QueryState. - --spec commit_update (query_state(), input()) -> 'ok'. -commit_update (QueryState, Input) -> - PlayerID = Input#input.player_id, - CharacterIX = Input#input.character_ix, - Character = Input#input.character, - Player = QueryState#query_state.player, - Roster = QueryState#query_state.roster, - - RosterID = shr_player:get_roster_id(Player), - UpdatedRoster = chr_roster:set_character(CharacterIX, Character, Roster), - - Query = - shr_db_query:new - ( - char_roster_db, - RosterID, - {user, PlayerID}, - [ - shr_db_query:update_indexed - ( - chr_roster:get_characters_field(), - CharacterIX, - [shr_db_query:set_value(Character)] - ) - ] - ), - - shr_database:commit(Query), - shr_timed_cache:update(char_roster_db, PlayerID, RosterID, UpdatedRoster), - - 'ok'. - --spec generate_reply () -> binary(). -generate_reply () -> - jiffy:encode([shr_okay:generate()]). - --spec handle (binary()) -> binary(). -handle (Req) -> - Input = parse_input(Req), - case authenticate_user(Input) of - {ok, Player} -> - shr_security:lock_queries(Input#input.player_id), - QueryState = fetch_data(Player, Input), - Update = update_data(QueryState, Input), - commit_update(Update, Input), - shr_security:unlock_queries(Input#input.player_id), - generate_reply(); - - error -> jiffy:encode([shr_disconnected:generate()]) - end. - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%% EXPORTED FUNCTIONS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -out(A) -> - { - content, - "application/json; charset=UTF-8", - handle(A#arg.clidata) - }. diff --git a/src/character/reply/chr_add_char.erl b/src/character/reply/chr_add_char.erl deleted file mode 100644 index 53a62d6..0000000 --- a/src/character/reply/chr_add_char.erl +++ /dev/null @@ -1,39 +0,0 @@ --module(chr_add_char). - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%% TYPES %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%% EXPORTS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% --export([generate/2]). - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%% LOCAL FUNCTIONS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%% EXPORTED FUNCTIONS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% --spec generate - ( - non_neg_integer(), - chr_character:type() - ) - -> {list(any())}. -generate (IX, Character) -> - {ActiveWeapon, SecondaryWeapon} = chr_character:get_weapon_ids(Character), - - { - [ - {<<"msg">>, <<"add_char">>}, - {<<"ix">>, IX}, - {<<"nam">>, chr_character:get_name(Character)}, - {<<"awp">>, ActiveWeapon}, - {<<"swp">>, SecondaryWeapon}, - {<<"ar">>, chr_character:get_armor_id(Character)}, - {<<"gls">>, array:to_list(chr_character:get_glyph_ids(Character))}, - {<<"gb">>, chr_character:get_glyph_board_id(Character)} - ] - }. diff --git a/src/character/struct/chr_character.erl b/src/character/struct/chr_character.erl deleted file mode 100644 index 0b1056e..0000000 --- a/src/character/struct/chr_character.erl +++ /dev/null @@ -1,238 +0,0 @@ --module(chr_character). - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%% TYPES %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% --record -( - character, - { - name :: binary(), - portrait :: binary(), - weapon_ids :: {shr_weapon:id(), shr_weapon:id()}, - armor_id :: shr_armor:id(), - glyph_ids :: array:array(shr_glyph:id()), - glyph_board_id :: shr_glyph_board:id() - } -). - --opaque type() :: #character{}. - --export_type([type/0]). -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%% EXPORTS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%%%% Accessors --export -( - [ - get_name/1, - get_portrait/1, - get_weapon_ids/1, - get_armor_id/1, - get_glyph_ids/1, - get_glyph_board_id/1, - - set_name/2, - set_portrait/2, - set_weapon_ids/2, - set_armor_id/2, - set_glyph_ids/2, - set_glyph_board_id/2, - - get_name_field/0, - get_portrait_field/0, - get_weapon_ids_field/0, - get_armor_id_field/0, - get_glyph_ids_field/0, - get_glyph_board_id_field/0 - ] -). - --export -( - [ - decode/1, - random/0 - ] -). - --export -( - [ - validate/2 - ] -). - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%% LOCAL FUNCTIONS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% --spec validate_name (binary()) -> ok. -validate_name (_Name) -> - % TODO [SECURITY][LOW]: unimplemented - ok. - --spec validate_portrait (shr_inventory:type(), binary()) -> ok. -validate_portrait (_Inventory, _Portrait) -> - % TODO [SECURITY][LOW]: unimplemented - ok. - --spec validate_weapons - ( - shr_inventory:type(), - {shr_weapon:id(), shr_weapon:id()} - ) - -> ok. -validate_weapons (_Inventory, {_ActiveWeapon, _SecondaryWeapon}) -> - % TODO [SECURITY][LOW]: unimplemented - ok. - --spec validate_armor (shr_inventory:type(), shr_armor:id()) -> ok. -validate_armor (_Inventory, _Armor) -> - % TODO [SECURITY][LOW]: unimplemented - ok. - --spec validate_glyphs (shr_inventory:type(), array:array(shr_glyph:id())) -> ok. -validate_glyphs (_Inventory, _Glyphs) -> - % TODO [SECURITY][LOW]: unimplemented - ok. - --spec validate_glyph_board (shr_inventory:type(), shr_glyph_board:id()) -> ok. -validate_glyph_board (_Inventory, _GlyphBoard) -> - % TODO [SECURITY][LOW]: unimplemented - ok. - --spec validate_glyphs_on_board - ( - array:array(shr_glyph:id()), - shr_glyph_board:id() - ) - -> ok. -validate_glyphs_on_board (_Glyphs, _GlyphBoard) -> - % TODO [SECURITY][LOW]: unimplemented - ok. - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%% EXPORTED FUNCTIONS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%%%% Accessors --spec get_name (type()) -> binary(). -get_name (Char) -> Char#character.name. - --spec get_portrait (type()) -> binary(). -get_portrait (Char) -> Char#character.portrait. - --spec get_weapon_ids (type()) -> {shr_weapon:id(), shr_weapon:id()}. -get_weapon_ids (Char) -> Char#character.weapon_ids. - --spec get_armor_id (type()) -> shr_armor:id(). -get_armor_id (Char) -> Char#character.armor_id. - --spec get_glyph_ids (type()) -> array:array(shr_glyph:id()). -get_glyph_ids (Char) -> Char#character.glyph_ids. - --spec get_glyph_board_id (type()) -> shr_glyph_board:id(). -get_glyph_board_id (Char) -> Char#character.glyph_board_id. - - --spec set_name (binary(), type()) -> type(). -set_name (Name, Char) -> - Char#character - { - name = Name - }. - --spec set_portrait (binary(), type()) -> type(). -set_portrait (PortraitID, Char) -> - Char#character - { - portrait = PortraitID - }. - --spec set_armor_id (shr_armor:id(), type()) -> type(). -set_armor_id (ArmorID, Char) -> - Char#character - { - armor_id = ArmorID - }. - --spec set_weapon_ids ({shr_weapon:id(), shr_weapon:id()}, type()) -> type(). -set_weapon_ids (WeaponIDs, Char) -> - Char#character - { - weapon_ids = WeaponIDs - }. - --spec set_glyph_ids (array:array(shr_glyph:id()), type()) -> type(). -set_glyph_ids (GlyphIDs, Char) -> - Char#character - { - glyph_ids = GlyphIDs - }. - --spec set_glyph_board_id (shr_glyph_board:id(), type()) -> type(). -set_glyph_board_id (GlyphBoardID, Char) -> - Char#character - { - glyph_board_id = GlyphBoardID - }. - --spec random () -> type(). -random () -> - #character - { - name = <<"">>, - portrait = <<"0">>, - weapon_ids = {0, 0}, - armor_id = 0, - glyph_ids = array:new(), - glyph_board_id = <<"0">> - }. - --spec get_name_field () -> non_neg_integer(). -get_name_field () -> #character.name. --spec get_portrait_field () -> non_neg_integer(). -get_portrait_field () -> #character.portrait. --spec get_armor_id_field () -> non_neg_integer(). -get_armor_id_field () -> #character.armor_id. --spec get_weapon_ids_field () -> non_neg_integer(). -get_weapon_ids_field () -> #character.weapon_ids. --spec get_glyph_ids_field () -> non_neg_integer(). -get_glyph_ids_field () -> #character.glyph_ids. --spec get_glyph_board_id_field () -> non_neg_integer(). -get_glyph_board_id_field () -> #character.glyph_board_id. - --spec decode (map()) -> type(). -decode (JSONReqMap) -> - Name = maps:get(<<"nam">>, JSONReqMap), - Portrait = maps:get(<<"prt">>, JSONReqMap), - ActiveWeapon = maps:get(<<"awp">>, JSONReqMap), - SecondaryWeapon = maps:get(<<"swp">>, JSONReqMap), - Armor = maps:get(<<"ar">>, JSONReqMap), - GlyphsList = maps:get(<<"gls">>, JSONReqMap), - GlyphBoard = maps:get(<<"gb">>, JSONReqMap), - - #character - { - name = Name, - portrait = Portrait, - weapon_ids = {ActiveWeapon, SecondaryWeapon}, - armor_id = Armor, - glyph_ids = array:from_list(GlyphsList), - glyph_board_id = GlyphBoard - }. - --spec validate (shr_inventory:type(), type()) -> ok. -validate (Inventory, Character) -> - Glyphs = Character#character.glyph_ids, - GlyphBoard = Character#character.glyph_board_id, - - validate_name(Character#character.name), - validate_portrait(Inventory, Character#character.portrait), - validate_weapons(Inventory, Character#character.weapon_ids), - validate_armor(Inventory, Character#character.armor_id), - validate_glyphs(Inventory, Glyphs), - validate_glyph_board(Inventory, GlyphBoard), - validate_glyphs_on_board(Glyphs, GlyphBoard), - - ok. diff --git a/src/character/struct/chr_roster.erl b/src/character/struct/chr_roster.erl deleted file mode 100644 index 99a82fc..0000000 --- a/src/character/struct/chr_roster.erl +++ /dev/null @@ -1,127 +0,0 @@ --module(chr_roster). - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%% TYPES %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% --type id() :: binary(). - --record -( - roster, - { - id :: id(), - owner :: binary(), - characters :: array:array(chr_character:type()) - } -). - --opaque type() :: #roster{}. - --export_type([type/0, id/0]). - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%% EXPORTS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%%%% Accessors --export -( - [ - get_id/1, - get_owner/1, - get_characters/1, - get_character/2, - - set_characters/2, - set_character/3, - - add_character/2, - remove_character/2 - ] -). - --export -( - [ - get_characters_field/0 - ] -). - --export -( - [ - new/2 - ] -). - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%% LOCAL FUNCTIONS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%% EXPORTED FUNCTIONS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%%%% Accessors --spec get_id (type()) -> id(). -get_id (Roster) -> Roster#roster.id. - --spec get_owner (type()) -> binary(). -get_owner (Roster) -> Roster#roster.owner. - --spec get_characters (type()) -> array:array(chr_character:type()). -get_characters (Roster) -> Roster#roster.characters. - --spec get_character (non_neg_integer(), type()) -> chr_character:type(). -get_character (IX, Roster) -> array:get(IX, Roster#roster.characters). - --spec set_characters (array:array(chr_character:type()), type()) -> type(). -set_characters (Characters, Roster) -> Roster#roster{ characters = Characters }. - --spec set_character - ( - non_neg_integer(), - chr_character:type(), - type() - ) - -> type(). -set_character (IX, Character, Roster) -> - Roster#roster - { - characters = array:set(IX, Character, Roster#roster.characters) - }. - --spec add_character (chr_character:type(), type()) -> type(). -add_character (Character, Roster) -> - CurrentCharacters = Roster#roster.characters, - CurrentSize = array:size(CurrentCharacters), - - Roster#roster - { - characters = array:set(CurrentSize, Character, CurrentCharacters) - }. - --spec remove_character (non_neg_integer(), type()) -> type(). -remove_character (IX, Roster) -> - CurrentCharacters = Roster#roster.characters, - CurrentSize = array:size(CurrentCharacters), - NewSize = (CurrentSize - 1), - LastCharacter = array:get(NewSize, CurrentCharacters), - - S0Characters = array:set(IX, LastCharacter, CurrentCharacters), - S1Characters = array:resize(NewSize, S0Characters), - - Roster#roster - { - characters = S1Characters - }. - --spec get_characters_field () -> non_neg_integer(). -get_characters_field () -> #roster.characters. - --spec new (binary(), binary()) -> type(). -new (ID, Owner) -> - #roster - { - id = ID, - owner = Owner, - characters = array:new() - }. diff --git a/src/query/qry_handler.erl b/src/query/qry_handler.erl index a6caf89..deb4e33 100644 --- a/src/query/qry_handler.erl +++ b/src/query/qry_handler.erl @@ -23,4 +23,5 @@ start (_YawsParams) -> ok = lgn_handler:start(TimedCachesManagerPid), ok = btl_handler:start(TimedCachesManagerPid), ok = map_handler:start(TimedCachesManagerPid), + ok = rst_handler:start(TimedCachesManagerPid), ok. diff --git a/src/roster/query/rst_load.erl b/src/roster/query/rst_load.erl new file mode 100644 index 0000000..761d1c9 --- /dev/null +++ b/src/roster/query/rst_load.erl @@ -0,0 +1,116 @@ +-module(rst_load). + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% TYPES %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +-include("../../../include/yaws_api.hrl"). + +-record +( + input, + { + player_id :: binary(), + session_token :: binary() + } +). + +-record +( + query_state, + { + player :: shr_player:type(), + inventory :: shr_inventory:type(), + roster :: rst_roster: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), + + #input + { + player_id = PlayerID, + session_token = SessionToken + }. + +-spec authenticate_user (input()) -> ({'ok', shr_player:type()} | 'error'). +authenticate_user (Input) -> + PlayerID = Input#input.player_id, + SessionToken = Input#input.session_token, + + Player = shr_timed_cache:fetch(player_db, any, PlayerID), + + case shr_security:credentials_match(SessionToken, Player) of + true -> {ok, Player}; + _ -> error + end. + +-spec fetch_data (shr_player:type(), input()) -> query_state(). +fetch_data (Player, Input) -> + PlayerID = Input#input.player_id, + RosterID = shr_player:get_roster_id(Player), + InventoryID = shr_player:get_inventory_id(Player), + + Roster = shr_timed_cache:fetch(char_roster_db, PlayerID, RosterID), + Inventory = shr_timed_cache:fetch(char_roster_db, PlayerID, InventoryID), + + #query_state + { + player = Player, + roster = Roster, + inventory = Inventory + }. + +-spec generate_reply(query_state()) -> binary(). +generate_reply (QueryState) -> + Roster = QueryState#query_state.roster, + Inventory = QueryState#query_state.inventory, + + RosterCharacters = rst_roster:get_characters(Roster), + SetInventory = shr_set_inventory:generate(Inventory), + EncodedRoster = + array:to_list + ( + array:sparse_map(fun rst_add_char:generate/2, RosterCharacters) + ), + + Output = jiffy:encode([SetInventory|EncodedRoster]), + + Output. + +-spec handle (binary()) -> binary(). +handle (Req) -> + Input = parse_input(Req), + case authenticate_user(Input) of + {ok, Player} -> + shr_security:lock_queries(Input#input.player_id), + QueryState = fetch_data(Player, Input), + shr_security:unlock_queries(Input#input.player_id), + generate_reply(QueryState); + + error -> jiffy:encode([shr_disconnected:generate()]) + end. + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% EXPORTED FUNCTIONS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +out(A) -> + { + content, + "application/json; charset=UTF-8", + handle(A#arg.clidata) + }. diff --git a/src/roster/query/rst_update.erl b/src/roster/query/rst_update.erl new file mode 100644 index 0000000..7e53972 --- /dev/null +++ b/src/roster/query/rst_update.erl @@ -0,0 +1,155 @@ +-module(rst_update). + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% TYPES %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +-include("../../../include/yaws_api.hrl"). + +-record +( + input, + { + player_id :: binary(), + session_token :: binary(), + character_ix :: non_neg_integer(), + character :: rst_character:type() + } +). + +-record +( + query_state, + { + player :: shr_player:type(), + inventory :: shr_inventory:type(), + roster :: rst_roster: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), + CharacterIX = maps:get(<<"cix">>, JSONReqMap), + EncodedCharacter = maps:get(<<"chr">>, JSONReqMap), + + Character = rst_character:decode(EncodedCharacter), + + #input + { + player_id = PlayerID, + session_token = SessionToken, + character_ix = CharacterIX, + character = Character + }. + +-spec authenticate_user (input()) -> ({'ok', shr_player:type()} | 'error'). +authenticate_user (Input) -> + PlayerID = Input#input.player_id, + SessionToken = Input#input.session_token, + + Player = shr_timed_cache:fetch(player_db, any, PlayerID), + + case shr_security:credentials_match(SessionToken, Player) of + true -> {ok, Player}; + _ -> error + end. + +-spec fetch_data (shr_player:type(), input()) -> query_state(). +fetch_data (Player, Input) -> + PlayerID = Input#input.player_id, + RosterID = shr_player:get_roster_id(Player), + InventoryID = shr_player:get_inventory_id(Player), + + Roster = shr_timed_cache:fetch(char_roster_db, PlayerID, RosterID), + Inventory = shr_timed_cache:fetch(char_roster_db, PlayerID, InventoryID), + + #query_state + { + player = Player, + roster = Roster, + inventory = Inventory + }. + +-spec update_data (query_state(), input()) -> query_state(). +update_data (QueryState, Input) -> + Inventory = QueryState#query_state.inventory, + Character = Input#input.character, + + rst_character:validate(Inventory, Character), + + %% TODO [FUNCTION: chr][REQUIRED]: unimplemented. + QueryState. + +-spec commit_update (query_state(), input()) -> 'ok'. +commit_update (QueryState, Input) -> + PlayerID = Input#input.player_id, + CharacterIX = Input#input.character_ix, + Character = Input#input.character, + Player = QueryState#query_state.player, + Roster = QueryState#query_state.roster, + + RosterID = shr_player:get_roster_id(Player), + UpdatedRoster = rst_roster:set_character(CharacterIX, Character, Roster), + + Query = + shr_db_query:new + ( + char_roster_db, + RosterID, + {user, PlayerID}, + [ + shr_db_query:update_indexed + ( + rst_roster:get_characters_field(), + CharacterIX, + [shr_db_query:set_value(Character)] + ) + ] + ), + + shr_database:commit(Query), + shr_timed_cache:update(char_roster_db, PlayerID, RosterID, UpdatedRoster), + + 'ok'. + +-spec generate_reply () -> binary(). +generate_reply () -> + jiffy:encode([shr_okay:generate()]). + +-spec handle (binary()) -> binary(). +handle (Req) -> + Input = parse_input(Req), + case authenticate_user(Input) of + {ok, Player} -> + shr_security:lock_queries(Input#input.player_id), + QueryState = fetch_data(Player, Input), + Update = update_data(QueryState, Input), + commit_update(Update, Input), + shr_security:unlock_queries(Input#input.player_id), + generate_reply(); + + error -> jiffy:encode([shr_disconnected:generate()]) + end. + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% EXPORTED FUNCTIONS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +out(A) -> + { + content, + "application/json; charset=UTF-8", + handle(A#arg.clidata) + }. diff --git a/src/roster/reply/rst_add_char.erl b/src/roster/reply/rst_add_char.erl new file mode 100644 index 0000000..1e0d1da --- /dev/null +++ b/src/roster/reply/rst_add_char.erl @@ -0,0 +1,39 @@ +-module(rst_add_char). + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% TYPES %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% EXPORTS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +-export([generate/2]). + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% LOCAL FUNCTIONS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% EXPORTED FUNCTIONS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +-spec generate + ( + non_neg_integer(), + rst_character:type() + ) + -> {list(any())}. +generate (IX, Character) -> + {ActiveWeapon, SecondaryWeapon} = rst_character:get_weapon_ids(Character), + + { + [ + {<<"msg">>, <<"add_char">>}, + {<<"ix">>, IX}, + {<<"nam">>, rst_character:get_name(Character)}, + {<<"awp">>, ActiveWeapon}, + {<<"swp">>, SecondaryWeapon}, + {<<"ar">>, rst_character:get_armor_id(Character)}, + {<<"gls">>, array:to_list(rst_character:get_glyph_ids(Character))}, + {<<"gb">>, rst_character:get_glyph_board_id(Character)} + ] + }. diff --git a/src/roster/rst_handler.erl b/src/roster/rst_handler.erl new file mode 100644 index 0000000..3d6073b --- /dev/null +++ b/src/roster/rst_handler.erl @@ -0,0 +1,35 @@ +-module(rst_handler). + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% TYPES %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% EXPORTS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +-export([start/1]). + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% LOCAL FUNCTIONS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% EXPORTED FUNCTIONS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +-spec start (pid()) -> 'ok'. +start (TimedCachesManagerPid) -> + case shr_database:fetch(roster_db, <<"0">>, admin) of + {ok, _} -> ok; + not_found -> + shr_database:insert_at + ( + roster_db, + <<"0">>, + any, + any, + rst_shim:generate_random_character_roster() + ) + end, + shr_timed_caches_manager:new_cache(TimedCachesManagerPid, roster_db, none), + + ok. diff --git a/src/roster/rst_shim.erl b/src/roster/rst_shim.erl new file mode 100644 index 0000000..57a62f5 --- /dev/null +++ b/src/roster/rst_shim.erl @@ -0,0 +1,25 @@ +-module(rst_shim). + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% TYPES %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% EXPORTS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +-export([generate_random_character_roster/0]). + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% LOCAL FUNCTIONS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% EXPORTED FUNCTIONS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +-spec generate_random_character_roster () -> rst_roster:type(). +generate_random_character_roster () -> + Result = rst_roster:new(<<"0">>, <<"0">>), + + %% TODO [DEBUG][REQUIRED]: unimplemented. + + Result. diff --git a/src/roster/struct/rst_character.erl b/src/roster/struct/rst_character.erl new file mode 100644 index 0000000..e3663cc --- /dev/null +++ b/src/roster/struct/rst_character.erl @@ -0,0 +1,238 @@ +-module(rst_character). + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% TYPES %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +-record +( + character, + { + name :: binary(), + portrait :: binary(), + weapon_ids :: {shr_weapon:id(), shr_weapon:id()}, + armor_id :: shr_armor:id(), + glyph_ids :: array:array(shr_glyph:id()), + glyph_board_id :: shr_glyph_board:id() + } +). + +-opaque type() :: #character{}. + +-export_type([type/0]). +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% EXPORTS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%% Accessors +-export +( + [ + get_name/1, + get_portrait/1, + get_weapon_ids/1, + get_armor_id/1, + get_glyph_ids/1, + get_glyph_board_id/1, + + set_name/2, + set_portrait/2, + set_weapon_ids/2, + set_armor_id/2, + set_glyph_ids/2, + set_glyph_board_id/2, + + get_name_field/0, + get_portrait_field/0, + get_weapon_ids_field/0, + get_armor_id_field/0, + get_glyph_ids_field/0, + get_glyph_board_id_field/0 + ] +). + +-export +( + [ + decode/1, + random/0 + ] +). + +-export +( + [ + validate/2 + ] +). + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% LOCAL FUNCTIONS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +-spec validate_name (binary()) -> ok. +validate_name (_Name) -> + % TODO [SECURITY][LOW]: unimplemented + ok. + +-spec validate_portrait (shr_inventory:type(), binary()) -> ok. +validate_portrait (_Inventory, _Portrait) -> + % TODO [SECURITY][LOW]: unimplemented + ok. + +-spec validate_weapons + ( + shr_inventory:type(), + {shr_weapon:id(), shr_weapon:id()} + ) + -> ok. +validate_weapons (_Inventory, {_ActiveWeapon, _SecondaryWeapon}) -> + % TODO [SECURITY][LOW]: unimplemented + ok. + +-spec validate_armor (shr_inventory:type(), shr_armor:id()) -> ok. +validate_armor (_Inventory, _Armor) -> + % TODO [SECURITY][LOW]: unimplemented + ok. + +-spec validate_glyphs (shr_inventory:type(), array:array(shr_glyph:id())) -> ok. +validate_glyphs (_Inventory, _Glyphs) -> + % TODO [SECURITY][LOW]: unimplemented + ok. + +-spec validate_glyph_board (shr_inventory:type(), shr_glyph_board:id()) -> ok. +validate_glyph_board (_Inventory, _GlyphBoard) -> + % TODO [SECURITY][LOW]: unimplemented + ok. + +-spec validate_glyphs_on_board + ( + array:array(shr_glyph:id()), + shr_glyph_board:id() + ) + -> ok. +validate_glyphs_on_board (_Glyphs, _GlyphBoard) -> + % TODO [SECURITY][LOW]: unimplemented + ok. + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% EXPORTED FUNCTIONS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%% Accessors +-spec get_name (type()) -> binary(). +get_name (Char) -> Char#character.name. + +-spec get_portrait (type()) -> binary(). +get_portrait (Char) -> Char#character.portrait. + +-spec get_weapon_ids (type()) -> {shr_weapon:id(), shr_weapon:id()}. +get_weapon_ids (Char) -> Char#character.weapon_ids. + +-spec get_armor_id (type()) -> shr_armor:id(). +get_armor_id (Char) -> Char#character.armor_id. + +-spec get_glyph_ids (type()) -> array:array(shr_glyph:id()). +get_glyph_ids (Char) -> Char#character.glyph_ids. + +-spec get_glyph_board_id (type()) -> shr_glyph_board:id(). +get_glyph_board_id (Char) -> Char#character.glyph_board_id. + + +-spec set_name (binary(), type()) -> type(). +set_name (Name, Char) -> + Char#character + { + name = Name + }. + +-spec set_portrait (binary(), type()) -> type(). +set_portrait (PortraitID, Char) -> + Char#character + { + portrait = PortraitID + }. + +-spec set_armor_id (shr_armor:id(), type()) -> type(). +set_armor_id (ArmorID, Char) -> + Char#character + { + armor_id = ArmorID + }. + +-spec set_weapon_ids ({shr_weapon:id(), shr_weapon:id()}, type()) -> type(). +set_weapon_ids (WeaponIDs, Char) -> + Char#character + { + weapon_ids = WeaponIDs + }. + +-spec set_glyph_ids (array:array(shr_glyph:id()), type()) -> type(). +set_glyph_ids (GlyphIDs, Char) -> + Char#character + { + glyph_ids = GlyphIDs + }. + +-spec set_glyph_board_id (shr_glyph_board:id(), type()) -> type(). +set_glyph_board_id (GlyphBoardID, Char) -> + Char#character + { + glyph_board_id = GlyphBoardID + }. + +-spec random () -> type(). +random () -> + #character + { + name = <<"">>, + portrait = <<"0">>, + weapon_ids = {0, 0}, + armor_id = 0, + glyph_ids = array:new(), + glyph_board_id = <<"0">> + }. + +-spec get_name_field () -> non_neg_integer(). +get_name_field () -> #character.name. +-spec get_portrait_field () -> non_neg_integer(). +get_portrait_field () -> #character.portrait. +-spec get_armor_id_field () -> non_neg_integer(). +get_armor_id_field () -> #character.armor_id. +-spec get_weapon_ids_field () -> non_neg_integer(). +get_weapon_ids_field () -> #character.weapon_ids. +-spec get_glyph_ids_field () -> non_neg_integer(). +get_glyph_ids_field () -> #character.glyph_ids. +-spec get_glyph_board_id_field () -> non_neg_integer(). +get_glyph_board_id_field () -> #character.glyph_board_id. + +-spec decode (map()) -> type(). +decode (JSONReqMap) -> + Name = maps:get(<<"nam">>, JSONReqMap), + Portrait = maps:get(<<"prt">>, JSONReqMap), + ActiveWeapon = maps:get(<<"awp">>, JSONReqMap), + SecondaryWeapon = maps:get(<<"swp">>, JSONReqMap), + Armor = maps:get(<<"ar">>, JSONReqMap), + GlyphsList = maps:get(<<"gls">>, JSONReqMap), + GlyphBoard = maps:get(<<"gb">>, JSONReqMap), + + #character + { + name = Name, + portrait = Portrait, + weapon_ids = {ActiveWeapon, SecondaryWeapon}, + armor_id = Armor, + glyph_ids = array:from_list(GlyphsList), + glyph_board_id = GlyphBoard + }. + +-spec validate (shr_inventory:type(), type()) -> ok. +validate (Inventory, Character) -> + Glyphs = Character#character.glyph_ids, + GlyphBoard = Character#character.glyph_board_id, + + validate_name(Character#character.name), + validate_portrait(Inventory, Character#character.portrait), + validate_weapons(Inventory, Character#character.weapon_ids), + validate_armor(Inventory, Character#character.armor_id), + validate_glyphs(Inventory, Glyphs), + validate_glyph_board(Inventory, GlyphBoard), + validate_glyphs_on_board(Glyphs, GlyphBoard), + + ok. diff --git a/src/roster/struct/rst_roster.erl b/src/roster/struct/rst_roster.erl new file mode 100644 index 0000000..a362619 --- /dev/null +++ b/src/roster/struct/rst_roster.erl @@ -0,0 +1,127 @@ +-module(rst_roster). + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% TYPES %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +-type id() :: binary(). + +-record +( + roster, + { + id :: id(), + owner :: binary(), + characters :: array:array(rst_character:type()) + } +). + +-opaque type() :: #roster{}. + +-export_type([type/0, id/0]). + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% EXPORTS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%% Accessors +-export +( + [ + get_id/1, + get_owner/1, + get_characters/1, + get_character/2, + + set_characters/2, + set_character/3, + + add_character/2, + remove_character/2 + ] +). + +-export +( + [ + get_characters_field/0 + ] +). + +-export +( + [ + new/2 + ] +). + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% LOCAL FUNCTIONS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% EXPORTED FUNCTIONS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%% Accessors +-spec get_id (type()) -> id(). +get_id (Roster) -> Roster#roster.id. + +-spec get_owner (type()) -> binary(). +get_owner (Roster) -> Roster#roster.owner. + +-spec get_characters (type()) -> array:array(rst_character:type()). +get_characters (Roster) -> Roster#roster.characters. + +-spec get_character (non_neg_integer(), type()) -> rst_character:type(). +get_character (IX, Roster) -> array:get(IX, Roster#roster.characters). + +-spec set_characters (array:array(rst_character:type()), type()) -> type(). +set_characters (Characters, Roster) -> Roster#roster{ characters = Characters }. + +-spec set_character + ( + non_neg_integer(), + rst_character:type(), + type() + ) + -> type(). +set_character (IX, Character, Roster) -> + Roster#roster + { + characters = array:set(IX, Character, Roster#roster.characters) + }. + +-spec add_character (rst_character:type(), type()) -> type(). +add_character (Character, Roster) -> + CurrentCharacters = Roster#roster.characters, + CurrentSize = array:size(CurrentCharacters), + + Roster#roster + { + characters = array:set(CurrentSize, Character, CurrentCharacters) + }. + +-spec remove_character (non_neg_integer(), type()) -> type(). +remove_character (IX, Roster) -> + CurrentCharacters = Roster#roster.characters, + CurrentSize = array:size(CurrentCharacters), + NewSize = (CurrentSize - 1), + LastCharacter = array:get(NewSize, CurrentCharacters), + + S0Characters = array:set(IX, LastCharacter, CurrentCharacters), + S1Characters = array:resize(NewSize, S0Characters), + + Roster#roster + { + characters = S1Characters + }. + +-spec get_characters_field () -> non_neg_integer(). +get_characters_field () -> #roster.characters. + +-spec new (binary(), binary()) -> type(). +new (ID, Owner) -> + #roster + { + id = ID, + owner = Owner, + characters = array:new() + }. diff --git a/src/shared/reply/shr_disconnected.erl b/src/shared/reply/shr_disconnected.erl index e7b1813..4f913a5 100644 --- a/src/shared/reply/shr_disconnected.erl +++ b/src/shared/reply/shr_disconnected.erl @@ -18,6 +18,7 @@ %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -spec generate () -> {list(any())}. generate () -> + io:format("User was disconnected.~n"), { [ {<<"msg">>, <<"disconnected">>} -- cgit v1.2.3-70-g09d2