/// <summary>
        /// Get the primary server that the player is online at.  Returns null
        /// if the player is not online.
        /// </summary>
        /// <returns>The primary server that the player is online at is
        /// returned, else null if the player is not online.</returns>
        public GameServer GetOnlineServer()
        {
            GameCharacter Character = GetOnlineCharacter();

            if (Character == null)
            {
                return(null);
            }

            return(Character.Server);
        }
 /// <summary>
 /// Create a new CharacterPartEvent.
 /// </summary>
 /// <param name="Character">Supplies the character.</param>
 /// <param name="IsDM">Supplies true if the character was DM
 /// privileged at part time.</param>
 /// <param name="Server">Supplies the server that the character has
 /// parted.</param>
 public CharacterPartEvent(GameCharacter Character, bool IsDM, GameServer Server)
 {
     this.Character = Character;
     this.IsDM = IsDM;
     this.Server = Server;
 }
        /// <summary>
        /// Reference the data for a character by the character name.  If the
        /// data was not yet available, it is retrieved from the database.
        /// </summary>
        /// <param name="CharacterName">Supplies the object name.</param>
        /// <param name="Database">Supplies the database connection to use for
        /// queries, if required.  The active rowset may be consumed.</param>
        /// <returns>The object data is returned, else null if the object did
        /// not exist.</returns>
        public GameCharacter ReferenceCharacterByName(string CharacterName, IALFADatabase Database)
        {
            //
            // Check if the object is already known first.
            //

            GameCharacter Character = (from C in Characters
                                       where C.CharacterName.Equals(CharacterName, StringComparison.InvariantCultureIgnoreCase)
                                       orderby C.Online descending
                                       select C).FirstOrDefault();

            if (Character != null)
                return Character;

            //
            // Need to pull the data from the database.
            //

            if (Database == null)
                return null;

            int ServerId;

            Database.ACR_SQLQuery(String.Format(
                "SELECT `ID`, `PlayerID`, `IsOnline`, `ServerID`, `Name`, `Location` FROM `characters` WHERE `Name` = '{0}' AND `IsDeleted` = 0 AND `IsPlayable` = 1 ORDER BY `ID` ASC ",
                Database.ACR_SQLEncodeSpecialChars(CharacterName)));

            if (!Database.ACR_SQLFetch())
                return null;

            Character = new GameCharacter(this);

            Character.CharacterId = Convert.ToInt32(Database.ACR_SQLGetData(0));
            Character.PlayerId = Convert.ToInt32(Database.ACR_SQLGetData(1));
            Character.Online = ConvertToBoolean(Database.ACR_SQLGetData(2));
            ServerId = Convert.ToInt32(Database.ACR_SQLGetData(3));
            Character.CharacterName = Database.ACR_SQLGetData(4);
            Character.LocationString = Database.ACR_SQLGetData(5);

            InsertNewCharacter(Character, ServerId, Database, null);

            return Character;
        }
        /// <summary>
        /// This function inserts a character into the various character lists
        /// and issues the character join event.
        /// </summary>
        /// <param name="Character">Supplies the character object to insert.
        /// </param>
        /// <param name="ServerId">Supplies the server id that the player is
        /// logged on to (only meaningful if the character is online).</param>
        /// <param name="Database">Supplies the database connection to use for
        /// queries, if required.  The active rowset may be consumed.</param>
        /// <param name="InitialDMState">Supplies the initial DM state of the
        /// backing player object to update, for a synchronization of an
        /// existing player with a new character.</param>
        private void InsertNewCharacter(GameCharacter Character, int ServerId, IALFADatabase Database, bool? InitialDMState)
        {
            GameServer Server;

            Character.Player = ReferencePlayerById(Character.PlayerId, Database);

            if (Character.Player == null)
                throw new ApplicationException(String.Format("Character {0} references invalid player id {1}", Character.CharacterId, Character.PlayerId));

            if (InitialDMState != null)
                Character.Player.IsDM = (InitialDMState != false);

            Character.Player.Characters.Add(Character);

            try
            {
                CharacterList.Add(Character);

                try
                {
                    if (Character.Online)
                    {
                        Server = ReferenceServerById(ServerId, Database);

                        if (Server == null)
                            throw new ApplicationException(String.Format("Character {0} is online but references invalid server id {1}", Character.CharacterId, ServerId));

                        Character.Server = Server;

                        //
                        // If the character is coming online, but its associated server is
                        // not actually online, then mark the character as offline.
                        //

                        if (Character.Online && !Character.Server.Online)
                        {
                            Character.Online = false;
                            return;
                        }

                        //
                        // Mark the character as visited so that if we come in
                        // on the main thread during the middle of a character
                        // synchronization cycle, we won't immediate offline
                        // the character.
                        //

                        Character.Visited = true;
                        Character.Server = Server;
                        Character.Server.Characters.Add(Character);

                        try
                        {
                            OnlineCharacterList.Add(Character);

                            try
                            {
                                Character.Player.UpdateOnlineCharacter();
                                OnCharacterJoin(Character);
                            }
                            catch
                            {
                                OnlineCharacterList.Remove(Character);
                                throw;
                            }
                        }
                        catch
                        {
                            Character.Server.Characters.Remove(Character);
                            throw;
                        }
                    }
                }
                catch
                {
                    CharacterList.Remove(Character);
                    throw;
                }
            }
            catch
            {
                Character.Player.Characters.Remove(Character);
                Character.Player.UpdateOnlineCharacter();
                throw;
            }
        }
 /// <summary>
 /// This method is called when a character is discovered to have gone
 /// offline.
 /// </summary>
 /// <param name="Character">Supplies the character that is now
 /// considered to be offline.</param>
 private void OnCharacterPart(GameCharacter Character)
 {
     EnqueueEvent(new CharacterPartEvent(Character, Character.Player.IsDM, Character.Server));
 }
 /// <summary>
 /// This method is called when a chat tell IPC event is received.
 /// </summary>
 /// <param name="Sender">Supplies the sender.</param>
 /// <param name="Recipient">Supplies the recipient.</param>
 /// <param name="Message">Supplies the message text.</param>
 private void OnChatTell(GameCharacter Sender, GamePlayer Recipient, string Message)
 {
     EnqueueEvent(new ChatTellEvent(Sender, Recipient, Message));
 }
        /// <summary>
        /// This method performs the initial synchronization step at first run
        /// that downloads the initial character list.  A bulk query is issued
        /// here to reduce the number of database round-trips at startup time.
        /// 
        /// Note that no attempt is made to mark offline characters here.  That
        /// step is done in the normal synchronization round, as this is the
        /// initial round anyway.
        /// </summary>
        private void PerformInitialSynchronization()
        {
            IALFADatabase Database = DatabaseLinkQueryThread;
            List<InitialSynchronizationRow> Rowset = new List<InitialSynchronizationRow>();

            Database.ACR_SQLQuery(
                "SELECT " +
                    "`characters`.`ID` AS character_id, " +                  //  0
                    "`characters`.`PlayerID` AS player_id, " +               //  1
                    "`characters`.`Name` AS character_name, " +              //  2
                    "`characters`.`ServerID` AS server_id, " +               //  3
                    "`characters`.`Location` AS character_location, " +      //  4
                    "`players`.`IsDM` AS player_is_dm, " +                   //  5
                    "`players`.`Name` AS player_name, " +                    //  6
                    "`servers`.`IPAddress` AS server_address_string, " +     //  7
                    "`servers`.`Name` AS server_name " +                     //  8
                "FROM " +
                    "`characters` " +
                "INNER JOIN `servers` ON `characters`.`ServerID` = `servers`.`ID` " +
                "INNER JOIN `players` ON `characters`.`PlayerID` = `players`.`ID` " +
                "WHERE " +
                    "`characters`.`IsOnline` = 1 "
                );

            while (Database.ACR_SQLFetch())
            {
                InitialSynchronizationRow Row;

                Row.CharacterId = Convert.ToInt32(Database.ACR_SQLGetData(0));
                Row.PlayerId = Convert.ToInt32(Database.ACR_SQLGetData(1));
                Row.CharacterName = Database.ACR_SQLGetData(2);
                Row.ServerId = Convert.ToInt32(Database.ACR_SQLGetData(3));
                Row.CharacterLocation = Database.ACR_SQLGetData(4);
                Row.PlayerIsDM = ConvertToBoolean(Database.ACR_SQLGetData(5));
                Row.PlayerName = Database.ACR_SQLGetData(6);
                Row.ServerAddressString = Database.ACR_SQLGetData(7);
                Row.ServerName = Database.ACR_SQLGetData(8);

                Rowset.Add(Row);
            }

            lock (this)
            {
                //
                // Update entries.
                //

                foreach (InitialSynchronizationRow Row in Rowset)
                {
                    GameServer Server = (from S in Servers
                                         where S.ServerId == Row.ServerId
                                         select S).FirstOrDefault();

                    if (Server == null)
                    {
                        Server = new GameServer(this);

                        Server.ServerName = Row.ServerName;
                        Server.ServerId = Row.ServerId;
                        Server.SetHostnameAndPort(Row.ServerAddressString);

                        InsertNewServer(Server, Database);
                    }

                    GamePlayer Player = (from P in Players
                                         where P.PlayerId == Row.PlayerId
                                         select P).FirstOrDefault();

                    if (Player == null)
                    {
                        Player = new GamePlayer(this);

                        Player.PlayerName = Row.PlayerName;
                        Player.PlayerId = Row.PlayerId;
                        Player.IsDM = Row.PlayerIsDM;

                        InsertNewPlayer(Player, Database);
                    }

                    GameCharacter Character = (from C in Characters
                                               where C.CharacterId == Row.CharacterId
                                               select C).FirstOrDefault();

                    if (Character == null)
                    {
                        Character = new GameCharacter(this);

                        Character.CharacterId = Row.CharacterId;
                        Character.PlayerId = Row.PlayerId;
                        Character.Online = true;
                        Character.CharacterName = Row.CharacterName;
                        Character.LocationString = Row.CharacterLocation;

                        InsertNewCharacter(Character, Row.ServerId, Database, null);
                    }
                }

#if DEBUG_MODE
                WriteDiagnosticLog(String.Format("GameWorldManager.PerformInitialSynchronization: Synchronized {0} servers, {1} players, {2} characters.",
                    ServerList.Count,
                    PlayerList.Count,
                    CharacterList.Count));
#endif
            }
        }
        /// <summary>
        /// Reference the data for a character by the character id.  If the
        /// data was not yet available, it is retrieved from the database.
        /// </summary>
        /// <param name="CharacterId">Supplies the object id.</param>
        /// <param name="Database">Supplies the database connection to use for
        /// queries, if required.  The active rowset may be consumed.</param>
        /// <param name="InitialDMState">Supplies the initial DM state of the
        /// backing player object to update, for a synchronization of an
        /// existing player with a new character.</param>
        /// <returns>The object data is returned, else null if the object did
        /// not exist.</returns>
        public GameCharacter ReferenceCharacterById(int CharacterId, IALFADatabase Database, bool? InitialDMState)
        {
            //
            // Check if the object is already known first.
            //

            GameCharacter Character = (from C in Characters
                                       where C.CharacterId == CharacterId
                                       select C).FirstOrDefault();

            if (Character != null)
                return Character;

            //
            // Need to pull the data from the database.
            //

            if (Database == null)
                return null;

            int ServerId;

            Database.ACR_SQLQuery(String.Format(
                "SELECT `Name`, `PlayerID`, `IsOnline`, `ServerID`, `Location` FROM `characters` WHERE `ID` = {0}",
                CharacterId));

            if (!Database.ACR_SQLFetch())
                return null;

            Character = new GameCharacter(this);

            Character.CharacterName = Database.ACR_SQLGetData(0);
            Character.CharacterId = CharacterId;
            Character.PlayerId = Convert.ToInt32(Database.ACR_SQLGetData(1));
            Character.Online = ConvertToBoolean(Database.ACR_SQLGetData(2));
            ServerId = Convert.ToInt32(Database.ACR_SQLGetData(3));
            Character.LocationString = Database.ACR_SQLGetData(4);

            InsertNewCharacter(Character, ServerId, Database, InitialDMState);

            return Character;
        }
