com.amanotes.gdk 0.1.20 → 0.2.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.
Files changed (58) hide show
  1. package/CHANGELOG.md +6 -0
  2. package/Editor/AmaGDKEditor.cs +91 -46
  3. package/Editor/AmaGDKManager.cs +26 -27
  4. package/Editor/Utils/AmaGDKEditor.ExtractVersion.cs +133 -103
  5. package/Editor/Utils/AmaGDKEditor.GUI.cs +54 -51
  6. package/Editor/Utils/AmaGDKEditor.Utils.cs +2 -3
  7. package/Packages/AmaGDKConfig.unitypackage +0 -0
  8. package/Packages/AmaGDKExample.unitypackage +0 -0
  9. package/Packages/AmaGDKTest.unitypackage +0 -0
  10. package/Packages/AmaPassport.ATTSupport.unitypackage +0 -0
  11. package/{Samples~/Example/AmaGDKExample.unity.meta → Packages/AmaPassport.ATTSupport.unitypackage.meta} +1 -1
  12. package/Packages/AmaPassport.AdvertisingID.unitypackage +0 -0
  13. package/{Sample~/Example/AmaGDKExample.unity.meta → Packages/AmaPassport.AdvertisingID.unitypackage.meta} +1 -1
  14. package/Packages/AppsFlyerAdapter_v6.5.4.unitypackage +0 -0
  15. package/Packages/FirebaseAnalyticsAdapter_v9.1.0.unitypackage +0 -0
  16. package/Packages/FirebaseRemoteConfigAdapter_v9.1.0.unitypackage +0 -0
  17. package/{Runtime/AmaPassport/Plugins.meta → Packages/FirebaseRemoteConfigAdapter_v9.1.0.unitypackage.meta} +1 -2
  18. package/Packages/IronsourceAdapter_v7.2.6.unitypackage +0 -0
  19. package/Runtime/AmaGDK.Adapters.cs +30 -12
  20. package/Runtime/AmaGDK.Ads.cs +520 -162
  21. package/Runtime/{AmaPassport/AmaGDK.AmaPassport.cs → AmaGDK.AmaPassport.cs} +36 -47
  22. package/Runtime/{AmaPassport/AmaGDK.AmaPassport.cs.meta → AmaGDK.AmaPassport.cs.meta} +1 -1
  23. package/Runtime/AmaGDK.Analytics.cs +78 -89
  24. package/Runtime/AmaGDK.Config.cs +23 -19
  25. package/Runtime/AmaGDK.Internal.SemVer.cs +11 -29
  26. package/Runtime/AmaGDK.Internal.cs +17 -11
  27. package/Runtime/AmaGDK.RemoteConfig.cs +352 -0
  28. package/Runtime/{AmaPassport/Plugins/Android/AdvertisingIdFetcher.cs.meta → AmaGDK.RemoteConfig.cs.meta} +1 -1
  29. package/Runtime/AmaGDK.UserProfile.cs +5 -8
  30. package/Runtime/AmaGDK.Utils.cs +79 -60
  31. package/Runtime/AmaGDK.WebUtils.cs +45 -48
  32. package/Runtime/AmaGDK.cs +74 -22
  33. package/Runtime/AssemblyInfo.cs +0 -1
  34. package/package.json +1 -1
  35. package/Packages/AppsflyerAdapter_v6.5.4.unitypackage +0 -0
  36. package/Runtime/AmaPassport/Plugins/Android/AdvertisingIdCallback.java +0 -7
  37. package/Runtime/AmaPassport/Plugins/Android/AdvertisingIdCallback.java.meta +0 -32
  38. package/Runtime/AmaPassport/Plugins/Android/AdvertisingIdFetcher.cs +0 -96
  39. package/Runtime/AmaPassport/Plugins/Android/AdvertisingIdFetcher.java +0 -79
  40. package/Runtime/AmaPassport/Plugins/Android/AdvertisingIdFetcher.java.meta +0 -32
  41. package/Runtime/AmaPassport/Plugins/Android.meta +0 -8
  42. package/Runtime/AmaPassport/Plugins/iOS/KeyChain.cs +0 -59
  43. package/Runtime/AmaPassport/Plugins/iOS/KeyChain.cs.meta +0 -11
  44. package/Runtime/AmaPassport/Plugins/iOS/KeyChainPlugin.mm +0 -52
  45. package/Runtime/AmaPassport/Plugins/iOS/KeyChainPlugin.mm.meta +0 -33
  46. package/Runtime/AmaPassport/Plugins/iOS/UICKeyChainStore.h +0 -281
  47. package/Runtime/AmaPassport/Plugins/iOS/UICKeyChainStore.h.meta +0 -33
  48. package/Runtime/AmaPassport/Plugins/iOS/UICKeyChainStore.m +0 -1393
  49. package/Runtime/AmaPassport/Plugins/iOS/UICKeyChainStore.m.meta +0 -33
  50. package/Runtime/AmaPassport/Plugins/iOS.meta +0 -8
  51. package/Runtime/AmaPassport.meta +0 -8
  52. package/Samples~/Example/AmaGDKExample.cs +0 -87
  53. package/Samples~/Example/AmaGDKExample.cs.meta +0 -11
  54. package/Samples~/Example/AmaGDKExample.unity +0 -3114
  55. package/Sample~/Example/AmaGDKExample.cs +0 -87
  56. package/Sample~/Example/AmaGDKExample.cs.meta +0 -11
  57. package/Sample~/Example/AmaGDKExample.unity +0 -3114
  58. /package/Packages/{AppsflyerAdapter_v6.5.4.unitypackage.meta → AppsFlyerAdapter_v6.5.4.unitypackage.meta} +0 -0
