com.amanotes.gdk 0.2.8 → 0.2.10

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,21 @@
1
1
  # Changelog
2
2
 
3
+ ## [0.2.10 - 2023-06-23]
4
+ ### Extra package: Project Panel
5
+ ### Remote config: Allow user to enable / disable automatic default valuye updating (in play mode)
6
+ ### Fix ad routine
7
+ ### Expose analytics migration flag
8
+
9
+ ## [0.2.9 - 2023-06-15]
10
+ ### Show total init time
11
+ ### Show adapter version + status at init time
12
+ ### Remove AmaGDK version in debug log
13
+ ### Remove "Params" in analytics debug log
14
+ ### Check "event_name" early
15
+ ### Fix null exception in AmaGDKInstaller
16
+ ### Add csc.rsp to enable AMAGDK_DEV
17
+ ### Update Ads module
18
+
3
19
  ## [0.2.8 - 2023-06-12]
4
20
  ### Mute Appsflyer's init log on Editor
5
21
  ### Clear analytics log in adapters
Binary file
Binary file
@@ -0,0 +1,7 @@
1
+ fileFormatVersion: 2
2
+ guid: 26e42be832082494fb3eb94a4d9cd300
3
+ DefaultImporter:
4
+ externalObjects: {}
5
+ userData:
6
+ assetBundleName:
7
+ assetBundleVariant:
Binary file
Binary file
Binary file
@@ -110,6 +110,9 @@ namespace Amanotes.Core
110
110
  public bool enableRewarded = true;
111
111
  public bool enableBanner = true;
112
112
  public bool autoMute = true;
113
+
114
+ [Header("EDITOR")]
115
+ [Range(0f, 1f)] public float rewardAdShowSuccessRate = 1;
113
116
  }
114
117
 
115
118
  public partial class Ads
@@ -119,9 +122,10 @@ namespace Amanotes.Core
119
122
 
120
123
  internal static AdAdapterConfig _adConfig;
121
124
  internal static IAdAdapter _adapter;
122
- public static AdListener Events = new AdListener();
123
125
  internal static float _savedVolume = -1;
124
- internal static AdsData localData = new AdsData().LoadJsonFromFile();
126
+
127
+ public static readonly AdListener Events = new AdListener();
128
+ internal static readonly AdsData localData = new AdsData().LoadJsonFromFile();
125
129
  }
126
130
 
127
131
  public partial class Ads // Public
@@ -134,16 +138,38 @@ namespace Amanotes.Core
134
138
  _adapter?.rewardVideo.StartLoadAd();
135
139
  }
136
140
 
137
- public static bool HasInterstitial => _adapter.interstitial.hasAd;
138
- public static bool HasRewardedVideo => _adapter.rewardVideo.hasAd;
141
+ public static bool hasInterstitial => _adapter.interstitial.hasAd;
142
+ public static bool hasRewardedVideo => _adapter.rewardVideo.hasAd;
143
+ public static bool showingBanner => _showingBanner;
144
+ public static bool showingAd => context != null;
139
145
 
