com.amanotes.gdk 0.2.68 → 0.2.70
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.
- package/CHANGELOG.md +39 -0
- package/Editor/AmaGDKEditor.cs +78 -23
- package/Editor/AmaGDKExtra.cs +14 -13
- package/Editor/Extra/GDKAutoUpdateAdapter.cs +14 -1
- package/Editor/Extra/GDKSymbolDefine.cs +372 -0
- package/Editor/{AmaGDKManager.cs.meta → Extra/GDKSymbolDefine.cs.meta} +1 -1
- package/Editor/Utils/AmaGDKEditor.ExtractVersion.cs +41 -3
- package/Extra/AmaGDKInstaller.unitypackage +0 -0
- package/Extra/CheckDiskSpace.unitypackage +0 -0
- package/Extra/Consent.unitypackage +0 -0
- package/Extra/{GoogleCMP.unitypackage.meta → Consent.unitypackage.meta} +1 -1
- package/Extra/ForceUpdate.unitypackage +0 -0
- package/Extra/LegacyGDKUpdateHelper.unitypackage +0 -0
- package/Extra/PostProcessor.unitypackage +0 -0
- package/Packages/AmaGDKConfig.unitypackage +0 -0
- package/Packages/AmaGDKExample.unitypackage +0 -0
- package/Packages/AmaGDKTest.unitypackage +0 -0
- package/Packages/AppsFlyerAdapter.PurchaseConnector.unitypackage +0 -0
- package/Packages/AppsFlyerAdapter.unitypackage +0 -0
- package/Packages/FirebaseAnalyticsAdapter.unitypackage +0 -0
- package/Packages/FirebaseRemoteConfigAdapter.unitypackage +0 -0
- package/Packages/IronSourceAdapter.unitypackage +0 -0
- package/Packages/MaxAdNetworkAdapter.unitypackage +0 -0
- package/{Editor/Resources.meta → Packages/MaxAdNetworkAdapter.unitypackage.meta} +1 -2
- package/Packages/RevenueCatAdapter.unitypackage +0 -0
- package/Packages/SqliteAnalyticsAdapter.unitypackage +0 -0
- package/Runtime/Ad/AdExtension.cs +2 -0
- package/Runtime/Ad/AdLogic.cs +83 -70
- package/Runtime/Ad/AdShowContext.cs +1 -0
- package/Runtime/Ad/AmaGDK.Ads.cs +17 -3
- package/Runtime/AmaGDK.Adapters.cs +12 -5
- package/Runtime/AmaGDK.Analytics.cs +45 -38
- package/Runtime/AmaGDK.Consent.cs +259 -0
- package/Runtime/AmaGDK.Consent.cs.meta +11 -0
- package/Runtime/AmaGDK.Device.cs +4 -4
- package/Runtime/AmaGDK.RemoteConfig.cs +3 -1
- package/Runtime/AmaGDK.cs +28 -19
- package/Runtime/AnalyticQualityAsset.cs +16 -9
- package/Runtime/AudioToolkit/AmaGDK.Audio.Latency.cs +1 -3
- package/Runtime/AudioToolkit/AmaGDK.Audio.cs +41 -25
- package/Runtime/AudioToolkit/Plugins/AudioDeviceDetector.cs +13 -12
- package/Runtime/Core/GDKPool.cs +83 -17
- package/Runtime/Fps/AmaFPS.cs +0 -1
- package/Runtime/Fps/AmaFPSVisualizer.cs +7 -7
- package/Runtime/Internal/AmaGDK.Internal.AmaGUI.cs +1 -1
- package/Runtime/Internal/AmaGDK.Internal.cs +2 -5
- package/Runtime/Internal/AmaGDK.Utils.cs +32 -81
- package/Runtime/Internal/GDKGeoLocationcs.cs +3 -1
- package/Runtime/Internal/GDKServerTime.cs +13 -10
- package/package.json +1 -1
- package/Editor/AmaGDKManager.cs +0 -235
- package/Editor/Resources/amasdk-modules.json +0 -31
- package/Editor/Resources/amasdk-modules.json.meta +0 -7
- package/Extra/GoogleCMP.unitypackage +0 -0
|
@@ -1,6 +1,4 @@
|
|
|
1
1
|
using System;
|
|
2
|
-
using System.Collections;
|
|
3
|
-
using Amanotes.Core.Internal;
|
|
4
2
|
using UnityEngine;
|
|
5
3
|
|
|
6
4
|
namespace Amanotes.Core
|
|
@@ -75,7 +73,7 @@ namespace Amanotes.Core
|
|
|
75
73
|
return DEFAULT_FOR_SPEAKER;
|
|
76
74
|
}
|
|
77
75
|
|
|
78
|
-
string deviceName =
|
|
76
|
+
string deviceName = currentDevice.name;
|
|
79
77
|
int savedLatency = PlayerPrefs.GetInt(PREF_AUDIO_LATENCY + deviceName, -1);
|
|
80
78
|
|
|
81
79
|
if (savedLatency >= 0)
|
|
@@ -1,7 +1,5 @@
|
|
|
1
1
|
using UnityEngine;
|
|
2
2
|
using System;
|
|
3
|
-
using System.Collections;
|
|
4
|
-
using System.Text;
|
|
5
3
|
using Amanotes.Core.Internal;
|
|
6
4
|
|
|
7
5
|
namespace Amanotes.Core.Internal
|
|
@@ -9,7 +7,8 @@ namespace Amanotes.Core.Internal
|
|
|
9
7
|
public partial class ConfigAsset
|
|
10
8
|
{
|
|
11
9
|
[SerializeField]
|
|
12
|
-
|
|
10
|
+
[Tooltip("Enable to get accurate audio latency & be informed when audio device changed\n\nApi: AmaGDK.Audio.DeviceInfo")]
|
|
11
|
+
public bool enableAudioModule = true;
|
|
13
12
|
}
|
|
14
13
|
}
|
|
15
14
|
|
|
@@ -23,21 +22,38 @@ namespace Amanotes.Core
|
|
|
23
22
|
public const string GDK_AUDIO_INTERRUPT_BEGIN = nameof(GDK_AUDIO_INTERRUPT_BEGIN);
|
|
24
23
|
public const string GDK_AUDIO_INTERRUPT_END = nameof(GDK_AUDIO_INTERRUPT_END);
|
|
25
24
|
}
|
|
26
|
-
|
|
27
|
-
{
|
|
28
|
-
internal AudioDeviceType Type;
|
|
29
|
-
internal string RawType;
|
|
30
|
-
public string Name;
|
|
31
|
-
public int LatencyMs;
|
|
32
|
-
}
|
|
25
|
+
|
|
33
26
|
// Public Usage
|
|
34
|
-
public partial class Audio
|
|
27
|
+
public static partial class Audio
|
|
35
28
|
{
|
|
36
|
-
public
|
|
29
|
+
public class AudioDeviceInfo
|
|
30
|
+
{
|
|
31
|
+
internal AudioDeviceType type;
|
|
32
|
+
internal string rawType;
|
|
33
|
+
public string name;
|
|
34
|
+
public int latencyMs;
|
|
35
|
+
|
|
36
|
+
public override string ToString()
|
|
37
|
+
{
|
|
38
|
+
if (string.IsNullOrEmpty(rawType) || string.IsNullOrEmpty(name)) return base.ToString();
|
|
39
|
+
return $"type: {type.ToString().ToLower()} rawType:{rawType} name:{name}";
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
private static AudioDeviceInfo _currentDevice;
|
|
44
|
+
|
|
45
|
+
public static AudioDeviceInfo currentDevice
|
|
46
|
+
{
|
|
47
|
+
get => _currentDevice ?? NO_DEVICE;
|
|
48
|
+
private set => _currentDevice = value;
|
|
49
|
+
}
|
|
37
50
|
|
|
38
51
|
private static readonly AudioDeviceInfo NO_DEVICE = new AudioDeviceInfo()
|
|
39
52
|
{
|
|
40
|
-
|
|
53
|
+
type = AudioDeviceType.Unknown,
|
|
54
|
+
rawType = string.Empty,
|
|
55
|
+
name = "NO_DEVICE",
|
|
56
|
+
latencyMs = DEFAULT_FOR_SPEAKER
|
|
41
57
|
};
|
|
42
58
|
|
|
43
59
|
/// <remarks>
|
|
@@ -87,8 +103,8 @@ namespace Amanotes.Core
|
|
|
87
103
|
_audioDeviceDetector.RegisterEvents();
|
|
88
104
|
RegisterCallbacks();
|
|
89
105
|
|
|
90
|
-
|
|
91
|
-
|
|
106
|
+
currentDevice = DetectAudioInfo();
|
|
107
|
+
currentDevice.latencyMs = GetAudioDeviceLatency();
|
|
92
108
|
}
|
|
93
109
|
|
|
94
110
|
private static AudioDeviceInfo DetectAudioInfo()
|
|
@@ -102,9 +118,9 @@ namespace Amanotes.Core
|
|
|
102
118
|
var info = _audioDeviceDetector.GetInfo();
|
|
103
119
|
return new AudioDeviceInfo
|
|
104
120
|
{
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
121
|
+
type = info.AudioDeviceType,
|
|
122
|
+
rawType = info.RawType,
|
|
123
|
+
name = info.Name
|
|
108
124
|
};
|
|
109
125
|
}
|
|
110
126
|
}
|
|
@@ -125,9 +141,9 @@ namespace Amanotes.Core
|
|
|
125
141
|
{
|
|
126
142
|
GDKUtils.DelayCall(1f, () =>
|
|
127
143
|
{
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
dispatcher.Dispatch(Event.GDK_AUDIO_INFO_CHANGE,
|
|
144
|
+
currentDevice = DetectAudioInfo();
|
|
145
|
+
currentDevice.latencyMs = GetAudioDeviceLatency();
|
|
146
|
+
dispatcher.Dispatch(Event.GDK_AUDIO_INFO_CHANGE, currentDevice);
|
|
131
147
|
});
|
|
132
148
|
}
|
|
133
149
|
|
|
@@ -144,10 +160,10 @@ namespace Amanotes.Core
|
|
|
144
160
|
{
|
|
145
161
|
GDKUtils.ThrowIf(!Config.enableAudioModule, "Audio Module is disabled, Please enable it in the AmaGDKConfig");
|
|
146
162
|
|
|
147
|
-
return
|
|
148
|
-
&& (
|
|
149
|
-
||
|
|
150
|
-
||
|
|
163
|
+
return currentDevice != null
|
|
164
|
+
&& (currentDevice.rawType == "AVAudioSessionPortBluetoothA2DP"
|
|
165
|
+
|| currentDevice.rawType == "TYPE_BLUETOOTH_A2DP"
|
|
166
|
+
|| currentDevice.rawType == "AVAudioSessionPortBluetoothHFP");
|
|
151
167
|
}
|
|
152
168
|
|
|
153
169
|
private static string GetCurrentRouteInputs()
|
|
@@ -86,15 +86,13 @@ namespace Amanotes.Core
|
|
|
86
86
|
|
|
87
87
|
private void OnAudioDeviceAdded(string param)
|
|
88
88
|
{
|
|
89
|
-
if (string.IsNullOrEmpty(param))
|
|
90
|
-
return;
|
|
89
|
+
if (string.IsNullOrEmpty(param)) return;
|
|
91
90
|
onChanged?.Invoke(param);
|
|
92
91
|
}
|
|
93
92
|
|
|
94
93
|
private void OnAudioDeviceRemoved(string param)
|
|
95
94
|
{
|
|
96
|
-
if (string.IsNullOrEmpty(param))
|
|
97
|
-
return;
|
|
95
|
+
if (string.IsNullOrEmpty(param)) return;
|
|
98
96
|
onChanged?.Invoke(param);
|
|
99
97
|
}
|
|
100
98
|
|
|
@@ -170,15 +168,18 @@ namespace Amanotes.Core
|
|
|
170
168
|
}
|
|
171
169
|
|
|
172
170
|
StringBuilder sb = null;
|
|
173
|
-
|
|
174
|
-
for (int i = 0; i < str.Length; i++)
|
|
171
|
+
for (var i = 0; i < str.Length; i++)
|
|
175
172
|
{
|
|
176
173
|
char ch = str[i];
|
|
177
174
|
|
|
178
175
|
if (char.IsSurrogate(ch))
|
|
179
176
|
{
|
|
180
|
-
|
|
181
|
-
|
|
177
|
+
if (sb == null)
|
|
178
|
+
{
|
|
179
|
+
sb = GDKPool.GetStringBuilder();
|
|
180
|
+
sb.Append(str, 0, i);
|
|
181
|
+
}
|
|
182
|
+
|
|
182
183
|
sb.Append(replacementCharacter);
|
|
183
184
|
|
|
184
185
|
// If there is a high+low surrogate, skip the low surrogate
|
|
@@ -187,13 +188,13 @@ namespace Amanotes.Core
|
|
|
187
188
|
i++;
|
|
188
189
|
}
|
|
189
190
|
}
|
|
190
|
-
else
|
|
191
|
+
else
|
|
191
192
|
{
|
|
192
|
-
sb
|
|
193
|
+
sb?.Append(ch);
|
|
193
194
|
}
|
|
194
195
|
}
|
|
195
|
-
|
|
196
|
-
return sb == null ? str :
|
|
196
|
+
|
|
197
|
+
return sb == null ? str : GDKPool.ReturnString(sb);
|
|
197
198
|
}
|
|
198
199
|
}
|
|
199
200
|
|
package/Runtime/Core/GDKPool.cs
CHANGED
|
@@ -1,4 +1,7 @@
|
|
|
1
|
+
using System;
|
|
1
2
|
using System.Collections.Concurrent;
|
|
3
|
+
using System.Collections.Generic;
|
|
4
|
+
using System.Text;
|
|
2
5
|
|
|
3
6
|
namespace Amanotes.Core.Internal
|
|
4
7
|
{
|
|
@@ -6,32 +9,95 @@ namespace Amanotes.Core.Internal
|
|
|
6
9
|
{
|
|
7
10
|
void Reset();
|
|
8
11
|
}
|
|
9
|
-
|
|
10
|
-
public class GDKPool
|
|
12
|
+
|
|
13
|
+
public static class GDKPool
|
|
11
14
|
{
|
|
12
|
-
|
|
15
|
+
internal class Pool<T> where T : new()
|
|
16
|
+
{
|
|
17
|
+
private readonly ConcurrentQueue<T> _pool;
|
|
18
|
+
public Pool(int initialCapacity = 4)
|
|
19
|
+
{
|
|
20
|
+
_pool = new ConcurrentQueue<T>();
|
|
21
|
+
for (var i = 0; i < initialCapacity; i++)
|
|
22
|
+
{
|
|
23
|
+
_pool.Enqueue(new T());
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
public Pool(int initialCapacity, Func<T> newT)
|
|
28
|
+
{
|
|
29
|
+
_pool = new ConcurrentQueue<T>();
|
|
30
|
+
for (var i = 0; i < initialCapacity; i++)
|
|
31
|
+
{
|
|
32
|
+
_pool.Enqueue(newT());
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
public T Get()
|
|
37
|
+
{
|
|
38
|
+
if (!_pool.TryDequeue(out var obj)) return new T();
|
|
39
|
+
if (obj is IPoolItem poolItem) poolItem.Reset();
|
|
40
|
+
return obj;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
public void Return(T obj)
|
|
44
|
+
{
|
|
45
|
+
_pool.Enqueue(obj);
|
|
46
|
+
}
|
|
13
47
|
|
|
14
|
-
|
|
48
|
+
public int Count => _pool.Count;
|
|
49
|
+
}
|
|
50
|
+
private static readonly Pool<StringBuilder> sbPool1KB = new Pool<StringBuilder>(8, () => new StringBuilder(1024));
|
|
51
|
+
private static readonly Pool<StringBuilder> sbPool8KB = new Pool<StringBuilder>(8, () => new StringBuilder(8*1024));
|
|
52
|
+
private static readonly Pool<HashSet<string>> hashsetPool = new Pool<HashSet<string>>(4);
|
|
53
|
+
|
|
54
|
+
public static StringBuilder GetStringBuilder(int capacityInKb = 1)
|
|
55
|
+
{
|
|
56
|
+
StringBuilder result = capacityInKb <= 1 ? sbPool1KB.Get() : sbPool8KB.Get();
|
|
57
|
+
result.Clear();
|
|
58
|
+
return result;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
public static HashSet<string> GetHashSet()
|
|
62
|
+
{
|
|
63
|
+
HashSet<string> result = hashsetPool.Get();
|
|
64
|
+
result.Clear();
|
|
65
|
+
return result;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
public static string ReturnString(StringBuilder sb)
|
|
15
69
|
{
|
|
16
|
-
|
|
17
|
-
|
|
70
|
+
if (sb == null) return null;
|
|
71
|
+
var result = sb.ToString();
|
|
72
|
+
Return(sb);
|
|
73
|
+
return result;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
public static void Return(StringBuilder sb)
|
|
77
|
+
{
|
|
78
|
+
if (sb == null) return;
|
|
79
|
+
int capacity = sb.Capacity;
|
|
80
|
+
|
|
81
|
+
if (capacity == 1024)
|
|
18
82
|
{
|
|
19
|
-
|
|
83
|
+
sbPool1KB.Return(sb);
|
|
84
|
+
return;
|
|
20
85
|
}
|
|
86
|
+
|
|
87
|
+
sbPool8KB.Return(sb);
|
|
21
88
|
}
|
|
22
|
-
|
|
23
|
-
public
|
|
89
|
+
|
|
90
|
+
public static void Return(HashSet<string> hashset)
|
|
24
91
|
{
|
|
25
|
-
if (
|
|
26
|
-
|
|
27
|
-
return obj;
|
|
92
|
+
if (hashset == null) return;
|
|
93
|
+
hashsetPool.Return(hashset);
|
|
28
94
|
}
|
|
29
|
-
|
|
30
|
-
public void
|
|
95
|
+
|
|
96
|
+
public static void ReturnAndNullize(ref HashSet<string> hashset)
|
|
31
97
|
{
|
|
32
|
-
|
|
98
|
+
if (hashset == null) return;
|
|
99
|
+
hashsetPool.Return(hashset);
|
|
100
|
+
hashset = null;
|
|
33
101
|
}
|
|
34
|
-
|
|
35
|
-
public int Count => _pool.Count;
|
|
36
102
|
}
|
|
37
103
|
}
|
package/Runtime/Fps/AmaFPS.cs
CHANGED
|
@@ -87,8 +87,8 @@ namespace Amanotes.Core
|
|
|
87
87
|
public bool enabled = true;
|
|
88
88
|
public Graphic graphic = null;
|
|
89
89
|
|
|
90
|
-
public int
|
|
91
|
-
public int
|
|
90
|
+
public int lowerFPSBoundary = 15;
|
|
91
|
+
public int upperFPSBoundary = 60;
|
|
92
92
|
public int goodFPS = 55;
|
|
93
93
|
public int acceptableFPS = 45;
|
|
94
94
|
public int badFPS = 30;
|
|
@@ -128,8 +128,8 @@ namespace Amanotes.Core
|
|
|
128
128
|
{
|
|
129
129
|
var idx = (i + stIndex) % RESOLUTION;
|
|
130
130
|
var fps = fpsHistory[idx];
|
|
131
|
-
var h = fps <=
|
|
132
|
-
fps >=
|
|
131
|
+
var h = fps <= lowerFPSBoundary ? 0 :
|
|
132
|
+
fps >= upperFPSBoundary ? 1 : (fps - lowerFPSBoundary) / (upperFPSBoundary - lowerFPSBoundary);
|
|
133
133
|
|
|
134
134
|
var v0 = new Vector3(barX, 0, 0);
|
|
135
135
|
var v1 = new Vector3(barX, h * barH, 0);
|
|
@@ -155,9 +155,9 @@ namespace Amanotes.Core
|
|
|
155
155
|
barX += barW;
|
|
156
156
|
}
|
|
157
157
|
|
|
158
|
-
AddHorzLine(vh, rect.width, barH * ((goodFPS-
|
|
159
|
-
AddHorzLine(vh, rect.width, barH * ((acceptableFPS-
|
|
160
|
-
AddHorzLine(vh, rect.width, barH * ((badFPS-
|
|
158
|
+
AddHorzLine(vh, rect.width, barH * ((goodFPS-lowerFPSBoundary) / (float)(upperFPSBoundary-lowerFPSBoundary)), colors[2], 2f);
|
|
159
|
+
AddHorzLine(vh, rect.width, barH * ((acceptableFPS-lowerFPSBoundary) / (float)(upperFPSBoundary-lowerFPSBoundary)), colors[1], 2f);
|
|
160
|
+
AddHorzLine(vh, rect.width, barH * ((badFPS-lowerFPSBoundary) / (float)(upperFPSBoundary-lowerFPSBoundary)), colors[0], 2f);
|
|
161
161
|
}
|
|
162
162
|
|
|
163
163
|
void AddHorzLine(VertexHelper vh, float w, float h, Color color, float thickness = 1f)
|
|
@@ -100,7 +100,7 @@ namespace Amanotes.Core.Internal
|
|
|
100
100
|
GUI.DrawTextureWithTexCoords(new Rect(x + l, y + t, centerX, centerY), texture, new Rect(lu, bv, ru - lu, tv - bv));
|
|
101
101
|
}
|
|
102
102
|
|
|
103
|
-
public static void SectionLabel(
|
|
103
|
+
public static void SectionLabel(GUIContent text)
|
|
104
104
|
{
|
|
105
105
|
if (BIG_LABEL == null)
|
|
106
106
|
{
|
|
@@ -68,16 +68,13 @@ namespace Amanotes.Core.Internal
|
|
|
68
68
|
{
|
|
69
69
|
public static Action<string> logNonfatalErrorHook = null;
|
|
70
70
|
private static readonly HashSet<string> nonFatalDict = new HashSet<string>();
|
|
71
|
-
|
|
72
|
-
public static readonly StringBuilder tmpWarningSB = new StringBuilder();
|
|
73
71
|
public static readonly HashSet<string> logWarningDict = new HashSet<string>();
|
|
74
72
|
|
|
75
73
|
public static void LogWarningOnce(string message, string key = null)
|
|
76
74
|
{
|
|
77
75
|
if (Config.common.logLevel < LogLevel.Warning) return;
|
|
78
76
|
if (string.IsNullOrEmpty(key)) key = message;
|
|
79
|
-
if (logWarningDict.
|
|
80
|
-
logWarningDict.Add(key);
|
|
77
|
+
if (!logWarningDict.Add(key)) return;
|
|
81
78
|
Debug.LogWarning($"AmaGDK {message}");
|
|
82
79
|
}
|
|
83
80
|
public static void LogWarning(string message)
|
|
@@ -133,7 +130,7 @@ namespace Amanotes.Core.Internal
|
|
|
133
130
|
}
|
|
134
131
|
|
|
135
132
|
AmaGDK[] result = Resources.FindObjectsOfTypeAll<AmaGDK>();
|
|
136
|
-
for (
|
|
133
|
+
for (var i = 0; i < result.Length; i++)
|
|
137
134
|
{
|
|
138
135
|
if (result[i] == null) continue;
|
|
139
136
|
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
using System;
|
|
2
2
|
using System.Collections;
|
|
3
|
-
using System.Collections.Concurrent;
|
|
4
3
|
using System.Collections.Generic;
|
|
5
4
|
using System.IO;
|
|
6
5
|
using System.Linq;
|
|
@@ -15,8 +14,6 @@ namespace Amanotes.Core.Internal
|
|
|
15
14
|
{
|
|
16
15
|
public static partial class GDKUtils
|
|
17
16
|
{
|
|
18
|
-
|
|
19
|
-
|
|
20
17
|
public static bool IsFromTemplate(string formattedString, string template)
|
|
21
18
|
{
|
|
22
19
|
// Split the original template into segments based on the positions of placeholders
|
|
@@ -271,7 +268,7 @@ namespace Amanotes.Core.Internal
|
|
|
271
268
|
|
|
272
269
|
public static void ClearCacheData()
|
|
273
270
|
{
|
|
274
|
-
var sb =
|
|
271
|
+
var sb = GDKPool.GetStringBuilder();
|
|
275
272
|
sb.AppendLine("[AmaGDK] All cached data & stats cleared");
|
|
276
273
|
|
|
277
274
|
if (!Directory.Exists(basePath))
|
|
@@ -408,16 +405,16 @@ namespace Amanotes.Core.Internal
|
|
|
408
405
|
return DictionaryToJson(new Dictionary<string, object>
|
|
409
406
|
{ { key, value } });
|
|
410
407
|
}
|
|
411
|
-
|
|
408
|
+
|
|
412
409
|
public static string DictionaryToJson(IDictionary inputDict, bool format = false, bool checkJsonInString = true)
|
|
413
410
|
{
|
|
414
411
|
if (inputDict == null) return "{}";
|
|
415
412
|
|
|
416
413
|
Profiler.BeginSample("AmaGDK.JsonUtils.DictionaryToJson()");
|
|
417
|
-
var jsonSb =
|
|
414
|
+
var jsonSb = GDKPool.GetStringBuilder(8);
|
|
418
415
|
jsonSb.Append("{");
|
|
419
416
|
bool isFirstElement = true;
|
|
420
|
-
|
|
417
|
+
|
|
421
418
|
foreach (DictionaryEntry entry in inputDict)
|
|
422
419
|
{
|
|
423
420
|
if (entry.Key == null || string.IsNullOrEmpty(entry.Key.ToString())) continue;
|
|
@@ -432,9 +429,9 @@ namespace Amanotes.Core.Internal
|
|
|
432
429
|
jsonSb.AppendFormat("{0}\"{1}\":", format ? "\n" : "", key);
|
|
433
430
|
AppendJsonValue(ref jsonSb, key, value, format, checkJsonInString);
|
|
434
431
|
}
|
|
435
|
-
|
|
432
|
+
|
|
436
433
|
jsonSb.AppendFormat("{0}{1}", format ? "\n" : "", "}");
|
|
437
|
-
|
|
434
|
+
var result = GDKPool.ReturnString(jsonSb);
|
|
438
435
|
Profiler.EndSample();
|
|
439
436
|
|
|
440
437
|
return result;
|
|
@@ -470,7 +467,7 @@ namespace Amanotes.Core.Internal
|
|
|
470
467
|
|
|
471
468
|
if (value is string)
|
|
472
469
|
{
|
|
473
|
-
|
|
470
|
+
var s = value.ToString();
|
|
474
471
|
if (checkJsonInString)
|
|
475
472
|
{
|
|
476
473
|
if (s.StartsWith("{") && s.EndsWith("}"))
|
|
@@ -484,7 +481,9 @@ namespace Amanotes.Core.Internal
|
|
|
484
481
|
return;
|
|
485
482
|
}
|
|
486
483
|
}
|
|
487
|
-
jsonSb.Append($"\"
|
|
484
|
+
jsonSb.Append($"\"");
|
|
485
|
+
AppendEscapeJsonString(jsonSb, s);
|
|
486
|
+
jsonSb.Append($"\"");
|
|
488
487
|
return;
|
|
489
488
|
}
|
|
490
489
|
|
|
@@ -521,81 +520,33 @@ namespace Amanotes.Core.Internal
|
|
|
521
520
|
/// </summary>
|
|
522
521
|
/// <param name="input">The input string to be escaped.</param>
|
|
523
522
|
/// <returns>The escaped string.</returns>
|
|
524
|
-
|
|
523
|
+
private static readonly Dictionary<char, string> escapeSequences = new Dictionary<char, string>
|
|
524
|
+
{
|
|
525
|
+
{ '\"', "\\\"" },
|
|
526
|
+
{ '\\', @"\\" },
|
|
527
|
+
{ '\b', "\\b" },
|
|
528
|
+
{ '\f', "\\f" },
|
|
529
|
+
{ '\n', "\\n" },
|
|
530
|
+
{ '\r', "\\r" },
|
|
531
|
+
{ '\t', "\\t" }
|
|
532
|
+
};
|
|
533
|
+
public static void AppendEscapeJsonString(StringBuilder sb, string input)
|
|
525
534
|
{
|
|
526
|
-
var sb = new StringBuilder();
|
|
527
535
|
foreach (char c in input)
|
|
528
536
|
{
|
|
529
|
-
|
|
537
|
+
if (escapeSequences.TryGetValue(c, out var escapedValue))
|
|
538
|
+
{
|
|
539
|
+
sb.Append(escapedValue);
|
|
540
|
+
}
|
|
541
|
+
else if (c < 0x20 || char.IsSurrogate(c))
|
|
530
542
|
{
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
case '\r': sb.Append("\\r"); break;
|
|
537
|
-
case '\t': sb.Append("\\t"); break;
|
|
538
|
-
default:
|
|
539
|
-
if (c < 0x20)
|
|
540
|
-
{
|
|
541
|
-
// Encode as \uXXXX for control characters
|
|
542
|
-
sb.Append("\\u" + ((int)c).ToString("X4"));
|
|
543
|
-
}
|
|
544
|
-
else if (char.IsSurrogate(c))
|
|
545
|
-
{
|
|
546
|
-
// Handle surrogate pairs
|
|
547
|
-
if (char.IsHighSurrogate(c))
|
|
548
|
-
{
|
|
549
|
-
sb.Append("\\u" + ((int)c).ToString("X4"));
|
|
550
|
-
}
|
|
551
|
-
else if (char.IsLowSurrogate(c))
|
|
552
|
-
{
|
|
553
|
-
sb.Append("\\u" + ((int)c).ToString("X4"));
|
|
554
|
-
}
|
|
555
|
-
}
|
|
556
|
-
else
|
|
557
|
-
{
|
|
558
|
-
// Keep characters as is if they are in the UTF-8 range
|
|
559
|
-
sb.Append(c);
|
|
560
|
-
}
|
|
561
|
-
break;
|
|
543
|
+
sb.AppendFormat("\\u{0:X4}", (int)c);
|
|
544
|
+
}
|
|
545
|
+
else
|
|
546
|
+
{
|
|
547
|
+
sb.Append(c);
|
|
562
548
|
}
|
|
563
549
|
}
|
|
564
|
-
|
|
565
|
-
}
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
//public static T[] FromJsonToArray<T>(string json)
|
|
569
|
-
//{
|
|
570
|
-
// if (!json.StartsWith("{\"items\":"))
|
|
571
|
-
// {
|
|
572
|
-
// json = $"{{\"items\":{json}}}";
|
|
573
|
-
// }
|
|
574
|
-
// Wrapper<T> wrapper = JsonUtility.FromJson<Wrapper<T>>(json);
|
|
575
|
-
// return wrapper.items;
|
|
576
|
-
//}
|
|
577
|
-
|
|
578
|
-
//public static T FromJsonToObject<T>(string json)
|
|
579
|
-
//{
|
|
580
|
-
// return JsonUtility.FromJson<T>(json);
|
|
581
|
-
//}
|
|
582
|
-
|
|
583
|
-
//public static string ToJson<T>(T[] array)
|
|
584
|
-
//{
|
|
585
|
-
// Wrapper<T> wrapper = new Wrapper<T>();
|
|
586
|
-
// wrapper.items = array;
|
|
587
|
-
// return JsonUtility.ToJson(wrapper);
|
|
588
|
-
//}
|
|
589
|
-
|
|
590
|
-
//public static string ToJson<T>(T obj)
|
|
591
|
-
//{
|
|
592
|
-
// return JsonUtility.ToJson(obj);
|
|
593
|
-
//}
|
|
594
|
-
|
|
595
|
-
//[Serializable]
|
|
596
|
-
//private class Wrapper<T>
|
|
597
|
-
//{
|
|
598
|
-
// public T[] items;
|
|
599
|
-
//}
|
|
550
|
+
}
|
|
600
551
|
}
|
|
601
552
|
}
|
|
@@ -7,7 +7,9 @@ namespace Amanotes.Core.Internal
|
|
|
7
7
|
{
|
|
8
8
|
public partial class ConfigAsset
|
|
9
9
|
{
|
|
10
|
-
[SerializeField]
|
|
10
|
+
[SerializeField]
|
|
11
|
+
[Tooltip("Enable to get countryCode automatically, provided by '"+ CountryIS_GeoLocationProvider.URL + "'\n\ndefault: OFF")]
|
|
12
|
+
public bool enableGeoLocation = false;
|
|
11
13
|
}
|
|
12
14
|
|
|
13
15
|
internal class GDKGeoLocation
|
|
@@ -58,7 +58,7 @@ namespace Amanotes.Core
|
|
|
58
58
|
|
|
59
59
|
internal class WorldTimeServer_TimeProvider : BaseServerTimeProvider
|
|
60
60
|
{
|
|
61
|
-
|
|
61
|
+
internal const string URL = "https://www.worldtimeserver.com/current_time_in_LA.aspx";
|
|
62
62
|
|
|
63
63
|
public override ServerTimeData ParseResponse(string response)
|
|
64
64
|
{
|
|
@@ -90,7 +90,7 @@ namespace Amanotes.Core
|
|
|
90
90
|
|
|
91
91
|
internal class WorldTimeAPI_TimeProvider : BaseServerTimeProvider
|
|
92
92
|
{
|
|
93
|
-
|
|
93
|
+
internal const string URL = "https://worldtimeapi.org/api/ip";
|
|
94
94
|
|
|
95
95
|
[Serializable]
|
|
96
96
|
private class TimeData
|
|
@@ -123,18 +123,21 @@ namespace Amanotes.Core.Internal
|
|
|
123
123
|
{
|
|
124
124
|
public partial class ConfigAsset
|
|
125
125
|
{
|
|
126
|
-
[SerializeField]
|
|
126
|
+
[SerializeField]
|
|
127
|
+
[Tooltip("Enable to get serverTime automatically, provided by\n\n'"+ WorldTimeAPI_TimeProvider.URL + "'\n'" + WorldTimeServer_TimeProvider.URL+ "'\n\ndefault: OFF" )]
|
|
128
|
+
public bool enableServerTime = false;
|
|
127
129
|
}
|
|
128
130
|
|
|
129
131
|
internal class GDKServerTime
|
|
130
132
|
{
|
|
131
133
|
private const float MAX_WAIT_TIME = 60;
|
|
132
|
-
private List<IServerTimeProvider> providers = new List<IServerTimeProvider>()
|
|
133
|
-
private int currentIndex = 0;
|
|
134
|
-
private IServerTimeProvider provider
|
|
134
|
+
private List<IServerTimeProvider> providers = new List<IServerTimeProvider>()
|
|
135
135
|
{
|
|
136
|
-
|
|
137
|
-
|
|
136
|
+
new WorldTimeAPI_TimeProvider(),
|
|
137
|
+
new WorldTimeServer_TimeProvider()
|
|
138
|
+
};
|
|
139
|
+
private int currentIndex = 0;
|
|
140
|
+
private IServerTimeProvider provider => providers[currentIndex];
|
|
138
141
|
|
|
139
142
|
private DateTime? serverTime;
|
|
140
143
|
private float timeSinceFetchServerTime;
|
|
@@ -144,7 +147,7 @@ namespace Amanotes.Core.Internal
|
|
|
144
147
|
{
|
|
145
148
|
}
|
|
146
149
|
|
|
147
|
-
|
|
150
|
+
internal void SetTimeProviders(List<IServerTimeProvider> providers)
|
|
148
151
|
{
|
|
149
152
|
GDKUtils.ThrowIf(providers == null || providers.Count == 0, "Server time providers list cannot be null or empty.");
|
|
150
153
|
this.providers = providers;
|
|
@@ -173,7 +176,7 @@ namespace Amanotes.Core.Internal
|
|
|
173
176
|
}
|
|
174
177
|
}
|
|
175
178
|
|
|
176
|
-
|
|
179
|
+
internal void UpdateTime(Action<DateTime?> result = null)
|
|
177
180
|
{
|
|
178
181
|
provider.FetchServerTime(data =>
|
|
179
182
|
{
|