Skip to content
This repository was archived by the owner on Apr 11, 2024. It is now read-only.

Commit dde6de9

Browse files
JohannesLootErik Bylund
authored andcommitted
Handle Unity Attribution
1 parent 18233c4 commit dde6de9

File tree

4 files changed

+199
-0
lines changed

4 files changed

+199
-0
lines changed
Lines changed: 107 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,107 @@
1+
using System;
2+
using UnityEngine;
3+
using UnityEditor;
4+
using System.Threading.Tasks;
5+
6+
#if UNITY_EDITOR
7+
namespace LootLocker.Admin
8+
{
9+
10+
[ExecuteInEditMode]
11+
public class AttributionHandler : MonoBehaviour
12+
{
13+
[InitializeOnLoadMethod]
14+
static void SubscribeToEventOnStartup()
15+
{
16+
// Only subscribe if needed
17+
if (EditorPrefs.GetBool("attributionChecked") == false)
18+
{
19+
ProjectSettings.APIKeyEnteredEvent += EventFired;
20+
}
21+
}
22+
23+
private static void EventFired()
24+
{
25+
// Only in Editor
26+
if(Application.isPlaying)
27+
{
28+
return;
29+
}
30+
// New ServerManager
31+
LootLockerServerManager.CheckInit();
32+
33+
// Disable logging
34+
LootLockerConfig.current.currentDebugLevel = LootLockerConfig.DebugLevel.Off;
35+
36+
string apiKey = string.IsNullOrWhiteSpace(LootLockerConfig.current.apiKey) ? "invalidGameAPIKey" : LootLockerConfig.current.apiKey;
37+
SendAttributionEvent(apiKey, (response) => {
38+
if(response.success)
39+
{
40+
// Send attribution event
41+
UnityEditor.VSAttribution.VSAttribution.SendAttributionEvent("Entered API Key", "LootLocker", response.hash);
42+
43+
DestroyImmediate(LootLockerServerManager.I.gameObject);
44+
45+
// Unsubscribe
46+
ProjectSettings.APIKeyEnteredEvent -= EventFired;
47+
// Re-enable logging
48+
LootLockerConfig.current.currentDebugLevel = LootLockerConfig.DebugLevel.All;
49+
}
50+
else
51+
{
52+
DestroyImmediate(LootLockerServerManager.I.gameObject);
53+
54+
// Unsubscribe
55+
ProjectSettings.APIKeyEnteredEvent -= EventFired;
56+
// Re-enable logging
57+
LootLockerConfig.current.currentDebugLevel = LootLockerConfig.DebugLevel.All;
58+
59+
// Resubscribe in 1 seconds
60+
Task task = ResetAttributionCheckAfterXSeconds(1);
61+
}
62+
});
63+
}
64+
65+
private static async Task ResetAttributionCheckAfterXSeconds(int seconds)
66+
{
67+
await Task.Delay((int)(seconds*1000f));
68+
69+
EditorPrefs.SetBool("attributionChecked", false);
70+
ProjectSettings.APIKeyEnteredEvent += EventFired;
71+
}
72+
73+
public static void SendAttributionEvent(string gameApiKey, Action<AttributionResponse> onComplete)
74+
{
75+
VerifyAttributionRequest verifyRequest = new VerifyAttributionRequest(gameApiKey);
76+
LootLockerAPIManager.Verify(verifyRequest, onComplete);
77+
}
78+
}
79+
80+
public class AttributionResponse : LootLockerResponse
81+
{
82+
public string hash;
83+
}
84+
public class VerifyAttributionRequest
85+
{
86+
public string game_key;
87+
public VerifyAttributionRequest(string gameApiKey)
88+
{
89+
this.game_key = gameApiKey;
90+
}
91+
}
92+
93+
public partial class LootLockerAPIManager
94+
{
95+
public static void Verify(VerifyAttributionRequest data, Action<AttributionResponse> onComplete)
96+
{
97+
string json = "";
98+
if (data == null) return;
99+
else json = LootLockerJson.SerializeObject(data);
100+
101+
EndPointClass endPoint = new EndPointClass("game/attribution/unity", LootLockerHTTPMethod.POST);
102+
103+
LootLockerServerRequest.CallAPI(endPoint.endPoint, endPoint.httpMethod, json, (serverResponse) => { LootLockerResponse.Deserialize(onComplete, serverResponse); }, false, LootLockerEnums.LootLockerCallerRole.Base);
104+
}
105+
}
106+
}
107+
#endif

Runtime/Editor/AttributionHandler.cs.meta

Lines changed: 11 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Runtime/Editor/VSAttribution.cs

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
using System;
2+
using UnityEngine.Analytics;
3+
4+
#if UNITY_EDITOR
5+
namespace UnityEditor.VSAttribution
6+
{
7+
public static class VSAttribution
8+
{
9+
const int k_VersionId = 4;
10+
const int k_MaxEventsPerHour = 10;
11+
const int k_MaxNumberOfElements = 1000;
12+
13+
const string k_VendorKey = "unity.vsp-attribution";
14+
const string k_EventName = "vspAttribution";
15+
16+
static bool RegisterEvent()
17+
{
18+
AnalyticsResult result = EditorAnalytics.RegisterEventWithLimit(k_EventName, k_MaxEventsPerHour,
19+
k_MaxNumberOfElements, k_VendorKey, k_VersionId);
20+
21+
var isResultOk = result == AnalyticsResult.Ok;
22+
return isResultOk;
23+
}
24+
25+
[Serializable]
26+
struct VSAttributionData
27+
{
28+
public string actionName;
29+
public string partnerName;
30+
public string customerUid;
31+
public string extra;
32+
}
33+
34+
/// <summary>
35+
/// Registers and attempts to send a Verified Solutions Attribution event.
36+
/// </summary>
37+
/// <param name="actionName">Name of the action, identifying a place this event was called from.</param>
38+
/// <param name="partnerName">Identifiable Verified Solutions Partner's name.</param>
39+
/// <param name="customerUid">Unique identifier of the customer using Partner's Verified Solution.</param>
40+
public static AnalyticsResult SendAttributionEvent(string actionName, string partnerName, string customerUid)
41+
{
42+
try
43+
{
44+
// Are Editor Analytics enabled ? (Preferences)
45+
if (!EditorAnalytics.enabled)
46+
return AnalyticsResult.AnalyticsDisabled;
47+
48+
if (!RegisterEvent())
49+
return AnalyticsResult.InvalidData;
50+
51+
// Create an expected data object
52+
var eventData = new VSAttributionData
53+
{
54+
actionName = actionName,
55+
partnerName = partnerName,
56+
customerUid = customerUid,
57+
extra = "{}"
58+
};
59+
60+
return EditorAnalytics.SendEventWithLimit(k_EventName, eventData, k_VersionId);
61+
}
62+
catch
63+
{
64+
// Fail silently
65+
return AnalyticsResult.AnalyticsDisabled;
66+
}
67+
}
68+
}
69+
}
70+
#endif

Runtime/Editor/VSAttribution.cs.meta

Lines changed: 11 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)