C:登录
登录登录登录!!!我听到有人非常不耐烦的声音。
%% @copyright GPL
%% @author --==rix==-- <zeze0556@gmail.com>
%% @doc
%% 主要处理用户的注册和登录.
-module( login ) .
%% API
-export( [login / 3, logout / 1, test / 0,creat/2 ] ) .
-include( "proto.hrl" ) .
-include( "test.hrl" ) .
-include( "schema.hrl" ) .
%% @doc 检查数据库中检索到的记录和用户登录的记录是否一致.
login( { atomic, [] }, _ ) ->
io:format("login: login error~n"),
{ error, ?ERR_BAD_LOGIN };
login({ atomic, [Player] }, [_Nick, Pass,Pid] = Args) when is_record( Player, player ) ->
Player1 = Player#player {
socket = fix_pid( Player#player.socket ),
pid = fix_pid( Player#player.pid ),
login_errors = 0,
online = false,
ingame = false,
now_play = 0
},
Condition = check_player( Player1, [Pass], [ fun is_account_disabled / 2,
fun is_bad_password / 2,
fun is_player_busy / 2,
fun is_player_online / 2,
fun is_client_down / 2,
fun is_offline / 2
] ),
{ ok, Player2 } = login( Player1, Condition, Args ),
%% Player2 = Player3#player{pid = Pid},
io:format("Player2=~w~n",[Player2]),
F = fun()->
mnesia:write( Player2 ) end,
case mnesia:transaction( F ) of
{ atomic, ok } ->
{ok, Player2};
_ ->
{ error, "unknow error, pleaseconnect administrator!" }
end .
%% @doc 尝试登录用户
login( Nick, Pass, Socket ) when is_list( Nick ), is_list( Pass ), is_pid( Socket ) ->
login( db:find( player, nick, Nick ), [Nick, Pass, Socket] );
login(Player, bad_password, _) ->
N = Player#player.login_errors + 1,
{ atomic, MaxLoginErrors } =
db:get( cluster_config, 0, max_login_errors ),
if
N > MaxLoginErrors ->
Player1 = Player#player {
disabled = true
},
{ Player1, { error, "your count have been locked, please connect administrator!" } };
true ->
Player1 = Player#player {
login_errors = N
},
{ Player1, { error, "login failed, try again" } }
end;
login(Player, accound_disabled, _ ) ->
{ Player, { error, "your count have been locked or the the count does not existed, try again" } };
login(Player, player_online, Args) ->
logout( Player#player.id ),
login( Player, player_offline, Args );
login(Player, client_down, [_, _, Socket] ) ->
router:logout( Player#player.pid),
{ ok, Player };
login(Player, player_busy, Args ) ->
Temp = login( Player, client_down, Args ),
router:logout(Player),
Temp;
login(Player, player_offline, [Nick, _, Socket] ) ->
io:format( "login check offline ~w ~w~n", [ ?MODULE, ?LINE] ),
Player1 = Player#player{online = true, socket=Socket},
{ ok, Player1 }.
%% @doc 检查登录
check_player( Player, Args, [Guard|Rest] ) ->
case Guard( Player, Args ) of
{ true, Condition } ->
Condition;
_ ->
check_player( Player, Args, Rest )
end;
check_player(_Player, _Args, [] ) ->
% io:format( "~w ~w~n", [ ?MODULE, ?LINE] ),
unknow_error .
%% @doc 密码错误?
is_bad_password( Player, [Pass] ) ->
Hash = erlang:phash2( Pass, 1 bsl 32 ),
Match = Player#player.password == Hash,
{ not Match, bad_password } .
%% @doc 帐号被禁掉? 倒霉蛋
is_account_disabled( Player, _ ) ->
{ Player#player.disabled, account_disabled } .
%% @doc 用户已经在游戏中?
is_player_busy( Player, _ ) ->
{ Online, _ } = is_player_online( Player, [] ) ,
Playing = Player#player.ingame /= none,
{ Online and Playing, player_busy } .
%% @doc 用户已在线?
is_player_online( Player, _ ) ->
SocketAlive = Player#player.socket /= none,
PlayerAlive = Player#player.pid /= none,
{ SocketAlive and PlayerAlive, player_online } .
%% @doc 用户已下线?
is_client_down( Player, _ ) ->
SocketDown = Player#player.socket == none,
PlayerAlive = Player#player.pid /= none,
{ SocketDown and PlayerAlive, player_offline } .
%% @doc 用户已下线?
is_offline( Player, _ ) ->
SocketDown = Player#player.socket == none,
PlayerDown = Player#player.pid == none,
{ SocketDown and PlayerDown, player_offline } .
%% @doc 纠正用户进程
fix_pid( Pid ) when is_pid( Pid ) ->
case erlang:is_process_alive( Pid ) of
true ->
Pid;
_ ->
none
end;
fix_pid(Pid) ->
Pid .
%% @doc 用户登出
logout( OID ) ->
case db:find( player, OID ) of
{ atomic, [Player] } ->
player:stop( Player#player.pid ),
{ atomic, ok } = db:set( player, OID, [{pid, none}, { socket, none } ] );
_ ->
oops
end .
%% @doc test函数
test() ->
ok.
%% @doc 添加新用户
creat( Nick, Pass ) ->
case db:find (player, nick, Nick) of
{atomic, []} ->
Player = #player{
id = counter:bump( player ),
nick = Nick,
password = erlang:phash2( Pass, 1 bsl 32 )
},
mnesia:transaction( fun()->mnesia:write( Player ), Player#player.id end ) ,
{ok, {Nick, Pass}};
_ ->
{error, "exist"}
end.
</zeze0556@gmail.com>
上面就是登录和创建新用户的所有处理了。大部分的代码都是在检查,检查,检查。相对来说,我反而没有什么要说的了。
因为添加了很多的代码,因此文件现在变成了这样的
bloggame
|-- ReadMe
`-- server
|-- doc
|-- ebin
|-- makefile
|-- src
| |-- login.erl
| |-- Makefile
| |-- netgame.app
| |-- netgame_app.erl
| |-- netgame_deps.erl
| |-- netgame.erl
| |-- netgame_sup.erl
| |-- proto.erl
| |-- proto.hrl
| |-- reloader.erl
| |-- router.erl
| |-- schema.erl
| |-- schema.hrl
| |-- server.erl
| |-- tcp_server.erl
| `-- test.hrl
|-- start-dev.sh
|-- start.sh
`-- support
`-- include.mk
5 directories, 21 files
基本上这就是这次所有的更新内容了。每个人看到这里都非常的不耐烦了,为了回应你们的耐心,我将代码的git管理的仓库使用Dropbox共享了,我放在我的Dropbox共享的Public目录下的bloggame.git中,我的Dropbox帐号是zeze0556@gmail.com,我现在还没看Dropbox如何查看获得别人共享的内容,但我知道总有办法的。