Decompiled source of Discord Rich Presence v1.1.2
Mods/LethalCompanyPresence.dll
Decompiled a year ago
The result has been truncated due to the large size, download it to view full contents!
using System; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Reflection; using System.Resources; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Runtime.Versioning; using System.Text; using Discord; using LethalPresence; using MelonLoader; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)] [assembly: AssemblyTitle("Lethal Presence")] [assembly: AssemblyDescription("")] [assembly: AssemblyConfiguration("")] [assembly: AssemblyCompany(null)] [assembly: AssemblyProduct("Lethal Presence")] [assembly: AssemblyCopyright("Created by squidypal")] [assembly: AssemblyTrademark(null)] [assembly: ComVisible(false)] [assembly: AssemblyFileVersion("1.0.0")] [assembly: NeutralResourcesLanguage("en")] [assembly: MelonInfo(typeof(global::LethalPresence.LethalPresence), "Lethal Presence", "1.0.0", "squidypal", null)] [assembly: MelonGame(null, null)] [assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")] [assembly: AssemblyVersion("1.0.0.0")] namespace LethalPresence { public static class BuildInfo { public const string Name = "Lethal Presence"; public const string Author = "squidypal"; public const string Company = null; public const string Version = "1.0.0"; public const string DownloadLink = null; } public class LethalPresence : MelonMod { public class EmbeddedResourceHelper { public static byte[] GetResourceBytes(string filename) { Assembly executingAssembly = Assembly.GetExecutingAssembly(); string[] manifestResourceNames = executingAssembly.GetManifestResourceNames(); foreach (string text in manifestResourceNames) { if (!text.Contains(filename)) { continue; } using Stream stream = executingAssembly.GetManifestResourceStream(text); if (stream == null) { return null; } byte[] array = new byte[stream.Length]; stream.Read(array, 0, array.Length); return array; } return null; } } public static class DllTools { [DllImport("kernel32.dll")] public static extern IntPtr LoadLibrary(string dllPath); } private static global::Discord.Discord _discord; private static ActivityManager _activityManager; private static long _clientId = 1174141549764935721L; private int quota = 0; public List<string> Moons; private bool inGame; public static Activity defaultActivity = new Activity { State = "Picking a launch mode", Details = "Ready to be a great great asset!", Assets = { LargeImage = "lethalcompanylargeimage", LargeText = "Lethal Company", SmallImage = "faceicon", SmallText = "Lethal Company" } }; public override void OnApplicationStart() { try { LoadEmbeddedDll(); _discord = new global::Discord.Discord(_clientId, 0uL); _activityManager = _discord.GetActivityManager(); _activityManager.RegisterSteam(1966720u); MelonLogger.Msg("RichPresence created."); SetActivity(defaultActivity); } catch (Exception ex) { MelonLogger.Error("Error in OnApplicationStart: " + ex.Message); } } public override void OnUpdate() { _discord?.RunCallbacks(); if (inGame) { SetActivity(defaultActivity); if (TimeOfDay.Instance.profitQuota > TimeOfDay.Instance.quotaFulfilled) { defaultActivity.Details = "Not meeting quota " + TimeOfDay.Instance.quotaFulfilled + "/" + TimeOfDay.Instance.profitQuota; } else { defaultActivity.Details = "Meeting quota " + TimeOfDay.Instance.quotaFulfilled + "/" + TimeOfDay.Instance.profitQuota; } defaultActivity.State = TimeOfDay.Instance.daysUntilDeadline + " days and " + TimeOfDay.Instance.hoursUntilDeadline + " hours until deadline"; string text = ((object)TimeOfDay.Instance.currentLevel).ToString(); string text2 = text; } } public static void LoadEmbeddedDll() { byte[] resourceBytes = EmbeddedResourceHelper.GetResourceBytes("discord_game_sdk.dll"); if (resourceBytes == null) { throw new Exception("Failed to find embedded resource: discord_game_sdk.dll"); } string text = Path.Combine(Path.GetTempPath(), "discord_game_sdk.dll"); File.WriteAllBytes(text, resourceBytes); IntPtr intPtr = DllTools.LoadLibrary(text); if (intPtr == IntPtr.Zero) { int lastWin32Error = Marshal.GetLastWin32Error(); throw new Exception($"Failed to load discord_game_sdk.dll. Error Code: {lastWin32Error}"); } } public override void OnSceneWasLoaded(int buildIndex, string sceneName) { if (!(sceneName == "SampleSceneRelay")) { if (sceneName == "MainMenu") { defaultActivity.Details = "In the Menu"; SetActivity(defaultActivity); inGame = false; } } else { inGame = true; } } public static void SetActivity(Activity activity) { _activityManager.UpdateActivity(activity, delegate(Result result) { if (result != 0) { MelonLogger.Msg("Failed: " + result); } }); } } } namespace Discord { public class ActivityManager { internal struct FFIEvents { [UnmanagedFunctionPointer(CallingConvention.Cdecl)] internal delegate void ActivityJoinHandler(IntPtr ptr, [MarshalAs(UnmanagedType.LPStr)] string secret); [UnmanagedFunctionPointer(CallingConvention.Cdecl)] internal delegate void ActivitySpectateHandler(IntPtr ptr, [MarshalAs(UnmanagedType.LPStr)] string secret); [UnmanagedFunctionPointer(CallingConvention.Cdecl)] internal delegate void ActivityJoinRequestHandler(IntPtr ptr, ref User user); [UnmanagedFunctionPointer(CallingConvention.Cdecl)] internal delegate void ActivityInviteHandler(IntPtr ptr, ActivityActionType type, ref User user, ref Activity activity); internal ActivityJoinHandler OnActivityJoin; internal ActivitySpectateHandler OnActivitySpectate; internal ActivityJoinRequestHandler OnActivityJoinRequest; internal ActivityInviteHandler OnActivityInvite; } internal struct FFIMethods { [UnmanagedFunctionPointer(CallingConvention.Cdecl)] internal delegate Result RegisterCommandMethod(IntPtr methodsPtr, [MarshalAs(UnmanagedType.LPStr)] string command); [UnmanagedFunctionPointer(CallingConvention.Cdecl)] internal delegate Result RegisterSteamMethod(IntPtr methodsPtr, uint steamId); [UnmanagedFunctionPointer(CallingConvention.Cdecl)] internal delegate void UpdateActivityCallback(IntPtr ptr, Result result); [UnmanagedFunctionPointer(CallingConvention.Cdecl)] internal delegate void UpdateActivityMethod(IntPtr methodsPtr, ref Activity activity, IntPtr callbackData, UpdateActivityCallback callback); [UnmanagedFunctionPointer(CallingConvention.Cdecl)] internal delegate void ClearActivityCallback(IntPtr ptr, Result result); [UnmanagedFunctionPointer(CallingConvention.Cdecl)] internal delegate void ClearActivityMethod(IntPtr methodsPtr, IntPtr callbackData, ClearActivityCallback callback); [UnmanagedFunctionPointer(CallingConvention.Cdecl)] internal delegate void SendRequestReplyCallback(IntPtr ptr, Result result); [UnmanagedFunctionPointer(CallingConvention.Cdecl)] internal delegate void SendRequestReplyMethod(IntPtr methodsPtr, long userId, ActivityJoinRequestReply reply, IntPtr callbackData, SendRequestReplyCallback callback); [UnmanagedFunctionPointer(CallingConvention.Cdecl)] internal delegate void SendInviteCallback(IntPtr ptr, Result result); [UnmanagedFunctionPointer(CallingConvention.Cdecl)] internal delegate void SendInviteMethod(IntPtr methodsPtr, long userId, ActivityActionType type, [MarshalAs(UnmanagedType.LPStr)] string content, IntPtr callbackData, SendInviteCallback callback); [UnmanagedFunctionPointer(CallingConvention.Cdecl)] internal delegate void AcceptInviteCallback(IntPtr ptr, Result result); [UnmanagedFunctionPointer(CallingConvention.Cdecl)] internal delegate void AcceptInviteMethod(IntPtr methodsPtr, long userId, IntPtr callbackData, AcceptInviteCallback callback); internal RegisterCommandMethod RegisterCommand; internal RegisterSteamMethod RegisterSteam; internal UpdateActivityMethod UpdateActivity; internal ClearActivityMethod ClearActivity; internal SendRequestReplyMethod SendRequestReply; internal SendInviteMethod SendInvite; internal AcceptInviteMethod AcceptInvite; } public delegate void UpdateActivityHandler(Result result); public delegate void ClearActivityHandler(Result result); public delegate void SendRequestReplyHandler(Result result); public delegate void SendInviteHandler(Result result); public delegate void AcceptInviteHandler(Result result); public delegate void ActivityJoinHandler(string secret); public delegate void ActivitySpectateHandler(string secret); public delegate void ActivityJoinRequestHandler(ref User user); public delegate void ActivityInviteHandler(ActivityActionType type, ref User user, ref Activity activity); private IntPtr MethodsPtr; private object MethodsStructure; private FFIMethods Methods { get { if (MethodsStructure == null) { MethodsStructure = Marshal.PtrToStructure(MethodsPtr, typeof(FFIMethods)); } return (FFIMethods)MethodsStructure; } } public event ActivityJoinHandler OnActivityJoin; public event ActivitySpectateHandler OnActivitySpectate; public event ActivityJoinRequestHandler OnActivityJoinRequest; public event ActivityInviteHandler OnActivityInvite; public void RegisterCommand() { RegisterCommand(null); } internal ActivityManager(IntPtr ptr, IntPtr eventsPtr, ref FFIEvents events) { if (eventsPtr == IntPtr.Zero) { throw new ResultException(Result.InternalError); } InitEvents(eventsPtr, ref events); MethodsPtr = ptr; if (MethodsPtr == IntPtr.Zero) { throw new ResultException(Result.InternalError); } } private void InitEvents(IntPtr eventsPtr, ref FFIEvents events) { events.OnActivityJoin = OnActivityJoinImpl; events.OnActivitySpectate = OnActivitySpectateImpl; events.OnActivityJoinRequest = OnActivityJoinRequestImpl; events.OnActivityInvite = OnActivityInviteImpl; Marshal.StructureToPtr(events, eventsPtr, fDeleteOld: false); } public void RegisterCommand(string command) { Result result = Methods.RegisterCommand(MethodsPtr, command); if (result != 0) { throw new ResultException(result); } } public void RegisterSteam(uint steamId) { Result result = Methods.RegisterSteam(MethodsPtr, steamId); if (result != 0) { throw new ResultException(result); } } [MonoPInvokeCallback] private static void UpdateActivityCallbackImpl(IntPtr ptr, Result result) { GCHandle gCHandle = GCHandle.FromIntPtr(ptr); UpdateActivityHandler updateActivityHandler = (UpdateActivityHandler)gCHandle.Target; gCHandle.Free(); updateActivityHandler(result); } public void UpdateActivity(Activity activity, UpdateActivityHandler callback) { GCHandle value = GCHandle.Alloc(callback); Methods.UpdateActivity(MethodsPtr, ref activity, GCHandle.ToIntPtr(value), UpdateActivityCallbackImpl); } [MonoPInvokeCallback] private static void ClearActivityCallbackImpl(IntPtr ptr, Result result) { GCHandle gCHandle = GCHandle.FromIntPtr(ptr); ClearActivityHandler clearActivityHandler = (ClearActivityHandler)gCHandle.Target; gCHandle.Free(); clearActivityHandler(result); } public void ClearActivity(ClearActivityHandler callback) { GCHandle value = GCHandle.Alloc(callback); Methods.ClearActivity(MethodsPtr, GCHandle.ToIntPtr(value), ClearActivityCallbackImpl); } [MonoPInvokeCallback] private static void SendRequestReplyCallbackImpl(IntPtr ptr, Result result) { GCHandle gCHandle = GCHandle.FromIntPtr(ptr); SendRequestReplyHandler sendRequestReplyHandler = (SendRequestReplyHandler)gCHandle.Target; gCHandle.Free(); sendRequestReplyHandler(result); } public void SendRequestReply(long userId, ActivityJoinRequestReply reply, SendRequestReplyHandler callback) { GCHandle value = GCHandle.Alloc(callback); Methods.SendRequestReply(MethodsPtr, userId, reply, GCHandle.ToIntPtr(value), SendRequestReplyCallbackImpl); } [MonoPInvokeCallback] private static void SendInviteCallbackImpl(IntPtr ptr, Result result) { GCHandle gCHandle = GCHandle.FromIntPtr(ptr); SendInviteHandler sendInviteHandler = (SendInviteHandler)gCHandle.Target; gCHandle.Free(); sendInviteHandler(result); } public void SendInvite(long userId, ActivityActionType type, string content, SendInviteHandler callback) { GCHandle value = GCHandle.Alloc(callback); Methods.SendInvite(MethodsPtr, userId, type, content, GCHandle.ToIntPtr(value), SendInviteCallbackImpl); } [MonoPInvokeCallback] private static void AcceptInviteCallbackImpl(IntPtr ptr, Result result) { GCHandle gCHandle = GCHandle.FromIntPtr(ptr); AcceptInviteHandler acceptInviteHandler = (AcceptInviteHandler)gCHandle.Target; gCHandle.Free(); acceptInviteHandler(result); } public void AcceptInvite(long userId, AcceptInviteHandler callback) { GCHandle value = GCHandle.Alloc(callback); Methods.AcceptInvite(MethodsPtr, userId, GCHandle.ToIntPtr(value), AcceptInviteCallbackImpl); } [MonoPInvokeCallback] private static void OnActivityJoinImpl(IntPtr ptr, string secret) { Discord discord = (Discord)GCHandle.FromIntPtr(ptr).Target; if (discord.ActivityManagerInstance.OnActivityJoin != null) { discord.ActivityManagerInstance.OnActivityJoin(secret); } } [MonoPInvokeCallback] private static void OnActivitySpectateImpl(IntPtr ptr, string secret) { Discord discord = (Discord)GCHandle.FromIntPtr(ptr).Target; if (discord.ActivityManagerInstance.OnActivitySpectate != null) { discord.ActivityManagerInstance.OnActivitySpectate(secret); } } [MonoPInvokeCallback] private static void OnActivityJoinRequestImpl(IntPtr ptr, ref User user) { Discord discord = (Discord)GCHandle.FromIntPtr(ptr).Target; if (discord.ActivityManagerInstance.OnActivityJoinRequest != null) { discord.ActivityManagerInstance.OnActivityJoinRequest(ref user); } } [MonoPInvokeCallback] private static void OnActivityInviteImpl(IntPtr ptr, ActivityActionType type, ref User user, ref Activity activity) { Discord discord = (Discord)GCHandle.FromIntPtr(ptr).Target; if (discord.ActivityManagerInstance.OnActivityInvite != null) { discord.ActivityManagerInstance.OnActivityInvite(type, ref user, ref activity); } } } internal static class Constants { public const string DllName = "discord_game_sdk"; } public enum Result { Ok, ServiceUnavailable, InvalidVersion, LockFailed, InternalError, InvalidPayload, InvalidCommand, InvalidPermissions, NotFetched, NotFound, Conflict, InvalidSecret, InvalidJoinSecret, NoEligibleActivity, InvalidInvite, NotAuthenticated, InvalidAccessToken, ApplicationMismatch, InvalidDataUrl, InvalidBase64, NotFiltered, LobbyFull, InvalidLobbySecret, InvalidFilename, InvalidFileSize, InvalidEntitlement, NotInstalled, NotRunning, InsufficientBuffer, PurchaseCanceled, InvalidGuild, InvalidEvent, InvalidChannel, InvalidOrigin, RateLimited, OAuth2Error, SelectChannelTimeout, GetGuildTimeout, SelectVoiceForceRequired, CaptureShortcutAlreadyListening, UnauthorizedForAchievement, InvalidGiftCode, PurchaseError, TransactionAborted } public enum CreateFlags { Default, NoRequireDiscord } public enum LogLevel { Error = 1, Warn, Info, Debug } public enum UserFlag { Partner = 2, HypeSquadEvents = 4, HypeSquadHouse1 = 0x40, HypeSquadHouse2 = 0x80, HypeSquadHouse3 = 0x100 } public enum PremiumType { None, Tier1, Tier2 } public enum ImageType { User } public enum ActivityType { Playing, Streaming, Listening, Watching } public enum ActivityActionType { Join = 1, Spectate } public enum ActivityJoinRequestReply { No, Yes, Ignore } public enum Status { Offline, Online, Idle, DoNotDisturb } public enum RelationshipType { None, Friend, Blocked, PendingIncoming, PendingOutgoing, Implicit } public enum LobbyType { Private = 1, Public } public enum LobbySearchComparison { LessThanOrEqual = -2, LessThan, Equal, GreaterThan, GreaterThanOrEqual, NotEqual } public enum LobbySearchCast { String = 1, Number } public enum LobbySearchDistance { Local, Default, Extended, Global } public enum EntitlementType { Purchase = 1, PremiumSubscription, DeveloperGift, TestModePurchase, FreePurchase, UserGift, PremiumPurchase } public enum SkuType { Application = 1, DLC, Consumable, Bundle } public enum InputModeType { VoiceActivity, PushToTalk } public struct User { public long Id; [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 256)] public string Username; [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 8)] public string Discriminator; [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 128)] public string Avatar; public bool Bot; } public struct OAuth2Token { [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 128)] public string AccessToken; [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 1024)] public string Scopes; public long Expires; } public struct ImageHandle { public ImageType Type; public long Id; public uint Size; public static ImageHandle User(long id) { return User(id, 128u); } public static ImageHandle User(long id, uint size) { ImageHandle result = default(ImageHandle); result.Type = ImageType.User; result.Id = id; result.Size = size; return result; } } public struct ImageDimensions { public uint Width; public uint Height; } public struct ActivityTimestamps { public long Start; public long End; } public struct ActivityAssets { [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 128)] public string LargeImage; [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 128)] public string LargeText; [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 128)] public string SmallImage; [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 128)] public string SmallText; } public struct PartySize { public int CurrentSize; public int MaxSize; } public struct ActivityParty { [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 128)] public string Id; public PartySize Size; } public struct ActivitySecrets { [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 128)] public string Match; [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 128)] public string Join; [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 128)] public string Spectate; } public struct Activity { public ActivityType Type; public long ApplicationId; [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 128)] public string Name; [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 128)] public string State; [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 128)] public string Details; public ActivityTimestamps Timestamps; public ActivityAssets Assets; public ActivityParty Party; public ActivitySecrets Secrets; public bool Instance; } public struct Presence { public Status Status; public Activity Activity; } public struct Relationship { public RelationshipType Type; public User User; public Presence Presence; } public struct Lobby { public long Id; public LobbyType Type; public long OwnerId; [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 128)] public string Secret; public uint Capacity; public bool Locked; } public struct FileStat { [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 260)] public string Filename; public ulong Size; public ulong LastModified; } public struct Entitlement { public long Id; public EntitlementType Type; public long SkuId; } public struct SkuPrice { public uint Amount; [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 16)] public string Currency; } public struct Sku { public long Id; public SkuType Type; [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 256)] public string Name; public SkuPrice Price; } public struct InputMode { public InputModeType Type; [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 256)] public string Shortcut; } public struct UserAchievement { public long UserId; public long AchievementId; public byte PercentComplete; [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 64)] public string UnlockedAt; } public struct LobbyTransaction { internal struct FFIMethods { [UnmanagedFunctionPointer(CallingConvention.Cdecl)] internal delegate Result SetTypeMethod(IntPtr methodsPtr, LobbyType type); [UnmanagedFunctionPointer(CallingConvention.Cdecl)] internal delegate Result SetOwnerMethod(IntPtr methodsPtr, long ownerId); [UnmanagedFunctionPointer(CallingConvention.Cdecl)] internal delegate Result SetCapacityMethod(IntPtr methodsPtr, uint capacity); [UnmanagedFunctionPointer(CallingConvention.Cdecl)] internal delegate Result SetMetadataMethod(IntPtr methodsPtr, [MarshalAs(UnmanagedType.LPStr)] string key, [MarshalAs(UnmanagedType.LPStr)] string value); [UnmanagedFunctionPointer(CallingConvention.Cdecl)] internal delegate Result DeleteMetadataMethod(IntPtr methodsPtr, [MarshalAs(UnmanagedType.LPStr)] string key); [UnmanagedFunctionPointer(CallingConvention.Cdecl)] internal delegate Result SetLockedMethod(IntPtr methodsPtr, bool locked); internal SetTypeMethod SetType; internal SetOwnerMethod SetOwner; internal SetCapacityMethod SetCapacity; internal SetMetadataMethod SetMetadata; internal DeleteMetadataMethod DeleteMetadata; internal SetLockedMethod SetLocked; } internal IntPtr MethodsPtr; internal object MethodsStructure; private FFIMethods Methods { get { if (MethodsStructure == null) { MethodsStructure = Marshal.PtrToStructure(MethodsPtr, typeof(FFIMethods)); } return (FFIMethods)MethodsStructure; } } public void SetType(LobbyType type) { if (MethodsPtr != IntPtr.Zero) { Result result = Methods.SetType(MethodsPtr, type); if (result != 0) { throw new ResultException(result); } } } public void SetOwner(long ownerId) { if (MethodsPtr != IntPtr.Zero) { Result result = Methods.SetOwner(MethodsPtr, ownerId); if (result != 0) { throw new ResultException(result); } } } public void SetCapacity(uint capacity) { if (MethodsPtr != IntPtr.Zero) { Result result = Methods.SetCapacity(MethodsPtr, capacity); if (result != 0) { throw new ResultException(result); } } } public void SetMetadata(string key, string value) { if (MethodsPtr != IntPtr.Zero) { Result result = Methods.SetMetadata(MethodsPtr, key, value); if (result != 0) { throw new ResultException(result); } } } public void DeleteMetadata(string key) { if (MethodsPtr != IntPtr.Zero) { Result result = Methods.DeleteMetadata(MethodsPtr, key); if (result != 0) { throw new ResultException(result); } } } public void SetLocked(bool locked) { if (MethodsPtr != IntPtr.Zero) { Result result = Methods.SetLocked(MethodsPtr, locked); if (result != 0) { throw new ResultException(result); } } } } public struct LobbyMemberTransaction { internal struct FFIMethods { [UnmanagedFunctionPointer(CallingConvention.Cdecl)] internal delegate Result SetMetadataMethod(IntPtr methodsPtr, [MarshalAs(UnmanagedType.LPStr)] string key, [MarshalAs(UnmanagedType.LPStr)] string value); [UnmanagedFunctionPointer(CallingConvention.Cdecl)] internal delegate Result DeleteMetadataMethod(IntPtr methodsPtr, [MarshalAs(UnmanagedType.LPStr)] string key); internal SetMetadataMethod SetMetadata; internal DeleteMetadataMethod DeleteMetadata; } internal IntPtr MethodsPtr; internal object MethodsStructure; private FFIMethods Methods { get { if (MethodsStructure == null) { MethodsStructure = Marshal.PtrToStructure(MethodsPtr, typeof(FFIMethods)); } return (FFIMethods)MethodsStructure; } } public void SetMetadata(string key, string value) { if (MethodsPtr != IntPtr.Zero) { Result result = Methods.SetMetadata(MethodsPtr, key, value); if (result != 0) { throw new ResultException(result); } } } public void DeleteMetadata(string key) { if (MethodsPtr != IntPtr.Zero) { Result result = Methods.DeleteMetadata(MethodsPtr, key); if (result != 0) { throw new ResultException(result); } } } } public struct LobbySearchQuery { internal struct FFIMethods { [UnmanagedFunctionPointer(CallingConvention.Cdecl)] internal delegate Result FilterMethod(IntPtr methodsPtr, [MarshalAs(UnmanagedType.LPStr)] string key, LobbySearchComparison comparison, LobbySearchCast cast, [MarshalAs(UnmanagedType.LPStr)] string value); [UnmanagedFunctionPointer(CallingConvention.Cdecl)] internal delegate Result SortMethod(IntPtr methodsPtr, [MarshalAs(UnmanagedType.LPStr)] string key, LobbySearchCast cast, [MarshalAs(UnmanagedType.LPStr)] string value); [UnmanagedFunctionPointer(CallingConvention.Cdecl)] internal delegate Result LimitMethod(IntPtr methodsPtr, uint limit); [UnmanagedFunctionPointer(CallingConvention.Cdecl)] internal delegate Result DistanceMethod(IntPtr methodsPtr, LobbySearchDistance distance); internal FilterMethod Filter; internal SortMethod Sort; internal LimitMethod Limit; internal DistanceMethod Distance; } internal IntPtr MethodsPtr; internal object MethodsStructure; private FFIMethods Methods { get { if (MethodsStructure == null) { MethodsStructure = Marshal.PtrToStructure(MethodsPtr, typeof(FFIMethods)); } return (FFIMethods)MethodsStructure; } } public void Filter(string key, LobbySearchComparison comparison, LobbySearchCast cast, string value) { if (MethodsPtr != IntPtr.Zero) { Result result = Methods.Filter(MethodsPtr, key, comparison, cast, value); if (result != 0) { throw new ResultException(result); } } } public void Sort(string key, LobbySearchCast cast, string value) { if (MethodsPtr != IntPtr.Zero) { Result result = Methods.Sort(MethodsPtr, key, cast, value); if (result != 0) { throw new ResultException(result); } } } public void Limit(uint limit) { if (MethodsPtr != IntPtr.Zero) { Result result = Methods.Limit(MethodsPtr, limit); if (result != 0) { throw new ResultException(result); } } } public void Distance(LobbySearchDistance distance) { if (MethodsPtr != IntPtr.Zero) { Result result = Methods.Distance(MethodsPtr, distance); if (result != 0) { throw new ResultException(result); } } } } public class ResultException : Exception { public readonly Result Result; public ResultException(Result result) : base(result.ToString()) { } } public class Discord : IDisposable { internal struct FFIEvents { } internal struct FFIMethods { [UnmanagedFunctionPointer(CallingConvention.Cdecl)] internal delegate void DestroyHandler(IntPtr MethodsPtr); [UnmanagedFunctionPointer(CallingConvention.Cdecl)] internal delegate Result RunCallbacksMethod(IntPtr methodsPtr); [UnmanagedFunctionPointer(CallingConvention.Cdecl)] internal delegate void SetLogHookCallback(IntPtr ptr, LogLevel level, [MarshalAs(UnmanagedType.LPStr)] string message); [UnmanagedFunctionPointer(CallingConvention.Cdecl)] internal delegate void SetLogHookMethod(IntPtr methodsPtr, LogLevel minLevel, IntPtr callbackData, SetLogHookCallback callback); [UnmanagedFunctionPointer(CallingConvention.Cdecl)] internal delegate IntPtr GetApplicationManagerMethod(IntPtr discordPtr); [UnmanagedFunctionPointer(CallingConvention.Cdecl)] internal delegate IntPtr GetUserManagerMethod(IntPtr discordPtr); [UnmanagedFunctionPointer(CallingConvention.Cdecl)] internal delegate IntPtr GetImageManagerMethod(IntPtr discordPtr); [UnmanagedFunctionPointer(CallingConvention.Cdecl)] internal delegate IntPtr GetActivityManagerMethod(IntPtr discordPtr); [UnmanagedFunctionPointer(CallingConvention.Cdecl)] internal delegate IntPtr GetRelationshipManagerMethod(IntPtr discordPtr); [UnmanagedFunctionPointer(CallingConvention.Cdecl)] internal delegate IntPtr GetLobbyManagerMethod(IntPtr discordPtr); [UnmanagedFunctionPointer(CallingConvention.Cdecl)] internal delegate IntPtr GetNetworkManagerMethod(IntPtr discordPtr); [UnmanagedFunctionPointer(CallingConvention.Cdecl)] internal delegate IntPtr GetOverlayManagerMethod(IntPtr discordPtr); [UnmanagedFunctionPointer(CallingConvention.Cdecl)] internal delegate IntPtr GetStorageManagerMethod(IntPtr discordPtr); [UnmanagedFunctionPointer(CallingConvention.Cdecl)] internal delegate IntPtr GetStoreManagerMethod(IntPtr discordPtr); [UnmanagedFunctionPointer(CallingConvention.Cdecl)] internal delegate IntPtr GetVoiceManagerMethod(IntPtr discordPtr); [UnmanagedFunctionPointer(CallingConvention.Cdecl)] internal delegate IntPtr GetAchievementManagerMethod(IntPtr discordPtr); internal DestroyHandler Destroy; internal RunCallbacksMethod RunCallbacks; internal SetLogHookMethod SetLogHook; internal GetApplicationManagerMethod GetApplicationManager; internal GetUserManagerMethod GetUserManager; internal GetImageManagerMethod GetImageManager; internal GetActivityManagerMethod GetActivityManager; internal GetRelationshipManagerMethod GetRelationshipManager; internal GetLobbyManagerMethod GetLobbyManager; internal GetNetworkManagerMethod GetNetworkManager; internal GetOverlayManagerMethod GetOverlayManager; internal GetStorageManagerMethod GetStorageManager; internal GetStoreManagerMethod GetStoreManager; internal GetVoiceManagerMethod GetVoiceManager; internal GetAchievementManagerMethod GetAchievementManager; } internal struct FFICreateParams { internal long ClientId; internal ulong Flags; internal IntPtr Events; internal IntPtr EventData; internal IntPtr ApplicationEvents; internal uint ApplicationVersion; internal IntPtr UserEvents; internal uint UserVersion; internal IntPtr ImageEvents; internal uint ImageVersion; internal IntPtr ActivityEvents; internal uint ActivityVersion; internal IntPtr RelationshipEvents; internal uint RelationshipVersion; internal IntPtr LobbyEvents; internal uint LobbyVersion; internal IntPtr NetworkEvents; internal uint NetworkVersion; internal IntPtr OverlayEvents; internal uint OverlayVersion; internal IntPtr StorageEvents; internal uint StorageVersion; internal IntPtr StoreEvents; internal uint StoreVersion; internal IntPtr VoiceEvents; internal uint VoiceVersion; internal IntPtr AchievementEvents; internal uint AchievementVersion; } public delegate void SetLogHookHandler(LogLevel level, string message); private GCHandle SelfHandle; private IntPtr EventsPtr; private FFIEvents Events; private IntPtr ApplicationEventsPtr; private ApplicationManager.FFIEvents ApplicationEvents; internal ApplicationManager ApplicationManagerInstance; private IntPtr UserEventsPtr; private UserManager.FFIEvents UserEvents; internal UserManager UserManagerInstance; private IntPtr ImageEventsPtr; private ImageManager.FFIEvents ImageEvents; internal ImageManager ImageManagerInstance; private IntPtr ActivityEventsPtr; private ActivityManager.FFIEvents ActivityEvents; internal ActivityManager ActivityManagerInstance; private IntPtr RelationshipEventsPtr; private RelationshipManager.FFIEvents RelationshipEvents; internal RelationshipManager RelationshipManagerInstance; private IntPtr LobbyEventsPtr; private LobbyManager.FFIEvents LobbyEvents; internal LobbyManager LobbyManagerInstance; private IntPtr NetworkEventsPtr; private NetworkManager.FFIEvents NetworkEvents; internal NetworkManager NetworkManagerInstance; private IntPtr OverlayEventsPtr; private OverlayManager.FFIEvents OverlayEvents; internal OverlayManager OverlayManagerInstance; private IntPtr StorageEventsPtr; private StorageManager.FFIEvents StorageEvents; internal StorageManager StorageManagerInstance; private IntPtr StoreEventsPtr; private StoreManager.FFIEvents StoreEvents; internal StoreManager StoreManagerInstance; private IntPtr VoiceEventsPtr; private VoiceManager.FFIEvents VoiceEvents; internal VoiceManager VoiceManagerInstance; private IntPtr AchievementEventsPtr; private AchievementManager.FFIEvents AchievementEvents; internal AchievementManager AchievementManagerInstance; private IntPtr MethodsPtr; private object MethodsStructure; private GCHandle? setLogHook; private FFIMethods Methods { get { if (MethodsStructure == null) { MethodsStructure = Marshal.PtrToStructure(MethodsPtr, typeof(FFIMethods)); } return (FFIMethods)MethodsStructure; } } [DllImport("discord_game_sdk", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] private static extern Result DiscordCreate(uint version, ref FFICreateParams createParams, out IntPtr manager); public Discord(long clientId, ulong flags) { FFICreateParams createParams = default(FFICreateParams); createParams.ClientId = clientId; createParams.Flags = flags; Events = default(FFIEvents); EventsPtr = Marshal.AllocHGlobal(Marshal.SizeOf(Events)); createParams.Events = EventsPtr; SelfHandle = GCHandle.Alloc(this); createParams.EventData = GCHandle.ToIntPtr(SelfHandle); ApplicationEvents = default(ApplicationManager.FFIEvents); ApplicationEventsPtr = Marshal.AllocHGlobal(Marshal.SizeOf(ApplicationEvents)); createParams.ApplicationEvents = ApplicationEventsPtr; createParams.ApplicationVersion = 1u; UserEvents = default(UserManager.FFIEvents); UserEventsPtr = Marshal.AllocHGlobal(Marshal.SizeOf(UserEvents)); createParams.UserEvents = UserEventsPtr; createParams.UserVersion = 1u; ImageEvents = default(ImageManager.FFIEvents); ImageEventsPtr = Marshal.AllocHGlobal(Marshal.SizeOf(ImageEvents)); createParams.ImageEvents = ImageEventsPtr; createParams.ImageVersion = 1u; ActivityEvents = default(ActivityManager.FFIEvents); ActivityEventsPtr = Marshal.AllocHGlobal(Marshal.SizeOf(ActivityEvents)); createParams.ActivityEvents = ActivityEventsPtr; createParams.ActivityVersion = 1u; RelationshipEvents = default(RelationshipManager.FFIEvents); RelationshipEventsPtr = Marshal.AllocHGlobal(Marshal.SizeOf(RelationshipEvents)); createParams.RelationshipEvents = RelationshipEventsPtr; createParams.RelationshipVersion = 1u; LobbyEvents = default(LobbyManager.FFIEvents); LobbyEventsPtr = Marshal.AllocHGlobal(Marshal.SizeOf(LobbyEvents)); createParams.LobbyEvents = LobbyEventsPtr; createParams.LobbyVersion = 1u; NetworkEvents = default(NetworkManager.FFIEvents); NetworkEventsPtr = Marshal.AllocHGlobal(Marshal.SizeOf(NetworkEvents)); createParams.NetworkEvents = NetworkEventsPtr; createParams.NetworkVersion = 1u; OverlayEvents = default(OverlayManager.FFIEvents); OverlayEventsPtr = Marshal.AllocHGlobal(Marshal.SizeOf(OverlayEvents)); createParams.OverlayEvents = OverlayEventsPtr; createParams.OverlayVersion = 1u; StorageEvents = default(StorageManager.FFIEvents); StorageEventsPtr = Marshal.AllocHGlobal(Marshal.SizeOf(StorageEvents)); createParams.StorageEvents = StorageEventsPtr; createParams.StorageVersion = 1u; StoreEvents = default(StoreManager.FFIEvents); StoreEventsPtr = Marshal.AllocHGlobal(Marshal.SizeOf(StoreEvents)); createParams.StoreEvents = StoreEventsPtr; createParams.StoreVersion = 1u; VoiceEvents = default(VoiceManager.FFIEvents); VoiceEventsPtr = Marshal.AllocHGlobal(Marshal.SizeOf(VoiceEvents)); createParams.VoiceEvents = VoiceEventsPtr; createParams.VoiceVersion = 1u; AchievementEvents = default(AchievementManager.FFIEvents); AchievementEventsPtr = Marshal.AllocHGlobal(Marshal.SizeOf(AchievementEvents)); createParams.AchievementEvents = AchievementEventsPtr; createParams.AchievementVersion = 1u; InitEvents(EventsPtr, ref Events); Result result = DiscordCreate(2u, ref createParams, out MethodsPtr); if (result != 0) { Dispose(); throw new ResultException(result); } } private void InitEvents(IntPtr eventsPtr, ref FFIEvents events) { Marshal.StructureToPtr(events, eventsPtr, fDeleteOld: false); } public void Dispose() { if (MethodsPtr != IntPtr.Zero) { Methods.Destroy(MethodsPtr); } SelfHandle.Free(); Marshal.FreeHGlobal(EventsPtr); Marshal.FreeHGlobal(ApplicationEventsPtr); Marshal.FreeHGlobal(UserEventsPtr); Marshal.FreeHGlobal(ImageEventsPtr); Marshal.FreeHGlobal(ActivityEventsPtr); Marshal.FreeHGlobal(RelationshipEventsPtr); Marshal.FreeHGlobal(LobbyEventsPtr); Marshal.FreeHGlobal(NetworkEventsPtr); Marshal.FreeHGlobal(OverlayEventsPtr); Marshal.FreeHGlobal(StorageEventsPtr); Marshal.FreeHGlobal(StoreEventsPtr); Marshal.FreeHGlobal(VoiceEventsPtr); Marshal.FreeHGlobal(AchievementEventsPtr); if (setLogHook.HasValue) { setLogHook.Value.Free(); } } public void RunCallbacks() { Result result = Methods.RunCallbacks(MethodsPtr); if (result != 0) { throw new ResultException(result); } } [MonoPInvokeCallback] private static void SetLogHookCallbackImpl(IntPtr ptr, LogLevel level, string message) { SetLogHookHandler setLogHookHandler = (SetLogHookHandler)GCHandle.FromIntPtr(ptr).Target; setLogHookHandler(level, message); } public void SetLogHook(LogLevel minLevel, SetLogHookHandler callback) { if (setLogHook.HasValue) { setLogHook.Value.Free(); } setLogHook = GCHandle.Alloc(callback); Methods.SetLogHook(MethodsPtr, minLevel, GCHandle.ToIntPtr(setLogHook.Value), SetLogHookCallbackImpl); } public ApplicationManager GetApplicationManager() { if (ApplicationManagerInstance == null) { ApplicationManagerInstance = new ApplicationManager(Methods.GetApplicationManager(MethodsPtr), ApplicationEventsPtr, ref ApplicationEvents); } return ApplicationManagerInstance; } public UserManager GetUserManager() { if (UserManagerInstance == null) { UserManagerInstance = new UserManager(Methods.GetUserManager(MethodsPtr), UserEventsPtr, ref UserEvents); } return UserManagerInstance; } public ImageManager GetImageManager() { if (ImageManagerInstance == null) { ImageManagerInstance = new ImageManager(Methods.GetImageManager(MethodsPtr), ImageEventsPtr, ref ImageEvents); } return ImageManagerInstance; } public ActivityManager GetActivityManager() { if (ActivityManagerInstance == null) { ActivityManagerInstance = new ActivityManager(Methods.GetActivityManager(MethodsPtr), ActivityEventsPtr, ref ActivityEvents); } return ActivityManagerInstance; } public RelationshipManager GetRelationshipManager() { if (RelationshipManagerInstance == null) { RelationshipManagerInstance = new RelationshipManager(Methods.GetRelationshipManager(MethodsPtr), RelationshipEventsPtr, ref RelationshipEvents); } return RelationshipManagerInstance; } public LobbyManager GetLobbyManager() { if (LobbyManagerInstance == null) { LobbyManagerInstance = new LobbyManager(Methods.GetLobbyManager(MethodsPtr), LobbyEventsPtr, ref LobbyEvents); } return LobbyManagerInstance; } public NetworkManager GetNetworkManager() { if (NetworkManagerInstance == null) { NetworkManagerInstance = new NetworkManager(Methods.GetNetworkManager(MethodsPtr), NetworkEventsPtr, ref NetworkEvents); } return NetworkManagerInstance; } public OverlayManager GetOverlayManager() { if (OverlayManagerInstance == null) { OverlayManagerInstance = new OverlayManager(Methods.GetOverlayManager(MethodsPtr), OverlayEventsPtr, ref OverlayEvents); } return OverlayManagerInstance; } public StorageManager GetStorageManager() { if (StorageManagerInstance == null) { StorageManagerInstance = new StorageManager(Methods.GetStorageManager(MethodsPtr), StorageEventsPtr, ref StorageEvents); } return StorageManagerInstance; } public StoreManager GetStoreManager() { if (StoreManagerInstance == null) { StoreManagerInstance = new StoreManager(Methods.GetStoreManager(MethodsPtr), StoreEventsPtr, ref StoreEvents); } return StoreManagerInstance; } public VoiceManager GetVoiceManager() { if (VoiceManagerInstance == null) { VoiceManagerInstance = new VoiceManager(Methods.GetVoiceManager(MethodsPtr), VoiceEventsPtr, ref VoiceEvents); } return VoiceManagerInstance; } public AchievementManager GetAchievementManager() { if (AchievementManagerInstance == null) { AchievementManagerInstance = new AchievementManager(Methods.GetAchievementManager(MethodsPtr), AchievementEventsPtr, ref AchievementEvents); } return AchievementManagerInstance; } } internal class MonoPInvokeCallbackAttribute : Attribute { } public class ApplicationManager { internal struct FFIEvents { } internal struct FFIMethods { [UnmanagedFunctionPointer(CallingConvention.Cdecl)] internal delegate void ValidateOrExitCallback(IntPtr ptr, Result result); [UnmanagedFunctionPointer(CallingConvention.Cdecl)] internal delegate void ValidateOrExitMethod(IntPtr methodsPtr, IntPtr callbackData, ValidateOrExitCallback callback); [UnmanagedFunctionPointer(CallingConvention.Cdecl)] internal delegate void GetCurrentLocaleMethod(IntPtr methodsPtr, StringBuilder locale); [UnmanagedFunctionPointer(CallingConvention.Cdecl)] internal delegate void GetCurrentBranchMethod(IntPtr methodsPtr, StringBuilder branch); [UnmanagedFunctionPointer(CallingConvention.Cdecl)] internal delegate void GetOAuth2TokenCallback(IntPtr ptr, Result result, ref OAuth2Token oauth2Token); [UnmanagedFunctionPointer(CallingConvention.Cdecl)] internal delegate void GetOAuth2TokenMethod(IntPtr methodsPtr, IntPtr callbackData, GetOAuth2TokenCallback callback); [UnmanagedFunctionPointer(CallingConvention.Cdecl)] internal delegate void GetTicketCallback(IntPtr ptr, Result result, [MarshalAs(UnmanagedType.LPStr)] ref string data); [UnmanagedFunctionPointer(CallingConvention.Cdecl)] internal delegate void GetTicketMethod(IntPtr methodsPtr, IntPtr callbackData, GetTicketCallback callback); internal ValidateOrExitMethod ValidateOrExit; internal GetCurrentLocaleMethod GetCurrentLocale; internal GetCurrentBranchMethod GetCurrentBranch; internal GetOAuth2TokenMethod GetOAuth2Token; internal GetTicketMethod GetTicket; } public delegate void ValidateOrExitHandler(Result result); public delegate void GetOAuth2TokenHandler(Result result, ref OAuth2Token oauth2Token); public delegate void GetTicketHandler(Result result, ref string data); private IntPtr MethodsPtr; private object MethodsStructure; private FFIMethods Methods { get { if (MethodsStructure == null) { MethodsStructure = Marshal.PtrToStructure(MethodsPtr, typeof(FFIMethods)); } return (FFIMethods)MethodsStructure; } } internal ApplicationManager(IntPtr ptr, IntPtr eventsPtr, ref FFIEvents events) { if (eventsPtr == IntPtr.Zero) { throw new ResultException(Result.InternalError); } InitEvents(eventsPtr, ref events); MethodsPtr = ptr; if (MethodsPtr == IntPtr.Zero) { throw new ResultException(Result.InternalError); } } private void InitEvents(IntPtr eventsPtr, ref FFIEvents events) { Marshal.StructureToPtr(events, eventsPtr, fDeleteOld: false); } [MonoPInvokeCallback] private static void ValidateOrExitCallbackImpl(IntPtr ptr, Result result) { GCHandle gCHandle = GCHandle.FromIntPtr(ptr); ValidateOrExitHandler validateOrExitHandler = (ValidateOrExitHandler)gCHandle.Target; gCHandle.Free(); validateOrExitHandler(result); } public void ValidateOrExit(ValidateOrExitHandler callback) { GCHandle value = GCHandle.Alloc(callback); Methods.ValidateOrExit(MethodsPtr, GCHandle.ToIntPtr(value), ValidateOrExitCallbackImpl); } public string GetCurrentLocale() { StringBuilder stringBuilder = new StringBuilder(128); Methods.GetCurrentLocale(MethodsPtr, stringBuilder); return stringBuilder.ToString(); } public string GetCurrentBranch() { StringBuilder stringBuilder = new StringBuilder(4096); Methods.GetCurrentBranch(MethodsPtr, stringBuilder); return stringBuilder.ToString(); } [MonoPInvokeCallback] private static void GetOAuth2TokenCallbackImpl(IntPtr ptr, Result result, ref OAuth2Token oauth2Token) { GCHandle gCHandle = GCHandle.FromIntPtr(ptr); GetOAuth2TokenHandler getOAuth2TokenHandler = (GetOAuth2TokenHandler)gCHandle.Target; gCHandle.Free(); getOAuth2TokenHandler(result, ref oauth2Token); } public void GetOAuth2Token(GetOAuth2TokenHandler callback) { GCHandle value = GCHandle.Alloc(callback); Methods.GetOAuth2Token(MethodsPtr, GCHandle.ToIntPtr(value), GetOAuth2TokenCallbackImpl); } [MonoPInvokeCallback] private static void GetTicketCallbackImpl(IntPtr ptr, Result result, ref string data) { GCHandle gCHandle = GCHandle.FromIntPtr(ptr); GetTicketHandler getTicketHandler = (GetTicketHandler)gCHandle.Target; gCHandle.Free(); getTicketHandler(result, ref data); } public void GetTicket(GetTicketHandler callback) { GCHandle value = GCHandle.Alloc(callback); Methods.GetTicket(MethodsPtr, GCHandle.ToIntPtr(value), GetTicketCallbackImpl); } } public class UserManager { internal struct FFIEvents { [UnmanagedFunctionPointer(CallingConvention.Cdecl)] internal delegate void CurrentUserUpdateHandler(IntPtr ptr); internal CurrentUserUpdateHandler OnCurrentUserUpdate; } internal struct FFIMethods { [UnmanagedFunctionPointer(CallingConvention.Cdecl)] internal delegate Result GetCurrentUserMethod(IntPtr methodsPtr, ref User currentUser); [UnmanagedFunctionPointer(CallingConvention.Cdecl)] internal delegate void GetUserCallback(IntPtr ptr, Result result, ref User user); [UnmanagedFunctionPointer(CallingConvention.Cdecl)] internal delegate void GetUserMethod(IntPtr methodsPtr, long userId, IntPtr callbackData, GetUserCallback callback); [UnmanagedFunctionPointer(CallingConvention.Cdecl)] internal delegate Result GetCurrentUserPremiumTypeMethod(IntPtr methodsPtr, ref PremiumType premiumType); [UnmanagedFunctionPointer(CallingConvention.Cdecl)] internal delegate Result CurrentUserHasFlagMethod(IntPtr methodsPtr, UserFlag flag, ref bool hasFlag); internal GetCurrentUserMethod GetCurrentUser; internal GetUserMethod GetUser; internal GetCurrentUserPremiumTypeMethod GetCurrentUserPremiumType; internal CurrentUserHasFlagMethod CurrentUserHasFlag; } public delegate void GetUserHandler(Result result, ref User user); public delegate void CurrentUserUpdateHandler(); private IntPtr MethodsPtr; private object MethodsStructure; private FFIMethods Methods { get { if (MethodsStructure == null) { MethodsStructure = Marshal.PtrToStructure(MethodsPtr, typeof(FFIMethods)); } return (FFIMethods)MethodsStructure; } } public event CurrentUserUpdateHandler OnCurrentUserUpdate; internal UserManager(IntPtr ptr, IntPtr eventsPtr, ref FFIEvents events) { if (eventsPtr == IntPtr.Zero) { throw new ResultException(Result.InternalError); } InitEvents(eventsPtr, ref events); MethodsPtr = ptr; if (MethodsPtr == IntPtr.Zero) { throw new ResultException(Result.InternalError); } } private void InitEvents(IntPtr eventsPtr, ref FFIEvents events) { events.OnCurrentUserUpdate = OnCurrentUserUpdateImpl; Marshal.StructureToPtr(events, eventsPtr, fDeleteOld: false); } public User GetCurrentUser() { User currentUser = default(User); Result result = Methods.GetCurrentUser(MethodsPtr, ref currentUser); if (result != 0) { throw new ResultException(result); } return currentUser; } [MonoPInvokeCallback] private static void GetUserCallbackImpl(IntPtr ptr, Result result, ref User user) { GCHandle gCHandle = GCHandle.FromIntPtr(ptr); GetUserHandler getUserHandler = (GetUserHandler)gCHandle.Target; gCHandle.Free(); getUserHandler(result, ref user); } public void GetUser(long userId, GetUserHandler callback) { GCHandle value = GCHandle.Alloc(callback); Methods.GetUser(MethodsPtr, userId, GCHandle.ToIntPtr(value), GetUserCallbackImpl); } public PremiumType GetCurrentUserPremiumType() { PremiumType premiumType = PremiumType.None; Result result = Methods.GetCurrentUserPremiumType(MethodsPtr, ref premiumType); if (result != 0) { throw new ResultException(result); } return premiumType; } public bool CurrentUserHasFlag(UserFlag flag) { bool hasFlag = false; Result result = Methods.CurrentUserHasFlag(MethodsPtr, flag, ref hasFlag); if (result != 0) { throw new ResultException(result); } return hasFlag; } [MonoPInvokeCallback] private static void OnCurrentUserUpdateImpl(IntPtr ptr) { Discord discord = (Discord)GCHandle.FromIntPtr(ptr).Target; if (discord.UserManagerInstance.OnCurrentUserUpdate != null) { discord.UserManagerInstance.OnCurrentUserUpdate(); } } } public class ImageManager { internal struct FFIEvents { } internal struct FFIMethods { [UnmanagedFunctionPointer(CallingConvention.Cdecl)] internal delegate void FetchCallback(IntPtr ptr, Result result, ImageHandle handleResult); [UnmanagedFunctionPointer(CallingConvention.Cdecl)] internal delegate void FetchMethod(IntPtr methodsPtr, ImageHandle handle, bool refresh, IntPtr callbackData, FetchCallback callback); [UnmanagedFunctionPointer(CallingConvention.Cdecl)] internal delegate Result GetDimensionsMethod(IntPtr methodsPtr, ImageHandle handle, ref ImageDimensions dimensions); [UnmanagedFunctionPointer(CallingConvention.Cdecl)] internal delegate Result GetDataMethod(IntPtr methodsPtr, ImageHandle handle, byte[] data, int dataLen); internal FetchMethod Fetch; internal GetDimensionsMethod GetDimensions; internal GetDataMethod GetData; } public delegate void FetchHandler(Result result, ImageHandle handleResult); private IntPtr MethodsPtr; private object MethodsStructure; private FFIMethods Methods { get { if (MethodsStructure == null) { MethodsStructure = Marshal.PtrToStructure(MethodsPtr, typeof(FFIMethods)); } return (FFIMethods)MethodsStructure; } } internal ImageManager(IntPtr ptr, IntPtr eventsPtr, ref FFIEvents events) { if (eventsPtr == IntPtr.Zero) { throw new ResultException(Result.InternalError); } InitEvents(eventsPtr, ref events); MethodsPtr = ptr; if (MethodsPtr == IntPtr.Zero) { throw new ResultException(Result.InternalError); } } private void InitEvents(IntPtr eventsPtr, ref FFIEvents events) { Marshal.StructureToPtr(events, eventsPtr, fDeleteOld: false); } [MonoPInvokeCallback] private static void FetchCallbackImpl(IntPtr ptr, Result result, ImageHandle handleResult) { GCHandle gCHandle = GCHandle.FromIntPtr(ptr); FetchHandler fetchHandler = (FetchHandler)gCHandle.Target; gCHandle.Free(); fetchHandler(result, handleResult); } public void Fetch(ImageHandle handle, bool refresh, FetchHandler callback) { GCHandle value = GCHandle.Alloc(callback); Methods.Fetch(MethodsPtr, handle, refresh, GCHandle.ToIntPtr(value), FetchCallbackImpl); } public ImageDimensions GetDimensions(ImageHandle handle) { ImageDimensions dimensions = default(ImageDimensions); Result result = Methods.GetDimensions(MethodsPtr, handle, ref dimensions); if (result != 0) { throw new ResultException(result); } return dimensions; } public void GetData(ImageHandle handle, byte[] data) { Result result = Methods.GetData(MethodsPtr, handle, data, data.Length); if (result != 0) { throw new ResultException(result); } } public void Fetch(ImageHandle handle, FetchHandler callback) { Fetch(handle, refresh: false, callback); } public byte[] GetData(ImageHandle handle) { ImageDimensions dimensions = GetDimensions(handle); byte[] array = new byte[dimensions.Width * dimensions.Height * 4]; GetData(handle, array); return array; } } public class RelationshipManager { internal struct FFIEvents { [UnmanagedFunctionPointer(CallingConvention.Cdecl)] internal delegate void RefreshHandler(IntPtr ptr); [UnmanagedFunctionPointer(CallingConvention.Cdecl)] internal delegate void RelationshipUpdateHandler(IntPtr ptr, ref Relationship relationship); internal RefreshHandler OnRefresh; internal RelationshipUpdateHandler OnRelationshipUpdate; } internal struct FFIMethods { [UnmanagedFunctionPointer(CallingConvention.Cdecl)] internal delegate bool FilterCallback(IntPtr ptr, ref Relationship relationship); [UnmanagedFunctionPointer(CallingConvention.Cdecl)] internal delegate void FilterMethod(IntPtr methodsPtr, IntPtr callbackData, FilterCallback callback); [UnmanagedFunctionPointer(CallingConvention.Cdecl)] internal delegate Result CountMethod(IntPtr methodsPtr, ref int count); [UnmanagedFunctionPointer(CallingConvention.Cdecl)] internal delegate Result GetMethod(IntPtr methodsPtr, long userId, ref Relationship relationship); [UnmanagedFunctionPointer(CallingConvention.Cdecl)] internal delegate Result GetAtMethod(IntPtr methodsPtr, uint index, ref Relationship relationship); internal FilterMethod Filter; internal CountMethod Count; internal GetMethod Get; internal GetAtMethod GetAt; } public delegate bool FilterHandler(ref Relationship relationship); public delegate void RefreshHandler(); public delegate void RelationshipUpdateHandler(ref Relationship relationship); private IntPtr MethodsPtr; private object MethodsStructure; private FFIMethods Methods { get { if (MethodsStructure == null) { MethodsStructure = Marshal.PtrToStructure(MethodsPtr, typeof(FFIMethods)); } return (FFIMethods)MethodsStructure; } } public event RefreshHandler OnRefresh; public event RelationshipUpdateHandler OnRelationshipUpdate; internal RelationshipManager(IntPtr ptr, IntPtr eventsPtr, ref FFIEvents events) { if (eventsPtr == IntPtr.Zero) { throw new ResultException(Result.InternalError); } InitEvents(eventsPtr, ref events); MethodsPtr = ptr; if (MethodsPtr == IntPtr.Zero) { throw new ResultException(Result.InternalError); } } private void InitEvents(IntPtr eventsPtr, ref FFIEvents events) { events.OnRefresh = OnRefreshImpl; events.OnRelationshipUpdate = OnRelationshipUpdateImpl; Marshal.StructureToPtr(events, eventsPtr, fDeleteOld: false); } [MonoPInvokeCallback] private static bool FilterCallbackImpl(IntPtr ptr, ref Relationship relationship) { FilterHandler filterHandler = (FilterHandler)GCHandle.FromIntPtr(ptr).Target; return filterHandler(ref relationship); } public void Filter(FilterHandler callback) { GCHandle value = GCHandle.Alloc(callback); Methods.Filter(MethodsPtr, GCHandle.ToIntPtr(value), FilterCallbackImpl); value.Free(); } public int Count() { int count = 0; Result result = Methods.Count(MethodsPtr, ref count); if (result != 0) { throw new ResultException(result); } return count; } public Relationship Get(long userId) { Relationship relationship = default(Relationship); Result result = Methods.Get(MethodsPtr, userId, ref relationship); if (result != 0) { throw new ResultException(result); } return relationship; } public Relationship GetAt(uint index) { Relationship relationship = default(Relationship); Result result = Methods.GetAt(MethodsPtr, index, ref relationship); if (result != 0) { throw new ResultException(result); } return relationship; } [MonoPInvokeCallback] private static void OnRefreshImpl(IntPtr ptr) { Discord discord = (Discord)GCHandle.FromIntPtr(ptr).Target; if (discord.RelationshipManagerInstance.OnRefresh != null) { discord.RelationshipManagerInstance.OnRefresh(); } } [MonoPInvokeCallback] private static void OnRelationshipUpdateImpl(IntPtr ptr, ref Relationship relationship) { Discord discord = (Discord)GCHandle.FromIntPtr(ptr).Target; if (discord.RelationshipManagerInstance.OnRelationshipUpdate != null) { discord.RelationshipManagerInstance.OnRelationshipUpdate(ref relationship); } } } public class LobbyManager { internal struct FFIEvents { [UnmanagedFunctionPointer(CallingConvention.Cdecl)] internal delegate void LobbyUpdateHandler(IntPtr ptr, long lobbyId); [UnmanagedFunctionPointer(CallingConvention.Cdecl)] internal delegate void LobbyDeleteHandler(IntPtr ptr, long lobbyId, uint reason); [UnmanagedFunctionPointer(CallingConvention.Cdecl)] internal delegate void MemberConnectHandler(IntPtr ptr, long lobbyId, long userId); [UnmanagedFunctionPointer(CallingConvention.Cdecl)] internal delegate void MemberUpdateHandler(IntPtr ptr, long lobbyId, long userId); [UnmanagedFunctionPointer(CallingConvention.Cdecl)] internal delegate void MemberDisconnectHandler(IntPtr ptr, long lobbyId, long userId); [UnmanagedFunctionPointer(CallingConvention.Cdecl)] internal delegate void LobbyMessageHandler(IntPtr ptr, long lobbyId, long userId, IntPtr dataPtr, int dataLen); [UnmanagedFunctionPointer(CallingConvention.Cdecl)] internal delegate void SpeakingHandler(IntPtr ptr, long lobbyId, long userId, bool speaking); [UnmanagedFunctionPointer(CallingConvention.Cdecl)] internal delegate void NetworkMessageHandler(IntPtr ptr, long lobbyId, long userId, byte channelId, IntPtr dataPtr, int dataLen); internal LobbyUpdateHandler OnLobbyUpdate; internal LobbyDeleteHandler OnLobbyDelete; internal MemberConnectHandler OnMemberConnect; internal MemberUpdateHandler OnMemberUpdate; internal MemberDisconnectHandler OnMemberDisconnect; internal LobbyMessageHandler OnLobbyMessage; internal SpeakingHandler OnSpeaking; internal NetworkMessageHandler OnNetworkMessage; } internal struct FFIMethods { [UnmanagedFunctionPointer(CallingConvention.Cdecl)] internal delegate Result GetLobbyCreateTransactionMethod(IntPtr methodsPtr, ref IntPtr transaction); [UnmanagedFunctionPointer(CallingConvention.Cdecl)] internal delegate Result GetLobbyUpdateTransactionMethod(IntPtr methodsPtr, long lobbyId, ref IntPtr transaction); [UnmanagedFunctionPointer(CallingConvention.Cdecl)] internal delegate Result GetMemberUpdateTransactionMethod(IntPtr methodsPtr, long lobbyId, long userId, ref IntPtr transaction); [UnmanagedFunctionPointer(CallingConvention.Cdecl)] internal delegate void CreateLobbyCallback(IntPtr ptr, Result result, ref Lobby lobby); [UnmanagedFunctionPointer(CallingConvention.Cdecl)] internal delegate void CreateLobbyMethod(IntPtr methodsPtr, IntPtr transaction, IntPtr callbackData, CreateLobbyCallback callback); [UnmanagedFunctionPointer(CallingConvention.Cdecl)] internal delegate void UpdateLobbyCallback(IntPtr ptr, Result result); [UnmanagedFunctionPointer(CallingConvention.Cdecl)] internal delegate void UpdateLobbyMethod(IntPtr methodsPtr, long lobbyId, IntPtr transaction, IntPtr callbackData, UpdateLobbyCallback callback); [UnmanagedFunctionPointer(CallingConvention.Cdecl)] internal delegate void DeleteLobbyCallback(IntPtr ptr, Result result); [UnmanagedFunctionPointer(CallingConvention.Cdecl)] internal delegate void DeleteLobbyMethod(IntPtr methodsPtr, long lobbyId, IntPtr callbackData, DeleteLobbyCallback callback); [UnmanagedFunctionPointer(CallingConvention.Cdecl)] internal delegate void ConnectLobbyCallback(IntPtr ptr, Result result, ref Lobby lobby); [UnmanagedFunctionPointer(CallingConvention.Cdecl)] internal delegate void ConnectLobbyMethod(IntPtr methodsPtr, long lobbyId, [MarshalAs(UnmanagedType.LPStr)] string secret, IntPtr callbackData, ConnectLobbyCallback callback); [UnmanagedFunctionPointer(CallingConvention.Cdecl)] internal delegate void ConnectLobbyWithActivitySecretCallback(IntPtr ptr, Result result, ref Lobby lobby); [UnmanagedFunctionPointer(CallingConvention.Cdecl)] internal delegate void ConnectLobbyWithActivitySecretMethod(IntPtr methodsPtr, [MarshalAs(UnmanagedType.LPStr)] string activitySecret, IntPtr callbackData, ConnectLobbyWithActivitySecretCallback callback); [UnmanagedFunctionPointer(CallingConvention.Cdecl)] internal delegate void DisconnectLobbyCallback(IntPtr ptr, Result result); [UnmanagedFunctionPointer(CallingConvention.Cdecl)] internal delegate void DisconnectLobbyMethod(IntPtr methodsPtr, long lobbyId, IntPtr callbackData, DisconnectLobbyCallback callback); [UnmanagedFunctionPointer(CallingConvention.Cdecl)] internal delegate Result GetLobbyMethod(IntPtr methodsPtr, long lobbyId, ref Lobby lobby); [UnmanagedFunctionPointer(CallingConvention.Cdecl)] internal delegate Result GetLobbyActivitySecretMethod(IntPtr methodsPtr, long lobbyId, StringBuilder secret); [UnmanagedFunctionPointer(CallingConvention.Cdecl)] internal delegate Result GetLobbyMetadataValueMethod(IntPtr methodsPtr, long lobbyId, [MarshalAs(UnmanagedType.LPStr)] string key, StringBuilder value); [UnmanagedFunctionPointer(CallingConvention.Cdecl)] internal delegate Result GetLobbyMetadataKeyMethod(IntPtr methodsPtr, long lobbyId, int index, StringBuilder key); [UnmanagedFunctionPointer(CallingConvention.Cdecl)] internal delegate Result LobbyMetadataCountMethod(IntPtr methodsPtr, long lobbyId, ref int count); [UnmanagedFunctionPointer(CallingConvention.Cdecl)] internal delegate Result MemberCountMethod(IntPtr methodsPtr, long lobbyId, ref int count); [UnmanagedFunctionPointer(CallingConvention.Cdecl)] internal delegate Result GetMemberUserIdMethod(IntPtr methodsPtr, long lobbyId, int index, ref long userId); [UnmanagedFunctionPointer(CallingConvention.Cdecl)] internal delegate Result GetMemberUserMethod(IntPtr methodsPtr, long lobbyId, long userId, ref User user); [UnmanagedFunctionPointer(CallingConvention.Cdecl)] internal delegate Result GetMemberMetadataValueMethod(IntPtr methodsPtr, long lobbyId, long userId, [MarshalAs(UnmanagedType.LPStr)] string key, StringBuilder value); [UnmanagedFunctionPointer(CallingConvention.Cdecl)] internal delegate Result GetMemberMetadataKeyMethod(IntPtr methodsPtr, long lobbyId, long userId, int index, StringBuilder key); [UnmanagedFunctionPointer(CallingConvention.Cdecl)] internal delegate Result MemberMetadataCountMethod(IntPtr methodsPtr, long lobbyId, long userId, ref int count); [UnmanagedFunctionPointer(CallingConvention.Cdecl)] internal delegate void UpdateMemberCallback(IntPtr ptr, Result result); [UnmanagedFunctionPointer(CallingConvention.Cdecl)] internal delegate void UpdateMemberMethod(IntPtr methodsPtr, long lobbyId, long userId, IntPtr transaction, IntPtr callbackData, UpdateMemberCallback callback); [UnmanagedFunctionPointer(CallingConvention.Cdecl)] internal delegate void SendLobbyMessageCallback(IntPtr ptr, Result result); [UnmanagedFunctionPointer(CallingConvention.Cdecl)] internal delegate void SendLobbyMessageMethod(IntPtr methodsPtr, long lobbyId, byte[] data, int dataLen, IntPtr callbackData, SendLobbyMessageCallback callback); [UnmanagedFunctionPointer(CallingConvention.Cdecl)] internal delegate Result GetSearchQueryMethod(IntPtr methodsPtr, ref IntPtr query); [UnmanagedFunctionPointer(CallingConvention.Cdecl)] internal delegate void SearchCallback(IntPtr ptr, Result result); [UnmanagedFunctionPointer(CallingConvention.Cdecl)] internal delegate void SearchMethod(IntPtr methodsPtr, IntPtr query, IntPtr callbackData, SearchCallback callback); [UnmanagedFunctionPointer(CallingConvention.Cdecl)] internal delegate void LobbyCountMethod(IntPtr methodsPtr, ref int count); [UnmanagedFunctionPointer(CallingConvention.Cdecl)] internal delegate Result GetLobbyIdMethod(IntPtr methodsPtr, int index, ref long lobbyId); [UnmanagedFunctionPointer(CallingConvention.Cdecl)] internal delegate void ConnectVoiceCallback(IntPtr ptr, Result result); [UnmanagedFunctionPointer(CallingConvention.Cdecl)] internal delegate void ConnectVoiceMethod(IntPtr methodsPtr, long lobbyId, IntPtr callbackData, ConnectVoiceCallback callback); [UnmanagedFunctionPointer(CallingConvention.Cdecl)] internal delegate void DisconnectVoiceCallback(IntPtr ptr, Result result); [UnmanagedFunctionPointer(CallingConvention.Cdecl)] internal delegate void DisconnectVoiceMethod(IntPtr methodsPtr, long lobbyId, IntPtr callbackData, DisconnectVoiceCallback callback); [UnmanagedFunctionPointer(CallingConvention.Cdecl)] internal delegate Result ConnectNetworkMethod(IntPtr methodsPtr, long lobbyId); [UnmanagedFunctionPointer(CallingConvention.Cdecl)] internal delegate Result DisconnectNetworkMethod(IntPtr methodsPtr, long lobbyId); [UnmanagedFunctionPointer(CallingConvention.Cdecl)] internal delegate Result FlushNetworkMethod(IntPtr methodsPtr); [UnmanagedFunctionPointer(CallingConvention.Cdecl)] internal delegate Result OpenNetworkChannelMethod(IntPtr methodsPtr, long lobbyId, byte channelId, bool reliable); [UnmanagedFunctionPointer(CallingConvention.Cdecl)] internal delegate Result SendNetworkMessageMethod(IntPtr methodsPtr, long lobbyId, long userId, byte channelId, byte[] data, int dataLen); internal GetLobbyCreateTransactionMethod GetLobbyCreateTransaction; internal GetLobbyUpdateTransactionMethod GetLobbyUpdateTransaction; internal GetMemberUpdateTransactionMethod GetMemberUpdateTransaction; internal CreateLobbyMethod CreateLobby; internal UpdateLobbyMethod UpdateLobby; internal DeleteLobbyMethod DeleteLobby; internal ConnectLobbyMethod ConnectLobby; internal ConnectLobbyWithActivitySecretMethod ConnectLobbyWithActivitySecret; internal DisconnectLobbyMethod DisconnectLobby; internal GetLobbyMethod GetLobby; internal GetLobbyActivitySecretMethod GetLobbyActivitySecret; internal GetLobbyMetadataValueMethod GetLobbyMetadataValue; internal GetLobbyMetadataKeyMethod GetLobbyMetadataKey; internal LobbyMetadataCountMethod LobbyMetadataCount; internal MemberCountMethod MemberCount; internal GetMemberUserIdMethod GetMemberUserId; internal GetMemberUserMethod GetMemberUser; internal GetMemberMetadataValueMethod GetMemberMetadataValue; internal GetMemberMetadataKeyMethod GetMemberMetadataKey; internal MemberMetadataCountMethod MemberMetadataCount; internal UpdateMemberMethod UpdateMember; internal SendLobbyMessageMethod SendLobbyMessage; internal GetSearchQueryMethod GetSearchQuery; internal SearchMethod Search; internal LobbyCountMethod LobbyCount; internal GetLobbyIdMethod GetLobbyId; internal ConnectVoiceMethod ConnectVoice; internal DisconnectVoiceMethod DisconnectVoice; internal ConnectNetworkMethod ConnectNetwork; internal DisconnectNetworkMethod DisconnectNetwork; internal FlushNetworkMethod FlushNetwork; internal OpenNetworkChannelMethod OpenNetworkChannel; internal SendNetworkMessageMethod SendNetworkMessage; } public delegate void CreateLobbyHandler(Result result, ref Lobby lobby); public delegate void UpdateLobbyHandler(Result result); public delegate void DeleteLobbyHandler(Result result); public delegate void ConnectLobbyHandler(Result result, ref Lobby lobby); public delegate void ConnectLobbyWithActivitySecretHandler(Result result, ref Lobby lobby); public delegate void DisconnectLobbyHandler(Result result); public delegate void UpdateMemberHandler(Result result); public delegate void SendLobbyMessageHandler(Result result); public delegate void SearchHandler(Result result); public delegate void ConnectVoiceHandler(Result result); public delegate void DisconnectVoiceHandler(Result result); public delegate void LobbyUpdateHandler(long lobbyId); public delegate void LobbyDeleteHandler(long lobbyId, uint reason); public delegate void MemberConnectHandler(long lobbyId, long userId); public delegate void MemberUpdateHandler(long lobbyId, long userId); public delegate void MemberDisconnectHandler(long lobbyId, long userId); public delegate void LobbyMessageHandler(long lobbyId, long userId, byte[] data); public delegate void SpeakingHandler(long lobbyId, long userId, bool speaking); public delegate void NetworkMessageHandler(long lobbyId, long userId, byte channelId, byte[] data); private IntPtr MethodsPtr; private object MethodsStructure; private FFIMethods Methods { get { if (MethodsStructure == null) { MethodsStructure = Marshal.PtrToStructure(MethodsPtr, typeof(FFIMethods)); } return (FFIMethods)MethodsStructure; } } public event LobbyUpdateHandler OnLobbyUpdate; public event LobbyDeleteHandler OnLobbyDelete; public event MemberConnectHandler OnMemberConnect; public event MemberUpdateHandler OnMemberUpdate; public event MemberDisconnectHandler OnMemberDisconnect; public event LobbyMessageHandler OnLobbyMessage; public event SpeakingHandler OnSpeaking; public event NetworkMessageHandler OnNetworkMessage; internal LobbyManager(IntPtr ptr, IntPtr eventsPtr, ref FFIEvents events) { if (eventsPtr == IntPtr.Zero) { throw new ResultException(Result.InternalError); } InitEvents(eventsPtr, ref events); MethodsPtr = ptr; if (MethodsPtr == IntPtr.Zero) { throw new ResultException(Result.InternalError); } } private void InitEvents(IntPtr eventsPtr, ref FFIEvents events) { events.OnLobbyUpdate = OnLobbyUpdateImpl; events.OnLobbyDelete = OnLobbyDeleteImpl; events.OnMemberConnect = OnMemberConnectImpl; events.OnMemberUpdate = OnMemberUpdateImpl; events.OnMemberDisconnect = OnMemberDisconnectImpl; events.OnLobbyMessage = OnLobbyMessageImpl; events.OnSpeaking = OnSpeakingImpl; events.OnNetworkMessage = OnNetworkMessageImpl; Marshal.StructureToPtr(events, eventsPtr, fDeleteOld: false); } public LobbyTransaction GetLobbyCreateTransaction() { LobbyTransaction result = default(LobbyTransaction); Result result2 = Methods.GetLobbyCreateTransaction(MethodsPtr, ref result.MethodsPtr); if (result2 != 0) { throw new ResultException(result2); } return result; } public LobbyTransaction GetLobbyUpdateTransaction(long lobbyId) { LobbyTransaction result = default(LobbyTransaction); Result result2 = Methods.GetLobbyUpdateTransaction(MethodsPtr, lobbyId, ref result.MethodsPtr); if (result2 != 0) { throw new ResultException(result2); } return result; } public LobbyMemberTransaction GetMemberUpdateTransaction(long lobbyId, long userId) { LobbyMemberTransaction result = default(LobbyMemberTransaction); Result result2 = Methods.GetMemberUpdateTransaction(MethodsPtr, lobbyId, userId, ref result.MethodsPtr); if (result2 != 0) { throw new ResultException(result2); } return result; } [MonoPInvokeCallback] private static void CreateLobbyCallbackImpl(IntPtr ptr, Result result, ref Lobby lobby) { GCHandle gCHandle = GCHandle.FromIntPtr(ptr); CreateLobbyHandler createLobbyHandler = (CreateLobbyHandler)gCHandle.Target; gCHandle.Free(); createLobbyHandler(result, ref lobby); } public void CreateLobby(LobbyTransaction transaction, CreateLobbyHandler callback) { GCHandle value = GCHandle.Alloc(callback); Methods.CreateLobby(MethodsPtr, transaction.MethodsPtr, GCHandle.ToIntPtr(value), CreateLobbyCallbackImpl); transaction.MethodsPtr = IntPtr.Zero; } [MonoPInvokeCallback] private static void UpdateLobbyCallbackImpl(IntPtr ptr, Result result) { GCHandle gCHandle = GCHandle.FromIntPtr(ptr); UpdateLobbyHandler updateLobbyHandler = (UpdateLobbyHandler)gCHandle.Target; gCHandle.Free(); updateLobbyHandler(result); } public void UpdateLobby(long lobbyId, LobbyTransaction transaction, UpdateLobbyHandler callback) { GCHandle value = GCHandle.Alloc(callback); Methods.UpdateLobby(MethodsPtr, lobbyId, transaction.MethodsPtr, GCHandle.ToIntPtr(value), UpdateLobbyCallbackImpl); transaction.MethodsPtr = IntPtr.Zero; } [MonoPInvokeCallback] private static void DeleteLobbyCallbackImpl(IntPtr ptr, Result result) { GCHandle gCHandle = GCHandle.FromIntPtr(ptr); DeleteLobbyHandler deleteLobbyHandler = (DeleteLobbyHandler)gCHandle.Target; gCHandle.Free(); deleteLobbyHandler(result); } public void DeleteLobby(long lobbyId, DeleteLobbyHandler callback) { GCHandle value = GCHandle.Alloc(callback); Methods.DeleteLobby(MethodsPtr, lobbyId, GCHandle.ToIntPtr(value), DeleteLobbyCallbackImpl); } [MonoPInvokeCallback] private static void ConnectLobbyCallbackImpl(IntPtr ptr, Result result, ref Lobby lobby) { GCHandle gCHandle = GCHandle.FromIntPtr(ptr); ConnectLobbyHandler connectLobbyHandler = (ConnectLobbyHandler)gCHandle.Target; gCHandle.Free(); connectLobbyHandler(result, ref lobby); } public void ConnectLobby(long lobbyId, string secret, ConnectLobbyHandler callback) { GCHandle value = GCHandle.Alloc(callback); Methods.ConnectLobby(MethodsPtr, lobbyId, secret, GCHandle.ToIntPtr(value), ConnectLobbyCallbackImpl); } [MonoPInvokeCallback] private static void ConnectLobbyWithActivitySecretCallbackImpl(IntPtr ptr, Result result, ref Lobby lobby) { GCHandle gCHandle = GCHandle.FromIntPtr(ptr); ConnectLobbyWithActivitySecretHandler connectLobbyWithActivitySecretHandler = (ConnectLobbyWithActivitySecretHandler)gCHandle.Target; gCHandle.Free(); connectLobbyWithActivitySecretHandler(result, ref lobby); } public void ConnectLobbyWithActivitySecret(string activitySecret, ConnectLobbyWithActivitySecretHandler callback) { GCHandle value = GCHandle.Alloc(callback); Methods.ConnectLobbyWithActivitySecret(MethodsPtr, activitySecret, GCHandle.ToIntPtr(value), ConnectLobbyWithActivitySecretCallbackImpl); } [MonoPInvokeCallback] private static void DisconnectLobbyCallbackImpl(IntPtr ptr, Result result) { GCHandle gCHandle = GCHandle.FromIntPtr(ptr); DisconnectLobbyHandler disconnectLobbyHandler = (DisconnectLobbyHandler)gCHandle.Target; gCHandle.Free(); disconnectLobbyHandler(result); } public void DisconnectLobby(long lobbyId, DisconnectLobbyHandler callback) { GCHandle value = GCHandle.Alloc(callback); Methods.DisconnectLobby(MethodsPtr, lobbyId, GCHandle.ToIntPtr(value), DisconnectLobbyCallbackImpl); } public Lobby GetLobby(long lobbyId) { Lobby lobby = default(Lobby); Result result = Methods.GetLobby(MethodsPtr, lobbyId, ref lobby); if (result != 0) { throw new ResultException(result); } return lobby; } public string GetLobbyActivitySecret(long lobbyId) { StringBuilder stringBuilder = new StringBuilder(128); Result result = Methods.GetLobbyActivitySecret(MethodsPtr, lobbyId, stringBuilder); if (result != 0) { throw new ResultException(result); } return stringBuilder.ToString(); } public string GetLobbyMetadataValue(long lobbyId, string key) { StringBuilder stringBuilder = new StringBuilder(4096); Result result = Methods.GetLobbyMetadataValue(MethodsPtr, lobbyId, key, stringBuilder); if (result != 0) { throw new ResultException(result); } return stringBuilder.ToString(); } public string GetLobbyMetadataKey(long lobbyId, int index) { StringBuilder stringBuilder = new StringBuilder(256); Result result = Methods.GetLobbyMetadataKey(MethodsPtr, lobbyId, index, stringBuilder); if (result != 0) { throw new ResultException(result); } return stringBuilder.ToString(); } public int LobbyMetadataCount(long lobbyId) { int count = 0; Result result = Methods.LobbyMetadataCount(MethodsPtr, lobbyId, ref count); if (result != 0) { throw new ResultException(result); } return count; } public int MemberCount(long lobbyId) { int count = 0; Result result = Methods.MemberCount(MethodsPtr, lobbyId, ref count); if (result != 0) { throw new ResultException(result); } return count; } public long GetMemberUserId(long lobbyId, int index) { long userId = 0L; Result result = Methods.GetMemberUserId(MethodsPtr, lobbyId, index, ref userId); if (result != 0) { throw new ResultException(result); } return userId; } public User GetMemberUser(long lobbyId, long userId) { User user = default(User); Result result = Methods.GetMemberUser(MethodsPtr, lobbyId, userId, ref user); if (result != 0) { throw new ResultException(result); } return user; } public string GetMemberMetadataValue(long lobbyId, long userId, string key) { StringBuilder stringBuilder = new StringBuilder(4096); Result result = Methods.GetMemberMetadataValue(MethodsPtr, lobbyId, userId, key, stringBuilder); if (result != 0) { throw new ResultException(result); } return stringBuilder.ToString(); } public string GetMemberMetadataKey(long lobbyId, long userId, int index) { StringBuilder stringBuilder = new StringBuilder(256); Result result = Methods.GetMemberMetadataKey(MethodsPtr, lobbyId, userId, index, stringBuilder); if (result != 0) { throw new ResultException(result); } return stringBuilder.ToString(); } public int MemberMetadataCount(long lobbyId, long userId) { int count = 0; Result result = Methods.MemberMetadataCount(MethodsPtr, lobbyId, userId, ref count); if (result != 0) { throw new ResultException(result); } return count; } [MonoPInvokeCallback] private static void UpdateMemberCallbackImpl(IntPtr ptr, Result result) { GCHandle gCHandle = GCHandle.FromIntPtr(ptr); UpdateMemberHandler updateMemberHandler = (UpdateMemberHandler)gCHandle.Target; gCHandle.Free(); updateMemberHandler(result); } public void UpdateMember(long lobbyId, long userId, LobbyMemberTransaction transaction, UpdateMemberHandler callback) { GCHandle value = GCHandle.Alloc(callback); Methods.UpdateMember(MethodsPtr, lobbyId, userId, transaction.MethodsPtr, GCHandle.ToIntPtr(value), UpdateMemberCallbackImpl); transaction.MethodsPtr = IntPtr.Zero; } [MonoPInvokeCallback] private static void SendLobbyMessageCallbackImpl(IntPtr ptr, Result result) { GCHandle gCHandle = GCHandle.FromIntPtr(ptr); SendLobbyMessageHandler sendLobbyMessageHandler = (SendLobbyMessageHandler)gCHandle.Target; gCHandle.Free(); sendLobbyMessageHandler(result); } public void SendLobbyMessage(long lobbyId, byte[] data, SendLobbyMessageHandler callback) { GCHandle value = GCHandle.Alloc(callback); Methods.SendLobbyMessage(MethodsPtr, lobbyId, data, data.Length, GCHandle.ToIntPtr(value), SendLobbyMessageCallbackImpl); } public LobbySearchQuery GetSearchQuery() { LobbySearchQuery result = default(LobbySearchQuery); Result result2 = Methods.GetSearchQuery(MethodsPtr, ref result.MethodsPtr); if (result2 != 0) { throw new ResultException(result2); } return result; } [MonoPInvokeCallback] private static void SearchCallbackImpl(IntPtr ptr, Result result) { GCHandle gCHandle = GCHandle.FromIntPtr(ptr); SearchHandler searchHandler = (SearchHandler)gCHandle.Target; gCHandle.Free(); searchHandler(result); } public void Search(LobbySearchQuery query, SearchHandler callback) { GCHandle value = GCHandle.Alloc(callback); Methods.Search(MethodsPtr, query.MethodsPtr, GCHandle.ToIntPtr(value), SearchCallbackImpl); query.MethodsPtr = IntPtr.Zero; } public int LobbyCount() { int count = 0; Methods.LobbyCount(MethodsPtr, ref count); return count; } public long GetLobbyId(int index) { long lobbyId = 0L; Result result = Methods.GetLobbyId(MethodsPtr, index, ref lobbyId); if (result != 0) { throw new ResultException(result); } return lobbyId; } [MonoPInvokeCallback] private static void ConnectVoiceCallbackImpl(IntPtr ptr, Result result) { GCHandle gCHandle = GCHandle.FromIntPtr(ptr); ConnectVoiceHandler connectVoiceHandler = (ConnectVoiceHandler)gCHandle.Target; gCHandle.Free(); connectVoiceHandler(result); } public void ConnectVoice(long lobbyId, ConnectVoiceHandler callback) { GCHandle value = GCHandle.Alloc(callback); Methods.ConnectVoice(MethodsPtr, lobbyId, GCHandle.ToIntPtr(value), ConnectVoiceCallbackImpl); } [MonoPInvokeCallback] private static void DisconnectVoiceCallbackImpl(IntPtr ptr, Result result) { GCHandle gCHandle = GCHandle.FromIntPtr(ptr); DisconnectVoiceHandler disconnectVoiceHandler = (DisconnectVoiceHandler)gCHandle.Target; gCHandle.Free(); disconnectVoiceHandler(result); } public void DisconnectVoice(long lobbyId, DisconnectVoiceHandler callback) { GCHandle value = GCHandle.Alloc(callback); Methods.DisconnectVoice(MethodsPtr, lobbyId, GCHandle.ToIntPtr(value), DisconnectVoiceCallbackImpl); } public void ConnectNetwork(long lobbyId) { Result result = Methods.ConnectNetwork(MethodsPtr, lobbyId); if (result != 0) { throw new ResultException(result); } } public void DisconnectNetwork(long lobbyId) { Result result = Methods.DisconnectNetwork(MethodsPtr, lobbyId); if (result != 0) { throw new ResultException(result); } } public void FlushNetwork() { Result result = Methods.FlushNetwork(MethodsPtr); if (result != 0) { throw new ResultException(result); } } public void OpenNetworkChannel(long lobbyId, byte channelId, bool reliable) { Result result = Methods.OpenNetworkChannel(MethodsPtr, lobbyId, channelId, reliable); if (result != 0) { throw new ResultException(result); } } public void SendNetworkMessage(long lobbyId, long userId, byte channelId, byte[] data) { Result result = Methods.SendNetworkMessage(MethodsPtr, lobbyId, userId, channelId, data, data.Length); if (result != 0) { throw new ResultException(result); } } [MonoPInvokeCallback] private static void OnLobbyUpdateImpl(IntPtr ptr, long lobbyId) { Discord discord = (Discord)GCHandle.FromIntPtr(ptr).Target; if (discord.LobbyManagerInstance.OnLobbyUpdate != null) { discord.LobbyManagerInstance.OnLobbyUpdate(lobbyId); } } [MonoPInvokeCallback] private static void OnLobbyDeleteImpl(IntPtr ptr, long lobbyId, uint reason) { Discord discord = (Discord)GCHandle.FromIntPtr(ptr).Target; if (discord.LobbyManagerInstance.OnLobbyDelete != null) { discord.LobbyManagerInstance.OnLobbyDelete(lobbyId, reason); } } [MonoPInvokeCallback] private static void OnMemberConnectImpl(IntPtr ptr, long lobbyId, long userId) { Discord discord = (Discord)GCHandle.FromIntPtr(ptr).Target; if (discord.LobbyManagerInstance.OnMemberConnect != null) { discord.LobbyManagerInstance.OnMemberConnect(lobbyId, userId); } } [MonoPInvokeCallback] private static void OnMemberUpdateImpl(IntPtr ptr, long lobbyId, long userId) { Discord discord = (Discord)GCHandle.FromIntPtr(ptr).Target; if (discord.LobbyManagerInstance.OnMemberUpdate != null) { discord.LobbyManagerInstance.OnMemberUpdate(lobbyId, userId); } } [MonoPInvokeCallback] private static void OnMemberDisconnectImpl(IntPtr ptr, long lobbyId, long userId) { Discord discord = (Discord)GCHandle.FromIntPtr(ptr).Target; if (discord.LobbyManagerInstance.OnMemberDisconnect != null) { discord.LobbyManagerInstance.OnMemberDisconnect(lobbyId, userId); } } [MonoPInvokeCallback] private static void OnLobbyMessageImpl(IntPtr ptr, long lobbyId, long userId, IntPtr dataPtr, int dataLen) { Discord discord = (Discord)GCHandle.FromIntPtr(ptr).Target; if (discord.LobbyManagerInstance.OnLobbyMessage != null) { byte[] array = new byte[dataLen]; Marshal.Copy(dataPtr, array, 0, dataLen); discord.LobbyManagerInstance.OnLobbyMessage(lobbyId, userId, array); } } [MonoPInvokeCallback] private static void OnSpeakingImpl(IntPtr ptr, long lobbyId, long userId, bool speaking) { Discord discord = (Discord)GCHandle.FromIntPtr(ptr).Target; if (discord.LobbyManagerInstance.OnSpeaking != null) { discord.LobbyManagerInstance.OnSpeaking(lobbyId, userId, speaking); } } [MonoPInvokeCallback] private static void OnNetworkMessageImpl(IntPtr ptr, long lobbyId, long userId, byte channelId, IntPtr dataPtr, int dataLen) { Discord discord = (Discord)GCHandle.FromIntPtr(ptr).Target; if (discord.LobbyManagerInstance.OnNetworkMessage != null) { byte[] array = new byte[dataLen]; Marshal.Copy(dataPtr, array, 0, dataLen); discord.LobbyManagerInstance.OnNetworkMessage(lobbyId, userId, channelId, array); } } public IEnumerable<User> GetMemberUsers(long lobbyID) { int num = MemberCount(lobbyID); List<User> list = new List<User>(); for (int i = 0; i < num; i++) { list.Add(GetMemberUser(lobbyID, GetMemberUserId(lobbyID, i))); } return list; } public void SendLobbyMessage(long lobbyID, string data, SendLobbyMessageHandler handler) { SendLobbyMessage(lobbyID, Encoding.UTF8.GetBytes(data), handler); } } public class NetworkManager { internal struct FFIEvents { [UnmanagedFunctionPointer(CallingConvention.Cdecl)] internal delegate void MessageHandler(IntPtr ptr, ulong peerId, byte channelId, IntPtr dataPtr, int dataLen); [UnmanagedFunctionPointer(CallingConvention.Cdecl)] internal delegate void RouteUpdateHandler(IntPtr ptr, [MarshalAs(UnmanagedType.LPStr)] string routeData); internal MessageHandler OnMessage; internal RouteUpdateHandler OnRouteUpdate; } internal struct FFIMethods { [UnmanagedFunctionPointer(CallingConvention.Cdecl)] internal delegate void GetPeerIdMethod(IntPtr methodsPtr, ref ulong peerId); [UnmanagedFunctionPointer(CallingConvention.Cdecl)] internal delegate Result FlushMethod(IntPtr methodsPtr); [UnmanagedFunctionPointer(CallingConvention.Cdecl)] internal delegate Result OpenPeerMethod(IntPtr methodsPtr, ulong peerId, [MarshalAs(UnmanagedType.LPStr)] string routeData); [UnmanagedFunctionPointer(CallingConvention.Cdecl)] internal delegate Result UpdatePeerMethod(IntPtr methodsPtr, ulong peerId, [MarshalAs(UnmanagedType.LPStr)] string routeData); [UnmanagedFunctionPointer(CallingConvention.Cdecl)] internal delegate Result ClosePeerMethod(IntPtr methodsPtr, ulong peerId); [UnmanagedFunctionPointer(CallingConvention.Cdecl)] internal delegate Result OpenChannelMethod(IntPtr methodsPtr, ulong peerId, byte channelId, bool reliable); [UnmanagedFunctionPointer(CallingConvention.Cdecl)] internal delegate Result CloseChannelMethod(IntPtr methodsPtr, ulong peerId, byte channelId); [UnmanagedFunctionPointer(CallingConvention.Cdecl)] internal delegate Result SendMessageMethod(IntPtr methodsPtr, ulong peerId, byte channelId, byte[] data, int dataLen); internal GetPeerIdMethod GetPeerId; internal FlushMethod Flush; internal OpenPeerMethod OpenPeer; internal UpdatePeerMethod UpdatePeer; internal ClosePeerMethod ClosePeer; internal OpenChannelMethod OpenChannel; internal CloseChannelMethod CloseChannel; internal SendMessageMethod SendMessage; } public delegate void MessageHandler(ulong peerId, byte channelId, byte[] data); public delegate void RouteUpdateHandler(string routeData); private IntPtr MethodsPtr; private object MethodsStructure; private FFIMethods Methods { get { if (MethodsStructure == null) { MethodsStructure = Marshal.PtrToStructure(MethodsPtr, typeof(FFIMethods)); } return (FFIMethods)MethodsStructure; } } public event MessageHandler OnMessage; public event RouteUpdateHandler OnRouteUpdate; internal NetworkManager(IntPtr ptr, IntPtr eventsPtr, ref FFIEvents events) { if (eventsPtr == IntPtr.Zero) { throw new ResultException(Result.InternalError); } InitEvents(eventsPtr, ref events); MethodsPtr = ptr; if (MethodsPtr == IntPtr.Zero) { throw new ResultException(Result.InternalError); } } private void InitEvents(IntPtr eventsPtr, ref FFIEvents events) { events.OnMessage = OnMessageImpl; events.OnRouteUpdate = OnRouteUpdateImpl; Marshal.StructureToPtr(events, eventsPtr, fDeleteOld: false); } public ulong GetPeerId() { ulong peerId = 0uL; Methods.GetPeerId(MethodsPtr, ref peerId); return peerId; } public void Flush() { Result result = Methods.Flush(MethodsPtr); if (result != 0) { throw new ResultException(result); } } public void OpenPeer(ulong peerId, string routeData) { Result result = Methods.OpenPeer(MethodsPtr, peerId, routeData); if (result != 0) { throw new ResultException(result); } } public void UpdatePeer(ulong peerId, string routeData) { Result result = Methods.UpdatePeer(MethodsPtr, peerId, routeData); if (result != 0) { throw new ResultException(result); } } public void ClosePeer(ulong peerId) { Result result = Methods.ClosePeer(MethodsPtr, peerId); if (result != 0) { throw new ResultException(result); } } public void OpenChannel(ulong peerId, byte channelId, bool reliable) { Result result = Methods.OpenChannel(MethodsPtr, peerId, channelId, reliable); if (result != 0) { throw new ResultException(result); } } public void CloseChannel(ulong peerId, byte channelId) { Result result = Methods.CloseChannel(MethodsPtr, peerId, channelId); if (result != 0) { throw new ResultException(result); } } public void SendMessage(ulong peerId, byte channelId, byte[] data) { Result result = Methods.SendMessage(MethodsPtr, peerId, channelId, data, data.Length); if (result != 0) { throw new ResultException(result); } } [MonoPInvokeCallback] private static void OnMessageImpl(IntPtr ptr, ulong peerId, byte channelId, IntPtr dataPtr, int dataLen) { Discord discord = (Discord)GCHandle.FromIntPtr(ptr).Target; if (discord.NetworkManagerInstance.OnMessage != null) { byte[] array = new byte[dataLen]; Marshal.Copy(dataPtr, array, 0, dataLen); discord.NetworkManagerInstance.OnMessage(peerId, channelId, array); } } [MonoPInvokeCallback] private static void OnRouteUpdateImpl(IntPtr ptr, string routeData) { Discord discord = (Discord)GCHandle.FromIntPtr(ptr).Target; if (discord.NetworkManagerInstance.OnRouteUpdate != null) { discord.NetworkManagerInstance.OnRouteUpdate(routeData); } } } public class OverlayManager { internal struct FFIEvents { [UnmanagedFunctionPointer(CallingConvention.Cdecl)] internal delegate void ToggleHandler(IntPtr ptr, bool locked); internal ToggleHandler OnToggle; } internal struct FFIMethods { [UnmanagedFunctionPointer(CallingConvention.Cdecl)] internal delegate void IsEnabledMethod(IntPtr methodsPtr, ref bool enabled); [UnmanagedFunctionPointer(CallingConvention.Cdecl)] internal delegate void IsLockedMethod(IntPtr methodsPtr, ref bool locked); [UnmanagedFunctionPointer(CallingConvention.Cdecl)] internal delegate void SetLockedCallback(IntPtr ptr, Result result); [UnmanagedFunctionPointer(CallingConvention.Cdecl)] internal delegate void SetLockedMethod(IntPtr methodsPtr, bool locked, IntPtr callbackData, SetLockedCallback callback); [UnmanagedFunctionPointer(CallingConvention.Cdecl)] internal delegate void OpenActivityInviteCallback(IntPtr ptr, Result result); [UnmanagedFunctionPointer(CallingConvention.Cdecl)] internal delegate void OpenActivityInviteMethod(IntPtr methodsPtr, ActivityActionType type, IntPtr callbackData, OpenActivityInviteCallback callback); [UnmanagedFunctionPointer(CallingConvention.Cdecl)] internal delegate void OpenGuildInviteCallback(IntPtr ptr, Result result); [UnmanagedFunctionPointer(CallingConvention.Cdecl)] internal delegate void OpenGuildInviteMethod(IntPtr methodsPtr, [MarshalAs(UnmanagedType.LPStr)] string code, IntPtr callbackData, OpenGuildInviteCallback callback); [UnmanagedFunctionPointer(CallingConvention.Cdecl)] internal delegate void OpenVoiceSettingsCallback(IntPtr ptr, Result result); [UnmanagedFunctionPointer(CallingConvention.Cdecl)] internal delegate void OpenVoiceSettingsMethod(IntPtr methodsPtr, IntPtr callbackData, OpenVoiceSettingsCallback callback); internal IsEnabledMethod IsEnabled; internal IsLockedMethod IsLocked; internal SetLockedMethod SetLocked; internal OpenActivityInviteMethod OpenActivityInvite; internal OpenGuildInviteMethod OpenGuildInvite; internal OpenVoiceSettingsMethod OpenVoiceSettings; } public delegate void SetLockedHandler(Result result); public delegate void OpenActivityInviteHandler(Result result); public delegate void OpenGuildInviteHandler(Result result); public delegate void OpenVoiceSettingsHandler(Result result); public delegate void ToggleHandler(bool locked); private IntPtr MethodsPtr; private object MethodsStructure; private FFIMethods Methods { get { if (MethodsStructure == null) { MethodsStructure = Marshal.PtrToStructure(MethodsPtr, typeof(FFIMethods)); } return (FFIMethods)MethodsStructure; } } public event ToggleHandler OnToggle; internal OverlayManager(IntPtr ptr, IntPtr eventsPtr, ref FFIEvents events) { if (eventsPtr == IntPtr.Zero) { throw new ResultException(Result.InternalError); } InitEvents(eventsPtr, ref events); MethodsPtr = ptr; if (MethodsPtr == IntPtr.Zero) { throw new ResultException(Result.InternalError); } } private void InitEvents(IntPtr eventsPtr, ref FFIEvents events) { events.OnToggle = OnToggleImpl; Marshal.StructureToPtr(events, eventsPtr, fDeleteOld: false); } public bool IsEnabled() { bool enabled = false; Methods.IsEnabled(MethodsPtr, ref enabled); return enabled; } public bool IsLocked() { bool locked = false; Methods.IsLocked(MethodsPtr, ref locked); return locked; } [MonoPInvokeCallback] private static void SetLockedCallbackImpl(IntPtr ptr, Result result) { GCHandle gCHandle = GCHandle.FromIntPtr(ptr); SetLockedHandler setLockedHandler = (SetLockedHandler)gCHandle.Target; gCHandle.Free(); setLockedHandler(result); } public void SetLocked(bool locked, SetLockedHandler callback) { GCHandle value = GCHandle.Alloc(callback); Methods.SetLocked(MethodsPtr, locked, GCHandle.ToIntPtr(value), SetLockedCallbackImpl); } [MonoPInvokeCallback] private static void OpenActivityInviteCallbackImpl(IntPtr ptr, Result result) { GCHandle gCHandle = GCHandle.FromIntPtr(ptr); OpenActivityInviteHandler openActivityInviteHandler = (OpenActivityInviteHandler)gCHandle.Target; gCHandle.Free(); openActivityInviteHandler(result); } public void OpenActivityInvite(ActivityActionType type, OpenActivityInviteHandler callback) { GCHandle value = GCHandle.Alloc(callback); Methods.OpenActivityInvite(MethodsPtr, type, GCHandle.ToIntPtr(value), OpenActivityInviteCallbackImpl); } [MonoPInvokeCallback] private static void OpenGuildInviteCallbackImpl(IntPtr ptr, Result result) { GCHandle gCHandle = GCHandle.FromIntPtr(ptr); OpenGuildInviteHandler openGuildInviteHandler = (OpenGuildInviteHandler)gCHandle.Target; gCHandle.Free(); openGuildInviteHandler(result); } public void OpenGuildInvite(string code, OpenGuildInviteHandler callback) { GCHandle value = GCHandle.Alloc(callback); Methods.OpenGuildInvite(MethodsPtr, code, GCHandle.ToIntPtr(value), OpenGuildInviteCallbackImpl); } [MonoPInvokeCallback] private static void OpenVoiceSettingsCallbackImpl(IntPtr ptr, Result result) { GCHandle gCHandle = GCHandle.FromIntPtr(ptr); OpenVoiceSettingsHandler openVoiceSettingsHandler = (OpenVoiceSettingsHandler)gCHandle.Target; gCHandle.Free(); openVoiceSettingsHandler(result); } public void OpenVoiceSettings(OpenVoiceSettingsHandler callback) { GCHandle value = GCHandle.Alloc(callback); Methods.OpenVoiceSettings(MethodsPtr, GCHandle.ToIntPtr(value), OpenVoiceSettingsCallbackImpl); } [MonoPInvokeCallback] private static void OnToggleImpl(IntPtr ptr, bool locked) { Discord discord = (Discord)GCHandle.FromIntPtr(ptr).Target; if (discord.OverlayManagerInstance.OnToggle != null) { discord.OverlayManagerInstance.OnToggle(locked); } } } public class StorageManager { internal struct FFIEvents { } internal struct FFIMethods { [UnmanagedFunctionPointer(CallingConvention.Cdecl)] internal delegate Result ReadMethod(IntPtr methodsPtr, [MarshalAs(UnmanagedType.LPStr)] string name, byte[] data, int dataLen, ref uint read); [UnmanagedFunctionPointer(CallingConvention.Cdecl)] internal delegate void ReadAsyncCallback(IntPtr ptr, Result result, IntPtr dataPtr, int dataLen); [UnmanagedFunctionPointer(CallingConvention.Cdecl)] internal delegate void ReadAsyncMethod(IntPtr methodsPtr, [MarshalAs(UnmanagedType.LPStr)] string name, IntPtr callbackData, ReadAsyncCallback callback); [UnmanagedFunctionPointer(CallingConvention.Cdecl)] internal delegate void ReadAsyncPartialCallback(IntPtr ptr, Result result, IntPtr dataPtr, int dataLen); [UnmanagedFunctionPointer(CallingConvention.Cdecl)] internal delegate void ReadAsyncPartialMethod(IntPtr methodsPtr, [MarshalAs(UnmanagedType.LPStr)] string name, ulong offset, ulong length, IntPtr callbackData, ReadAsyncPartialCallback callback); [UnmanagedFunctionPointer(CallingConvention.Cdecl)] internal delegate Result WriteMethod(IntPtr methodsPtr, [MarshalAs(UnmanagedType.LPStr)] string name, byte[] data, int dataLen); [UnmanagedFunctionPointer(CallingConvention.Cdecl)] internal delegate void WriteAsyncCallback(IntPtr ptr, Result result); [UnmanagedFunctionPointer(CallingConvention.Cdecl)] internal delegate void WriteAsyncMethod(IntPtr methodsPtr, [MarshalAs(UnmanagedType.LPStr)] string name, byte[] data, int dataLen, IntPtr callbackData, WriteAsyncCallback callback); [UnmanagedFunctionPointer(CallingConvention.Cdecl)] internal delegate Result DeleteMethod(IntPtr methodsPtr, [MarshalAs(UnmanagedType.LPStr)] string name); [UnmanagedFunctionPointer(CallingConvention.Cdecl)] internal delegate Result ExistsMethod(IntPtr methodsPtr, [MarshalAs(UnmanagedType.LPStr)] string name, ref bool exists); [UnmanagedFunctionPointer(CallingConvention.Cdecl)] internal delegate void CountMethod(IntPtr methodsPtr, ref int count); [UnmanagedFunctionPointer(CallingConvention.Cdecl)] internal delegate Result StatMethod(IntPtr methodsPtr, [MarshalAs(UnmanagedType.LPStr)] string name, ref FileStat stat); [UnmanagedFunctionPointer(CallingConvention.Cdecl)] internal delegate Result StatAtMethod(IntPtr methodsPtr, int index, ref FileStat stat); [UnmanagedFunctionPointer(CallingConvention.Cdecl)] internal delegate Result GetPathMethod(IntPtr methodsPtr, StringBuilder path); internal ReadMethod Read; internal ReadAsyncMethod ReadAsync; internal ReadAsyncPartialMethod ReadAsyncPartial; internal WriteMethod Write; internal WriteAsyncMethod WriteAsync; internal DeleteMethod Delete; internal ExistsMethod Exists; internal CountMethod Count; internal StatMethod Stat; internal StatAtMethod StatAt; internal GetPathMethod GetPath; } public delegate void ReadAsyncHandler(Result result, byte[] data); public delegate void ReadAsyncPartialHandler(Result result, byte[] data); public delegate void WriteAsyncHandler(Result result); private IntPtr MethodsPtr; private object MethodsStructure; private FFIMethods Methods { get { if (MethodsStructure == null) { MethodsStructure = Marshal.PtrToStructure(MethodsPtr, typeof(FFIMethods)); } return (FFIMethods)MethodsStructure; } } internal StorageManager(IntPtr ptr, IntPtr eventsPtr, ref FFIEvents events) { if (eventsPtr == IntPtr.Zero) { throw new ResultException(Result.InternalError); } InitEvents(eventsPtr, ref events); MethodsPtr = ptr; if (MethodsPtr == IntPtr.Zero) { throw new ResultException(Result.InternalErr