예제 #1
0
        /// <summary>
        /// A specifier is some block of text contained in < >, such as '<a1>'. While specifiers always follow the form
        /// 'labelNUMBER', this parser will happily accept specifiers missing one or both parts.
        /// </summary>
        /// <param name="From"></param>
        /// <param name="Type">Out parameter. Set to the label parsed from the specifier. Blank if no label found.</param>
        /// <param name="Index">Out parameter. Set to the value of the integer index parsed from the specifier. 0 if no index found.</param>
        /// <returns>True if parsing succeeded, false if parsing failed</returns>
        internal static bool ReadSpecifier(StringIterator From, out String Type, out int Index)
        {
            Type  = "";
            Index = 0;

            if (From.Next != '<')
            {
                return(false);
            }

            From.Advance();
            while (!From.AtEnd && From.Next != '>' && !IsDigit(From.Next))
            {
                Type += From.Next;
                From.Advance();
            }

            if (IsDigit(From.Next))
            {
                if (!ReadNumber(From, out Index))
                {
                    return(false);
                }
            }
            if (From.AtEnd || From.Next != '>')
            {
                return(false);
            }
            From.Advance();
            return(true);
        }
예제 #2
0
        /// <summary>
        /// Parse and format a message intended for a specific recipient.
        /// </summary>
        /// <param name="Recipient"></param>
        /// <param name="Message">The message, possibly containing specifiers.</param>
        /// <param name="Objects">Specifier indicies refer to this list of objects.</param>
        /// <returns></returns>
        public static String FormatParserMessage(MudObject Recipient, String Message, PossibleMatch Objects)
        {
            //A leading @ indicates that the message should be interpretted as an entry in the global message table.
            if (Message[0] == '@')
            {
                Message = Core.GetMessage(Message.Substring(1));
            }

            var formattedMessage = new StringBuilder();
            var iterator         = new StringIterator(Message);

            while (!iterator.AtEnd)
            {
                if (iterator.Next == '<') //We have located a specifier.
                {
                    if (MessageFormatParser.ReadIdentifier(iterator, out var propertyName) && Objects.ContainsKey(propertyName))
                    {
                        formattedMessage.Append(Objects[propertyName] == null ? "%NULL" : Objects[propertyName].ToString());
                    }
                }
                else
                {
                    formattedMessage.Append(iterator.Next);
                    iterator.Advance();
                }
            }

            Message = formattedMessage.ToString();
            formattedMessage.Clear();
            iterator = new StringIterator(Message);

            //Apply the ^ transform: Capitalize the letter following the ^ and remove the ^.
            while (!iterator.AtEnd)
            {
                if (iterator.Next == '^')
                {
                    iterator.Advance();
                    if (iterator.AtEnd)
                    {
                        break;
                    }
                    formattedMessage.Append(new String(iterator.Next, 1).ToUpper());
                    iterator.Advance();
                }
                else
                {
                    formattedMessage.Append(iterator.Next);
                    iterator.Advance();
                }
            }

            return(formattedMessage.ToString());
        }
예제 #3
0
        /// <summary>
        /// Parses a number, which may be multiple digits.
        /// </summary>
        /// <param name="From"></param>
        /// <param name="Number"></param>
        /// <returns></returns>
        private static bool ReadNumber(StringIterator From, out int Number)
        {
            Number = 0;
            var digitString = "";

            while (!From.AtEnd && IsDigit(From.Next))
            {
                digitString += From.Next;
                From.Advance();
            }
            if (digitString.Length == 0)
            {
                return(false);
            }
            Number = Convert.ToInt32(digitString);
            return(true);
        }
예제 #4
0
        internal static bool ReadIdentifier(StringIterator From, out String Into)
        {
            Into = "";
            if (From.Next != '<')
            {
                return(false);
            }
            From.Advance();
            while (!From.AtEnd && From.Next != '>')
            {
                Into += From.Next;
                From.Advance();
            }

            if (From.AtEnd)
            {
                return(false);
            }
            From.Advance();
            return(true);
        }
