/// <summary> /// Handles incoming <see cref="Packet"/>. /// </summary> /// <param name="p"><see cref="Packet"/> to handle.</param> internal void Handle( Packet p ) { switch ( p.FirstOpcode ) { case ServiceLayer.Identity: { switch ( p.SecondOpcode ) { case ServiceLayer.InitializeRequest: { Logger.WriteLine(Source.InnerNetwork, "Connected service requests connection initialization."); return; } case ServiceLayer.SetSettingsRequest: { LoginServiceSettings settings = ( LoginServiceSettings )SetSettingsRequest.FromPacket(p, ServiceType.LoginService); ConnectionsManager.SetServiceSettings(settings); return; } } break; } case UserDataLayer.Identity: { switch ( p.SecondOpcode ) { case UserDataLayer.AuthenticateUser: { UserAuthenticationRequest request = new UserAuthenticationRequest(p); if ( RealtimeManager.ConnectedUsers.Connected(request.SessionID) ) { Send(new UserAuthenticationResponse(request.RequestID, UserAuthenticationResponseType.AccessFailed).ToPacket()); return; } if ( RealtimeManager.ConnectedUsers.Connected(request.Login) ) { Send(new UserAuthenticationResponse(request.RequestID, UserAuthenticationResponseType.AccountInUse).ToPacket()); return; } Send(DataProvider.DataBase.User_Auth(request, ( LoginServiceSettings )Service.RemoteServiceSettings).ToPacket()); return; } case UserDataLayer.CacheUserSessionRequest: { CacheUserSessionRequest request = new CacheUserSessionRequest(p); if ( RealtimeManager.ConnectedUsers.Connected(request.Session.ID) || RealtimeManager.ConnectedUsers.Connected(request.Session.AccountName) ) { Send(new CacheUserSessionResponse(request.RequestID, CacheUserSessionResponse.Failed).ToPacket()); return; } RealtimeManager.ConnectedUsers.Register(request.Session); Send(new CacheUserSessionResponse(request.RequestID, CacheUserSessionResponse.Accepted).ToPacket()); return; } case UserDataLayer.WorldsListRequest: { WorldsListRequest request = new WorldsListRequest(p); Send(new WorldsListResponse(request.RequestID, RealtimeManager.WorldsInfo.Get()).ToPacket()); return; } case UserDataLayer.UnCacheUser: { UnCacheUser request = new UnCacheUser(p); // update user login / logout / used_time values in database. UserSession session = RealtimeManager.ConnectedUsers.Find(request.SessionID); if ( session != UserSession.Null ) { DataProvider.DataBase.User_Logout(session.AccountID, session.StartTime, session.IPAddress, session.LastWorld); RealtimeManager.ConnectedUsers.Unregister(request.SessionID); } return; } case UserDataLayer.JoinWorldRequest: { // check access level JoinWorldRequest request = new JoinWorldRequest(p); if ( !RealtimeManager.ConnectedUsers.Connected(request.SessionID) ) { Send(new JoinWorldResponse(request.RequestID, JoinWorldRequestResult.AccessFailed).ToPacket()); return; } if ( !RealtimeManager.WorldsInfo.Contains(request.WorldID) || !RealtimeManager.WorldsInfo.IsOnline(request.WorldID) ) { Send(new JoinWorldResponse(request.RequestID, JoinWorldRequestResult.SystemError).ToPacket()); return; } if ( RealtimeManager.WorldsInfo.IsFull(request.WorldID) ) { Send(new JoinWorldResponse(request.RequestID, JoinWorldRequestResult.TooManyPlayers).ToPacket()); return; } Send(new JoinWorldResponse(request.RequestID, JoinWorldRequestResult.Accepted).ToPacket()); return; } } break; } default: { break; } } Logger.WriteLine(Source.InnerNetwork, "Unknown packet received from {0} service:{1}{2}", ServiceType.LoginService, Environment.NewLine, p.ToString()); }
/// <summary> /// User authentication request processing. /// </summary> /// <param name="netRequest"><see cref="UserAuthenticationRequest"/> to verify user data from.</param> /// <param name="settings"><see cref="LoginServiceSettings"/> object.</param> /// <returns><see cref="UserAuthenticationResponse"/> struct.</returns> public override UserAuthenticationResponse User_Auth( UserAuthenticationRequest netRequest, LoginServiceSettings settings ) { MsSqlDataCommand msdc = new MsSqlDataCommand ( "[User_Auth]", CommandType.StoredProcedure, new SqlParameter("@login", SqlDbType.VarChar, 0x10) { Value = netRequest.Login }, new SqlParameter("@password", SqlDbType.VarChar, 0x2f) { Value = netRequest.Password }, new SqlParameter("@uid", SqlDbType.Int) { Direction = ParameterDirection.Output }, new SqlParameter("@last_world", SqlDbType.TinyInt) { Direction = ParameterDirection.Output }, new SqlParameter("@access_level", SqlDbType.TinyInt) { Direction = ParameterDirection.Output } ); SetConnection(ref msdc, m_ActiveConnections.Next()); msdc.ExecuteNonQuery(); int uid = TypesConverter.GetInt(msdc.Parameters["@uid"].Value, int.MinValue); UserAuthenticationResponse rsp = new UserAuthenticationResponse(netRequest.RequestID, UserAuthenticationResponseType.UserOrPasswordWrong); switch ( uid ) { case int.MinValue: // conversion error { rsp.Response = UserAuthenticationResponseType.SystemError; break; } case -2: // invalid credentials break; case -1: // login doesn't exist { if ( settings != null && settings.AutoCreateUser ) { // creating user uid = User_Create(netRequest.Login, netRequest.Password, settings.DefaultAccessLevel); switch ( uid ) { case int.MinValue: // conversion error case -2: // db insert error { rsp.Response = UserAuthenticationResponseType.SystemError; break; } case -1: // login already exists break; default: // user created { rsp.Response = UserAuthenticationResponseType.UserAccepted; rsp.UserID = uid; rsp.AccessLevel = settings.DefaultAccessLevel; rsp.LastWorldID = TypesConverter.GetByte(msdc.Parameters["@last_world"].Value, 1); break; } } } else goto case -2; break; } default: { rsp.Response = UserAuthenticationResponseType.UserAccepted; rsp.UserID = uid; rsp.LastWorldID = TypesConverter.GetByte(msdc.Parameters["@last_world"].Value, 1); rsp.AccessLevel = TypesConverter.GetByte(msdc.Parameters["@access_level"].Value, 0); break; } } ReleaseCommand(msdc); return rsp; }