3 using System.Collections.Generic;
4 using System.Collections.Immutable;
6 using System.Text.RegularExpressions;
12 private static readonly Regex reFormattedMessage =
13 new Regex(
@"^(?<variable>[\[\].a-z0-9_]+?)=(?<formatter>[a-z0-9_]+?)\((?<value>.+?)\)",
14 RegexOptions.Compiled | RegexOptions.IgnoreCase);
16 private static readonly Regex reReplacedMessage =
new Regex(
@"^(?<variable>[\[\].a-z0-9_]+?)=(?<message>.*)$",
17 RegexOptions.Compiled | RegexOptions.IgnoreCase);
19 private static readonly ImmutableDictionary<Identifier, Func<string, string?>> messageFormatters =
20 new Dictionary<Identifier, Func<string, string?>>
23 "duration".ToIdentifier(),
24 secondsValue =>
double.TryParse(secondsValue, out var seconds)
25 ? $
"{TimeSpan.FromSeconds(seconds):g}"
28 }.ToImmutableDictionary();
30 private static readonly ImmutableHashSet<char> serverMessageCharacters =
31 new [] {
'~',
'[',
']',
'='}.ToImmutableHashSet();
33 private readonly
string serverMessage;
34 private readonly ImmutableArray<string> messageSplit;
38 serverMessage = serverMsg;
39 messageSplit = serverMessage.Split(
"/").ToImmutableArray();
42 private static bool IsServerMessageWithVariables(
string message) =>
43 serverMessageCharacters.All(message.Contains);
57 Dictionary<string, string> replacedMessages =
new Dictionary<string, string>();
58 bool translationsFound =
false;
60 string? TranslateMessage(
string input)
62 string? message = input;
63 if (message.EndsWith(
"~", StringComparison.Ordinal))
65 message = message.Substring(0, message.Length - 1);
68 if (!IsServerMessageWithVariables(message) && !message.Contains(
'='))
70 foreach (var replacedMessage
in replacedMessages)
72 message = message.Replace(replacedMessage.Key, replacedMessage.Value);
75 if (message.Contains(
" "))
80 var msg = TextManager.Get(message);
84 translationsFound =
true;
89 string? messageVariable =
null;
90 var matchFormatted = reFormattedMessage.Match(message);
91 if (matchFormatted.Success)
93 var formatter = matchFormatted.Groups[
"formatter"].ToString().ToIdentifier();
94 if (messageFormatters.TryGetValue(formatter, out var formatterFn))
96 var formattedValue = formatterFn(matchFormatted.Groups[
"value"].ToString());
97 if (formattedValue !=
null)
99 messageVariable = matchFormatted.Groups[
"variable"].ToString();
100 message = formattedValue;
105 if (messageVariable ==
null)
107 var matchReplaced = reReplacedMessage.Match(message);
108 if (matchReplaced.Success)
110 messageVariable = matchReplaced.Groups[
"variable"].ToString();
111 message = matchReplaced.Groups[
"message"].ToString();
115 foreach (var replacedMessage
in replacedMessages)
117 message = message.Replace(replacedMessage.Key, replacedMessage.Value);
120 string[] messageWithVariables = message.Split(
'~');
122 var msg = TextManager.Get(messageWithVariables[0]);
127 translationsFound =
true;
129 else if (messageVariable ==
null)
135 for (
int j = 1; j < messageWithVariables.Length; j++)
137 string[] variableAndValue = messageWithVariables[j].Split(
'=');
138 message = message.Replace(variableAndValue[0],
139 variableAndValue[1].
Length > 1 && variableAndValue[1][0] ==
'ยง'
140 ? TextManager.Get(variableAndValue[1].Substring(1)).Value
141 : variableAndValue[1]);
144 if (messageVariable !=
null)
146 replacedMessages[messageVariable] = message;
156 string translatedServerMessage =
"";
158 for (
int i = 0; i < messageSplit.Length; i++)
160 string? message = TranslateMessage(messageSplit[i]);
163 translatedServerMessage += message;
167 cachedValue = translationsFound ? translatedServerMessage : serverMessage;
170 catch (IndexOutOfRangeException exception)
172 string errorMsg = $
"Failed to translate server message \"{serverMessage}\".";
174 DebugConsole.ThrowError(errorMsg, exception);
176 GameAnalyticsManager.AddErrorEventOnce($
"TextManager.GetServerMessage:{serverMessage}",
177 GameAnalyticsManager.ErrorSeverity.Error, errorMsg);
override void RetrieveValue()
ServerMsgLString(string serverMsg)