140
- public static IAdCallback ShowInterstitial(string placementName = null, Dictionary<string, object> userData = null)
146
+ private static bool ClearPrevContext()
141
147
  {
142
- if (context != null)
148
+ if (context == null) return true;
149
+ float duration = Time.realtimeSinceStartup - context.showCallAt;
150
+ bool willSkip = duration < Mathf.Max(5f, _adConfig.adShowTimeoutInSecs);
151
+ if (willSkip)
152
+ {
153
+ LogWarning($"[AD] ShowRequest IGNORED as another ad is showing (elapsedTime: {duration:n2}s):\n" + JsonUtility.ToJson(context, true));
154
+ return false;
155
+ }
156
+
157
+ LogWarning($"[AD] FORCE STOPPED the previous ad, as it seems to hang (elapsedTime: {duration:n2}s):\n" + JsonUtility.ToJson(context, true));
158
+ // possibly hang: force stop
159
+ if (context.adType == AdType.Interstitial)
160
+ {
161
+ _adapter.interstitial.StopShowAd();
162
+ } else
143
163
  {
144
- LogWarning("Context != null, might some ad be showing???");
145
- context = null;
164
+ _adapter.rewardVideo.StopShowAd();
146
165
  }
166
+ context = null;
167
+ return true;
168
+ }
169
+
170
+ public static IAdCallback ShowInterstitial(string placementName = null, Dictionary<string, object> userData = null)
171
+ {
172
+ if (!ClearPrevContext()) return null;
147
173
 
148
174
  context = new ShowAdContext(AdType.Interstitial, placementName, userData);
149
175
  _adapter.interstitial.StartShowAd();
@@ -152,18 +178,14 @@ namespace Amanotes.Core
152
178
 
153
179
  public static IAdCallback ShowRewardedVideo(string placementName = null, Dictionary<string, object> userData = null)
154
180
  {
155
- if (context != null)
156
- {
157
- LogWarning("Context != null, might some ad be showing???");
158
- context = null;
159
- }
160
-
181
+ if (!ClearPrevContext()) return null;
182
+
161
183
  context = new ShowAdContext(AdType.VideoReward, placementName, userData);
162
184
  _adapter.rewardVideo.StartShowAd();
163
185
  return context;
164
186
  }
165
187
 
166
- private static bool _showingBanner = false;
188
+ private static bool _showingBanner;
167
189
  public static void ShowBanner()
168
190
  {
169
191
  if (_showingBanner) return;
@@ -225,16 +247,16 @@ namespace Amanotes.Core.Internal
225
247
  [Flags]
226
248
  public enum AdCallback
227
249
  {
228
- None,
229
- Open,
230
- Reward,
231
- Click,
232
- Cancel,
233
- Close,
234
- Success,
235
- Fail
250
+ None = 0,
251
+ Open = 1,
252
+ Reward = 2,
253
+ Click = 4,
254
+ Cancel = 8,
255
+ Close = 16,
256
+ Success = 32,
257
+ Fail = 64
236
258
  }
237
-
259
+
238
260
  public enum BannerPosition
239
261
  {
240
262
  TOP = 1,
@@ -272,14 +294,14 @@ namespace Amanotes.Core.Internal
272
294
  this.userData = userData;
273
295
  this.placementName = placementName;
274
296
  adCallback = AdCallback.None;
275
- showCallAt = Time.time;
297
+ showCallAt = Time.realtimeSinceStartup;
276
298
  showFinishAt = 0;
277
299
  }
278
300
 
279
- public bool hasError => (adCallback & (AdCallback.Fail | AdCallback.Cancel)) != 0;
280
- public bool hasCompleted => (adCallback & (AdCallback.Close | AdCallback.Reward | AdCallback.Cancel)) != 0;
301
+ public bool hasFailedOrCancelled => (adCallback & (AdCallback.Fail | AdCallback.Cancel)) != 0;
302
+ public bool potentiallyCompleted => (adCallback & (AdCallback.Close | AdCallback.Fail | AdCallback.Reward | AdCallback.Cancel)) != 0;
281
303
  public bool hasReward => (adCallback & AdCallback.Reward) != 0;
282
- public bool hasCancel => (adCallback & AdCallback.Cancel) != 0;
304
+ public bool hasClosed => (adCallback & AdCallback.Close) != 0;
283
305
  public bool hasClicked => (adCallback & AdCallback.Click) != 0;
284
306
  }
285
307
 
@@ -300,18 +322,19 @@ namespace Amanotes.Core.Internal
300
322
  return;
301
323
  }
302
324
 
325
+ Log("StartLoadAd");
303
326
  _loadRoutine = _instance.StartCoroutine(LoadAdRoutine());
304
327
  }
305
-
328
+
306
329
  public void StopLoadAd()
307
330
  {
331
+ Log("StopLoadAd");
308
332
  if (_loadState == LoadAdsState.Requesting)
309
333
  {
310
334
  _loadState = LoadAdsState.None;
311
335
  }
312
-
336
+
313
337
  if (_loadRoutine == null) return;
314
-
315
338
  _instance.StopCoroutine(_loadRoutine);
316
339
  _loadRoutine = null;
317
340
  }
@@ -335,7 +358,7 @@ namespace Amanotes.Core.Internal
335
358
  _isRequesting = true;
336
359
  RequestAd();
337
360
 
338
- var timeout = Ads._adConfig.adLoadTimeoutInSecs;
361
+ int timeout = Ads._adConfig.adLoadTimeoutInSecs;
339
362
  var counter = 0;
