com.amanotes.gdk 0.2.9 → 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,11 @@
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
+
3
9
  ## [0.2.9 - 2023-06-15]
4
10
  ### Show total init time
5
11
  ### Show adapter version + status at init time
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
@@ -139,13 +143,33 @@ namespace Amanotes.Core
139
143
  public static bool showingBanner => _showingBanner;
140
144
  public static bool showingAd => context != null;
141
145
 
142
- public static IAdCallback ShowInterstitial(string placementName = null, Dictionary<string, object> userData = null)
146
+ private static bool ClearPrevContext()
143
147
  {
144
- 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)
145
152
  {
146
- LogWarning("Context != null, might some ad be showing???");
147
- context = null;
153
+ LogWarning($"[AD] ShowRequest IGNORED as another ad is showing (elapsedTime: {duration:n2}s):\n" + JsonUtility.ToJson(context, true));
154
+ return false;
148
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
163
+ {
164
+ _adapter.rewardVideo.StopShowAd();
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;
149
173
 
150
174
  context = new ShowAdContext(AdType.Interstitial, placementName, userData);
151
175
  _adapter.interstitial.StartShowAd();
@@ -154,18 +178,14 @@ namespace Amanotes.Core
154
178
 
155
179
  public static IAdCallback ShowRewardedVideo(string placementName = null, Dictionary<string, object> userData = null)
156
180
  {
157
- if (context != null)
158
- {
159
- LogWarning("Context != null, might some ad be showing???");
160
- context = null;
161
- }
162
-
181
+ if (!ClearPrevContext()) return null;
182
+
163
183
  context = new ShowAdContext(AdType.VideoReward, placementName, userData);
164
184
  _adapter.rewardVideo.StartShowAd();
165
185
  return context;
166
186
  }
167
187
 
168
- private static bool _showingBanner = false;
188
+ private static bool _showingBanner;
169
189
  public static void ShowBanner()
170
190
  {
171
191
  if (_showingBanner) return;
@@ -227,16 +247,16 @@ namespace Amanotes.Core.Internal
227
247
  [Flags]
228
248
  public enum AdCallback
229
249
  {
230
- None,
231
- Open,
232
- Reward,
233
- Click,
234
- Cancel,
235
- Close,
236
- Success,
237
- 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
238
258
  }
239
-
259
+
240
260
  public enum BannerPosition
241
261
  {
242
262
  TOP = 1,
@@ -278,11 +298,10 @@ namespace Amanotes.Core.Internal
278
298
  showFinishAt = 0;
279
299
  }
280
300
 
281
- public bool hasError => (adCallback & (AdCallback.Fail | AdCallback.Cancel)) != 0;
282
- public bool potentiallyCompleted => (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;
283
303
  public bool hasReward => (adCallback & AdCallback.Reward) != 0;
284
304
  public bool hasClosed => (adCallback & AdCallback.Close) != 0;
285
- public bool hasCancel => (adCallback & AdCallback.Cancel) != 0;
286
305
  public bool hasClicked => (adCallback & AdCallback.Click) != 0;
287
306
  }
288
307
 
@@ -303,18 +322,19 @@ namespace Amanotes.Core.Internal
303
322
  return;
304
323
  }
305
324
 
325
+ Log("StartLoadAd");
306
326
  _loadRoutine = _instance.StartCoroutine(LoadAdRoutine());
307
327
  }
308
-
328
+
309
329
  public void StopLoadAd()
310
330
  {
331
+ Log("StopLoadAd");
311
332
  if (_loadState == LoadAdsState.Requesting)
312
333
  {
313
334
  _loadState = LoadAdsState.None;
314
335
  }
315
-
336
+
316
337
  if (_loadRoutine == null) return;
317
-
318
338
  _instance.StopCoroutine(_loadRoutine);
319
339
  _loadRoutine = null;
320
340
  }
@@ -338,7 +358,7 @@ namespace Amanotes.Core.Internal
338
358
  _isRequesting = true;
339
359
  RequestAd();
340
360
 
341
- var timeout = Ads._adConfig.adLoadTimeoutInSecs;
361
+ int timeout = Ads._adConfig.adLoadTimeoutInSecs;
342
362
  var counter = 0;
343
363
 
344
364
  while (counter < timeout || timeout == 0)
@@ -383,9 +403,10 @@ namespace Amanotes.Core.Internal
383
403
  {
384
404
  if (_showState != ShowAdsState.None)
385
405
  {
386
- LogWarning("StartShowAd() --> Invalid _showState: " + _showState);
406
+ LogWarning("[Ad] StartShowAd() --> Invalid _showState: " + _showState);
387
407
  }
388
-
408
+
409
+ Log($"[Ad] {adType} StartShowAd");
389
410
  _showState = ShowAdsState.ShowCalled;
390
411
  if (_showAdRoutine != null) _instance.StopCoroutine(_showAdRoutine);
391
412
  _showAdRoutine = _instance.StartCoroutine(ShowAdRoutine());
@@ -393,6 +414,7 @@ namespace Amanotes.Core.Internal
393
414
 
394
415
  public void StopShowAd()
395
416
  {
417
+ Log($"[Ad] {adType} StopShowAd");
396
418
  _showState = ShowAdsState.None;
397
419
  RestoreVolume();
398
420
  if (_showAdRoutine == null) return;
@@ -407,20 +429,21 @@ namespace Amanotes.Core.Internal
407
429
  {
408
430
  if (_loadState == LoadAdsState.Ready)
409
431
  {
410
- LogWarning("Inconsistent state report: isAdReady == false while _loadState == Ready");
432
+ LogWarning("[Ad] Inconsistent state report: isAdReady == false while _loadState == Ready");
411
433
  _loadState = LoadAdsState.None;
412
434
  }
413
435
 
414
436
  if (Ads._adConfig.checkInternet && !hasInternet)
415
437
  {
416
438
  _showState = ShowAdsState.ShowFail;
439
+ ShowAdRoutineCompleted(false);
417
440
  yield break;
418
441
  }
419
442
 
420
443
  if (_loadState != LoadAdsState.Requesting) StartLoadAd();
421
444
  _showState = ShowAdsState.WaitForAd;
422
445
 
423
- var timeout = Ads._adConfig.adShowTimeoutInSecs;
446
+ int timeout = Ads._adConfig.adShowTimeoutInSecs;
424
447
  var counter = 0;
425
448
 
426
449
  while (counter < timeout || timeout == 0)
@@ -433,12 +456,12 @@ namespace Amanotes.Core.Internal
433
456
  if (!isAdReady)
434
457
  {
435
458
  Ads.Events.OnShowTimeout?.Invoke();
436
- _showState = ShowAdsState.ShowFail;
437
459
  ShowAdRoutineCompleted(false);
438
460
  yield break;
439
461
  }
440
462
  }
441
-
463
+
464
+ _showState = ShowAdsState.Showing;
442
465
  // Ad should be ready here!
443
466
  ShowAd();
444
467
  if (Ads._adConfig.autoMute && AudioListener.volume > 0 && Ads._savedVolume == -1)
@@ -446,9 +469,8 @@ namespace Amanotes.Core.Internal
446
469
  Ads._savedVolume = AudioListener.volume;
447
470
  AudioListener.volume = 0;
448
471
  }
449
-
450
- var context = Ads.context;
451
-
472
+
473
+ ShowAdContext context = Ads.context;
452
474
  while (!context.potentiallyCompleted)
453
475
  {
454
476
  yield return wait1Sec;
@@ -456,51 +478,52 @@ namespace Amanotes.Core.Internal
456
478
 
457
479
  if (adType == AdType.Interstitial)
458
480
  {
459
- _showState = context.hasError ? ShowAdsState.ShowFail : ShowAdsState.ShowSuccess;
460
- ShowAdRoutineCompleted(_showState == ShowAdsState.ShowSuccess);
481
+ ShowAdRoutineCompleted(!context.hasFailedOrCancelled);
461
482
  yield break;
462
483
  }
463
484
 
464
- if (context.hasCancel)
485
+ if (context.hasFailedOrCancelled)
465
486
  {
487
+ Log($"[Ad] {adType} Waiting for [close]");
466
488
  yield return wait1Sec; // wait for close (1s)
467
- _showState = ShowAdsState.ShowFail;
468
489
  ShowAdRoutineCompleted(false);
469
490
  yield break;
470
491
  }
471
492
 
472
493
  if (context.hasClosed)
473
494
  {
474
- while (!context.hasCancel && !context.hasReward)
495
+ while (!context.hasFailedOrCancelled && !context.hasReward)
475
496
  {
497
+ Log($"[Ad] {adType} Waiting for [cancel] or [reward]");
476
498
  yield return wait1Sec;
477
499
  }
478
500
 
479
- _showState = context.hasCancel ? ShowAdsState.ShowFail : ShowAdsState.ShowSuccess;
480
- ShowAdRoutineCompleted(_showState == ShowAdsState.ShowSuccess);
501
+ ShowAdRoutineCompleted(!context.hasFailedOrCancelled);
481
502
  yield break;
482
503
  }
483
504
 
484
505
  while (!context.hasClosed)
485
506
  {
507
+ Log($"[Ad] {adType} Waiting for [close]");
486
508
  yield return wait1Sec;
487
509
  }
488
510
 
489
- _showState = ShowAdsState.ShowSuccess;
490
511
  ShowAdRoutineCompleted(true);
491
-
492
- Ads.context = null;
493
- _showState = ShowAdsState.None;
494
512
  }
495
513
 
496
514
  private void ShowAdRoutineCompleted(bool isSuccess)
497
515
  {
498
- 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;
499
523
  Ads.context.showFinishAt = Time.realtimeSinceStartup;
500
524
 
501
525
  var localData = Ads.localData;
502
526
  var stat = _isInterstitial ? localData.interstitial : localData.reward;
503
-
504
527
  if (isSuccess)
505
528
  {
506
529
  stat.success++;
@@ -515,6 +538,10 @@ namespace Amanotes.Core.Internal
515
538
 
516
539
  localData.Save();
517
540
  RestoreVolume();
541
+
542
+ Log($"[Ad] {adType} ShowAdRoutineCompleted: {isSuccess}\n{JsonUtility.ToJson(Ads.context)}");
543
+ Ads.context = null;
544
+ _showState = ShowAdsState.None;
518
545
  }
519
546
 
520
547
  private void RestoreVolume()
@@ -528,6 +555,8 @@ namespace Amanotes.Core.Internal
528
555
  // Default implementation
529
556
  protected void OnAdClosed()
530
557
  {
558
+ Log($"[Ad] {adType} OnAdClosed");
559
+
531
560
  if (Ads.context != null)
532
561
  {
533
562
  Ads.context.adCallback |= AdCallback.Close;
@@ -546,6 +575,8 @@ namespace Amanotes.Core.Internal
546
575
 
547
576
  protected void OnAdClicked()
548
577
  {
578
+ Log($"[Ad] {adType} OnAdClicked");
579
+
549
580
  if (Ads.context != null)
550
581
  {
551
582
  Ads.context.adCallback |= AdCallback.Click;
@@ -565,6 +596,8 @@ namespace Amanotes.Core.Internal
565
596
 
566
597
  protected void OnAdShowFailed()
567
598
  {
599
+ Log($"[Ad] {adType} OnAdShowFailed");
600
+
568
601
  if (Ads.context != null)
569
602
  {
570
603
  Ads.context.adCallback |= AdCallback.Fail;
@@ -584,6 +617,8 @@ namespace Amanotes.Core.Internal
584
617
 
585
618
  protected void OnAdShowSucceeded()
586
619
  {
620
+ Log($"[Ad] {adType} OnAdShowSucceeded");
621
+
587
622
  if (Ads.context != null)
588
623
  {
589
624
  Ads.context.adCallback |= AdCallback.Success;
@@ -601,6 +636,8 @@ namespace Amanotes.Core.Internal
601
636
 
602
637
  protected void OnAdOpen()
603
638
  {
639
+ Log($"[Ad] {adType} OnAdOpen");
640
+
604
641
  if (Ads.context != null)
605
642
  {
606
643
  Ads.context.adCallback |= AdCallback.Open;
@@ -619,6 +656,8 @@ namespace Amanotes.Core.Internal
619
656
 
620
657
  protected void OnAdReward()
621
658
  {
659
+ Log($"[Ad] {adType} OnAdReward");
660
+
622
661
  if (Ads.context != null)
623
662
  {
624
663
  Ads.context.adCallback |= AdCallback.Reward;
@@ -635,6 +674,8 @@ namespace Amanotes.Core.Internal
635
674
 
636
675
  protected void OnAdLoadSuccess()
637
676
  {
677
+ Log($"[Ad] {adType} OnAdLoadSuccess");
678
+
638
679
  if (!_isRequesting)
639
680
  {
640
681
  LogWarning("Something wrong? OnAdReady called when no ad is loading!");
@@ -647,6 +688,8 @@ namespace Amanotes.Core.Internal
647
688
 
648
689
  protected void OnAdLoadFailed(string error)
649
690
  {
691
+ Log($"[Ad] {adType} OnAdLoadFailed: {error}");
692
+
650
693
  if (_isInterstitial)
651
694
  Ads.Events.OnInterstitialLoadFailed?.Invoke(error);
652
695
  }
@@ -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
@@ -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
@@ -10,7 +10,7 @@ namespace Amanotes.Core
10
10
  {
11
11
  public partial class AmaGDK : MonoBehaviour
12
12
  {
13
- public const string VERSION = "0.2.9";
13
+ public const string VERSION = "0.2.10";
14
14
 
15
15
  internal static AmaGDK _instance;
16
16
  internal static Status _status = Status.None;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "com.amanotes.gdk",
3
- "version": "0.2.9",
3
+ "version": "0.2.10",
4
4
  "displayName": "AmaGDK",
5
5
  "description": "Amanotes Game Development Kit",
6
6
  "unity": "2020.3",