com.amanotes.gdk 0.2.47 → 0.2.49

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 (67) hide show
  1. package/CHANGELOG.md +15 -1
  2. package/Editor/AmaGDKEditor.cs +133 -65
  3. package/Editor/AmaGDKExtra.cs +31 -0
  4. package/Editor/AmaGDKExtra.cs.meta +11 -0
  5. package/Editor/Utils/AmaGDKEditor.ExtractVersion.cs +1 -1
  6. package/Extra/AmaGDKInstaller.unitypackage +0 -0
  7. package/Extra/AmaGDKProject.unitypackage +0 -0
  8. package/Extra/SDKVersionTracking.unitypackage +0 -0
  9. package/Extra/SDKVersionTracking.unitypackage.meta +7 -0
  10. package/Packages/AmaGDKConfig.unitypackage +0 -0
  11. package/Packages/AmaGDKExample.unitypackage +0 -0
  12. package/Packages/AmaGDKTest.unitypackage +0 -0
  13. package/Packages/AppsFlyerAdapter.unitypackage +0 -0
  14. package/Packages/FirebaseAnalyticsAdapter.unitypackage +0 -0
  15. package/Packages/FirebaseRemoteConfigAdapter.unitypackage +0 -0
  16. package/Packages/IronSourceAdapter.unitypackage +0 -0
  17. package/Packages/RevenueCatAdapter.unitypackage +0 -0
  18. package/Runtime/AmaGDK.Adapters.cs +0 -4
  19. package/Runtime/AmaGDK.Ads.cs +89 -29
  20. package/Runtime/AmaGDK.Analytics.cs +97 -64
  21. package/Runtime/AmaGDK.IAP.cs +39 -45
  22. package/Runtime/AmaGDK.RemoteConfig.cs +76 -52
  23. package/Runtime/AmaGDK.UserProfile.cs +106 -124
  24. package/Runtime/AmaGDK.cs +46 -35
  25. package/Runtime/Internal/AmaGDK.Event.cs +185 -0
  26. package/Runtime/Internal/AmaGDK.Event.cs.meta +3 -0
  27. package/Runtime/Internal/AmaGDK.Internal.cs +3 -0
  28. package/Runtime/Internal/AmaGDK.Utils.cs +85 -24
  29. package/Runtime/Klavar/Attributes/AccumulatedCountAttribute.cs +19 -0
  30. package/Runtime/Klavar/Attributes/AccumulatedCountAttribute.cs.meta +11 -0
  31. package/Runtime/Klavar/Attributes/ConnectionAttribute.cs +18 -0
  32. package/Runtime/Klavar/Attributes/ConnectionAttribute.cs.meta +11 -0
  33. package/Runtime/Klavar/Attributes/CountInSessionAttribute.cs +27 -0
  34. package/Runtime/Klavar/Attributes/CountInSessionAttribute.cs.meta +11 -0
  35. package/Runtime/Klavar/Attributes/DescriptionAttribute.cs +7 -0
  36. package/Runtime/Klavar/Attributes/DescriptionAttribute.cs.meta +11 -0
  37. package/Runtime/Klavar/Attributes/DynamicValidateAttribute.cs +30 -0
  38. package/Runtime/Klavar/Attributes/DynamicValidateAttribute.cs.meta +11 -0
  39. package/Runtime/Klavar/Attributes/IgnoreAttribute.cs +16 -0
  40. package/Runtime/Klavar/Attributes/IgnoreAttribute.cs.meta +11 -0
  41. package/Runtime/Klavar/Attributes/MinMaxAttribute.cs +130 -0
  42. package/Runtime/Klavar/Attributes/MinMaxAttribute.cs.meta +11 -0
  43. package/Runtime/Klavar/Attributes/MinMaxLengthAttribute.cs +88 -0
  44. package/Runtime/Klavar/Attributes/MinMaxLengthAttribute.cs.meta +11 -0
  45. package/Runtime/Klavar/Attributes/NameAttribute.cs +35 -0
  46. package/Runtime/Klavar/Attributes/NameAttribute.cs.meta +11 -0
  47. package/Runtime/Klavar/Attributes/NotNullAttribute.cs +16 -0
  48. package/Runtime/Klavar/Attributes/NotNullAttribute.cs.meta +11 -0
  49. package/Runtime/Klavar/Attributes/RegexPatternAttribute.cs +58 -0
  50. package/Runtime/Klavar/Attributes/RegexPatternAttribute.cs.meta +11 -0
  51. package/Runtime/Klavar/Attributes/TimeDiffLastFireAttribute.cs +28 -0
  52. package/Runtime/Klavar/Attributes/TimeDiffLastFireAttribute.cs.meta +11 -0
  53. package/Runtime/Klavar/Attributes/ToStringAttribute.cs +97 -0
  54. package/Runtime/Klavar/Attributes/ToStringAttribute.cs.meta +11 -0
  55. package/Runtime/Klavar/Attributes/ValueAttribute.cs +30 -0
  56. package/Runtime/Klavar/Attributes/ValueAttribute.cs.meta +11 -0
  57. package/Runtime/Klavar/Attributes.meta +8 -0
  58. package/Runtime/Klavar/KlavarEvent.cs +91 -0
  59. package/Runtime/Klavar/KlavarEvent.cs.meta +11 -0
  60. package/Runtime/Klavar/KlavarEventAttribute.cs +39 -0
  61. package/Runtime/Klavar/KlavarEventAttribute.cs.meta +11 -0
  62. package/Runtime/Klavar/KlavarEventTools.cs +92 -0
  63. package/Runtime/Klavar/KlavarEventTools.cs.meta +11 -0
  64. package/Runtime/Klavar/KlavarEventUtils.cs +58 -0
  65. package/Runtime/Klavar/KlavarEventUtils.cs.meta +11 -0
  66. package/Runtime/{Core.meta → Klavar.meta} +1 -1
  67. package/package.json +1 -1
