com.xmobitea.changx.mini-localization 1.4.2 → 1.4.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -6,6 +6,8 @@
6
6
  using System.Linq;
7
7
  using System.Xml;
8
8
  using System.Collections.Generic;
9
+ using System.Text.RegularExpressions;
10
+ using System.Text;
9
11
 
10
12
  [CustomEditor(typeof(LocalizationManager))]
11
13
  public class LocalizationManagerEditor : Editor
@@ -199,11 +201,13 @@
199
201
  {
200
202
  var key = node.Attributes.GetNamedItem("name").Value;
201
203
 
202
- if (!keyNameLst.Contains(key))
204
+ var validKey = ToValidFieldName(key);
205
+
206
+ if (!keyNameLst.Contains(validKey))
203
207
  {
204
- keyNameLst.Add(key);
208
+ keyNameLst.Add(validKey);
205
209
 
206
- contentBuilder.AppendLine(" public const string " + key + " = " + "\"" + key + "\";");
210
+ contentBuilder.AppendLine(" public const string " + validKey + " = " + "\"" + key + "\";");
207
211
  }
208
212
  }
209
213
  }
@@ -212,5 +216,48 @@
212
216
  contentBuilder.AppendLine("}");
213
217
  MiniAutoGenerate.Editor.AutoGenerate.GenerateFile("LocalizationConstanceId.cs", contentBuilder, Application.dataPath + "/XmobiTea-constance/Scripts/");
214
218
  }
219
+
220
+ private static readonly HashSet<string> CSharpKeywords = new()
221
+ {
222
+ "class","struct","int","float","string","public","private","protected",
223
+ "internal","void","new","return","if","else","for","while","switch",
224
+ "case","default","break","continue","static","this","base","null",
225
+ "true","false","namespace","using"
226
+ };
227
+
228
+ private static string RemoveDiacritics(string text)
229
+ {
230
+ var normalized = text.Normalize(NormalizationForm.FormD);
231
+ var sb = new StringBuilder();
232
+
233
+ foreach (var c in normalized)
234
+ {
235
+ if (System.Globalization.CharUnicodeInfo.GetUnicodeCategory(c)
236
+ != System.Globalization.UnicodeCategory.NonSpacingMark)
237
+ {
238
+ sb.Append(c);
239
+ }
240
+ }
241
+
242
+ return sb.ToString().Normalize(NormalizationForm.FormC);
243
+ }
244
+
245
+ private static string ToValidFieldName(string input)
246
+ {
247
+ if (string.IsNullOrWhiteSpace(input))
248
+ return "_field";
249
+
250
+ input = RemoveDiacritics(input.Trim());
251
+
252
+ input = Regex.Replace(input, @"[^a-zA-Z0-9_]", "_");
253
+
254
+ if (char.IsDigit(input[0]))
255
+ input = "_" + input;
256
+
257
+ if (CSharpKeywords.Contains(input))
258
+ input = "_" + input;
259
+
260
+ return input;
261
+ }
215
262
  }
216
263
  }
@@ -3,6 +3,10 @@
3
3
  using System;
4
4
  using UnityEngine;
5
5
 
6
+ #if ADDRESSABLE
7
+ using UnityEngine.AddressableAssets;
8
+ #endif
9
+
6
10
  [Serializable]
7
11
  public class LocalizationLanguageItem
8
12
  {
@@ -18,16 +22,17 @@
18
22
  private TextAsset xml;
19
23
  public TextAsset XML { get { return xml; } set { xml = value; } }
20
24
 
21
- public string OnlineXmlStr
22
- {
23
- get => PlayerPrefs.GetString("LocalizationLanguageItem_OnlineXmlStr_" + systemLanguage);
24
- set => PlayerPrefs.SetString("LocalizationLanguageItem_OnlineXmlStr_" + systemLanguage, value);
25
- }
26
-
27
- public int VersionXml
28
- {
29
- get => PlayerPrefs.GetInt("LocalizationLanguageItem_VersionXml_" + systemLanguage);
30
- set => PlayerPrefs.SetInt("LocalizationLanguageItem_VersionXml_" + systemLanguage, value);
31
- }
25
+ #if ADDRESSABLE
26
+
27
+ [SerializeField]
28
+ private AssetReferenceT<TextAsset> xmlRef;
29
+ public AssetReferenceT<TextAsset> XMLRef { get { return xmlRef; } set { xmlRef = value; } }
30
+
31
+ #endif
32
+
33
+ [SerializeField]
34
+ private string onlineLocalizationUrl;
35
+ public string OnlineLocalizationUrl { get { return onlineLocalizationUrl; } set { onlineLocalizationUrl = value; } }
36
+
32
37
  }
33
38
  }
@@ -7,6 +7,7 @@
7
7
  using System.IO;
8
8
  using MiniSingleton;
9
9
  using Core;
10
+ using UnityEngine.Networking;
10
11
 
11
12
  public class LocalizationManager : Singleton<LocalizationManager>
