com.amanotes.gdk 0.2.50 → 0.2.51

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 CHANGED
@@ -1,5 +1,17 @@
1
1
  # Changelog
2
2
 
3
+ ## [0.2.51 - 2024-02-23]
4
+ - New feature: GDKCIBuildCommand
5
+ - [Dev] Change Google Mobile Ads SDK version for iOS, 10.9 -> 10.5.0
6
+ - [Analytics] Add LogEventImmediately()
7
+ - [Analytics] Move AddParam() to internal use
8
+ - [Analytics] Replace event Queue by ConcurrentQueue
9
+ - [Ads] Check null Ads._adapter
10
+ - [Ads] Autostart AdEventTracking
11
+ - [Analytics] Update AppsFlyer adapter version
12
+ - [UserProfile] Change logic of getting ama_device_id
13
+ - [Core] Init modules before Hooks
14
+
3
15
  ## [0.2.50 - 2024-02-20]
4
16
  - New feature: Modify Android post processor
5
17
  - [Fix] remove installer should be skipped in DEV mode
@@ -11,13 +11,25 @@ using UnityObject = UnityEngine.Object;
11
11
 
12
12
  namespace Amanotes.Editor
13
13
  {
14
- [CreateAssetMenu(menuName = "AmaGDK/Build Config")]
15
- public class GDKAutoBuild : ScriptableObject
14
+ [CreateAssetMenu(menuName = "Ama GDK/Build Config", fileName = "LocalBuild")]
15
+ public class GDKLocalBuild : ScriptableObject
16
16
  {
17
17
  private const string DEFAULT_BUILD_FOLDER = "../../_Build";
18
18
 
19
19
  public KeystoreInfo keystore;
20
- public string buildFolder = DEFAULT_BUILD_FOLDER;
20
+ [SerializeField] private string relativeBuildFolder = DEFAULT_BUILD_FOLDER;
21
+
22
+ private string _buildFolder;
23
+ public string buildFolder
24
+ {
25
+ get
26
+ {
27
+ if (!string.IsNullOrEmpty(_buildFolder)) return _buildFolder;
28
+ _buildFolder = new DirectoryInfo(Path.Combine(Application.dataPath, relativeBuildFolder ?? DEFAULT_BUILD_FOLDER)).FullName;
29
+ return _buildFolder;
30
+ }
31
+ }
32
+
21
33
  public Texture2D icon;
22
34
 
23
35
  public List<BuildInfo> listBuild = new List<BuildInfo>();
@@ -135,8 +147,6 @@ namespace Amanotes.Editor
135
147
 
136
148
  public void DryRun(BuildInfo info)
137
149
  {
138
- if (string.IsNullOrEmpty(buildFolder)) buildFolder = DEFAULT_BUILD_FOLDER;
139
-
140
150
  var buildDir = new DirectoryInfo(buildFolder);
141
151
  if (!buildDir.Exists) Directory.CreateDirectory(buildDir.FullName);
142
152
 
@@ -344,8 +354,13 @@ namespace Amanotes.Editor
344
354
 
345
355
  EditorUserBuildSettings.buildAppBundle = isAAB;
346
356
  EditorUserBuildSettings.exportAsGoogleAndroidProject = false;
357
+
358
+ #if UNITY_2021_1_OR_NEWER
347
359
  EditorUserBuildSettings.androidCreateSymbols = AndroidCreateSymbols.Disabled;
348
-
360
+ #else
361
+ EditorUserBuildSettings.androidCreateSymbolsZip = false;
362
+ #endif
363
+
349
364
  string[] listAPKNames = GetAPKNames(buildFolder);
350
365
 
351
366
  for (var i = 0; i < listAPKNames.Length; i++)
@@ -508,10 +523,10 @@ namespace Amanotes.Editor
508
523
 
509
524
 
510
525
  [InitializeOnLoad]
511
- internal class GDKAutoBuildHelper
526
+ internal class GDKLocalBuildHelper
512
527
  {
513
- private static GDKAutoBuild build;
514
- static GDKAutoBuildHelper()
528
+ private static GDKLocalBuild build;
529
+ static GDKLocalBuildHelper()
515
530
  {
516
531
  EditorApplication.update -= Update;
517
532
  EditorApplication.update += Update;
@@ -530,7 +545,7 @@ namespace Amanotes.Editor
530
545
 
531
546
  if (build == null)
532
547
  {
533
- string[] guids = AssetDatabase.FindAssets("t:" + nameof(GDKAutoBuild)); //FindAssets uses tags check documentation for more info
548
+ string[] guids = AssetDatabase.FindAssets("t:" + nameof(GDKLocalBuild)); //FindAssets uses tags check documentation for more info
534
549
  if (guids.Length == 0)
535
550
  {
536
551
  EditorApplication.update -= Update;
@@ -538,7 +553,7 @@ namespace Amanotes.Editor
538
553
  }
539
554
 
540
555
  string path = AssetDatabase.GUIDToAssetPath(guids[0]);
541
- build = AssetDatabase.LoadAssetAtPath<GDKAutoBuild>(path);
556
+ build = AssetDatabase.LoadAssetAtPath<GDKLocalBuild>(path);
542
557
  if (build == null)
543
558
  {
544
559
  EditorApplication.update -= Update;
@@ -558,7 +573,7 @@ namespace Amanotes.Editor
558
573
  // [MenuItem("Window/AmaGDK/Build/Select Build Asset &#b", false, 10)]
559
574
  public static void SelectBuild()
560
575
  {
561
- string[] arr = AssetDatabase.FindAssets("t:" + nameof(GDKAutoBuild));
576
+ string[] arr = AssetDatabase.FindAssets("t:" + nameof(GDKLocalBuild));
562
577
 
563
578
  if (arr.Length == 0)
564
579
  {
@@ -577,9 +592,9 @@ namespace Amanotes.Editor
577
592
  EditorGUIUtility.PingObject(obj);
578
593
  }
579
594
 
580
- private static GDKAutoBuild FindAutoBuildAssets(string name = null, bool allowFallback = false)
595
+ private static GDKLocalBuild FindLocalBuildAssets(string name = null, bool allowFallback = false)
581
596
  {
582
- string[] arr = AssetDatabase.FindAssets("t:" + nameof(GDKAutoBuild));
597
+ string[] arr = AssetDatabase.FindAssets("t:" + nameof(GDKLocalBuild));
583
598
  if (arr.Length == 0)
584
599
  {
585
600
  Debug.LogWarning("There are no Build asset in the project!");
@@ -589,17 +604,17 @@ namespace Amanotes.Editor
589
604
  for (var i = 0; i < arr.Length; i++)
590
605
  {
591
606
  string path = AssetDatabase.GUIDToAssetPath(arr[i]).Replace("\\", "/");
592
- if (string.IsNullOrEmpty(name)) return AssetDatabase.LoadAssetAtPath<GDKAutoBuild>(path);
607
+ if (string.IsNullOrEmpty(name)) return AssetDatabase.LoadAssetAtPath<GDKLocalBuild>(path);
593
608
 
594
609
  string fileName = Path.GetFileName(path);
595
- if (fileName.ToLower().Contains(name.ToLower())) return AssetDatabase.LoadAssetAtPath<GDKAutoBuild>(path);
610
+ if (fileName.ToLower().Contains(name.ToLower())) return AssetDatabase.LoadAssetAtPath<GDKLocalBuild>(path);
596
611
  }
597
612
 
598
613
  if (!allowFallback) return null;
599
614
 
600
615
  // Fall back to the first one
601
616
  string path0 = AssetDatabase.GUIDToAssetPath(arr[0]).Replace("\\", "/");
602
- return AssetDatabase.LoadAssetAtPath<GDKAutoBuild>(path0);
617
+ return AssetDatabase.LoadAssetAtPath<GDKLocalBuild>(path0);
603
618
  }
604
619
 
605
620
  // [MenuItem("Window/AmaGDK/Build/Android", false, 50)] public static void BuildAndroid() { BuildAndroid(false); }
@@ -610,7 +625,7 @@ namespace Amanotes.Editor
610
625
 
611
626
  private static void BuildAndroid(bool isRelease)
612
627
  {
613
- GDKAutoBuild buildAsset = FindAutoBuildAssets("android");
628
+ GDKLocalBuild buildAsset = FindLocalBuildAssets("android");
614
629
  if (buildAsset == null)
615
630
  {
616
631
  Debug.LogWarning("Build Asset for Android not found!");
@@ -618,26 +633,26 @@ namespace Amanotes.Editor
618
633
  }
619
634
 
620
635
  buildAsset.EnableBuildForTarget(BuildTarget.Android);
621
- buildAsset.buildRQ = GDKAutoBuild.BuildRequestTS.Generate();// isRelease
636
+ buildAsset.buildRQ = GDKLocalBuild.BuildRequestTS.Generate();// isRelease
622
637
  buildAsset.ProcessBuild();
623
638
  }
624
639
 
625
640
  private static void BuildIOS(bool isRelease)
626
641
  {
627
- GDKAutoBuild buildAsset = FindAutoBuildAssets("ios");
642
+ GDKLocalBuild buildAsset = FindLocalBuildAssets("ios");
628
643
  if (buildAsset == null)
629
644
  {
630
645
  Debug.LogWarning("Build Asset for iOS not found!");
631
646
  return;
632
647
  }
633
648
  buildAsset.EnableBuildForTarget(BuildTarget.iOS);
634
- buildAsset.buildRQ = GDKAutoBuild.BuildRequestTS.Generate(); //isRelease
649
+ buildAsset.buildRQ = GDKLocalBuild.BuildRequestTS.Generate(); //isRelease
635
650
  buildAsset.ProcessBuild();
636
651
  }
637
652
  }
638
653
 
639
- [CustomEditor(typeof(GDKAutoBuild))]
640
- public class GDKAutoBuildEditor : UnityEditor.Editor
654
+ [CustomEditor(typeof(GDKLocalBuild))]
655
+ public class GDKLocalBuildEditor : UnityEditor.Editor
641
656
  {
642
657
  public int bIndex;
643
658
  public string path;
@@ -671,7 +686,7 @@ namespace Amanotes.Editor
671
686
  }
672
687
  public override void OnInspectorGUI()
673
688
  {
674
- var ab = (GDKAutoBuild)target;
689
+ var ab = (GDKLocalBuild)target;
675
690
  if (ab == null) return;
676
691
 
677
692
  if (productNameStyle == null) Init();
@@ -681,7 +696,7 @@ namespace Amanotes.Editor
681
696
  Rect r0 = GUILayoutUtility.GetRect(0, Screen.width, 16f, 16f);
682
697
  r0.xMin = 0;
683
698
  r0.xMax += 16f;
684
- GDKAutoBuild.DrawRect(r0, new Color32(20, 20, 20, 255));
699
+ GDKLocalBuild.DrawRect(r0, new Color32(20, 20, 20, 255));
685
700
 
686
701
  if ((Event.current.type == EventType.MouseUp) && r0.Contains(Event.current.mousePosition))
687
702
  {
@@ -715,19 +730,19 @@ namespace Amanotes.Editor
715
730
 
716
731
  if (GUILayout.Button("Create Default"))
717
732
  {
718
- new GDKAutoBuild.BuildInfo().Read();
733
+ new GDKLocalBuild.BuildInfo().Read();
719
734
 
720
- ab.listBuild = new List<GDKAutoBuild.BuildInfo>
735
+ ab.listBuild = new List<GDKLocalBuild.BuildInfo>
721
736
  {
722
- new GDKAutoBuild.BuildInfo
737
+ new GDKLocalBuild.BuildInfo
723
738
  {
724
739
  target = BuildTarget.Android, isAAB = false, splitAPK = true
725
740
  }.Read(),
726
- new GDKAutoBuild.BuildInfo
741
+ new GDKLocalBuild.BuildInfo
727
742
  {
728
743
  target = BuildTarget.Android, isAAB = true, splitAPK = true
729
744
  }.Read(),
730
- new GDKAutoBuild.BuildInfo
745
+ new GDKLocalBuild.BuildInfo
731
746
  {
732
747
  target = BuildTarget.iOS, isAAB = true, splitAPK = true
733
748
  }.Read()
@@ -740,7 +755,7 @@ namespace Amanotes.Editor
740
755
  SerializedProperty prop = serializedObject.FindProperty($"listBuild.Array.data[{bIndex}]");
741
756
  prop.isExpanded = true;
742
757
 
743
- GDKAutoBuild.BuildInfo info = ab.listBuild[bIndex];
758
+ GDKLocalBuild.BuildInfo info = ab.listBuild[bIndex];
744
759
 
745
760
  EditorGUI.BeginChangeCheck();
746
761
  {
@@ -753,7 +768,7 @@ namespace Amanotes.Editor
753
768
  r.width = Screen.width;
754
769
  r.height = 16f;
755
770
 
756
- GDKAutoBuild.DrawRect(r, new Color32(20, 20, 20, 255));
771
+ GDKLocalBuild.DrawRect(r, new Color32(20, 20, 20, 255));
757
772
 
758
773
  r.xMin += 12f;
759
774
  GUI.Label(r, info.buildName);
@@ -782,7 +797,7 @@ namespace Amanotes.Editor
782
797
  var nBuilds = 0;
783
798
  for (var i = 0; i < ab.listBuild.Count; i++)
784
799
  {
785
- GDKAutoBuild.BuildInfo item = ab.listBuild[i];
800
+ GDKLocalBuild.BuildInfo item = ab.listBuild[i];
786
801
 
787
802
  if (!item.enable) continue;
788
803
  nBuilds++;
@@ -800,7 +815,7 @@ namespace Amanotes.Editor
800
815
  {
801
816
  if (GUILayout.Button("Build"))
802
817
  {
803
- ab.buildRQ = GDKAutoBuild.BuildRequestTS.Generate(); //ab.runGitPostBuild
818
+ ab.buildRQ = GDKLocalBuild.BuildRequestTS.Generate(); //ab.runGitPostBuild
804
819
  ab.ProcessBuild();
805
820
  }
806
821
 
Binary file
Binary file
Binary file
Binary file
Binary file
@@ -13,7 +13,7 @@ namespace Amanotes.Core.Internal
13
13
  [HideInInspector] [SerializeField] internal bool enabled = true;
14
14
  [NonSerialized] internal string adapterId;
15
15
  [NonSerialized] internal string adapterVersion;
16
- [NonSerialized] internal protected Status status = Status.None;
16
+ [NonSerialized] protected internal Status status = Status.None;
17
17
 
18
18
  protected abstract void Init(Action<bool> onComplete);
19
19
 
@@ -196,11 +196,11 @@ namespace Amanotes.Core
196
196
  // internal use
197
197
  internal static readonly AdsData localData = new AdsData().LoadJsonFromFile();
198
198
 
199
- internal protected static AdShowContext context;
200
- internal protected static AdAdapter _adapter;
201
- internal protected static float _savedVolume = -1;
202
- internal protected static float _savedTimeScale = -1;
203
-
199
+ protected internal static AdShowContext context;
200
+ protected internal static AdAdapter _adapter;
201
+ protected internal static float _savedVolume = -1;
202
+ protected internal static float _savedTimeScale = -1;
203
+
204
204
  public static void OnInter_Request(Action callback)
205
205
  {
206
206
  dispatcher.AddListener(Event.INTER_REQUEST, callback, false);
@@ -258,8 +258,8 @@ namespace Amanotes.Core
258
258
  }
259
259
  }
260
260
 
261
- public static bool HasInterstitial => _adapter.interstitial.hasAd;
262
- public static bool HasRewardedVideo => _adapter.rewardVideo.hasAd;
261
+ public static bool HasInterstitial => _adapter?.interstitial.hasAd ?? false;
262
+ public static bool HasRewardedVideo => _adapter?.rewardVideo.hasAd ?? false;
263
263
  public static bool IsBannerShowing => _isBannerShowing;
264
264
  public static bool IsAdShowing => context != null;
265
265
 
@@ -273,6 +273,7 @@ namespace Amanotes.Core
273
273
 
274
274
  public static IAdCallback ShowInterstitial(string placementName = null, Dictionary<string, object> userData = null)
275
275
  {
276
+ if (_adapter == null) return null;
276
277
  if (!ClearPrevContext()) return null;
277
278
 
278
279
  context = new AdShowContext(AdType.Interstitial, placementName, userData);
@@ -284,6 +285,7 @@ namespace Amanotes.Core
284
285
 
285
286
  public static IAdCallback ShowRewardedVideo(string placementName = null, Dictionary<string, object> userData = null)
286
287
  {
288
+ if (_adapter == null) return null;
287
289
  if (!ClearPrevContext()) return null;
288
290
 
289
291
  context = new AdShowContext(AdType.VideoReward, placementName, userData);
@@ -303,12 +305,8 @@ namespace Amanotes.Core
303
305
  _isBannerShowing = true;
304
306
  _showingBannerPosition = bannerPosition ?? Config.ad.bannerPosition;
305
307
 
306
- if (_adapter == null)
307
- {
308
- return;
309
- }
310
-
311
-
308
+ if (_adapter == null) return;
309
+
312
310
  dispatcher.Dispatch(Event.BANNER_SHOW);
313
311
  _adapter.ShowBanner(_showingBannerPosition);
314
312
  }
@@ -317,11 +315,13 @@ namespace Amanotes.Core
317
315
  {
318
316
  if (!_isBannerShowing) return;
319
317
  _isBannerShowing = false;
318
+ if (_adapter == null) return;
320
319
  _adapter.HideBanner();
321
320
  }
322
321
 
323
322
  public static void StopWaitForAd()
324
323
  {
324
+ if (_adapter == null) return;
325
325
  if (context == null)
326
326
  return;
327
327
 
@@ -357,6 +357,7 @@ namespace Amanotes.Core
357
357
 
358
358
  public static void SetUserId(string userId)
359
359
  {
360
+ if (_adapter == null) return;
360
361
  _adapter.SetUserId(userId);
361
362
  }
362
363
  }
@@ -397,14 +398,14 @@ namespace Amanotes.Core.Internal
397
398
  protected AdModuleConfig moduleConfig => Config.ad;
398
399
 
399
400
  // APIs
400
- internal protected abstract AdLogic interstitial { get; }
401
- internal protected abstract AdLogic rewardVideo { get; }
401
+ protected internal abstract AdLogic interstitial { get; }
402
+ protected internal abstract AdLogic rewardVideo { get; }
402
403
 
403
404
  public abstract void ShowBanner(BannerPosition bannerPosition);
404
405
  public abstract void HideBanner();
405
406
 
406
407
  // Internally used
407
- internal protected abstract void SetUserId(string userId);
408
+ protected internal abstract void SetUserId(string userId);
408
409
  }
409
410
 
410
411
  public interface IAdCallback { }
@@ -504,7 +505,6 @@ namespace Amanotes.Core.Internal
504
505
 
505
506
  public abstract class AdLogic
506
507
  {
507
- internal protected AdAdapter adapter => Ads._adapter;
508
508
  protected AdModuleConfig adConfig => Config.ad;
509
509
  protected AdShowContext context => Ads.context;
510
510
 
@@ -1,4 +1,5 @@
1
1
  using System;
2
+ using System.Collections.Concurrent;
2
3
  using System.Collections.Generic;
3
4
  using System.Text;
4
5
  using System.Text.RegularExpressions;
@@ -39,10 +40,7 @@ namespace Amanotes.Core
39
40
  this.eventName = eventName;
40
41
  }
41
42
 
42
- public bool IsFunnelEvent
43
- {
44
- get { return !string.IsNullOrEmpty(funnelSignature); }
45
- }
43
+ public bool IsFunnelEvent => !string.IsNullOrEmpty(funnelSignature);
46
44
 
47
45
  public bool IsAdapterForbidden(string adapterId)
48
46
  {
@@ -71,31 +69,22 @@ namespace Amanotes.Core
71
69
 
72
70
  public static IEventParamsBuilder LogEvent(string eventName)
73
71
  {
74
- NormalizeEventName(ref eventName, true);
75
- if (localData.GetEventDetail(eventName) == null && localData.eventDetails.Count >= 500)
76
- {
77
- LogWarning($" - You have reported 500 types of events. New event <{eventName}> will be ignored.");
78
- return null;
79
- }
80
- var result = new EventParams(eventName);
72
+ var result = PrepareEvent(eventName);
81
73
  eventQueue.Enqueue(result);
82
74
  return result;
83
75
  }
84
76
 
85
77
  public static IEventParamsBuilder LogEvent(string eventName, Dictionary<string, object> parameters)
86
78
  {
87
- if (parameters == null) return LogEvent(eventName);
88
- return LogEvent(eventName).AddParam(parameters);
79
+ var result = PrepareEvent(eventName, parameters);
80
+ eventQueue.Enqueue(result);
81
+ return result;
89
82
  }
90
83
 
91
84
  public static IEventParamsBuilder LogEvent(string eventName, params (string, object)[] parameters)
92
85
  {
93
- IEventParamsBuilder result = LogEvent(eventName);
94
- if (parameters == null) return result;
95
- for (var i = 0; i < parameters.Length; i++)
96
- {
97
- result.AddParam(parameters[i].Item1, parameters[i].Item2);
98
- }
86
+ var result = PrepareEvent(eventName, parameters);
87
+ eventQueue.Enqueue(result);
99
88
  return result;
100
89
  }
101
90
 
@@ -113,6 +102,24 @@ namespace Amanotes.Core
113
102
  {
114
103
  return LogEvent(eventName, parameters).SetAsFunnel(signature);
115
104
  }
105
+
106
+ public static void LogEventImmediately(string eventName)
107
+ {
108
+ var eventParams = PrepareEvent(eventName);
109
+ LogEventImmediately(eventParams);
110
+ }
111
+
112
+ public static void LogEventImmediately(string eventName, Dictionary<string, object> parameters)
113
+ {
114
+ var eventParams = PrepareEvent(eventName, parameters);
115
+ LogEventImmediately(eventParams);
116
+ }
117
+
118
+ public static void LogEventImmediately(string eventName, params (string, object)[] parameters)
119
+ {
120
+ var eventParams = PrepareEvent(eventName, parameters);
121
+ LogEventImmediately(eventParams);
122
+ }
116
123
 
117
124
  public static int GetAccumulatedCount(string eventName, bool withinSession = false)
118
125
  {
@@ -128,12 +135,18 @@ namespace Amanotes.Core
128
135
 
129
136
  public static void SetUserId(string userId)
130
137
  {
131
- actionQueue.Enqueue(() => InternalSetUserId(userId));
138
+ foreach (AnalyticsAdapter s in listAdapters)
139
+ {
140
+ s.SetUserId(userId);
141
+ }
132
142
  }
133
143
 
134
144
  public static void SetUserProperty(string key, string value)
135
145
  {
136
- actionQueue.Enqueue(() => InternalSetUserProperty(key, value));
146
+ foreach (AnalyticsAdapter s in listAdapters)
147
+ {
148
+ s.SetUserProperty(key, value);
149
+ }
137
150
  }
138
151
 
139
152
  private static IntegrityFlag MergeData(List<string> funnelEvents, Dictionary<string, int> eventCountMap, bool sumEventCount)
@@ -237,8 +250,7 @@ namespace Amanotes.Core
237
250
 
238
251
  internal static readonly Dictionary<string, EventConfig> sendAtCount = new Dictionary<string, EventConfig>();
239
252
  internal static Predicate<EventParams> logEventHook;
240
- internal static readonly Queue<EventParams> eventQueue = new Queue<EventParams>();
241
- internal static readonly Queue<Action> actionQueue = new Queue<Action>();
253
+ internal static readonly ConcurrentQueue<EventParams> eventQueue = new ConcurrentQueue<EventParams>();
242
254
  internal static readonly List<AnalyticsAdapter> listAdapters = new List<AnalyticsAdapter>();
243
255
  internal static readonly AnalyticsData localData = new AnalyticsData().LoadJsonFromFile();
244
256
  internal static readonly SessionStat sessionStat = new SessionStat();
@@ -298,68 +310,109 @@ namespace Amanotes.Core
298
310
  // TODO: Refactor Resolve Early Calls
299
311
  onFrameUpdate -= ProcessEventQueue;
300
312
  onFrameUpdate += ProcessEventQueue;
301
-
302
- onFrameUpdate -= ProcessActionQueue;
303
- onFrameUpdate += ProcessActionQueue;
304
313
  }
305
-
314
+
315
+ internal static EventParams PrepareEvent(string eventName)
316
+ {
317
+ PrepareEventCheck(eventName);
318
+ var result = new EventParams(eventName);
319
+ PostPrepareEventProcess(result);
320
+ return result;
321
+ }
322
+
323
+ internal static EventParams PrepareEvent(string eventName, Dictionary<string, object> parameters)
324
+ {
325
+ if (parameters == null) return PrepareEvent(eventName);
326
+ PrepareEventCheck(eventName);
327
+ var result = new EventParams(eventName);
328
+ result.AddParam(parameters);
329
+ PostPrepareEventProcess(result);
330
+ return result;
331
+ }
332
+
333
+ internal static EventParams PrepareEvent(string eventName, params (string, object)[] parameters)
334
+ {
335
+ if (parameters == null) return PrepareEvent(eventName);
336
+ PrepareEventCheck(eventName);
337
+ var result = new EventParams(eventName);
338
+ for (var i = 0; i < parameters.Length; i++)
339
+ {
340
+ result.AddParam(parameters[i].Item1, parameters[i].Item2);
341
+ }
342
+ PostPrepareEventProcess(result);
343
+ return result;
344
+ }
345
+
306
346
  internal static void ProcessEventQueue()
307
347
  {
308
348
  if (eventQueue.Count <= 0) return;
309
349
 
310
350
  Profiler.BeginSample("AmaGDK.Analytics.ProcessEventQueue()");
311
- AnalyticsConfig config = Config.analytics;
312
- bool showAnalyticsLog = config.showAnalyticsLog;
313
- sessionStat.ClearLastFrameEventInfo();
351
+
352
+ sessionStat.savedEventStatsInLastFrame.Clear();
353
+
354
+ while (eventQueue.TryDequeue(out var eventData))
355
+ {
356
+ var (eventNameToSend, inUseAdapterIDs) = LogEventActually(eventData);
357
+ if (string.IsNullOrEmpty(eventNameToSend) || inUseAdapterIDs == null) continue;
358
+ sessionStat.Add(eventNameToSend, eventData, inUseAdapterIDs);
359
+ }
360
+
361
+ localData.SaveIfDirty();
362
+ sessionStat.Save();
363
+ Profiler.EndSample();
364
+ }
314
365
 
315
- while (eventQueue.Count > 0)
366
+ internal static (string eventNameToSend, List<string> inUseAdapterIDs) LogEventActually(EventParams eventParams)
367
+ {
368
+ if (eventParams == null) return ("", null);
369
+ if (!ShouldSendEvent(eventParams)) return ("", null);
370
+ var (countInSession, totalCount) = localData.IncreaseCounter(eventParams);
371
+ if (eventParams.accumulated || eventParams.parameters.ContainsKey("accumulated_count"))
316
372
  {
317
- var eventData = eventQueue.Dequeue();
318
- if (!ShouldSendEvent(eventData)) continue;
319
-
320
- var (countInSession, totalCount) = localData.IncreaseCounter(eventData);
321
- if (eventData.accumulated || eventData.parameters.ContainsKey("accumulated_count"))
322
- {
323
- UpdateAccumulatedCount(eventData, countInSession, totalCount);
324
- }
373
+ UpdateAccumulatedCount(eventParams, countInSession, totalCount);
374
+ }
375
+
376
+ string eventNameToSend = GetEventNameToSend(eventParams.eventName, countInSession, totalCount);
377
+ AnalyticsConfig config = Config.analytics;
378
+ if (config.normalizeEventName) NormalizeEventName(ref eventNameToSend);
325
379
 
326
- if (!eventData.parameters.ContainsKey("ama_device_id"))
327
- eventData.AddParam("ama_device_id", User.AmaDeviceId);
380
+ if (config.showAnalyticsLog)
381
+ {
382
+ Debug.Log($"AmaGDK [Analytics] Event <{eventNameToSend}> (in session: {countInSession}, total: {totalCount})\n{JsonUtils.DictionaryToJson(eventParams.parameters, true)}");
383
+ }
328
384
 
329
- string eventNameToSend = GetEventNameToSend(eventData.eventName, countInSession, totalCount);
330
- if (config.normalizeEventName) NormalizeEventName(ref eventNameToSend);
385
+ config.quality.CheckEventQuality(eventParams.eventName, eventParams.parameters);
331
386
 
332
- if (showAnalyticsLog)
387
+ var inUseAdapterIDs = new List<string>();
388
+ foreach (AnalyticsAdapter m in listAdapters)
389
+ {
390
+ if (eventParams.overrideConfig)
333
391
  {
334
- Debug.Log($"AmaGDK [Analytics] Event <{eventNameToSend}> (in session: {countInSession}, total: {totalCount})\n{JsonUtils.DictionaryToJson(eventData.parameters, true)}");
392
+ // IMPORTANT NOTE:
393
+ //
394
+ // Once set overrideConfig, we should skip the adapter config completely!!!
395
+ //
396
+ if (eventParams.IsAdapterForbidden(m.adapterId)) continue;
335
397
  }
336
-
337
- config.quality.CheckEventQuality(eventData.eventName, eventData.parameters);
338
-
339
- var inUseAdapterIDs = new List<string>();
340
- foreach (AnalyticsAdapter m in listAdapters)
398
+ else // Do not remove else
341
399
  {
342
- if (eventData.overrideConfig)
343
- {
344
- // IMPORTANT NOTE:
345
- //
346
- // Once set overrideConfig, we should skip the adapter config completely!!!
347
- //
348
- if (eventData.IsAdapterForbidden(m.adapterId)) continue;
349
- }
350
- else // Do not remove else
351
- {
352
- if (m.IsForbidden(eventData.eventName)) continue;
353
- }
354
- m.LogEvent(eventNameToSend, eventData.parameters);
355
- inUseAdapterIDs.Add(m.adapterId);
400
+ if (m.IsForbidden(eventParams.eventName)) continue;
356
401
  }
357
- sessionStat.Add(eventNameToSend, eventData, inUseAdapterIDs);
402
+ m.LogEvent(eventNameToSend, eventParams.parameters);
403
+ inUseAdapterIDs.Add(m.adapterId);
358
404
  }
359
405
 
360
- localData.SaveIfDirty();
406
+ return (eventNameToSend, inUseAdapterIDs);
407
+ }
408
+
409
+ internal static void LogEventImmediately(EventParams eventParams)
410
+ {
411
+ var (eventNameToSend, inUseAdapterIDs) = LogEventActually(eventParams);
412
+ if (string.IsNullOrEmpty(eventNameToSend) || inUseAdapterIDs == null) return;
413
+ sessionStat.Add(eventNameToSend, eventParams, inUseAdapterIDs);
361
414
  sessionStat.Save();
362
- Profiler.EndSample();
415
+ localData.SaveIfDirty();
363
416
  }
364
417
 
365
418
  internal static void UpdateAccumulatedCount(EventParams eventData, int countInSession, int totalCount)
@@ -411,7 +464,7 @@ namespace Amanotes.Core
411
464
 
412
465
  internal static void NormalizeKeyString(ref string key, StringBuilder warningLog, bool dryRun)
413
466
  {
414
- Profiler.BeginSample("AmaGDK.Analytics.NormalizeEventName()");
467
+ Profiler.BeginSample("AmaGDK.Analytics.NormalizeKeyString()");
415
468
  {
416
469
  if (string.IsNullOrWhiteSpace(key))
417
470
  {
@@ -465,6 +518,22 @@ namespace Amanotes.Core
465
518
  }
466
519
  Profiler.EndSample();
467
520
  }
521
+
522
+ internal static void PrepareEventCheck(string eventName)
523
+ {
524
+ NormalizeEventName(ref eventName, true);
525
+
526
+ if (localData.GetEventDetail(eventName) == null && localData.eventDetails.Count >= 500)
527
+ {
528
+ LogWarning($" - You have reported 500 types of events. New event <{eventName}> will be ignored.");
529
+ }
530
+ }
531
+
532
+ internal static void PostPrepareEventProcess(EventParams eventData)
533
+ {
534
+ if (!eventData.parameters.ContainsKey("ama_device_id"))
535
+ eventData.AddParam("ama_device_id", User.AmaDeviceId);
536
+ }
468
537
 
469
538
  internal static bool ShouldSendEvent(EventParams eventData)
470
539
  {
@@ -489,33 +558,6 @@ namespace Amanotes.Core
489
558
 
490
559
  return true;
491
560
  }
492
-
493
-
494
- internal static void ProcessActionQueue()
495
- {
496
- if (actionQueue.Count <= 0) return;
497
- while (actionQueue.Count > 0)
498
- {
499
- var action = actionQueue.Dequeue();
500
- action.Invoke();
501
- }
502
- }
503
-
504
- internal static void InternalSetUserId(string userId)
505
- {
506
- foreach (AnalyticsAdapter s in listAdapters)
507
- {
508
- s.SetUserId(userId);
509
- }
510
- }
511
-
512
- internal static void InternalSetUserProperty(string key, string value)
513
- {
514
- foreach (AnalyticsAdapter s in listAdapters)
515
- {
516
- s.SetUserProperty(key, value);
517
- }
518
- }
519
561
  }
520
562
 
521
563
  //PERSISTENT DATA
@@ -645,7 +687,7 @@ namespace Amanotes.Core
645
687
  migrationLog.count++;
646
688
  Log($"Analytics data was migrated {migrationLog.count} times");
647
689
 
648
- if (migrationLog.count == 2) LogEvent("migration_error").AddParam(migrationLog.ToDictionary());
690
+ if (migrationLog.count == 2) LogEvent("migration_error", migrationLog.ToDictionary());
649
691
  }
650
692
 
651
693
  _dirty = true;
@@ -659,17 +701,13 @@ namespace Amanotes.Core
659
701
  private readonly string fileName = nameof(SessionStat) + DateTime.Now.ToString("_yyMMdd_HHmmss") + ".tsv";
660
702
  private StringBuilder contents = new StringBuilder();
661
703
  private bool isFirstSave = true;
662
- public List<EventStat> lastFrameEventStats = new List<EventStat>();
704
+ private readonly ConcurrentQueue<EventStat> lastFrameEventStats = new ConcurrentQueue<EventStat>();
705
+ internal readonly ConcurrentQueue<EventStat> savedEventStatsInLastFrame = new ConcurrentQueue<EventStat>();
663
706
 
664
707
  internal void Add(string eventNameToSend, EventParams eventParams, List<string> adapterIDs)
665
708
  {
666
709
  var eventStat = new EventStat(eventNameToSend, eventParams, adapterIDs);
667
- lastFrameEventStats.Add(eventStat);
668
- }
669
-
670
- internal void ClearLastFrameEventInfo()
671
- {
672
- lastFrameEventStats.Clear();
710
+ lastFrameEventStats.Enqueue(eventStat);
673
711
  }
674
712
 
675
713
  internal void Save()
@@ -682,14 +720,17 @@ namespace Amanotes.Core
682
720
  contents = contents.AppendLine(TSV_HEADER_ROW);
683
721
  isFirstSave = false;
684
722
  }
685
- foreach (EventStat stat in lastFrameEventStats)
723
+ while (lastFrameEventStats.TryDequeue(out var stat))
686
724
  {
687
725
  contents.AppendLine(stat.ToTsv());
726
+ savedEventStatsInLastFrame.Enqueue(stat);
688
727
  }
689
728
 
690
729
  GDKFileUtils.SaveAppend(fileName, contents.ToString());
691
730
  }
692
731
  }
732
+
733
+
693
734
  }
694
735
  }
695
736
 
@@ -771,7 +812,7 @@ namespace Amanotes.Core
771
812
  return ap;
772
813
  }
773
814
 
774
- public static IEventParamsBuilder AddParam(this IEventParamsBuilder ap, string key, object value)
815
+ internal static IEventParamsBuilder AddParam(this IEventParamsBuilder ap, string key, object value)
775
816
  {
776
817
  if (ap == null) return null;
777
818
  if (!IsValidKeyValue(ap, ref key, ref value)) return ap;
@@ -795,7 +836,7 @@ namespace Amanotes.Core
795
836
  return ap;
796
837
  }
797
838
 
798
- public static IEventParamsBuilder AddParam(this IEventParamsBuilder ap, Dictionary<string, object> dictParams)
839
+ internal static IEventParamsBuilder AddParam(this IEventParamsBuilder ap, Dictionary<string, object> dictParams)
799
840
  {
800
841
  if (ap == null) return null;
801
842
  if (dictParams == null)
@@ -814,7 +855,7 @@ namespace Amanotes.Core
814
855
  return ap;
815
856
  }
816
857
 
817
- public static IEventParamsBuilder AddParam(this IEventParamsBuilder ap, params (string key, object value)[] parameters)
858
+ internal static IEventParamsBuilder AddParam(this IEventParamsBuilder ap, params (string key, object value)[] parameters)
818
859
  {
819
860
  if (ap == null) return null;
820
861
  if (parameters.Length == 0)
@@ -200,14 +200,14 @@ namespace Amanotes.Core
200
200
  #elif UNITY_IOS
201
201
  IDFV = SystemInfo.deviceUniqueIdentifier;
202
202
  #endif
203
-
204
- // Always get the latest advertising id
205
- GetAdvertisingId();
203
+ GetAmaDeviceId();
204
+ UpdateUserId();
206
205
  }
207
206
 
208
207
  internal void StartModule()
209
208
  {
210
- UpdateUserId();
209
+ // Always get the latest advertising id
210
+ GetAdvertisingId();
211
211
  Logging.Log($"[UserProfile] user_id: {_userId}");
212
212
  }
213
213
 
@@ -231,39 +231,43 @@ namespace Amanotes.Core
231
231
  GDKUtils.DelayCall(0, () =>
232
232
  {
233
233
  SetAdvertisingID(advertisingId);
234
- switch (Application.platform)
235
- {
236
- case RuntimePlatform.IPhonePlayer:
237
- string v = KeyChain.GetKeyChain(AMA_DEVICE_ID_KEY);
238
- if (string.IsNullOrEmpty(v))
239
- {
240
- v = Guid.NewGuid().ToString();
241
- KeyChain.SetKeyChain(AMA_DEVICE_ID_KEY, v);
242
- }
243
- AmaDeviceId = v;
244
- break;
245
-
246
- case RuntimePlatform.Android:
247
- string cachedAmaDeviceId = PlayerPrefs.GetString(AMA_DEVICE_ID_KEY);
248
- if (string.IsNullOrEmpty(cachedAmaDeviceId))
249
- {
250
- cachedAmaDeviceId = SystemInfo.deviceUniqueIdentifier;
251
- PlayerPrefs.SetString(AMA_DEVICE_ID_KEY, cachedAmaDeviceId);
252
- }
253
- AmaDeviceId = cachedAmaDeviceId;
254
- break;
255
-
256
- default:
257
- AmaDeviceId = SystemInfo.deviceUniqueIdentifier;
258
- break;
259
- }
260
-
261
- Logging.Log($"[UserProfile] ama_device_id: {_amaDeviceId}");
262
234
  Save();
263
235
  });
264
236
  });
265
237
  }
266
238
 
239
+ private void GetAmaDeviceId()
240
+ {
241
+ if (!string.IsNullOrEmpty(AmaDeviceId)) return;
242
+ switch (Application.platform)
243
+ {
244
+ case RuntimePlatform.IPhonePlayer:
245
+ string v = KeyChain.GetKeyChain(AMA_DEVICE_ID_KEY);
246
+ if (string.IsNullOrEmpty(v))
247
+ {
248
+ v = Guid.NewGuid().ToString();
249
+ KeyChain.SetKeyChain(AMA_DEVICE_ID_KEY, v);
250
+ }
251
+ AmaDeviceId = v;
252
+ break;
253
+
254
+ case RuntimePlatform.Android:
255
+ string cachedAmaDeviceId = PlayerPrefs.GetString(AMA_DEVICE_ID_KEY);
256
+ if (string.IsNullOrEmpty(cachedAmaDeviceId))
257
+ {
258
+ cachedAmaDeviceId = SystemInfo.deviceUniqueIdentifier;
259
+ }
260
+ AmaDeviceId = cachedAmaDeviceId;
261
+ break;
262
+
263
+ default:
264
+ AmaDeviceId = SystemInfo.deviceUniqueIdentifier;
265
+ break;
266
+ }
267
+ Logging.Log($"[UserProfile] Generate ama_device_id: {_amaDeviceId}");
268
+ Save();
269
+ }
270
+
267
271
  private string ValidateId (string id, string pattern)
268
272
  {
269
273
  if (string.IsNullOrWhiteSpace(id)) return null;
package/Runtime/AmaGDK.cs CHANGED
@@ -17,7 +17,7 @@ namespace Amanotes.Core
17
17
  {
18
18
  public partial class AmaGDK : MonoBehaviour
19
19
  {
20
- public const string VERSION = "0.2.50";
20
+ public const string VERSION = "0.2.51";
21
21
 
22
22
  internal static AmaGDK _instance;
23
23
  internal static Status _status = Status.None;
@@ -182,12 +182,12 @@ namespace Amanotes.Core
182
182
  }
183
183
 
184
184
  float startTime = Time.realtimeSinceStartup;
185
- yield return InitHook();
186
185
 
187
186
  dispatcher.Dispatch(Event.GDK_INIT_START);
188
187
  var sb = new StringBuilder();
189
188
  InitModules();
190
189
 
190
+ yield return InitHook();
191
191
  yield return WaitForManualInit();
192
192
  yield return InitAdapters(sb);
193
193
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "com.amanotes.gdk",
3
- "version": "0.2.50",
3
+ "version": "0.2.51",
4
4
  "displayName": "AmaGDK",
5
5
  "description": "Amanotes Game Development Kit",
6
6
  "unity": "2019.4",