/// <summary>
        /// Builds the 'FullString' property based on
        /// the available parameters in 'Variables',
        /// the root resource id and the user-language dependent strings.
        /// </summary>
        protected void BuildString()
        {
            int            index, varindex;
            InlineVariable var;
            string         strval;
            int            intval;
            uint           uintval;
            List <int>     q_indices = new List <int>();
            List <string>  q_strings = new List <string>();

            // In this iteration we will use the parsed 'Variables' to actually build
            // the string in the user-lanuage, honoring the $ordering.

            // resolve root resource string in user-language
            if (!stringResources.TryGetValue(resourceID, out resourceName))
            {
                resourceName = String.Empty;
            }

            // will store fully constructed string
            fullString = String.Copy(resourceName);

            // specifies the index of next variable to use
            varindex = 0;

            // build string
            index = HasVariable(fullString);
            while (index > -1)
            {
                while (index > -1)
                {
                    // which type of inline var
                    switch (fullString[index + 1])
                    {
                    // %i or %d are 4 byte integers. Their value should be inserted as a string.
                    case INTEGERFLAG:
                    case INTEGERFLAG2:
                        var    = Variables[varindex];
                        intval = (int)var.Data;                                 // todo check type
                        varindex++;

                        string intstr = intval.ToString();

                        // remove the %i, %d and insert the integer directly
                        fullString = fullString.Remove(index, 2);
                        fullString = fullString.Insert(index, intstr);

                        // adjust stringliteral indices right to this index
                        for (int i = 0; i < q_indices.Count; i++)
                        {
                            if (q_indices[i] > index)
                            {
                                q_indices[i] = q_indices[i] + intstr.Length - 2;
                            }
                        }
                        break;

                    // %q is a server-sent string which is directly attached to the message and not looked up from rsb
                    // if it contains any %vars itself, these MUST NOT be resolved further (won't be available in params)
                    case EMBEDDEDSTRINGLITERALFLAG:
                        var    = Variables[varindex];
                        strval = (string)var.Data;
                        varindex++;

                        // remove the %q, save string and position for insert later
                        fullString = fullString.Remove(index, 2);
                        q_strings.Add(strval);
                        q_indices.Add(index);

                        // adjust stringliteral indices right to this index
                        for (int i = 0; i < q_indices.Count; i++)
                        {
                            if (q_indices[i] > index)
                            {
                                q_indices[i] = q_indices[i] - 2;
                            }
                        }
                        break;

                    // %s is a server-sent string resource id. It must be resolved from .rsb
                    // If it contains any %vars itself, these sub-vars must be resolved AFTER any next-vars.
                    case STRINGRESOURCELITERALFLAG:
                        var     = Variables[varindex];
                        uintval = (uint)var.Data;
                        varindex++;

                        if (!stringResources.TryGetValue(uintval, out strval))
                        {
                            strval = String.Empty;
                        }

                        // remove the %s, and insert the string,
                        // but skip its content in this inner while()
                        fullString = fullString.Remove(index, 2);
                        fullString = fullString.Insert(index, strval);

                        // adjust stringliteral indices right to this index
                        for (int i = 0; i < q_indices.Count; i++)
                        {
                            if (q_indices[i] > index)
                            {
                                q_indices[i] = q_indices[i] + strval.Length - 2;
                            }
                        }

                        // skip
                        index += strval.Length;

                        break;

#if !VANILLA
                    // %r is a server-sent string resource id. It must be resolved from .rsb
                    // If it contains any %vars itself, these sub-vars must be resolved BEFORE any next-vars.
                    case STRINGRESOURCERECURSIVEFLAG:
                        var     = Variables[varindex];
                        uintval = (uint)var.Data;
                        varindex++;

                        if (!stringResources.TryGetValue(uintval, out strval))
                        {
                            strval = String.Empty;
                        }

                        // remove the %r, insert the content (so we process it next)
                        fullString = fullString.Remove(index, 2);
                        fullString = fullString.Insert(index, strval);

                        // adjust stringliteral indices right to this index
                        for (int i = 0; i < q_indices.Count; i++)
                        {
                            if (q_indices[i] > index)
                            {
                                q_indices[i] = q_indices[i] + strval.Length - 2;
                            }
                        }
                        break;
#endif
                    default:
                        break;
                    }

                    // see if there is more inline vars to the right of current index
                    // this makes sure we don't yet process nested and already inserted %s
                    index = HasVariable(fullString, index);
                }

                // start from the beginning again, this will process nested %s
                index = HasVariable(fullString);
            }

            // Now finally add the %q stringliterals:
            // MUST iterate backwards (right to left in string)
            // so these inserts don't invalidate the other indices
            for (int i = q_indices.Count - 1; i >= 0; i--)
            {
                fullString = fullString.Insert(q_indices[i], q_strings[i]);
            }

            // extract and remove the inline styles (~B ...)
            Styles     = ChatStyle.GetStyles(fullString, chatMessageType);
            fullString = ChatStyle.RemoveInlineStyles(fullString);
        }
        /// <summary>
        /// Builds the 'FullString' property based on
        /// the available parameters in 'Variables',
        /// the root resource id and the user-language dependent strings.
        /// </summary>
        /// <param name="RaiseChangedEvent"></param>
        public void BuildString(bool RaiseChangedEvent = false)
        {
            int            index, varindex;
            int            position = 0;
            int            removed  = 0;
            InlineVariable var;
            string         strval;
            int            intval;
            uint           uintval;
            List <int>     q_indices = new List <int>();
            List <string>  q_strings = new List <string>();

            if (stringResources == null)
            {
                return;
            }

            // In this iteration we will use the parsed 'Variables' to actually build
            // the string in the user-lanuage, honoring the $ordering.

            // resolve root resource string in user-language
            if (!stringResources.TryGetValue(resourceID, out resourceName) || resourceName == null)
            {
                resourceName = String.Empty;
            }

            // will store fully constructed string
            fullString = String.Copy(resourceName);

            // specifies the index of next variable to use
            varindex = 0;

            // build string
            index = HasVariable(fullString);
            while (index > -1)
            {
                while (index > -1)
                {
                    // which type of inline var
                    switch (fullString[index + 1])
                    {
                    // %% in string is literal %, remove one.
                    case VARIABLEFLAG:
                        fullString = fullString.Remove(index, 1);
                        // adjust stringliteral indices right to this index
                        for (int i = 0; i < q_indices.Count; i++)
                        {
                            if (q_indices[i] > index)
                            {
                                q_indices[i] = q_indices[i] - 1;
                            }
                        }
                        break;

                    // %i or %d are 4 byte integers. Their value should be inserted as a string.
                    case INTEGERFLAG:
                    case INTEGERFLAG2:
#if !VANILLA
                        if (ExtractPosition(fullString, index + 2, out fullString, out position, out removed) &&
                            position >= 0)
                        {
                            var = Variables[position];
                        }
                        else
                        {
                            var = Variables[varindex];
                        }
#else
                        var = Variables[varindex];
#endif
                        intval = (int)var.Data;     // todo check type
                        varindex++;

                        string intstr = (position != -1) ? intval.ToString() : String.Empty;

                        // remove the %i, %d and insert the integer directly
                        fullString = fullString.Remove(index, 2);
                        fullString = fullString.Insert(index, intstr);

                        // adjust stringliteral indices right to this index
                        for (int i = 0; i < q_indices.Count; i++)
                        {
                            if (q_indices[i] > index)
                            {
                                q_indices[i] = q_indices[i] + intstr.Length - 2 - removed;
                            }
                        }
                        break;

                    // %q is a server-sent string which is directly attached to the message and not looked up from rsb
                    // if it contains any %vars itself, these MUST NOT be resolved further (won't be available in params)
                    case EMBEDDEDSTRINGLITERALFLAG:
#if !VANILLA
                        if (ExtractPosition(fullString, index + 2, out fullString, out position, out removed) &&
                            position >= 0)
                        {
                            var = Variables[position];
                        }
                        else
                        {
                            var = Variables[varindex];
                        }
#else
                        var = Variables[varindex];
#endif
                        strval = (position != -1) ? (string)var.Data : String.Empty;
                        varindex++;

                        // remove the %q, save string and position for insert later
                        fullString = fullString.Remove(index, 2);
                        q_strings.Add(strval);
                        q_indices.Add(index);

                        // adjust stringliteral indices right to this index
                        for (int i = 0; i < q_indices.Count; i++)
                        {
                            if (q_indices[i] > index)
                            {
                                q_indices[i] = q_indices[i] - 2 - removed;
                            }
                        }
                        break;

                    // %s is a server-sent string resource id. It must be resolved from .rsb
                    // If it contains any %vars itself, these sub-vars must be resolved AFTER any next-vars.
                    case STRINGRESOURCELITERALFLAG:
#if !VANILLA
                        // try to extract a $pos and possibly use it instead of the current index
                        if (ExtractPosition(fullString, index + 2, out fullString, out position, out removed) &&
                            position >= 0)
                        {
                            var = Variables[position];
                        }
                        else
                        {
                            var = Variables[varindex];
                        }
#else
                        var = Variables[varindex];
#endif
                        uintval = (uint)var.Data;
                        varindex++;

                        // use empty string for $0 or in case not found
                        if (position == -1 || !stringResources.TryGetValue(uintval, out strval) || strval == null)
                        {
                            strval = String.Empty;
                        }

                        // remove the %s, and insert the string,
                        // but skip its content in this inner while()
                        fullString = fullString.Remove(index, 2);
                        fullString = fullString.Insert(index, strval);

                        // adjust stringliteral indices right to this index
                        for (int i = 0; i < q_indices.Count; i++)
                        {
                            if (q_indices[i] > index)
                            {
                                q_indices[i] = q_indices[i] + strval.Length - 2 - removed;
                            }
                        }

                        // skip
                        index += strval.Length;
                        break;

#if !VANILLA
                    // %r is a server-sent string resource id. It must be resolved from .rsb
                    // If it contains any %vars itself, these sub-vars must be resolved BEFORE any next-vars.
                    case STRINGRESOURCERECURSIVEFLAG:

                        // try to extract a $pos and possibly use it instead of the current index
                        if (ExtractPosition(fullString, index + 2, out fullString, out position, out removed) &&
                            position >= 0)
                        {
                            var = Variables[position];
                        }
                        else
                        {
                            var = Variables[varindex];
                        }

                        uintval = (uint)var.Data;
                        varindex++;

                        // use empty string for $0 or in case not found
                        if (position == -1 || !stringResources.TryGetValue(uintval, out strval))
                        {
                            strval = String.Empty;
                        }

                        // remove the %r, insert the content (so we process it next)
                        fullString = fullString.Remove(index, 2);
                        fullString = fullString.Insert(index, strval);

                        // adjust stringliteral indices right to this index
                        for (int i = 0; i < q_indices.Count; i++)
                        {
                            if (q_indices[i] > index)
                            {
                                q_indices[i] = q_indices[i] + strval.Length - 2 - removed;
                            }
                        }
                        break;
#endif
                    default:
                        break;
                    }

                    // see if there is more inline vars to the right of current index
                    // this makes sure we don't yet process nested and already inserted %s
                    index = HasVariable(fullString, index);
                }

                // start from the beginning again, this will process nested %s
                index = HasVariable(fullString);
            }

            // Now finally add the %q stringliterals:
            // MUST iterate backwards (right to left in string)
            // so these inserts don't invalidate the other indices
            for (int i = q_indices.Count - 1; i >= 0; i--)
            {
                fullString = fullString.Insert(q_indices[i], q_strings[i]);
            }

            // extract and remove the inline styles (~B ...)
            Styles     = ChatStyle.GetStyles(fullString, chatMessageType);
            fullString = ChatStyle.RemoveInlineStyles(fullString);

            // possibly raise changed event
            if (RaiseChangedEvent)
            {
                RaisePropertyChanged(new PropertyChangedEventArgs(PROPNAME_RESOURCENAME));
                RaisePropertyChanged(new PropertyChangedEventArgs(PROPNAME_FULLSTRING));
            }
        }