12
13
  {
@@ -63,42 +64,22 @@
63
64
 
64
65
  var thisLanguage = Instance.localizationLanguageItemDic[systemLanguage];
65
66
 
66
- var textLocalizationDic = Instance.textLocalizationDic;
67
-
68
- {
69
- var xml = LocalizationManager.GetTextWithoutBOM(thisLanguage.XML);
70
-
71
- var xmlDoc = new XmlDocument();
72
-
73
- xmlDoc.LoadXml(xml);
74
-
75
- //var xml = thisLanguage.XML;
76
-
77
- var xSectionNode = xmlDoc.ChildNodes.Item(1);
78
-
79
- textLocalizationDic.Clear();
67
+ Instance.currentLanguage = thisLanguage;
80
68
 
81
- foreach (XmlNode sectionNode in xSectionNode)
82
- {
83
- foreach (XmlNode node in sectionNode)
84
- {
85
- var key = node.Attributes.GetNamedItem("name").Value;
86
- var text = node.InnerText.Replace("\\n", "\n").Replace("&lt;", "<").Replace("&gt;", ">").Replace("&#38;", "&").Replace("&#39;", "'").Replace("&#34;", "\"");
69
+ var textLocalizationDic = Instance.textLocalizationDic;
87
70
 
88
- if (Instance.textLocalizationDic.ContainsKey(key)) Debug.LogError("[Localization] " + key + " " + " duplicate");
89
- else Instance.textLocalizationDic[key] = text;
90
- }
91
- }
92
- }
71
+ textLocalizationDic.Clear();
93
72
 
94
73
  {
95
- var onlineXmlStr = thisLanguage.OnlineXmlStr;
96
-
97
- if (!string.IsNullOrEmpty(onlineXmlStr))
74
+ if (thisLanguage.XML != null)
98
75
  {
76
+ var xml = LocalizationManager.GetTextWithoutBOM(thisLanguage.XML);
77
+
99
78
  var xmlDoc = new XmlDocument();
100
79
 
101
- xmlDoc.LoadXml(onlineXmlStr);
80
+ xmlDoc.LoadXml(xml);
81
+
82
+ //var xml = thisLanguage.XML;
102
83
 
103
84
  var xSectionNode = xmlDoc.ChildNodes.Item(1);
104
85
 
@@ -109,78 +90,116 @@
109
90
  var key = node.Attributes.GetNamedItem("name").Value;
110
91
  var text = node.InnerText.Replace("\\n", "\n").Replace("&lt;", "<").Replace("&gt;", ">").Replace("&#38;", "&").Replace("&#39;", "'").Replace("&#34;", "\"");
111
92
 
112
- if (textLocalizationDic.ContainsKey(key))
113
- {
114
- Debug.LogError("[Localization] " + key + " " + " had replace by online xml");
115
- }
116
-
117
- textLocalizationDic[key] = text;
93
+ if (textLocalizationDic.ContainsKey(key)) Debug.LogError("[Localization] " + key + " " + " duplicate");
94
+ else textLocalizationDic[key] = text;
118
95
  }
119
96
  }
120
97
  }
121
- }
122
98
 
123
- Instance.currentLanguage = thisLanguage;
99
+ #if ADDRESSABLE
100
+ if (thisLanguage.XMLRef != null)
101
+ {
102
+ thisLanguage.XMLRef.LoadAssetAsync().Completed += (handle) =>
103
+ {
104
+ if (handle.Status == UnityEngine.ResourceManagement.AsyncOperations.AsyncOperationStatus.Succeeded)
105
+ {
106
+ Debug.Log("Load xml from addressable success");
124
107
 
125
- OnUpdateText?.Invoke();
108
+ if (Instance.currentLanguage == thisLanguage)
109
+ {
110
+ var xml = LocalizationManager.GetTextWithoutBOM(handle.Result);
126
111
 
127
- return true;
128
- }
112
+ var xmlDoc = new XmlDocument();
129
113
 
130
- public static bool OnLanguageXmlOnlineChange()
131
- {
132
- if (!IsExists)
133
- {
134
- Debug.LogError("[Localization] LocalizationManager instance is null!");
135
- return false;
136
- }
114
+ xmlDoc.LoadXml(xml);
137
115
 
138
- if (Instance.currentLanguage == null)
139
- {
140
- Debug.LogError("[Localization] LocalizationManager currentLanguage is null!");
141
- return false;
142
- }
116
+ var xSectionNode = xmlDoc.ChildNodes.Item(1);
143
117
 
144
- var systemLanguage = Instance.currentLanguage.SystemLanguage;
118
+ foreach (XmlNode sectionNode in xSectionNode)
119
+ {
120
+ foreach (XmlNode node in sectionNode)
121
+ {
122
+ var key = node.Attributes.GetNamedItem("name").Value;
123
+ var text = node.InnerText.Replace("\\n", "\n").Replace("&lt;", "<").Replace("&gt;", ">").Replace("&#38;", "&").Replace("&#39;", "'").Replace("&#34;", "\"");
145
124
 
146
- if (!Instance.localizationLanguageItemDic.ContainsKey(systemLanguage))
147
- {
148
- Debug.LogError("[Localization] " + systemLanguage + " does not esixts!");
149
- return false;
150
- }
125
+ if (textLocalizationDic.ContainsKey(key))
126
+ {
127
+ Debug.LogError("[Localization] " + key + " " + " had replace by addressable xml");
128
+ }
151
129
 
152
- var thisLanguage = Instance.localizationLanguageItemDic[systemLanguage];
130
+ textLocalizationDic[key] = text;
131
+ }
132
+ }
153
133
 
154
- var textLocalizationDic = Instance.textLocalizationDic;
134
+ OnUpdateText?.Invoke();
135
+ }
136
+ else
137
+ {
138
+ Debug.Log("Load xml from addressable success, but the current language does not match");
139
+ }
140
+ }
141
+ else
142
+ {
143
+ Debug.LogError("Failed to load xml from addressable");
144
+ }
145
+
146
+
147
+ };
148
+ }
149
+ #endif
150
+ }
155
151
 
