public unsafe virtual void ReadFrom(ref byte* Buffer) { InlineVariable var; string strval; int intval; uint uintval; int index; List<Tuple<string, int>> stringliterals = new List<Tuple<string, int>>(); resourceID = *((uint*)Buffer); Buffer += TypeSizes.INT; // resolve root resource id if (!stringResources.TryGetValue(resourceID, out resourceName)) resourceName = String.Empty; // build string fullString = String.Copy(resourceName); index = HasVariable(fullString); 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 = new InlineVariable(InlineVariableType.Integer, ref Buffer); intval = (int)var.Data; Variables.Add(var); // remove the %i, %d and insert the integer directly fullString = fullString.Remove(index, 2); fullString = fullString.Insert(index, intval.ToString()); 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 = new InlineVariable(InlineVariableType.String, ref Buffer); strval = (string)var.Data; Variables.Add(var); // remove the %q, save string and position for insert later // this position won't invalidate, because the string grows to the right of this index only fullString = fullString.Remove(index, 2); stringliterals.Add(new Tuple<string, int>(strval, index)); break; // %s is a server-sent string resource id. It must be resolved from .rsb // if it contains any %vars itself, these MUST NOT be resolved further (won't be available in params) case STRINGRESOURCELITERALFLAG: var = new InlineVariable(InlineVariableType.Resource, ref Buffer); uintval = (uint)var.Data; Variables.Add(var); if (!stringResources.TryGetValue(uintval, out strval)) strval = String.Empty; // remove the %s, save string and position for insert later // this position won't invalidate, because the string grows to the right of this index only fullString = fullString.Remove(index, 2); stringliterals.Add(new Tuple<string, int>(strval, index)); break; #if !VANILLA // %r is a server-sent string resource id. It must be resolved from .rsb // if it contains any %vars itself, these MUST be resolved before any next var. case STRINGRESOURCERECURSIVEFLAG: var = new InlineVariable(InlineVariableType.Resource, ref Buffer); uintval = (uint)var.Data; Variables.Add(var); if (!stringResources.TryGetValue(uintval, out strval)) strval = String.Empty; // remove the %r, immediately insert the content (so we process it next) fullString = fullString.Remove(index, 2); fullString = fullString.Insert(index, strval); break; #endif default: break; } // check if there is more inline vars (may start loop again) index = HasVariable(fullString); } // Now finally add the %q and %s stringliterals: // MUST iterate backwards (right to left in string) // so these inserts don't invalidate the other indices for(int i = stringliterals.Count - 1; i >= 0; i--) fullString = fullString.Insert(stringliterals[i].Item2, stringliterals[i].Item1); // extract and remove the inline styles (~B ...) Styles = ChatStyle.GetStyles(fullString, chatMessageType); fullString = ChatStyle.RemoveInlineStyles(fullString); }
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); }
public unsafe virtual void ReadFrom(ref byte *Buffer) { InlineVariable var; string strval; string tempstr; int intval; uint uintval; int index; // read root resource ID resourceID = *((uint *)Buffer); Buffer += TypeSizes.INT; // This is the parser-iteration in which we go through the string-building process, // but only do enough of it to get the info we need to read parameters from buffer. // Parameters are ordered on the buffer like they appear in ENGLISH. // Todo: Change serverside to specify amount and type of parameters to be read. // get root resource-string in english if (!stringResources.TryGetValue(resourceID, out tempstr, LanguageCode.English)) { tempstr = String.Empty; } // string building process index = HasVariable(tempstr); while (index > -1) { while (index > -1) { // which type of inline var switch (tempstr[index + 1]) { // %% in string is literal %, remove one. case VARIABLEFLAG: tempstr = tempstr.Remove(index, 1); break; case INTEGERFLAG: case INTEGERFLAG2: var = new InlineVariable(InlineVariableType.Integer, ref Buffer); intval = (int)var.Data; Variables.Add(var); // remove the %i, %d, no handling pass 1 tempstr = tempstr.Remove(index, 2); break; case EMBEDDEDSTRINGLITERALFLAG: var = new InlineVariable(InlineVariableType.String, ref Buffer); strval = (string)var.Data; Variables.Add(var); // remove the %q, no handling in pass 1 tempstr = tempstr.Remove(index, 2); break; case STRINGRESOURCELITERALFLAG: var = new InlineVariable(InlineVariableType.Resource, ref Buffer); uintval = (uint)var.Data; Variables.Add(var); if (!stringResources.TryGetValue(uintval, out strval, LanguageCode.English)) { strval = String.Empty; } // remove the %s, and insert the string, // but skip its content in this inner while() tempstr = tempstr.Remove(index, 2); tempstr = tempstr.Insert(index, strval); // skip index += strval.Length; break; #if !VANILLA case STRINGRESOURCERECURSIVEFLAG: var = new InlineVariable(InlineVariableType.Resource, ref Buffer); uintval = (uint)var.Data; Variables.Add(var); if (!stringResources.TryGetValue(uintval, out strval, LanguageCode.English)) { strval = String.Empty; } // remove the %r, insert the content (so we process it next) tempstr = tempstr.Remove(index, 2); tempstr = tempstr.Insert(index, strval); 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(tempstr, index); } // start from the beginning again, this will process nested %s index = HasVariable(tempstr); } // now build the user-language based FullString using parameters BuildString(); }
public unsafe virtual void ReadFrom(ref byte* Buffer) { InlineVariable var; string strval; string tempstr; int intval; uint uintval; int index; // read root resource ID resourceID = *((uint*)Buffer); Buffer += TypeSizes.INT; // This is the parser-iteration in which we go through the string-building process, // but only do enough of it to get the info we need to read parameters from buffer. // Parameters are ordered on the buffer like they appear in ENGLISH. // Todo: Change serverside to specify amount and type of parameters to be read. // get root resource-string in english if (!stringResources.TryGetValue(resourceID, out tempstr, LanguageCode.English)) tempstr = String.Empty; // string building process index = HasVariable(tempstr); while (index > -1) { while (index > -1) { // which type of inline var switch (tempstr[index + 1]) { case INTEGERFLAG: case INTEGERFLAG2: var = new InlineVariable(InlineVariableType.Integer, ref Buffer); intval = (int)var.Data; Variables.Add(var); // remove the %i, %d, no handling pass 1 tempstr = tempstr.Remove(index, 2); break; case EMBEDDEDSTRINGLITERALFLAG: var = new InlineVariable(InlineVariableType.String, ref Buffer); strval = (string)var.Data; Variables.Add(var); // remove the %q, no handling in pass 1 tempstr = tempstr.Remove(index, 2); break; case STRINGRESOURCELITERALFLAG: var = new InlineVariable(InlineVariableType.Resource, ref Buffer); uintval = (uint)var.Data; Variables.Add(var); if (!stringResources.TryGetValue(uintval, out strval, LanguageCode.English)) strval = String.Empty; // remove the %s, and insert the string, // but skip its content in this inner while() tempstr = tempstr.Remove(index, 2); tempstr = tempstr.Insert(index, strval); // skip index += strval.Length; break; #if !VANILLA case STRINGRESOURCERECURSIVEFLAG: var = new InlineVariable(InlineVariableType.Resource, ref Buffer); uintval = (uint)var.Data; Variables.Add(var); if (!stringResources.TryGetValue(uintval, out strval, LanguageCode.English)) strval = String.Empty; // remove the %r, insert the content (so we process it next) tempstr = tempstr.Remove(index, 2); tempstr = tempstr.Insert(index, strval); 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(tempstr, index); } // start from the beginning again, this will process nested %s index = HasVariable(tempstr); } // now build the user-language based FullString using parameters BuildString(); }