@@ -20,7 +20,7 @@ namespace Amanotes.Core
20
20
  public static DateTime? SubscriptionLastPurchaseDate => localData.SubscriptionLastPurchaseDate;
21
21
  public static DateTime? SubscriptionExpiredDate => localData.SubscriptionExpiredDate;
22
22
  public static DateTime? UnsubscribedDate => localData.UnsubscribedDate;
23
- public static Dictionary<string, ProductInfo> AllProducts => dicProducts;
23
+ public static readonly Dictionary<string, ProductInfo> AllProducts = new Dictionary<string, ProductInfo>();
24
24
  private const string DATE_FORMAT = "yyyy/MM/yy HH:mm:ss";
25
25
 
26
26
  public static ISetupBuilder GetProducts(bool appendExistingList = false)
@@ -28,42 +28,62 @@ namespace Amanotes.Core
28
28
  if (!appendExistingList)
29
29
  {
30
30
  IAPExtension.isCleanUpConfig = false;
31
- dicProducts.Clear();
31
+ AllProducts.Clear();
32
32
  }
33
33
  var result = new SetupContext();
34
- ExecuteInNextFrame(result.GetProducts);
34
+ GDKUtils.DelayCall(0f, result.GetProducts);
35
35
  return result;
36
36
  }
37
37
 
38
38
  public static IPurchaseBuilder Purchase(string productId)
39
39
  {
40
40
  var result = new PurchaseContext();
41
- if (!dicProducts.ContainsKey(productId))
41
+ GDKUtils.DelayCall(0f, () =>
42
42
  {
43
- LogWarning($"[IAP] Product {productId} is not found");
44
- result.onFail?.Invoke(new PurchaseError($"Product {productId} is not found"));
45
- return result;
46
- }
47
- ExecuteInNextFrame(() => result.Purchase(dicProducts[productId]));
43
+ if (!AllProducts.ContainsKey(productId))
44
+ {
45
+ LogWarning($"[IAP] Product {productId} is not found");
46
+ result.onFail?.Invoke(new PurchaseError($"Product {productId} is not found"));
47
+ return;
48
+ }
49
+
50
+ #if UNITY_EDITOR
51
+ if (Config.iap.allPurchaseSuccessInEditor)
52
+ {
53
+ var s = new PurchaseSuccess
54
+ {
55
+ productIds = new[] { productId },
56
+ isSandbox = true
57
+ };
58
+ result.onSuccess?.Invoke(s);
59
+ }
60
+ else
61
+ {
62
+ result.onFail?.Invoke(new PurchaseError("Force to fail", productId));
63
+ }
64
+ #else
65
+ result.Purchase(AllProducts[productId]);
66
+ #endif
67
+ });
48
68
  return result;