340
363
 
341
364
  while (counter < timeout || timeout == 0)
@@ -374,15 +397,16 @@ namespace Amanotes.Core.Internal
374
397
  internal ShowAdsState _showState = ShowAdsState.None;
375
398
  private Coroutine _showAdRoutine;
376
399
  private bool _isRequesting;
377
- internal bool isInterstitial => Ads.context.adType == AdType.Interstitial;
400
+ private bool _isInterstitial => adType == AdType.Interstitial;
378
401
 
379
402
  public void StartShowAd()
380
403
  {
381
404
  if (_showState != ShowAdsState.None)
382
405
  {
383
- LogWarning("StartShowAd() --> Invalid _showState: " + _showState);
406
+ LogWarning("[Ad] StartShowAd() --> Invalid _showState: " + _showState);
384
407
  }
385
-
408
+
409
+ Log($"[Ad] {adType} StartShowAd");
386
410
  _showState = ShowAdsState.ShowCalled;
387
411
  if (_showAdRoutine != null) _instance.StopCoroutine(_showAdRoutine);
388
412
  _showAdRoutine = _instance.StartCoroutine(ShowAdRoutine());
@@ -390,6 +414,7 @@ namespace Amanotes.Core.Internal
390
414
 
391
415
  public void StopShowAd()
392
416
  {
417
+ Log($"[Ad] {adType} StopShowAd");
393
418
  _showState = ShowAdsState.None;
394
419
  RestoreVolume();
395
420
  if (_showAdRoutine == null) return;
@@ -404,20 +429,21 @@ namespace Amanotes.Core.Internal
404
429
  {
405
430
  if (_loadState == LoadAdsState.Ready)
406
431
  {
407
- LogWarning("Inconsistent state report: isAdReady == false while _loadState == Ready");
432
+ LogWarning("[Ad] Inconsistent state report: isAdReady == false while _loadState == Ready");
408
433
  _loadState = LoadAdsState.None;
409
434
  }
410
435
 
411
436
  if (Ads._adConfig.checkInternet && !hasInternet)
412
437
  {
413
438
  _showState = ShowAdsState.ShowFail;
439
+ ShowAdRoutineCompleted(false);
414
440
  yield break;
415
441
  }
416
442
 
417
443
  if (_loadState != LoadAdsState.Requesting) StartLoadAd();
418
444
  _showState = ShowAdsState.WaitForAd;
419
445
 
420
- var timeout = Ads._adConfig.adShowTimeoutInSecs;
446
+ int timeout = Ads._adConfig.adShowTimeoutInSecs;
421
447
  var counter = 0;
422
448
 
423
449
  while (counter < timeout || timeout == 0)
@@ -429,11 +455,13 @@ namespace Amanotes.Core.Internal
429
455
 
430
456
  if (!isAdReady)
431
457
  {
432
- _showState = ShowAdsState.ShowFail;
458
+ Ads.Events.OnShowTimeout?.Invoke();
459
+ ShowAdRoutineCompleted(false);
433
460
  yield break;
434
461
  }
435
462
  }
436
-
463
+
464
+ _showState = ShowAdsState.Showing;
437
465
  // Ad should be ready here!
438
466
  ShowAd();
439
467
  if (Ads._adConfig.autoMute && AudioListener.volume > 0 && Ads._savedVolume == -1)
@@ -441,42 +469,61 @@ namespace Amanotes.Core.Internal
441
469
  Ads._savedVolume = AudioListener.volume;
442
470
  AudioListener.volume = 0;
443
471
  }
444
-
445
- var context = Ads.context;
446
- while (!context.hasCompleted)
472
+
473
+ ShowAdContext context = Ads.context;
474
+ while (!context.potentiallyCompleted)
447
475
  {
448
476
  yield return wait1Sec;
449
477
  }
450
478
 
451
479
  if (adType == AdType.Interstitial)
452
480
  {
453
- _showState = context.hasError ? ShowAdsState.ShowFail : ShowAdsState.ShowSuccess;
454
- ShowCompleted(_showState == ShowAdsState.ShowSuccess);
481
+ ShowAdRoutineCompleted(!context.hasFailedOrCancelled);
482
+ yield break;
483
+ }
484
+
485
+ if (context.hasFailedOrCancelled)
486
+ {
487
+ Log($"[Ad] {adType} Waiting for [close]");
488
+ yield return wait1Sec; // wait for close (1s)
489
+ ShowAdRoutineCompleted(false);
490
+ yield break;
491
+ }
492
+
493
+ if (context.hasClosed)
494
+ {
495
+ while (!context.hasFailedOrCancelled && !context.hasReward)
496
+ {
497
+ Log($"[Ad] {adType} Waiting for [cancel] or [reward]");
498
+ yield return wait1Sec;
499
+ }
500
+
501
+ ShowAdRoutineCompleted(!context.hasFailedOrCancelled);
455
502
  yield break;
456
503
  }
457
504
 
458
- // Should be rewardedVideo
459
- if (!context.hasReward && !context.hasCancel) // no reward & no cancel: wait for the delayed reward callback
505
+ while (!context.hasClosed)
460
506
  {
507
+ Log($"[Ad] {adType} Waiting for [close]");
461
508
  yield return wait1Sec;
462
509
  }
463
510
 
464
- _showState = context.hasError ? ShowAdsState.ShowFail : ShowAdsState.ShowSuccess;
465
- ShowCompleted(_showState == ShowAdsState.ShowSuccess);
511
+ ShowAdRoutineCompleted(true);
466
512
  }
