com.amanotes.gdk 0.1.3
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 +6 -0
- package/CHANGELOG.md.meta +7 -0
- package/Editor/AmaGDK.Editor.asmdef +18 -0
- package/Editor/AmaGDK.Editor.asmdef.meta +7 -0
- package/Editor/AmaGDKEditor.cs +210 -0
- package/Editor/AmaGDKEditor.cs.meta +11 -0
- package/Editor.meta +8 -0
- package/LICENSE.md +7 -0
- package/LICENSE.md.meta +7 -0
- package/Packages/AmaGDKConfig.unitypackage +0 -0
- package/Packages/AmaGDKConfig.unitypackage.meta +8 -0
- package/Packages/AppsflyerAdapter_v6.5.4.unitypackage +0 -0
- package/Packages/AppsflyerAdapter_v6.5.4.unitypackage.meta +7 -0
- package/Packages/FirebaseAnalyticsAdapter_v9.1.0.unitypackage +0 -0
- package/Packages/FirebaseAnalyticsAdapter_v9.1.0.unitypackage.meta +7 -0
- package/Packages.meta +8 -0
- package/README.md +44 -0
- package/README.md.meta +7 -0
- package/Runtime/AmaGDK.Adapters.cs +45 -0
- package/Runtime/AmaGDK.Adapters.cs.meta +11 -0
- package/Runtime/AmaGDK.Analytics.cs +454 -0
- package/Runtime/AmaGDK.Analytics.cs.meta +11 -0
- package/Runtime/AmaGDK.Config.cs +13 -0
- package/Runtime/AmaGDK.Config.cs.meta +11 -0
- package/Runtime/AmaGDK.Internal.cs +133 -0
- package/Runtime/AmaGDK.Internal.cs.meta +11 -0
- package/Runtime/AmaGDK.UserProfile.cs +41 -0
- package/Runtime/AmaGDK.UserProfile.cs.meta +11 -0
- package/Runtime/AmaGDK.Utils.cs +121 -0
- package/Runtime/AmaGDK.Utils.cs.meta +11 -0
- package/Runtime/AmaGDK.asmdef +14 -0
- package/Runtime/AmaGDK.asmdef.meta +7 -0
- package/Runtime/AmaGDK.cs +159 -0
- package/Runtime/AmaGDK.cs.meta +11 -0
- package/Runtime/AmaGDK.prefab +46 -0
- package/Runtime/AmaGDK.prefab.meta +8 -0
- package/Runtime/AssemblyInfo.cs +8 -0
- package/Runtime/AssemblyInfo.cs.meta +11 -0
- package/Runtime/Interfaces/Analytics/IAnalytics.cs +6 -0
- package/Runtime/Interfaces/Analytics/IAnalytics.cs.meta +11 -0
- package/Runtime/Interfaces/Analytics.meta +8 -0
- package/Runtime/Interfaces.meta +8 -0
- package/Runtime.meta +8 -0
- package/Tests/Editor/AmaGDK.Editor.Test.asmdef +23 -0
- package/Tests/Editor/AmaGDK.Editor.Test.asmdef.meta +7 -0
- package/Tests/Editor.meta +8 -0
- package/Tests/Runtime/AmaGDK.Test.asmdef +20 -0
- package/Tests/Runtime/AmaGDK.Test.asmdef.meta +7 -0
- package/Tests/Runtime/AmaGDKCoreTest.cs +229 -0
- package/Tests/Runtime/AmaGDKCoreTest.cs.meta +11 -0
- package/Tests/Runtime/MigrationTest.cs +165 -0
- package/Tests/Runtime/MigrationTest.cs.meta +11 -0
- package/Tests/Runtime.meta +8 -0
- package/Tests/TestScene00.unity +125 -0
- package/Tests/TestScene00.unity.meta +7 -0
- package/Tests/TestScene01.unity +199 -0
- package/Tests/TestScene01.unity.meta +7 -0
- package/Tests/TestScene02.unity +209 -0
- package/Tests/TestScene02.unity.meta +7 -0
- package/Tests/TestScene03.unity +599 -0
- package/Tests/TestScene03.unity.meta +7 -0
- package/Tests.meta +8 -0
- package/package.json +18 -0
- package/package.json.meta +7 -0
|
@@ -0,0 +1,454 @@
|
|
|
1
|
+
using System;
|
|
2
|
+
using System.Collections.Generic;
|
|
3
|
+
using UnityEngine;
|
|
4
|
+
|
|
5
|
+
using Amanotes.Core.Internal;
|
|
6
|
+
using static Amanotes.Core.Internal.Logging;
|
|
7
|
+
using IEventParamsBuilder = Amanotes.Core.AmaGDK.Analytics.IEventParamsBuilder;
|
|
8
|
+
using EventParams = Amanotes.Core.AmaGDK.Analytics.EventParams;
|
|
9
|
+
|
|
10
|
+
namespace Amanotes.Core
|
|
11
|
+
{
|
|
12
|
+
partial class AmaGDK
|
|
13
|
+
{
|
|
14
|
+
//PUBLIC APIS
|
|
15
|
+
public static partial class Analytics
|
|
16
|
+
{
|
|
17
|
+
public interface IEventParamsBuilder { }
|
|
18
|
+
|
|
19
|
+
public class EventParams : IEventParamsBuilder
|
|
20
|
+
{
|
|
21
|
+
public string eventName;
|
|
22
|
+
public Dictionary<string, object> parameters = new Dictionary<string, object>();
|
|
23
|
+
public string funnelSignature;
|
|
24
|
+
public bool accumulated;
|
|
25
|
+
public HashSet<string> ignoreAnalyticIds = new HashSet<string>();
|
|
26
|
+
public HashSet<string> allowAnalyticIds = new HashSet<string>();
|
|
27
|
+
|
|
28
|
+
public EventParams(string eventName)
|
|
29
|
+
{
|
|
30
|
+
this.eventName = eventName;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
public bool IsFunnelEvent
|
|
34
|
+
{
|
|
35
|
+
get { return !string.IsNullOrEmpty(funnelSignature); }
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
public static IEventParamsBuilder LogEvent(string eventName)
|
|
40
|
+
{
|
|
41
|
+
var result = new EventParams(eventName);
|
|
42
|
+
eventQueue.Enqueue(result);
|
|
43
|
+
return result;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
public static IEventParamsBuilder LogFunnelEvent(string eventName, string signature = "")
|
|
47
|
+
{
|
|
48
|
+
return LogEvent(eventName).SetAsFunnel(signature);
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
public static int GetAccumulatedCount(string eventName)
|
|
52
|
+
{
|
|
53
|
+
var eventDetail = localData.GetEventDetail(eventName);
|
|
54
|
+
return eventDetail != null ? eventDetail.count : 0;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
public static void SetLogEventCondition(Predicate<EventDetail> condition)
|
|
58
|
+
{
|
|
59
|
+
if (logEventHook != null) LogWarning("LogEventCondition has already set! Please make sure to call it once.");
|
|
60
|
+
logEventHook = condition;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
public static void SetUserId(string userId)
|
|
64
|
+
{
|
|
65
|
+
if (listAdapters.Count == 0)
|
|
66
|
+
{
|
|
67
|
+
LogWarningOnce("ListAnalyticsAdapter is empty! Maybe you need to wait for Analytics to init");
|
|
68
|
+
return;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
foreach (var s in listAdapters)
|
|
72
|
+
{
|
|
73
|
+
s.SetUserId(userId);
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
public static void SetUserProperty(string key, string value)
|
|
78
|
+
{
|
|
79
|
+
if (listAdapters.Count == 0)
|
|
80
|
+
{
|
|
81
|
+
LogWarningOnce("ListAnalyticsAdapter is empty! Maybe you need to wait for Analytics to init");
|
|
82
|
+
return;
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
foreach (var s in listAdapters)
|
|
86
|
+
{
|
|
87
|
+
s.SetUserProperty(key, value);
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
private static IntegrityFlag MergeData(List<string> funnelEvents, Dictionary<string, int> eventCountMap, bool sumEventCount)
|
|
92
|
+
{
|
|
93
|
+
var flag = IntegrityFlag.Ok;
|
|
94
|
+
|
|
95
|
+
foreach (var e in funnelEvents)
|
|
96
|
+
{
|
|
97
|
+
if (localData.funnelSignatures.Contains(e)) continue;
|
|
98
|
+
|
|
99
|
+
flag |= IntegrityFlag.NewFunnel;
|
|
100
|
+
localData.AddFunnelSignature(e);
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
foreach (var e in eventCountMap)
|
|
104
|
+
{
|
|
105
|
+
var eventDetail = localData.GetEventDetail(e.Key);
|
|
106
|
+
if (eventDetail == null)
|
|
107
|
+
{
|
|
108
|
+
localData.eventDetails.Add(new EventDetail
|
|
109
|
+
{
|
|
110
|
+
eventName = e.Key,
|
|
111
|
+
count = e.Value
|
|
112
|
+
});
|
|
113
|
+
flag |= IntegrityFlag.NewEvent;
|
|
114
|
+
continue;
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
if (eventDetail.count != e.Value)
|
|
118
|
+
{
|
|
119
|
+
flag |= IntegrityFlag.DifferentCount;
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
if (sumEventCount)
|
|
123
|
+
{
|
|
124
|
+
eventDetail.count += e.Value;
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
return flag;
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
public static void Migrate(List<string> lsFunnelEvents, Dictionary<string, int> dicEventCounts)
|
|
132
|
+
{
|
|
133
|
+
var migrationLog = localData.migrationLog;
|
|
134
|
+
|
|
135
|
+
//First time
|
|
136
|
+
if (migrationLog.count == 0)
|
|
137
|
+
{
|
|
138
|
+
MergeData(lsFunnelEvents, dicEventCounts, true);
|
|
139
|
+
localData.UpdateMigrationLog();
|
|
140
|
+
return;
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
//Integrity check
|
|
144
|
+
if (!Config.common.checkMigrationIntegrity)
|
|
145
|
+
return;
|
|
146
|
+
|
|
147
|
+
// False: DO NOT UPDATE EXISTED COUNT VALUE BECAUSE WE DON'T HAVE
|
|
148
|
+
// ENOUGH INFORMATION TO DECIDE WHICH ONE IS MORE ACCURATE
|
|
149
|
+
var flag = MergeData(lsFunnelEvents, dicEventCounts, false);
|
|
150
|
+
if (flag == IntegrityFlag.Ok) return;
|
|
151
|
+
|
|
152
|
+
localData.UpdateMigrationLog();
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
//INTERNAL
|
|
157
|
+
public static partial class Analytics
|
|
158
|
+
{
|
|
159
|
+
internal static Predicate<EventDetail> logEventHook = null;
|
|
160
|
+
internal static readonly Queue<EventParams> eventQueue = new Queue<EventParams>();
|
|
161
|
+
internal static readonly List<IAnalyticAdapter> listAdapters = new List<IAnalyticAdapter>();
|
|
162
|
+
internal static readonly AnalyticsData localData = new AnalyticsData().LoadJsonFromFile();
|
|
163
|
+
|
|
164
|
+
internal static void GetAnalyticAdapters()
|
|
165
|
+
{
|
|
166
|
+
listAdapters.Clear();
|
|
167
|
+
listAdapters.AddRange(Adapter.FindAll<IAnalyticAdapter>());
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
internal static void ProcessEventQueue()
|
|
171
|
+
{
|
|
172
|
+
if (eventQueue.Count <= 0) return;
|
|
173
|
+
|
|
174
|
+
while (eventQueue.Count > 0)
|
|
175
|
+
{
|
|
176
|
+
var eventData = eventQueue.Dequeue();
|
|
177
|
+
|
|
178
|
+
if (!NormalizeEventName(ref eventData.eventName))
|
|
179
|
+
continue;
|
|
180
|
+
|
|
181
|
+
var counter = localData.IncreaseCounter(eventData.eventName);
|
|
182
|
+
|
|
183
|
+
if (!ShouldSendEvent(eventData))
|
|
184
|
+
continue;
|
|
185
|
+
|
|
186
|
+
if (eventData.accumulated)
|
|
187
|
+
{
|
|
188
|
+
eventData.AddParam("accumulated_count", counter);
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
Log($"Send {eventData.eventName}, count {counter}");
|
|
192
|
+
foreach (var m in listAdapters)
|
|
193
|
+
{
|
|
194
|
+
if (eventData.ignoreAnalyticIds.Contains(((IAdapter)m).Id))
|
|
195
|
+
continue;
|
|
196
|
+
m.LogEvent(eventData);
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
localData.SaveIfDirty();
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
internal static bool NormalizeEventName(ref string eventName)
|
|
204
|
+
{
|
|
205
|
+
if (string.IsNullOrWhiteSpace(eventName))
|
|
206
|
+
{
|
|
207
|
+
LogWarningOnce($"Invalid EventName: <{eventName}> ");
|
|
208
|
+
return false;
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
var sb = tmpWarningSB;
|
|
212
|
+
sb.Clear();
|
|
213
|
+
|
|
214
|
+
var normalizedEventName = eventName.Trim()
|
|
215
|
+
.Replace(' ', '_')
|
|
216
|
+
.Replace('-', '_');
|
|
217
|
+
|
|
218
|
+
if (eventName != normalizedEventName)
|
|
219
|
+
{
|
|
220
|
+
if (Config.common.normalizeEventName)
|
|
221
|
+
{
|
|
222
|
+
eventName = normalizedEventName;
|
|
223
|
+
}
|
|
224
|
+
else
|
|
225
|
+
{
|
|
226
|
+
sb.AppendLine($" - Malformed eventName (should not contains <space> or <dash>: <{eventName}>");
|
|
227
|
+
}
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
if (!char.IsLetter(eventName[0])) sb.AppendLine($" - EventName must start with a letter: <{eventName}> ");
|
|
231
|
+
if (eventName.Length > 40) sb.AppendLine($" - EventName is too long ({eventName.Length} > 40): <{eventName}> ");
|
|
232
|
+
if (sb.Length > 0) LogWarningOnce(sb.ToString(), $"NormalizeEventName<{eventName}>");
|
|
233
|
+
return true;
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
internal static bool ShouldSendEvent(EventParams eventData)
|
|
237
|
+
{
|
|
238
|
+
//Funnel event
|
|
239
|
+
if (eventData.IsFunnelEvent)
|
|
240
|
+
{
|
|
241
|
+
return localData.AddFunnelSignature(eventData.funnelSignature);
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
//Check the rule to log event
|
|
245
|
+
if (logEventHook == null) return true;
|
|
246
|
+
var eventDetail = localData.GetEventDetail(eventData.eventName, true);
|
|
247
|
+
return logEventHook(eventDetail);
|
|
248
|
+
}
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
//PERSISTENT DATA
|
|
252
|
+
public static partial class Analytics
|
|
253
|
+
{
|
|
254
|
+
[Serializable]
|
|
255
|
+
public class EventDetail
|
|
256
|
+
{
|
|
257
|
+
public string eventName;
|
|
258
|
+
public int count;
|
|
259
|
+
}
|
|
260
|
+
|
|
261
|
+
[Flags]
|
|
262
|
+
internal enum IntegrityFlag
|
|
263
|
+
{
|
|
264
|
+
Ok = 0,
|
|
265
|
+
NewFunnel = 1,
|
|
266
|
+
NewEvent = 2,
|
|
267
|
+
DifferentCount = 4
|
|
268
|
+
}
|
|
269
|
+
|
|
270
|
+
[Serializable]
|
|
271
|
+
public class MigrationLog
|
|
272
|
+
{
|
|
273
|
+
public string deviceId;
|
|
274
|
+
public string appVersion;
|
|
275
|
+
public string amaGDKVersion;
|
|
276
|
+
public int count;
|
|
277
|
+
|
|
278
|
+
public Dictionary<string, object> ToDictionary()
|
|
279
|
+
{
|
|
280
|
+
var result = new Dictionary<string, object>();
|
|
281
|
+
result.Add("device_id", deviceId);
|
|
282
|
+
result.Add("app_version", appVersion);
|
|
283
|
+
result.Add("amagdk_version", amaGDKVersion);
|
|
284
|
+
return result;
|
|
285
|
+
}
|
|
286
|
+
}
|
|
287
|
+
|
|
288
|
+
[Serializable]
|
|
289
|
+
internal class AnalyticsData : IJsonFile
|
|
290
|
+
{
|
|
291
|
+
[NonSerialized] internal bool _dirty = false;
|
|
292
|
+
|
|
293
|
+
public List<string> funnelSignatures = new List<string>();
|
|
294
|
+
public List<EventDetail> eventDetails = new List<EventDetail>();
|
|
295
|
+
public MigrationLog migrationLog = new MigrationLog();
|
|
296
|
+
|
|
297
|
+
internal EventDetail GetEventDetail(string eventName, bool autoNew = false)
|
|
298
|
+
{
|
|
299
|
+
var result = eventDetails.Find(e => e.eventName == eventName);
|
|
300
|
+
if (result != null) return result;
|
|
301
|
+
if (autoNew == false) return null;
|
|
302
|
+
|
|
303
|
+
result = new EventDetail
|
|
304
|
+
{
|
|
305
|
+
eventName = eventName
|
|
306
|
+
};
|
|
307
|
+
eventDetails.Add(result);
|
|
308
|
+
_dirty = true;
|
|
309
|
+
return result;
|
|
310
|
+
}
|
|
311
|
+
|
|
312
|
+
internal bool AddFunnelSignature(string signature)
|
|
313
|
+
{
|
|
314
|
+
if (funnelSignatures.Contains(signature))
|
|
315
|
+
{
|
|
316
|
+
return false;
|
|
317
|
+
}
|
|
318
|
+
|
|
319
|
+
_dirty = true;
|
|
320
|
+
funnelSignatures.Add(signature);
|
|
321
|
+
return true;
|
|
322
|
+
}
|
|
323
|
+
|
|
324
|
+
internal int IncreaseCounter(string eventName)
|
|
325
|
+
{
|
|
326
|
+
var result = GetEventDetail(eventName, true);
|
|
327
|
+
result.count++;
|
|
328
|
+
_dirty = true;
|
|
329
|
+
return result.count;
|
|
330
|
+
}
|
|
331
|
+
|
|
332
|
+
internal void SaveIfDirty()
|
|
333
|
+
{
|
|
334
|
+
if (!_dirty) return;
|
|
335
|
+
_dirty = false;
|
|
336
|
+
this.SaveJsonToFile();
|
|
337
|
+
}
|
|
338
|
+
|
|
339
|
+
internal void UpdateMigrationLog()
|
|
340
|
+
{
|
|
341
|
+
if (migrationLog.count == 0) // reset migration log
|
|
342
|
+
{
|
|
343
|
+
migrationLog.deviceId = SystemInfo.deviceUniqueIdentifier;
|
|
344
|
+
migrationLog.appVersion = Application.version;
|
|
345
|
+
migrationLog.amaGDKVersion = AmaGDK.VERSION;
|
|
346
|
+
migrationLog.count = 1;
|
|
347
|
+
Log($"Analytics data was migrated successfully");
|
|
348
|
+
}
|
|
349
|
+
else
|
|
350
|
+
{
|
|
351
|
+
migrationLog.count++;
|
|
352
|
+
Log($"Analytics data was migrated {migrationLog.count} times");
|
|
353
|
+
|
|
354
|
+
if (migrationLog.count == 2)
|
|
355
|
+
{
|
|
356
|
+
LogEvent("migration_error").AddParam(migrationLog.ToDictionary());
|
|
357
|
+
}
|
|
358
|
+
}
|
|
359
|
+
|
|
360
|
+
_dirty = true;
|
|
361
|
+
SaveIfDirty();
|
|
362
|
+
}
|
|
363
|
+
}
|
|
364
|
+
}
|
|
365
|
+
}
|
|
366
|
+
|
|
367
|
+
public static class EventParamsExtension
|
|
368
|
+
{
|
|
369
|
+
public static IEventParamsBuilder SetAsFunnel(this IEventParamsBuilder ap, string signature = null)
|
|
370
|
+
{
|
|
371
|
+
if (ap == null) return null;
|
|
372
|
+
|
|
373
|
+
EventParams data = ap as EventParams;
|
|
374
|
+
data.funnelSignature = string.IsNullOrEmpty(signature) ? data.eventName : signature;
|
|
375
|
+
return ap;
|
|
376
|
+
}
|
|
377
|
+
public static IEventParamsBuilder SetAsAccumulated(this IEventParamsBuilder ap)
|
|
378
|
+
{
|
|
379
|
+
if (ap == null) return null;
|
|
380
|
+
|
|
381
|
+
(ap as EventParams).accumulated = true;
|
|
382
|
+
return ap;
|
|
383
|
+
}
|
|
384
|
+
|
|
385
|
+
public static IEventParamsBuilder Except(this IEventParamsBuilder ap, params string[] analyticIds)
|
|
386
|
+
{
|
|
387
|
+
if (ap == null) return null;
|
|
388
|
+
|
|
389
|
+
EventParams eventData = ap as EventParams;
|
|
390
|
+
foreach (var mId in analyticIds)
|
|
391
|
+
{
|
|
392
|
+
eventData.ignoreAnalyticIds.Add(mId);
|
|
393
|
+
}
|
|
394
|
+
return ap;
|
|
395
|
+
}
|
|
396
|
+
|
|
397
|
+
public static IEventParamsBuilder OnlyTo(this IEventParamsBuilder ap, params string[] analyticIds)
|
|
398
|
+
{
|
|
399
|
+
if (ap == null) return null;
|
|
400
|
+
|
|
401
|
+
EventParams eventData = ap as EventParams;
|
|
402
|
+
foreach (var mId in analyticIds)
|
|
403
|
+
{
|
|
404
|
+
eventData.allowAnalyticIds.Add(mId);
|
|
405
|
+
}
|
|
406
|
+
return ap;
|
|
407
|
+
}
|
|
408
|
+
|
|
409
|
+
public static IEventParamsBuilder AddParam(this IEventParamsBuilder ap, string key, object value)
|
|
410
|
+
{
|
|
411
|
+
if (ap == null) return null;
|
|
412
|
+
|
|
413
|
+
var parameters = (ap as EventParams).parameters;
|
|
414
|
+
if (parameters.ContainsKey(key))
|
|
415
|
+
{
|
|
416
|
+
LogWarning($"Duplicated key: {key}!");
|
|
417
|
+
return ap;
|
|
418
|
+
};
|
|
419
|
+
|
|
420
|
+
parameters.Add(key, value);
|
|
421
|
+
return ap;
|
|
422
|
+
}
|
|
423
|
+
|
|
424
|
+
public static IEventParamsBuilder AddParam(this IEventParamsBuilder ap, Dictionary<string, object> dictParams)
|
|
425
|
+
{
|
|
426
|
+
if (ap == null) return null;
|
|
427
|
+
|
|
428
|
+
foreach (var kvp in dictParams)
|
|
429
|
+
{
|
|
430
|
+
ap.AddParam(kvp.Key, kvp.Value);
|
|
431
|
+
}
|
|
432
|
+
return ap;
|
|
433
|
+
}
|
|
434
|
+
|
|
435
|
+
}
|
|
436
|
+
}
|
|
437
|
+
|
|
438
|
+
namespace Amanotes.Core.Internal
|
|
439
|
+
{
|
|
440
|
+
partial class SDKConfig
|
|
441
|
+
{
|
|
442
|
+
public bool normalizeEventName;
|
|
443
|
+
public bool checkMigrationIntegrity;
|
|
444
|
+
}
|
|
445
|
+
|
|
446
|
+
public interface IAnalyticAdapter
|
|
447
|
+
{
|
|
448
|
+
void LogEvent(EventParams eventData);
|
|
449
|
+
|
|
450
|
+
void SetUserId(string userId);
|
|
451
|
+
|
|
452
|
+
void SetUserProperty(string key, string value);
|
|
453
|
+
}
|
|
454
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
using System;
|
|
2
|
+
using UnityEngine;
|
|
3
|
+
|
|
4
|
+
namespace Amanotes.Core.Internal {
|
|
5
|
+
public partial class ConfigAsset : ScriptableObject
|
|
6
|
+
{
|
|
7
|
+
[SerializeField] internal SDKConfig common;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
[Serializable] internal partial class SDKConfig {
|
|
11
|
+
public bool verboseLog = false;
|
|
12
|
+
}
|
|
13
|
+
}
|
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
using System.Linq;
|
|
2
|
+
using System.Text;
|
|
3
|
+
using System.Collections.Generic;
|
|
4
|
+
|
|
5
|
+
using UnityEngine;
|
|
6
|
+
using UnityObject = UnityEngine.Object;
|
|
7
|
+
|
|
8
|
+
namespace Amanotes.Core.Internal
|
|
9
|
+
{
|
|
10
|
+
public enum Status
|
|
11
|
+
{
|
|
12
|
+
None,
|
|
13
|
+
Initialize,
|
|
14
|
+
Ready,
|
|
15
|
+
Failed
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
public static class Messsage
|
|
19
|
+
{
|
|
20
|
+
public const string READY = "init success!";
|
|
21
|
+
public const string SDK_INIT_CALLED = "init has been called!";
|
|
22
|
+
public const string MULTIPLE_INSTANCE = "multiple instance found!";
|
|
23
|
+
public const string CONFIG_NOT_FOUND = "AmaGDKConfig not found in Resources!";
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
public static class Res
|
|
27
|
+
{
|
|
28
|
+
#if AMAGDK_DEV
|
|
29
|
+
public const string BASE_PATH = "Assets/AmaGDKCore/";
|
|
30
|
+
#else
|
|
31
|
+
public const string BASE_PATH = "Packages/com.amanotes.gdk/";
|
|
32
|
+
#endif
|
|
33
|
+
|
|
34
|
+
public const string PACKAGE_PATH = BASE_PATH + "Packages/";
|
|
35
|
+
public const string AMAGDK_PREFAB = BASE_PATH + "AmaGDK.prefab";
|
|
36
|
+
public const string AMAGDK_CONFIG_PACKAGE = PACKAGE_PATH + "AmaGDKConfig.unitypackage";
|
|
37
|
+
|
|
38
|
+
public static readonly string[] AMAGDK_ADAPTERS = new string[]
|
|
39
|
+
{
|
|
40
|
+
"FirebaseAnalyticsAdapter_v9.1.0",
|
|
41
|
+
"AppsflyerAdapter_v6.5.4",
|
|
42
|
+
};
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
public static class Logging
|
|
47
|
+
{
|
|
48
|
+
public static readonly StringBuilder tmpWarningSB = new StringBuilder();
|
|
49
|
+
public static readonly HashSet<string> logWarningDict = new HashSet<string>();
|
|
50
|
+
|
|
51
|
+
public static void LogWarningOnce(string message, string key = null)
|
|
52
|
+
{
|
|
53
|
+
if (string.IsNullOrEmpty(key)) key = message;
|
|
54
|
+
if (logWarningDict.Contains(key)) return;
|
|
55
|
+
logWarningDict.Add(key);
|
|
56
|
+
Debug.LogWarning("[AmaGDK] " + message);
|
|
57
|
+
}
|
|
58
|
+
public static void LogWarning(string message)
|
|
59
|
+
{
|
|
60
|
+
Debug.LogWarning("[AmaGDK] " + message);
|
|
61
|
+
}
|
|
62
|
+
public static void LogError(string message)
|
|
63
|
+
{
|
|
64
|
+
Debug.LogError("[AmaGDK] " + message);
|
|
65
|
+
}
|
|
66
|
+
public static void Log(string message)
|
|
67
|
+
{
|
|
68
|
+
Debug.Log("[AmaGDK] " + message);
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
public static class Adapter {
|
|
73
|
+
internal static readonly List<IAdapter> listAdapters = new List<IAdapter>();
|
|
74
|
+
|
|
75
|
+
public static void Register(IAdapter adapter)
|
|
76
|
+
{
|
|
77
|
+
if (AmaGDK._status != Status.None)
|
|
78
|
+
{
|
|
79
|
+
Logging.LogWarningOnce($"RegisterAdapter - Invalid status: {AmaGDK._status}");
|
|
80
|
+
return;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
listAdapters.Add(adapter);
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
public static T Find<T>()
|
|
87
|
+
{
|
|
88
|
+
return listAdapters.OfType<T>().FirstOrDefault();
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
public static T[] FindAll<T>()
|
|
92
|
+
{
|
|
93
|
+
return listAdapters.OfType<T>().ToArray();
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
|
|
97
|
+
public static T GetConfig<T>() where T: ConfigAsset {
|
|
98
|
+
return (T) AmaGDK.Config;
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
public static class Forbidden {
|
|
103
|
+
public static void DestroyAndReset()
|
|
104
|
+
{
|
|
105
|
+
if (AmaGDK._instance != null) {
|
|
106
|
+
UnityObject.Destroy(AmaGDK._instance);
|
|
107
|
+
AmaGDK._instance = null;
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
var result = Resources.FindObjectsOfTypeAll<AmaGDK>();
|
|
111
|
+
for (var i = 0;i < result.Length; i++)
|
|
112
|
+
{
|
|
113
|
+
if (result[i] == null) continue;
|
|
114
|
+
|
|
115
|
+
#if UNITY_EDITOR // Ignore loaded prefabs assets
|
|
116
|
+
{
|
|
117
|
+
var path = UnityEditor.AssetDatabase.GetAssetPath(result[i]);
|
|
118
|
+
if (!string.IsNullOrEmpty(path)) continue;
|
|
119
|
+
}
|
|
120
|
+
#endif
|
|
121
|
+
|
|
122
|
+
// Logging.LogWarning("Something wrong: another AmaGDK instance found!");
|
|
123
|
+
UnityObject.Destroy(result[i].gameObject);
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
AmaGDK._status = Status.None;
|
|
127
|
+
AmaGDK._allowInit = false;
|
|
128
|
+
|
|
129
|
+
// TODO: Destroy adapters?
|
|
130
|
+
Adapter.listAdapters.Clear();
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
using System;
|
|
2
|
+
using UnityEngine;
|
|
3
|
+
using static Amanotes.Core.Internal.Logging;
|
|
4
|
+
using FileUtils = Amanotes.Core.Internal.FileUtils;
|
|
5
|
+
|
|
6
|
+
namespace Amanotes.Core
|
|
7
|
+
{
|
|
8
|
+
public partial class AmaGDK //User profile
|
|
9
|
+
{
|
|
10
|
+
public static readonly UserProfile User = new UserProfile().Load();
|
|
11
|
+
|
|
12
|
+
[Serializable]
|
|
13
|
+
public class UserProfile
|
|
14
|
+
{
|
|
15
|
+
const string FILE_NAME = nameof(UserProfile);
|
|
16
|
+
|
|
17
|
+
public string amaId;
|
|
18
|
+
public string amaDeviceId;
|
|
19
|
+
public string gaId;
|
|
20
|
+
public string androidId;
|
|
21
|
+
public string idfa;
|
|
22
|
+
public string idfv;
|
|
23
|
+
public string appsflyerId;
|
|
24
|
+
public string firebaseUserPseudoId;
|
|
25
|
+
|
|
26
|
+
public void Save()
|
|
27
|
+
{
|
|
28
|
+
FileUtils.Save(FILE_NAME, JsonUtility.ToJson(this));
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
public UserProfile Load()
|
|
32
|
+
{
|
|
33
|
+
var json = FileUtils.Load(FILE_NAME);
|
|
34
|
+
if (string.IsNullOrEmpty(json))
|
|
35
|
+
return this;
|
|
36
|
+
JsonUtility.FromJsonOverwrite(json, this);
|
|
37
|
+
return this;
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
}
|