49
69
  }
50
70
 
51
71
  public static IPurchaseBuilder RestorePurchase()
52
72
  {
53
73
  var result = new PurchaseContext();
54
- ExecuteInNextFrame(result.RestorePurchase);
74
+ GDKUtils.DelayCall(0f, result.RestorePurchase);
55
75
  return result;
56
76
  }
57
77
 
58
78
  public static ProductInfo GetProduct(string productId)
59
79
  {
60
- if (!dicProducts.ContainsKey(productId))
80
+ if (!AllProducts.ContainsKey(productId))
61
81
  {
62
82
  LogWarning($"[IAP] Not found product with id <{productId}>. Make sure you have called GetProducts() first.");
63
83
  return null;
64
84
  }
65
85
 
66
- return dicProducts[productId];
86
+ return AllProducts[productId];
67
87
  }
68
88
 
69
89
  public static List<string> GetActiveSubscriptions()
@@ -108,10 +128,7 @@ namespace Amanotes.Core
108
128
  return null;
109
129
  }
110
130
  }
111
-
112
131
 
113
- internal static Dictionary<string, ProductInfo> dicProducts = new Dictionary<string, ProductInfo>();
114
-
115
132
  internal static bool InitModule()
116
133
  {
117
134
  _adapter = Adapter2.GetAdapter<IAPAdapter>();
@@ -126,17 +143,6 @@ namespace Amanotes.Core
126
143
  localData.Sync();
127
144
  if (Config.iap.autoGetProducts) GetProducts();
128
145
  }
129
-
130
- internal static void ExecuteInNextFrame(Action method)
131
- {
132
- _instance.StartCoroutine(ExecuteRoutine(method));
133
- }
134
-
135
- static IEnumerator ExecuteRoutine(Action method)
136
- {
137
- yield return null;
138
- method?.Invoke();
139
- }
140
146
  }
141
147
 
142
148
  public partial class IAP //Persistent
@@ -431,10 +437,10 @@ namespace Amanotes.Core.Internal
431
437
  #if UNITY_EDITOR
432
438
  foreach (var p in ls)
433
439
  {
434
- if (dicProducts.ContainsKey(p.id)) dicProducts[p.id] = p;
435
- else dicProducts.Add(p.id, p);
440
+ if (AllProducts.ContainsKey(p.id)) AllProducts[p.id] = p;
441
+ else AllProducts.Add(p.id, p);
436
442
  }
437
- onSuccess?.Invoke(dicProducts);
443
+ onSuccess?.Invoke(AllProducts);
438
444
  return;
439
445
  #else
440
446
 
@@ -473,7 +479,7 @@ namespace Amanotes.Core.Internal
473
479
  {
474
480
  if (getProdQueue.Count <= 0)
475
481
  {
476
- onSuccess?.Invoke(dicProducts);
482
+ onSuccess?.Invoke(AllProducts);
477
483
  return;
478
484
  }
479
485
 
@@ -489,10 +495,10 @@ namespace Amanotes.Core.Internal
489
495
  {
490
496
  foreach (var p in pList)
491
497
  {
492
- if (dicProducts.ContainsKey(p.id)) dicProducts[p.id] = p;
493
- else dicProducts.Add(p.id, p);
498
+ if (AllProducts.ContainsKey(p.id)) AllProducts[p.id] = p;
499
+ else AllProducts.Add(p.id, p);
494
500
  }
495
- ExecuteInNextFrame(GetNextProductsInQueue);
501
+ GDKUtils.DelayCall(0f, GetNextProductsInQueue);
496
502
  }, error => onFail?.Invoke(error));
497
503
  }
498
504
  catch (Exception e)
@@ -513,18 +519,6 @@ namespace Amanotes.Core.Internal
513
519
 
514
520
  public void Purchase(ProductInfo productInfo)
