/// <summary> /// Processes a packet that has been recieved from a client. /// </summary> /// <param name="packet">Packet that we recieved.</param> private void ProcessIncomingPacket(Packet packet) { // ----------------------------------------------------------------- // Client is attempting to login. // ----------------------------------------------------------------- if (packet is LoginPacket) { LoginPacket specificPacket = packet as LoginPacket; LoginResultPacket reply = new LoginResultPacket(); reply.Result = LoginResult.Success; // Already logged into an account? if (m_account != null) { reply.Result = LoginResult.AlreadyLoggedIn; } else { UserAccount account = UserAccount.LoadByUsername(m_arbitrator.DatabaseConnection, specificPacket.Username); // Account not found? if (account == null) { reply.Result = LoginResult.AccountNotFound; } // Password invalid? else if (account.Password != specificPacket.Password) { reply.Result = LoginResult.PasswordInvalid; } // Account already in us? else { DBResults results = m_arbitrator.DatabaseConnection.Query(@"SELECT id FROM {0} WHERE account_id={1}", Settings.DB_TABLE_ACTIVE_CLIENTS, account.ID); // Account already in us? if (results.RowsAffected > 0) { reply.Result = LoginResult.AccountInUse; } // Success! Mark client as logged in. else { m_arbitrator.DatabaseConnection.Query(@"UPDATE {0} SET account_id={1} WHERE id={2}", Settings.DB_TABLE_ACTIVE_CLIENTS, account.ID, m_clientDatabaseID); m_account = account; } } } m_connection.SendPacket(reply, specificPacket); } // ----------------------------------------------------------------- // Client is attempting to create an account. // ----------------------------------------------------------------- else if (packet is CreateAccountPacket) { CreateAccountPacket specificPacket = packet as CreateAccountPacket; CreateAccountResultPacket reply = new CreateAccountResultPacket(); reply.Result = CreateAccountResult.Success; // Email already exists :( if (UserAccount.LoadByEmail(m_arbitrator.DatabaseConnection, specificPacket.Email) != null) { reply.Result = CreateAccountResult.EmailAlreadyExists; } else { // Username already exists :(. if (UserAccount.LoadByUsername(m_arbitrator.DatabaseConnection, specificPacket.Username) != null) { reply.Result = CreateAccountResult.UsernameAlreadyExists; } // Create account! else { UserAccount.CreateAccount(m_arbitrator.Settings, m_arbitrator.DatabaseConnection, specificPacket.Username, specificPacket.Password, specificPacket.Email); } } m_connection.SendPacket(reply, specificPacket); } // ----------------------------------------------------------------- // Client is attempting to register as listening and ready to be // a superpeer. // ----------------------------------------------------------------- else if (packet is RegisterAsListeningPacket) { RegisterAsListeningPacket specificPacket = packet as RegisterAsListeningPacket; RegisterAsListeningResultPacket reply = new RegisterAsListeningResultPacket(); if (m_listening == true) { reply.Result = RegisterAsListeningResult.AlreadyListening; } else if (m_account == null) { reply.Result = RegisterAsListeningResult.NotLoggedIn; } else { m_listenPort = specificPacket.Port; m_listening = true; reply.Result = RegisterAsListeningResult.Success; // Update the client registration to include listening information. RegisterClient(); // Send the peer a world grid. SendUpdatedWorldGrid(); // Send account information to them. UserAccountStatePacket p = new UserAccountStatePacket(); p.Account = m_account.Clone(); p.Account.Email = ""; p.Account.Password = ""; p.ClientID = (int)m_clientDatabaseID; m_connection.SendPacket(p); } m_connection.SendPacket(reply, specificPacket); } // ----------------------------------------------------------------- // Client has changed zone. // ----------------------------------------------------------------- else if (packet is ChangeZonePacket) { ChangeZonePacket specificPacket = packet as ChangeZonePacket; Logger.Info("Client moved into zone #{0} from zone #{1}.", LoggerVerboseLevel.High, specificPacket.ZoneID, m_zoneID); // Update and save zone information to database. m_zoneID = specificPacket.ZoneID; RegisterClient(); } // ----------------------------------------------------------------- // SuperPeer wants account information for a given client. // ----------------------------------------------------------------- else if (packet is SuperPeerRetrieveAccountPacket) { SuperPeerRetrieveAccountPacket specificPacket = packet as SuperPeerRetrieveAccountPacket; // TODO: Check client has authority to retrieve account information for given player. // (eg. its a superpeer in an area the client is). Flag as cheating if not. Logger.Info("Client #{0} wants to retrieve account information for player #{1}.", LoggerVerboseLevel.High, m_clientDatabaseID, specificPacket.ClientID); // Load clients information from the database. DBResults client_info = m_arbitrator.DatabaseConnection.Query(@"SELECT `account_id` FROM {0} WHERE id={1}", Settings.DB_TABLE_ACTIVE_CLIENTS, specificPacket.ClientID); // TODO: Add error checking for when client-id is not valid. SuperPeerRetrieveAccountReplyPacket reply = new SuperPeerRetrieveAccountReplyPacket(); reply.SuperPeerID = specificPacket.SuperPeerID; reply.ClientID = specificPacket.ClientID; if (client_info.RowsAffected > 0) { reply.Account = UserAccount.LoadByID(m_arbitrator.DatabaseConnection, (int)client_info[0]["account_id"]); } else { reply.Account = new UserAccount(); reply.Account.Username = "******"; } reply.Account.Email = ""; reply.Account.Password = ""; m_connection.SendPacket(reply); } // ----------------------------------------------------------------- // SuperPeer wants to store account information for a given client. // ----------------------------------------------------------------- else if (packet is SuperPeerStoreAccountPacket) { SuperPeerStoreAccountPacket specificPacket = packet as SuperPeerStoreAccountPacket; // TODO: Check client has authority to store account information for given player. // (eg. its a superpeer in an area the client is). Flag as cheating if not. Logger.Info("Client #{0} wants to store account information for player #{1} in zone #{2}.", LoggerVerboseLevel.High, m_clientDatabaseID, specificPacket.ClientID, specificPacket.ZoneID); StoreAccountRequest request = new StoreAccountRequest(); request.SuperPeerID = specificPacket.SuperPeerID; request.ClientID = specificPacket.ClientID; request.ZoneID = specificPacket.ZoneID; request.RecievedFrom = this; request.Account = specificPacket.Account; request.RecieveTime = Environment.TickCount; request.Reason = specificPacket.Reason; m_arbitrator.StoreAccountRequestRecieved(request); } // ----------------------------------------------------------------- // Client wants to gracefully disconnect. // ----------------------------------------------------------------- else if (packet is GracefulDisconnectPacket) { UnRegisterClient(); GracefulDisconnectReplyPacket reply = new GracefulDisconnectReplyPacket(); m_connection.SendPacket(reply, packet); } }
/// <summary> /// Invoked when a peer recieves a request to store account information persistently. /// The request is queued until coloborating information is recieved from enough other /// super-peers. /// </summary> /// <param name="request">Request that was recieved.</param> internal void StoreAccountRequestRecieved(StoreAccountRequest request) { m_databaseConnection.QueryParameterized(@"INSERT INTO {0}(superpeer_id, client_id, zone_id, account_id, state, success, failed, recieved_arbitrator_id, superpeer_client_id, recieved_time, reason) VALUES ({1}, {2}, {3}, {4}, @parameter_1, 0, 0, {5}, {6}, UNIX_TIMESTAMP(), '{7}')", new object[] { request.Account.PeristentState.Serialize() }, Settings.DB_TABLE_PENDING_STORE_REQUESTS, request.SuperPeerID, request.ClientID, request.ZoneID, request.Account.ID, m_arbitratorDatabaseID, request.RecievedFrom.DatabaseID, StringHelper.Escape(request.Reason)); //System.Console.WriteLine("["+Environment.TickCount+"] Recieved store account for " + request.SuperPeerID+"/"+request.ClientID+" - "+request.Reason); }