Пример #1
0
        /// <summary>
        ///     Invoked when we recieve a world state from the superpeers controlling our zone.
        /// </summary>
        /// <param name="state">World state recieved.</param>
        internal void RecievedWorldState(SuperPeerWorldStatePacket state)
        {
            if (m_currentZone == null)
            {
                return;
            }
            
            // Check packet comes from a superpeer simulating our current zone.
            int lowest_id = 0;
            foreach (ZoneSuperPeer p in m_currentZone.SuperPeers)
            {
                if (p.ID < lowest_id || lowest_id == 0)
                {
                    lowest_id = p.ID;
                }
            }

            // If it dosen't then ignore it, as its probably a left over from a superpeer we are
            // currently unregistering from.
            if (lowest_id != state.SuperPeerID)
            {
                return;
            }

            // Check for jumps.
            /*
            if (m_worldState != null)
            {
                foreach (SuperPeerWorldStatePlayerInfo newInfo in state.Peers)
                {
                    foreach (SuperPeerWorldStatePlayerInfo oldInfo in m_worldState.Peers)
                    {
                        if (newInfo.ClientID == oldInfo.ClientID)
                        {
                            float dx = Math.Abs(newInfo.Account.PeristentState.X - oldInfo.Account.PeristentState.X);
                            float dy = Math.Abs(newInfo.Account.PeristentState.Y - oldInfo.Account.PeristentState.Y);

                            if (dx > 26.0f || dy > 26.0f)
                            {
                                System.Console.WriteLine("WUT!");
                            }
                        }
                    }
                }
            }
            */

            m_worldState = state;

            foreach (SuperPeerWorldStatePlayerInfo peer in state.Peers)
            {
                if (peer.ClientID == m_clientID)
                {
                    m_account = peer.Account;
                }
            }
        }
Пример #2
0
        /// <summary>
        ///     Processes a packet that has been recieved from the arbitrator.
        /// </summary>
        /// <param name="peer">The client or peer we recieved the packet from.</param>
        /// <param name="packet">Packet that we recieved.</param>
        private void ProcessArbitratorIncomingPacket(Connection peer, Packet packet)
        {
            // -----------------------------------------------------------------
            // We've been sent an updated version of the zone grid.
            // -----------------------------------------------------------------           
            if (packet is ZoneGridPacket)
            {
                ZoneGridPacket specificPacket = packet as ZoneGridPacket;
                m_zoneGrid.FromPacket(specificPacket);

                // Invoke events for all super peers who have gained control of zones.
                foreach (ZoneSuperPeer p in m_zoneGrid.GainedSuperPeers)
                {
                    Zone zone = m_zoneGrid.GetZoneByID(p.ZoneID);
                    SuperPeerGainedControl(zone, p);
                }
                
                // Invoke events for all super peers who have lost control of zones.
                foreach (ZoneSuperPeer p in m_zoneGrid.LostSuperPeers)
                {
                    Zone zone = m_zoneGrid.GetZoneByID(p.ZoneID);
                    SuperPeerLostControl(zone, p);
                }

                Logger.Info("Recieved updated zone grid from arbitrator.", LoggerVerboseLevel.High);
            }

            // -----------------------------------------------------------------
            // We've been sent our persistent state information.
            // -----------------------------------------------------------------
            else if (packet is UserAccountStatePacket)
            {
                UserAccountStatePacket specificPacket = packet as UserAccountStatePacket;

                m_account  = specificPacket.Account;
                m_clientID = specificPacket.ClientID;

                if (m_threadNameSet == false)
                {
                    System.Threading.Thread.CurrentThread.Name = "Client #" + m_clientID;
                    m_threadNameSet = true;
                }

                Logger.Info("Recieved updated account information from arbitrator.", LoggerVerboseLevel.High);
            }

            // -----------------------------------------------------------------
            // Information sent to one of our super peers about a client?
            // -----------------------------------------------------------------
            else if ((packet as SuperPeerClientPacket) != null)
            {
                SuperPeerClientPacket specificPacket = packet as SuperPeerClientPacket;
                bool found = false;

                foreach (Connection connection in m_listenConnection.Peers)
                {
                    if (connection.MetaData != null)
                    {
                        GameClientPeer p = ((GameClientPeer)connection.MetaData);
                        foreach (SuperPeerToClientConnection conn in p.SuperPeerConnections)    // ERROR IS HERE: SuperPeerConnections is filled with inactive ones that are recieving the packets too :(
                        {
                            if (conn.SuperPeer.ID == specificPacket.SuperPeerID &&
                                conn.ClientID     == specificPacket.ClientID)
                            {
                                conn.RecievedArbitratorPacket(specificPacket);
                                found = true;
                            }
                        }
                    }
                }

                if (found == false)
                {
                    throw new InvalidOperationException("Failed to find super peer to direct arbitrator packet to.");
                }
            }

            // -----------------------------------------------------------------
            // Information sent to one of our super peers?
            // -----------------------------------------------------------------
            else if ((packet as SuperPeerPacket) != null)
            {
                SuperPeerPacket specificPacket = packet as SuperPeerPacket;
                SuperPeer superpeer = FindSuperPeerByID(specificPacket.SuperPeerID);

                if (superpeer != null)
                {
                    superpeer.ArbitratorRecievedPacket(m_arbitratorConnection, specificPacket);
                }
                else
                {
                    throw new InvalidOperationException("Failed to find super peer to direct arbitrator packet to.");
                }
            }
        }
