com.amanotes.gdk 0.2.57 → 0.2.59
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 +13 -0
- package/Extra/AmaGDKInstaller.unitypackage +0 -0
- package/Extra/CheckDiskSpace.unitypackage +0 -0
- package/Extra/ForceUpdate.unitypackage +0 -0
- package/Extra/PostProcessor.unitypackage +0 -0
- package/Extra/SDKVersionTracking.unitypackage +0 -0
- package/Packages/AmaGDKConfig.unitypackage +0 -0
- package/Packages/AmaGDKExample.unitypackage +0 -0
- package/Packages/AmaGDKTest.unitypackage +0 -0
- package/Packages/AppsFlyerAdapter.unitypackage +0 -0
- package/Packages/FirebaseAnalyticsAdapter.unitypackage +0 -0
- package/Packages/FirebaseRemoteConfigAdapter.unitypackage +0 -0
- package/Packages/IronSourceAdapter.unitypackage +0 -0
- package/Packages/RevenueCatAdapter.unitypackage +0 -0
- package/Packages/SqliteAnalyticsAdapter.unitypackage +0 -0
- package/Runtime/AmaGDK.Ads.cs +45 -4
- package/Runtime/AmaGDK.UserProfile.cs +15 -2
- package/Runtime/AmaGDK.cs +36 -3
- package/Runtime/Internal/AmaGDK.Internal.cs +29 -0
- package/Runtime/Internal/AmaGDK.Utils.cs +42 -0
- package/Runtime/Internal/GDKGeoLocationcs.cs +119 -0
- package/Runtime/Internal/GDKGeoLocationcs.cs.meta +3 -0
- package/Runtime/Internal/GDKServerTime.cs +211 -0
- package/Runtime/Internal/GDKServerTime.cs.meta +3 -0
- package/Runtime/Klavar/KlavarContainer.cs +5 -3
- package/Runtime/Klavar/KlavarEventUtils.cs +3 -3
- package/package.json +1 -1
- package/Runtime/Klavar/KlavarEventTools.cs +0 -92
- package/Runtime/Klavar/KlavarEventTools.cs.meta +0 -11
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,18 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## [0.2.59 - 2024-04-12]
|
|
4
|
+
- [Dev] Improve code coverage
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
## [0.2.58 - 2024-04-09]
|
|
8
|
+
- [DEV] combine code coverage report
|
|
9
|
+
- [Dev] Improve GDK Utils
|
|
10
|
+
- [Dev] Add hints to AdCallback APIs
|
|
11
|
+
- [Fix] timeDiffLastFire always returns 0 in adShowCalled callbacks
|
|
12
|
+
- [Fix] Various warnings fixes due to invalid examples
|
|
13
|
+
- [Fix] Warning on AdContext destroyed caused by invalid editor ad callback
|
|
14
|
+
|
|
15
|
+
|
|
3
16
|
## [0.2.57 - 2024-04-08]
|
|
4
17
|
- [Dev] Fix bug in value conversion within KlavarEvent
|
|
5
18
|
- [Dev] Auto get change log
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
package/Runtime/AmaGDK.Ads.cs
CHANGED
|
@@ -11,6 +11,9 @@ namespace Amanotes.Core
|
|
|
11
11
|
{
|
|
12
12
|
public static class AdExtension
|
|
13
13
|
{
|
|
14
|
+
/// <summary>
|
|
15
|
+
/// Invoke when ad view has opened
|
|
16
|
+
/// </summary>
|
|
14
17
|
public static IAdCallback OnAdOpened(this IAdCallback ad, Action callback)
|
|
15
18
|
{
|
|
16
19
|
if (!MakeSureAdNotNull(ad)) return null;
|
|
@@ -19,6 +22,9 @@ namespace Amanotes.Core
|
|
|
19
22
|
return ad;
|
|
20
23
|
}
|
|
21
24
|
|
|
25
|
+
/// <summary>
|
|
26
|
+
/// The user finished watching the video, and should be rewarded.
|
|
27
|
+
/// </summary>
|
|
22
28
|
public static IAdCallback OnRewardReceived(this IAdCallback ad, Action callback)
|
|
23
29
|
{
|
|
24
30
|
if (!MakeSureAdNotNull(ad)) return null;
|
|
@@ -27,6 +33,9 @@ namespace Amanotes.Core
|
|
|
27
33
|
return ad;
|
|
28
34
|
}
|
|
29
35
|
|
|
36
|
+
/// <summary>
|
|
37
|
+
/// Invoked when the video ad was clicked.
|
|
38
|
+
/// </summary>
|
|
30
39
|
public static IAdCallback OnAdClicked(this IAdCallback ad, Action callback)
|
|
31
40
|
{
|
|
32
41
|
if (!MakeSureAdNotNull(ad)) return null;
|
|
@@ -35,6 +44,9 @@ namespace Amanotes.Core
|
|
|
35
44
|
return ad;
|
|
36
45
|
}
|
|
37
46
|
|
|
47
|
+
/// <summary>
|
|
48
|
+
/// Callback when the rewarded video ad was failed to show
|
|
49
|
+
/// </summary>
|
|
38
50
|
public static IAdCallback OnAdShowFailed(this IAdCallback ad, Action callback)
|
|
39
51
|
{
|
|
40
52
|
if (!MakeSureAdNotNull(ad)) return null;
|
|
@@ -43,6 +55,9 @@ namespace Amanotes.Core
|
|
|
43
55
|
return ad;
|
|
44
56
|
}
|
|
45
57
|
|
|
58
|
+
/// <summary>
|
|
59
|
+
/// Invoked before OnAdOpened but is not reliable (not supported by all adNetworks)
|
|
60
|
+
/// </summary>
|
|
46
61
|
public static IAdCallback OnAdShowSuccess(this IAdCallback ad, Action callback)
|
|
47
62
|
{
|
|
48
63
|
if (!MakeSureAdNotNull(ad)) return null;
|
|
@@ -51,6 +66,9 @@ namespace Amanotes.Core
|
|
|
51
66
|
return ad;
|
|
52
67
|
}
|
|
53
68
|
|
|
69
|
+
/// <summary>
|
|
70
|
+
/// Invoke when ad view is about to be closed
|
|
71
|
+
/// </summary>
|
|
54
72
|
public static IAdCallback OnAdClosed(this IAdCallback ad, Action callback)
|
|
55
73
|
{
|
|
56
74
|
if (!MakeSureAdNotNull(ad)) return null;
|
|
@@ -59,6 +77,11 @@ namespace Amanotes.Core
|
|
|
59
77
|
return ad;
|
|
60
78
|
}
|
|
61
79
|
|
|
80
|
+
/// <summary>
|
|
81
|
+
/// This callback may invokes several times according to the AdShowReadyStatus
|
|
82
|
+
/// - When there is no ad cached (wifi disabled / no internet / wait4Ad / timeout)
|
|
83
|
+
/// - When the ad is cached & ready to show
|
|
84
|
+
/// </summary>
|
|
62
85
|
public static IAdCallback OnAdShowReadyStatus(this IAdCallback ad, Action<AdShowReadyStatus> callback)
|
|
63
86
|
{
|
|
64
87
|
if (!MakeSureAdNotNull(ad)) return null;
|
|
@@ -67,6 +90,10 @@ namespace Amanotes.Core
|
|
|
67
90
|
return ad;
|
|
68
91
|
}
|
|
69
92
|
|
|
93
|
+
/// <summary>
|
|
94
|
+
/// The finalize callback that will always trigger to mark an end for the AdShowRoutine
|
|
95
|
+
///
|
|
96
|
+
/// </summary>
|
|
70
97
|
public static IAdCallback OnAdResult(this IAdCallback ad, Action<bool> callback)
|
|
71
98
|
{
|
|
72
99
|
if (!MakeSureAdNotNull(ad)) return null;
|
|
@@ -77,7 +104,7 @@ namespace Amanotes.Core
|
|
|
77
104
|
|
|
78
105
|
/// <summary>
|
|
79
106
|
/// Call right before the ad actually open (that means Ad has already been cached & available to show).
|
|
80
|
-
/// This callback will not be triggered in case Ad is not available or no internet
|
|
107
|
+
/// This callback will not be triggered in case Ad is not available or no internet (in those case use OnAdShowReadyStatus callback)
|
|
81
108
|
/// </summary>
|
|
82
109
|
public static IAdCallback OnBeforeAdOpen(this IAdCallback ad, Action callback)
|
|
83
110
|
{
|
|
@@ -124,7 +151,8 @@ namespace Amanotes.Core
|
|
|
124
151
|
internal class AdStat
|
|
125
152
|
{
|
|
126
153
|
// per session
|
|
127
|
-
internal float
|
|
154
|
+
internal float prevCallTime;
|
|
155
|
+
internal float currentCallTime;
|
|
128
156
|
internal int callCount;
|
|
129
157
|
|
|
130
158
|
internal float lastSuccessTime;
|
|
@@ -154,7 +182,18 @@ namespace Amanotes.Core
|
|
|
154
182
|
|
|
155
183
|
internal int TimeSinceLastShowCalled(AdType adType)
|
|
156
184
|
{
|
|
157
|
-
|
|
185
|
+
AdStat stat = GetStat(adType);
|
|
186
|
+
AdShowContext context = Ads.context;
|
|
187
|
+
|
|
188
|
+
// Right inside XXX_ShowCalled() callbacks
|
|
189
|
+
if (context != null && context.adType == adType)
|
|
190
|
+
{
|
|
191
|
+
if (stat.callCount == 1) return 0; // first call
|
|
192
|
+
return (int)(stat.currentCallTime - stat.prevCallTime);
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
if (stat.callCount == 0) return 0; // not yet called
|
|
196
|
+
return (int)(Time.realtimeSinceStartup - stat.prevCallTime);
|
|
158
197
|
}
|
|
159
198
|
|
|
160
199
|
internal int TimeSinceLastShowSuccess(AdType adType)
|
|
@@ -626,7 +665,9 @@ namespace Amanotes.Core.Internal
|
|
|
626
665
|
|
|
627
666
|
AdStat stat = Ads.localData.GetStat(adType);
|
|
628
667
|
stat.callCount++;
|
|
629
|
-
stat.
|
|
668
|
+
stat.prevCallTime = stat.currentCallTime;
|
|
669
|
+
stat.currentCallTime = Time.realtimeSinceStartup;
|
|
670
|
+
|
|
630
671
|
dispatcher.Dispatch(
|
|
631
672
|
_isInterstitial ? AmaGDK.Event.INTER_SHOW_CALLED : AmaGDK.Event.REWARD_VIDEO_SHOW_CALLED
|
|
632
673
|
);
|
|
@@ -120,7 +120,17 @@ namespace Amanotes.Core
|
|
|
120
120
|
{
|
|
121
121
|
get => _session;
|
|
122
122
|
}
|
|
123
|
-
|
|
123
|
+
|
|
124
|
+
public string Country
|
|
125
|
+
{
|
|
126
|
+
get => _country;
|
|
127
|
+
set
|
|
128
|
+
{
|
|
129
|
+
_country = ValidateId(value, COUNTRY_CODE_PATTERN);
|
|
130
|
+
SaveIfDirty();
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
|
|
124
134
|
public void UpdateUserId()
|
|
125
135
|
{
|
|
126
136
|
#if UNITY_ANDROID
|
|
@@ -199,12 +209,15 @@ namespace Amanotes.Core
|
|
|
199
209
|
private string _appsFlyerId;
|
|
200
210
|
[SerializeField]
|
|
201
211
|
private string _installationId;
|
|
202
|
-
[SerializeField]
|
|
212
|
+
[SerializeField]
|
|
203
213
|
private int _session;
|
|
214
|
+
[SerializeField]
|
|
215
|
+
private string _country;
|
|
204
216
|
|
|
205
217
|
private const string ALPHANUMERIC_HYPHEN_PATTERN = @"^(?=.*\d)(?=.*[a-zA-Z])(?=.*-).+$";
|
|
206
218
|
private const string ALPHANUMERIC_PATTERN = @"^(?=.*\d)(?=.*[a-zA-Z])[a-zA-Z\d]+$";
|
|
207
219
|
private const string NUMERIC_HYPHEN_PATTERN = @"^(?=.*\d)(?=.*-)[\d-]+$";
|
|
220
|
+
private const string COUNTRY_CODE_PATTERN = @"^[A-Z]{2}$";
|
|
208
221
|
|
|
209
222
|
private const string AMA_DEVICE_ID_KEY = "ama_device_id";
|
|
210
223
|
|
package/Runtime/AmaGDK.cs
CHANGED
|
@@ -17,13 +17,14 @@ namespace Amanotes.Core
|
|
|
17
17
|
{
|
|
18
18
|
public partial class AmaGDK : MonoBehaviour
|
|
19
19
|
{
|
|
20
|
-
public const string VERSION = "0.2.
|
|
20
|
+
public const string VERSION = "0.2.59";
|
|
21
21
|
|
|
22
22
|
internal static AmaGDK _instance;
|
|
23
23
|
internal static Status _status = Status.None;
|
|
24
24
|
internal static bool _allowInit = false;
|
|
25
25
|
public bool autoInit = true;
|
|
26
|
-
|
|
26
|
+
internal static readonly GDKGeoLocation GeoLocation = new GDKGeoLocation();
|
|
27
|
+
internal static readonly GDKServerTime ServerTime = new GDKServerTime();
|
|
27
28
|
private static ConfigAsset _config = null;
|
|
28
29
|
|
|
29
30
|
public static partial class Event
|
|
@@ -173,7 +174,6 @@ namespace Amanotes.Core
|
|
|
173
174
|
}
|
|
174
175
|
}
|
|
175
176
|
|
|
176
|
-
|
|
177
177
|
IEnumerator InitRoutine()
|
|
178
178
|
{
|
|
179
179
|
if (Config == null)
|
|
@@ -192,12 +192,39 @@ namespace Amanotes.Core
|
|
|
192
192
|
yield return InitAdapters(sb);
|
|
193
193
|
|
|
194
194
|
StartModules();
|
|
195
|
+
|
|
196
|
+
ConfigGeoLocation();
|
|
197
|
+
if (Config.enableServerTime)
|
|
198
|
+
{
|
|
199
|
+
ServerTime.UpdateTime();
|
|
200
|
+
}
|
|
201
|
+
|
|
195
202
|
dispatcher.Dispatch(Event.GDK_INIT_END);
|
|
196
203
|
|
|
197
204
|
_status = Status.Ready;
|
|
198
205
|
dispatcher.Dispatch(Event.GDK_READY);
|
|
199
206
|
Debug.Log($"AmaGDK v{VERSION} | {READY} in {Time.realtimeSinceStartup - startTime:#0.00}s\n\n{sb}");
|
|
200
207
|
}
|
|
208
|
+
|
|
209
|
+
private void ConfigGeoLocation()
|
|
210
|
+
{
|
|
211
|
+
if (Config.enableGeoLocation)
|
|
212
|
+
{
|
|
213
|
+
var countryCode = User.Country;
|
|
214
|
+
if (string.IsNullOrWhiteSpace(countryCode))
|
|
215
|
+
{
|
|
216
|
+
GeoLocation.GetCountryCode(remoteCountryCode =>
|
|
217
|
+
{
|
|
218
|
+
User.Country = remoteCountryCode;
|
|
219
|
+
GeoLocation.SetCountryCode(remoteCountryCode);
|
|
220
|
+
});
|
|
221
|
+
}
|
|
222
|
+
else
|
|
223
|
+
{
|
|
224
|
+
GeoLocation.SetCountryCode(countryCode);
|
|
225
|
+
}
|
|
226
|
+
}
|
|
227
|
+
}
|
|
201
228
|
}
|
|
202
229
|
|
|
203
230
|
public partial class AmaGDK // PUBLIC APIS
|
|
@@ -461,4 +488,10 @@ namespace Amanotes.Core
|
|
|
461
488
|
}
|
|
462
489
|
}
|
|
463
490
|
}
|
|
491
|
+
|
|
492
|
+
public class GDKException : Exception
|
|
493
|
+
{
|
|
494
|
+
public GDKException() { }
|
|
495
|
+
public GDKException(string message) : base(message) { }
|
|
496
|
+
}
|
|
464
497
|
}
|
|
@@ -182,4 +182,33 @@ namespace Amanotes.Core.Internal
|
|
|
182
182
|
public interface IOnApplicationQuit { void OnApplicationQuit(); }
|
|
183
183
|
public interface IOnApplicationFocus { void OnApplicationFocus(bool hasFocus); }
|
|
184
184
|
public interface IOnFrameUpdate { void OnFrameUpdate(); }
|
|
185
|
+
|
|
186
|
+
public static class Utils
|
|
187
|
+
{
|
|
188
|
+
/// <summary>
|
|
189
|
+
/// Registers the list of server time providers.
|
|
190
|
+
/// </summary>
|
|
191
|
+
/// <param name="providers">List of server time providers implementing IServerTimeProvider interface or extending BaseServerTimeProvider.</param>
|
|
192
|
+
/// <remarks>
|
|
193
|
+
/// It is mandatory to call RegisterServerTimeProvider before initializing AmaGDK by calling AmaGDK.Init().
|
|
194
|
+
/// </remarks>
|
|
195
|
+
public static void RegisterServerTimeProvider(List<IServerTimeProvider> providers)
|
|
196
|
+
{
|
|
197
|
+
GDKUtils.ThrowIf(AmaGDK._status != Status.None, "Please call RegisterServerTimeProvider() before initializing AmaGDK by calling AmaGDK.Init()");
|
|
198
|
+
ServerTime.SetTimeProviders(providers);
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
/// <summary>
|
|
202
|
+
/// Set the GeoLocation Provider.
|
|
203
|
+
/// </summary>
|
|
204
|
+
/// <param name="provider">provider implementing IGeoLocationProvider interface.</param>
|
|
205
|
+
/// <remarks>
|
|
206
|
+
/// It is mandatory to call SetGeoLocationProvider before initializing AmaGDK by calling AmaGDK.Init().
|
|
207
|
+
/// </remarks>
|
|
208
|
+
public static void SetGeoLocationProvider(IGeoLocationProvider provider)
|
|
209
|
+
{
|
|
210
|
+
GDKUtils.ThrowIf(AmaGDK._status != Status.None, "Please call SetGeoLocationProvider() before initializing AmaGDK by calling AmaGDK.Init()");
|
|
211
|
+
GeoLocation.SetGeoLocationProvider(provider);
|
|
212
|
+
}
|
|
213
|
+
}
|
|
185
214
|
}
|
|
@@ -77,6 +77,42 @@ namespace Amanotes.Core.Internal
|
|
|
77
77
|
// Check if each segment exists in the output string in the correct order
|
|
78
78
|
return AreSegmentsPresentInOrder(segments, formattedString);
|
|
79
79
|
}
|
|
80
|
+
|
|
81
|
+
/// <summary>
|
|
82
|
+
/// Retrieves the current server time adjusted to the user's timezone.
|
|
83
|
+
/// </summary>
|
|
84
|
+
/// <returns>The current server time adjusted to the user's timezone if available; otherwise, null.</returns>
|
|
85
|
+
public static DateTime? GetServerTime()
|
|
86
|
+
{
|
|
87
|
+
return AmaGDK.ServerTime.GetTime();
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
/// <summary>
|
|
91
|
+
/// Asynchronously retrieves the current server time with a callback function, adjusted to the user's timezone.
|
|
92
|
+
/// </summary>
|
|
93
|
+
/// <param name="result">Callback function invoked with the server time adjusted to the user's timezone if available; otherwise, null is passed in case of network or server errors.</param>
|
|
94
|
+
public static void GetServerTime(Action<DateTime?> result)
|
|
95
|
+
{
|
|
96
|
+
AmaGDK.ServerTime.GetTime(result);
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
/// <summary>
|
|
100
|
+
/// Gets the country code.
|
|
101
|
+
/// </summary>
|
|
102
|
+
/// <returns>The country code if available; otherwise, null.</returns>
|
|
103
|
+
public static string GetCountryCode()
|
|
104
|
+
{
|
|
105
|
+
return AmaGDK.GeoLocation.GetCountryCode();
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
/// <summary>
|
|
109
|
+
/// Gets the country code asynchronously with a callback function.
|
|
110
|
+
/// </summary>
|
|
111
|
+
/// <param name="result">Callback function to be invoked with the country code if available; otherwise, null will be passed in case of network or server errors.</param>
|
|
112
|
+
public static void GetCountryCode(Action<string> result)
|
|
113
|
+
{
|
|
114
|
+
AmaGDK.GeoLocation.GetCountryCode(result);
|
|
115
|
+
}
|
|
80
116
|
|
|
81
117
|
static bool AreSegmentsPresentInOrder(string[] segments, string outputString)
|
|
82
118
|
{
|
|
@@ -117,6 +153,12 @@ namespace Amanotes.Core.Internal
|
|
|
117
153
|
segments[matches.Count] = template.Substring(lastIndex);
|
|
118
154
|
return segments;
|
|
119
155
|
}
|
|
156
|
+
|
|
157
|
+
internal static void ThrowIf(bool condition, string message)
|
|
158
|
+
{
|
|
159
|
+
if (condition)
|
|
160
|
+
throw new GDKException(message);
|
|
161
|
+
}
|
|
120
162
|
}
|
|
121
163
|
|
|
122
164
|
public static class GDKReflection
|
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
using System;
|
|
2
|
+
using System.Collections;
|
|
3
|
+
using UnityEngine;
|
|
4
|
+
using UnityEngine.Networking;
|
|
5
|
+
|
|
6
|
+
namespace Amanotes.Core.Internal
|
|
7
|
+
{
|
|
8
|
+
public partial class ConfigAsset
|
|
9
|
+
{
|
|
10
|
+
[SerializeField] public bool enableGeoLocation = true;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
internal class GDKGeoLocation
|
|
14
|
+
{
|
|
15
|
+
private IGeoLocationProvider provider = new CountryIS_GeoLocationProvider();
|
|
16
|
+
private string localCountryCode;
|
|
17
|
+
|
|
18
|
+
public void SetGeoLocationProvider(IGeoLocationProvider provider)
|
|
19
|
+
{
|
|
20
|
+
this.provider = provider;
|
|
21
|
+
}
|
|
22
|
+
public string GetCountryCode()
|
|
23
|
+
{
|
|
24
|
+
GDKUtils.ThrowIf(!AmaGDK.Config.enableGeoLocation, "GeoLocation is disabled, Please enable it in the AmaGDKConfig");
|
|
25
|
+
return localCountryCode;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
public void GetCountryCode(Action<string> result)
|
|
29
|
+
{
|
|
30
|
+
GDKUtils.ThrowIf(!AmaGDK.Config.enableGeoLocation, "GeoLocation is disabled, Please enable it in the AmaGDKConfig");
|
|
31
|
+
if (!string.IsNullOrWhiteSpace(localCountryCode))
|
|
32
|
+
{
|
|
33
|
+
result?.Invoke(localCountryCode);
|
|
34
|
+
return;
|
|
35
|
+
}
|
|
36
|
+
provider.FetchGeoLocation(data =>
|
|
37
|
+
{
|
|
38
|
+
result?.Invoke(data.countryCode?.ToUpper());
|
|
39
|
+
if (data.errorMessage != null)
|
|
40
|
+
Logging.Log(data.errorMessage);
|
|
41
|
+
});
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
internal void SetCountryCode(string countryCode)
|
|
45
|
+
{
|
|
46
|
+
localCountryCode = countryCode;
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
namespace Amanotes.Core
|
|
52
|
+
{
|
|
53
|
+
public class GeoLocationData
|
|
54
|
+
{
|
|
55
|
+
public string countryCode;
|
|
56
|
+
public string errorMessage;
|
|
57
|
+
|
|
58
|
+
public GeoLocationData(string countryCode, string errorMessage = null)
|
|
59
|
+
{
|
|
60
|
+
this.countryCode = countryCode;
|
|
61
|
+
this.errorMessage = errorMessage;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
public static GeoLocationData WithErrorMessage(string message)
|
|
65
|
+
{
|
|
66
|
+
return new GeoLocationData(null, message);
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
public interface IGeoLocationProvider
|
|
71
|
+
{
|
|
72
|
+
public void FetchGeoLocation(Action<GeoLocationData> result);
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
public class CountryIS_GeoLocationProvider: IGeoLocationProvider
|
|
76
|
+
{
|
|
77
|
+
public const string URL = "https://api.country.is/";
|
|
78
|
+
[Serializable]
|
|
79
|
+
private class LocationData
|
|
80
|
+
{
|
|
81
|
+
public string country;
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
void IGeoLocationProvider.FetchGeoLocation(Action<GeoLocationData> result)
|
|
85
|
+
{
|
|
86
|
+
AmaGDK._instance.StartCoroutine(FetchGeoLocationRoutine(result));
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
private IEnumerator FetchGeoLocationRoutine(Action<GeoLocationData> result)
|
|
90
|
+
{
|
|
91
|
+
using (var request = UnityWebRequest.Get(URL))
|
|
92
|
+
{
|
|
93
|
+
yield return request.SendWebRequest();
|
|
94
|
+
|
|
95
|
+
if (request.result != UnityWebRequest.Result.Success)
|
|
96
|
+
{
|
|
97
|
+
result?.Invoke(GeoLocationData.WithErrorMessage($"Error fetching location: {request.error}"));
|
|
98
|
+
yield break;
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
try
|
|
102
|
+
{
|
|
103
|
+
var data = ParseResponse(request.downloadHandler.text);
|
|
104
|
+
result?.Invoke(data);
|
|
105
|
+
}
|
|
106
|
+
catch (Exception e)
|
|
107
|
+
{
|
|
108
|
+
result?.Invoke(GeoLocationData.WithErrorMessage($"Error parsing location data: {e.Message}"));
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
private GeoLocationData ParseResponse(string response)
|
|
114
|
+
{
|
|
115
|
+
var locationData = JsonUtility.FromJson<LocationData>(response);
|
|
116
|
+
return new GeoLocationData(locationData.country);
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
}
|
|
@@ -0,0 +1,211 @@
|
|
|
1
|
+
using System;
|
|
2
|
+
using System.Collections;
|
|
3
|
+
using System.Collections.Generic;
|
|
4
|
+
using UnityEngine;
|
|
5
|
+
using UnityEngine.Networking;
|
|
6
|
+
|
|
7
|
+
namespace Amanotes.Core
|
|
8
|
+
{
|
|
9
|
+
public class ServerTimeData
|
|
10
|
+
{
|
|
11
|
+
public DateTime? time;
|
|
12
|
+
public string errorMessage;
|
|
13
|
+
|
|
14
|
+
public ServerTimeData(DateTime time)
|
|
15
|
+
{
|
|
16
|
+
this.time = time;
|
|
17
|
+
errorMessage = null;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
public ServerTimeData(string errorMessage)
|
|
21
|
+
{
|
|
22
|
+
time = null;
|
|
23
|
+
this.errorMessage = errorMessage;
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
public interface IServerTimeProvider
|
|
28
|
+
{
|
|
29
|
+
public void FetchServerTime(Action<ServerTimeData> result);
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
public abstract class BaseServerTimeProvider : IServerTimeProvider
|
|
33
|
+
{
|
|
34
|
+
public abstract string GetURL();
|
|
35
|
+
public abstract ServerTimeData ParseResponse(string response);
|
|
36
|
+
|
|
37
|
+
public void FetchServerTime(Action<ServerTimeData> result)
|
|
38
|
+
{
|
|
39
|
+
AmaGDK._instance.StartCoroutine(FetchTimeRoutine(result));
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
private IEnumerator FetchTimeRoutine(Action<ServerTimeData> result)
|
|
43
|
+
{
|
|
44
|
+
using (var request = UnityWebRequest.Get(GetURL()))
|
|
45
|
+
{
|
|
46
|
+
yield return request.SendWebRequest();
|
|
47
|
+
|
|
48
|
+
if (request.result != UnityWebRequest.Result.Success)
|
|
49
|
+
{
|
|
50
|
+
result?.Invoke(new ServerTimeData($"Error fetching time: {request.error}"));
|
|
51
|
+
yield break;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
result?.Invoke(ParseResponse(request.downloadHandler.text));
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
internal class WorldTimeServer_TimeProvider : BaseServerTimeProvider
|
|
60
|
+
{
|
|
61
|
+
private const string URL = "https://www.worldtimeserver.com/current_time_in_LA.aspx";
|
|
62
|
+
|
|
63
|
+
public override ServerTimeData ParseResponse(string response)
|
|
64
|
+
{
|
|
65
|
+
string startStr = "id=\"serverTimeStamp\" value=\"";
|
|
66
|
+
int startIndex = response.IndexOf(startStr) + startStr.Length;
|
|
67
|
+
string unixTimeStr = string.Empty;
|
|
68
|
+
char currentChar = char.MinValue;
|
|
69
|
+
for (int i = startIndex, n = response.Length; i < n; i++)
|
|
70
|
+
{
|
|
71
|
+
currentChar = response[i];
|
|
72
|
+
if (currentChar == '.' || currentChar == '\"') break;
|
|
73
|
+
unixTimeStr += currentChar;
|
|
74
|
+
}
|
|
75
|
+
if (long.TryParse(unixTimeStr, out long unixTime))
|
|
76
|
+
{
|
|
77
|
+
DateTimeOffset dateTimeOffset = DateTimeOffset.FromUnixTimeMilliseconds(unixTime);
|
|
78
|
+
return new ServerTimeData(dateTimeOffset.DateTime);
|
|
79
|
+
}
|
|
80
|
+
else
|
|
81
|
+
{
|
|
82
|
+
return new ServerTimeData("Error parsing WorldTimeServer data");
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
public override string GetURL()
|
|
86
|
+
{
|
|
87
|
+
return URL;
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
internal class WorldTimeAPI_TimeProvider : BaseServerTimeProvider
|
|
92
|
+
{
|
|
93
|
+
private const string URL = "https://worldtimeapi.org/api/ip";
|
|
94
|
+
|
|
95
|
+
[Serializable]
|
|
96
|
+
private class TimeData
|
|
97
|
+
{
|
|
98
|
+
public string datetime;
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
public override string GetURL()
|
|
102
|
+
{
|
|
103
|
+
return URL;
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
public override ServerTimeData ParseResponse(string response)
|
|
107
|
+
{
|
|
108
|
+
try
|
|
109
|
+
{
|
|
110
|
+
var data = JsonUtility.FromJson<TimeData>(response);
|
|
111
|
+
DateTime utcTime = DateTime.ParseExact(data.datetime, "yyyy-MM-dd'T'HH:mm:ss.ffffffzzz", System.Globalization.CultureInfo.InvariantCulture, System.Globalization.DateTimeStyles.AdjustToUniversal);
|
|
112
|
+
return new ServerTimeData(utcTime);
|
|
113
|
+
}
|
|
114
|
+
catch (Exception e)
|
|
115
|
+
{
|
|
116
|
+
return new ServerTimeData($"Error parsing time data: {e.Message}");
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
namespace Amanotes.Core.Internal
|
|
123
|
+
{
|
|
124
|
+
public partial class ConfigAsset
|
|
125
|
+
{
|
|
126
|
+
[SerializeField] public bool enableServerTime = true;
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
internal class GDKServerTime
|
|
130
|
+
{
|
|
131
|
+
private const float MAX_WAIT_TIME = 60;
|
|
132
|
+
private List<IServerTimeProvider> providers = new List<IServerTimeProvider>() { new WorldTimeAPI_TimeProvider(), new WorldTimeServer_TimeProvider() };
|
|
133
|
+
private int currentIndex = 0;
|
|
134
|
+
private IServerTimeProvider provider
|
|
135
|
+
{
|
|
136
|
+
get { return providers[currentIndex]; }
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
private DateTime? serverTime;
|
|
140
|
+
private float timeSinceFetchServerTime;
|
|
141
|
+
private int retryCount = 0;
|
|
142
|
+
|
|
143
|
+
internal GDKServerTime()
|
|
144
|
+
{
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
public void SetTimeProviders(List<IServerTimeProvider> providers)
|
|
148
|
+
{
|
|
149
|
+
GDKUtils.ThrowIf(providers == null || providers.Count == 0, "Server time providers list cannot be null or empty.");
|
|
150
|
+
this.providers = providers;
|
|
151
|
+
currentIndex = 0;
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
public DateTime? GetTime()
|
|
155
|
+
{
|
|
156
|
+
GDKUtils.ThrowIf(!AmaGDK.Config.enableServerTime, "ServerTime is disabled, Please enable it in the AmaGDKConfig");
|
|
157
|
+
if (serverTime == null)
|
|
158
|
+
return null;
|
|
159
|
+
float duration = Time.realtimeSinceStartup - timeSinceFetchServerTime;
|
|
160
|
+
return ((DateTime)serverTime).AddSeconds(duration);
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
public void GetTime(Action<DateTime?> result)
|
|
164
|
+
{
|
|
165
|
+
GDKUtils.ThrowIf(!AmaGDK.Config.enableServerTime, "ServerTime is disabled, Please enable it in the AmaGDKConfig");
|
|
166
|
+
if (serverTime == null)
|
|
167
|
+
{
|
|
168
|
+
UpdateTime(result);
|
|
169
|
+
}
|
|
170
|
+
else
|
|
171
|
+
{
|
|
172
|
+
result(GetTime());
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
public void UpdateTime(Action<DateTime?> result = null)
|
|
177
|
+
{
|
|
178
|
+
provider.FetchServerTime(data =>
|
|
179
|
+
{
|
|
180
|
+
if (data.time != null)
|
|
181
|
+
{
|
|
182
|
+
serverTime = data.time;
|
|
183
|
+
timeSinceFetchServerTime = Time.realtimeSinceStartup;
|
|
184
|
+
result?.Invoke(data.time);
|
|
185
|
+
}
|
|
186
|
+
else
|
|
187
|
+
{
|
|
188
|
+
result?.Invoke(null);
|
|
189
|
+
Logging.Log(data.errorMessage);
|
|
190
|
+
FetchTimeWithOtherProvider();
|
|
191
|
+
}
|
|
192
|
+
});
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
private void FetchTimeWithOtherProvider()
|
|
196
|
+
{
|
|
197
|
+
retryCount++;
|
|
198
|
+
currentIndex = (currentIndex + 1) % providers.Count;
|
|
199
|
+
if (retryCount < providers.Count)
|
|
200
|
+
{
|
|
201
|
+
UpdateTime();
|
|
202
|
+
return;
|
|
203
|
+
}
|
|
204
|
+
float waitTime = Mathf.Min(MAX_WAIT_TIME, Mathf.Pow(2, retryCount - providers.Count + 1));
|
|
205
|
+
GDKUtils.DelayCall(waitTime, () =>
|
|
206
|
+
{
|
|
207
|
+
UpdateTime();
|
|
208
|
+
});
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
}
|
|
@@ -11,10 +11,12 @@ namespace Amanotes.Core
|
|
|
11
11
|
public string lastEventName;
|
|
12
12
|
|
|
13
13
|
public static void LogEventError(string message)
|
|
14
|
-
{
|
|
15
|
-
if
|
|
16
|
-
Logging.LogError(message);
|
|
14
|
+
{
|
|
15
|
+
#if UNITY_EDITOR
|
|
17
16
|
throw new KlavarException(message);
|
|
17
|
+
#else
|
|
18
|
+
Logging.LogError(message);
|
|
19
|
+
#endif
|
|
18
20
|
}
|
|
19
21
|
}
|
|
20
22
|
|
|
@@ -39,14 +39,14 @@ namespace Amanotes.Core
|
|
|
39
39
|
public static string ToCamelCase(string text)
|
|
40
40
|
{
|
|
41
41
|
var tokens = ToTokens(text);
|
|
42
|
-
return string.Join("", tokens.Select(t
|
|
42
|
+
return string.Join("", tokens.Select((t, i) =>
|
|
43
|
+
(i == 0 ? Char.ToLower(t[0]) : Char.ToUpper(t[0])) + t.Substring(1).ToLower()));
|
|
43
44
|
}
|
|
44
45
|
|
|
45
46
|
public static string ToPascalCase(string text)
|
|
46
47
|
{
|
|
47
48
|
var tokens = ToTokens(text);
|
|
48
|
-
return string.Join("", tokens.Select((t
|
|
49
|
-
(i == 0 ? Char.ToLower(t[0]) : Char.ToUpper(t[0])) + t.Substring(1).ToLower()));
|
|
49
|
+
return string.Join("", tokens.Select(t => Char.ToUpper(t[0]) + t.Substring(1).ToLower()));
|
|
50
50
|
}
|
|
51
51
|
|
|
52
52
|
public static string ToKebabCase(string text)
|
package/package.json
CHANGED
|
@@ -1,92 +0,0 @@
|
|
|
1
|
-
//
|
|
2
|
-
// #if UNITY_EDITOR
|
|
3
|
-
//
|
|
4
|
-
// using System.Linq;
|
|
5
|
-
// using System.Collections;
|
|
6
|
-
// using UnityEditor;
|
|
7
|
-
// using UnityEngine;
|
|
8
|
-
//
|
|
9
|
-
// using System.IO;
|
|
10
|
-
// using System.Collections.Generic;
|
|
11
|
-
// using System;
|
|
12
|
-
//
|
|
13
|
-
// namespace Amanotes.Core
|
|
14
|
-
// {
|
|
15
|
-
// /// <summary>
|
|
16
|
-
// /// Prety Log Event Tools
|
|
17
|
-
// /// </summary>
|
|
18
|
-
// public class KlavarEventTools
|
|
19
|
-
// {
|
|
20
|
-
// public class KlavarEventLine
|
|
21
|
-
// {
|
|
22
|
-
// public string No;
|
|
23
|
-
// public string EventName;
|
|
24
|
-
// public string EventParameterName;
|
|
25
|
-
//
|
|
26
|
-
// public string ValueType;
|
|
27
|
-
//
|
|
28
|
-
// public string ParameterValue;
|
|
29
|
-
//
|
|
30
|
-
// public bool IsInvalid()
|
|
31
|
-
// {
|
|
32
|
-
// return string.IsNullOrWhiteSpace(No)
|
|
33
|
-
// && string.IsNullOrWhiteSpace(EventName)
|
|
34
|
-
// && string.IsNullOrWhiteSpace(EventParameterName)
|
|
35
|
-
// && string.IsNullOrWhiteSpace(ValueType)
|
|
36
|
-
// && string.IsNullOrWhiteSpace(ParameterValue);
|
|
37
|
-
// }
|
|
38
|
-
// }
|
|
39
|
-
//
|
|
40
|
-
// static private IEnumerable<T[]> Chunk<T>(IEnumerable<T> colection, Func<T, bool> splitter)
|
|
41
|
-
// {
|
|
42
|
-
//
|
|
43
|
-
// IEnumerator<T> iter = colection.GetEnumerator();
|
|
44
|
-
// var running = iter.MoveNext();
|
|
45
|
-
//
|
|
46
|
-
// IEnumerable<T> OneChunk()
|
|
47
|
-
// {
|
|
48
|
-
// yield return iter.Current;
|
|
49
|
-
// while (running = iter.MoveNext())
|
|
50
|
-
// {
|
|
51
|
-
// var val = iter.Current;
|
|
52
|
-
// if (splitter(val)) break;
|
|
53
|
-
// yield return val;
|
|
54
|
-
// }
|
|
55
|
-
// }
|
|
56
|
-
//
|
|
57
|
-
// while (running)
|
|
58
|
-
// {
|
|
59
|
-
// var chunk = OneChunk().ToArray();
|
|
60
|
-
// if (chunk.Length > 0) yield return chunk;
|
|
61
|
-
// }
|
|
62
|
-
// }
|
|
63
|
-
//
|
|
64
|
-
//
|
|
65
|
-
// static void ConvertFromCSV()
|
|
66
|
-
// {
|
|
67
|
-
//
|
|
68
|
-
// // string path = EditorUtility.OpenFilePanel("Overwrite with png", ".", "tsv");
|
|
69
|
-
//
|
|
70
|
-
// var path = "/Users/nam.dn/Downloads/Test Pretty Event - Ad Mon.tsv";
|
|
71
|
-
// if (string.IsNullOrEmpty(path)) return;
|
|
72
|
-
//
|
|
73
|
-
//
|
|
74
|
-
// Debug.Log(path);
|
|
75
|
-
// string text = File.ReadAllText(path);
|
|
76
|
-
// var lines = Amanotes.Klavar.TSVParser
|
|
77
|
-
// .Parse<KlavarEventLine>(text)
|
|
78
|
-
// .Where(line => !line.IsInvalid());
|
|
79
|
-
//
|
|
80
|
-
// var linesEvents = Chunk(lines, line => !string.IsNullOrEmpty(line.No));
|
|
81
|
-
// foreach (var linesEvent in linesEvents)
|
|
82
|
-
// {
|
|
83
|
-
// Debug.Log(linesEvent[0]);
|
|
84
|
-
// Debug.Log(linesEvent.Length);
|
|
85
|
-
//
|
|
86
|
-
// var linesParams = Chunk(lines, line => !string.IsNullOrEmpty(line.EventParameterName));
|
|
87
|
-
//
|
|
88
|
-
// }
|
|
89
|
-
// }
|
|
90
|
-
// }
|
|
91
|
-
// }
|
|
92
|
-
// #endif
|