@@ -1,235 +1,593 @@
1
1
  using System;
2
2
  using System.Collections;
3
-
3
+ using System.Collections.Generic;
4
4
  using UnityEngine;
5
-
6
5
  using Amanotes.Core.Internal;
7
6
  using static Amanotes.Core.Internal.Logging;
7
+ using static Amanotes.Core.AmaGDK;
8
8
 
9
9
  namespace Amanotes.Core
10
10
  {
11
- public interface IAds
11
+ public static class AdExtension
12
12
  {
13
- bool IsAdReady(AdType Type);
14
-
15
- #region Interstitial
16
- event Action InterstitialShowSucceededCallback;
17
- event Action InterstitialShowFailedCallback;
18
- event Action InterstitialClickedCallback;
19
- void RequestInterstitial();
20
- void ShowInterstitial();
21
- void ShowInterstitial(string placementName);
22
- #endregion FullAds
23
-
24
- #region VideoAds
25
- event Action RewardedVideoShowFailedCallback;
26
- event Action RewardedVideoClosedCallback;
27
- event Action RewardedCallback;
28
- event Action RewardedVideoClickCallback;
29
- void RequestRewardedVideo();
30
- void ShowRewardedVideo();
31
- void ShowRewardedVideo(string placementName);
32
- #endregion VideoAds
33
-
34
- #region Banner
35
- event Action BannerAdsClickCallback;
36
- event Action BannerShowCallback;
37
- void RequestBanner(BannerPosition position = BannerPosition.TOP);
38
- void RequestBanner(BannerPosition position, string placementName);
39
- void ShowBanner();
40
- void HideBanner();
41
- #endregion Banner
13
+ public static IAdCallback OnAdOpened(this IAdCallback ad, Action callback)
14
+ {
15
+ if (ad == null)
16
+ return null;
17
+ Ads.context.onOpened -= callback;
18
+ Ads.context.onOpened += callback;
19
+ return ad;
20
+ }
21
+
22
+ public static IAdCallback OnRewardReceived(this IAdCallback ad, Action callback)
23
+ {
24
+ if (ad == null)
25
+ return null;
26
+ Ads.context.onRewardReceived -= callback;
27
+ Ads.context.onRewardReceived += callback;
28
+ return ad;
29
+ }
30
+
31
+ public static IAdCallback OnAdClicked(this IAdCallback ad, Action callback)
32
+ {
33
+ if (ad == null)
34
+ return null;
35
+ Ads.context.onClicked -= callback;
36
+ Ads.context.onClicked += callback;
37
+ return ad;
38
+ }
39
+
40
+ public static IAdCallback OnAdShowFailed(this IAdCallback ad, Action callback)
41
+ {
42
+ if (ad == null)
43
+ return null;
44
+ Ads.context.onShowFailed -= callback;
45
+ Ads.context.onShowFailed += callback;
46
+ return ad;
47
+ }
48
+
49
+ public static IAdCallback OnAdShowSuccess(this IAdCallback ad, Action callback)
50
+ {
51
+ if (ad == null)
52
+ return null;
53
+ Ads.context.onShowSuccess -= callback;
54
+ Ads.context.onShowSuccess += callback;
55
+ return ad;
56
+ }
57
+
58
+ public static IAdCallback OnAdClosed(this IAdCallback ad, Action callback)
59
+ {
60
+ if (ad == null)
61
+ return null;
62
+ Ads.context.onClosed -= callback;
63
+ Ads.context.onClosed += callback;
64
+ return ad;
65
+ }
66
+
42
67
  }
43
68
 
44
- public enum BannerPosition
69
+ public partial class AmaGDK // Ads module
45
70
  {
46
- TOP = 1,
47
- BOTTOM = 2
48
- };
71
+ [Serializable]
72
+ internal class AdStat
73
+ {
74
+ internal int lastSuccessTime;
75
+ internal int success;
76
+ internal int failed;
49
77
 
50
- public enum AdType : byte
51
- {
52
- Interstitial,
53
- Reward,
54
- Banner
55
- };
78
+ public int successTotal;
79
+ public int failedTotal;
80
+ }
56
81
 
57
- public partial class AmaGDK // IAds module
58
- {
59
- public static class Ads
82
+ [Serializable]
83
+ internal class AdsData : IJsonFile
60
84
  {
61
- internal static IAds adsModule;
62
- public static Action<string> OnInterstitalFailCallback;
63
- public static Action<string> OnRewardedVideoFailCallback;
85
+ public AdStat interstitial = new AdStat();
86
+ public AdStat reward = new AdStat();
64
87
 
65
- public static void Init()
88
+ internal int GetLastShowInSeconds(AdType adType)
66
89
  {
67
- var adsModules = Adapter.FindAll<IAds>();
90
+ return (int)(Time.realtimeSinceStartup - (adType == AdType.Interstitial ? interstitial.lastSuccessTime : reward.lastSuccessTime));
91
+ }
68
92
 
69
- if (adsModules == null || adsModules.Count < 1)
70
- {
71
- LogError("Ads module not found!");
72
- return;
73
- }
74
-
75
- if (adsModules.Count > 1)
93
+ internal void Save()
94
+ {
95
+ this.SaveJsonToFile();
96
+ }
97
+ }
98
+
99
+ [Serializable]
100
+ public class AdAdapterConfig
101
+ {
102
+ public int adLoadTimeoutInSecs = 60;
103
+ public int adShowTimeoutInSecs = 5;
104
+ public BannerPosition bannerPosition = BannerPosition.BOTTOM;
105
+
106
+ public bool checkInternet = true;
107
+ public bool autoLogEvent = true;
108
+
109
+ public bool enableInterstitial = true;
110
+ public bool enableRewarded = true;
111
+ public bool enableBanner = true;
112
+ public bool autoMute = true;
113
+ }
114
+
115
+ public partial class Ads
116
+ {
117
+ public static ShowAdContext context;
118
+ public static bool allowAdRequest = true;
119
+
120
+ internal static AdAdapterConfig _adConfig;
121
+ internal static IAdAdapter _adapter;
122
+ public static AdListener Events = new AdListener();
123
+ internal static float _savedVolume = -1;
124
+ internal static AdsData localData = new AdsData().LoadJsonFromFile();
125
+ }
126
+
127
+ public partial class Ads // Public
128
+ {
129
+ internal static void Init()
130
+ {
131
+ _adapter = Adapter.GetSingleAdapter<IAdAdapter>();
132
+ _adConfig = ((AdapterContext)_adapter).GetAdapterConfig<AdAdapterConfig>();
133
+ _adapter.interstitial.StartLoadAd();
134
+ _adapter.rewardVideo.StartLoadAd();
135
+ }
136
+
137
+ public static bool HasInterstitial => _adapter.interstitial.hasAd;
138
+ public static bool HasRewardedVideo => _adapter.rewardVideo.hasAd;
139
+
140
+ public static IAdCallback ShowInterstitial(string placementName = null, Dictionary<string, object> userData = null)
141
+ {
142
+ if (context != null)
76
143
  {
77
- LogError("Multiple Ads modules is not supported!");
78
- return;
144
+ LogWarning("Context != null, might some ad be showing???");
145
+ context = null;
79
146
  }
80
-
81
- adsModule = adsModules[0].GetAdapterApi<IAds>();
147
+
148
+ context = new ShowAdContext(AdType.Interstitial, placementName, userData);
149
+ _adapter.interstitial.StartShowAd();
150
+ return context;
82
151
  }
83
152
 
84
- public static void RequestBanner(BannerPosition position)
153
+ public static IAdCallback ShowRewardedVideo(string placementName = null, Dictionary<string, object> userData = null)
85
154
  {
86
- if (adsModule == null)
155
+ if (context != null)
87
156
  {
88
- LogWarning("Ads module is not initialized");
89
- return;
157
+ LogWarning("Context != null, might some ad be showing???");
158
+ context = null;
90
159
  }
91
- adsModule.RequestBanner(position);
160
+
161
+ context = new ShowAdContext(AdType.VideoReward, placementName, userData);
162
+ _adapter.rewardVideo.StartShowAd();
163
+ return context;
92
164
  }
93
165
 
166
+ private static bool _showingBanner = false;
94
167
  public static void ShowBanner()
95
168
  {
96
- adsModule.ShowBanner();
169
+ if (_showingBanner) return;
170
+ _showingBanner = true;
171
+ _adapter.ShowBanner(_adConfig.bannerPosition);
97
172
  }
98
173
 
99
174
  public static void HideBanner()
100
175
  {
101
- if (!adsModule.IsAdReady(AdType.Banner))
102
- {
103
- LogWarning("Banner is not ready");
104
- return;
105
- }
106
-
107
- adsModule.HideBanner();
176
+ if (!_showingBanner) return;
177
+ _showingBanner = false;
178
+ _adapter.HideBanner();
108
179
  }
109
180
 
110
- public static void RequestInterstitial()
181
+ public static void StopWaitForAd()
111
182
  {
112
- if (adsModule == null)
113
- {
114
- LogWarning("Ads module is not initialized");
183
+ if (context == null)
115
184
  return;
116
- }
117
- adsModule.RequestInterstitial();
185
+
186
+ if (context.adType == AdType.Interstitial)
187
+ _adapter.interstitial.StopShowAd();
188
+ else
189
+ _adapter.rewardVideo.StopShowAd();
190
+
191
+ context = null;
118
192
  }
193
+ }
194
+ }
195
+ }
196
+
197
+ namespace Amanotes.Core.Internal
198
+ {
199
+ public interface IAdCallback { }
200
+
201
+ public interface IAdAdapter
202
+ {
203
+ AdLogic interstitial { get; }
204
+ AdLogic rewardVideo { get; }
205
+
206
+ void ShowBanner(BannerPosition position);
207
+ void HideBanner();
208
+ }
209
+
210
+ public enum LoadAdsState
211
+ {
212
+ None,
213
+ Requesting,
214
+ Ready
215
+ }
216
+
217
+ public enum ShowAdsState
218
+ {
219
+ None,
220
+ ShowCalled,
221
+ WaitForAd,
222
+ Showing,
223
+ ShowFail,
224
+ ShowSuccess
225
+ }
226
+
227
+ [Flags]
228
+ public enum AdCallback
229
+ {
230
+ None,
231
+ Open,
232
+ Reward,
233
+ Click,
234
+ Cancel,
235
+ Close,
236
+ Success,
237
+ Fail
238
+ }
239
+
240
+ public enum BannerPosition
241
+ {
242
+ TOP = 1,
243
+ BOTTOM = 2
244
+ }
245
+
246
+ public enum AdType
247
+ {
248
+ Interstitial,
249
+ VideoReward,
250
+ Banner
251
+ }
252
+
253
+ public class ShowAdContext : IAdCallback
254
+ {
255
+ public readonly AdType adType;
256
+ public readonly string placementName;
257
+ public readonly Dictionary<string, object> userData;
258
+ public AdCallback adCallback;
259
+
260
+ internal Action onOpened;
261
+ internal Action onRewardReceived;
262
+ internal Action onClicked;
263
+ internal Action onShowSuccess;
264
+ internal Action onShowFailed;
265
+ internal Action onClosed;
266
+
267
+ // Stats
268
+ public float showCallAt;
269
+ public float showFinishAt;
270
+
271
+ public ShowAdContext(AdType adType, string placementName, Dictionary<string, object> userData)
272
+ {
273
+ this.adType = adType;
274
+ this.userData = userData;
275
+ this.placementName = placementName;
276
+ adCallback = AdCallback.None;
277
+ showCallAt = Time.time;
278
+ showFinishAt = 0;
279
+ }
280
+
281
+ public bool hasError => (adCallback & (AdCallback.Fail | AdCallback.Cancel)) != 0;
282
+ public bool hasCompleted => (adCallback & (AdCallback.Close | AdCallback.Reward | AdCallback.Cancel)) != 0;
283
+ public bool hasReward => (adCallback & AdCallback.Reward) != 0;
284
+ public bool hasCancel => (adCallback & AdCallback.Cancel) != 0;
285
+ public bool hasClicked => (adCallback & AdCallback.Click) != 0;
286
+ }
287
+
288
+ public abstract class AdLogic
289
+ {
290
+ private static readonly WaitForSeconds wait1Sec = new WaitForSeconds(1f);
291
+
292
+ internal LoadAdsState _loadState = LoadAdsState.None;
293
+ internal bool hasAd => _loadState == LoadAdsState.Ready;
119
294
 
120
- public static void ShowInterstitial()
295
+ internal Coroutine _loadRoutine;
296
+
297
+ public void StartLoadAd()
298
+ {
299
+ if (_loadState != LoadAdsState.None)
121
300
  {
122
- if (!adsModule.IsAdReady(AdType.Interstitial))
123
- {
124
- LogWarning("Interstitial is not ready");
125
- AmaGDK._instance.StartCoroutine(IWaitShowInterstitial());
126
- return;
127
- }
128
- adsModule.ShowInterstitial();
301
+ LogWarning("StartLoadAd() --> Invalid state: " + _loadState);
302
+ return;
129
303
  }
130
304
 
131
- public static void RequestRewardedVideo()
305
+ _loadRoutine = _instance.StartCoroutine(LoadAdRoutine());
306
+ }
307
+
308
+ public void StopLoadAd()
309
+ {
310
+ if (_loadState == LoadAdsState.Requesting)
132
311
  {
133
- if (adsModule == null)
134
- {
135
- LogWarning("Ads module is not initialized");
136
- return;
137
- }
138
- adsModule.RequestRewardedVideo();
312
+ _loadState = LoadAdsState.None;
139
313
  }
140
314
 
141
- public static void ShowRewardedVideo()
315
+ if (_loadRoutine == null) return;
316
+
317
+ _instance.StopCoroutine(_loadRoutine);
318
+ _loadRoutine = null;
319
+ }
320
+
321
+ IEnumerator LoadAdRoutine()
322
+ {
323
+ if (isAdReady)
142
324
  {
143
- if (!adsModule.IsAdReady(AdType.Reward))
144
- {
145
- LogWarning("Reward is not ready");
146
- AmaGDK._instance.StartCoroutine(IWaitShowRewardedVideo());
147
- return;
148
- }
149
- adsModule.ShowRewardedVideo();
325
+ _loadState = LoadAdsState.Ready;
326
+ yield break;
150
327
  }
151
328
 
152
- private static IEnumerator IWaitShowRewardedVideo()
329
+ while (true)
153
330
  {
154
- LogWarning("Wait Show Rewarded Video");
155
- if (adsModule == null)
156
- {
157
- OnRewardedVideoFailCallback?.Invoke("Not found ads module");
158
- OnRewardedVideoFailCallback = null;
159
- yield break;
160
- }
331
+ yield return wait1Sec;
332
+
333
+ if (!Ads.allowAdRequest) continue;
334
+ if (Ads._adConfig.checkInternet && !hasInternet) continue;
161
335
 
162
- var startTime = Time.time;
163
- float timeout = 5;
164
- string error = null;
165
- while (!adsModule.IsAdReady(AdType.Reward))
336
+ _loadState = LoadAdsState.Requesting;
337
+ _isRequesting = true;
338
+ RequestAd();
339
+
340
+ var timeout = Ads._adConfig.adLoadTimeoutInSecs;
341
+ var counter = 0;
342
+
343
+ while (counter < timeout || timeout == 0)
166
344
  {
167
- if (Application.internetReachability == NetworkReachability.NotReachable)
168
- {
169
- error = Application.internetReachability.ToString();
170
- break;
171
- }
172
-
173
- if ((Time.time - startTime) > timeout)
174
- {
175
- error = "Timeout";
176
- break;
177
- }
178
-
179
- yield return null;
345
+ yield return wait1Sec;
346
+ counter++;
347
+ if (_isRequesting == false) break;
180
348
  }
181
349
 
182
- if (adsModule.IsAdReady(AdType.Reward))
350
+ if (counter > timeout && timeout > 0) // timeout
183
351
  {
184
- adsModule.ShowRewardedVideo();
352
+ continue;
185
353
  }
186
- else
354
+
355
+ // request should be completed here!
356
+ if (!isAdReady)
187
357
  {
188
- OnRewardedVideoFailCallback?.Invoke(error);
189
- OnRewardedVideoFailCallback = null;
358
+ LogWarning("Request complete but failed!");
359
+ continue;
190
360
  }
361
+
362
+ _loadState = LoadAdsState.Ready;
363
+ yield break;
191
364
  }
365
+ }
366
+
367
+ bool hasInternet => Application.internetReachability != NetworkReachability.NotReachable;
192
368
 
193
- private static IEnumerator IWaitShowInterstitial()
369
+ // Override by actual Ad instance
370
+ protected abstract AdType adType { get; }
371
+ protected abstract bool isAdReady { get; }
372
+ protected abstract void RequestAd();
373
+ protected abstract void ShowAd();
374
+
375
+ // Show Ad logic
376
+ internal ShowAdsState _showState = ShowAdsState.None;
377
+ private Coroutine _showAdRoutine;
378
+ private bool _isRequesting;
379
+ internal bool isInterstitial => Ads.context.adType == AdType.Interstitial;
380
+
381
+ public void StartShowAd()
382
+ {
383
+ if (_showState != ShowAdsState.None)
194
384
  {
195
- LogWarning("Wait Show Interstitial");
196
- if (adsModule == null)
385
+ LogWarning("StartShowAd() --> Invalid _showState: " + _showState);
386
+ }
387
+
388
+ _showState = ShowAdsState.ShowCalled;
389
+ if (_showAdRoutine != null) _instance.StopCoroutine(_showAdRoutine);
390
+ _showAdRoutine = _instance.StartCoroutine(ShowAdRoutine());
391
+ }
392
+
393
+ public void StopShowAd()
394
+ {
395
+ _showState = ShowAdsState.None;
396
+ RestoreVolume();
397
+ if (_showAdRoutine == null) return;
398
+ _instance.StopCoroutine(_showAdRoutine);
399
+ _showAdRoutine = null;
400
+ }
401
+
402
+ IEnumerator ShowAdRoutine()
403
+ {
404
+ // Wait for Ad
405
+ if (!isAdReady)
406
+ {
407
+ if (_loadState == LoadAdsState.Ready)
197
408
  {
198
- OnInterstitalFailCallback?.Invoke("Not found ads module");
199
- OnInterstitalFailCallback = null;
200
- yield break;
409
+ LogWarning("Inconsistent state report: isAdReady == false while _loadState == Ready");
410
+ _loadState = LoadAdsState.None;
201
411
  }
202
412
 
203
- var startTime = Time.time;
204
- float timeout = 5;
205
- string error = null;
206
- while (!adsModule.IsAdReady(AdType.Interstitial))
413
+ if (Ads._adConfig.checkInternet && !hasInternet)
207
414
  {
208
- if (Application.internetReachability == NetworkReachability.NotReachable)
209
- {
210
- error = Application.internetReachability.ToString();
211
- break;
212
- }
213
-
214
- if ((Time.time - startTime) > timeout)
215
- {
216
- error = "Timeout";
217
- break;
218
- }
219
-
220
- yield return null;
415
+ _showState = ShowAdsState.ShowFail;
416
+ yield break;
221
417
  }
222
418
 
223
- if (adsModule.IsAdReady(AdType.Interstitial))
419
+ if (_loadState != LoadAdsState.Requesting) StartLoadAd();
420
+ _showState = ShowAdsState.WaitForAd;
421
+
422
+ var timeout = Ads._adConfig.adShowTimeoutInSecs;
423
+ var counter = 0;
424
+
425
+ while (counter < timeout || timeout == 0)
224
426
  {
225
- adsModule.ShowInterstitial();
427
+ yield return wait1Sec;
428
+ counter++;
429
+ if (_loadState == LoadAdsState.Ready) break;
226
430
  }
227
- else
431
+
432
+ if (!isAdReady)
228
433
  {
229
- OnInterstitalFailCallback?.Invoke(error);
230
- OnInterstitalFailCallback = null;
434
+ _showState = ShowAdsState.ShowFail;
435
+ yield break;
231
436
  }
232
437
  }
438
+
439
+ // Ad should be ready here!
440
+ ShowAd();
441
+ if (Ads._adConfig.autoMute && AudioListener.volume > 0 && Ads._savedVolume == -1)
442
+ {
443
+ Ads._savedVolume = AudioListener.volume;
444
+ AudioListener.volume = 0;
445
+ }
446
+
447
+ var context = Ads.context;
448
+ while (!context.hasCompleted)
449
+ {
450
+ yield return wait1Sec;
451
+ }
452
+
453
+ if (adType == AdType.Interstitial)
454
+ {
455
+ _showState = context.hasError ? ShowAdsState.ShowFail : ShowAdsState.ShowSuccess;
456
+ ShowCompleted(_showState == ShowAdsState.ShowSuccess);
457
+ yield break;
458
+ }
459
+
460
+ // Should be rewardedVideo
461
+ if (!context.hasReward && !context.hasCancel) // no reward & no cancel: wait for the delayed reward callback
462
+ {
463
+ yield return wait1Sec;
464
+ }
465
+
466
+ _showState = context.hasError ? ShowAdsState.ShowFail : ShowAdsState.ShowSuccess;
467
+ ShowCompleted(_showState == ShowAdsState.ShowSuccess);
468
+ }
469
+
470
+ private void ShowCompleted(bool isSuccess)
471
+ {
472
+ bool isInterstitial = adType == AdType.Interstitial;
473
+ var adapter = Ads._adapter;
474
+ if (isInterstitial)
475
+ adapter.interstitial.StartLoadAd();
476
+ else
477
+ adapter.rewardVideo.StartLoadAd();
478
+
479
+ var localData = Ads.localData;
480
+ var stat = isInterstitial ? localData.interstitial : localData.reward;
481
+
482
+ if (isSuccess)
483
+ {
484
+ stat.success++;
485
+ stat.successTotal++;
486
+ stat.lastSuccessTime = (int)Time.realtimeSinceStartup;
487
+ }
488
+ else
489
+ {
490
+ stat.failed++;
491
+ stat.failedTotal++;
492
+ }
493
+
494
+ localData.Save();
495
+
496
+ RestoreVolume();
497
+ }
498
+
499
+ private void RestoreVolume()
500
+ {
501
+ if (!Ads._adConfig.autoMute || Ads._savedVolume <= 0)
502
+ return;
503
+ AudioListener.volume = Ads._savedVolume;
504
+ Ads._savedVolume = -1;
505
+ }
506
+
507
+ // Default implementation
508
+ protected void OnAdClosed()
509
+ {
510
+ Ads.context.adCallback |= AdCallback.Close;
511
+ Ads.context.onClosed?.Invoke();
512
+ if (isInterstitial)
513
+ Ads.Events.OnInterstitialClosed?.Invoke();
514
+ else
515
+ Ads.Events.OnRewardedClosed?.Invoke();
516
+ }
517
+
518
+ protected void OnAdClicked()
519
+ {
520
+ Ads.context.adCallback |= AdCallback.Click;
521
+ Ads.context.onClicked?.Invoke();
522
+ if (isInterstitial)
523
+ Ads.Events.OnInterstitialClicked?.Invoke();
524
+ else
525
+ Ads.Events.OnRewardedClicked?.Invoke();
526
+ }
527
+
528
+ protected void OnAdShowFailed()
529
+ {
530
+ Ads.context.adCallback |= AdCallback.Fail;
531
+ Ads.context.onShowFailed?.Invoke();
532
+ if (isInterstitial)
533
+ Ads.Events.OnInterstitialShowFailed?.Invoke();
534
+ else
535
+ Ads.Events.OnRewardedShowFailed?.Invoke();
536
+
537
+ Ads.context = null;
538
+ }
539
+
540
+ protected void OnAdShowSucceeded()
541
+ {
542
+ Ads.context.adCallback |= AdCallback.Success;
543
+ Ads.context.onShowSuccess?.Invoke();
544
+ if (isInterstitial)
545
+ Ads.Events.OnInterstitialShowSucceeded?.Invoke();
546
+
547
+ Ads.context = null;
548
+ }
549
+
550
+ protected void OnAdOpen()
551
+ {
552
+ Ads.context.adCallback |= AdCallback.Open;
553
+ Ads.context.onOpened?.Invoke();
554
+ if (isInterstitial)
555
+ Ads.Events.OnInterstitialOpened?.Invoke();
556
+ else
557
+ Ads.Events.OnRewardedOpened?.Invoke();
558
+ }
559
+
560
+ protected void OnAdReward()
561
+ {
562
+ Ads.context.adCallback |= AdCallback.Reward;
563
+ Ads.context.onRewardReceived?.Invoke();
564
+ if (!isInterstitial)
565
+ Ads.Events.OnRewardedReceived?.Invoke();
566
+ }
567
+
568
+ protected void OnAdReady()
569
+ {
570
+ if (!_isRequesting)
571
+ {
572
+ LogWarning("Something wrong? OnAdReady called when no ad is loading!");
573
+ }
574
+
575
+ _isRequesting = false;
233
576
  }
234
577
  }
235
- }
578
+
579
+ public class AdListener
580
+ {
581
+ public Action OnRewardedOpened;
582
+ public Action OnRewardedReceived;
583
+ public Action OnRewardedClicked;
584
+ public Action OnRewardedShowFailed;
585
+ public Action OnRewardedClosed;
586
+
587
+ public Action OnInterstitialOpened;
588
+ public Action OnInterstitialShowSucceeded;
589
+ public Action OnInterstitialShowFailed;
590
+ public Action OnInterstitialClicked;
591
+ public Action OnInterstitialClosed;
592
+ }
593
+ }