示例#9
0
 /// <summary>
 /// Create a new ChatTellEvent.
 /// </summary>
 /// <param name="Sender">Supplies the sender.</param>
 /// <param name="Recipient">Supplies the recipient.</param>
 /// <param name="Message">Supplies the message text.</param>
 public ChatTellEvent(GameCharacter Sender, GamePlayer Recipient, string Message)
 {
     this.Sender    = Sender;
     this.Recipient = Recipient;
     this.Message   = Message;
 }
 /// <summary>
 /// Create a new ChatTellEvent.
 /// </summary>
 /// <param name="Sender">Supplies the sender.</param>
 /// <param name="Recipient">Supplies the recipient.</param>
 /// <param name="Message">Supplies the message text.</param>
 public ChatTellEvent(GameCharacter Sender, GamePlayer Recipient, string Message)
 {
     this.Sender = Sender;
     this.Recipient = Recipient;
     this.Message = Message;
 }
示例#11
0
 /// <summary>
 /// Create a new CharacterJoinEvent.
 /// </summary>
 /// <param name="Character">Supplies the character.</param>
 /// <param name="IsDM">Supplies true if the character was DM
 /// privileged at join time.</param>
 /// <param name="Server">Supplies the server that the character has
 /// joined.</param>
 public CharacterJoinEvent(GameCharacter Character, bool IsDM, GameServer Server)
 {
     this.Character = Character;
     this.IsDM      = IsDM;
     this.Server    = Server;
 }