com.amanotes.gdk 0.2.68 → 0.2.70-1
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/GDKCIBuildCommand.cs +2 -16
- 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
package/Runtime/Ad/AdLogic.cs
CHANGED
|
@@ -7,6 +7,7 @@ namespace Amanotes.Core.Internal
|
|
|
7
7
|
{
|
|
8
8
|
public abstract class AdLogic
|
|
9
9
|
{
|
|
10
|
+
private const int MAX_FRAMES_WAIT_FOR_CALLBACK = 60;
|
|
10
11
|
protected AdModuleConfig adConfig => Config.ad;
|
|
11
12
|
protected AdShowContext context => Ads.context;
|
|
12
13
|
|
|
@@ -130,9 +131,11 @@ namespace Amanotes.Core.Internal
|
|
|
130
131
|
private Coroutine _showAdRoutine;
|
|
131
132
|
protected bool _isRequesting;
|
|
132
133
|
protected bool _isInterstitial => adType == AdType.Interstitial;
|
|
134
|
+
private bool isFocus;
|
|
133
135
|
|
|
134
136
|
public void StartShowAd()
|
|
135
137
|
{
|
|
138
|
+
isFocus = false;
|
|
136
139
|
unityCallbacks.OnApplicationFocus -= OnApplicationFocus;
|
|
137
140
|
unityCallbacks.OnApplicationFocus += OnApplicationFocus;
|
|
138
141
|
|
|
@@ -157,16 +160,12 @@ namespace Amanotes.Core.Internal
|
|
|
157
160
|
_showAdRoutine = _instance.StartCoroutine(ShowAdRoutine());
|
|
158
161
|
}
|
|
159
162
|
|
|
160
|
-
void OnApplicationFocus(bool
|
|
163
|
+
private void OnApplicationFocus(bool focus)
|
|
161
164
|
{
|
|
162
|
-
if (!
|
|
165
|
+
if (!focus) return;
|
|
163
166
|
|
|
164
167
|
unityCallbacks.OnApplicationFocus -= OnApplicationFocus;
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
Log($"OnApplicationFocus Before: {context.hasClosed}");
|
|
168
|
-
context.adCallback |= AdCallback.Close;
|
|
169
|
-
Log($"OnApplicationFocus After: {context.hasClosed}");
|
|
168
|
+
isFocus = true;
|
|
170
169
|
}
|
|
171
170
|
|
|
172
171
|
public void StopShowAd()
|
|
@@ -209,55 +208,26 @@ namespace Amanotes.Core.Internal
|
|
|
209
208
|
|
|
210
209
|
if (!HasLocalNetworkConnection)
|
|
211
210
|
{
|
|
212
|
-
|
|
213
|
-
OnAdShowReadyStatus(false, AdShowReadyStatus.Wifi3GDisabled);
|
|
214
|
-
ShowAdRoutineCompleted(false);
|
|
211
|
+
EndShowAdRoutineWithFailure(AdShowReadyStatus.Wifi3GDisabled);
|
|
215
212
|
yield break;
|
|
216
213
|
}
|
|
217
214
|
|
|
218
215
|
int timeout = Config.ad.adShowTimeoutInSecs;
|
|
219
216
|
if (timeout == 0) // do not wait for Ad
|
|
220
217
|
{
|
|
221
|
-
|
|
222
|
-
OnAdShowReadyStatus(false, AdShowReadyStatus.TimeOut);
|
|
223
|
-
ShowAdRoutineCompleted(false);
|
|
218
|
+
EndShowAdRoutineWithFailure(AdShowReadyStatus.TimeOut);
|
|
224
219
|
yield break;
|
|
225
220
|
}
|
|
226
221
|
|
|
227
222
|
_showState = ShowAdsState.WaitForAd;
|
|
228
223
|
OnAdShowReadyStatus(false, AdShowReadyStatus.WaitForAd);
|
|
229
224
|
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
bool? hasInternet = null;
|
|
233
|
-
if (adConfig.checkInternet) _instance.StartCoroutine(WebUtils.CheckInternet(result => hasInternet = result));
|
|
234
|
-
|
|
235
|
-
var wait1Sec = new WaitForSecondsRealtime(1f);
|
|
236
|
-
while (counter < timeout || timeout == -1)
|
|
237
|
-
{
|
|
238
|
-
yield return wait1Sec;
|
|
239
|
-
counter++;
|
|
240
|
-
|
|
241
|
-
// finish checking internet & result is false
|
|
242
|
-
if (adConfig.checkInternet && hasInternet == false)
|
|
243
|
-
{
|
|
244
|
-
Log("[Ad] Stop WaitForAd : No internet!");
|
|
245
|
-
_showState = ShowAdsState.ShowFail;
|
|
246
|
-
OnAdShowReadyStatus(false, AdShowReadyStatus.NoInternet);
|
|
247
|
-
ShowAdRoutineCompleted(false);
|
|
248
|
-
yield break;
|
|
249
|
-
}
|
|
250
|
-
|
|
251
|
-
if (_loadState != LoadAdsState.Ready) continue;
|
|
252
|
-
Log("[Ad] WaitForAd success after " + counter + " | timeout = " + timeout + " secs");
|
|
253
|
-
break;
|
|
254
|
-
}
|
|
255
|
-
|
|
225
|
+
yield return WaitForAdReadyWithTimeout(timeout);
|
|
226
|
+
|
|
256
227
|
if (!isAdReady)
|
|
257
228
|
{
|
|
258
|
-
Log("[Ad] WaitForAd failed (timeout) " +
|
|
259
|
-
|
|
260
|
-
ShowAdRoutineCompleted(false);
|
|
229
|
+
Log("[Ad] WaitForAd failed (timeout) " + " | timeout = " + timeout + " secs");
|
|
230
|
+
EndShowAdRoutineWithFailure(AdShowReadyStatus.TimeOut);
|
|
261
231
|
yield break;
|
|
262
232
|
}
|
|
263
233
|
}
|
|
@@ -266,43 +236,78 @@ namespace Amanotes.Core.Internal
|
|
|
266
236
|
OnAdShowReadyStatus(true, AdShowReadyStatus.Ready);
|
|
267
237
|
TriggerBeforeAdShow();
|
|
268
238
|
ShowAd();
|
|
239
|
+
|
|
240
|
+
yield return WaitForMediationCallback();
|
|
269
241
|
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
242
|
+
// wait 1 frame in case hasReward callback after onClose
|
|
243
|
+
if (!context.hasReward && adType == AdType.VideoReward && !context.hasFailedOrCancelled) yield return null;
|
|
244
|
+
ShowAdRoutineCompleted(context.isSuccess);
|
|
245
|
+
}
|
|
274
246
|
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
247
|
+
private void EndShowAdRoutineWithFailure(AdShowReadyStatus status)
|
|
248
|
+
{
|
|
249
|
+
_showState = ShowAdsState.ShowFail;
|
|
250
|
+
OnAdShowReadyStatus(false, status);
|
|
251
|
+
ShowAdRoutineCompleted(false);
|
|
252
|
+
}
|
|
280
253
|
|
|
281
|
-
|
|
254
|
+
private IEnumerator WaitForAdReadyWithTimeout(int timeout)
|
|
255
|
+
{
|
|
256
|
+
if (_loadState != LoadAdsState.Requesting) StartLoadAd();
|
|
257
|
+
var counter = 0;
|
|
258
|
+
bool? hasInternet = null;
|
|
259
|
+
if (adConfig.checkInternet) _instance.StartCoroutine(WebUtils.CheckInternet(result => hasInternet = result));
|
|
260
|
+
|
|
261
|
+
var wait1Sec = new WaitForSecondsRealtime(1f);
|
|
262
|
+
while (counter < timeout || timeout == -1)
|
|
282
263
|
{
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
264
|
+
yield return wait1Sec;
|
|
265
|
+
counter++;
|
|
266
|
+
Log($"[Ad] Waiting for ad {counter} secs");
|
|
267
|
+
|
|
268
|
+
// finish checking internet & result is false
|
|
269
|
+
if (adConfig.checkInternet && hasInternet == false)
|
|
270
|
+
{
|
|
271
|
+
Log("[Ad] Stop WaitForAd : No internet!");
|
|
272
|
+
EndShowAdRoutineWithFailure(AdShowReadyStatus.NoInternet);
|
|
273
|
+
yield break;
|
|
274
|
+
}
|
|
275
|
+
|
|
276
|
+
if (_loadState != LoadAdsState.Ready) continue;
|
|
277
|
+
Log("[Ad] WaitForAd success after " + counter + " | timeout = " + timeout + " secs");
|
|
278
|
+
break;
|
|
287
279
|
}
|
|
280
|
+
}
|
|
288
281
|
|
|
289
|
-
|
|
282
|
+
private IEnumerator WaitForMediationCallback()
|
|
283
|
+
{
|
|
284
|
+
#if !UNITY_EDITOR
|
|
285
|
+
while (!isFocus) yield return null;
|
|
286
|
+
#endif
|
|
287
|
+
|
|
288
|
+
int wait4CallbackCounter = 0;
|
|
289
|
+
while (!context.potentiallyCompleted && wait4CallbackCounter <= MAX_FRAMES_WAIT_FOR_CALLBACK)
|
|
290
290
|
{
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
ShowAdRoutineCompleted(context.hasReward);
|
|
294
|
-
yield break;
|
|
291
|
+
wait4CallbackCounter++;
|
|
292
|
+
yield return null;
|
|
295
293
|
}
|
|
294
|
+
Log($"[Ad] Waiting for potentially completed callback: {wait4CallbackCounter} frames");
|
|
295
|
+
|
|
296
|
+
if (!context.hasClosed) yield return WaitForAdClosedCallback();
|
|
297
|
+
}
|
|
296
298
|
|
|
297
|
-
|
|
298
|
-
|
|
299
|
+
private IEnumerator WaitForAdClosedCallback()
|
|
300
|
+
{
|
|
301
|
+
int counter = 0;
|
|
302
|
+
while (!context.hasClosed && counter <= MAX_FRAMES_WAIT_FOR_CALLBACK)
|
|
299
303
|
{
|
|
300
|
-
|
|
301
|
-
Log($"[Ad] {adType} Waiting for [close]: {wait4CloseCounter}");
|
|
304
|
+
counter++;
|
|
302
305
|
yield return null;
|
|
303
306
|
}
|
|
304
|
-
|
|
305
|
-
|
|
307
|
+
Log($"[Ad] Waiting for ad closed callback: {counter} frames");
|
|
308
|
+
if (context.hasClosed) yield break;
|
|
309
|
+
LogWarning("[Ad] Force close ad (mediation missing OnAdClose callback)");
|
|
310
|
+
OnAdClosed();
|
|
306
311
|
}
|
|
307
312
|
|
|
308
313
|
private void ShowAdRoutineCompleted(bool isSuccess)
|
|
@@ -315,9 +320,7 @@ namespace Amanotes.Core.Internal
|
|
|
315
320
|
|
|
316
321
|
_showState = isSuccess ? ShowAdsState.ShowSuccess : ShowAdsState.ShowFail;
|
|
317
322
|
|
|
318
|
-
|
|
319
|
-
Ads.context.showFinishAt = Time.realtimeSinceStartup;
|
|
320
|
-
Ads.context.onAdResult?.Invoke(isSuccess);
|
|
323
|
+
|
|
321
324
|
|
|
322
325
|
var localData = Ads.localData;
|
|
323
326
|
var stat = _isInterstitial ? localData.interstitial : localData.reward;
|
|
@@ -336,8 +339,13 @@ namespace Amanotes.Core.Internal
|
|
|
336
339
|
TriggerOnAfterAdShow();
|
|
337
340
|
|
|
338
341
|
Log($"[Ad] {adType} ShowAdRoutineCompleted: {isSuccess}\n{JsonUtility.ToJson(Ads.context)}");
|
|
342
|
+
|
|
343
|
+
// Extra callback
|
|
344
|
+
context.showFinishAt = Time.realtimeSinceStartup;
|
|
345
|
+
var resultCallback = context.onAdResult;
|
|
339
346
|
Ads.context = null;
|
|
340
347
|
_showState = ShowAdsState.None;
|
|
348
|
+
resultCallback?.Invoke(isSuccess);
|
|
341
349
|
}
|
|
342
350
|
|
|
343
351
|
private void TriggerBeforeAdShow()
|
|
@@ -399,6 +407,11 @@ namespace Amanotes.Core.Internal
|
|
|
399
407
|
|
|
400
408
|
if (Ads.context != null)
|
|
401
409
|
{
|
|
410
|
+
if ((Ads.context.adCallback & AdCallback.Close) != 0)
|
|
411
|
+
{
|
|
412
|
+
LogWarning("[Ad] OnAdClosed() has been called multiple times for the same ad.");
|
|
413
|
+
return;
|
|
414
|
+
}
|
|
402
415
|
Ads.context.adCallback |= AdCallback.Close;
|
|
403
416
|
Ads.context.onClosed?.Invoke();
|
|
404
417
|
} else
|
|
@@ -39,5 +39,6 @@ namespace Amanotes.Core.Internal
|
|
|
39
39
|
public bool hasReward => (adCallback & AdCallback.Reward) != 0;
|
|
40
40
|
public bool hasClosed => (adCallback & AdCallback.Close) != 0;
|
|
41
41
|
public bool hasClicked => (adCallback & AdCallback.Click) != 0;
|
|
42
|
+
public bool isSuccess => (hasReward || adType == AdType.Interstitial) && !hasFailedOrCancelled;
|
|
42
43
|
}
|
|
43
44
|
}
|
package/Runtime/Ad/AmaGDK.Ads.cs
CHANGED
|
@@ -150,8 +150,12 @@ namespace Amanotes.Core
|
|
|
150
150
|
{
|
|
151
151
|
internal static bool InitModule()
|
|
152
152
|
{
|
|
153
|
+
if (Adapter2.GetAllAdapter<AdAdapter>().Count > 1)
|
|
154
|
+
{
|
|
155
|
+
Utils.ThrowExceptionIfEditor("Multiple AdAdapters is not supported!");
|
|
156
|
+
}
|
|
153
157
|
_adapter = Adapter2.GetAdapter<AdAdapter>();
|
|
154
|
-
return _adapter
|
|
158
|
+
return _adapter != null;
|
|
155
159
|
}
|
|
156
160
|
|
|
157
161
|
internal static void StartModule()
|
|
@@ -181,24 +185,34 @@ namespace Amanotes.Core
|
|
|
181
185
|
return false;
|
|
182
186
|
}
|
|
183
187
|
|
|
184
|
-
public static IAdCallback ShowInterstitial(string placementName = null, Dictionary<string, object> userData = null)
|
|
188
|
+
public static IAdCallback ShowInterstitial(Action<bool> onAdResult = null, string placementName = null, Dictionary<string, object> userData = null)
|
|
185
189
|
{
|
|
186
190
|
if (_adapter == null) return null;
|
|
187
191
|
if (!ClearPrevContext()) return null;
|
|
188
192
|
|
|
189
193
|
context = new AdShowContext(AdType.Interstitial, placementName, userData);
|
|
194
|
+
if (onAdResult != null)
|
|
195
|
+
{
|
|
196
|
+
context.onAdResult += onAdResult;
|
|
197
|
+
}
|
|
198
|
+
|
|
190
199
|
_adapter.interstitial.StartShowAd();
|
|
191
200
|
return context;
|
|
192
201
|
}
|
|
193
202
|
|
|
194
203
|
public static bool IsInterstitialShowing => (context != null) && (context.adType == AdType.Interstitial);
|
|
195
204
|
|
|
196
|
-
public static IAdCallback ShowRewardedVideo(string placementName = null, Dictionary<string, object> userData = null)
|
|
205
|
+
public static IAdCallback ShowRewardedVideo(Action<bool> onAdResult = null, string placementName = null, Dictionary<string, object> userData = null)
|
|
197
206
|
{
|
|
198
207
|
if (_adapter == null) return null;
|
|
199
208
|
if (!ClearPrevContext()) return null;
|
|
200
209
|
|
|
201
210
|
context = new AdShowContext(AdType.VideoReward, placementName, userData);
|
|
211
|
+
if (onAdResult != null)
|
|
212
|
+
{
|
|
213
|
+
context.onAdResult += onAdResult;
|
|
214
|
+
}
|
|
215
|
+
|
|
202
216
|
_adapter.rewardVideo.StartShowAd();
|
|
203
217
|
return context;
|
|
204
218
|
}
|
|
@@ -10,7 +10,7 @@ namespace Amanotes.Core.Internal
|
|
|
10
10
|
|
|
11
11
|
public abstract partial class Adapter2
|
|
12
12
|
{
|
|
13
|
-
internal
|
|
13
|
+
protected internal enum ConfigStatus
|
|
14
14
|
{
|
|
15
15
|
Ok,
|
|
16
16
|
Invalid,
|
|
@@ -22,12 +22,15 @@ namespace Amanotes.Core.Internal
|
|
|
22
22
|
[HideInNormalInspector] [SerializeField] internal bool enabled = true;
|
|
23
23
|
[NonSerialized] internal string adapterId;
|
|
24
24
|
[NonSerialized] internal string adapterVersion;
|
|
25
|
-
[NonSerialized] internal
|
|
25
|
+
[NonSerialized] protected internal Status status = Status.None;
|
|
26
26
|
|
|
27
27
|
protected abstract void Init(Action<bool> onComplete);
|
|
28
|
-
internal
|
|
29
|
-
|
|
30
|
-
|
|
28
|
+
protected internal abstract string GetServiceKey();
|
|
29
|
+
protected virtual float GetTimeoutInEditor() => 0.1f;
|
|
30
|
+
protected virtual float GetTimeoutInRuntime() => 0.1f;
|
|
31
|
+
protected internal abstract ConfigStatus configStatus { get; }
|
|
32
|
+
protected internal float Timeout => Application.isEditor ? GetTimeoutInEditor() : GetTimeoutInRuntime();
|
|
33
|
+
|
|
31
34
|
public bool IsReady => status == Status.Ready;
|
|
32
35
|
|
|
33
36
|
internal void InitSDK() // call by AmaGDK
|
|
@@ -63,6 +66,10 @@ namespace Amanotes.Core.Internal
|
|
|
63
66
|
LogWarning($"Adapter <{id}> == null in ConfigAsset? (non-serialized?)");
|
|
64
67
|
return false;
|
|
65
68
|
}
|
|
69
|
+
if (!adapter.enabled)
|
|
70
|
+
{
|
|
71
|
+
return false;
|
|
72
|
+
}
|
|
66
73
|
|
|
67
74
|
adapter.adapterId = id;
|
|
68
75
|
adapter.adapterVersion = version;
|
|
@@ -68,8 +68,9 @@ namespace Amanotes.Core
|
|
|
68
68
|
doNotIncreaseCounter = false;
|
|
69
69
|
isLoggedImmediately = false;
|
|
70
70
|
overrideConfig = false;
|
|
71
|
-
|
|
72
|
-
|
|
71
|
+
|
|
72
|
+
GDKPool.ReturnAndNullize(ref ignoreAdapterIds);
|
|
73
|
+
GDKPool.ReturnAndNullize(ref allowAdapterIds);
|
|
73
74
|
_detail = null;
|
|
74
75
|
}
|
|
75
76
|
|
|
@@ -307,9 +308,8 @@ namespace Amanotes.Core
|
|
|
307
308
|
internal static readonly List<AnalyticsAdapter> listAdapters = new List<AnalyticsAdapter>();
|
|
308
309
|
internal static readonly AnalyticsData localData = new AnalyticsData().LoadJsonFromFile().BuildCache();
|
|
309
310
|
internal static SessionStat sessionStat;
|
|
310
|
-
internal static readonly GDKPool<
|
|
311
|
-
|
|
312
|
-
|
|
311
|
+
internal static readonly GDKPool.Pool<EventParams> epPool = new GDKPool.Pool<EventParams>(1);
|
|
312
|
+
|
|
313
313
|
internal static readonly Dictionary<string, string> reservedPrefixes = new Dictionary<string, string>()
|
|
314
314
|
{
|
|
315
315
|
{ "firebase_", "frb_" },
|
|
@@ -515,32 +515,31 @@ namespace Amanotes.Core
|
|
|
515
515
|
{
|
|
516
516
|
Profiler.BeginSample("AmaGDK.Analytics.NormalizeEventName()");
|
|
517
517
|
{
|
|
518
|
-
var
|
|
519
|
-
|
|
520
|
-
NormalizeKeyString(ref eventName, sb, dryRun);
|
|
518
|
+
var warningLog = GDKPool.GetStringBuilder(8);
|
|
519
|
+
NormalizeKeyString(ref eventName, warningLog, dryRun);
|
|
521
520
|
if (reservedEvents.Contains(eventName))
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
521
|
+
{
|
|
522
|
+
warningLog.AppendLine($" - EventName <{eventName}> is reserved and should not be used");
|
|
523
|
+
}
|
|
524
|
+
if (warningLog.Length > 0 && dryRun) LogWarningOnce($"NormalizeEventName <{eventName}> warnings:\n{warningLog}\n", $"NormalizeEventName<{eventName}>");
|
|
525
|
+
GDKPool.Return(warningLog);
|
|
525
526
|
}
|
|
526
527
|
Profiler.EndSample();
|
|
527
528
|
}
|
|
528
529
|
|
|
529
530
|
internal static void NormalizeKeyString(ref string key, StringBuilder warningLog, bool dryRun)
|
|
530
531
|
{
|
|
532
|
+
if (string.IsNullOrWhiteSpace(key))
|
|
533
|
+
{
|
|
534
|
+
LogWarning($" - Name should not be empty");
|
|
535
|
+
return;
|
|
536
|
+
}
|
|
537
|
+
|
|
531
538
|
Profiler.BeginSample("AmaGDK.Analytics.NormalizeKeyString()");
|
|
532
539
|
{
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
Profiler.EndSample();
|
|
537
|
-
return;
|
|
538
|
-
}
|
|
539
|
-
|
|
540
|
-
var tempLog = Config.common.logLevel == LogLevel.None ? null : sbPool.Get();
|
|
541
|
-
tempLog?.Clear();
|
|
542
|
-
var tempKey = sbPool.Get();
|
|
543
|
-
tempKey.Clear();
|
|
540
|
+
var willLog = Config.common.logLevel != LogLevel.None;
|
|
541
|
+
var tempLog = willLog ? GDKPool.GetStringBuilder() : null;
|
|
542
|
+
var tempKey = GDKPool.GetStringBuilder();
|
|
544
543
|
|
|
545
544
|
var hasChanged = false;
|
|
546
545
|
var trimKey = key.Trim();
|
|
@@ -563,16 +562,16 @@ namespace Amanotes.Core
|
|
|
563
562
|
}
|
|
564
563
|
}
|
|
565
564
|
|
|
566
|
-
if (hasChanged)
|
|
565
|
+
if (hasChanged && willLog)
|
|
567
566
|
{
|
|
568
|
-
tempLog
|
|
567
|
+
tempLog.Append(" - Name may only contain alphanumeric characters and underscores");
|
|
569
568
|
}
|
|
570
569
|
|
|
571
570
|
if (tempKey.Length > 0 && !IsAlphabet(tempKey[0]))
|
|
572
571
|
{
|
|
573
572
|
hasChanged = true;
|
|
574
573
|
tempKey.Insert(0, 'E');
|
|
575
|
-
tempLog
|
|
574
|
+
if (willLog) tempLog.Append($" - Name must start with a letter: <{key}>");
|
|
576
575
|
}
|
|
577
576
|
|
|
578
577
|
foreach (var prefix in reservedPrefixes)
|
|
@@ -581,13 +580,13 @@ namespace Amanotes.Core
|
|
|
581
580
|
hasChanged = true;
|
|
582
581
|
tempKey.Remove(0, prefix.Key.Length);
|
|
583
582
|
tempKey.Insert(0, prefix.Value);
|
|
584
|
-
tempLog
|
|
583
|
+
if (willLog) tempLog.AppendLine($" - <{key}> starts with reserved prefix <{prefix}>");
|
|
585
584
|
}
|
|
586
585
|
|
|
587
586
|
if (trimKey.Length > 40)
|
|
588
587
|
{
|
|
589
588
|
hasChanged = true;
|
|
590
|
-
tempLog
|
|
589
|
+
if (willLog) tempLog.AppendLine($" - Name is too long ({key.Length} > 40): <{key}> ");
|
|
591
590
|
tempKey.Length = 40;
|
|
592
591
|
}
|
|
593
592
|
|
|
@@ -598,8 +597,8 @@ namespace Amanotes.Core
|
|
|
598
597
|
if (hasChanged) key = tempKey.ToString();
|
|
599
598
|
}
|
|
600
599
|
|
|
601
|
-
|
|
602
|
-
|
|
600
|
+
GDKPool.Return(tempLog);
|
|
601
|
+
GDKPool.Return(tempKey);
|
|
603
602
|
}
|
|
604
603
|
Profiler.EndSample();
|
|
605
604
|
}
|
|
@@ -702,9 +701,17 @@ namespace Amanotes.Core
|
|
|
702
701
|
adapters = adapterIDs;
|
|
703
702
|
}
|
|
704
703
|
|
|
705
|
-
public
|
|
704
|
+
public void AppendAsTSV(StringBuilder sb)
|
|
706
705
|
{
|
|
707
|
-
|
|
706
|
+
sb.Append(eventNameToSend);
|
|
707
|
+
sb.Append("\t");
|
|
708
|
+
for (var i = 0; i < adapters.Count; i++)
|
|
709
|
+
{
|
|
710
|
+
sb.Append(adapters[i]);
|
|
711
|
+
if (i < adapters.Count - 1) sb.Append(",");
|
|
712
|
+
}
|
|
713
|
+
sb.Append("\t");
|
|
714
|
+
sb.Append(parameters);
|
|
708
715
|
}
|
|
709
716
|
}
|
|
710
717
|
|
|
@@ -856,8 +863,8 @@ namespace Amanotes.Core
|
|
|
856
863
|
{
|
|
857
864
|
private const string TSV_HEADER_ROW = "EventName\tAdapters\tParameters";
|
|
858
865
|
private readonly string fileName = nameof(SessionStat) + DateTime.Now.ToString("_yyMMdd_HHmmss") + ".tsv";
|
|
859
|
-
private StringBuilder contents = new StringBuilder();
|
|
860
866
|
private bool isFirstSave = true;
|
|
867
|
+
private StringBuilder contents = new StringBuilder(8192);
|
|
861
868
|
private readonly ConcurrentQueue<EventStat> lastFrameEventStats = new ConcurrentQueue<EventStat>();
|
|
862
869
|
internal readonly ConcurrentQueue<EventStat> savedEventStatsInLastFrame = new ConcurrentQueue<EventStat>();
|
|
863
870
|
|
|
@@ -878,10 +885,10 @@ namespace Amanotes.Core
|
|
|
878
885
|
}
|
|
879
886
|
while (lastFrameEventStats.TryDequeue(out var stat))
|
|
880
887
|
{
|
|
881
|
-
|
|
888
|
+
stat.AppendAsTSV(contents);
|
|
882
889
|
savedEventStatsInLastFrame.Enqueue(stat);
|
|
883
890
|
}
|
|
884
|
-
|
|
891
|
+
|
|
885
892
|
GDKFileUtils.SaveAppend(fileName, contents.ToString());
|
|
886
893
|
}
|
|
887
894
|
|
|
@@ -972,7 +979,7 @@ namespace Amanotes.Core
|
|
|
972
979
|
}
|
|
973
980
|
|
|
974
981
|
eventData.overrideConfig = true;
|
|
975
|
-
eventData.ignoreAdapterIds ??=
|
|
982
|
+
eventData.ignoreAdapterIds ??= GDKPool.GetHashSet();
|
|
976
983
|
|
|
977
984
|
foreach (string mId in analyticIds)
|
|
978
985
|
{
|
|
@@ -998,7 +1005,7 @@ namespace Amanotes.Core
|
|
|
998
1005
|
}
|
|
999
1006
|
|
|
1000
1007
|
eventData.overrideConfig = true;
|
|
1001
|
-
eventData.allowAdapterIds ??=
|
|
1008
|
+
eventData.allowAdapterIds ??= GDKPool.GetHashSet();
|
|
1002
1009
|
|
|
1003
1010
|
foreach (string mId in analyticIds)
|
|
1004
1011
|
{
|
|
@@ -1080,12 +1087,12 @@ namespace Amanotes.Core
|
|
|
1080
1087
|
{
|
|
1081
1088
|
string eventName = (ap as EventParams)?.eventName;
|
|
1082
1089
|
|
|
1083
|
-
var sb =
|
|
1090
|
+
var sb = GDKPool.GetStringBuilder();
|
|
1084
1091
|
sb.Clear();
|
|
1085
1092
|
NormalizeKeyString(ref key, sb, AmaGDK.Config.analytics.normalizeEventName);
|
|
1086
1093
|
|
|
1087
1094
|
if (sb.Length > 0) LogWarningOnce($"Warning for event <{eventName}>, param <{key}>:\n{sb}", $"NormalizeParamKey <{eventName}>");
|
|
1088
|
-
|
|
1095
|
+
GDKPool.Return(sb);
|
|
1089
1096
|
|
|
1090
1097
|
if (string.IsNullOrWhiteSpace(key))
|
|
1091
1098
|
{
|