467
513
 
468
- private void ShowCompleted(bool isSuccess)
514
+ private void ShowAdRoutineCompleted(bool isSuccess)
469
515
  {
470
- bool isInterstitial = adType == AdType.Interstitial;
471
- var adapter = Ads._adapter;
472
- if (isInterstitial)
473
- adapter.interstitial.StartLoadAd();
474
- else
475
- adapter.rewardVideo.StartLoadAd();
516
+ if (_loadState == LoadAdsState.Ready)
517
+ {
518
+ _loadState = isAdReady ? LoadAdsState.Ready : LoadAdsState.None;
519
+ if (_loadState == LoadAdsState.None) StartLoadAd();
520
+ }
521
+
522
+ _showState = isSuccess ? ShowAdsState.ShowSuccess : ShowAdsState.ShowFail;
523
+ Ads.context.showFinishAt = Time.realtimeSinceStartup;
476
524
 
477
525
  var localData = Ads.localData;
478
- var stat = isInterstitial ? localData.interstitial : localData.reward;
479
-
526
+ var stat = _isInterstitial ? localData.interstitial : localData.reward;
480
527
  if (isSuccess)
481
528
  {
482
529
  stat.success++;
@@ -490,8 +537,11 @@ namespace Amanotes.Core.Internal
490
537
  }
491
538
 
492
539
  localData.Save();
493
-
494
540
  RestoreVolume();
541
+
542
+ Log($"[Ad] {adType} ShowAdRoutineCompleted: {isSuccess}\n{JsonUtility.ToJson(Ads.context)}");
543
+ Ads.context = null;
544
+ _showState = ShowAdsState.None;
495
545
  }
496
546
 
497
547
  private void RestoreVolume()
@@ -505,9 +555,19 @@ namespace Amanotes.Core.Internal
505
555
  // Default implementation
506
556
  protected void OnAdClosed()