156
152
  {
157
- var onlineXmlStr = thisLanguage.OnlineXmlStr;
153
+ var onlineLocalizationUrl = thisLanguage.OnlineLocalizationUrl;
158
154
 
159
- if (!string.IsNullOrEmpty(onlineXmlStr))
155
+ if (!string.IsNullOrEmpty(onlineLocalizationUrl))
160
156
  {
161
- var xmlDoc = new XmlDocument();
157
+ Instance.StartCoroutine(IELoadOnlineLocalization(onlineLocalizationUrl, (success, value) =>
158
+ {
159
+ if (success)
160
+ {
161
+ Debug.Log("Load xml from online url success");
162
162
 
163
- xmlDoc.LoadXml(onlineXmlStr);
163
+ if (Instance.currentLanguage == thisLanguage)
164
+ {
165
+ var xml = value;
164
166
 
165
- //var xml = thisLanguage.XML;
167
+ var xmlDoc = new XmlDocument();
166
168
 
167
- var xSectionNode = xmlDoc.ChildNodes.Item(1);
169
+ xmlDoc.LoadXml(xml);
168
170
 
169
- foreach (XmlNode sectionNode in xSectionNode)
170
- {
171
- foreach (XmlNode node in sectionNode)
172
- {
173
- var key = node.Attributes.GetNamedItem("name").Value;
174
- var text = node.InnerText.Replace("\\n", "\n").Replace("&lt;", "<").Replace("&gt;", ">").Replace("&#38;", "&").Replace("&#39;", "'").Replace("&#34;", "\"");
171
+ var xSectionNode = xmlDoc.ChildNodes.Item(1);
172
+
173
+ textLocalizationDic.Clear();
174
+
175
+ foreach (XmlNode sectionNode in xSectionNode)
176
+ {
177
+ foreach (XmlNode node in sectionNode)
178
+ {
179
+ var key = node.Attributes.GetNamedItem("name").Value;
180
+ var text = node.InnerText.Replace("\\n", "\n").Replace("&lt;", "<").Replace("&gt;", ">").Replace("&#38;", "&").Replace("&#39;", "'").Replace("&#34;", "\"");
181
+
182
+ if (textLocalizationDic.ContainsKey(key))
183
+ {
184
+ Debug.LogError("[Localization] " + key + " " + " had replace by online url");
185
+ }
175
186
 
176
- if (textLocalizationDic.ContainsKey(key))
187
+ textLocalizationDic[key] = text;
188
+ }
189
+ }
190
+
191
+ OnUpdateText?.Invoke();
192
+ }
193
+ else
177
194
  {
178
- Debug.LogError("[Localization] " + key + " " + " had replace by online xml");
195
+ Debug.Log("Load xml from online url success, but the current language does not match");
179
196
  }
180
-
181
- textLocalizationDic[key] = text;
182
197
  }
183
- }
198
+ else
199
+ {
200
+ Debug.LogError("Failed to load xml from online url");
201
+ }
202
+ }));
184
203
  }
185
204
  }
186
205
 
@@ -189,6 +208,17 @@
189
208
  return true;
190
209
  }
191
210
 
211
+ private static System.Collections.IEnumerator IELoadOnlineLocalization(string localizationUrl, Action<bool, string> onLoaded)
212
+ {
213
+ using var unityWebRequest = UnityWebRequest.Get(localizationUrl);
214
+ yield return unityWebRequest.SendWebRequest();
215
+
216
+ if (unityWebRequest.result == UnityWebRequest.Result.Success)
217
+ onLoaded?.Invoke(true, unityWebRequest.downloadHandler.text);
218
+ else
219
+ onLoaded?.Invoke(false, unityWebRequest.error);
220
+ }
221
+
192
222
  public static string GetTextWithoutBOM(TextAsset textAsset)
193
223
  {
194
224
  var memoryStream = new MemoryStream(textAsset.bytes);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "com.xmobitea.changx.mini-localization",
3
- "version": "1.4.2",
3
+ "version": "1.4.3",
4
4
  "displayName": "XmobiTea Localization",
5
5
  "description": "XmobiTea Unity package",
6
6
  "unity": "2020.3",