Example #3
0
        public unsafe virtual void ReadFrom(ref byte *Buffer)
        {
            resourceID = *((uint *)Buffer);
            Buffer    += TypeSizes.INT;

            string resourceName;

            stringResources.TryGetValue(resourceID, out resourceName);
            this.resourceName = resourceName;

            // start filling up variables (example: %s) with values
            // their values are attached to the packet/buffer and make it a variable length
            // also there might be more than one iteration necessary as varibles may be nested into variable-strings
            fullString = String.Copy(resourceName);

            int index = HasVariable(fullString);

            while (index > -1)
            {
                // which type of inline var
                switch (fullString[index + 1])
                {
                case INTEGERFLAG:
                case INTEGERFLAG2:
                    InlineVariable var1 = new InlineVariable(InlineVariableType.Integer, ref Buffer);

                    Variables.Add(var1);
                    int j = (int)var1.Data;

                    // remove the %i and insert the integer
                    fullString = fullString.Remove(index, 2);
                    fullString = fullString.Insert(index, j.ToString());
                    break;

                case EMBEDDEDSTRINGFLAG:
                    InlineVariable var2 = new InlineVariable(InlineVariableType.String, ref Buffer);

                    Variables.Add(var2);
                    string s = (string)var2.Data;

                    // remove the %q and insert the string
                    fullString = fullString.Remove(index, 2);
                    fullString = fullString.Insert(index, s);
                    break;

                case STRINGRESOURCEFLAG:
                    InlineVariable var3 = new InlineVariable(InlineVariableType.Resource, ref Buffer);

                    Variables.Add(var3);
                    uint resourceid = (uint)var3.Data;

                    // try to get it from strings
                    string resourcestr;
                    stringResources.TryGetValue(resourceid, out resourcestr);

                    // still null? use dummy
                    if (resourcestr == null)
                    {
                        resourcestr = String.Empty;
                    }

                    // remove the %s and insert the resourcestr
                    fullString = fullString.Remove(index, 2);
                    fullString = fullString.Insert(index, resourcestr);
                    break;

                default:
                    break;
                }

                // check if there is more inline vars (may start loop again)
                index = HasVariable(fullString);
            }

            // extract and remove the inline styles (~B ...)
            Styles     = ChatStyle.GetStyles(fullString, chatMessageType);
            fullString = ChatStyle.RemoveInlineStyles(fullString);
        }