예제 #5
0
        /// <summary>
        /// Parse and format a message intended for a specific recipient.
        /// </summary>
        /// <param name="Recipient"></param>
        /// <param name="Message">The message, possibly containing specifiers.</param>
        /// <param name="Objects">Specifier indicies refer to this list of objects.</param>
        /// <returns></returns>
        public static String FormatMessage(Actor Recipient, String Message, params Object[] Objects)
        {
            //A leading @ indicates that the message should be interpretted as an entry in the global message table.
            if (Message[0] == '@') Message = Core.GetMessage(Message.Substring(1));

            var formattedMessage = new StringBuilder();
            var iterator = new StringIterator(Message);

            while (!iterator.AtEnd)
            {
                if (iterator.Next == '<') //We have located a specifier.
                {
                    var type = "";
                    var index = 0;
                    if (MessageFormatParser.ReadSpecifier(iterator, out type, out index))
                    {
                        if (index < 0 || index >= Objects.Length) continue; //A blank in the output is preferable to crashing.

                        #region Expand Specifier
                        if (type == "the" && Objects[index] is MudObject)
                        {
                            //'the' overrides the object's article property.
                            formattedMessage.Append(GlobalRules.ConsiderValueRule<String>("printed name", Recipient, Objects[index], "the"));
                        }
                        else if (type == "a" && Objects[index] is MudObject)
                        {
                            formattedMessage.Append(GlobalRules.ConsiderValueRule<String>("printed name", Recipient, Objects[index], (Objects[index] as MudObject).Article));
                        }
                        else if (type == "l") //No connective clause is used for this style of list. eg 1, 2, 3.
                        {
                            FormatList(Recipient, Objects[index], formattedMessage, "");
                        }
                        else if (type == "lor") //Use or. eg 1, 2, or 3.
                        {
                            FormatList(Recipient, Objects[index], formattedMessage, "or");
                        }
                        else if (type == "land") //Use and. eg 1, 2, and 3.
                        {
                            FormatList(Recipient, Objects[index], formattedMessage, "and");
                        }
                        else if (type == "lnor") //Use nor. eg 1, 2, nor 3.
                        {
                            FormatList(Recipient, Objects[index], formattedMessage, "nor");
                        }
                        else if (type == "s")
                        {
                            formattedMessage.Append(Objects[index].ToString());
                        }
                        #endregion
                    }
                }
                else
                {
                    formattedMessage.Append(iterator.Next);
                    iterator.Advance();
                }
            }

            Message = formattedMessage.ToString();
            formattedMessage.Clear();
            iterator = new StringIterator(Message);

            //Apply the ^ transform: Capitalize the letter following the ^ and remove the ^.
            while (!iterator.AtEnd)
            {
                if (iterator.Next == '^')
                {
                    iterator.Advance();
                    if (iterator.AtEnd) break;
                    formattedMessage.Append(new String(iterator.Next, 1).ToUpper());
                    iterator.Advance();
                }
                else
                {
                    formattedMessage.Append(iterator.Next);
                    iterator.Advance();
                }
            }

            return formattedMessage.ToString();
        }
예제 #6
0
 /// <summary>
 /// Parses a number, which may be multiple digits.
 /// </summary>
 /// <param name="From"></param>
 /// <param name="Number"></param>
 /// <returns></returns>
 private static bool ReadNumber(StringIterator From, out int Number)
 {
     Number = 0;
     var digitString = "";
     while (!From.AtEnd && IsDigit(From.Next))
     {
         digitString += From.Next;
         From.Advance();
     }
     if (digitString.Length == 0) return false;
     Number = Convert.ToInt32(digitString);
     return true;
 }
