15六/100
一起做网游吧【7】:服务器端注册和登录处理
C:登录
登录登录登录!!!我听到有人非常不耐烦的声音。
?Download server_src_login.erl
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插件自动生成