RIX 编程应该是快乐的

15六/100

一起做网游吧【7】:服务器端注册和登录处理

C:登录

登录登录登录!!!我听到有人非常不耐烦的声音。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
 
%% @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.

上面就是登录和创建新用户的所有处理了。大部分的代码都是在检查,检查,检查。相对来说,我反而没有什么要说的了。

因为添加了很多的代码,因此文件现在变成了这样的

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
    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如何查看获得别人共享的内容,但我知道总有办法的。

原创文章,转载请注明: 转载自RIX 编程应该是快乐的

本文链接地址: 一起做网游吧【7】:服务器端注册和登录处理

文章的脚注信息由WordPress的wp-posturl插件自动生成

相关文章

喜欢这个文章吗?

考虑订阅我们的RSS Feed吧!

评论 (0) 引用 (0)

还没有评论.


发表评论


还没有引用.