Skip to content

Commit 97fc86d

Browse files
update
Refactored this a bit so we don't have a lot of the Analytics stuff within the NetworkManager, making some adjustments for integration testing and future analytics needs, and making sure we are not adding to our public API footprint.
1 parent 7a13eff commit 97fc86d

File tree

8 files changed

+446
-274
lines changed

8 files changed

+446
-274
lines changed

com.unity.netcode.gameobjects/Editor/Analytics/AnalyticsHandler.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@ internal class AnalyticsHandler<T> : IAnalytic where T : IAnalytic.IData
88
{
99
private T m_Data;
1010

11+
internal T Data => m_Data;
12+
1113
public AnalyticsHandler(T data)
1214
{
1315
m_Data = data;
Lines changed: 214 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,214 @@
1+
#if UNITY_EDITOR
2+
using System.Collections.Generic;
3+
using UnityEditor;
4+
using UnityEngine;
5+
using UnityEngine.Analytics;
6+
7+
namespace Unity.Netcode.Editor
8+
{
9+
/// <summary>
10+
/// Netcode for GameObjects Analytics Class
11+
/// </summary>
12+
internal class NetcodeAnalytics : NetworkManager.NetcodeAnalytics
13+
{
14+
/// <summary>
15+
/// Determines if we are running an integration test of the analytics integration
16+
/// </summary>
17+
internal static bool IsIntegrationTest = false;
18+
#if ENABLE_NGO_ANALYTICS_LOGGING
19+
internal static bool EnableLogging = true;
20+
#else
21+
internal static bool EnableLogging = false;
22+
#endif
23+
24+
// Preserves the analytics enabled flag
25+
private bool m_OriginalAnalyticsEnabled;
26+
27+
internal override void OnOneTimeSetup()
28+
{
29+
m_OriginalAnalyticsEnabled = EditorAnalytics.enabled;
30+
// By default, we always disable analytics during integration testing
31+
EditorAnalytics.enabled = false;
32+
}
33+
34+
internal override void OnOneTimeTearDown()
35+
{
36+
// Reset analytics to the original value
37+
EditorAnalytics.enabled = m_OriginalAnalyticsEnabled;
38+
}
39+
40+
internal List<NetworkManagerAnalyticsHandler> AnalyticsTestResults = new List<NetworkManagerAnalyticsHandler>();
41+
42+
internal List<NetworkSessionInfo> RecentSessions = new List<NetworkSessionInfo>();
43+
/// <summary>
44+
/// Invoked from <see cref="NetworkManager.ModeChanged(PlayModeStateChange)"/>.
45+
/// </summary>
46+
/// <param name="playModeState">The new <see cref="PlayModeStateChange"/> state.</param>
47+
/// <param name="networkManager">The current <see cref="NetworkManager"/> instance when play mode was entered.</param>
48+
internal override void ModeChanged(PlayModeStateChange playModeState, NetworkManager networkManager)
49+
{
50+
switch (playModeState)
51+
{
52+
case PlayModeStateChange.EnteredPlayMode:
53+
{
54+
if (IsIntegrationTest)
55+
{
56+
AnalyticsTestResults.Clear();
57+
}
58+
break;
59+
}
60+
case PlayModeStateChange.ExitingPlayMode:
61+
{
62+
// Update analytics
63+
UpdateAnalytics(networkManager);
64+
break;
65+
}
66+
}
67+
}
68+
69+
/// <summary>
70+
/// Editor Only
71+
/// Invoked when the session is started.
72+
/// </summary>
73+
/// <param name="networkManager">The <see cref="NetworkManager"/> instance when the session is started.</param>
74+
internal override void SessionStarted(NetworkManager networkManager)
75+
{
76+
// If analytics is disabled, then exit early
77+
if (!EditorAnalytics.enabled)
78+
{
79+
return;
80+
}
81+
82+
var newSession = new NetworkSessionInfo()
83+
{
84+
SessionIndex = RecentSessions.Count,
85+
WasClient = networkManager.IsClient,
86+
WasServer = networkManager.IsServer,
87+
NetworkConfig = networkManager.NetworkConfig.Copy(),
88+
Transport = networkManager.NetworkConfig.NetworkTransport != null ? networkManager.NetworkConfig.NetworkTransport.GetType().Name : "None",
89+
};
90+
RecentSessions.Add(newSession);
91+
}
92+
93+
/// <summary>
94+
/// Editor Only
95+
/// Invoked when the session is stopped or upon exiting play mode.
96+
/// </summary>
97+
/// <param name="networkManager">The <see cref="NetworkManager"/> instance.</param>
98+
internal override void SessionStopped(NetworkManager networkManager)
99+
{
100+
// If analytics is disabled or there are no sessions, then exit early
101+
if (!EditorAnalytics.enabled || RecentSessions.Count == 0)
102+
{
103+
return;
104+
}
105+
106+
var lastIndex = RecentSessions.Count - 1;
107+
var recentSession = RecentSessions[lastIndex];
108+
// If the session has already been finalized, then exit early.
109+
if (recentSession.SessionStopped)
110+
{
111+
return;
112+
}
113+
recentSession.UsedCMBService = networkManager.CMBServiceConnection;
114+
recentSession.SessionStopped = true;
115+
RecentSessions[lastIndex] = recentSession;
116+
}
117+
118+
/// <summary>
119+
/// Invoked from within <see cref="NetworkManager.ModeChanged"/> when exiting play mode.
120+
/// </summary>
121+
private void UpdateAnalytics(NetworkManager networkManager)
122+
{
123+
// Exit early if analytics is disabled or there are no sessions to process.
124+
if (!EditorAnalytics.enabled || RecentSessions.Count == 0)
125+
{
126+
return;
127+
}
128+
129+
// If the NetworkManager isn't null, then make sure the last entry is marked off as stopped.
130+
// If the last session is stopped, then SessionStopped will exit early.
131+
if (networkManager != null)
132+
{
133+
SessionStopped(networkManager);
134+
}
135+
136+
// Parse through all of the recent network sessions to generate and send NetworkManager analytics
137+
for (int i = 0; i < RecentSessions.Count; i++)
138+
{
139+
var networkManagerAnalytics = GetNetworkManagerAnalytics(RecentSessions[i]);
140+
141+
var isDuplicate = false;
142+
foreach (var analytics in AnalyticsTestResults)
143+
{
144+
// If we have any sessions with identical configurations,
145+
// then we want to ignore those.
146+
if (analytics.Data.Equals(networkManagerAnalytics))
147+
{
148+
isDuplicate = true;
149+
break;
150+
}
151+
}
152+
153+
if (isDuplicate)
154+
{
155+
continue;
156+
}
157+
158+
if (!IsIntegrationTest)
159+
{
160+
var result = EditorAnalytics.SendAnalytic(new NetworkManagerAnalyticsHandler(networkManagerAnalytics));
161+
if (EnableLogging && result != AnalyticsResult.Ok)
162+
{
163+
Debug.LogWarning($"[Analytics] Problem sending analytics: {result}");
164+
}
165+
}
166+
else
167+
{
168+
AnalyticsTestResults.Add(new NetworkManagerAnalyticsHandler(networkManagerAnalytics));
169+
}
170+
}
171+
172+
if (IsIntegrationTest && EnableLogging)
173+
{
174+
var count = 0;
175+
foreach (var entry in AnalyticsTestResults)
176+
{
177+
entry.Data.LogAnalyticData(count);
178+
count++;
179+
}
180+
}
181+
RecentSessions.Clear();
182+
}
183+
184+
/// <summary>
185+
/// Generates a <see cref="NetworkManagerAnalytics"/> based on the <see cref="NetworkManager.NetworkSessionInfo"/> passed in
186+
/// </summary>
187+
/// <param name="networkSession">Represents a network session with the used NetworkManager configuration</param>
188+
/// <returns></returns>
189+
private NetworkManagerAnalytics GetNetworkManagerAnalytics(NetworkSessionInfo networkSession)
190+
{
191+
var multiplayerSDKInstalled = false;
192+
#if MULTIPLAYER_SERVICES_SDK_INSTALLED
193+
multiplayerSDKInstalled = true;
194+
#endif
195+
if (EnableLogging && !networkSession.SessionStopped)
196+
{
197+
Debug.LogWarning($"Session-{networkSession.SessionIndex} was not considered stopped!");
198+
}
199+
var networkManagerAnalytics = new NetworkManagerAnalytics()
200+
{
201+
IsDistributedAuthority = networkSession.NetworkConfig.NetworkTopology == NetworkTopologyTypes.DistributedAuthority,
202+
WasServer = networkSession.WasServer,
203+
WasClient = networkSession.WasClient,
204+
UsedCMBService = networkSession.UsedCMBService,
205+
IsUsingMultiplayerSDK = multiplayerSDKInstalled,
206+
NetworkTransport = networkSession.Transport,
207+
EnableSceneManagement = networkSession.NetworkConfig.EnableSceneManagement,
208+
TickRate = (int)networkSession.NetworkConfig.TickRate,
209+
};
210+
return networkManagerAnalytics;
211+
}
212+
}
213+
}
214+
#endif

com.unity.netcode.gameobjects/Editor/Analytics/NetcodeAnalytics.cs.meta

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

com.unity.netcode.gameobjects/Editor/Analytics/NetworkManagerAnalytics.cs

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,7 @@
11
#if UNITY_EDITOR
22
using System;
33
using System.Text;
4-
#if ENABLE_NGO_ANALYTICS_LOGGING
54
using UnityEngine;
6-
#endif
75
using UnityEngine.Analytics;
86

97
namespace Unity.Netcode.Editor
@@ -32,12 +30,11 @@ public override string ToString()
3230
message.AppendLine($"{nameof(TickRate)}: {TickRate}");
3331
return message.ToString();
3432
}
35-
#if ENABLE_NGO_ANALYTICS_LOGGING
36-
internal void LogAnalytics(int sessionNumber)
33+
34+
internal void LogAnalyticData(int sessionNumber)
3735
{
3836
Debug.Log($"{nameof(NetworkManagerAnalytics)} Session-{sessionNumber}:\n {ToString()}");
3937
}
40-
#endif
4138
public bool Equals(NetworkManagerAnalytics other)
4239
{
4340
return IsDistributedAuthority == other.IsDistributedAuthority && WasServer == other.WasServer && WasClient == other.WasClient

com.unity.netcode.gameobjects/Editor/AssemblyInfo.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,5 +3,6 @@
33
#if UNITY_INCLUDE_TESTS
44
#if UNITY_EDITOR
55
[assembly: InternalsVisibleTo("Unity.Netcode.EditorTests")]
6+
[assembly: InternalsVisibleTo("TestProject.RuntimeTests")]
67
#endif // UNITY_EDITOR
78
#endif // UNITY_INCLUDE_TESTS

com.unity.netcode.gameobjects/Editor/NetworkManagerHelper.cs

Lines changed: 17 additions & 67 deletions
Original file line numberDiff line numberDiff line change
@@ -3,14 +3,22 @@
33
using Unity.Netcode.Editor.Configuration;
44
using UnityEditor;
55
using UnityEngine;
6-
#if ENABLE_NGO_ANALYTICS_LOGGING
7-
using UnityEngine.Analytics;
8-
#endif
96
using UnityEngine.SceneManagement;
107

118
namespace Unity.Netcode.Editor
129
{
1310
#if UNITY_EDITOR
11+
internal struct NetworkSessionInfo
12+
{
13+
public int SessionIndex;
14+
public bool SessionStopped;
15+
public bool WasServer;
16+
public bool WasClient;
17+
public bool UsedCMBService;
18+
public string Transport;
19+
public NetworkConfig NetworkConfig;
20+
}
21+
1422
/// <summary>
1523
/// Specialized editor specific NetworkManager code
1624
/// </summary>
@@ -30,6 +38,7 @@ public class NetworkManagerHelper : NetworkManager.INetworkManagerHelper
3038
private static void InitializeOnload()
3139
{
3240
Singleton = new NetworkManagerHelper();
41+
3342
NetworkManager.NetworkManagerHelper = Singleton;
3443
EditorApplication.playModeStateChanged -= EditorApplication_playModeStateChanged;
3544
EditorApplication.hierarchyChanged -= EditorApplication_hierarchyChanged;
@@ -228,74 +237,15 @@ public bool NotifyUserOfNestedNetworkManager(NetworkManager networkManager, bool
228237
return isParented;
229238
}
230239

231-
/// <summary>
232-
/// Invoked from within <see cref="NetworkManager.ModeChanged"/> when exiting play mode.
233-
/// </summary>
234-
public void UpdateAnalytics()
235-
{
236-
// Exit early if analytics is disabled
237-
if (!EditorAnalytics.enabled || NetworkManager.RecentSessions.Count == 0)
238-
{
239-
return;
240-
}
241-
242-
var previousAnalytics = new NetworkManagerAnalytics();
243-
// Parse through all of the recent network sessions to generate and send NetworkManager analytics
244-
for (int i = 0; i < NetworkManager.RecentSessions.Count; i++)
245-
{
246-
var networkManagerAnalytics = GetNetworkManagerAnalytics(NetworkManager.RecentSessions[i]);
247-
248-
249-
// If the previous session has no changes to the configuration then skip it (only unique configurations)
250-
if (previousAnalytics.Equals(networkManagerAnalytics))
251-
{
252-
continue;
253-
}
254-
255-
#if ENABLE_NGO_ANALYTICS_LOGGING
256-
networkManagerAnalytics.LogAnalytics(NetworkManager.RecentSessions[i].SessionIndex);
257-
#endif
258-
var result = EditorAnalytics.SendAnalytic(new NetworkManagerAnalyticsHandler(networkManagerAnalytics));
259-
#if ENABLE_NGO_ANALYTICS_LOGGING
260-
if (result != AnalyticsResult.Ok)
261-
{
262-
Debug.LogWarning($"[Analytics] Problem sending analytics: {result}");
263-
}
264-
#endif
265-
previousAnalytics = networkManagerAnalytics;
266-
}
267-
}
240+
internal NetcodeAnalytics NetcodeAnalytics = new NetcodeAnalytics();
268241

269242
/// <summary>
270-
/// Generates a <see cref="NetworkManagerAnalytics"/> based on the <see cref="NetworkManager.NetworkSessionInfo"/> passed in
243+
/// Directly define the interface method to keep this internal
271244
/// </summary>
272-
/// <param name="networkSession">Represents a network session with the used NetworkManager configuration</param>
273-
/// <returns></returns>
274-
private NetworkManagerAnalytics GetNetworkManagerAnalytics(NetworkManager.NetworkSessionInfo networkSession)
245+
/// <returns>The <see cref="NetcodeAnalytics"/> instance which is derived from the <see cref="NetworkManager.NetcodeAnalytics"/> abstract class.</returns>
246+
NetworkManager.NetcodeAnalytics NetworkManager.INetworkManagerHelper.Analytics()
275247
{
276-
var multiplayerSDKInstalled = false;
277-
#if MULTIPLAYER_SERVICES_SDK_INSTALLED
278-
multiplayerSDKInstalled = true;
279-
#endif
280-
#if ENABLE_NGO_ANALYTICS_LOGGING
281-
if (!networkSession.SessionStopped)
282-
{
283-
Debug.LogWarning($"Session-{networkSession.SessionIndex} was not considered stopped!");
284-
}
285-
#endif
286-
287-
var networkManagerAnalytics = new NetworkManagerAnalytics()
288-
{
289-
IsDistributedAuthority = networkSession.NetworkConfig.NetworkTopology == NetworkTopologyTypes.DistributedAuthority,
290-
WasServer = networkSession.WasServer,
291-
WasClient = networkSession.WasClient,
292-
UsedCMBService = networkSession.UsedCMBService,
293-
IsUsingMultiplayerSDK = multiplayerSDKInstalled,
294-
NetworkTransport = networkSession.Transport,
295-
EnableSceneManagement = networkSession.NetworkConfig.EnableSceneManagement,
296-
TickRate = (int)networkSession.NetworkConfig.TickRate,
297-
};
298-
return networkManagerAnalytics;
248+
return NetcodeAnalytics;
299249
}
300250
}
301251
#endif

0 commit comments

Comments
 (0)