예제 #7
0
        /// <summary>
        /// A specifier is some block of text contained in < >, such as '<a1>'. While specifiers always follow the form 
        /// 'labelNUMBER', this parser will happily accept specifiers missing one or both parts.
        /// </summary>
        /// <param name="From"></param>
        /// <param name="Type">Out parameter. Set to the label parsed from the specifier. Blank if no label found.</param>
        /// <param name="Index">Out parameter. Set to the value of the integer index parsed from the specifier. 0 if no index found.</param>
        /// <returns>True if parsing succeeded, false if parsing failed</returns>
        internal static bool ReadSpecifier(StringIterator From, out String Type, out int Index)
        {
            Type = "";
            Index = 0;

            if (From.Next != '<') return false;

            From.Advance();
            while (!From.AtEnd && From.Next != '>' && !IsDigit(From.Next))
            {
                Type += From.Next;
                From.Advance();
            }

            if (IsDigit(From.Next)) if (!ReadNumber(From, out Index)) return false;
            if (From.AtEnd || From.Next != '>') return false;
            From.Advance();
            return true;
        }
예제 #8
0
        /// <summary>
        /// Parse and format a message intended for a specific recipient.
        /// </summary>
        /// <param name="Recipient"></param>
        /// <param name="Message">The message, possibly containing specifiers.</param>
        /// <param name="Objects">Specifier indicies refer to this list of objects.</param>
        /// <returns></returns>
        public static String FormatMessage(MudObject Recipient, String Message, params Object[] Objects)
        {
            //A leading @ indicates that the message should be interpretted as an entry in the global message table.
            if (Message[0] == '@')
            {
                Message = Core.GetMessage(Message.Substring(1));
            }

            var formattedMessage = new StringBuilder();
            var iterator         = new StringIterator(Message);

            while (!iterator.AtEnd)
            {
                if (iterator.Next == '<') //We have located a specifier.
                {
                    var type  = "";
                    var index = 0;
                    if (MessageFormatParser.ReadSpecifier(iterator, out type, out index))
                    {
                        if (index < 0 || index >= Objects.Length)
                        {
                            continue;                                       //A blank in the output is preferable to crashing.
                        }
                        #region Expand Specifier
                        if (type == "the" && Objects[index] is MudObject)
                        {
                            //'the' overrides the object's article property.
                            formattedMessage.Append(GlobalRules.ConsiderValueRule <String>("printed name", Recipient, Objects[index], "the"));
                        }
                        else if (type == "a" && Objects[index] is MudObject)
                        {
                            formattedMessage.Append(GlobalRules.ConsiderValueRule <String>("printed name", Recipient, Objects[index], (Objects[index] as MudObject).GetProperty <String>("article")));
                        }
                        else if (type == "l") //No connective clause is used for this style of list. eg 1, 2, 3.
                        {
                            FormatList(Recipient, Objects[index], formattedMessage, "");
                        }
                        else if (type == "lor") //Use or. eg 1, 2, or 3.
                        {
                            FormatList(Recipient, Objects[index], formattedMessage, "or");
                        }
                        else if (type == "land") //Use and. eg 1, 2, and 3.
                        {
                            FormatList(Recipient, Objects[index], formattedMessage, "and");
                        }
                        else if (type == "lnor") //Use nor. eg 1, 2, nor 3.
                        {
                            FormatList(Recipient, Objects[index], formattedMessage, "nor");
                        }
                        else if (type == "s")
                        {
                            if (Objects[index] == null)
                            {
                                formattedMessage.Append("%NULL%");
                            }
                            else
                            {
                                formattedMessage.Append(Objects[index].ToString());
                            }
                        }
                        #endregion
                    }
                }
                else
                {
                    formattedMessage.Append(iterator.Next);
                    iterator.Advance();
                }
            }

            Message = formattedMessage.ToString();
            formattedMessage.Clear();
            iterator = new StringIterator(Message);

            //Apply the ^ transform: Capitalize the letter following the ^ and remove the ^.
            while (!iterator.AtEnd)
            {
                if (iterator.Next == '^')
                {
                    iterator.Advance();
                    if (iterator.AtEnd)
                    {
                        break;
                    }
                    formattedMessage.Append(new String(iterator.Next, 1).ToUpper());
                    iterator.Advance();
                }
                else
                {
                    formattedMessage.Append(iterator.Next);
                    iterator.Advance();
                }
            }

            return(formattedMessage.ToString());
        }