From 7b82ddc8077eb5dae616abb669dbdd500b6e9737 Mon Sep 17 00:00:00 2001 From: Retr0 <61121754+Retr0-01@users.noreply.github.com> Date: Tue, 11 Jan 2022 22:12:03 +0200 Subject: [PATCH] Init --- .editorconfig | 100 + .gitattributes | 196 ++ .gitignore | 398 +++ CSGO-Discord-RP.csproj | 22 + CSGO-Discord-RP.sln | 25 + DiscordGameSDK/ActivityManager.cs | 12 + DiscordGameSDK/Constants.cs | 9 + DiscordGameSDK/Core.cs | 4199 ++++++++++++++++++++++++++ DiscordGameSDK/ImageManager.cs | 53 + DiscordGameSDK/LobbyManager.cs | 26 + DiscordGameSDK/StorageManager.cs | 20 + DiscordGameSDK/StoreManager.cs | 32 + DiscordManager.cs | 37 + HttpServer.cs | 70 + Program.cs | 10 + favicon.ico | Bin 0 -> 110292 bytes gamestate_integration_discord-rp.cfg | 21 + 17 files changed, 5230 insertions(+) create mode 100644 .editorconfig create mode 100644 .gitattributes create mode 100644 .gitignore create mode 100644 CSGO-Discord-RP.csproj create mode 100644 CSGO-Discord-RP.sln create mode 100644 DiscordGameSDK/ActivityManager.cs create mode 100644 DiscordGameSDK/Constants.cs create mode 100644 DiscordGameSDK/Core.cs create mode 100644 DiscordGameSDK/ImageManager.cs create mode 100644 DiscordGameSDK/LobbyManager.cs create mode 100644 DiscordGameSDK/StorageManager.cs create mode 100644 DiscordGameSDK/StoreManager.cs create mode 100644 DiscordManager.cs create mode 100644 HttpServer.cs create mode 100644 Program.cs create mode 100644 favicon.ico create mode 100644 gamestate_integration_discord-rp.cfg diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 0000000..fb22870 --- /dev/null +++ b/.editorconfig @@ -0,0 +1,100 @@ +# Remove the line below if you want to inherit .editorconfig settings from higher directories +root = true + +# C# files +[*.cs] +indent_style = tab +indent_size = tab +tab_size = 4 + +# New line preferences +end_of_line = crlf +insert_final_newline = true + + +#### C# Coding Conventions #### + +# Expression-bodied members +csharp_style_expression_bodied_accessors = true:silent +csharp_style_expression_bodied_constructors = false:silent +csharp_style_expression_bodied_indexers = true:silent +csharp_style_expression_bodied_lambdas = true:silent +csharp_style_expression_bodied_local_functions = false:silent +csharp_style_expression_bodied_methods = false:silent +csharp_style_expression_bodied_operators = false:silent +csharp_style_expression_bodied_properties = true:silent + +# Pattern matching preferences +csharp_style_pattern_matching_over_as_with_null_check = true:suggestion +csharp_style_pattern_matching_over_is_with_cast_check = true:suggestion +csharp_style_prefer_not_pattern = true:suggestion +csharp_style_prefer_pattern_matching = true:silent +csharp_style_prefer_switch_expression = true:suggestion + +# Null-checking preferences +csharp_style_conditional_delegate_call = true:suggestion + +# Code-block preferences +csharp_prefer_braces = true:silent + +# Expression-level preferences +csharp_prefer_simple_default_expression = true:suggestion +csharp_style_deconstructed_variable_declaration = true:suggestion +csharp_style_implicit_object_creation_when_type_is_apparent = true:suggestion +csharp_style_inlined_variable_declaration = true:suggestion +csharp_style_pattern_local_over_anonymous_function = true:suggestion +csharp_style_prefer_index_operator = true:suggestion +csharp_style_prefer_range_operator = true:suggestion +csharp_style_throw_expression = true:suggestion +csharp_style_unused_value_assignment_preference = discard_variable:suggestion +csharp_style_unused_value_expression_statement_preference = discard_variable:silent + +# 'using' directive preferences +csharp_using_directive_placement = outside_namespace:silent + +#### C# Formatting Rules #### + +# New line preferences +csharp_new_line_before_catch = true +csharp_new_line_before_else = true +csharp_new_line_before_finally = true +csharp_new_line_before_members_in_anonymous_types = true +csharp_new_line_before_members_in_object_initializers = true +csharp_new_line_before_open_brace = all +csharp_new_line_between_query_expression_clauses = true + +# Indentation preferences +csharp_indent_block_contents = true +csharp_indent_braces = false +csharp_indent_case_contents = true +csharp_indent_case_contents_when_block = true +csharp_indent_labels = no_change +csharp_indent_switch_labels = true + +# Space preferences +csharp_space_after_cast = false +csharp_space_after_colon_in_inheritance_clause = true +csharp_space_after_comma = true +csharp_space_after_dot = false +csharp_space_after_keywords_in_control_flow_statements = true +csharp_space_after_semicolon_in_for_statement = true +csharp_space_around_binary_operators = before_and_after +csharp_space_around_declaration_statements = false +csharp_space_before_colon_in_inheritance_clause = true +csharp_space_before_comma = false +csharp_space_before_dot = false +csharp_space_before_open_square_brackets = false +csharp_space_before_semicolon_in_for_statement = false +csharp_space_between_empty_square_brackets = false +csharp_space_between_method_call_empty_parameter_list_parentheses = false +csharp_space_between_method_call_name_and_opening_parenthesis = false +csharp_space_between_method_call_parameter_list_parentheses = true +csharp_space_between_method_declaration_empty_parameter_list_parentheses = false +csharp_space_between_method_declaration_name_and_open_parenthesis = false +csharp_space_between_method_declaration_parameter_list_parentheses = true +csharp_space_between_parentheses = control_flow_statements +csharp_space_between_square_brackets = false + +# Wrapping preferences +csharp_preserve_single_line_blocks = true +csharp_preserve_single_line_statements = true \ No newline at end of file diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000..b7f8b8f --- /dev/null +++ b/.gitattributes @@ -0,0 +1,196 @@ +* text=auto + +###### Git +.gitattributes text +.gitignore text +.gitconfig text +.gitmodules text + +##### Windows +*.bat text eol=crlf +*.exe binary +*.dll binary + +##### Linux +*.sh text eol=lf +*.so binary + +##### Global +# Documents +*.sql text +*.md text +*.adoc text +*.textile text +*.mustache text +*.csv text +*.tab text +*.tsv text +*.coffee text +*.css text +*.htm text +*.html text +*.xhtml text +*.inc text +*.js text +*.jsx text +*.less text +*.od text +*.onlydata text +*.sass text +*.scm text +*.log text +*.properties text +*.scss text +*.styl text +*.tag text +*.ts text +*.tsx text +*.dockerignore text +Dockerfile text +*.markdown text +*.mdwn text +*.mdown text +*.mkd text +*.mkdn text +*.mdtxt text +*.mdtext text +*.txt text +AUTHORS text +CHANGELOG text +CHANGES text +CONTRIBUTING text +COPYING text +copyright text +*COPYRIGHT* text +INSTALL text +license text +LICENSE text +NEWS text +readme text +*README* text +TODO text +# Configuration +*.cnf text +*.cfg text +*.conf text +*.config text +*.ini text +*.json text +*.xml text +*.bowerrc text +.browserslistrc text +.editorconfig text +*.npmignore text +*.yaml text +*.yml text +browserslist text +Makefile text +makefile text +Procfile text +.slugignore text +# Linters +.csslintrc text +.eslintrc text +.htmlhintrc text +.jscsrc text +.jshintrc text +.jshintignore text +.stylelintrc text +# Video +*.3gpp binary +*.3gp binary +*.as binary +*.asf binary +*.asx binary +*.fla binary +*.flv binary +*.m4v binary +*.mng binary +*.mov binary +*.mp4 binary +*.mpeg binary +*.mpg binary +*.ogv binary +*.swc binary +*.swf binary +*.webm binary +# Audio +*.kar binary +*.m4a binary +*.mid binary +*.midi binary +*.mp3 binary +*.ogg binary +*.ra binary +# Graphics +*.png binary +*.jpg binary +*.jpeg binary +*.gif binary +*.tif binary +*.tiff binary +*.ico binary +*.eps binary +*.ai binary +*.bmp binary +*.jng binary +*.jp2 binary +*.jpx binary +*.jxr binary +*.pdf binary +*.psb binary +*.psd binary +*.svg text +*.svgz binary +*.wbmp binary +*.webp binary +# Archives +*.7z binary +*.gz binary +*.jar binary +*.rar binary +*.tar binary +*.zip binary +# Fonts +*.ttf binary +*.eot binary +*.otf binary +*.woff binary +*.woff2 binary +# Executables +*.pyc binary +# Objects +*.o binary + +##### IDE/Editor +# Visual Studio +*.sln text eol=crlf +*.csproj text eol=crlf +*.vbproj text eol=crlf +*.vcxproj text eol=crlf +*.vcproj text eol=crlf +*.dbproj text eol=crlf +*.fsproj text eol=crlf +*.lsproj text eol=crlf +*.wixproj text eol=crlf +*.modelproj text eol=crlf +*.sqlproj text eol=crlf +*.wmaproj text eol=crlf +*.xproj text eol=crlf +*.props text eol=crlf +*.filters text eol=crlf +*.vcxitems text eol=crlf +# Eclipse +*.project text +*.classpath text +*.prefs + +##### Language +# .Net +*.resx text +*.settings text +*.cs text +*.vb text +*.cpp text +*.h text +*.fs text diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..426d76d --- /dev/null +++ b/.gitignore @@ -0,0 +1,398 @@ +## Ignore Visual Studio temporary files, build results, and +## files generated by popular Visual Studio add-ons. +## +## Get latest from https://github.com/github/gitignore/blob/main/VisualStudio.gitignore + +# User-specific files +*.rsuser +*.suo +*.user +*.userosscache +*.sln.docstates + +# User-specific files (MonoDevelop/Xamarin Studio) +*.userprefs + +# Mono auto generated files +mono_crash.* + +# Build results +[Dd]ebug/ +[Dd]ebugPublic/ +[Rr]elease/ +[Rr]eleases/ +x64/ +x86/ +[Ww][Ii][Nn]32/ +[Aa][Rr][Mm]/ +[Aa][Rr][Mm]64/ +bld/ +[Bb]in/ +[Oo]bj/ +[Ll]og/ +[Ll]ogs/ + +# Visual Studio 2015/2017 cache/options directory +.vs/ +# Uncomment if you have tasks that create the project's static files in wwwroot +#wwwroot/ + +# Visual Studio 2017 auto generated files +Generated\ Files/ + +# MSTest test Results +[Tt]est[Rr]esult*/ +[Bb]uild[Ll]og.* + +# NUnit +*.VisualState.xml +TestResult.xml +nunit-*.xml + +# Build Results of an ATL Project +[Dd]ebugPS/ +[Rr]eleasePS/ +dlldata.c + +# Benchmark Results +BenchmarkDotNet.Artifacts/ + +# .NET Core +project.lock.json +project.fragment.lock.json +artifacts/ + +# ASP.NET Scaffolding +ScaffoldingReadMe.txt + +# StyleCop +StyleCopReport.xml + +# Files built by Visual Studio +*_i.c +*_p.c +*_h.h +*.ilk +*.meta +*.obj +*.iobj +*.pch +*.pdb +*.ipdb +*.pgc +*.pgd +*.rsp +*.sbr +*.tlb +*.tli +*.tlh +*.tmp +*.tmp_proj +*_wpftmp.csproj +*.log +*.tlog +*.vspscc +*.vssscc +.builds +*.pidb +*.svclog +*.scc + +# Chutzpah Test files +_Chutzpah* + +# Visual C++ cache files +ipch/ +*.aps +*.ncb +*.opendb +*.opensdf +*.sdf +*.cachefile +*.VC.db +*.VC.VC.opendb + +# Visual Studio profiler +*.psess +*.vsp +*.vspx +*.sap + +# Visual Studio Trace Files +*.e2e + +# TFS 2012 Local Workspace +$tf/ + +# Guidance Automation Toolkit +*.gpState + +# ReSharper is a .NET coding add-in +_ReSharper*/ +*.[Rr]e[Ss]harper +*.DotSettings.user + +# TeamCity is a build add-in +_TeamCity* + +# DotCover is a Code Coverage Tool +*.dotCover + +# AxoCover is a Code Coverage Tool +.axoCover/* +!.axoCover/settings.json + +# Coverlet is a free, cross platform Code Coverage Tool +coverage*.json +coverage*.xml +coverage*.info + +# Visual Studio code coverage results +*.coverage +*.coveragexml + +# NCrunch +_NCrunch_* +.*crunch*.local.xml +nCrunchTemp_* + +# MightyMoose +*.mm.* +AutoTest.Net/ + +# Web workbench (sass) +.sass-cache/ + +# Installshield output folder +[Ee]xpress/ + +# DocProject is a documentation generator add-in +DocProject/buildhelp/ +DocProject/Help/*.HxT +DocProject/Help/*.HxC +DocProject/Help/*.hhc +DocProject/Help/*.hhk +DocProject/Help/*.hhp +DocProject/Help/Html2 +DocProject/Help/html + +# Click-Once directory +publish/ + +# Publish Web Output +*.[Pp]ublish.xml +*.azurePubxml +# Note: Comment the next line if you want to checkin your web deploy settings, +# but database connection strings (with potential passwords) will be unencrypted +*.pubxml +*.publishproj + +# Microsoft Azure Web App publish settings. Comment the next line if you want to +# checkin your Azure Web App publish settings, but sensitive information contained +# in these scripts will be unencrypted +PublishScripts/ + +# NuGet Packages +*.nupkg +# NuGet Symbol Packages +*.snupkg +# The packages folder can be ignored because of Package Restore +**/[Pp]ackages/* +# except build/, which is used as an MSBuild target. +!**/[Pp]ackages/build/ +# Uncomment if necessary however generally it will be regenerated when needed +#!**/[Pp]ackages/repositories.config +# NuGet v3's project.json files produces more ignorable files +*.nuget.props +*.nuget.targets + +# Microsoft Azure Build Output +csx/ +*.build.csdef + +# Microsoft Azure Emulator +ecf/ +rcf/ + +# Windows Store app package directories and files +AppPackages/ +BundleArtifacts/ +Package.StoreAssociation.xml +_pkginfo.txt +*.appx +*.appxbundle +*.appxupload + +# Visual Studio cache files +# files ending in .cache can be ignored +*.[Cc]ache +# but keep track of directories ending in .cache +!?*.[Cc]ache/ + +# Others +ClientBin/ +~$* +*~ +*.dbmdl +*.dbproj.schemaview +*.jfm +*.pfx +*.publishsettings +orleans.codegen.cs + +# Including strong name files can present a security risk +# (https://github.com/github/gitignore/pull/2483#issue-259490424) +#*.snk + +# Since there are multiple workflows, uncomment next line to ignore bower_components +# (https://github.com/github/gitignore/pull/1529#issuecomment-104372622) +#bower_components/ + +# RIA/Silverlight projects +Generated_Code/ + +# Backup & report files from converting an old project file +# to a newer Visual Studio version. Backup files are not needed, +# because we have git ;-) +_UpgradeReport_Files/ +Backup*/ +UpgradeLog*.XML +UpgradeLog*.htm +ServiceFabricBackup/ +*.rptproj.bak + +# SQL Server files +*.mdf +*.ldf +*.ndf + +# Business Intelligence projects +*.rdl.data +*.bim.layout +*.bim_*.settings +*.rptproj.rsuser +*- [Bb]ackup.rdl +*- [Bb]ackup ([0-9]).rdl +*- [Bb]ackup ([0-9][0-9]).rdl + +# Microsoft Fakes +FakesAssemblies/ + +# GhostDoc plugin setting file +*.GhostDoc.xml + +# Node.js Tools for Visual Studio +.ntvs_analysis.dat +node_modules/ + +# Visual Studio 6 build log +*.plg + +# Visual Studio 6 workspace options file +*.opt + +# Visual Studio 6 auto-generated workspace file (contains which files were open etc.) +*.vbw + +# Visual Studio 6 auto-generated project file (contains which files were open etc.) +*.vbp + +# Visual Studio 6 workspace and project file (working project files containing files to include in project) +*.dsw +*.dsp + +# Visual Studio 6 technical files +*.ncb +*.aps + +# Visual Studio LightSwitch build output +**/*.HTMLClient/GeneratedArtifacts +**/*.DesktopClient/GeneratedArtifacts +**/*.DesktopClient/ModelManifest.xml +**/*.Server/GeneratedArtifacts +**/*.Server/ModelManifest.xml +_Pvt_Extensions + +# Paket dependency manager +.paket/paket.exe +paket-files/ + +# FAKE - F# Make +.fake/ + +# CodeRush personal settings +.cr/personal + +# Python Tools for Visual Studio (PTVS) +__pycache__/ +*.pyc + +# Cake - Uncomment if you are using it +# tools/** +# !tools/packages.config + +# Tabs Studio +*.tss + +# Telerik's JustMock configuration file +*.jmconfig + +# BizTalk build output +*.btp.cs +*.btm.cs +*.odx.cs +*.xsd.cs + +# OpenCover UI analysis results +OpenCover/ + +# Azure Stream Analytics local run output +ASALocalRun/ + +# MSBuild Binary and Structured Log +*.binlog + +# NVidia Nsight GPU debugger configuration file +*.nvuser + +# MFractors (Xamarin productivity tool) working folder +.mfractor/ + +# Local History for Visual Studio +.localhistory/ + +# Visual Studio History (VSHistory) files +.vshistory/ + +# BeatPulse healthcheck temp database +healthchecksdb + +# Backup folder for Package Reference Convert tool in Visual Studio 2017 +MigrationBackup/ + +# Ionide (cross platform F# VS Code tools) working folder +.ionide/ + +# Fody - auto-generated XML schema +FodyWeavers.xsd + +# VS Code files for those working on multiple tools +.vscode/* +!.vscode/settings.json +!.vscode/tasks.json +!.vscode/launch.json +!.vscode/extensions.json +*.code-workspace + +# Local History for Visual Studio Code +.history/ + +# Windows Installer files from build outputs +*.cab +*.msi +*.msix +*.msm +*.msp + +# JetBrains Rider +*.sln.iml diff --git a/CSGO-Discord-RP.csproj b/CSGO-Discord-RP.csproj new file mode 100644 index 0000000..1a05293 --- /dev/null +++ b/CSGO-Discord-RP.csproj @@ -0,0 +1,22 @@ + + + + Exe + net6.0 + CSGO_Discord_RP + enable + annotations + False + favicon.ico + portable + + + + + + + + + + + diff --git a/CSGO-Discord-RP.sln b/CSGO-Discord-RP.sln new file mode 100644 index 0000000..af9180c --- /dev/null +++ b/CSGO-Discord-RP.sln @@ -0,0 +1,25 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 17 +VisualStudioVersion = 17.0.32014.148 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CSGO-Discord-RP", "CSGO-Discord-RP.csproj", "{3A8BB5BD-AD13-4221-A708-6F3611C232AA}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {3A8BB5BD-AD13-4221-A708-6F3611C232AA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {3A8BB5BD-AD13-4221-A708-6F3611C232AA}.Debug|Any CPU.Build.0 = Debug|Any CPU + {3A8BB5BD-AD13-4221-A708-6F3611C232AA}.Release|Any CPU.ActiveCfg = Release|Any CPU + {3A8BB5BD-AD13-4221-A708-6F3611C232AA}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {877A3C2D-82EE-470A-A119-458FAEC8943A} + EndGlobalSection +EndGlobal diff --git a/DiscordGameSDK/ActivityManager.cs b/DiscordGameSDK/ActivityManager.cs new file mode 100644 index 0000000..048e3b4 --- /dev/null +++ b/DiscordGameSDK/ActivityManager.cs @@ -0,0 +1,12 @@ +using System; + +namespace Discord +{ + public partial class ActivityManager + { + public void RegisterCommand() + { + RegisterCommand(null); + } + } +} diff --git a/DiscordGameSDK/Constants.cs b/DiscordGameSDK/Constants.cs new file mode 100644 index 0000000..8e77e1b --- /dev/null +++ b/DiscordGameSDK/Constants.cs @@ -0,0 +1,9 @@ +using System; + +namespace Discord +{ + static class Constants + { + public const string DllName = "discord_game_sdk"; + } +} diff --git a/DiscordGameSDK/Core.cs b/DiscordGameSDK/Core.cs new file mode 100644 index 0000000..fa95765 --- /dev/null +++ b/DiscordGameSDK/Core.cs @@ -0,0 +1,4199 @@ +using System; +using System.Runtime.InteropServices; +using System.Text; + +namespace Discord +{ + public enum Result + { + Ok = 0, + ServiceUnavailable = 1, + InvalidVersion = 2, + LockFailed = 3, + InternalError = 4, + InvalidPayload = 5, + InvalidCommand = 6, + InvalidPermissions = 7, + NotFetched = 8, + NotFound = 9, + Conflict = 10, + InvalidSecret = 11, + InvalidJoinSecret = 12, + NoEligibleActivity = 13, + InvalidInvite = 14, + NotAuthenticated = 15, + InvalidAccessToken = 16, + ApplicationMismatch = 17, + InvalidDataUrl = 18, + InvalidBase64 = 19, + NotFiltered = 20, + LobbyFull = 21, + InvalidLobbySecret = 22, + InvalidFilename = 23, + InvalidFileSize = 24, + InvalidEntitlement = 25, + NotInstalled = 26, + NotRunning = 27, + InsufficientBuffer = 28, + PurchaseCanceled = 29, + InvalidGuild = 30, + InvalidEvent = 31, + InvalidChannel = 32, + InvalidOrigin = 33, + RateLimited = 34, + OAuth2Error = 35, + SelectChannelTimeout = 36, + GetGuildTimeout = 37, + SelectVoiceForceRequired = 38, + CaptureShortcutAlreadyListening = 39, + UnauthorizedForAchievement = 40, + InvalidGiftCode = 41, + PurchaseError = 42, + TransactionAborted = 43, + } + + public enum CreateFlags + { + Default = 0, + NoRequireDiscord = 1, + } + + public enum LogLevel + { + Error = 1, + Warn, + Info, + Debug, + } + + public enum UserFlag + { + Partner = 2, + HypeSquadEvents = 4, + HypeSquadHouse1 = 64, + HypeSquadHouse2 = 128, + HypeSquadHouse3 = 256, + } + + public enum PremiumType + { + None = 0, + Tier1 = 1, + Tier2 = 2, + } + + 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 = 0, + Online = 1, + Idle = 2, + DoNotDisturb = 3, + } + + 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 = 0, + PushToTalk, + } + + [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)] + public partial struct User + { + public Int64 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; + } + + [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)] + public partial struct OAuth2Token + { + [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 128)] + public string AccessToken; + + [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 1024)] + public string Scopes; + + public Int64 Expires; + } + + [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)] + public partial struct ImageHandle + { + public ImageType Type; + + public Int64 Id; + + public UInt32 Size; + } + + [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)] + public partial struct ImageDimensions + { + public UInt32 Width; + + public UInt32 Height; + } + + [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)] + public partial struct ActivityTimestamps + { + public Int64 Start; + + public Int64 End; + } + + [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)] + public partial 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; + } + + [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)] + public partial struct PartySize + { + public Int32 CurrentSize; + + public Int32 MaxSize; + } + + [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)] + public partial struct ActivityParty + { + [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 128)] + public string Id; + + public PartySize Size; + } + + [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)] + public partial 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; + } + + [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)] + public partial struct Activity + { + public ActivityType Type; + + public Int64 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; + } + + [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)] + public partial struct Presence + { + public Status Status; + + public Activity Activity; + } + + [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)] + public partial struct Relationship + { + public RelationshipType Type; + + public User User; + + public Presence Presence; + } + + [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)] + public partial struct Lobby + { + public Int64 Id; + + public LobbyType Type; + + public Int64 OwnerId; + + [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 128)] + public string Secret; + + public UInt32 Capacity; + + public bool Locked; + } + + [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)] + public partial struct FileStat + { + [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 260)] + public string Filename; + + public UInt64 Size; + + public UInt64 LastModified; + } + + [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)] + public partial struct Entitlement + { + public Int64 Id; + + public EntitlementType Type; + + public Int64 SkuId; + } + + [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)] + public partial struct SkuPrice + { + public UInt32 Amount; + + [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 16)] + public string Currency; + } + + [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)] + public partial struct Sku + { + public Int64 Id; + + public SkuType Type; + + [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 256)] + public string Name; + + public SkuPrice Price; + } + + [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)] + public partial struct InputMode + { + public InputModeType Type; + + [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 256)] + public string Shortcut; + } + + [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)] + public partial struct UserAchievement + { + public Int64 UserId; + + public Int64 AchievementId; + + public byte PercentComplete; + + [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 64)] + public string UnlockedAt; + } + + [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)] + public partial struct LobbyTransaction + { + [StructLayout(LayoutKind.Sequential)] + internal partial struct FFIMethods + { + [UnmanagedFunctionPointer(CallingConvention.Cdecl)] + internal delegate Result SetTypeMethod(IntPtr methodsPtr, LobbyType type); + + [UnmanagedFunctionPointer(CallingConvention.Cdecl)] + internal delegate Result SetOwnerMethod(IntPtr methodsPtr, Int64 ownerId); + + [UnmanagedFunctionPointer(CallingConvention.Cdecl)] + internal delegate Result SetCapacityMethod(IntPtr methodsPtr, UInt32 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) + { + var res = Methods.SetType(MethodsPtr, type); + if (res != Result.Ok) + { + throw new ResultException(res); + } + } + } + + public void SetOwner(Int64 ownerId) + { + if (MethodsPtr != IntPtr.Zero) + { + var res = Methods.SetOwner(MethodsPtr, ownerId); + if (res != Result.Ok) + { + throw new ResultException(res); + } + } + } + + public void SetCapacity(UInt32 capacity) + { + if (MethodsPtr != IntPtr.Zero) + { + var res = Methods.SetCapacity(MethodsPtr, capacity); + if (res != Result.Ok) + { + throw new ResultException(res); + } + } + } + + public void SetMetadata(string key, string value) + { + if (MethodsPtr != IntPtr.Zero) + { + var res = Methods.SetMetadata(MethodsPtr, key, value); + if (res != Result.Ok) + { + throw new ResultException(res); + } + } + } + + public void DeleteMetadata(string key) + { + if (MethodsPtr != IntPtr.Zero) + { + var res = Methods.DeleteMetadata(MethodsPtr, key); + if (res != Result.Ok) + { + throw new ResultException(res); + } + } + } + + public void SetLocked(bool locked) + { + if (MethodsPtr != IntPtr.Zero) + { + var res = Methods.SetLocked(MethodsPtr, locked); + if (res != Result.Ok) + { + throw new ResultException(res); + } + } + } + } + + [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)] + public partial struct LobbyMemberTransaction + { + [StructLayout(LayoutKind.Sequential)] + internal partial 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) + { + var res = Methods.SetMetadata(MethodsPtr, key, value); + if (res != Result.Ok) + { + throw new ResultException(res); + } + } + } + + public void DeleteMetadata(string key) + { + if (MethodsPtr != IntPtr.Zero) + { + var res = Methods.DeleteMetadata(MethodsPtr, key); + if (res != Result.Ok) + { + throw new ResultException(res); + } + } + } + } + + [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)] + public partial struct LobbySearchQuery + { + [StructLayout(LayoutKind.Sequential)] + internal partial 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, UInt32 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) + { + var res = Methods.Filter(MethodsPtr, key, comparison, cast, value); + if (res != Result.Ok) + { + throw new ResultException(res); + } + } + } + + public void Sort(string key, LobbySearchCast cast, string value) + { + if (MethodsPtr != IntPtr.Zero) + { + var res = Methods.Sort(MethodsPtr, key, cast, value); + if (res != Result.Ok) + { + throw new ResultException(res); + } + } + } + + public void Limit(UInt32 limit) + { + if (MethodsPtr != IntPtr.Zero) + { + var res = Methods.Limit(MethodsPtr, limit); + if (res != Result.Ok) + { + throw new ResultException(res); + } + } + } + + public void Distance(LobbySearchDistance distance) + { + if (MethodsPtr != IntPtr.Zero) + { + var res = Methods.Distance(MethodsPtr, distance); + if (res != Result.Ok) + { + throw new ResultException(res); + } + } + } + } + + public partial class ResultException : Exception + { + public readonly Result Result; + + public ResultException(Result result) : base(result.ToString()) + { + } + } + + public partial class Discord : IDisposable + { + [StructLayout(LayoutKind.Sequential)] + internal partial struct FFIEvents + { + + } + + [StructLayout(LayoutKind.Sequential)] + internal partial 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; + } + + [StructLayout(LayoutKind.Sequential)] + internal partial struct FFICreateParams + { + internal Int64 ClientId; + + internal UInt64 Flags; + + internal IntPtr Events; + + internal IntPtr EventData; + + internal IntPtr ApplicationEvents; + + internal UInt32 ApplicationVersion; + + internal IntPtr UserEvents; + + internal UInt32 UserVersion; + + internal IntPtr ImageEvents; + + internal UInt32 ImageVersion; + + internal IntPtr ActivityEvents; + + internal UInt32 ActivityVersion; + + internal IntPtr RelationshipEvents; + + internal UInt32 RelationshipVersion; + + internal IntPtr LobbyEvents; + + internal UInt32 LobbyVersion; + + internal IntPtr NetworkEvents; + + internal UInt32 NetworkVersion; + + internal IntPtr OverlayEvents; + + internal UInt32 OverlayVersion; + + internal IntPtr StorageEvents; + + internal UInt32 StorageVersion; + + internal IntPtr StoreEvents; + + internal UInt32 StoreVersion; + + internal IntPtr VoiceEvents; + + internal UInt32 VoiceVersion; + + internal IntPtr AchievementEvents; + + internal UInt32 AchievementVersion; + } + + [DllImport(Constants.DllName, ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)] + private static extern Result DiscordCreate(UInt32 version, ref FFICreateParams createParams, out IntPtr manager); + + 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 FFIMethods Methods + { + get + { + if (MethodsStructure == null) + { + MethodsStructure = Marshal.PtrToStructure(MethodsPtr, typeof(FFIMethods)); + } + return (FFIMethods)MethodsStructure; + } + + } + + private GCHandle? setLogHook; + + public Discord(Int64 clientId, UInt64 flags) + { + FFICreateParams createParams; + createParams.ClientId = clientId; + createParams.Flags = flags; + Events = new FFIEvents(); + EventsPtr = Marshal.AllocHGlobal(Marshal.SizeOf(Events)); + createParams.Events = EventsPtr; + SelfHandle = GCHandle.Alloc(this); + createParams.EventData = GCHandle.ToIntPtr(SelfHandle); + ApplicationEvents = new ApplicationManager.FFIEvents(); + ApplicationEventsPtr = Marshal.AllocHGlobal(Marshal.SizeOf(ApplicationEvents)); + createParams.ApplicationEvents = ApplicationEventsPtr; + createParams.ApplicationVersion = 1; + UserEvents = new UserManager.FFIEvents(); + UserEventsPtr = Marshal.AllocHGlobal(Marshal.SizeOf(UserEvents)); + createParams.UserEvents = UserEventsPtr; + createParams.UserVersion = 1; + ImageEvents = new ImageManager.FFIEvents(); + ImageEventsPtr = Marshal.AllocHGlobal(Marshal.SizeOf(ImageEvents)); + createParams.ImageEvents = ImageEventsPtr; + createParams.ImageVersion = 1; + ActivityEvents = new ActivityManager.FFIEvents(); + ActivityEventsPtr = Marshal.AllocHGlobal(Marshal.SizeOf(ActivityEvents)); + createParams.ActivityEvents = ActivityEventsPtr; + createParams.ActivityVersion = 1; + RelationshipEvents = new RelationshipManager.FFIEvents(); + RelationshipEventsPtr = Marshal.AllocHGlobal(Marshal.SizeOf(RelationshipEvents)); + createParams.RelationshipEvents = RelationshipEventsPtr; + createParams.RelationshipVersion = 1; + LobbyEvents = new LobbyManager.FFIEvents(); + LobbyEventsPtr = Marshal.AllocHGlobal(Marshal.SizeOf(LobbyEvents)); + createParams.LobbyEvents = LobbyEventsPtr; + createParams.LobbyVersion = 1; + NetworkEvents = new NetworkManager.FFIEvents(); + NetworkEventsPtr = Marshal.AllocHGlobal(Marshal.SizeOf(NetworkEvents)); + createParams.NetworkEvents = NetworkEventsPtr; + createParams.NetworkVersion = 1; + OverlayEvents = new OverlayManager.FFIEvents(); + OverlayEventsPtr = Marshal.AllocHGlobal(Marshal.SizeOf(OverlayEvents)); + createParams.OverlayEvents = OverlayEventsPtr; + createParams.OverlayVersion = 1; + StorageEvents = new StorageManager.FFIEvents(); + StorageEventsPtr = Marshal.AllocHGlobal(Marshal.SizeOf(StorageEvents)); + createParams.StorageEvents = StorageEventsPtr; + createParams.StorageVersion = 1; + StoreEvents = new StoreManager.FFIEvents(); + StoreEventsPtr = Marshal.AllocHGlobal(Marshal.SizeOf(StoreEvents)); + createParams.StoreEvents = StoreEventsPtr; + createParams.StoreVersion = 1; + VoiceEvents = new VoiceManager.FFIEvents(); + VoiceEventsPtr = Marshal.AllocHGlobal(Marshal.SizeOf(VoiceEvents)); + createParams.VoiceEvents = VoiceEventsPtr; + createParams.VoiceVersion = 1; + AchievementEvents = new AchievementManager.FFIEvents(); + AchievementEventsPtr = Marshal.AllocHGlobal(Marshal.SizeOf(AchievementEvents)); + createParams.AchievementEvents = AchievementEventsPtr; + createParams.AchievementVersion = 1; + InitEvents(EventsPtr, ref Events); + var result = DiscordCreate(2, ref createParams, out MethodsPtr); + if (result != Result.Ok) + { + Dispose(); + throw new ResultException(result); + } + } + + private void InitEvents(IntPtr eventsPtr, ref FFIEvents events) + { + Marshal.StructureToPtr(events, eventsPtr, 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() + { + var res = Methods.RunCallbacks(MethodsPtr); + if (res != Result.Ok) + { + throw new ResultException(res); + } + } + + [MonoPInvokeCallback] + private static void SetLogHookCallbackImpl(IntPtr ptr, LogLevel level, string message) + { + GCHandle h = GCHandle.FromIntPtr(ptr); + SetLogHookHandler callback = (SetLogHookHandler)h.Target; + callback(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 partial class MonoPInvokeCallbackAttribute : Attribute + { + + } + + public partial class ApplicationManager + { + [StructLayout(LayoutKind.Sequential)] + internal partial struct FFIEvents + { + + } + + [StructLayout(LayoutKind.Sequential)] + internal partial 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, false); + } + + [MonoPInvokeCallback] + private static void ValidateOrExitCallbackImpl(IntPtr ptr, Result result) + { + GCHandle h = GCHandle.FromIntPtr(ptr); + ValidateOrExitHandler callback = (ValidateOrExitHandler)h.Target; + h.Free(); + callback(result); + } + + public void ValidateOrExit(ValidateOrExitHandler callback) + { + GCHandle wrapped = GCHandle.Alloc(callback); + Methods.ValidateOrExit(MethodsPtr, GCHandle.ToIntPtr(wrapped), ValidateOrExitCallbackImpl); + } + + public string GetCurrentLocale() + { + var ret = new StringBuilder(128); + Methods.GetCurrentLocale(MethodsPtr, ret); + return ret.ToString(); + } + + public string GetCurrentBranch() + { + var ret = new StringBuilder(4096); + Methods.GetCurrentBranch(MethodsPtr, ret); + return ret.ToString(); + } + + [MonoPInvokeCallback] + private static void GetOAuth2TokenCallbackImpl(IntPtr ptr, Result result, ref OAuth2Token oauth2Token) + { + GCHandle h = GCHandle.FromIntPtr(ptr); + GetOAuth2TokenHandler callback = (GetOAuth2TokenHandler)h.Target; + h.Free(); + callback(result, ref oauth2Token); + } + + public void GetOAuth2Token(GetOAuth2TokenHandler callback) + { + GCHandle wrapped = GCHandle.Alloc(callback); + Methods.GetOAuth2Token(MethodsPtr, GCHandle.ToIntPtr(wrapped), GetOAuth2TokenCallbackImpl); + } + + [MonoPInvokeCallback] + private static void GetTicketCallbackImpl(IntPtr ptr, Result result, ref string data) + { + GCHandle h = GCHandle.FromIntPtr(ptr); + GetTicketHandler callback = (GetTicketHandler)h.Target; + h.Free(); + callback(result, ref data); + } + + public void GetTicket(GetTicketHandler callback) + { + GCHandle wrapped = GCHandle.Alloc(callback); + Methods.GetTicket(MethodsPtr, GCHandle.ToIntPtr(wrapped), GetTicketCallbackImpl); + } + } + + public partial class UserManager + { + [StructLayout(LayoutKind.Sequential)] + internal partial struct FFIEvents + { + [UnmanagedFunctionPointer(CallingConvention.Cdecl)] + internal delegate void CurrentUserUpdateHandler(IntPtr ptr); + + internal CurrentUserUpdateHandler OnCurrentUserUpdate; + } + + [StructLayout(LayoutKind.Sequential)] + internal partial 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, Int64 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, false); + } + + public User GetCurrentUser() + { + var ret = new User(); + var res = Methods.GetCurrentUser(MethodsPtr, ref ret); + if (res != Result.Ok) + { + throw new ResultException(res); + } + return ret; + } + + [MonoPInvokeCallback] + private static void GetUserCallbackImpl(IntPtr ptr, Result result, ref User user) + { + GCHandle h = GCHandle.FromIntPtr(ptr); + GetUserHandler callback = (GetUserHandler)h.Target; + h.Free(); + callback(result, ref user); + } + + public void GetUser(Int64 userId, GetUserHandler callback) + { + GCHandle wrapped = GCHandle.Alloc(callback); + Methods.GetUser(MethodsPtr, userId, GCHandle.ToIntPtr(wrapped), GetUserCallbackImpl); + } + + public PremiumType GetCurrentUserPremiumType() + { + var ret = new PremiumType(); + var res = Methods.GetCurrentUserPremiumType(MethodsPtr, ref ret); + if (res != Result.Ok) + { + throw new ResultException(res); + } + return ret; + } + + public bool CurrentUserHasFlag(UserFlag flag) + { + var ret = new bool(); + var res = Methods.CurrentUserHasFlag(MethodsPtr, flag, ref ret); + if (res != Result.Ok) + { + throw new ResultException(res); + } + return ret; + } + + [MonoPInvokeCallback] + private static void OnCurrentUserUpdateImpl(IntPtr ptr) + { + GCHandle h = GCHandle.FromIntPtr(ptr); + Discord d = (Discord)h.Target; + if (d.UserManagerInstance.OnCurrentUserUpdate != null) + { + d.UserManagerInstance.OnCurrentUserUpdate.Invoke(); + } + } + } + + public partial class ImageManager + { + [StructLayout(LayoutKind.Sequential)] + internal partial struct FFIEvents + { + + } + + [StructLayout(LayoutKind.Sequential)] + internal partial 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, Int32 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, false); + } + + [MonoPInvokeCallback] + private static void FetchCallbackImpl(IntPtr ptr, Result result, ImageHandle handleResult) + { + GCHandle h = GCHandle.FromIntPtr(ptr); + FetchHandler callback = (FetchHandler)h.Target; + h.Free(); + callback(result, handleResult); + } + + public void Fetch(ImageHandle handle, bool refresh, FetchHandler callback) + { + GCHandle wrapped = GCHandle.Alloc(callback); + Methods.Fetch(MethodsPtr, handle, refresh, GCHandle.ToIntPtr(wrapped), FetchCallbackImpl); + } + + public ImageDimensions GetDimensions(ImageHandle handle) + { + var ret = new ImageDimensions(); + var res = Methods.GetDimensions(MethodsPtr, handle, ref ret); + if (res != Result.Ok) + { + throw new ResultException(res); + } + return ret; + } + + public void GetData(ImageHandle handle, byte[] data) + { + var res = Methods.GetData(MethodsPtr, handle, data, data.Length); + if (res != Result.Ok) + { + throw new ResultException(res); + } + } + } + + public partial class ActivityManager + { + [StructLayout(LayoutKind.Sequential)] + internal partial 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; + } + + [StructLayout(LayoutKind.Sequential)] + internal partial 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, UInt32 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, Int64 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, Int64 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, Int64 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; + + 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, false); + } + + public void RegisterCommand(string command) + { + var res = Methods.RegisterCommand(MethodsPtr, command); + if (res != Result.Ok) + { + throw new ResultException(res); + } + } + + public void RegisterSteam(UInt32 steamId) + { + var res = Methods.RegisterSteam(MethodsPtr, steamId); + if (res != Result.Ok) + { + throw new ResultException(res); + } + } + + [MonoPInvokeCallback] + private static void UpdateActivityCallbackImpl(IntPtr ptr, Result result) + { + GCHandle h = GCHandle.FromIntPtr(ptr); + UpdateActivityHandler callback = (UpdateActivityHandler)h.Target; + h.Free(); + callback(result); + } + + public void UpdateActivity(Activity activity, UpdateActivityHandler callback) + { + GCHandle wrapped = GCHandle.Alloc(callback); + Methods.UpdateActivity(MethodsPtr, ref activity, GCHandle.ToIntPtr(wrapped), UpdateActivityCallbackImpl); + } + + [MonoPInvokeCallback] + private static void ClearActivityCallbackImpl(IntPtr ptr, Result result) + { + GCHandle h = GCHandle.FromIntPtr(ptr); + ClearActivityHandler callback = (ClearActivityHandler)h.Target; + h.Free(); + callback(result); + } + + public void ClearActivity(ClearActivityHandler callback) + { + GCHandle wrapped = GCHandle.Alloc(callback); + Methods.ClearActivity(MethodsPtr, GCHandle.ToIntPtr(wrapped), ClearActivityCallbackImpl); + } + + [MonoPInvokeCallback] + private static void SendRequestReplyCallbackImpl(IntPtr ptr, Result result) + { + GCHandle h = GCHandle.FromIntPtr(ptr); + SendRequestReplyHandler callback = (SendRequestReplyHandler)h.Target; + h.Free(); + callback(result); + } + + public void SendRequestReply(Int64 userId, ActivityJoinRequestReply reply, SendRequestReplyHandler callback) + { + GCHandle wrapped = GCHandle.Alloc(callback); + Methods.SendRequestReply(MethodsPtr, userId, reply, GCHandle.ToIntPtr(wrapped), SendRequestReplyCallbackImpl); + } + + [MonoPInvokeCallback] + private static void SendInviteCallbackImpl(IntPtr ptr, Result result) + { + GCHandle h = GCHandle.FromIntPtr(ptr); + SendInviteHandler callback = (SendInviteHandler)h.Target; + h.Free(); + callback(result); + } + + public void SendInvite(Int64 userId, ActivityActionType type, string content, SendInviteHandler callback) + { + GCHandle wrapped = GCHandle.Alloc(callback); + Methods.SendInvite(MethodsPtr, userId, type, content, GCHandle.ToIntPtr(wrapped), SendInviteCallbackImpl); + } + + [MonoPInvokeCallback] + private static void AcceptInviteCallbackImpl(IntPtr ptr, Result result) + { + GCHandle h = GCHandle.FromIntPtr(ptr); + AcceptInviteHandler callback = (AcceptInviteHandler)h.Target; + h.Free(); + callback(result); + } + + public void AcceptInvite(Int64 userId, AcceptInviteHandler callback) + { + GCHandle wrapped = GCHandle.Alloc(callback); + Methods.AcceptInvite(MethodsPtr, userId, GCHandle.ToIntPtr(wrapped), AcceptInviteCallbackImpl); + } + + [MonoPInvokeCallback] + private static void OnActivityJoinImpl(IntPtr ptr, string secret) + { + GCHandle h = GCHandle.FromIntPtr(ptr); + Discord d = (Discord)h.Target; + if (d.ActivityManagerInstance.OnActivityJoin != null) + { + d.ActivityManagerInstance.OnActivityJoin.Invoke(secret); + } + } + + [MonoPInvokeCallback] + private static void OnActivitySpectateImpl(IntPtr ptr, string secret) + { + GCHandle h = GCHandle.FromIntPtr(ptr); + Discord d = (Discord)h.Target; + if (d.ActivityManagerInstance.OnActivitySpectate != null) + { + d.ActivityManagerInstance.OnActivitySpectate.Invoke(secret); + } + } + + [MonoPInvokeCallback] + private static void OnActivityJoinRequestImpl(IntPtr ptr, ref User user) + { + GCHandle h = GCHandle.FromIntPtr(ptr); + Discord d = (Discord)h.Target; + if (d.ActivityManagerInstance.OnActivityJoinRequest != null) + { + d.ActivityManagerInstance.OnActivityJoinRequest.Invoke(ref user); + } + } + + [MonoPInvokeCallback] + private static void OnActivityInviteImpl(IntPtr ptr, ActivityActionType type, ref User user, ref Activity activity) + { + GCHandle h = GCHandle.FromIntPtr(ptr); + Discord d = (Discord)h.Target; + if (d.ActivityManagerInstance.OnActivityInvite != null) + { + d.ActivityManagerInstance.OnActivityInvite.Invoke(type, ref user, ref activity); + } + } + } + + public partial class RelationshipManager + { + [StructLayout(LayoutKind.Sequential)] + internal partial 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; + } + + [StructLayout(LayoutKind.Sequential)] + internal partial 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 Int32 count); + + [UnmanagedFunctionPointer(CallingConvention.Cdecl)] + internal delegate Result GetMethod(IntPtr methodsPtr, Int64 userId, ref Relationship relationship); + + [UnmanagedFunctionPointer(CallingConvention.Cdecl)] + internal delegate Result GetAtMethod(IntPtr methodsPtr, UInt32 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, false); + } + + [MonoPInvokeCallback] + private static bool FilterCallbackImpl(IntPtr ptr, ref Relationship relationship) + { + GCHandle h = GCHandle.FromIntPtr(ptr); + FilterHandler callback = (FilterHandler)h.Target; + return callback(ref relationship); + } + + public void Filter(FilterHandler callback) + { + GCHandle wrapped = GCHandle.Alloc(callback); + Methods.Filter(MethodsPtr, GCHandle.ToIntPtr(wrapped), FilterCallbackImpl); + wrapped.Free(); + } + + public Int32 Count() + { + var ret = new Int32(); + var res = Methods.Count(MethodsPtr, ref ret); + if (res != Result.Ok) + { + throw new ResultException(res); + } + return ret; + } + + public Relationship Get(Int64 userId) + { + var ret = new Relationship(); + var res = Methods.Get(MethodsPtr, userId, ref ret); + if (res != Result.Ok) + { + throw new ResultException(res); + } + return ret; + } + + public Relationship GetAt(UInt32 index) + { + var ret = new Relationship(); + var res = Methods.GetAt(MethodsPtr, index, ref ret); + if (res != Result.Ok) + { + throw new ResultException(res); + } + return ret; + } + + [MonoPInvokeCallback] + private static void OnRefreshImpl(IntPtr ptr) + { + GCHandle h = GCHandle.FromIntPtr(ptr); + Discord d = (Discord)h.Target; + if (d.RelationshipManagerInstance.OnRefresh != null) + { + d.RelationshipManagerInstance.OnRefresh.Invoke(); + } + } + + [MonoPInvokeCallback] + private static void OnRelationshipUpdateImpl(IntPtr ptr, ref Relationship relationship) + { + GCHandle h = GCHandle.FromIntPtr(ptr); + Discord d = (Discord)h.Target; + if (d.RelationshipManagerInstance.OnRelationshipUpdate != null) + { + d.RelationshipManagerInstance.OnRelationshipUpdate.Invoke(ref relationship); + } + } + } + + public partial class LobbyManager + { + [StructLayout(LayoutKind.Sequential)] + internal partial struct FFIEvents + { + [UnmanagedFunctionPointer(CallingConvention.Cdecl)] + internal delegate void LobbyUpdateHandler(IntPtr ptr, Int64 lobbyId); + + [UnmanagedFunctionPointer(CallingConvention.Cdecl)] + internal delegate void LobbyDeleteHandler(IntPtr ptr, Int64 lobbyId, UInt32 reason); + + [UnmanagedFunctionPointer(CallingConvention.Cdecl)] + internal delegate void MemberConnectHandler(IntPtr ptr, Int64 lobbyId, Int64 userId); + + [UnmanagedFunctionPointer(CallingConvention.Cdecl)] + internal delegate void MemberUpdateHandler(IntPtr ptr, Int64 lobbyId, Int64 userId); + + [UnmanagedFunctionPointer(CallingConvention.Cdecl)] + internal delegate void MemberDisconnectHandler(IntPtr ptr, Int64 lobbyId, Int64 userId); + + [UnmanagedFunctionPointer(CallingConvention.Cdecl)] + internal delegate void LobbyMessageHandler(IntPtr ptr, Int64 lobbyId, Int64 userId, IntPtr dataPtr, Int32 dataLen); + + [UnmanagedFunctionPointer(CallingConvention.Cdecl)] + internal delegate void SpeakingHandler(IntPtr ptr, Int64 lobbyId, Int64 userId, bool speaking); + + [UnmanagedFunctionPointer(CallingConvention.Cdecl)] + internal delegate void NetworkMessageHandler(IntPtr ptr, Int64 lobbyId, Int64 userId, byte channelId, IntPtr dataPtr, Int32 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; + } + + [StructLayout(LayoutKind.Sequential)] + internal partial struct FFIMethods + { + [UnmanagedFunctionPointer(CallingConvention.Cdecl)] + internal delegate Result GetLobbyCreateTransactionMethod(IntPtr methodsPtr, ref IntPtr transaction); + + [UnmanagedFunctionPointer(CallingConvention.Cdecl)] + internal delegate Result GetLobbyUpdateTransactionMethod(IntPtr methodsPtr, Int64 lobbyId, ref IntPtr transaction); + + [UnmanagedFunctionPointer(CallingConvention.Cdecl)] + internal delegate Result GetMemberUpdateTransactionMethod(IntPtr methodsPtr, Int64 lobbyId, Int64 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, Int64 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, Int64 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, Int64 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, Int64 lobbyId, IntPtr callbackData, DisconnectLobbyCallback callback); + + [UnmanagedFunctionPointer(CallingConvention.Cdecl)] + internal delegate Result GetLobbyMethod(IntPtr methodsPtr, Int64 lobbyId, ref Lobby lobby); + + [UnmanagedFunctionPointer(CallingConvention.Cdecl)] + internal delegate Result GetLobbyActivitySecretMethod(IntPtr methodsPtr, Int64 lobbyId, StringBuilder secret); + + [UnmanagedFunctionPointer(CallingConvention.Cdecl)] + internal delegate Result GetLobbyMetadataValueMethod(IntPtr methodsPtr, Int64 lobbyId, [MarshalAs(UnmanagedType.LPStr)]string key, StringBuilder value); + + [UnmanagedFunctionPointer(CallingConvention.Cdecl)] + internal delegate Result GetLobbyMetadataKeyMethod(IntPtr methodsPtr, Int64 lobbyId, Int32 index, StringBuilder key); + + [UnmanagedFunctionPointer(CallingConvention.Cdecl)] + internal delegate Result LobbyMetadataCountMethod(IntPtr methodsPtr, Int64 lobbyId, ref Int32 count); + + [UnmanagedFunctionPointer(CallingConvention.Cdecl)] + internal delegate Result MemberCountMethod(IntPtr methodsPtr, Int64 lobbyId, ref Int32 count); + + [UnmanagedFunctionPointer(CallingConvention.Cdecl)] + internal delegate Result GetMemberUserIdMethod(IntPtr methodsPtr, Int64 lobbyId, Int32 index, ref Int64 userId); + + [UnmanagedFunctionPointer(CallingConvention.Cdecl)] + internal delegate Result GetMemberUserMethod(IntPtr methodsPtr, Int64 lobbyId, Int64 userId, ref User user); + + [UnmanagedFunctionPointer(CallingConvention.Cdecl)] + internal delegate Result GetMemberMetadataValueMethod(IntPtr methodsPtr, Int64 lobbyId, Int64 userId, [MarshalAs(UnmanagedType.LPStr)]string key, StringBuilder value); + + [UnmanagedFunctionPointer(CallingConvention.Cdecl)] + internal delegate Result GetMemberMetadataKeyMethod(IntPtr methodsPtr, Int64 lobbyId, Int64 userId, Int32 index, StringBuilder key); + + [UnmanagedFunctionPointer(CallingConvention.Cdecl)] + internal delegate Result MemberMetadataCountMethod(IntPtr methodsPtr, Int64 lobbyId, Int64 userId, ref Int32 count); + + [UnmanagedFunctionPointer(CallingConvention.Cdecl)] + internal delegate void UpdateMemberCallback(IntPtr ptr, Result result); + + [UnmanagedFunctionPointer(CallingConvention.Cdecl)] + internal delegate void UpdateMemberMethod(IntPtr methodsPtr, Int64 lobbyId, Int64 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, Int64 lobbyId, byte[] data, Int32 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 Int32 count); + + [UnmanagedFunctionPointer(CallingConvention.Cdecl)] + internal delegate Result GetLobbyIdMethod(IntPtr methodsPtr, Int32 index, ref Int64 lobbyId); + + [UnmanagedFunctionPointer(CallingConvention.Cdecl)] + internal delegate void ConnectVoiceCallback(IntPtr ptr, Result result); + + [UnmanagedFunctionPointer(CallingConvention.Cdecl)] + internal delegate void ConnectVoiceMethod(IntPtr methodsPtr, Int64 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, Int64 lobbyId, IntPtr callbackData, DisconnectVoiceCallback callback); + + [UnmanagedFunctionPointer(CallingConvention.Cdecl)] + internal delegate Result ConnectNetworkMethod(IntPtr methodsPtr, Int64 lobbyId); + + [UnmanagedFunctionPointer(CallingConvention.Cdecl)] + internal delegate Result DisconnectNetworkMethod(IntPtr methodsPtr, Int64 lobbyId); + + [UnmanagedFunctionPointer(CallingConvention.Cdecl)] + internal delegate Result FlushNetworkMethod(IntPtr methodsPtr); + + [UnmanagedFunctionPointer(CallingConvention.Cdecl)] + internal delegate Result OpenNetworkChannelMethod(IntPtr methodsPtr, Int64 lobbyId, byte channelId, bool reliable); + + [UnmanagedFunctionPointer(CallingConvention.Cdecl)] + internal delegate Result SendNetworkMessageMethod(IntPtr methodsPtr, Int64 lobbyId, Int64 userId, byte channelId, byte[] data, Int32 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(Int64 lobbyId); + + public delegate void LobbyDeleteHandler(Int64 lobbyId, UInt32 reason); + + public delegate void MemberConnectHandler(Int64 lobbyId, Int64 userId); + + public delegate void MemberUpdateHandler(Int64 lobbyId, Int64 userId); + + public delegate void MemberDisconnectHandler(Int64 lobbyId, Int64 userId); + + public delegate void LobbyMessageHandler(Int64 lobbyId, Int64 userId, byte[] data); + + public delegate void SpeakingHandler(Int64 lobbyId, Int64 userId, bool speaking); + + public delegate void NetworkMessageHandler(Int64 lobbyId, Int64 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, false); + } + + public LobbyTransaction GetLobbyCreateTransaction() + { + var ret = new LobbyTransaction(); + var res = Methods.GetLobbyCreateTransaction(MethodsPtr, ref ret.MethodsPtr); + if (res != Result.Ok) + { + throw new ResultException(res); + } + return ret; + } + + public LobbyTransaction GetLobbyUpdateTransaction(Int64 lobbyId) + { + var ret = new LobbyTransaction(); + var res = Methods.GetLobbyUpdateTransaction(MethodsPtr, lobbyId, ref ret.MethodsPtr); + if (res != Result.Ok) + { + throw new ResultException(res); + } + return ret; + } + + public LobbyMemberTransaction GetMemberUpdateTransaction(Int64 lobbyId, Int64 userId) + { + var ret = new LobbyMemberTransaction(); + var res = Methods.GetMemberUpdateTransaction(MethodsPtr, lobbyId, userId, ref ret.MethodsPtr); + if (res != Result.Ok) + { + throw new ResultException(res); + } + return ret; + } + + [MonoPInvokeCallback] + private static void CreateLobbyCallbackImpl(IntPtr ptr, Result result, ref Lobby lobby) + { + GCHandle h = GCHandle.FromIntPtr(ptr); + CreateLobbyHandler callback = (CreateLobbyHandler)h.Target; + h.Free(); + callback(result, ref lobby); + } + + public void CreateLobby(LobbyTransaction transaction, CreateLobbyHandler callback) + { + GCHandle wrapped = GCHandle.Alloc(callback); + Methods.CreateLobby(MethodsPtr, transaction.MethodsPtr, GCHandle.ToIntPtr(wrapped), CreateLobbyCallbackImpl); + transaction.MethodsPtr = IntPtr.Zero; + } + + [MonoPInvokeCallback] + private static void UpdateLobbyCallbackImpl(IntPtr ptr, Result result) + { + GCHandle h = GCHandle.FromIntPtr(ptr); + UpdateLobbyHandler callback = (UpdateLobbyHandler)h.Target; + h.Free(); + callback(result); + } + + public void UpdateLobby(Int64 lobbyId, LobbyTransaction transaction, UpdateLobbyHandler callback) + { + GCHandle wrapped = GCHandle.Alloc(callback); + Methods.UpdateLobby(MethodsPtr, lobbyId, transaction.MethodsPtr, GCHandle.ToIntPtr(wrapped), UpdateLobbyCallbackImpl); + transaction.MethodsPtr = IntPtr.Zero; + } + + [MonoPInvokeCallback] + private static void DeleteLobbyCallbackImpl(IntPtr ptr, Result result) + { + GCHandle h = GCHandle.FromIntPtr(ptr); + DeleteLobbyHandler callback = (DeleteLobbyHandler)h.Target; + h.Free(); + callback(result); + } + + public void DeleteLobby(Int64 lobbyId, DeleteLobbyHandler callback) + { + GCHandle wrapped = GCHandle.Alloc(callback); + Methods.DeleteLobby(MethodsPtr, lobbyId, GCHandle.ToIntPtr(wrapped), DeleteLobbyCallbackImpl); + } + + [MonoPInvokeCallback] + private static void ConnectLobbyCallbackImpl(IntPtr ptr, Result result, ref Lobby lobby) + { + GCHandle h = GCHandle.FromIntPtr(ptr); + ConnectLobbyHandler callback = (ConnectLobbyHandler)h.Target; + h.Free(); + callback(result, ref lobby); + } + + public void ConnectLobby(Int64 lobbyId, string secret, ConnectLobbyHandler callback) + { + GCHandle wrapped = GCHandle.Alloc(callback); + Methods.ConnectLobby(MethodsPtr, lobbyId, secret, GCHandle.ToIntPtr(wrapped), ConnectLobbyCallbackImpl); + } + + [MonoPInvokeCallback] + private static void ConnectLobbyWithActivitySecretCallbackImpl(IntPtr ptr, Result result, ref Lobby lobby) + { + GCHandle h = GCHandle.FromIntPtr(ptr); + ConnectLobbyWithActivitySecretHandler callback = (ConnectLobbyWithActivitySecretHandler)h.Target; + h.Free(); + callback(result, ref lobby); + } + + public void ConnectLobbyWithActivitySecret(string activitySecret, ConnectLobbyWithActivitySecretHandler callback) + { + GCHandle wrapped = GCHandle.Alloc(callback); + Methods.ConnectLobbyWithActivitySecret(MethodsPtr, activitySecret, GCHandle.ToIntPtr(wrapped), ConnectLobbyWithActivitySecretCallbackImpl); + } + + [MonoPInvokeCallback] + private static void DisconnectLobbyCallbackImpl(IntPtr ptr, Result result) + { + GCHandle h = GCHandle.FromIntPtr(ptr); + DisconnectLobbyHandler callback = (DisconnectLobbyHandler)h.Target; + h.Free(); + callback(result); + } + + public void DisconnectLobby(Int64 lobbyId, DisconnectLobbyHandler callback) + { + GCHandle wrapped = GCHandle.Alloc(callback); + Methods.DisconnectLobby(MethodsPtr, lobbyId, GCHandle.ToIntPtr(wrapped), DisconnectLobbyCallbackImpl); + } + + public Lobby GetLobby(Int64 lobbyId) + { + var ret = new Lobby(); + var res = Methods.GetLobby(MethodsPtr, lobbyId, ref ret); + if (res != Result.Ok) + { + throw new ResultException(res); + } + return ret; + } + + public string GetLobbyActivitySecret(Int64 lobbyId) + { + var ret = new StringBuilder(128); + var res = Methods.GetLobbyActivitySecret(MethodsPtr, lobbyId, ret); + if (res != Result.Ok) + { + throw new ResultException(res); + } + return ret.ToString(); + } + + public string GetLobbyMetadataValue(Int64 lobbyId, string key) + { + var ret = new StringBuilder(4096); + var res = Methods.GetLobbyMetadataValue(MethodsPtr, lobbyId, key, ret); + if (res != Result.Ok) + { + throw new ResultException(res); + } + return ret.ToString(); + } + + public string GetLobbyMetadataKey(Int64 lobbyId, Int32 index) + { + var ret = new StringBuilder(256); + var res = Methods.GetLobbyMetadataKey(MethodsPtr, lobbyId, index, ret); + if (res != Result.Ok) + { + throw new ResultException(res); + } + return ret.ToString(); + } + + public Int32 LobbyMetadataCount(Int64 lobbyId) + { + var ret = new Int32(); + var res = Methods.LobbyMetadataCount(MethodsPtr, lobbyId, ref ret); + if (res != Result.Ok) + { + throw new ResultException(res); + } + return ret; + } + + public Int32 MemberCount(Int64 lobbyId) + { + var ret = new Int32(); + var res = Methods.MemberCount(MethodsPtr, lobbyId, ref ret); + if (res != Result.Ok) + { + throw new ResultException(res); + } + return ret; + } + + public Int64 GetMemberUserId(Int64 lobbyId, Int32 index) + { + var ret = new Int64(); + var res = Methods.GetMemberUserId(MethodsPtr, lobbyId, index, ref ret); + if (res != Result.Ok) + { + throw new ResultException(res); + } + return ret; + } + + public User GetMemberUser(Int64 lobbyId, Int64 userId) + { + var ret = new User(); + var res = Methods.GetMemberUser(MethodsPtr, lobbyId, userId, ref ret); + if (res != Result.Ok) + { + throw new ResultException(res); + } + return ret; + } + + public string GetMemberMetadataValue(Int64 lobbyId, Int64 userId, string key) + { + var ret = new StringBuilder(4096); + var res = Methods.GetMemberMetadataValue(MethodsPtr, lobbyId, userId, key, ret); + if (res != Result.Ok) + { + throw new ResultException(res); + } + return ret.ToString(); + } + + public string GetMemberMetadataKey(Int64 lobbyId, Int64 userId, Int32 index) + { + var ret = new StringBuilder(256); + var res = Methods.GetMemberMetadataKey(MethodsPtr, lobbyId, userId, index, ret); + if (res != Result.Ok) + { + throw new ResultException(res); + } + return ret.ToString(); + } + + public Int32 MemberMetadataCount(Int64 lobbyId, Int64 userId) + { + var ret = new Int32(); + var res = Methods.MemberMetadataCount(MethodsPtr, lobbyId, userId, ref ret); + if (res != Result.Ok) + { + throw new ResultException(res); + } + return ret; + } + + [MonoPInvokeCallback] + private static void UpdateMemberCallbackImpl(IntPtr ptr, Result result) + { + GCHandle h = GCHandle.FromIntPtr(ptr); + UpdateMemberHandler callback = (UpdateMemberHandler)h.Target; + h.Free(); + callback(result); + } + + public void UpdateMember(Int64 lobbyId, Int64 userId, LobbyMemberTransaction transaction, UpdateMemberHandler callback) + { + GCHandle wrapped = GCHandle.Alloc(callback); + Methods.UpdateMember(MethodsPtr, lobbyId, userId, transaction.MethodsPtr, GCHandle.ToIntPtr(wrapped), UpdateMemberCallbackImpl); + transaction.MethodsPtr = IntPtr.Zero; + } + + [MonoPInvokeCallback] + private static void SendLobbyMessageCallbackImpl(IntPtr ptr, Result result) + { + GCHandle h = GCHandle.FromIntPtr(ptr); + SendLobbyMessageHandler callback = (SendLobbyMessageHandler)h.Target; + h.Free(); + callback(result); + } + + public void SendLobbyMessage(Int64 lobbyId, byte[] data, SendLobbyMessageHandler callback) + { + GCHandle wrapped = GCHandle.Alloc(callback); + Methods.SendLobbyMessage(MethodsPtr, lobbyId, data, data.Length, GCHandle.ToIntPtr(wrapped), SendLobbyMessageCallbackImpl); + } + + public LobbySearchQuery GetSearchQuery() + { + var ret = new LobbySearchQuery(); + var res = Methods.GetSearchQuery(MethodsPtr, ref ret.MethodsPtr); + if (res != Result.Ok) + { + throw new ResultException(res); + } + return ret; + } + + [MonoPInvokeCallback] + private static void SearchCallbackImpl(IntPtr ptr, Result result) + { + GCHandle h = GCHandle.FromIntPtr(ptr); + SearchHandler callback = (SearchHandler)h.Target; + h.Free(); + callback(result); + } + + public void Search(LobbySearchQuery query, SearchHandler callback) + { + GCHandle wrapped = GCHandle.Alloc(callback); + Methods.Search(MethodsPtr, query.MethodsPtr, GCHandle.ToIntPtr(wrapped), SearchCallbackImpl); + query.MethodsPtr = IntPtr.Zero; + } + + public Int32 LobbyCount() + { + var ret = new Int32(); + Methods.LobbyCount(MethodsPtr, ref ret); + return ret; + } + + public Int64 GetLobbyId(Int32 index) + { + var ret = new Int64(); + var res = Methods.GetLobbyId(MethodsPtr, index, ref ret); + if (res != Result.Ok) + { + throw new ResultException(res); + } + return ret; + } + + [MonoPInvokeCallback] + private static void ConnectVoiceCallbackImpl(IntPtr ptr, Result result) + { + GCHandle h = GCHandle.FromIntPtr(ptr); + ConnectVoiceHandler callback = (ConnectVoiceHandler)h.Target; + h.Free(); + callback(result); + } + + public void ConnectVoice(Int64 lobbyId, ConnectVoiceHandler callback) + { + GCHandle wrapped = GCHandle.Alloc(callback); + Methods.ConnectVoice(MethodsPtr, lobbyId, GCHandle.ToIntPtr(wrapped), ConnectVoiceCallbackImpl); + } + + [MonoPInvokeCallback] + private static void DisconnectVoiceCallbackImpl(IntPtr ptr, Result result) + { + GCHandle h = GCHandle.FromIntPtr(ptr); + DisconnectVoiceHandler callback = (DisconnectVoiceHandler)h.Target; + h.Free(); + callback(result); + } + + public void DisconnectVoice(Int64 lobbyId, DisconnectVoiceHandler callback) + { + GCHandle wrapped = GCHandle.Alloc(callback); + Methods.DisconnectVoice(MethodsPtr, lobbyId, GCHandle.ToIntPtr(wrapped), DisconnectVoiceCallbackImpl); + } + + public void ConnectNetwork(Int64 lobbyId) + { + var res = Methods.ConnectNetwork(MethodsPtr, lobbyId); + if (res != Result.Ok) + { + throw new ResultException(res); + } + } + + public void DisconnectNetwork(Int64 lobbyId) + { + var res = Methods.DisconnectNetwork(MethodsPtr, lobbyId); + if (res != Result.Ok) + { + throw new ResultException(res); + } + } + + public void FlushNetwork() + { + var res = Methods.FlushNetwork(MethodsPtr); + if (res != Result.Ok) + { + throw new ResultException(res); + } + } + + public void OpenNetworkChannel(Int64 lobbyId, byte channelId, bool reliable) + { + var res = Methods.OpenNetworkChannel(MethodsPtr, lobbyId, channelId, reliable); + if (res != Result.Ok) + { + throw new ResultException(res); + } + } + + public void SendNetworkMessage(Int64 lobbyId, Int64 userId, byte channelId, byte[] data) + { + var res = Methods.SendNetworkMessage(MethodsPtr, lobbyId, userId, channelId, data, data.Length); + if (res != Result.Ok) + { + throw new ResultException(res); + } + } + + [MonoPInvokeCallback] + private static void OnLobbyUpdateImpl(IntPtr ptr, Int64 lobbyId) + { + GCHandle h = GCHandle.FromIntPtr(ptr); + Discord d = (Discord)h.Target; + if (d.LobbyManagerInstance.OnLobbyUpdate != null) + { + d.LobbyManagerInstance.OnLobbyUpdate.Invoke(lobbyId); + } + } + + [MonoPInvokeCallback] + private static void OnLobbyDeleteImpl(IntPtr ptr, Int64 lobbyId, UInt32 reason) + { + GCHandle h = GCHandle.FromIntPtr(ptr); + Discord d = (Discord)h.Target; + if (d.LobbyManagerInstance.OnLobbyDelete != null) + { + d.LobbyManagerInstance.OnLobbyDelete.Invoke(lobbyId, reason); + } + } + + [MonoPInvokeCallback] + private static void OnMemberConnectImpl(IntPtr ptr, Int64 lobbyId, Int64 userId) + { + GCHandle h = GCHandle.FromIntPtr(ptr); + Discord d = (Discord)h.Target; + if (d.LobbyManagerInstance.OnMemberConnect != null) + { + d.LobbyManagerInstance.OnMemberConnect.Invoke(lobbyId, userId); + } + } + + [MonoPInvokeCallback] + private static void OnMemberUpdateImpl(IntPtr ptr, Int64 lobbyId, Int64 userId) + { + GCHandle h = GCHandle.FromIntPtr(ptr); + Discord d = (Discord)h.Target; + if (d.LobbyManagerInstance.OnMemberUpdate != null) + { + d.LobbyManagerInstance.OnMemberUpdate.Invoke(lobbyId, userId); + } + } + + [MonoPInvokeCallback] + private static void OnMemberDisconnectImpl(IntPtr ptr, Int64 lobbyId, Int64 userId) + { + GCHandle h = GCHandle.FromIntPtr(ptr); + Discord d = (Discord)h.Target; + if (d.LobbyManagerInstance.OnMemberDisconnect != null) + { + d.LobbyManagerInstance.OnMemberDisconnect.Invoke(lobbyId, userId); + } + } + + [MonoPInvokeCallback] + private static void OnLobbyMessageImpl(IntPtr ptr, Int64 lobbyId, Int64 userId, IntPtr dataPtr, Int32 dataLen) + { + GCHandle h = GCHandle.FromIntPtr(ptr); + Discord d = (Discord)h.Target; + if (d.LobbyManagerInstance.OnLobbyMessage != null) + { + byte[] data = new byte[dataLen]; + Marshal.Copy(dataPtr, data, 0, (int)dataLen); + d.LobbyManagerInstance.OnLobbyMessage.Invoke(lobbyId, userId, data); + } + } + + [MonoPInvokeCallback] + private static void OnSpeakingImpl(IntPtr ptr, Int64 lobbyId, Int64 userId, bool speaking) + { + GCHandle h = GCHandle.FromIntPtr(ptr); + Discord d = (Discord)h.Target; + if (d.LobbyManagerInstance.OnSpeaking != null) + { + d.LobbyManagerInstance.OnSpeaking.Invoke(lobbyId, userId, speaking); + } + } + + [MonoPInvokeCallback] + private static void OnNetworkMessageImpl(IntPtr ptr, Int64 lobbyId, Int64 userId, byte channelId, IntPtr dataPtr, Int32 dataLen) + { + GCHandle h = GCHandle.FromIntPtr(ptr); + Discord d = (Discord)h.Target; + if (d.LobbyManagerInstance.OnNetworkMessage != null) + { + byte[] data = new byte[dataLen]; + Marshal.Copy(dataPtr, data, 0, (int)dataLen); + d.LobbyManagerInstance.OnNetworkMessage.Invoke(lobbyId, userId, channelId, data); + } + } + } + + public partial class NetworkManager + { + [StructLayout(LayoutKind.Sequential)] + internal partial struct FFIEvents + { + [UnmanagedFunctionPointer(CallingConvention.Cdecl)] + internal delegate void MessageHandler(IntPtr ptr, UInt64 peerId, byte channelId, IntPtr dataPtr, Int32 dataLen); + + [UnmanagedFunctionPointer(CallingConvention.Cdecl)] + internal delegate void RouteUpdateHandler(IntPtr ptr, [MarshalAs(UnmanagedType.LPStr)]string routeData); + + internal MessageHandler OnMessage; + + internal RouteUpdateHandler OnRouteUpdate; + } + + [StructLayout(LayoutKind.Sequential)] + internal partial struct FFIMethods + { + [UnmanagedFunctionPointer(CallingConvention.Cdecl)] + internal delegate void GetPeerIdMethod(IntPtr methodsPtr, ref UInt64 peerId); + + [UnmanagedFunctionPointer(CallingConvention.Cdecl)] + internal delegate Result FlushMethod(IntPtr methodsPtr); + + [UnmanagedFunctionPointer(CallingConvention.Cdecl)] + internal delegate Result OpenPeerMethod(IntPtr methodsPtr, UInt64 peerId, [MarshalAs(UnmanagedType.LPStr)]string routeData); + + [UnmanagedFunctionPointer(CallingConvention.Cdecl)] + internal delegate Result UpdatePeerMethod(IntPtr methodsPtr, UInt64 peerId, [MarshalAs(UnmanagedType.LPStr)]string routeData); + + [UnmanagedFunctionPointer(CallingConvention.Cdecl)] + internal delegate Result ClosePeerMethod(IntPtr methodsPtr, UInt64 peerId); + + [UnmanagedFunctionPointer(CallingConvention.Cdecl)] + internal delegate Result OpenChannelMethod(IntPtr methodsPtr, UInt64 peerId, byte channelId, bool reliable); + + [UnmanagedFunctionPointer(CallingConvention.Cdecl)] + internal delegate Result CloseChannelMethod(IntPtr methodsPtr, UInt64 peerId, byte channelId); + + [UnmanagedFunctionPointer(CallingConvention.Cdecl)] + internal delegate Result SendMessageMethod(IntPtr methodsPtr, UInt64 peerId, byte channelId, byte[] data, Int32 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(UInt64 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, false); + } + + /// + /// Get the local peer ID for this process. + /// + public UInt64 GetPeerId() + { + var ret = new UInt64(); + Methods.GetPeerId(MethodsPtr, ref ret); + return ret; + } + + /// + /// Send pending network messages. + /// + public void Flush() + { + var res = Methods.Flush(MethodsPtr); + if (res != Result.Ok) + { + throw new ResultException(res); + } + } + + /// + /// Open a connection to a remote peer. + /// + public void OpenPeer(UInt64 peerId, string routeData) + { + var res = Methods.OpenPeer(MethodsPtr, peerId, routeData); + if (res != Result.Ok) + { + throw new ResultException(res); + } + } + + /// + /// Update the route data for a connected peer. + /// + public void UpdatePeer(UInt64 peerId, string routeData) + { + var res = Methods.UpdatePeer(MethodsPtr, peerId, routeData); + if (res != Result.Ok) + { + throw new ResultException(res); + } + } + + /// + /// Close the connection to a remote peer. + /// + public void ClosePeer(UInt64 peerId) + { + var res = Methods.ClosePeer(MethodsPtr, peerId); + if (res != Result.Ok) + { + throw new ResultException(res); + } + } + + /// + /// Open a message channel to a connected peer. + /// + public void OpenChannel(UInt64 peerId, byte channelId, bool reliable) + { + var res = Methods.OpenChannel(MethodsPtr, peerId, channelId, reliable); + if (res != Result.Ok) + { + throw new ResultException(res); + } + } + + /// + /// Close a message channel to a connected peer. + /// + public void CloseChannel(UInt64 peerId, byte channelId) + { + var res = Methods.CloseChannel(MethodsPtr, peerId, channelId); + if (res != Result.Ok) + { + throw new ResultException(res); + } + } + + /// + /// Send a message to a connected peer over an opened message channel. + /// + public void SendMessage(UInt64 peerId, byte channelId, byte[] data) + { + var res = Methods.SendMessage(MethodsPtr, peerId, channelId, data, data.Length); + if (res != Result.Ok) + { + throw new ResultException(res); + } + } + + [MonoPInvokeCallback] + private static void OnMessageImpl(IntPtr ptr, UInt64 peerId, byte channelId, IntPtr dataPtr, Int32 dataLen) + { + GCHandle h = GCHandle.FromIntPtr(ptr); + Discord d = (Discord)h.Target; + if (d.NetworkManagerInstance.OnMessage != null) + { + byte[] data = new byte[dataLen]; + Marshal.Copy(dataPtr, data, 0, (int)dataLen); + d.NetworkManagerInstance.OnMessage.Invoke(peerId, channelId, data); + } + } + + [MonoPInvokeCallback] + private static void OnRouteUpdateImpl(IntPtr ptr, string routeData) + { + GCHandle h = GCHandle.FromIntPtr(ptr); + Discord d = (Discord)h.Target; + if (d.NetworkManagerInstance.OnRouteUpdate != null) + { + d.NetworkManagerInstance.OnRouteUpdate.Invoke(routeData); + } + } + } + + public partial class OverlayManager + { + [StructLayout(LayoutKind.Sequential)] + internal partial struct FFIEvents + { + [UnmanagedFunctionPointer(CallingConvention.Cdecl)] + internal delegate void ToggleHandler(IntPtr ptr, bool locked); + + internal ToggleHandler OnToggle; + } + + [StructLayout(LayoutKind.Sequential)] + internal partial 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, false); + } + + public bool IsEnabled() + { + var ret = new bool(); + Methods.IsEnabled(MethodsPtr, ref ret); + return ret; + } + + public bool IsLocked() + { + var ret = new bool(); + Methods.IsLocked(MethodsPtr, ref ret); + return ret; + } + + [MonoPInvokeCallback] + private static void SetLockedCallbackImpl(IntPtr ptr, Result result) + { + GCHandle h = GCHandle.FromIntPtr(ptr); + SetLockedHandler callback = (SetLockedHandler)h.Target; + h.Free(); + callback(result); + } + + public void SetLocked(bool locked, SetLockedHandler callback) + { + GCHandle wrapped = GCHandle.Alloc(callback); + Methods.SetLocked(MethodsPtr, locked, GCHandle.ToIntPtr(wrapped), SetLockedCallbackImpl); + } + + [MonoPInvokeCallback] + private static void OpenActivityInviteCallbackImpl(IntPtr ptr, Result result) + { + GCHandle h = GCHandle.FromIntPtr(ptr); + OpenActivityInviteHandler callback = (OpenActivityInviteHandler)h.Target; + h.Free(); + callback(result); + } + + public void OpenActivityInvite(ActivityActionType type, OpenActivityInviteHandler callback) + { + GCHandle wrapped = GCHandle.Alloc(callback); + Methods.OpenActivityInvite(MethodsPtr, type, GCHandle.ToIntPtr(wrapped), OpenActivityInviteCallbackImpl); + } + + [MonoPInvokeCallback] + private static void OpenGuildInviteCallbackImpl(IntPtr ptr, Result result) + { + GCHandle h = GCHandle.FromIntPtr(ptr); + OpenGuildInviteHandler callback = (OpenGuildInviteHandler)h.Target; + h.Free(); + callback(result); + } + + public void OpenGuildInvite(string code, OpenGuildInviteHandler callback) + { + GCHandle wrapped = GCHandle.Alloc(callback); + Methods.OpenGuildInvite(MethodsPtr, code, GCHandle.ToIntPtr(wrapped), OpenGuildInviteCallbackImpl); + } + + [MonoPInvokeCallback] + private static void OpenVoiceSettingsCallbackImpl(IntPtr ptr, Result result) + { + GCHandle h = GCHandle.FromIntPtr(ptr); + OpenVoiceSettingsHandler callback = (OpenVoiceSettingsHandler)h.Target; + h.Free(); + callback(result); + } + + public void OpenVoiceSettings(OpenVoiceSettingsHandler callback) + { + GCHandle wrapped = GCHandle.Alloc(callback); + Methods.OpenVoiceSettings(MethodsPtr, GCHandle.ToIntPtr(wrapped), OpenVoiceSettingsCallbackImpl); + } + + [MonoPInvokeCallback] + private static void OnToggleImpl(IntPtr ptr, bool locked) + { + GCHandle h = GCHandle.FromIntPtr(ptr); + Discord d = (Discord)h.Target; + if (d.OverlayManagerInstance.OnToggle != null) + { + d.OverlayManagerInstance.OnToggle.Invoke(locked); + } + } + } + + public partial class StorageManager + { + [StructLayout(LayoutKind.Sequential)] + internal partial struct FFIEvents + { + + } + + [StructLayout(LayoutKind.Sequential)] + internal partial struct FFIMethods + { + [UnmanagedFunctionPointer(CallingConvention.Cdecl)] + internal delegate Result ReadMethod(IntPtr methodsPtr, [MarshalAs(UnmanagedType.LPStr)]string name, byte[] data, Int32 dataLen, ref UInt32 read); + + [UnmanagedFunctionPointer(CallingConvention.Cdecl)] + internal delegate void ReadAsyncCallback(IntPtr ptr, Result result, IntPtr dataPtr, Int32 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, Int32 dataLen); + + [UnmanagedFunctionPointer(CallingConvention.Cdecl)] + internal delegate void ReadAsyncPartialMethod(IntPtr methodsPtr, [MarshalAs(UnmanagedType.LPStr)]string name, UInt64 offset, UInt64 length, IntPtr callbackData, ReadAsyncPartialCallback callback); + + [UnmanagedFunctionPointer(CallingConvention.Cdecl)] + internal delegate Result WriteMethod(IntPtr methodsPtr, [MarshalAs(UnmanagedType.LPStr)]string name, byte[] data, Int32 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, Int32 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 Int32 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, Int32 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.InternalError); + } + } + + private void InitEvents(IntPtr eventsPtr, ref FFIEvents events) + { + Marshal.StructureToPtr(events, eventsPtr, false); + } + + public UInt32 Read(string name, byte[] data) + { + var ret = new UInt32(); + var res = Methods.Read(MethodsPtr, name, data, data.Length, ref ret); + if (res != Result.Ok) + { + throw new ResultException(res); + } + return ret; + } + + [MonoPInvokeCallback] + private static void ReadAsyncCallbackImpl(IntPtr ptr, Result result, IntPtr dataPtr, Int32 dataLen) + { + GCHandle h = GCHandle.FromIntPtr(ptr); + ReadAsyncHandler callback = (ReadAsyncHandler)h.Target; + h.Free(); + byte[] data = new byte[dataLen]; + Marshal.Copy(dataPtr, data, 0, (int)dataLen); + callback(result, data); + } + + public void ReadAsync(string name, ReadAsyncHandler callback) + { + GCHandle wrapped = GCHandle.Alloc(callback); + Methods.ReadAsync(MethodsPtr, name, GCHandle.ToIntPtr(wrapped), ReadAsyncCallbackImpl); + } + + [MonoPInvokeCallback] + private static void ReadAsyncPartialCallbackImpl(IntPtr ptr, Result result, IntPtr dataPtr, Int32 dataLen) + { + GCHandle h = GCHandle.FromIntPtr(ptr); + ReadAsyncPartialHandler callback = (ReadAsyncPartialHandler)h.Target; + h.Free(); + byte[] data = new byte[dataLen]; + Marshal.Copy(dataPtr, data, 0, (int)dataLen); + callback(result, data); + } + + public void ReadAsyncPartial(string name, UInt64 offset, UInt64 length, ReadAsyncPartialHandler callback) + { + GCHandle wrapped = GCHandle.Alloc(callback); + Methods.ReadAsyncPartial(MethodsPtr, name, offset, length, GCHandle.ToIntPtr(wrapped), ReadAsyncPartialCallbackImpl); + } + + public void Write(string name, byte[] data) + { + var res = Methods.Write(MethodsPtr, name, data, data.Length); + if (res != Result.Ok) + { + throw new ResultException(res); + } + } + + [MonoPInvokeCallback] + private static void WriteAsyncCallbackImpl(IntPtr ptr, Result result) + { + GCHandle h = GCHandle.FromIntPtr(ptr); + WriteAsyncHandler callback = (WriteAsyncHandler)h.Target; + h.Free(); + callback(result); + } + + public void WriteAsync(string name, byte[] data, WriteAsyncHandler callback) + { + GCHandle wrapped = GCHandle.Alloc(callback); + Methods.WriteAsync(MethodsPtr, name, data, data.Length, GCHandle.ToIntPtr(wrapped), WriteAsyncCallbackImpl); + } + + public void Delete(string name) + { + var res = Methods.Delete(MethodsPtr, name); + if (res != Result.Ok) + { + throw new ResultException(res); + } + } + + public bool Exists(string name) + { + var ret = new bool(); + var res = Methods.Exists(MethodsPtr, name, ref ret); + if (res != Result.Ok) + { + throw new ResultException(res); + } + return ret; + } + + public Int32 Count() + { + var ret = new Int32(); + Methods.Count(MethodsPtr, ref ret); + return ret; + } + + public FileStat Stat(string name) + { + var ret = new FileStat(); + var res = Methods.Stat(MethodsPtr, name, ref ret); + if (res != Result.Ok) + { + throw new ResultException(res); + } + return ret; + } + + public FileStat StatAt(Int32 index) + { + var ret = new FileStat(); + var res = Methods.StatAt(MethodsPtr, index, ref ret); + if (res != Result.Ok) + { + throw new ResultException(res); + } + return ret; + } + + public string GetPath() + { + var ret = new StringBuilder(4096); + var res = Methods.GetPath(MethodsPtr, ret); + if (res != Result.Ok) + { + throw new ResultException(res); + } + return ret.ToString(); + } + } + + public partial class StoreManager + { + [StructLayout(LayoutKind.Sequential)] + internal partial struct FFIEvents + { + [UnmanagedFunctionPointer(CallingConvention.Cdecl)] + internal delegate void EntitlementCreateHandler(IntPtr ptr, ref Entitlement entitlement); + + [UnmanagedFunctionPointer(CallingConvention.Cdecl)] + internal delegate void EntitlementDeleteHandler(IntPtr ptr, ref Entitlement entitlement); + + internal EntitlementCreateHandler OnEntitlementCreate; + + internal EntitlementDeleteHandler OnEntitlementDelete; + } + + [StructLayout(LayoutKind.Sequential)] + internal partial struct FFIMethods + { + [UnmanagedFunctionPointer(CallingConvention.Cdecl)] + internal delegate void FetchSkusCallback(IntPtr ptr, Result result); + + [UnmanagedFunctionPointer(CallingConvention.Cdecl)] + internal delegate void FetchSkusMethod(IntPtr methodsPtr, IntPtr callbackData, FetchSkusCallback callback); + + [UnmanagedFunctionPointer(CallingConvention.Cdecl)] + internal delegate void CountSkusMethod(IntPtr methodsPtr, ref Int32 count); + + [UnmanagedFunctionPointer(CallingConvention.Cdecl)] + internal delegate Result GetSkuMethod(IntPtr methodsPtr, Int64 skuId, ref Sku sku); + + [UnmanagedFunctionPointer(CallingConvention.Cdecl)] + internal delegate Result GetSkuAtMethod(IntPtr methodsPtr, Int32 index, ref Sku sku); + + [UnmanagedFunctionPointer(CallingConvention.Cdecl)] + internal delegate void FetchEntitlementsCallback(IntPtr ptr, Result result); + + [UnmanagedFunctionPointer(CallingConvention.Cdecl)] + internal delegate void FetchEntitlementsMethod(IntPtr methodsPtr, IntPtr callbackData, FetchEntitlementsCallback callback); + + [UnmanagedFunctionPointer(CallingConvention.Cdecl)] + internal delegate void CountEntitlementsMethod(IntPtr methodsPtr, ref Int32 count); + + [UnmanagedFunctionPointer(CallingConvention.Cdecl)] + internal delegate Result GetEntitlementMethod(IntPtr methodsPtr, Int64 entitlementId, ref Entitlement entitlement); + + [UnmanagedFunctionPointer(CallingConvention.Cdecl)] + internal delegate Result GetEntitlementAtMethod(IntPtr methodsPtr, Int32 index, ref Entitlement entitlement); + + [UnmanagedFunctionPointer(CallingConvention.Cdecl)] + internal delegate Result HasSkuEntitlementMethod(IntPtr methodsPtr, Int64 skuId, ref bool hasEntitlement); + + [UnmanagedFunctionPointer(CallingConvention.Cdecl)] + internal delegate void StartPurchaseCallback(IntPtr ptr, Result result); + + [UnmanagedFunctionPointer(CallingConvention.Cdecl)] + internal delegate void StartPurchaseMethod(IntPtr methodsPtr, Int64 skuId, IntPtr callbackData, StartPurchaseCallback callback); + + internal FetchSkusMethod FetchSkus; + + internal CountSkusMethod CountSkus; + + internal GetSkuMethod GetSku; + + internal GetSkuAtMethod GetSkuAt; + + internal FetchEntitlementsMethod FetchEntitlements; + + internal CountEntitlementsMethod CountEntitlements; + + internal GetEntitlementMethod GetEntitlement; + + internal GetEntitlementAtMethod GetEntitlementAt; + + internal HasSkuEntitlementMethod HasSkuEntitlement; + + internal StartPurchaseMethod StartPurchase; + } + + public delegate void FetchSkusHandler(Result result); + + public delegate void FetchEntitlementsHandler(Result result); + + public delegate void StartPurchaseHandler(Result result); + + public delegate void EntitlementCreateHandler(ref Entitlement entitlement); + + public delegate void EntitlementDeleteHandler(ref Entitlement entitlement); + + private IntPtr MethodsPtr; + + private Object MethodsStructure; + + private FFIMethods Methods + { + get + { + if (MethodsStructure == null) + { + MethodsStructure = Marshal.PtrToStructure(MethodsPtr, typeof(FFIMethods)); + } + return (FFIMethods)MethodsStructure; + } + + } + + public event EntitlementCreateHandler OnEntitlementCreate; + + public event EntitlementDeleteHandler OnEntitlementDelete; + + internal StoreManager(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.OnEntitlementCreate = OnEntitlementCreateImpl; + events.OnEntitlementDelete = OnEntitlementDeleteImpl; + Marshal.StructureToPtr(events, eventsPtr, false); + } + + [MonoPInvokeCallback] + private static void FetchSkusCallbackImpl(IntPtr ptr, Result result) + { + GCHandle h = GCHandle.FromIntPtr(ptr); + FetchSkusHandler callback = (FetchSkusHandler)h.Target; + h.Free(); + callback(result); + } + + public void FetchSkus(FetchSkusHandler callback) + { + GCHandle wrapped = GCHandle.Alloc(callback); + Methods.FetchSkus(MethodsPtr, GCHandle.ToIntPtr(wrapped), FetchSkusCallbackImpl); + } + + public Int32 CountSkus() + { + var ret = new Int32(); + Methods.CountSkus(MethodsPtr, ref ret); + return ret; + } + + public Sku GetSku(Int64 skuId) + { + var ret = new Sku(); + var res = Methods.GetSku(MethodsPtr, skuId, ref ret); + if (res != Result.Ok) + { + throw new ResultException(res); + } + return ret; + } + + public Sku GetSkuAt(Int32 index) + { + var ret = new Sku(); + var res = Methods.GetSkuAt(MethodsPtr, index, ref ret); + if (res != Result.Ok) + { + throw new ResultException(res); + } + return ret; + } + + [MonoPInvokeCallback] + private static void FetchEntitlementsCallbackImpl(IntPtr ptr, Result result) + { + GCHandle h = GCHandle.FromIntPtr(ptr); + FetchEntitlementsHandler callback = (FetchEntitlementsHandler)h.Target; + h.Free(); + callback(result); + } + + public void FetchEntitlements(FetchEntitlementsHandler callback) + { + GCHandle wrapped = GCHandle.Alloc(callback); + Methods.FetchEntitlements(MethodsPtr, GCHandle.ToIntPtr(wrapped), FetchEntitlementsCallbackImpl); + } + + public Int32 CountEntitlements() + { + var ret = new Int32(); + Methods.CountEntitlements(MethodsPtr, ref ret); + return ret; + } + + public Entitlement GetEntitlement(Int64 entitlementId) + { + var ret = new Entitlement(); + var res = Methods.GetEntitlement(MethodsPtr, entitlementId, ref ret); + if (res != Result.Ok) + { + throw new ResultException(res); + } + return ret; + } + + public Entitlement GetEntitlementAt(Int32 index) + { + var ret = new Entitlement(); + var res = Methods.GetEntitlementAt(MethodsPtr, index, ref ret); + if (res != Result.Ok) + { + throw new ResultException(res); + } + return ret; + } + + public bool HasSkuEntitlement(Int64 skuId) + { + var ret = new bool(); + var res = Methods.HasSkuEntitlement(MethodsPtr, skuId, ref ret); + if (res != Result.Ok) + { + throw new ResultException(res); + } + return ret; + } + + [MonoPInvokeCallback] + private static void StartPurchaseCallbackImpl(IntPtr ptr, Result result) + { + GCHandle h = GCHandle.FromIntPtr(ptr); + StartPurchaseHandler callback = (StartPurchaseHandler)h.Target; + h.Free(); + callback(result); + } + + public void StartPurchase(Int64 skuId, StartPurchaseHandler callback) + { + GCHandle wrapped = GCHandle.Alloc(callback); + Methods.StartPurchase(MethodsPtr, skuId, GCHandle.ToIntPtr(wrapped), StartPurchaseCallbackImpl); + } + + [MonoPInvokeCallback] + private static void OnEntitlementCreateImpl(IntPtr ptr, ref Entitlement entitlement) + { + GCHandle h = GCHandle.FromIntPtr(ptr); + Discord d = (Discord)h.Target; + if (d.StoreManagerInstance.OnEntitlementCreate != null) + { + d.StoreManagerInstance.OnEntitlementCreate.Invoke(ref entitlement); + } + } + + [MonoPInvokeCallback] + private static void OnEntitlementDeleteImpl(IntPtr ptr, ref Entitlement entitlement) + { + GCHandle h = GCHandle.FromIntPtr(ptr); + Discord d = (Discord)h.Target; + if (d.StoreManagerInstance.OnEntitlementDelete != null) + { + d.StoreManagerInstance.OnEntitlementDelete.Invoke(ref entitlement); + } + } + } + + public partial class VoiceManager + { + [StructLayout(LayoutKind.Sequential)] + internal partial struct FFIEvents + { + [UnmanagedFunctionPointer(CallingConvention.Cdecl)] + internal delegate void SettingsUpdateHandler(IntPtr ptr); + + internal SettingsUpdateHandler OnSettingsUpdate; + } + + [StructLayout(LayoutKind.Sequential)] + internal partial struct FFIMethods + { + [UnmanagedFunctionPointer(CallingConvention.Cdecl)] + internal delegate Result GetInputModeMethod(IntPtr methodsPtr, ref InputMode inputMode); + + [UnmanagedFunctionPointer(CallingConvention.Cdecl)] + internal delegate void SetInputModeCallback(IntPtr ptr, Result result); + + [UnmanagedFunctionPointer(CallingConvention.Cdecl)] + internal delegate void SetInputModeMethod(IntPtr methodsPtr, InputMode inputMode, IntPtr callbackData, SetInputModeCallback callback); + + [UnmanagedFunctionPointer(CallingConvention.Cdecl)] + internal delegate Result IsSelfMuteMethod(IntPtr methodsPtr, ref bool mute); + + [UnmanagedFunctionPointer(CallingConvention.Cdecl)] + internal delegate Result SetSelfMuteMethod(IntPtr methodsPtr, bool mute); + + [UnmanagedFunctionPointer(CallingConvention.Cdecl)] + internal delegate Result IsSelfDeafMethod(IntPtr methodsPtr, ref bool deaf); + + [UnmanagedFunctionPointer(CallingConvention.Cdecl)] + internal delegate Result SetSelfDeafMethod(IntPtr methodsPtr, bool deaf); + + [UnmanagedFunctionPointer(CallingConvention.Cdecl)] + internal delegate Result IsLocalMuteMethod(IntPtr methodsPtr, Int64 userId, ref bool mute); + + [UnmanagedFunctionPointer(CallingConvention.Cdecl)] + internal delegate Result SetLocalMuteMethod(IntPtr methodsPtr, Int64 userId, bool mute); + + [UnmanagedFunctionPointer(CallingConvention.Cdecl)] + internal delegate Result GetLocalVolumeMethod(IntPtr methodsPtr, Int64 userId, ref byte volume); + + [UnmanagedFunctionPointer(CallingConvention.Cdecl)] + internal delegate Result SetLocalVolumeMethod(IntPtr methodsPtr, Int64 userId, byte volume); + + internal GetInputModeMethod GetInputMode; + + internal SetInputModeMethod SetInputMode; + + internal IsSelfMuteMethod IsSelfMute; + + internal SetSelfMuteMethod SetSelfMute; + + internal IsSelfDeafMethod IsSelfDeaf; + + internal SetSelfDeafMethod SetSelfDeaf; + + internal IsLocalMuteMethod IsLocalMute; + + internal SetLocalMuteMethod SetLocalMute; + + internal GetLocalVolumeMethod GetLocalVolume; + + internal SetLocalVolumeMethod SetLocalVolume; + } + + public delegate void SetInputModeHandler(Result result); + + public delegate void SettingsUpdateHandler(); + + private IntPtr MethodsPtr; + + private Object MethodsStructure; + + private FFIMethods Methods + { + get + { + if (MethodsStructure == null) + { + MethodsStructure = Marshal.PtrToStructure(MethodsPtr, typeof(FFIMethods)); + } + return (FFIMethods)MethodsStructure; + } + + } + + public event SettingsUpdateHandler OnSettingsUpdate; + + internal VoiceManager(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.OnSettingsUpdate = OnSettingsUpdateImpl; + Marshal.StructureToPtr(events, eventsPtr, false); + } + + public InputMode GetInputMode() + { + var ret = new InputMode(); + var res = Methods.GetInputMode(MethodsPtr, ref ret); + if (res != Result.Ok) + { + throw new ResultException(res); + } + return ret; + } + + [MonoPInvokeCallback] + private static void SetInputModeCallbackImpl(IntPtr ptr, Result result) + { + GCHandle h = GCHandle.FromIntPtr(ptr); + SetInputModeHandler callback = (SetInputModeHandler)h.Target; + h.Free(); + callback(result); + } + + public void SetInputMode(InputMode inputMode, SetInputModeHandler callback) + { + GCHandle wrapped = GCHandle.Alloc(callback); + Methods.SetInputMode(MethodsPtr, inputMode, GCHandle.ToIntPtr(wrapped), SetInputModeCallbackImpl); + } + + public bool IsSelfMute() + { + var ret = new bool(); + var res = Methods.IsSelfMute(MethodsPtr, ref ret); + if (res != Result.Ok) + { + throw new ResultException(res); + } + return ret; + } + + public void SetSelfMute(bool mute) + { + var res = Methods.SetSelfMute(MethodsPtr, mute); + if (res != Result.Ok) + { + throw new ResultException(res); + } + } + + public bool IsSelfDeaf() + { + var ret = new bool(); + var res = Methods.IsSelfDeaf(MethodsPtr, ref ret); + if (res != Result.Ok) + { + throw new ResultException(res); + } + return ret; + } + + public void SetSelfDeaf(bool deaf) + { + var res = Methods.SetSelfDeaf(MethodsPtr, deaf); + if (res != Result.Ok) + { + throw new ResultException(res); + } + } + + public bool IsLocalMute(Int64 userId) + { + var ret = new bool(); + var res = Methods.IsLocalMute(MethodsPtr, userId, ref ret); + if (res != Result.Ok) + { + throw new ResultException(res); + } + return ret; + } + + public void SetLocalMute(Int64 userId, bool mute) + { + var res = Methods.SetLocalMute(MethodsPtr, userId, mute); + if (res != Result.Ok) + { + throw new ResultException(res); + } + } + + public byte GetLocalVolume(Int64 userId) + { + var ret = new byte(); + var res = Methods.GetLocalVolume(MethodsPtr, userId, ref ret); + if (res != Result.Ok) + { + throw new ResultException(res); + } + return ret; + } + + public void SetLocalVolume(Int64 userId, byte volume) + { + var res = Methods.SetLocalVolume(MethodsPtr, userId, volume); + if (res != Result.Ok) + { + throw new ResultException(res); + } + } + + [MonoPInvokeCallback] + private static void OnSettingsUpdateImpl(IntPtr ptr) + { + GCHandle h = GCHandle.FromIntPtr(ptr); + Discord d = (Discord)h.Target; + if (d.VoiceManagerInstance.OnSettingsUpdate != null) + { + d.VoiceManagerInstance.OnSettingsUpdate.Invoke(); + } + } + } + + public partial class AchievementManager + { + [StructLayout(LayoutKind.Sequential)] + internal partial struct FFIEvents + { + [UnmanagedFunctionPointer(CallingConvention.Cdecl)] + internal delegate void UserAchievementUpdateHandler(IntPtr ptr, ref UserAchievement userAchievement); + + internal UserAchievementUpdateHandler OnUserAchievementUpdate; + } + + [StructLayout(LayoutKind.Sequential)] + internal partial struct FFIMethods + { + [UnmanagedFunctionPointer(CallingConvention.Cdecl)] + internal delegate void SetUserAchievementCallback(IntPtr ptr, Result result); + + [UnmanagedFunctionPointer(CallingConvention.Cdecl)] + internal delegate void SetUserAchievementMethod(IntPtr methodsPtr, Int64 achievementId, byte percentComplete, IntPtr callbackData, SetUserAchievementCallback callback); + + [UnmanagedFunctionPointer(CallingConvention.Cdecl)] + internal delegate void FetchUserAchievementsCallback(IntPtr ptr, Result result); + + [UnmanagedFunctionPointer(CallingConvention.Cdecl)] + internal delegate void FetchUserAchievementsMethod(IntPtr methodsPtr, IntPtr callbackData, FetchUserAchievementsCallback callback); + + [UnmanagedFunctionPointer(CallingConvention.Cdecl)] + internal delegate void CountUserAchievementsMethod(IntPtr methodsPtr, ref Int32 count); + + [UnmanagedFunctionPointer(CallingConvention.Cdecl)] + internal delegate Result GetUserAchievementMethod(IntPtr methodsPtr, Int64 userAchievementId, ref UserAchievement userAchievement); + + [UnmanagedFunctionPointer(CallingConvention.Cdecl)] + internal delegate Result GetUserAchievementAtMethod(IntPtr methodsPtr, Int32 index, ref UserAchievement userAchievement); + + internal SetUserAchievementMethod SetUserAchievement; + + internal FetchUserAchievementsMethod FetchUserAchievements; + + internal CountUserAchievementsMethod CountUserAchievements; + + internal GetUserAchievementMethod GetUserAchievement; + + internal GetUserAchievementAtMethod GetUserAchievementAt; + } + + public delegate void SetUserAchievementHandler(Result result); + + public delegate void FetchUserAchievementsHandler(Result result); + + public delegate void UserAchievementUpdateHandler(ref UserAchievement userAchievement); + + private IntPtr MethodsPtr; + + private Object MethodsStructure; + + private FFIMethods Methods + { + get + { + if (MethodsStructure == null) + { + MethodsStructure = Marshal.PtrToStructure(MethodsPtr, typeof(FFIMethods)); + } + return (FFIMethods)MethodsStructure; + } + + } + + public event UserAchievementUpdateHandler OnUserAchievementUpdate; + + internal AchievementManager(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.OnUserAchievementUpdate = OnUserAchievementUpdateImpl; + Marshal.StructureToPtr(events, eventsPtr, false); + } + + [MonoPInvokeCallback] + private static void SetUserAchievementCallbackImpl(IntPtr ptr, Result result) + { + GCHandle h = GCHandle.FromIntPtr(ptr); + SetUserAchievementHandler callback = (SetUserAchievementHandler)h.Target; + h.Free(); + callback(result); + } + + public void SetUserAchievement(Int64 achievementId, byte percentComplete, SetUserAchievementHandler callback) + { + GCHandle wrapped = GCHandle.Alloc(callback); + Methods.SetUserAchievement(MethodsPtr, achievementId, percentComplete, GCHandle.ToIntPtr(wrapped), SetUserAchievementCallbackImpl); + } + + [MonoPInvokeCallback] + private static void FetchUserAchievementsCallbackImpl(IntPtr ptr, Result result) + { + GCHandle h = GCHandle.FromIntPtr(ptr); + FetchUserAchievementsHandler callback = (FetchUserAchievementsHandler)h.Target; + h.Free(); + callback(result); + } + + public void FetchUserAchievements(FetchUserAchievementsHandler callback) + { + GCHandle wrapped = GCHandle.Alloc(callback); + Methods.FetchUserAchievements(MethodsPtr, GCHandle.ToIntPtr(wrapped), FetchUserAchievementsCallbackImpl); + } + + public Int32 CountUserAchievements() + { + var ret = new Int32(); + Methods.CountUserAchievements(MethodsPtr, ref ret); + return ret; + } + + public UserAchievement GetUserAchievement(Int64 userAchievementId) + { + var ret = new UserAchievement(); + var res = Methods.GetUserAchievement(MethodsPtr, userAchievementId, ref ret); + if (res != Result.Ok) + { + throw new ResultException(res); + } + return ret; + } + + public UserAchievement GetUserAchievementAt(Int32 index) + { + var ret = new UserAchievement(); + var res = Methods.GetUserAchievementAt(MethodsPtr, index, ref ret); + if (res != Result.Ok) + { + throw new ResultException(res); + } + return ret; + } + + [MonoPInvokeCallback] + private static void OnUserAchievementUpdateImpl(IntPtr ptr, ref UserAchievement userAchievement) + { + GCHandle h = GCHandle.FromIntPtr(ptr); + Discord d = (Discord)h.Target; + if (d.AchievementManagerInstance.OnUserAchievementUpdate != null) + { + d.AchievementManagerInstance.OnUserAchievementUpdate.Invoke(ref userAchievement); + } + } + } +} diff --git a/DiscordGameSDK/ImageManager.cs b/DiscordGameSDK/ImageManager.cs new file mode 100644 index 0000000..292e230 --- /dev/null +++ b/DiscordGameSDK/ImageManager.cs @@ -0,0 +1,53 @@ +using System; +using System.Runtime.InteropServices; +#if UNITY_EDITOR || UNITY_STANDALONE +using UnityEngine; +#endif + +namespace Discord +{ + public partial struct ImageHandle + { + static public ImageHandle User(Int64 id) + { + return User(id, 128); + } + + static public ImageHandle User(Int64 id, UInt32 size) + { + return new ImageHandle + { + Type = ImageType.User, + Id = id, + Size = size, + }; + } + } + + public partial class ImageManager + { + public void Fetch(ImageHandle handle, FetchHandler callback) + { + Fetch(handle, false, callback); + } + + public byte[] GetData(ImageHandle handle) + { + var dimensions = GetDimensions(handle); + var data = new byte[dimensions.Width * dimensions.Height * 4]; + GetData(handle, data); + return data; + } + +#if UNITY_EDITOR || UNITY_STANDALONE + public Texture2D GetTexture(ImageHandle handle) + { + var dimensions = GetDimensions(handle); + var texture = new Texture2D((int)dimensions.Width, (int)dimensions.Height, TextureFormat.RGBA32, false, true); + texture.LoadRawTextureData(GetData(handle)); + texture.Apply(); + return texture; + } +#endif + } +} diff --git a/DiscordGameSDK/LobbyManager.cs b/DiscordGameSDK/LobbyManager.cs new file mode 100644 index 0000000..c914ba8 --- /dev/null +++ b/DiscordGameSDK/LobbyManager.cs @@ -0,0 +1,26 @@ +using System; +using System.Runtime.InteropServices; +using System.Collections.Generic; +using System.Text; + +namespace Discord +{ + public partial class LobbyManager + { + public IEnumerable GetMemberUsers(Int64 lobbyID) + { + var memberCount = MemberCount(lobbyID); + var members = new List(); + for (var i = 0; i < memberCount; i++) + { + members.Add(GetMemberUser(lobbyID, GetMemberUserId(lobbyID, i))); + } + return members; + } + + public void SendLobbyMessage(Int64 lobbyID, string data, SendLobbyMessageHandler handler) + { + SendLobbyMessage(lobbyID, Encoding.UTF8.GetBytes(data), handler); + } + } +} diff --git a/DiscordGameSDK/StorageManager.cs b/DiscordGameSDK/StorageManager.cs new file mode 100644 index 0000000..65cfe72 --- /dev/null +++ b/DiscordGameSDK/StorageManager.cs @@ -0,0 +1,20 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace Discord +{ + public partial class StorageManager + { + public IEnumerable Files() + { + var fileCount = Count(); + var files = new List(); + for (var i = 0; i < fileCount; i++) + { + files.Add(StatAt(i)); + } + return files; + } + } +} diff --git a/DiscordGameSDK/StoreManager.cs b/DiscordGameSDK/StoreManager.cs new file mode 100644 index 0000000..4864576 --- /dev/null +++ b/DiscordGameSDK/StoreManager.cs @@ -0,0 +1,32 @@ +using System; +using System.Runtime.InteropServices; +using System.Collections.Generic; +using System.Text; + +namespace Discord +{ + public partial class StoreManager + { + public IEnumerable GetEntitlements() + { + var count = CountEntitlements(); + var entitlements = new List(); + for (var i = 0; i < count; i++) + { + entitlements.Add(GetEntitlementAt(i)); + } + return entitlements; + } + + public IEnumerable GetSkus() + { + var count = CountSkus(); + var skus = new List(); + for (var i = 0; i < count; i++) + { + skus.Add(GetSkuAt(i)); + } + return skus; + } + } +} diff --git a/DiscordManager.cs b/DiscordManager.cs new file mode 100644 index 0000000..5c1b401 --- /dev/null +++ b/DiscordManager.cs @@ -0,0 +1,37 @@ +using Discord; + +namespace CSGODiscordRP; + +public class DiscordManager +{ + public static Discord.Discord discord = new( 872181511334543370, (ulong)CreateFlags.NoRequireDiscord ); + + public static void Start() + { + Action action = () => discord.RunCallbacks(); + Task task = Task.Run( action ); + } + + public static void UpdateDiscordActivity() + { + var activity = new Activity + { + State = "Test", + Details = "Hello world!", + }; + + var activityManager = discord.GetActivityManager(); + + activityManager.UpdateActivity( activity, ( result ) => + { + if ( result == Result.Ok ) + { + Console.WriteLine( "Success!" ); + } + else + { + Console.WriteLine( "Failed" ); + } + } ); + } +} diff --git a/HttpServer.cs b/HttpServer.cs new file mode 100644 index 0000000..9cb32b9 --- /dev/null +++ b/HttpServer.cs @@ -0,0 +1,70 @@ +using System.Net; +using System.Text; +using Newtonsoft.Json; + +namespace CSGODiscordRP; + +public class HttpServer +{ + public static HttpListener Listener = new(); + public static readonly string Url = "http://localhost:3000/"; + + public static void Start() + { + Listener.Prefixes.Add( Url ); + Listener.Start(); + Console.WriteLine( $"Listening for data on {Url}" ); + + // Handle requests. + Task ListenTask = HandleRequests(); + ListenTask.GetAwaiter().GetResult(); + + Listener.Close(); + } + + public static async Task HandleRequests() + { + bool IsRunning = true; + + while ( IsRunning ) + { + string RawData; + string JSONData = "{ 'info': 'No Data' }"; + + HttpListenerContext Context = await Listener.GetContextAsync(); + HttpListenerRequest Request = Context.Request; + HttpListenerResponse Response = Context.Response; + + if ( Request.HttpMethod == "POST" ) + { + Console.WriteLine( "Incoming data..." ); + + using ( var Reader = new StreamReader( Request.InputStream, Request.ContentEncoding ) ) + { + RawData = Reader.ReadToEnd(); + } + + JSONData = JsonConvert.SerializeObject( RawData ); + + Console.WriteLine( JSONData ); + } + // Enable manual shutdown through a browser. + else if ( Request.HttpMethod == "GET" && Request.Url.AbsolutePath == "/shutdown" ) + { + Console.WriteLine( "Shutdown requested." ); + IsRunning = false; + } + + byte[] Data = Encoding.UTF8.GetBytes( JSONData ); + + Response.ContentType = "application/json"; + Response.ContentEncoding = Encoding.UTF8; + Response.ContentLength64 = Data.LongLength; + + // Write out the data. + await Response.OutputStream.WriteAsync( Data ); + DiscordManager.UpdateDiscordActivity(); + Response.Close(); + } + } +} diff --git a/Program.cs b/Program.cs new file mode 100644 index 0000000..db44122 --- /dev/null +++ b/Program.cs @@ -0,0 +1,10 @@ +namespace CSGODiscordRP; + +public class Program +{ + public static void Main( string[] args ) + { + DiscordManager.Start(); + HttpServer.Start(); + } +} diff --git a/favicon.ico b/favicon.ico new file mode 100644 index 0000000000000000000000000000000000000000..ae807a27a98ed709693809b3d5795107e5d159f9 GIT binary patch literal 110292 zcmeG_2V9Nc`?oSeQC7n!vO|%qP)J3{UZIRKN|{+{pdyi^s5GburGe7WFj5I=Pwl<; z?){(V`o8|xb#L8!yXE%%eb49f-t)fazVA8DInNo-dCoHk1UA9|0uK)X#lnQc{Rjkg z0)Zeb{PWojrGG_f;^O~2PbLs_MiB@yGC!ZEtsoG_OA!bL2LC*BvJvDip$t%f{M4rt z2wFyLglXs*Wrb3HrlW{JK>3mf%e?~F&x;?63x0&fhd5(*_VE3aCV*M*7s7JmLa?N= zR!r9M2R8U}JT`>n!oRmr9)$%voWTlGBQZM-QIrQiF^{_{f>_!o56m#M3>#<=_uIFS z&#&)ykHTKx-iNg|H)26{$1#iDqtSo-*nRa$SaDhucJ*Bu#@WgDP@es<*;rXlB9{E& zIWb>IvpX^!tIAKpEF&whL59D>PFg;|aR-$d`tUqfS5b($Us;b?D38RRUtWhbRu*6m zUn~EpJNfq(s17eoHe>B=Em&%VH}?4A3am6M4(q@$OzU-ir|{$DKQmZ^wKUdZ%?&kJ zML|0H62p>9o3N?3Q)q(!nZatTslJ-{9sIPkbzsMR3n+d|4nN@i;i-jKZF#}3?`xae zvEA-D7$=3c`{VoFe3MK2Wf9iV0hq_Is>U{~q^=dqt8T%3Q){rh5oMT) zM=mzkI_;0|A-}t-V=(9k1u2ol?}LBTVJjSdV6*S0V&Yb5*n<1%*i6e*3}7HHAAg2= zeD$>^e(#l7O@tN358x3lybZ|b1A3ofo)Jcu47y*L0#XuT>3RuOS2QuIwJOK{UZI&YXA6Ouol&}Vq#XQUG_U12GV>;@1cBW9Vx7~ z;^&;((o~Q7;RXu*5Uqu3B4~Y$BG$jOz73mqFOA}yikC?mla@(-e^+%Z_C3&^m~Tf% zJ6gw2|5-j7dp7EmvBLB(#P@2N+A-+|85Gwv(sJ>8@-j)Ef40FAtg`3_G4J9Z-~YkE z|Mx>!n~1bX;s@e8O=#?|N9zG4ngTDAG$t*N(mjmr$QL*MX@d^b9uC;OgA>vG%1`W% z574^u*~bE{tv}Z$SXVbaW?uO~?}R@yCYBFBtxXM>*Y)kh^$5mj^vgRa_2+s5|7TP* z6W0JrG!1FJ@q0>jCQXB}4YUtwi1D{0);+-H7@|jNN&mvk!%Jx%`v3!JS(NUf{MTr1 zYj11)RZdN5F81w>4RI~~m56RC(R#WZt%sE8LA<`?F{Ls|)9|?!Xt&?OKWjK?nkQOM zhZ`p_z5e9wPg*8^UySGoIYfidQ+Hb0ANoJ^x0c2_yr@6ow)PI}LSPYH^~Ui)+SZir ziL~d*`H1$+|D#+yA*ZSZld;dBX}!hE#bZiklBVHvP<>S~UfdsXE2@87Q6n}B(O$HU zJKD=1jc5^|oy-3ymox$9oy||OX`c7!Dc{Fz7uM259sf8SM_=X>%ZE0==}5dBYB6bB zQ@V%o=WBTo>p-+kSK*Z3&;86K^JGjA(ON2JY0&>+&(~G`Vcoxo#(=|@3L*^_ znpuY}v`Oz02GX)9-9!0LbXQ_EWqD|t|NnWOye)v{twVb<(g3hfYj-@IQkmpwu)ca2 zZN#dJvq-b=@*Ze0(L0@w3G%WiJ;Q$8=Fk+Z1nrq=2|$C?p}k!_x>h3IL}#=BrSkqv z0~%}6FB+>W7_!lP6kptk!Mvz}#>4=$zXBNGBHe4j{hww1KMhL$AFO$_1XL^r{Q&~Z zjc5G}F&LYgukx`qk1~nK{z z`)NNfL<<8wEP?jaQnu;XA@4kF*wuuec%ZZW0VZgN+dGFNUVtun6JU?NRsP&h|Ff6I z_tba{JhD+HiNB3W%Jrn)2jG3+C%v}VkF~Y_PLsgCv#WWR8lR3HIAA{F?I^G7<$!}jo04DW}qj%`3~-`N^Y3MaMu zKgvP#D0v#}H6EQ_gjE%1{%SkmIeT5-)+zsuG@qZm@&y>|Q6a#32Yi4i24{hgoTmqeMq~V|wW8j&)o|mD@ zf5c&j80LU4udROj-r`dk!{Zk3Po!mZb`N8KbPmD+`SjeR6aMAzeKG07PrfVut#xF1 z@4=7y&{IA6Kh9e65NqUp%NrbYVr-B0A>?!i-mbL9ot639f2jR! z(EI^w7iq{#3jf8o`|W+Qc>vbCocJ)(PcgUHDvS%Asn7~5rT023ll(tegI<~M{f+0+ zR98vl|H6Od?~^_g;g1Xb4Sqj#w#0*IUP^G$nnqei*Z2Gw@Wk=+100yNNFRiQ3793q z5%oOyv4pV4_$S2pQ%*fL`Wo$L3Y6+Zy}aMY9{wJ*^OKAJ?7RPg2G(WZMRbM(I3vK% z=kQ7ZZ)n_&-_I8*!Pr?E4i~*~e25DU1~INK$;Nzc?xr}GhB)eA#hKrKB>+$6w}9X1I#~DcvsL(?JOCdA&O|$dudDy)ZFhJd&TFC1 zlZS@tQexkNegtctgO)f3^DCtQ`)AlE)63T-uMZ>e18m;|exCo3!}js%RqXbz5yUki z>HSmkzkfY@Cskv-M%|lxpe~HS5BubgZdZQ6LV8n@6^nV_*onmlI}_zHNdLp{fv>y& zMQ*ogABN#aw3z=rjoIcFo{(Sd9ZHF)SvXJq_B{{h(# z@-xQHDg-QYqtIfe!Hw6GA^6e!`S8?&UuXE8!HxfyQr3h`MlxO9o$qnD@t9HgVLuFV zZ?p!GWpesjfl1kQEqjB*MoY{P{HXtctX*Sm1+C!!dhbz8Ww&X5(t0rpKgjKY%pbks zb6x``aJ_ppGc(|Ss;|IM`@;bKKpjQruw5=)KGXy{C z|G^=o=T<0YbPvD?{J@LyzjySP3>H20fOD_;NFI_O?HhrAXcAU} zX`%BkTF-^aalk12-ljXyIZZP?pku&u1D@@fH-#ANeL=<)0-PtlKr$vmX0*$<;q_n$ ze$;P4%P+eM{tqKkCWB~c)yImjei5<*y+SPtg`T@-UB1>L*K#Y zQTQJA_LoD7iL#R7NM09Y?m}}2n=v2Rf z`heUK$o}E-72#;Tu!}Co&Ic4?I!NvV_Rz4FFb?-m{wR)vqJQLksRH%S9|bk7SX$Xn zc@P-8pf3Vz0$f#1ZA9G%(0{=1L3R@^sFT@;Qj8C^IkY{*z00nU+P-#Vf5 zfe%=AZ18XA^`v#WfnX3pyc5vLFh}jT+#!QV4*^XCdIhk*k+Mt279p7uxIms}F^b`= z2J|uTxfS|;cl$qS-JuTfY_)GZ=5|T$51ksk4$vRAx@BV`NLB#$0i-k>PRkKvqW%r& ze<0cp!K#4HDxtr_J?R)Gg@GCOFsDAhy!N*<4jgtoHho`0oFmC$A%%2#5lals#j&49^;3gWgAd8K|(cSYqGI5~)9(%b3Ku${rT?Xj-C8q@mWP!AQba{{V z_aIkV{3C|6`w;IxJh@ENvFI`nG#68Q2j)1?%c6yU@I1b%+h?@U*QvomEgjC-D4kJ- zIGyc&{n7XY{w=lrBgm`+O?(ycYsJu-NzXiwk8ARnT0N?y82<;qzi1cot50k!2?>&sKNKdoh@&;Y!?#iQ3YX^GagZF`s z06sOY!-oS4a&us3pmTW@>hnLIH~GGgC=Z3kJheJ>C!MkS^I>6+E@JIuIyNvT!aM-& z!$`jH4XiKe(Xa6)CC0W$PMz7~9&a;-;6!7TRDYZl*!<)OB8|XEAAqp~IujtjNE$#M zi164@)EH*ae4Cvd(Fwi;mFr=?ExyhAUH`1`O1#s)dzRsJo8J+8~y zB{a*g;(0>5;~#{kSLzsui2I{*)C zDdHmm{{@GeSuwr!#@{FMGthcZO}`85anMT-f{mY)PoAWxC*Ffz9`F{J#Ty}QJG?#& z#b_M>Ic;>(@CVFMo;T^Hg@C`3@x||tyy&$NKw7`9?is50KlJd=y?_|S{cuHoD&}-j zlCC)b>Yo<%@{jrhFMc1BJRoZC{T4rxO+w6@b_BZhpA>+JbAc>bB! z=}m)m0Q9gxSAbf8{gUNgGMX6G|DCh$A9~5;c?2Nd51i{UgWpHq7WCGY;`^u`)cC@9 zT`CJRh;0OI1$jWfe|c*U)$=&~J2;!zgY4$@1nmQDL9spz^n;({KNtu5j~L|718ud4 zYXR6pe4;D+2M_U&k5Ixlq)Q@1W^0cehuwK*R{bF#kQ?eOj!*&(5oZWl_r0O^cnb`a7Nw}>mJ@`n1z4X>x4eKKni}h@7?06 zh_)wiSbHL7R{cR=xHG*TdK&}wyo%15J+kJLwj*=u|C0vJPyR%2HL1Q2GVwjd^JaSe ziR&M->6iMMYJKSWBcY^;c)r(@^B&#?%)vjRe~}(A@c+9TK*nkN)9fDMb>Vd;jhR({ znEyeivNIZrh4D<N^dS#J!wA3tT*X{{%<_dq7O zC-(c~V}x1w2mT)H>*}ljXBF|AEXO$k>C-HnZjiX4Ri46NT)ZGb4ar1Ms`SEcTrRA$dUWT%lgM^!cWESM)gNqjf?or7 zz$3*2^a;?fWON;5cD*4#-~|Ld zIPr%ZD-JWGF`yl216;2i&nGye7MpN0nP^KKXd=)@1{-R)%rJ}(YFAIxpC}KYJr^s> zO~yg&(HL~Ifp-XdX3!OQgX9H(hXy{q41jbP7sz{CuWXZq}9LQAlMExO8 zXoL5zdfl=Cz>G$NJ_BcI*WQ&7eG7nX-UFU_L|t##SM*%{kuJ}XX%y`-c2zI1cL28N zz&9E2Lm>c;K@J9<@eBM{;1|pdHTZ?yPITvTv|1fURM$CD~PgJ?^H*^!w)_ zuOs-W1RoOA_$4@ey%M7~069Qf{jz}n5o&lNuP3$Vu6RYgQg4#I1lVDqWTTe6KLBmF z$DKL0M5(n6r1y6Hflv4jt&3d+utxzlGI~<>=daWs(FGtE5Bidw1+XCwG#s^Y+Zj&j z`LDO}59L800R50ZeB}MpAfWFCHc?>g;<5nXBc{8&4odApW)9%L$N#Yw06P%|P-iw0 zI}z|e7J6fxSc6|!WMhby06uoXcM2t$`rd$*ybORN4%ta!W?+UN2ufp~ku>u9_Qdl~ zUl@Pte^F{v@ONW-cv_cwB|QNrr95Fy|LI$n614QE0iOf*>x}Ys7{PI8-%zSEv(tcQ z@YVMoY}vaEAU}@#6=pUZjN}J=e`>b#yQ~b!3$XWt^S>iL`NZ@8o~C~~!#U}HjI;^8 z-@yJ5d~JXa`K|)!S^=M(-ZFaX{qCH918*lXw;lugZL1J}1Gf{&D!7M!&{OS3nlG%O zc4&W0i_OFzUjvA?GDyGwoA-c!&}V8V^D)^~KZbqogXjvPtOxA%fS1Ecc*o~}-fCM| zN5Pg@R{>wjoRXPqTT zj=G?;W+Telu@e44{tpxyEYBpiWD^P*XaKW#0Pv~?r1K;F%;PvZ`7}kJrqFoX4R{Q^F;Gx6$T32=j zdIMg(44_}VZ|tH;1{`cmDP4V`_<3{A;)eCIxp}iN~`IDSUGV5Ew zKb&pVl;zE#6W`={QNvSDrNiDX`laO`cE<5`{4GWTq2bSs|2qC*&U$UJzf+j&5dLM6+*)7R z_u>7Zr|?WEUl{w~#}R0JT0>QFCXx1rIhazOy^#iGfAzcHDadfHx8@Obc|5$mSuO63 z_QT77am0upK=85sxAud?wIBK1D$h&l6#u~QhjZQT%Jubj|G;t68}U#4@1)xgWKsH8 zqI~7w;0e)6uR`ZQwv9TNp}X0eeV{k+j+X&r*iBCkgZ&*n0nUx#3=a55cwW5~1J5GH z-;O45!B_8$JIwRd+Z+9$x7zV%IsDjtH4zNxdU^x+=lUBwA&_g%{1!kHxS*HOQ})bz zsxR~|{(tI_1>2vdTYm`bFFAwl{odpU{B!n4$uAbA4$*-20P;wer7zI{y^VjMr$A?> zET?lGFs1f=@2cOcbRZE{?Kw!dDU%X7f26@4V09nc1N1ijp*$GFK-1G3@>3#-XYsv7 z2mU|bhc??s|KY!LA5eH-gK-7?baG#7UG)d>Mc{kqK(En(K(B&7EU^7SO91`ObuPVQ z-;G)H0FIO1j-d~PKQp4GS$}&6bj-jeDcB|HX_#TZ(V5@I-vC1o;Ll_;vhVZX`rq|D z0Q+jsYg=iO2_|i4&@qOyc<4Vpj(-H>D|3}j`M#vEA@pO)&%0;0gIVL6)_i)p4XNc1 zJ|ldPObsRfGNf%vexIB8q1W_7ppU*G`fa00b%6+~npfU`g1ihgn0Q1u)_v@X)LjEV%_GCpp9~|H0@!!HbdAZHVe?=}|M_XZm;jN+s>zoQpVJ@!6oYd9OG#fB7)i_)9~x_$A|13$g| ze}L;pMKdD`&f`RX{Yx@f80nuk9o2|$X_#}M*#OQAEifkZqtz*IIv$o|9;QgcVpHX z!3chO@*8M-C**IdoMxH}*;IY|5OYL!d11Zo7Ht2lL7?jeKA)f;(rfpjyrHdE?EC#& z@elZebs+qiG5OG<`V6{6XddYBN4$DQ`GU}QK<_x^lP3ne2=Mm@zJ2Kp;M-N=URs~w z0d;G<(8A|u;2og5KDl3`x9N#<2J9mlq6ZNE!OjySI41=(rL2kQ%jduKpLQPbZ+#HP zAvzZ-Op7LMR+{c%9tg5KK{qV`^9|^n)5C+L2GH~Pp7(9cthpcZ`K|347^}?w9>)IT z3o;D*o6Lyz#jKFMNm}88c^`b-XT}6lLn+PaApgj0#b4Iq%ke{=iiFQ^0>O8Q#*mQ;17JYf-eEP zqcbpHivx(Ce;fHIqg~F7mNJ0u10UXfN#={y$3G+I?v!u^yj(a(NC{iNd_zwhm} zou={-{=w%sE&c*1;ib3ItRu_%EZxV__(wb-knaXQ4yy)`^8lZueR=L@-T9vn^Dx?g zRhMM5D*7?k@0D0zv-O0JdD57s`M8(Q1%WpUHX>Oyz}N@>#C?72v+DQ<-TwFx7gj|- z2J3!L`0OMdm%Vk*isSz-vJsvf?!l7y2cPA$kZ+g1O!JfWEmp)oz(kKeSZ{R{u<^Vf z`JC@d`kkb>rgYDG`2VQ~0(Kr)E!cc6$9Q_dcQqwE^;8<`;s58}FD>dNOQHWmc0DFy zp8T(w_woM3iui}~U(ah>Fk0;{_H;)nsA>Jz(EB*v@t76y4=`Em8cFmMf?>4V-sy>c z06tvL`WJTmTj)I;?|96z_($ipL|gGK%{_run)CEat@$a}W!N|Ld2zhb8nY_?fd>S( z!ok+V-wG8-mrDWJ^ZhsQd8qXVmc>7!0Un)M%&;6dGy2TS;eAv_y@T@knOsS`oT80>^>{w)7d=5 zvg04t|4Xar@)gC{WiB)A6E&cRY=i@$Yw6y<0Ni z-NiMf?`_c;Kwp*h#c@s=voihzZM7+(;IF3jHT!;~xTbW^%J>g)I{Q~~O{s9O?>6Oj z-?8sT3Fo9~tc?G6&bpLP@K@8o$J??8eP8Yq?*pui{|`?L|0=F26%OY?+xwuNKaOwm zm}T*g_Wxejw=qQrgc2URlcx3h-?Il`Rs7o=nu>uvx0fA?7XY~-&=p{1elbhppQ!&2emBy38kG#?|2ePW4_j}5V;tY${{?&itaSK+Ng`X& z!%<&hRh=v!Vme^mU?o{HR>eQ7=>UU`$D=RvF?PLJ;<`WAIt|kgF2Z688;O3u zso|Y8y&2huet`ClV@z4cKNPFtALReOy|E!}zQ2Bd=TjM`=$zT{@LL6OerH581^UrV zZbNz@_?l2^xnf-0CXWM(1fgw|9kW{ZJ&An^c&Xj z6VBTBXRYzi%+B>9fi?WZvM&BdBRjqH`CeuwetJ4DR`C{-P3KS(4l-f3`)MY2Tb9I-cXPFhx9!+(_5%}(2sRsICr8;6y2 zyg~MZItyS^@Nb?6_9gsV>>fpzU+~V_y{G>RQ+g;{Kyj)C4dwQ&7?$zPQv?^F0^ zak)@Z9LEfwLj-(cRk=y{B2mh@(ps(TojnyHR(+Q`BTS!0srV!hTY{xVp z+rg9q&<74*Dt`KqLh?bRYjbbh_a*!T5AgZrwM_NjMhPd(OaprXAQRSv`~y=9ZAd7< z9LWTLKZ)L!59?F-NBke~=~$YRK&>hJY&x6=>~YWObz6gd3I9J~*a8LY+{YRdcUSnmvQ*e~k% z7lO@U>|8)0ruVi8(?^#fT0=|_EqU!-2?qLyV4LtBqAx)v5$J@@`U3D5@C)RWM$+D&-|BF*@6L$0eg)H(G?xeF_oAL$py0N?(tQ`>p6-8 z(rdBE+y)Hxr=QT(7xDj-4qW%IodX!{ykMIG{L@4s{S?40*eZI9_{;ujwHVm4^*}O5 zpt}Te?5Sl<#H%mjA7BO@@t8NZj5gK3^1E`Re*iuSLB{}ekYKI{ee{&VGRIZ z#S@Uuf)LVSfUB?KAI<`uPR_?lvSR<0xMZYKF#fe)|MW*pZ68Ub{r;gFfp+Yx_y@RQ z9RM3KwdDnjG#B09fd3~ruX}~&QkY{wjvLY#3BV1Yc%ek#2~oNLzvNdNyodt$A_l*7 z>s_+w;wAQF{1f{C;tBYe?ZV1(lZfrmlRxhfA6MXd5;hdgr~KCwiGJWVJ9|N#qy&gl|EICZf+Z$Sy>)cc>w`pM#!%UPza$1NZ>D$u8yRIUQhw8hDBL zwfRXl=#*iNh_?j(NMR2^FCV$DvCUwsnx@bp4tJ6w*)CvZI{joBQYig}st=(a6spqoK&W4cAk zFTM-3xfPms!A`i8T?UbNLr?p6=Uw0d&A*?HRUtd&h78)I`nTZ!|Leg|><2&_{Jeh3 z5J$YY(Ve0H+qbax<1%|dLoGly!C}q@+L{{O)g3%j`xfvof%M2S(fR}H0L(Ge-ldlQ z|LxYh{vCR=T<|6T3!d`D4>I0yY&Pe&aiHE;a)=z(; z1*uWpMfq>vgAOo`gTEcaJiy2~0KolsaMGJ|%|G}@bRjcCFtYIh{FT3r`|g(i@5ld7 zf3iQm`ZE*#L_TU~HlVtTm)`pRe*yo%D~$1HF0a@N?fHNY&|7%wsdD}o@DDnKfi}mO zDmP{k&e(ptr|`&VzW)pO2YZ4pXP07i6@^S$1Aygv0P*e^*>5q5r=I%me*yncN7w_V zguh@4{=v4}9K?5Hgx}Uvcw{u+{}ucLF9>YPHaFIGyAJ@b9nMr4ZF5%o?tcaUKj(n) zSbT^}xA0$x{6MZic0D-_>F2ev65erG{+I9%`v5p6g7YAH1DvuZmo{O0J#zmQ1d+5^Cs!Gpi0WG!_{*?l&om+iofA+~&_MM|DUcfbF$ll>Qh7TW} zTsGz4OC_I4N_W1nEt-FR{=n4{!>^sl3L6{#geyEe*+*^X)H`RsDhPf#JoL-=xU&hZ zY0?)Cn%@#wCzP-?uDx}M`5f~lC3=BRN|Yr08!U}P0F|N`wb%~C=h6)@`Y^q*9Y}*Jg^j6>DB^;5f2$2v~bLDjB ze57id)}QC==IFyuxpR{$LVkR=6C%7*tdL1+?GSja@nc}@I)idWeS<}3Enl+V<@SB4 zD#h(95hpFxT6@i7N8v63^a~pR6R= zvIh+(j9NSAz-oo`ss>)H!f(C6Rht+?{!IVKS~&43RzAkR(CY=dv*`*&Ne`6SGi z#f{)Kj%eLl8f`Q})n;H8AnB@&Mbr*0z60xLNEp>cjJdsxpnZFs;EZdV%q${Z(mvkb ztdqkv_rQ~bBeRBcZHo(>Fv8GH*LflOP5|vx+-dR>tJ$3{AC_HsMsMuY0iV3pZ2S^A+@eRy zoo%1>>DIE zeg-Df)bAVL@;kQI%slh0gP%u{lg5{_I7tpRM?+%;p67vr)uA^<#pheCSQmP_HP?U( z3redBPW^bVP1CJZ?v}eQ9~+m|tqJEVB)#n4My>SrN#(Q^>zAQ2M18iRq6~Ye$ld*~ z7Q|=0tV}T-mf<6qZQ$vo5+ZjsTp_01oP!{~V%^I&z5(~29O9U(uz>gQ+lo7moM*J3 ztP;}eC%i((eb^;)UCzXVnAvSrgHbPiYMUJH@0=cWQLtw0)Y0D>stwL-ojY0W6knV) z_5HA=@wYQuM=fU$<G!x@H^ka= z_MFarHq`IN=1r1IrD9Gd33*ATC<(I{>oq+ZSGB;yIOWaQfRNF7LkwQ|Ye>1Y@*GY( z_fbd$Ytf%@cGHB)&9Wx_C&Zr_G1vLiL!Z@db(7qmh7||jj&*J@>5$u|_U5Y1MwJnv zDta|qL6<&n^1C6j!-#S?e-ti``wqG?8^8x<%Frhqb3=?jM$YDfc4AeV{c&uXvlP zY>b)kN{JWe4`>)WPWQWAGDBLCvoU?p7fzq3wcqol5d>4#%&|TjUmNH*>z)pF`CY{B zg&%b;jO|w*RU8!@I!ftC>?PgiGP&4wQ(`lBnK%iowOuZ};^c9m;cvy(ig5(zy)Bel zv!L+Xy73*ecc>MAS^q&`5+TaSpw(}d{MpSP%I{oT;v#RJUFIi!E81xD_KJi3*o&v^ z*{eA9OGJ5zMC~^-fki*9%E#*sUrrowNP|I3yI{oF5L0o%+D~u*Cs#kh%jRiE7 zRn?ZqwQq@DCw0ClkYBf?*30t1))TcHn>da?c&KsM!?Gk~^E?%v;DA-CqV{Quo-&)K zI(*EEb2J$xJ?w7v@%4VI2@9j+&%`J7OP?*5uj=q)?7Xwb<(v)-87mZZCs8IMGi+L?Ve#PV62|FA*ixBJ{nx1g1ZCZ4|WZ{XoD^|YuRpJZM+AF~x z6D=NfhQ}l+!m3z!fU2P2TIYaNtMx-(y;zy?*nG~*o3^fJPvxSQm+Uh+Ej>>{H}d-D z1lf|uLq#SY-a6N1%d)F2rP6Ftl414A%Z4tE-_aymyiDFNqhawN!qhogjm1@~xt;QK zEruQqY*aF>d=sY|^QC0Zqgm?+CPz+xoIm`L?3(WyO1491ZP;#auCG8?XlfzVE^pbd zYM#iZw?ke}B8)9)EEb>FZ2LBvuXxfkpFuKwkyg{6If%s$jlJ|SB!+zwTh=t=;<$&3 z+@W!1$A?64Itj|N=S7|75m~^i&_W1WH%xMQt^9_YmTV}mDNppzJC1iV;?;5I|^ z(Cvk-gXf6)-N-@Y;-hB=4;0>BtiK@@i_25y**ZA|6Le4ZH}%Jq_0GC@Z9o>oAcmenFN71$paHln)z1w zbNSoCP2Z$M&C1(n_*fotMep^KF+AuQ;=j|I&BbIWqPA}3JaG`wkDDR8J;S`nc3_tF zUgd^aZ}xw32yObIe}$`k&l+|oVKajxp)r#Q>Xzddu}htwaMt)(Gt zoJKhsh~dL@IV`nxg~EKl><+BpxaJ;YuKW7Nnq?B^%-A_Y)^sC#wDLK->@56*Lw|r@3o)9z~|(Gg&SXtSidvE%<=J4OR4EP zWvdTP{U$Rk-kbNR%cikS`zFhsYih>6y#I!It520v(CT<@NtkB9e&ExY8z)*@v=AnC zy4WF7dHL!3c5$?akUnE^|oaguVDm1bVzY+tA${?`H;Yn zwH*Zsh_)--(5TaIS7Mmk5s@!^{S-Jvhv?|`s}3%l<69_t%~6kc!?pzNx;ZMt3Fr3{ z^ft>Y?%AQ$u_Qmicj`DFT|&%Ky=`3G@ga6+ZlEP&g@lIcRC$Z>i%ije zXT!D&0q-|HYpb2ic3VtcmVJt?#!9Vw2g5cNPZw7{-!bb#?UAohmnF|z`;0gwerkcx z#92vZx1Z?!m_(>?;Xiz>-$tRKZ}!~nFR!+rAUZPPq-}*5kL!dpu1n@fq?W#S8x*xy zzu6~lj6MCI*P_Dm}<4 zuHvrg7JWDEBhNhxLIj7zft?qZ9({juyiD*8wI^o>-ifljr$ETNVla8u>lihW+dzKD3eq6jT{=+{nQOy ztEIJ5BK5rPSd8$rAWXZhmZqSVciBNmPA6xcx>nAFpyljNJa+@{+UzXpsCDw0o~KjI zyBCpp!mj+*9(fk?hs{`Os9E-4Y*g{`nlaM}Y+j>8>|eVM5FfTplLvLRx$Id>(Hy!d zI%0=!JfUEMgx(ClkvrrRm&mg_$(RZ}b)USwZi$PDxtGseExwhzjnMRTcmJfgW~~!@ zF6~HB;1-%9z*aQ{;eL+9@FONF4+b{Gr8tEr>YG!_R zEm&8hJe~i*jLGGx8mos18QR+l7Zd7;-*b4opf@KC+$-Xnf3ar9AcKh?hM(N`Z8F+R zq1jb#3gP_yHg!{Ro3-yZos3UNnAEDW3TxD}i4)O|IP!Mgj%^a6%M*5)sMR#m=%S9-y#Av{4>CaW!-dq6DvPwFnpoe(em8OjE_fO4s%YDT zc8EJ{*@u{L_f3Ew=0gpRZ?yd&Q5C=bUGbITtAF-x%oFu_W2r(twZsDO+CH zHnTC?�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 ILiO_h0piR2VgLXD literal 0 HcmV?d00001 diff --git a/gamestate_integration_discord-rp.cfg b/gamestate_integration_discord-rp.cfg new file mode 100644 index 0000000..ed0efd2 --- /dev/null +++ b/gamestate_integration_discord-rp.cfg @@ -0,0 +1,21 @@ +"CSGO-Discord-RP" +{ + "uri" "http://localhost:3000" + "timeout" "5.0" + "buffer" "1" + "throttle" "5" + "heartbeat" "15" + "data" + { + "provider" "1" + "map" "1" + "round" "1" + "player_id" "1" + "player_weapons" "1" + "player_match_stats" "1" + "player_state" "1" + "allplayers_id" "1" + "allplayers_state" "1" + "allplayers_match_stats" "1" + } +}