Пример #3
0
        /// <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>
        ///     Finishes the process of unregistering a peer.
        /// </summary>
        private void FinishUnregister()
        {
            if (m_unregistered == true)
            {
                throw new InvalidOperationException("Recieved invalid finish-unregister request, already unregistered.");
            }

            m_unregistered      = true;
            m_registering       = false;
            m_registered        = false;
            m_unregistering     = false;
            m_isActive          = false;
            m_account           = null;

            SuperPeerUnregisterReplyPacket reply = new SuperPeerUnregisterReplyPacket();
            reply.SuperPeerID = m_superpeer.ID;
            m_connection.SendPacket(reply);
        }
        /// <summary>
        ///     Finishes the process of registering a peer.
        /// </summary>
        private void FinishRegister(UserAccount account)
        {
            if (m_registered == true || m_registering == false || m_unregistered == true || m_unregistering == true)
            {
                return;
            }

            m_unregistered      = false;
            m_registering       = false;
            m_registered        = true;
            m_unregistering     = false;
            m_isActive          = true;
            m_account           = account;

            // Send a success reply!
            SuperPeerRegisterReplyPacket reply = new SuperPeerRegisterReplyPacket();
            reply.SuperPeerID = m_superpeer.ID;
            m_connection.SendPacket(reply);

            // And register this peer with the superpeer.
            m_superpeer.PeerRegistered(this);
        }
Пример #6
0
        /// <summary>
        ///     Loads a user account that has the given username from the database.
        /// </summary>
        /// <param name="database">Database to load username from.</param>
        /// <param name="username">Username of account to load.</param>
        /// <returns>Account loaded, or null if one dosen't exist.</returns>
        public static UserAccount LoadByUsername(DBConnection database, string username)
        {
            DBResults results = database.Query(@"SELECT id, username, password, email, last_login_timestamp, persistent_state FROM {0} WHERE LOWER(`username`)='{1}'",
                                                Settings.DB_TABLE_ACCOUNTS,
                                                StringHelper.Escape(username.ToLower()));

            if (results.RowsAffected > 0)
            {
                DBRow row = results[0];

                UserAccount account = new UserAccount();
                account.m_id                    = (int)row["id"];
                account.m_username              = row["username"].ToString();
                account.m_password              = row["password"].ToString();
                account.m_email                 = row["email"].ToString();
                account.m_last_login_timestamp  = row["last_login_timestamp"] == null ? 0 : (int)row["last_login_timestamp"];
                account.m_persistent_state      = new UserAccountPersistentState((byte[])row["persistent_state"]);

                return account;
            }
            else
            {
                return null;
            }
        }
Пример #7
0
        /// <summary>
        ///     Create a user account with the given information.
        /// </summary>
        /// <param name="settings">Settings used to initialize this account.</param>
        /// <param name="database">Database to load username from.</param>
        /// <param name="username">Username of account to load.</param>
        /// <returns>Account loaded, or null if one dosen't exist.</returns>
        public static UserAccount CreateAccount(Settings settings, DBConnection database, string username, string password, string email)
        {
            DBResults results = database.Query(@"SELECT id FROM {0} WHERE LOWER(`username`)='{1}'",
                                                Settings.DB_TABLE_ACCOUNTS,
                                                StringHelper.Escape(username.ToLower()));

            if (results.RowsAffected <= 0)
            {
                UserAccount account = new UserAccount();
                account.m_id                    = (int)results.LastInsertID;
                account.m_username              = username;
                account.m_password              = password;
                account.m_email                 = email;
                account.m_last_login_timestamp  = 0;
                account.m_persistent_state      = new UserAccountPersistentState();

                account.LoadDefaults(settings);

                account.Serialize(database);

                return account;
            }
            else
            {
                return null;
            }
        }