Skip to content

Commit

Permalink
feat: Dedicated Server support (#1468)
Browse files Browse the repository at this point in the history
  • Loading branch information
bitsandfoxes authored Nov 7, 2023
1 parent ec3b3ce commit dea552d
Show file tree
Hide file tree
Showing 17 changed files with 214 additions and 139 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,10 @@

## Unreleased

## Feature

- Added the dedicated server platforms to the known platforms to prevent the SDK from interpreting them as restricted platforms (i.e. disabling offline caching, session tracking) ([#1468](https://github.com/getsentry/sentry-unity/pull/1468))

### Dependencies

- Bump CLI from v2.21.1 to v2.21.2 ([#1454](https://github.com/getsentry/sentry-unity/pull/1454))
Expand Down
9 changes: 7 additions & 2 deletions package-dev/Plugins/macOS/SentryNativeBridge.m
Original file line number Diff line number Diff line change
Expand Up @@ -24,10 +24,15 @@ int SentryNativeBridgeLoadLibrary()
if (loadStatus == -1) {
loadStatus = 0; // init to "error"
do {
// The default path from the executable to the dylib within a .app
void *dylib = dlopen("@executable_path/../PlugIns/Sentry.dylib", RTLD_LAZY);
if (!dylib) {
NSLog(@"Sentry (bridge): Couldn't load Sentry.dylib - dlopen() failed");
break;
// Fallback path for the dedicated server setup
dylib = dlopen("@executable_path/PlugIns/Sentry.dylib", RTLD_LAZY);
if (!dylib) {
NSLog(@"Sentry (bridge): Couldn't load Sentry.dylib - dlopen() failed");
break;
}
}

LOAD_CLASS_OR_BREAK(SentrySDK)
Expand Down
62 changes: 61 additions & 1 deletion package-dev/Runtime/SentryInitialization.cs
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ public static void Init()
#elif SENTRY_NATIVE_ANDROID
SentryNativeAndroid.Configure(options, sentryUnityInfo);
#elif SENTRY_NATIVE
SentryNative.Configure(options);
SentryNative.Configure(options, sentryUnityInfo);
#elif SENTRY_WEBGL
SentryWebGL.Configure(options);
#endif
Expand Down Expand Up @@ -269,5 +269,65 @@ private static void Il2CppNativeStackTraceShim(IntPtr exc, out IntPtr addresses,
#endif
#pragma warning restore 8632
#endif

public bool IsKnownPlatform()
{
var platform = Application.platform;
return
platform == RuntimePlatform.Android ||
platform == RuntimePlatform.IPhonePlayer ||
platform == RuntimePlatform.WindowsEditor ||
platform == RuntimePlatform.WindowsPlayer ||
platform == RuntimePlatform.OSXEditor ||
platform == RuntimePlatform.OSXPlayer ||
platform == RuntimePlatform.LinuxEditor ||
platform == RuntimePlatform.LinuxPlayer ||
platform == RuntimePlatform.WebGLPlayer
#if UNITY_2021_3_OR_NEWER
||
platform == RuntimePlatform.WindowsServer ||
platform == RuntimePlatform.OSXServer ||
platform == RuntimePlatform.LinuxServer
#endif
;
}

public bool IsLinux()
{
var platform = Application.platform;
return
platform == RuntimePlatform.LinuxPlayer
#if UNITY_2021_3_OR_NEWER
|| platform == RuntimePlatform.LinuxServer
#endif
;
}

public bool IsNativeSupportEnabled(SentryUnityOptions options, RuntimePlatform platform)
{
switch (platform)
{
case RuntimePlatform.Android:
return options.AndroidNativeSupportEnabled;
case RuntimePlatform.IPhonePlayer:
return options.IosNativeSupportEnabled;
case RuntimePlatform.WindowsPlayer:
return options.WindowsNativeSupportEnabled;
case RuntimePlatform.OSXPlayer:
return options.MacosNativeSupportEnabled;
case RuntimePlatform.LinuxPlayer:
return options.LinuxNativeSupportEnabled;
#if UNITY_2021_3_OR_NEWER
case RuntimePlatform.WindowsServer:
return options.WindowsNativeSupportEnabled;
case RuntimePlatform.OSXServer:
return options.MacosNativeSupportEnabled;
case RuntimePlatform.LinuxServer:
return options.LinuxNativeSupportEnabled;
#endif
default:
return false;
}
}
}
}
2 changes: 1 addition & 1 deletion src/Sentry.Unity.Editor/SentryScriptableObject.cs
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ internal static (SentryUnityOptions?, SentryCliOptions?) ConfiguredBuildTimeOpti
SentryUnityOptions? options = null;
if (scriptableOptions is not null)
{
options = scriptableOptions.ToSentryUnityOptions(isBuilding: true);
options = scriptableOptions.ToSentryUnityOptions(isBuilding: true, unityInfo: null);
// Must be non-nullable in the interface otherwise Unity script compilation fails...
cliOptions ??= ScriptableObject.CreateInstance<SentryCliOptions>();
var setupScript = scriptableOptions.BuildTimeOptionsConfiguration;
Expand Down
85 changes: 42 additions & 43 deletions src/Sentry.Unity.Native/SentryNative.cs
Original file line number Diff line number Diff line change
Expand Up @@ -17,59 +17,58 @@ public static class SentryNative
/// Configures the native SDK.
/// </summary>
/// <param name="options">The Sentry Unity options to use.</param>
public static void Configure(SentryUnityOptions options)
/// <param name="sentryUnityInfo">Infos about the current Unity environment</param>
public static void Configure(SentryUnityOptions options, ISentryUnityInfo sentryUnityInfo)
{
if (ApplicationAdapter.Instance.Platform switch
if (!sentryUnityInfo.IsNativeSupportEnabled(options, ApplicationAdapter.Instance.Platform))
{
RuntimePlatform.WindowsPlayer => options.WindowsNativeSupportEnabled,
RuntimePlatform.LinuxPlayer => options.LinuxNativeSupportEnabled,
_ => false,
})
options.DiagnosticLogger?.LogDebug("Native support is disabled for '{0}'.", ApplicationAdapter.Instance.Platform);
return;
}

if (!SentryNativeBridge.Init(options, sentryUnityInfo))
{
if (!SentryNativeBridge.Init(options))
{
options.DiagnosticLogger?
.LogWarning("Sentry native initialization failed - native crashes are not captured.");
return;
}
options.DiagnosticLogger?
.LogWarning("Sentry native initialization failed - native crashes are not captured.");
return;
}

ApplicationAdapter.Instance.Quitting += () =>
{
options.DiagnosticLogger?.LogDebug("Closing the sentry-native SDK");
SentryNativeBridge.Close();
};
options.ScopeObserver = new NativeScopeObserver(options);
options.EnableScopeSync = true;
options.NativeContextWriter = new NativeContextWriter();
ApplicationAdapter.Instance.Quitting += () =>
{
options.DiagnosticLogger?.LogDebug("Closing the sentry-native SDK");
SentryNativeBridge.Close();
};
options.ScopeObserver = new NativeScopeObserver(options);
options.EnableScopeSync = true;
options.NativeContextWriter = new NativeContextWriter();

// Use AnalyticsSessionInfo.userId as the default UserID in native & dotnet
options.DefaultUserId = AnalyticsSessionInfo.userId;
if (options.DefaultUserId is not null)
{
options.ScopeObserver.SetUser(new User { Id = options.DefaultUserId });
}
// Use AnalyticsSessionInfo.userId as the default UserID in native & dotnet
options.DefaultUserId = AnalyticsSessionInfo.userId;
if (options.DefaultUserId is not null)
{
options.ScopeObserver.SetUser(new User { Id = options.DefaultUserId });
}

// Note: we must actually call the function now and on every other call use the value we get here.
// Additionally, we cannot call this multiple times for the same directory, because the result changes
// on subsequent runs. Therefore, we cache the value during the whole runtime of the application.
var cacheDirectory = SentryNativeBridge.GetCacheDirectory(options);
var crashedLastRun = false;
// In the event the SDK is re-initialized with a different path on disk, we need to track which ones were already read
// Similarly we need to cache the value of each call since a subsequent call would return a different value
// as the file used on disk to mark it as crashed is deleted after we read it.
lock (PerDirectoryCrashInfo)
// Note: we must actually call the function now and on every other call use the value we get here.
// Additionally, we cannot call this multiple times for the same directory, because the result changes
// on subsequent runs. Therefore, we cache the value during the whole runtime of the application.
var cacheDirectory = SentryNativeBridge.GetCacheDirectory(options);
var crashedLastRun = false;
// In the event the SDK is re-initialized with a different path on disk, we need to track which ones were already read
// Similarly we need to cache the value of each call since a subsequent call would return a different value
// as the file used on disk to mark it as crashed is deleted after we read it.
lock (PerDirectoryCrashInfo)
{
if (!PerDirectoryCrashInfo.TryGetValue(cacheDirectory, out crashedLastRun))
{
if (!PerDirectoryCrashInfo.TryGetValue(cacheDirectory, out crashedLastRun))
{
crashedLastRun = SentryNativeBridge.HandleCrashedLastRun(options);
PerDirectoryCrashInfo.Add(cacheDirectory, crashedLastRun);
crashedLastRun = SentryNativeBridge.HandleCrashedLastRun(options);
PerDirectoryCrashInfo.Add(cacheDirectory, crashedLastRun);

options.DiagnosticLogger?
.LogDebug("Native SDK reported: 'crashedLastRun': '{0}'", crashedLastRun);
}
options.DiagnosticLogger?
.LogDebug("Native SDK reported: 'crashedLastRun': '{0}'", crashedLastRun);
}
options.CrashedLastRun = () => crashedLastRun;
}
options.CrashedLastRun = () => crashedLastRun;
}
}
}
4 changes: 2 additions & 2 deletions src/Sentry.Unity.Native/SentryNativeBridge.cs
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,9 @@ public static class SentryNativeBridge

public static bool CrashedLastRun;

public static bool Init(SentryUnityOptions options)
public static bool Init(SentryUnityOptions options, ISentryUnityInfo sentryUnityInfo)
{
_isLinux = ApplicationAdapter.Instance.Platform is RuntimePlatform.LinuxPlayer;
_isLinux = sentryUnityInfo.IsLinux();

var cOptions = sentry_options_new();

Expand Down
42 changes: 19 additions & 23 deletions src/Sentry.Unity.iOS/SentryNativeCocoa.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
using System;
using Sentry.Extensibility;
using Sentry.PlatformAbstractions;
using Sentry.Unity.Integrations;
using UnityEngine;

Expand All @@ -13,36 +15,30 @@ public static class SentryNativeCocoa
/// Configures the native support.
/// </summary>
/// <param name="options">The Sentry Unity options to use.</param>
/// <param name="sentryUnityInfo">Infos about the current Unity environment</param>
public static void Configure(SentryUnityOptions options, ISentryUnityInfo sentryUnityInfo) =>
Configure(options, sentryUnityInfo, ApplicationAdapter.Instance.Platform);

internal static void Configure(SentryUnityOptions options, ISentryUnityInfo sentryUnityInfo, RuntimePlatform platform)
{
switch (platform)
if (!sentryUnityInfo.IsNativeSupportEnabled(options, platform))
{
case RuntimePlatform.IPhonePlayer:
if (!options.IosNativeSupportEnabled)
{
return;
}
options.ScopeObserver = new NativeScopeObserver("iOS", options);
break;
case RuntimePlatform.OSXPlayer:
if (!options.MacosNativeSupportEnabled)
{
return;
}
if (!SentryCocoaBridgeProxy.Init(options))
{
options.DiagnosticLogger?.LogWarning("Failed to initialize the native SDK");
return;
}
options.ScopeObserver = new NativeScopeObserver("macOS", options);
break;
default:
options.DiagnosticLogger?
.LogWarning("Cocoa SentryNative.Configure() called for unsupported platform: '{0}'", platform);
options.DiagnosticLogger?.LogDebug("Native support is not enabled for: '{0}'", platform);
return;
}

if (platform == RuntimePlatform.IPhonePlayer)
{
options.ScopeObserver = new NativeScopeObserver("iOS", options);
}
else
{
if (!SentryCocoaBridgeProxy.Init(options))
{
options.DiagnosticLogger?.LogWarning("Failed to initialize the native SDK");
return;
}
options.ScopeObserver = new NativeScopeObserver("macOS", options);
}

options.NativeContextWriter = new NativeContextWriter();
Expand Down
4 changes: 4 additions & 0 deletions src/Sentry.Unity/ISentryUnityInfo.cs
Original file line number Diff line number Diff line change
@@ -1,11 +1,15 @@
using System;
using UnityEngine;

namespace Sentry.Unity
{
public interface ISentryUnityInfo
{
public bool IL2CPP { get; }
public Il2CppMethods? Il2CppMethods { get; }
public bool IsKnownPlatform();
public bool IsLinux();
public bool IsNativeSupportEnabled(SentryUnityOptions options, RuntimePlatform platform);
}

public class Il2CppMethods
Expand Down
Loading

0 comments on commit dea552d

Please sign in to comment.