507
557
  {
508
- Ads.context.adCallback |= AdCallback.Close;
509
- Ads.context.onClosed?.Invoke();
510
- if (isInterstitial)
558
+ Log($"[Ad] {adType} OnAdClosed");
559
+
560
+ if (Ads.context != null)
561
+ {
562
+ Ads.context.adCallback |= AdCallback.Close;
563
+ Ads.context.onClosed?.Invoke();
564
+ }
565
+ else
566
+ {
567
+ LogWarning("OnAdClosed() Something wrong - No AdContext");
568
+ }
569
+
570
+ if (_isInterstitial)
511
571
  Ads.Events.OnInterstitialClosed?.Invoke();
512
572
  else
513
573
  Ads.Events.OnRewardedClosed?.Invoke();
@@ -515,10 +575,19 @@ namespace Amanotes.Core.Internal
515
575
 
516
576
  protected void OnAdClicked()
517
577
  {
518
- Ads.context.adCallback |= AdCallback.Click;
519
- Ads.context.onClicked?.Invoke();
578
+ Log($"[Ad] {adType} OnAdClicked");
579
+
580
+ if (Ads.context != null)
581
+ {
582
+ Ads.context.adCallback |= AdCallback.Click;
583
+ Ads.context.onClicked?.Invoke();
584
+ }
585
+ else
586
+ {
587
+ LogWarning("OnAdClicked() Something wrong - No AdContext");
588
+ }
520
589
 
521
- if (isInterstitial)
590
+ if (_isInterstitial)
522
591
  Ads.Events.OnInterstitialClicked?.Invoke();
523
592
  else
524
593
  Ads.Events.OnRewardedClicked?.Invoke();
@@ -527,10 +596,19 @@ namespace Amanotes.Core.Internal
527
596
 
528
597
  protected void OnAdShowFailed()
529
598
  {
530
- Ads.context.adCallback |= AdCallback.Fail;
531
- Ads.context.onShowFailed?.Invoke();
599
+ Log($"[Ad] {adType} OnAdShowFailed");
600
+
601
+ if (Ads.context != null)
602
+ {
603
+ Ads.context.adCallback |= AdCallback.Fail;
604
+ Ads.context.onShowFailed?.Invoke();
605
+ }
606
+ else
607
+ {
608
+ LogWarning("OnAdShowFailed() Something wrong - No AdContext");
609
+ }
532
610
 
533
- if (isInterstitial)
611
+ if (_isInterstitial)
534
612
  Ads.Events.OnInterstitialShowFailed?.Invoke();
535
613
  else
536
614
  Ads.Events.OnRewardedShowFailed?.Invoke();
@@ -539,20 +617,38 @@ namespace Amanotes.Core.Internal
539
617
 
540
618
  protected void OnAdShowSucceeded()
541
619
  {
542
- Ads.context.adCallback |= AdCallback.Success;
543
- Ads.context.onShowSuccess?.Invoke();
620
+ Log($"[Ad] {adType} OnAdShowSucceeded");
621
+
622
+ if (Ads.context != null)
623
+ {
624
+ Ads.context.adCallback |= AdCallback.Success;
625
+ Ads.context.onShowSuccess?.Invoke();
626
+ }
627
+ else
628
+ {
629
+ LogWarning("OnAdShowSucceeded() Something wrong - No AdContext");
630
+ }
544
631
 
545
- if (isInterstitial)
632
+ if (_isInterstitial)
546
633
  Ads.Events.OnInterstitialShowSucceeded?.Invoke();
547
634
 
548
635
  }
549
636
 
550
637
  protected void OnAdOpen()
551
638
  {
552
- Ads.context.adCallback |= AdCallback.Open;
553
- Ads.context.onOpened?.Invoke();
639
+ Log($"[Ad] {adType} OnAdOpen");
640
+
641
+ if (Ads.context != null)
642
+ {
643
+ Ads.context.adCallback |= AdCallback.Open;
644
+ Ads.context.onOpened?.Invoke();
645
+ }
646
+ else
647
+ {
648
+ LogWarning("OnAdOpen() Something wrong - No AdContext");
649
+ }
554
650
 
555
- if (isInterstitial)
651
+ if (_isInterstitial)
556
652
  Ads.Events.OnInterstitialOpened?.Invoke();
557
653
  else
558
654
  Ads.Events.OnRewardedOpened?.Invoke();
@@ -560,28 +656,41 @@ namespace Amanotes.Core.Internal
560
656
 
561
657
  protected void OnAdReward()
562
658
  {
563
- Ads.context.adCallback |= AdCallback.Reward;
564
- Ads.context.onRewardReceived?.Invoke();
659
+ Log($"[Ad] {adType} OnAdReward");
660
+
661
+ if (Ads.context != null)
662
+ {
663
+ Ads.context.adCallback |= AdCallback.Reward;
664
+ Ads.context.onRewardReceived?.Invoke();
665
+ }
666
+ else
667
+ {
668
+ LogWarning("OnAdReward() Something wrong - No AdContext");
669
+ }
565
670
 
566
- if (!isInterstitial)
671
+ if (!_isInterstitial)
567
672
  Ads.Events.OnRewardedReceived?.Invoke();
568
673
  }
569
674
 
570
675
  protected void OnAdLoadSuccess()
571
676
  {
677
+ Log($"[Ad] {adType} OnAdLoadSuccess");
678
+
572
679
  if (!_isRequesting)
573
680
  {
574
681
  LogWarning("Something wrong? OnAdReady called when no ad is loading!");
575
682
  }
576
683
 
577
684
  _isRequesting = false;
578
- if (isInterstitial)
685
+ if (_isInterstitial)
579
686
  Ads.Events.OnInterstitialLoadSucceeded?.Invoke();
580
687
  }
581
688
 
582
689
  protected void OnAdLoadFailed(string error)
583
690
  {
584
- if (isInterstitial)
691
+ Log($"[Ad] {adType} OnAdLoadFailed: {error}");
692
+
693
+ if (_isInterstitial)
585
694
  Ads.Events.OnInterstitialLoadFailed?.Invoke(error);
586
695
  }
587
696
  }
@@ -601,5 +710,7 @@ namespace Amanotes.Core.Internal
601
710
  public Action OnInterstitialClosed;
602
711
  public Action OnInterstitialLoadSucceeded;
603
712
  public Action<string> OnInterstitialLoadFailed;
713
+
714
+ public Action OnShowTimeout;
604
715
  }
605
716
  }
@@ -29,6 +29,8 @@ namespace Amanotes.Core
29
29
  //PUBLIC APIS
30
30
  public static partial class Analytics
31
31
  {
32
+ public static bool Migrated => localData.migrationLog.count > 0;
33
+
32
34
  public interface IEventParamsBuilder { }
33
35
 
34
36
  public class EventParams : IEventParamsBuilder
@@ -80,12 +82,7 @@ namespace Amanotes.Core
80
82
 
81
83
  public static IEventParamsBuilder LogEvent(string eventName)
82
84
  {
83
- if (string.IsNullOrWhiteSpace(eventName))
84
- {
85
- LogWarningOnce($"Invalid EventName: <{eventName}> ");
86
- return null;
87
- }
88
-
85
+ NormalizeEventName(ref eventName, true);
89
86
  var result = new EventParams(eventName);
90
87
  eventQueue.Enqueue(result);
91
88
  return result;
@@ -318,10 +315,9 @@ namespace Amanotes.Core
318
315
  }
319
316
 
320
317
  string eventNameToSend = GetEventNameToSend(eventData.eventName, countInSession, totalCount);
321
- NormalizeEventName(ref eventNameToSend);
318
+ if (Config.common.normalizeEventName) NormalizeEventName(ref eventNameToSend);
322
319
 
323
- if (showAnalyticsLog) Debug.Log($"AmaGDK v{AmaGDK.VERSION} | Event <{eventNameToSend}> (in session: {countInSession}, total: {totalCount})\n" +
324
- $"Params:\n{JsonUtils.DictionaryToJson(eventData.parameters, true)}");
320
+ if (showAnalyticsLog) Debug.Log($"AmaGDK v{AmaGDK.VERSION} | Event <{eventNameToSend}> (in session: {countInSession}, total: {totalCount})\n{JsonUtils.DictionaryToJson(eventData.parameters, true)}");
325
321
 
326
322
  var inUseAdapterIDs = new List<string>();
327
323
  foreach (AdapterContext m in listAdapters)
@@ -360,7 +356,7 @@ namespace Amanotes.Core
360
356
  return $"{eventName}_{(config.withinSession ? countInSession : totalCount).ToString(config.numberFormat)}";
361
357
  }
362
358
 
363
- internal static void NormalizeEventName(ref string eventName)
359
+ internal static void NormalizeEventName(ref string eventName, bool dryRun = false)
364
360
  {
365
361
  StringBuilder sb = tmpWarningSB;
366
362
  sb.Clear();
@@ -377,7 +373,7 @@ namespace Amanotes.Core
377
373
 
378
374
  if (eventName != normalizedEventName)
379
375
  {
380
- if (Config.common.normalizeEventName)
376
+ if (!dryRun)
381
377
  {
382
378
  eventName = normalizedEventName;
383
379
  }
@@ -389,7 +385,7 @@ namespace Amanotes.Core
389
385
 
390
386
  if (!char.IsLetter(eventName[0])) sb.AppendLine($" - EventName must start with a letter: <{eventName}> ");
391
387
  if (eventName.Length > 40) sb.AppendLine($" - EventName is too long ({eventName.Length} > 40): <{eventName}> ");
392
- if (sb.Length > 0) LogWarningOnce(sb.ToString(), $"NormalizeEventName<{eventName}>");
388
+ if (sb.Length > 0 && dryRun) LogWarningOnce(sb.ToString(), $"NormalizeEventName<{eventName}>");
393
389
  }
394
390
 
395
391
  internal static bool ShouldSendEvent(EventParams eventData)
@@ -22,7 +22,7 @@ namespace Amanotes.Core.Internal
22
22
 
23
23
  public static class Messsage
24
24
  {
25
- public const string READY = "init success!";
25
+ public const string READY = "init success";
26
26
  public const string SDK_INIT_CALLED = "init has been called!";
27
27
  public const string MULTIPLE_INSTANCE = "multiple instance found!";
28
28
  public const string CONFIG_NOT_FOUND = "AmaGDKConfig not found in Resources!";
@@ -79,19 +79,19 @@ namespace Amanotes.Core.Internal
79
79
  if (string.IsNullOrEmpty(key)) key = message;
80
80
  if (logWarningDict.Contains(key)) return;
81
81
  logWarningDict.Add(key);
82
- Debug.LogWarning($"AmaGDK v{VERSION} | {message}");
82
+ Debug.LogWarning($"AmaGDK {message}");
83
83
  }
84
84
  public static void LogWarning(string message)
85
85
  {
86
- Debug.LogWarning($"AmaGDK v{VERSION} | {message}");
86
+ Debug.LogWarning($"AmaGDK {message}");
87
87
  }
88
88
  public static void LogError(string message)
89
89
  {
90
- Debug.LogError($"AmaGDK v{VERSION} | {message}");
90
+ Debug.LogError($"AmaGDK {message}");
91
91
  }
92
92
  public static void Log(string message)
93
93
  {
94
- if (AmaGDK.Config.common.verboseLog) Debug.Log($"AmaGDK v{VERSION} | {message}");
94
+ if (AmaGDK.Config.common.verboseLog) Debug.Log($"AmaGDK {message}");
95
95
  }
96
96
  }
97
97
 
@@ -3,10 +3,13 @@ using System.Collections.Generic;
3
3
  using System.IO;
4
4
  using System.Text;
5
5
  using UnityEngine;
6
-
7
6
  using Amanotes.Core.Internal;
8
7
  using static Amanotes.Core.Internal.Logging;
9
8
 
9
+ #if UNITY_EDITOR
10
+ using UnityEditor;
11
+ #endif
12
+
10
13
  namespace Amanotes.Core
11
14
  {
12
15
  public partial class AmaGDK //Remote Config
@@ -112,6 +115,7 @@ namespace Amanotes.Core
112
115
  };
113
116
 
114
117
  internal static IRemoteConfig adapter;
118
+ internal static RemoteConfigConfig adapterConfig;
115
119
  internal static Action<bool> onAdapterInitCompleteCallback;
116
120
 
117
121
  internal static void NextState(bool result = true)
@@ -140,6 +144,8 @@ namespace Amanotes.Core
140
144
  NextState(false);
141
145
  return;
142
146
  }
