summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authornsensfel <SpamShield0@noot-noot.org>2018-10-10 17:21:10 +0200
committernsensfel <SpamShield0@noot-noot.org>2018-10-10 17:21:10 +0200
commitbd1f3d6aaaaf14d6bb0ef6d18cbfb1a149d727dc (patch)
tree61da130e46771e413eb436081ade78b2b220cae9 /src
parent69c0a530f82c8158da454ee0e10678dd417f1533 (diff)
(Broken) Working on DB item ID generation...
Diffstat (limited to 'src')
-rw-r--r--src/db/db_node.erl4
-rw-r--r--src/db/logic/db_access.erl2
-rw-r--r--src/db/struct/db_item_ids_manager.erl208
-rw-r--r--src/login/lgn_handler.erl44
-rw-r--r--src/map/map_handler.erl24
-rw-r--r--src/roster/rst_handler.erl12
-rw-r--r--src/special/spe_player.erl1
7 files changed, 213 insertions, 82 deletions
diff --git a/src/db/db_node.erl b/src/db/db_node.erl
index 309adc0..30a29e2 100644
--- a/src/db/db_node.erl
+++ b/src/db/db_node.erl
@@ -32,5 +32,9 @@ start () ->
db_model:add_db(map_db, Mnesia),
db_model:add_db(player_db, Mnesia),
db_model:add_db(roster_db, Mnesia),
+ db_model:add_db(inventory_db, Mnesia),
+
+ ok = db_item_ids_manager:start(),
+
wait_for_stop(),
ok.
diff --git a/src/db/logic/db_access.erl b/src/db/logic/db_access.erl
index d62e4ec..39019a6 100644
--- a/src/db/logic/db_access.erl
+++ b/src/db/logic/db_access.erl
@@ -88,7 +88,7 @@ insert_at (DB, ID, ReadPerm, WritePerm, Value) ->
any())
-> ({'aborted', any()} | {'atomic', {'ok', binary()}}).
insert (DB, ReadPerm, WritePerm, Value) ->
- ID = <<"?">>, %% TODO [FUNCTION: db][HIGH]: gen new ID.
+ ID = db_item_ids_manager:allocate(DB),
case insert_at(DB, ID, ReadPerm, WritePerm, Value) of
{'atomic', 'ok'} -> {'atomic', {'ok', ID}};
{aborted, Val} -> {aborted, Val}
diff --git a/src/db/struct/db_item_ids_manager.erl b/src/db/struct/db_item_ids_manager.erl
new file mode 100644
index 0000000..999a047
--- /dev/null
+++ b/src/db/struct/db_item_ids_manager.erl
@@ -0,0 +1,208 @@
+-module(db_item_ids_manager).
+-behavior(gen_server).
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%% TYPES %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+-record
+(
+ entry,
+ {
+ last_id :: binary(),
+ freed_ids :: list(binary())
+ }
+).
+
+-type entry() :: #entry{}.
+
+%% FIXME: IDs should be generated in a decentralized fashion.
+%% TODO: How to handle IDs management with the redundancy DBs?
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%% EXPORTS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%%%% 'gen_server' Exports
+-export
+(
+ [
+ init/1,
+ handle_cast/2,
+ handle_call/3, %% No reply will ever be given.
+ terminate/2,
+ code_change/3,
+ format_status/2,
+ handle_info/2
+ ]
+).
+
+%%%% Actual Interface
+-export
+(
+ [
+ allocate/1,
+ free/2,
+ start/0
+ ]
+).
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%% LOCAL FUNCTIONS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+-spec next_char (integer()) -> integer().
+next_char ($9) -> $a;
+next_char ($z) -> $A;
+next_char ($Z) -> $0;
+next_char (C) -> (C + 1).
+
+-spec next_id_internal
+ (
+ list(integer()),
+ boolean(),
+ list(integer())
+ )
+ -> list(integer()).
+next_id_internal ([], true, Result) -> [$0|Result];
+next_id_internal ([], false, Result) -> Result;
+next_id_internal ([$Z|Next], true, Result) ->
+ next_id_internal(Next, true, [$0|Result]);
+next_id_internal ([Char|Next], true, Result) ->
+ next_id_internal(Next, false, [next_char(Char)|Result]);
+next_id_internal ([Char|Next], false, Result) ->
+ next_id_internal(Next, false, [Char|Result]).
+
+-spec next_id (binary()) -> binary().
+next_id (ID) ->
+ list_to_binary
+ (
+ next_id_internal
+ (
+ lists:reverse(binary:bin_to_list(ID)),
+ true,
+ []
+ )
+ ).
+
+-spec new_entry () -> entry().
+new_entry () ->
+ #entry
+ {
+ last_id = <<"">>,
+ freed_ids = []
+ }.
+
+-spec allocate_id_in_entry (entry()) -> {entry(), binary()}.
+allocate_id_in_entry (Entry) ->
+ case Entry#entry.freed_ids of
+ [] ->
+ NewID = next_id(Entry#entry.last_id),
+ {
+ Entry#entry{ last_id = NewID },
+ NewID
+ };
+
+ [OldID|OtherOldIDs] ->
+ {
+ Entry#entry{ freed_ids = OtherOldIDs },
+ OldID
+ }
+ end.
+
+-spec allocate_id
+ (
+ atom(),
+ dict:dict(atom(), entry())
+ )
+ -> {dict:dict(atom(), entry()), binary()}.
+allocate_id (DB, State) ->
+ S0Entry =
+ case dict:find(DB, State) of
+ {ok, Value} -> Value;
+ error -> new_entry()
+ end,
+
+ {S1Entry, NewID} = allocate_id_in_entry(S0Entry),
+
+ S0State = dict:store(DB, S1Entry, State),
+
+ {S0State, NewID}.
+
+-spec free_id
+ (
+ binary(),
+ atom(),
+ dict:dict(atom(), entry())
+ )
+ -> dict:dict(atom(), entry()).
+free_id (ID, DB, State) ->
+ Entry =
+ case dict:find(DB, State) of
+ {ok, Value} -> Value;
+ error -> new_entry()
+ end,
+
+ EntryFreedIDs = Entry#entry.freed_ids,
+
+ case lists:member(ID, EntryFreedIDs) of
+ true -> State;
+ false ->
+ Result =
+ dict:store
+ (
+ DB,
+ Entry#entry{ freed_ids = [ID|EntryFreedIDs] },
+ State
+ ),
+
+ Result
+ end.
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%% EXPORTED FUNCTIONS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%%%% 'gen_server' functions
+init (_) -> {ok, dict:new()}.
+
+handle_call ({allocate, DB}, _, State) ->
+ {NewState, NewID} = allocate_id(DB, State),
+ {reply, {allocated_id, NewID}, NewState};
+handle_call ({free, ID, DB}, _, State) ->
+ {noreply, free_id(ID, DB, State)}.
+
+handle_cast ({allocate, _DB}, State) ->
+ {noreply, State};
+handle_cast ({free, ID, DB}, State) ->
+ {noreply, free_id(ID, DB, State)}.
+
+terminate (_, _) -> ok.
+
+code_change (_, State, _) ->
+ {ok, State}.
+
+format_status (_, [_, State]) ->
+ [{data, [{"State", State}]}].
+
+handle_info(_, State) ->
+ {noreply, State}.
+
+%%%% Interface Functions
+-spec allocate (atom()) -> binary().
+allocate (DB) ->
+ gen_server:call({global, db_item_ids_manager}, {allocate, DB}),
+
+ receive
+ {allocated_id, Result} ->
+ io:format("~n[DB: ~p] Item ID ~p allocated.~n", [DB, Result]),
+ Result
+ end.
+
+-spec free (binary(), atom()) -> 'ok'.
+free (ID, DB) ->
+ gen_server:cast({global, db_item_ids_manager}, {free, ID, DB}),
+
+ ok.
+
+-spec start () -> 'ok'.
+start () ->
+ {ok, _} = gen_server:start({global, db_item_ids_manager}, ?MODULE, none, []),
+
+ ok.
diff --git a/src/login/lgn_handler.erl b/src/login/lgn_handler.erl
index d2a6ee2..e14387c 100644
--- a/src/login/lgn_handler.erl
+++ b/src/login/lgn_handler.erl
@@ -12,55 +12,11 @@
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% LOCAL FUNCTIONS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
--spec ensure_player_exists (binary(), binary(), binary(), binary()) -> 'ok'.
-ensure_player_exists (ID, Username, Password, Email) ->
- case shr_database:fetch(player_db, ID, admin) of
- {ok, _} -> ok;
- not_found ->
- shr_database:insert_at
- (
- player_db,
- ID,
- any,
- any,
- lgn_shim:generate_random_player(ID, Username, Password, Email)
- )
- end,
-
- UsernameLC = string:lowercase(Username),
- EmailLC = string:lowercase(Email),
-
- case shr_database:fetch(login_db, UsernameLC, admin) of
- {ok, _} -> ok;
- not_found -> shr_database:insert_at(login_db, UsernameLC, any, any, ID)
- end,
-
- case shr_database:fetch(login_db, EmailLC, admin) of
- {ok, _} -> ok;
- not_found -> shr_database:insert_at(login_db, EmailLC, any, any, ID)
- end,
-
- ok.
-
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% EXPORTED FUNCTIONS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-spec start (pid()) -> 'ok'.
start (TimedCachesManagerPid) ->
- ensure_player_exists
- (
- <<"0">>,
- <<"Player1">>,
- <<"Kalimer0">>,
- <<"P1@Tacticians.Online">>
- ),
- ensure_player_exists
- (
- <<"1">>,
- <<"Player2">>,
- <<"Kalimer1">>,
- <<"P2@Tacticians.Online">>
- ),
shr_timed_caches_manager:new_cache(TimedCachesManagerPid, login_db, none),
shr_timed_caches_manager:new_cache(TimedCachesManagerPid, player_db, none),
ok.
diff --git a/src/map/map_handler.erl b/src/map/map_handler.erl
index e4bcb60..eb19e18 100644
--- a/src/map/map_handler.erl
+++ b/src/map/map_handler.erl
@@ -18,29 +18,5 @@
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-spec start (pid()) -> 'ok'.
start (TimedCachesManagerPid) ->
- case shr_database:fetch(map_db, <<"0">>, admin) of
- {ok, _} -> ok;
- not_found ->
- shr_database:insert_at
- (
- map_db,
- <<"0">>,
- any,
- any,
- map_shim:generate_random_map(0, <<"0">>)
- )
- end,
- case shr_database:fetch(map_db, <<"1">>, admin) of
- {ok, _} -> ok;
- not_found ->
- shr_database:insert_at
- (
- map_db,
- <<"1">>,
- any,
- any,
- map_shim:generate_random_map(1, <<"1">>)
- )
- end,
shr_timed_caches_manager:new_cache(TimedCachesManagerPid, map_db, none),
ok.
diff --git a/src/roster/rst_handler.erl b/src/roster/rst_handler.erl
index 3d6073b..3b23f0c 100644
--- a/src/roster/rst_handler.erl
+++ b/src/roster/rst_handler.erl
@@ -18,18 +18,6 @@
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-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/special/spe_player.erl b/src/special/spe_player.erl
index 7560a2d..6f0eebc 100644
--- a/src/special/spe_player.erl
+++ b/src/special/spe_player.erl
@@ -87,7 +87,6 @@ generate (Username, Password, Email) ->
{ok, PlayerID} = shr_database:insert(player_db, janitor, janitor, Player),
-
shr_janitor:new(player_db, PlayerID),
InvID = generate_inventory(PlayerID),