db: Cleanup users who didn't reach game after login every 5 minutes.

This commit is contained in:
Loïc Hoguin 2010-05-20 23:51:13 +02:00
parent 2914393c3a
commit 53f2c49e73
5 changed files with 29 additions and 5 deletions

View File

@ -19,4 +19,4 @@
%% EGS database schema. %% EGS database schema.
-record(ids, {type, id}). -record(ids, {type, id}).
-record(users, {gid, pid, socket, auth, folder, charnumber, charname, lid, map, entry, coords}). -record(users, {gid, pid, socket, auth, time, folder, charnumber, charname, lid, map, entry, coords}).

View File

@ -26,7 +26,20 @@
start() -> start() ->
KeepAlivePid = spawn_link(?MODULE, keepalive, []), KeepAlivePid = spawn_link(?MODULE, keepalive, []),
[{keepalive, KeepAlivePid}]. CleanupPid = spawn_link(?MODULE, cleanup, []),
[{keepalive, KeepAlivePid}, {cleanup, CleanupPid}].
%% @doc Cleanup the users table of failures to log into the game server.
cleanup() ->
receive
_ ->
?MODULE:cleanup()
after 300000 ->
egs_db:users_cleanup(),
reload,
?MODULE:cleanup()
end.
%% @doc Keep connected players alive. %% @doc Keep connected players alive.
%% @todo Don't even need to send a keepalive packet if we sent a packet in the last Timeout milliseconds. %% @todo Don't even need to send a keepalive packet if we sent a packet in the last Timeout milliseconds.

View File

@ -74,3 +74,13 @@ users_insert(User) ->
users_delete(GID) -> users_delete(GID) ->
mnesia:transaction(fun() -> mnesia:delete({users, GID}) end). mnesia:transaction(fun() -> mnesia:delete({users, GID}) end).
%% @doc Cleanup the disconnected users who failed after the login stage but before the game stage.
users_cleanup() ->
Timeout = calendar:datetime_to_gregorian_seconds(calendar:universal_time()) - 300,
Users = do(qlc:q([X#users.gid || X <- mnesia:table(users),
X#users.auth /= success, X#users.time < Timeout])),
mnesia:transaction(fun() ->
lists:foreach(fun(GID) -> users_delete(GID) end, Users)
end).

View File

@ -79,7 +79,8 @@ process_handle(16#020d, CSocket, Version, Packet) ->
Auth -> Auth ->
log(GID, "good auth, proceed"), log(GID, "good auth, proceed"),
LID = egs_db:next(lobby), LID = egs_db:next(lobby),
egs_db:users_insert(#users{gid=GID, pid=self(), socket=CSocket, auth= << 0:32 >>, folder=User#users.folder, lid=LID}), Time = calendar:datetime_to_gregorian_seconds(calendar:universal_time()),
egs_db:users_insert(#users{gid=GID, pid=self(), socket=CSocket, auth=success, time=Time, folder=User#users.folder, lid=LID}),
egs_proto:send_flags(CSocket, GID), egs_proto:send_flags(CSocket, GID),
?MODULE:char_select(CSocket, GID, Version); ?MODULE:char_select(CSocket, GID, Version);
_ -> _ ->

View File

@ -98,8 +98,8 @@ handle(16#0219, CSocket, SessionID, Packet) ->
log(SessionID, io_lib:format("auth success for ~s ~s", [Username, Password])), log(SessionID, io_lib:format("auth success for ~s ~s", [Username, Password])),
Auth = crypto:rand_bytes(4), Auth = crypto:rand_bytes(4),
Folder = << Username/binary, "-", Password/binary >>, Folder = << Username/binary, "-", Password/binary >>,
log(SessionID, Folder), Time = calendar:datetime_to_gregorian_seconds(calendar:universal_time()),
egs_db:users_insert(#users{gid=SessionID, pid=self(), socket=CSocket, auth=Auth, folder=Folder}), egs_db:users_insert(#users{gid=SessionID, pid=self(), socket=CSocket, auth=Auth, time=Time, folder=Folder}),
egs_proto:send_auth_success(CSocket, SessionID, SessionID, Auth); egs_proto:send_auth_success(CSocket, SessionID, SessionID, Auth);
%% @doc MOTD request handler. Handles both forms of MOTD requests, US and JP. %% @doc MOTD request handler. Handles both forms of MOTD requests, US and JP.