147
+
148
+ adapterConfig = (adapter as AdapterContext)?.GetAdapterConfig<RemoteConfigConfig>();
143
149
  adapter.ResolveDependencies(NextState);
144
150
  }
145
151
 
@@ -171,12 +177,29 @@ namespace Amanotes.Core
171
177
  {
172
178
  _state = FetchState.SaveCache;
173
179
  StringBuilder sb = new StringBuilder();
180
+
181
+
182
+ bool needUpdateDefault = Application.isEditor && adapterConfig.autoUpdateDefaultValue;
183
+ List<KeyValue> list = needUpdateDefault ? new List<KeyValue>() : null;
184
+
174
185
  foreach (var c in dictConfig)
175
186
  {
176
187
  sb.AppendLine($"{c.Key}\t{Encode(c.Value)}");
188
+ if (!needUpdateDefault) continue;
189
+ list.Add(new KeyValue() { key = c.Key, value = c.Value });
177
190
  }
178
-
179
- var filePath = FileUtils.GetPath(fileName);
191
+
192
+ #if UNITY_EDITOR
193
+ if (needUpdateDefault)
194
+ {
195
+ list.Sort((item1, item2) => string.Compare(item1.key, item2.key, StringComparison.Ordinal));
196
+ adapterConfig.defaultValue = list.ToArray();
197
+ EditorUtility.SetDirty(_config);
198
+ Log($"[RemoteConfig] Updated default remote config!");
199
+ }
200
+ #endif
201
+
202
+ string filePath = FileUtils.GetPath(fileName);
180
203
  FileUtils.Save(filePath, sb.ToString());
181
204
  Log($"[RemoteConfig] Saved remote config to {filePath}");
182
205
  NextState();
@@ -301,6 +324,7 @@ namespace Amanotes.Core.Internal
301
324
  [Serializable]
302
325
  public class RemoteConfigConfig
303
326
  {
327
+ public bool autoUpdateDefaultValue;
304
328
  public KeyValue[] defaultValue;
305
329
  public float firstFetchTimeOutInSeconds = 10;
306
330
  public float defaultTimeOutInSeconds = 3;
@@ -8,6 +8,20 @@ using static Amanotes.Core.Internal.Logging;
8
8
 
9
9
  namespace Amanotes.Core.Internal
10
10
  {
11
+ public class Utils
12
+ {
13
+ public static void DelayCall(float seconds, Action action)
14
+ {
15
+ AmaGDK._instance.StartCoroutine(DelayCallRoutine(seconds, action));
16
+ }
17
+
18
+ private static IEnumerator DelayCallRoutine(float seconds, Action callback)
19
+ {
20
+ yield return new WaitForSeconds(seconds);
21
+ callback();
22
+ }
23
+ }
24
+
11
25
  internal class FileUtils
12
26
  {
13
27
 
package/Runtime/AmaGDK.cs CHANGED
@@ -1,5 +1,6 @@
1
1
  using System;
2
2
  using System.Collections;
3
+ using System.Text;
3
4
  using Amanotes.Core.Internal;
4
5
  using UnityEngine;
5
6
  using static Amanotes.Core.Internal.Logging;
@@ -9,7 +10,7 @@ namespace Amanotes.Core
9
10
  {
10
11
  public partial class AmaGDK : MonoBehaviour
11
12
  {
12
- public const string VERSION = "0.2.8";
13
+ public const string VERSION = "0.2.10";
13
14
 
14
15
  internal static AmaGDK _instance;
15
16
  internal static Status _status = Status.None;
@@ -75,6 +76,8 @@ namespace Amanotes.Core
75
76
  }
76
77
 
77
78
  _status = Status.Initialize;
79
+ float startTime = Time.realtimeSinceStartup;
80
+ StringBuilder adapterInfo = new StringBuilder();
78
81
 
79
82
  // sort on priority
80
83
  Adapter.listAdapters.Sort((a1, a2) => a1.initOrder.CompareTo(a2.initOrder));
@@ -94,8 +97,8 @@ namespace Amanotes.Core
94
97
  LogWarning($"{adapter.adapterId} init time out: {timeout}");
95
98
  break;
96
99
  }
97
-
98
- Log($"Adapter {adapter.adapterId} {(adapter.IsReady ? "initiated!" : "is not ready!")}");
100
+
101
+ adapterInfo.AppendLine(string.Format("[{0}] {1} (adapter v{2})", adapter.IsReady ? "OK" : "FAIL", adapter.adapterId, adapter.adapterVersion));
99
102
  }
100
103
 
101
104
  // Init modules (Adapter managers)
@@ -106,7 +109,7 @@ namespace Amanotes.Core
106
109
  _status = Status.Ready;
107
110
  _onReadyCallback?.Invoke();
108
111
  _onReadyCallback = null;
109
- Debug.Log($"AmaGDK v{VERSION} | {READY}");
112
+ Debug.Log($"AmaGDK v{VERSION} | {READY} in {Time.realtimeSinceStartup - startTime}s\n\n{adapterInfo.ToString()}");
110
113
  }
111
114
 
112
115
  void RegisterUnityCallback(AdapterContext adapter)
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "com.amanotes.gdk",
3
- "version": "0.2.8",
3
+ "version": "0.2.10",
4
4
  "displayName": "AmaGDK",
5
5
  "description": "Amanotes Game Development Kit",
6
6
  "unity": "2020.3",