515
521
  {
516
- #if UNITY_EDITOR
517
- if (AmaGDK.Config.iap.allPurchaseSuccessInEditor)
518
- {
519
- DoOnSuccess(new PurchaseSuccess
520
- {
521
- productIds = new[] { productInfo.id },
522
- isSandbox = true
523
- });
524
- return;
525
- }
526
- #endif
527
-
528
522
  if (!string.IsNullOrWhiteSpace(discountId))
529
523
  {
530
524
  AmaGDK.IAP.Adapter?.PurchaseDiscount(productInfo, discountId, DoOnSuccess, DoOnFail);
@@ -17,17 +17,22 @@ namespace Amanotes.Core
17
17
  {
18
18
  public enum RemoteConfigSource
19
19
  {
20
- EmbedConfig,
20
+ None,
21
21
  Cache,
22
+ Local,
22
23
  Internet
23
24
  }
24
25
 
26
+ partial class Event
27
+ {
28
+ public const string REMOTE_CONFIG_FETCH_COMPLETE = nameof(REMOTE_CONFIG_FETCH_COMPLETE);
29
+ }
30
+
25
31
  [Serializable]
26
32
  public partial class RemoteConfig //Public
27
33
  {
28
- public static Action<bool> onFetchCompleted;
29
- public static Dictionary<string, string> DictConfig => dictConfig;
30
- public static RemoteConfigSource Source { private set; get; }
34
+ public static RemoteConfigSource Source { private set; get; } = RemoteConfigSource.None;
35
+
31
36
  static bool? _cacheExisted = null;
32
37
  public static bool HasCache
33
38
  {
@@ -73,8 +78,8 @@ namespace Amanotes.Core
73
78
  return (T)Convert.ChangeType(c.value, typeof(T));
74
79
  }
75
80
  #endif
76
- if (dictConfig.ContainsKey(key))
77
- return (T)Convert.ChangeType(dictConfig[key], typeof(T));
81
+ if (DictConfig.ContainsKey(key))
82
+ return (T)Convert.ChangeType(DictConfig[key], typeof(T));
78
83
  return defaultValue;
79
84
  }
80
85
 
@@ -85,7 +90,7 @@ namespace Amanotes.Core
85
90
 
86
91
  public static string GetConfigAsJsonString()
87
92
  {
88
- return JsonUtils.DictionaryToJson(dictConfig);
93
+ return JsonUtils.DictionaryToJson(DictConfig);
89
94
  }
90
95
 
91
96
  public static void SetActiveEmbedConfig(string id)
@@ -105,7 +110,6 @@ namespace Amanotes.Core
105
110
  internal enum FetchState
106
111
  {
107
112
  None,
108
- CheckInternet,
109
113
  Fetch,
110
114
  SaveCache,
111
115
 
@@ -116,7 +120,9 @@ namespace Amanotes.Core
116
120
  Fail
117
121
  }
118
122
 
119
- static Dictionary<string, string> dictConfig = new Dictionary<string, string>();
123
+ public static Dictionary<string, string> DictConfig { get; private set; } = new Dictionary<string, string>();
124
+
125
+
120
126
  static string fileName = $"{nameof(RemoteConfig)}.kv";
121
127
  static string base64Prefix = "base64:";
122
128
  const string VERSION_PREFIX = "version:";
@@ -125,28 +131,25 @@ namespace Amanotes.Core
125
131
  ? Config.remoteConfig.embedRemoteConfig.version
126
132
  : 1;
127
133
 
128
- static FetchState _state = FetchState.None;
129
- internal static FetchState State => _state;
134
+ static FetchState _fetchState = FetchState.None;
135
+ internal static FetchState fetchState => _fetchState;
130
136
 
131
137
  static readonly Dictionary<FetchState, Action[]> fetchSM = new Dictionary<FetchState, Action[]>
132
138
  {
133
- { FetchState.None, new Action[]{ CheckInternet}},
134
- { FetchState.CheckInternet, new Action[]{ LoadCache, Fetch}},
139
+ { FetchState.None, new Action[]{ Fetch}},
135
140
  { FetchState.Fetch, new Action[]{ LoadCache, SaveCache}},
136
141
  { FetchState.SaveCache, new Action[]{ SetDone }},
137
142
  { FetchState.LoadCache, new Action[]{ LoadEmbedConfig, SetDone}},
138
- { FetchState.LoadEmbedConfig, new Action[]{ SetFail, SetDone}}
143
+ { FetchState.LoadEmbedConfig, new Action[]{ SetFail, SetDone}}
139
144
  };
140
145
 
141
146
  internal static RemoteConfigAdapter adapter;
142
-
143
- internal static Action<bool> onAdapterInitCompleteCallback;
144
147
 
145
148
  internal static void NextState(bool result = true)
146
149
  {
147
- if (!fetchSM.TryGetValue(_state, out var actions))
150
+ if (!fetchSM.TryGetValue(_fetchState, out var actions))
148
151
  {
149
- LogWarning("[RemoteConfig] Invalid / Unsupported state: " + _state);
152
+ LogWarning("[RemoteConfig] Invalid / Unsupported state: " + _fetchState);
150
153
  return;
151
154
  }
152
155
 
@@ -159,15 +162,37 @@ namespace Amanotes.Core
159
162
  actions[result ? 1 : 0]();
160
163
  }
161
164
 
162
- static void CheckInternet()
165
+ internal static void InitModule()
163
166
  {
164
- _state = FetchState.CheckInternet;
165
- NextState(Application.internetReachability != NetworkReachability.NotReachable);
167
+ adapter = Adapter2.GetAdapter<RemoteConfigAdapter>();
168
+ }
169
+
170
+ internal static void StartModule()
171
+ {
172
+ if (adapter != null) Fetch();
173
+ }
174
+
175
+ public static void SetFetchCompleteCallback(Action<RemoteConfigSource> callback)
176
+ {
177
+
178
+ if (_fetchState == FetchState.Success || _fetchState == FetchState.Fail)
179
+ {
180
+ callback?.Invoke(Source);
181
+ return;
182
+ }
183
+
184
+ dispatcher.AddListener(Event.REMOTE_CONFIG_FETCH_COMPLETE, callback, true);
166
185
  }
167
186
 
168
187
  static void Fetch()
169
188
  {
170
- _state = FetchState.Fetch;
189
+ if (adapter == null)
190
+ {
191
+ _fetchState = FetchState.None;
192
+ return;
193
+ }
194
+
195
+ _fetchState = FetchState.Fetch;
171
196
  adapter.FetchConfig(HasCache, (isSuccess, result) =>
172
197
  {
173
198
  if (!isSuccess)
@@ -175,8 +200,8 @@ namespace Amanotes.Core
175
200
  NextState(false);
176
201
  return;
177
202
  }
178
-
179
- dictConfig = result;
203
+
204
+ DictConfig = result;
180
205
  Source = RemoteConfigSource.Internet;
181
206
  Log("[RemoteConfig] Load from the internet");
182
207
  NextState(true);
@@ -187,13 +212,13 @@ namespace Amanotes.Core
187
212
  {
188
213
  Profiler.BeginSample("AmaGDK.RemoteConfig.SaveCache()");
189
214
 
190
- _state = FetchState.SaveCache;
215
+ _fetchState = FetchState.SaveCache;
191
216
  StringBuilder sb = new StringBuilder();
192
217
 
193
218
  //Add embedded remote config version to force load from embedded config after app update
194
219
  sb.AppendLine($"{VERSION_PREFIX}{EmbedVersion}");
195
220
 
196
- foreach (var c in dictConfig)
221
+ foreach (var c in DictConfig)
197
222
  {
198
223
  sb.AppendLine($"{c.Key}\t{Encode(c.Value)}");
199
224
  }
@@ -209,7 +234,7 @@ namespace Amanotes.Core
209
234
  {
210
235
  Profiler.BeginSample("AmaGDK.RemoteConfig.LoadCache()");
211
236
 
212
- _state = FetchState.LoadCache;
237
+ _fetchState = FetchState.LoadCache;
213
238
 
214
239
  if (!HasCache)
215
240
  {
@@ -220,7 +245,7 @@ namespace Amanotes.Core
220
245
 
221
246
  try
222
247
  {
223
- dictConfig.Clear();
248
+ DictConfig.Clear();
224
249
  using (StreamReader sr = new StreamReader(GDKFileUtils.GetPath(fileName)))
225
250
  {
226
251
  //Check new app update
@@ -253,10 +278,10 @@ namespace Amanotes.Core
253
278
  }
254
279
  string key = line.Substring(0, idx);
255
280
  string value = line.Substring(idx + 1);
256
- dictConfig.Add(key, Decode(value));
281
+ DictConfig.Add(key, Decode(value));
257
282
  }
258
283
  }
259
- Source = RemoteConfigSource.Cache;
284
+ Source = RemoteConfigSource.Local;
260
285
  Log("[RemoteConfig] Load from cache");
261
286
  }
262
287
  catch (Exception ex)
@@ -274,7 +299,7 @@ namespace Amanotes.Core
274
299
 
275
300
  static void LoadEmbedConfig()
276
301
  {
277
- _state = FetchState.LoadEmbedConfig;
302
+ _fetchState = FetchState.LoadEmbedConfig;
278
303
 
279
304
  if (_config.remoteConfig == null || _config.remoteConfig.embedRemoteConfig == null)
280
305
  {
@@ -292,25 +317,24 @@ namespace Amanotes.Core
292
317
 
293
318
  foreach (var item in config.items)
294
319
  {
295
- dictConfig.Add(item.key, item.value);
320
+ DictConfig.Add(item.key, item.value);
296
321
  }
297
- Source = RemoteConfigSource.EmbedConfig;
322
+ Source = RemoteConfigSource.Cache;
298
323
  Log("[RemoteConfig] Load from embed asset");
299
324
  NextState(true);
300
325
  }
301
326
 
302
327
  static void SetDone()
303
328
  {
304
- _state = FetchState.Success;
305
- onAdapterInitCompleteCallback(true);
306
- onFetchCompleted?.Invoke(true);
329
+ _fetchState = FetchState.Success;
330
+ dispatcher.Dispatch(Event.REMOTE_CONFIG_FETCH_COMPLETE, Source);
307
331
  }
308
332
 
309
333
  static void SetFail()
310
334
  {
311
- _state = FetchState.Fail;
312
- onAdapterInitCompleteCallback(false);
313
- onFetchCompleted?.Invoke(false);
335
+ _fetchState = FetchState.Fail;
336
+ Source = RemoteConfigSource.None;
337
+ dispatcher.Dispatch(Event.REMOTE_CONFIG_FETCH_COMPLETE, Source);
314
338
  }
315
339
 
316
340
  static string Encode(string s)
@@ -338,19 +362,19 @@ namespace Amanotes.Core
338
362
  }
339
363
  }
340
364
 
341
- public static class RemoteConfigExtension
342
- {
343
- public static void InitRemoteConfigModule(this RemoteConfigAdapter ap, Action<bool> onCompleteCallback)
344
- {
345
- if (AmaGDK.RemoteConfig.State != AmaGDK.RemoteConfig.FetchState.None)
346
- {
347
- LogWarning($"[RemoteConfig] Current state {AmaGDK.RemoteConfig.State.ToString()}\nCannot start to initialize");
348
- return;
349
- }
350
- AmaGDK.RemoteConfig.onAdapterInitCompleteCallback = onCompleteCallback;
351
- AmaGDK.RemoteConfig.NextState();
352
- }
353
- }
365
+ // public static class RemoteConfigExtension
366
+ // {
367
+ // public static void InitRemoteConfigModule(this RemoteConfigAdapter ap, Action<bool> onCompleteCallback)
368
+ // {
369
+ // if (AmaGDK.RemoteConfig.fetchState != AmaGDK.RemoteConfig.FetchState.None)
370
+ // {
371
+ // LogWarning($"[RemoteConfig] Current state {AmaGDK.RemoteConfig.fetchState.ToString()}\nCannot start to initialize");
372
+ // return;
373
+ // }
374
+ //
375
+ // AmaGDK.RemoteConfig.NextState();
376
+ // }
377
+ // }
354
378
  }
355
379
 
356
380
  namespace Amanotes.Core.Internal