diff --git a/.github/ISSUE_TEMPLATE/BUG.yml b/.github/ISSUE_TEMPLATE/BUG.yml index 8af5a0b..f71b668 100644 --- a/.github/ISSUE_TEMPLATE/BUG.yml +++ b/.github/ISSUE_TEMPLATE/BUG.yml @@ -21,7 +21,7 @@ body: id: version attributes: label: Version - description: What version of the Discord Game SDK Godot plugin are you running? + description: What version of the Discord RPC Godot plugin are you running? options: - 1.2.0 - 1.1.0 @@ -94,5 +94,5 @@ body: required: true - label: I tried restarting Discord and Godot completely. required: true - - label: I did read the documentation https://vaporvee.com/docs/discord-sdk-godot/ + - label: I did read the documentation https://vaporvee.com/docs/discord-rpc-godot/ required: true diff --git a/.gitignore b/.gitignore index a2efecc..ad38f6c 100644 --- a/.gitignore +++ b/.gitignore @@ -22,7 +22,7 @@ build/ *.a #Clean files from setup.py -src/lib/discord_game_sdk/ +src/lib/discord_rpc/ # release release/ diff --git a/README.md b/README.md index 6a7f40e..6623c8e 100644 --- a/README.md +++ b/README.md @@ -1,10 +1,10 @@ Project Banner -**Discord Game SDK support for GDScript in Godot Engine 4.2. with the easiest code pattern!**

+**Discord Game RPC support for GDScript with an easy-to-use code pattern in Godot Engine 4.1+, with optional Editor Rich Presence! (Compatible with Linux, Windows, & MacOS)**


### [My Discord Server](https://discord.gg/EBdaTefpWy) -# [Quick start :rocket: (click here)](https://vaporvee.com/docs/discord-sdk-godot#quick-start) +# [Quick start :rocket: (click here)](https://vaporvee.com/docs/discord-rpc-godot#quick-start)
**A small donation with the sponsor button would be nice if you sell your project with this addon but is of course not mandatory!** @@ -17,7 +17,7 @@ - Relationship Manager (Get friendlist and its updates) - Overlay management - Editor Presence (optional) - +

diff --git a/SConstruct b/SConstruct index a8f8039..cf75202 100644 --- a/SConstruct +++ b/SConstruct @@ -39,7 +39,7 @@ sources += Glob("src/*.cpp") env.Append(CPPDEFINES=["HOT_RELOAD_ENABLED"]) library = env.SharedLibrary( - target="project/addons/discord-sdk-gd/bin/" + target="project/addons/discord-rpc-gd/bin/" + libexportfolder + "discord_game_sdk_binding" + armsuffix @@ -49,7 +49,7 @@ library = env.SharedLibrary( env.Depends( library, Command( - "project/addons/discord-sdk-gd/bin/" + libexportfolder + discord_library, + "project/addons/discord-rpc-gd/bin/" + libexportfolder + discord_library, "src/lib/discord_game_sdk/bin/" + discord_library, Copy("$TARGET", "$SOURCE"), ), @@ -58,7 +58,7 @@ if discord_library_second != "": env.Depends( library, Command( - "project/addons/discord-sdk-gd/bin/" + "project/addons/discord-rpc-gd/bin/" + libexportfolder + discord_library_second, "src/lib/discord_game_sdk/bin/" + discord_library_second, diff --git a/project/addons/discord-sdk-gd/Debug.svg b/project/addons/discord-rpc-gd/Debug.svg similarity index 100% rename from project/addons/discord-sdk-gd/Debug.svg rename to project/addons/discord-rpc-gd/Debug.svg diff --git a/project/addons/discord-sdk-gd/Debug.svg.import b/project/addons/discord-rpc-gd/Debug.svg.import similarity index 75% rename from project/addons/discord-sdk-gd/Debug.svg.import rename to project/addons/discord-rpc-gd/Debug.svg.import index 708694a..4596fbd 100644 --- a/project/addons/discord-sdk-gd/Debug.svg.import +++ b/project/addons/discord-rpc-gd/Debug.svg.import @@ -3,15 +3,15 @@ importer="texture" type="CompressedTexture2D" uid="uid://ufh1hha1ehui" -path="res://.godot/imported/Debug.svg-97b25f5d09dbf04212867cd1a46cf368.ctex" +path="res://.godot/imported/Debug.svg-d4cb8599fa7926b76a2d6e40d2efd949.ctex" metadata={ "vram_texture": false } [deps] -source_file="res://addons/discord-sdk-gd/Debug.svg" -dest_files=["res://.godot/imported/Debug.svg-97b25f5d09dbf04212867cd1a46cf368.ctex"] +source_file="res://addons/discord-rpc-gd/Debug.svg" +dest_files=["res://.godot/imported/Debug.svg-d4cb8599fa7926b76a2d6e40d2efd949.ctex"] [params] diff --git a/project/addons/discord-sdk-gd/Logo_V2_No_Bg.png b/project/addons/discord-rpc-gd/Logo_V2_No_Bg.png similarity index 100% rename from project/addons/discord-sdk-gd/Logo_V2_No_Bg.png rename to project/addons/discord-rpc-gd/Logo_V2_No_Bg.png diff --git a/project/addons/discord-sdk-gd/Logo_V2_No_Bg.png.import b/project/addons/discord-rpc-gd/Logo_V2_No_Bg.png.import similarity index 70% rename from project/addons/discord-sdk-gd/Logo_V2_No_Bg.png.import rename to project/addons/discord-rpc-gd/Logo_V2_No_Bg.png.import index 4d6ea22..a1f1230 100644 --- a/project/addons/discord-sdk-gd/Logo_V2_No_Bg.png.import +++ b/project/addons/discord-rpc-gd/Logo_V2_No_Bg.png.import @@ -3,15 +3,15 @@ importer="texture" type="CompressedTexture2D" uid="uid://csl0e2px0cwc1" -path="res://.godot/imported/Logo_V2_No_Bg.png-9c8178062d6891c8370df63a912bd8e2.ctex" +path="res://.godot/imported/Logo_V2_No_Bg.png-ed667fb599fe1e17ebcfc361ff7c9c93.ctex" metadata={ "vram_texture": false } [deps] -source_file="res://addons/discord-sdk-gd/Logo_V2_No_Bg.png" -dest_files=["res://.godot/imported/Logo_V2_No_Bg.png-9c8178062d6891c8370df63a912bd8e2.ctex"] +source_file="res://addons/discord-rpc-gd/Logo_V2_No_Bg.png" +dest_files=["res://.godot/imported/Logo_V2_No_Bg.png-ed667fb599fe1e17ebcfc361ff7c9c93.ctex"] [params] diff --git a/project/addons/discord-sdk-gd/READ_ME_PLEASE.txt b/project/addons/discord-rpc-gd/READ_ME_PLEASE.txt similarity index 63% rename from project/addons/discord-sdk-gd/READ_ME_PLEASE.txt rename to project/addons/discord-rpc-gd/READ_ME_PLEASE.txt index e070946..a98427b 100644 --- a/project/addons/discord-sdk-gd/READ_ME_PLEASE.txt +++ b/project/addons/discord-rpc-gd/READ_ME_PLEASE.txt @@ -1,7 +1,7 @@ MINIMUM GODOT VERSION: 4.2 -PLEASE ACTIVATE THE PLUGIN UNDER Project -> Project Settings... -> Plugins -> DiscordSDK -> Status +PLEASE ACTIVATE THE PLUGIN UNDER Project -> Project Settings... -> Plugins -> DiscordRPC -> Status IGNORE THE RED ERRORS ON THE FIRST 2 RESTARTS READ THE TUTORIAL LINKED IN THE WINDOW THAT WILL OPEN ON PLUGIN ENABLE -If nothing works, enable the plugin and delete /addons/discord-sdk-gd/bin/.gdignore +If nothing works, enable the plugin and delete /addons/discord-rpc-gd/bin/.gdignore diff --git a/project/addons/discord-sdk-gd/bin/discord-rpc-gd.gdextension b/project/addons/discord-rpc-gd/bin/discord-rpc-gd.gdextension similarity index 96% rename from project/addons/discord-sdk-gd/bin/discord-rpc-gd.gdextension rename to project/addons/discord-rpc-gd/bin/discord-rpc-gd.gdextension index a9416e3..27e2845 100644 --- a/project/addons/discord-sdk-gd/bin/discord-rpc-gd.gdextension +++ b/project/addons/discord-rpc-gd/bin/discord-rpc-gd.gdextension @@ -1,6 +1,6 @@ [configuration] -entry_symbol = "discordsdkgd_library_init" +entry_symbol = "discordrpcgd_library_init" compatibility_minimum = 4.1 [libraries] diff --git a/project/addons/discord-sdk-gd/bin/linux/libdiscord_game_sdk.so b/project/addons/discord-rpc-gd/bin/linux/libdiscord_game_sdk.so similarity index 100% rename from project/addons/discord-sdk-gd/bin/linux/libdiscord_game_sdk.so rename to project/addons/discord-rpc-gd/bin/linux/libdiscord_game_sdk.so diff --git a/project/addons/discord-sdk-gd/bin/linux/libdiscord_game_sdk_binding.so b/project/addons/discord-rpc-gd/bin/linux/libdiscord_game_sdk_binding.so similarity index 100% rename from project/addons/discord-sdk-gd/bin/linux/libdiscord_game_sdk_binding.so rename to project/addons/discord-rpc-gd/bin/linux/libdiscord_game_sdk_binding.so diff --git a/project/addons/discord-sdk-gd/bin/linux/libdiscord_game_sdk_binding_debug.so b/project/addons/discord-rpc-gd/bin/linux/libdiscord_game_sdk_binding_debug.so similarity index 100% rename from project/addons/discord-sdk-gd/bin/linux/libdiscord_game_sdk_binding_debug.so rename to project/addons/discord-rpc-gd/bin/linux/libdiscord_game_sdk_binding_debug.so diff --git a/project/addons/discord-sdk-gd/bin/macos/libdiscord_game_sdk.dylib b/project/addons/discord-rpc-gd/bin/macos/libdiscord_game_sdk.dylib similarity index 100% rename from project/addons/discord-sdk-gd/bin/macos/libdiscord_game_sdk.dylib rename to project/addons/discord-rpc-gd/bin/macos/libdiscord_game_sdk.dylib diff --git a/project/addons/discord-sdk-gd/bin/macos/libdiscord_game_sdk_binding.dylib b/project/addons/discord-rpc-gd/bin/macos/libdiscord_game_sdk_binding.dylib similarity index 100% rename from project/addons/discord-sdk-gd/bin/macos/libdiscord_game_sdk_binding.dylib rename to project/addons/discord-rpc-gd/bin/macos/libdiscord_game_sdk_binding.dylib diff --git a/project/addons/discord-sdk-gd/bin/macos/libdiscord_game_sdk_binding_debug.dylib b/project/addons/discord-rpc-gd/bin/macos/libdiscord_game_sdk_binding_debug.dylib similarity index 100% rename from project/addons/discord-sdk-gd/bin/macos/libdiscord_game_sdk_binding_debug.dylib rename to project/addons/discord-rpc-gd/bin/macos/libdiscord_game_sdk_binding_debug.dylib diff --git a/project/addons/discord-sdk-gd/bin/windows/discord_game_sdk.dll b/project/addons/discord-rpc-gd/bin/windows/discord_game_sdk.dll similarity index 100% rename from project/addons/discord-sdk-gd/bin/windows/discord_game_sdk.dll rename to project/addons/discord-rpc-gd/bin/windows/discord_game_sdk.dll diff --git a/project/addons/discord-sdk-gd/bin/windows/discord_game_sdk_binding.dll b/project/addons/discord-rpc-gd/bin/windows/discord_game_sdk_binding.dll similarity index 97% rename from project/addons/discord-sdk-gd/bin/windows/discord_game_sdk_binding.dll rename to project/addons/discord-rpc-gd/bin/windows/discord_game_sdk_binding.dll index c5688c7..77ffef2 100644 Binary files a/project/addons/discord-sdk-gd/bin/windows/discord_game_sdk_binding.dll and b/project/addons/discord-rpc-gd/bin/windows/discord_game_sdk_binding.dll differ diff --git a/project/addons/discord-rpc-gd/bin/windows/discord_game_sdk_binding_debug.dll b/project/addons/discord-rpc-gd/bin/windows/discord_game_sdk_binding_debug.dll new file mode 100644 index 0000000..2b52a76 Binary files /dev/null and b/project/addons/discord-rpc-gd/bin/windows/discord_game_sdk_binding_debug.dll differ diff --git a/project/addons/discord-sdk-gd/bin/windows/discord_game_sdk_x86.dll b/project/addons/discord-rpc-gd/bin/windows/discord_game_sdk_x86.dll similarity index 100% rename from project/addons/discord-sdk-gd/bin/windows/discord_game_sdk_x86.dll rename to project/addons/discord-rpc-gd/bin/windows/discord_game_sdk_x86.dll diff --git a/project/addons/discord-rpc-gd/bin/windows/~discord_game_sdk_binding_debug.dll b/project/addons/discord-rpc-gd/bin/windows/~discord_game_sdk_binding_debug.dll new file mode 100644 index 0000000..2b52a76 Binary files /dev/null and b/project/addons/discord-rpc-gd/bin/windows/~discord_game_sdk_binding_debug.dll differ diff --git a/project/addons/discord-sdk-gd/example.gd b/project/addons/discord-rpc-gd/example.gd similarity index 65% rename from project/addons/discord-sdk-gd/example.gd rename to project/addons/discord-rpc-gd/example.gd index 04f4c91..95f2926 100644 --- a/project/addons/discord-sdk-gd/example.gd +++ b/project/addons/discord-rpc-gd/example.gd @@ -1,8 +1,8 @@ -class_name DiscordSDKTutorial +class_name DiscordRPCTutorial extends Node ## 1. Put the addons/ folder in your Godot project[br] -## 2. Enable the addon in your Project Settings under "Plugins" and "DiscordSDK". [br](if it doesn't show up restart your project and try again)[br] +## 2. Enable the addon in your Project Settings under "Plugins" and "DiscordRPC". [br](if it doesn't show up restart your project and try again)[br] ## 3. Restart your project[br] ## 4. Create an Application under https://discord.com/developers/applications and get the Application ID br] ## 5. (optional) Set images under "Rich Presence" and "Art Assets" and remember the keys[br] @@ -11,28 +11,28 @@ extends Node ## [codeblock] ## func _ready(): ## # Application ID -## DiscordSDK.app_id = 1099618430065324082 +## DiscordRPC.app_id = 1099618430065324082 ## # this is boolean if everything worked -## print("Discord working: " + str(DiscordSDK.get_is_discord_working())) +## print("Discord working: " + str(DiscordRPC.get_is_discord_working())) ## # Set the first custom text row of the activity here -## DiscordSDK.details = "A demo activity by vaporvee#1231" +## DiscordRPC.details = "A demo activity by vaporvee#1231" ## # Set the second custom text row of the activity here -## DiscordSDK.state = "Checkpoint 23/23" +## DiscordRPC.state = "Checkpoint 23/23" ## # Image key for small image from "Art Assets" from the Discord Developer website -## DiscordSDK.large_image = "game" +## DiscordRPC.large_image = "game" ## # Tooltip text for the large image -## DiscordSDK.large_image_text = "Try it now!" +## DiscordRPC.large_image_text = "Try it now!" ## # Image key for large image from "Art Assets" from the Discord Developer website -## DiscordSDK.small_image = "boss" +## DiscordRPC.small_image = "boss" ## # Tooltip text for the small image -## DiscordSDK.small_image_text = "Fighting the end boss! D:" +## DiscordRPC.small_image_text = "Fighting the end boss! D:" ## # "02:41 elapsed" timestamp for the activity -## DiscordSDK.start_timestamp = int(Time.get_unix_time_from_system()) +## DiscordRPC.start_timestamp = int(Time.get_unix_time_from_system()) ## # "59:59 remaining" timestamp for the activity -## DiscordSDK.end_timestamp = int(Time.get_unix_time_from_system()) + 3600 +## DiscordRPC.end_timestamp = int(Time.get_unix_time_from_system()) + 3600 ## # Always refresh after changing the values! -## DiscordSDK.refresh() +## DiscordRPC.refresh() ## [/codeblock] ## -## @tutorial(More information here): https://github.com/vaporvee/discord-sdk-godot/wiki/Quick-start +## @tutorial(More information here): https://github.com/vaporvee/discord-rpc-godot/wiki/Quick-start ## @tutorial(Make your Application ID and else here): https://discord.com/developers/applications diff --git a/project/addons/discord-sdk-gd/logo.png b/project/addons/discord-rpc-gd/logo.png similarity index 100% rename from project/addons/discord-sdk-gd/logo.png rename to project/addons/discord-rpc-gd/logo.png diff --git a/project/addons/discord-sdk-gd/logo.png.import b/project/addons/discord-rpc-gd/logo.png.import similarity index 72% rename from project/addons/discord-sdk-gd/logo.png.import rename to project/addons/discord-rpc-gd/logo.png.import index a6947aa..1cce19a 100644 --- a/project/addons/discord-sdk-gd/logo.png.import +++ b/project/addons/discord-rpc-gd/logo.png.import @@ -3,15 +3,15 @@ importer="texture" type="CompressedTexture2D" uid="uid://csl0e2px0cwc1" -path="res://.godot/imported/logo.png-b59b4861dc0c64616d78af30082b08b5.ctex" +path="res://.godot/imported/logo.png-bacb448eabae556bdb0659359ea4e4af.ctex" metadata={ "vram_texture": false } [deps] -source_file="res://addons/discord-sdk-gd/logo.png" -dest_files=["res://.godot/imported/logo.png-b59b4861dc0c64616d78af30082b08b5.ctex"] +source_file="res://addons/discord-rpc-gd/logo.png" +dest_files=["res://.godot/imported/logo.png-bacb448eabae556bdb0659359ea4e4af.ctex"] [params] diff --git a/project/addons/discord-sdk-gd/nodes/Debug.tscn b/project/addons/discord-rpc-gd/nodes/Debug.tscn similarity index 83% rename from project/addons/discord-sdk-gd/nodes/Debug.tscn rename to project/addons/discord-rpc-gd/nodes/Debug.tscn index adf08fc..6953f83 100644 --- a/project/addons/discord-sdk-gd/nodes/Debug.tscn +++ b/project/addons/discord-rpc-gd/nodes/Debug.tscn @@ -1,18 +1,18 @@ [gd_scene load_steps=9 format=3 uid="uid://c1slhdnlsv2qt"] -[ext_resource type="Texture2D" uid="uid://dnfq6kug4x6o2" path="res://addons/discord-sdk-gd/nodes/assets/Checked.svg" id="2_q6tao"] -[ext_resource type="Texture2D" uid="uid://compmm3kviqqe" path="res://addons/discord-sdk-gd/nodes/assets/Unchecked.svg" id="3_5cyem"] -[ext_resource type="Texture2D" uid="uid://dtc6ckladq0td" path="res://addons/discord-sdk-gd/nodes/assets/circle.svg" id="3_goflf"] +[ext_resource type="Texture2D" uid="uid://dnfq6kug4x6o2" path="res://addons/discord-rpc-gd/nodes/assets/Checked.svg" id="2_q6tao"] +[ext_resource type="Texture2D" uid="uid://compmm3kviqqe" path="res://addons/discord-rpc-gd/nodes/assets/Unchecked.svg" id="3_5cyem"] +[ext_resource type="Texture2D" uid="uid://dtc6ckladq0td" path="res://addons/discord-rpc-gd/nodes/assets/circle.svg" id="3_goflf"] [sub_resource type="GDScript" id="GDScript_ak1tp"] resource_name = "Debug" script/source = "extends Node func _ready(): - DiscordSDK.connect(\"activity_join_request\",_on_activity_join_request) + DiscordRPC.connect(\"activity_join_request\",_on_activity_join_request) func _process(_delta): - if(DiscordSDK.get_is_discord_working()): + if(DiscordRPC.get_is_discord_working()): $Panel/TextureRect.self_modulate = Color(\"#3eff8d\") $Panel/TextureRect/AnimationPlayer.play(\"pulsate\") debug_text_update() @@ -45,7 +45,7 @@ Is party public: {ppublic} (needs to be activated in Discord client settings) Is instanced: {instanced} \" - $Panel/Info.text = $Panel/Info.text.replace(\"{ppublic}\",str(DiscordSDK.is_public_party)).replace(\"{instanced}\",str(DiscordSDK.instanced)).replace(\"{ssecret}\",DiscordSDK.spectate_secret).replace(\"{jsecret}\",DiscordSDK.join_secret).replace(\"{msecret}\",DiscordSDK.match_secret).replace(\"{mpartysize}\",str(DiscordSDK.max_party_size)).replace(\"{cpartysize}\",str(DiscordSDK.current_party_size)).replace(\"{partyid}\",DiscordSDK.party_id).replace(\"{id}\",str(DiscordSDK.app_id)).replace(\"{details}\",DiscordSDK.details).replace(\"{state}\",DiscordSDK.state).replace(\"{lkey}\",DiscordSDK.large_image).replace(\"{ltext}\",DiscordSDK.large_image_text).replace(\"{skey}\",DiscordSDK.small_image).replace(\"{stext}\",DiscordSDK.small_image_text).replace(\"{stimestamp}\",str(DiscordSDK.start_timestamp)).replace(\"{etimestamp}\",str(DiscordSDK.end_timestamp)) + $Panel/Info.text = $Panel/Info.text.replace(\"{ppublic}\",str(DiscordRPC.is_public_party)).replace(\"{instanced}\",str(DiscordRPC.instanced)).replace(\"{ssecret}\",DiscordRPC.spectate_secret).replace(\"{jsecret}\",DiscordRPC.join_secret).replace(\"{msecret}\",DiscordRPC.match_secret).replace(\"{mpartysize}\",str(DiscordRPC.max_party_size)).replace(\"{cpartysize}\",str(DiscordRPC.current_party_size)).replace(\"{partyid}\",DiscordRPC.party_id).replace(\"{id}\",str(DiscordRPC.app_id)).replace(\"{details}\",DiscordRPC.details).replace(\"{state}\",DiscordRPC.state).replace(\"{lkey}\",DiscordRPC.large_image).replace(\"{ltext}\",DiscordRPC.large_image_text).replace(\"{skey}\",DiscordRPC.small_image).replace(\"{stext}\",DiscordRPC.small_image_text).replace(\"{stimestamp}\",str(DiscordRPC.start_timestamp)).replace(\"{etimestamp}\",str(DiscordRPC.end_timestamp)) var user_request = {}; @@ -55,25 +55,25 @@ func _on_activity_join_request(user_requesting): func _on_accept_join_request_pressed(): if(!user_request.is_empty()): - DiscordSDK.accept_join_request(user_request.id) + DiscordRPC.accept_join_request(user_request.id) func _on_invite_with_user_id_text_submitted(new_text): - DiscordSDK.send_invite(int(new_text),true,\"this is a test invite sent from godot\") + DiscordRPC.send_invite(int(new_text),true,\"this is a test invite sent from godot\") func _on_accept_with_user_id_text_submitted(new_text): - DiscordSDK.accept_invite(int(new_text)) + DiscordRPC.accept_invite(int(new_text)) func _on_print_current_user_on_console_pressed(): - print(DiscordSDK.get_current_user()) + print(DiscordRPC.get_current_user()) func _on_toggle_sdk_toggled(button_pressed): if(button_pressed): - DiscordSDK.unclear() + DiscordRPC.unclear() else: - DiscordSDK.clear(false) + DiscordRPC.clear(false) func _on_print_friends_pressed(): - print(DiscordSDK.get_all_relationships()) + print(DiscordRPC.get_all_relationships()) " [sub_resource type="StyleBoxEmpty" id="StyleBoxEmpty_8abo6"] diff --git a/project/addons/discord-sdk-gd/nodes/assets/Checked.svg b/project/addons/discord-rpc-gd/nodes/assets/Checked.svg similarity index 100% rename from project/addons/discord-sdk-gd/nodes/assets/Checked.svg rename to project/addons/discord-rpc-gd/nodes/assets/Checked.svg diff --git a/project/addons/discord-sdk-gd/nodes/assets/Checked.svg.import b/project/addons/discord-rpc-gd/nodes/assets/Checked.svg.import similarity index 74% rename from project/addons/discord-sdk-gd/nodes/assets/Checked.svg.import rename to project/addons/discord-rpc-gd/nodes/assets/Checked.svg.import index bc9fc5a..9913c3c 100644 --- a/project/addons/discord-sdk-gd/nodes/assets/Checked.svg.import +++ b/project/addons/discord-rpc-gd/nodes/assets/Checked.svg.import @@ -3,15 +3,15 @@ importer="texture" type="CompressedTexture2D" uid="uid://dnfq6kug4x6o2" -path="res://.godot/imported/Checked.svg-152467b95b56fa0b9944b5cc25700916.ctex" +path="res://.godot/imported/Checked.svg-80704e37f30c24e2ec3dfc0955f5f21c.ctex" metadata={ "vram_texture": false } [deps] -source_file="res://addons/discord-sdk-gd/nodes/assets/Checked.svg" -dest_files=["res://.godot/imported/Checked.svg-152467b95b56fa0b9944b5cc25700916.ctex"] +source_file="res://addons/discord-rpc-gd/nodes/assets/Checked.svg" +dest_files=["res://.godot/imported/Checked.svg-80704e37f30c24e2ec3dfc0955f5f21c.ctex"] [params] diff --git a/project/addons/discord-sdk-gd/nodes/assets/Unchecked.svg b/project/addons/discord-rpc-gd/nodes/assets/Unchecked.svg similarity index 100% rename from project/addons/discord-sdk-gd/nodes/assets/Unchecked.svg rename to project/addons/discord-rpc-gd/nodes/assets/Unchecked.svg diff --git a/project/addons/discord-sdk-gd/nodes/assets/Unchecked.svg.import b/project/addons/discord-rpc-gd/nodes/assets/Unchecked.svg.import similarity index 73% rename from project/addons/discord-sdk-gd/nodes/assets/Unchecked.svg.import rename to project/addons/discord-rpc-gd/nodes/assets/Unchecked.svg.import index 43b3409..7503ec8 100644 --- a/project/addons/discord-sdk-gd/nodes/assets/Unchecked.svg.import +++ b/project/addons/discord-rpc-gd/nodes/assets/Unchecked.svg.import @@ -3,15 +3,15 @@ importer="texture" type="CompressedTexture2D" uid="uid://compmm3kviqqe" -path="res://.godot/imported/Unchecked.svg-91cff67e13e7a1508fbc6a949f5f5f52.ctex" +path="res://.godot/imported/Unchecked.svg-b526adfd78f7b1577fc3c10a8ea626ee.ctex" metadata={ "vram_texture": false } [deps] -source_file="res://addons/discord-sdk-gd/nodes/assets/Unchecked.svg" -dest_files=["res://.godot/imported/Unchecked.svg-91cff67e13e7a1508fbc6a949f5f5f52.ctex"] +source_file="res://addons/discord-rpc-gd/nodes/assets/Unchecked.svg" +dest_files=["res://.godot/imported/Unchecked.svg-b526adfd78f7b1577fc3c10a8ea626ee.ctex"] [params] diff --git a/project/addons/discord-sdk-gd/nodes/assets/circle.svg b/project/addons/discord-rpc-gd/nodes/assets/circle.svg similarity index 100% rename from project/addons/discord-sdk-gd/nodes/assets/circle.svg rename to project/addons/discord-rpc-gd/nodes/assets/circle.svg diff --git a/project/addons/discord-sdk-gd/nodes/assets/circle.svg.import b/project/addons/discord-rpc-gd/nodes/assets/circle.svg.import similarity index 74% rename from project/addons/discord-sdk-gd/nodes/assets/circle.svg.import rename to project/addons/discord-rpc-gd/nodes/assets/circle.svg.import index d7598a8..509c745 100644 --- a/project/addons/discord-sdk-gd/nodes/assets/circle.svg.import +++ b/project/addons/discord-rpc-gd/nodes/assets/circle.svg.import @@ -3,15 +3,15 @@ importer="texture" type="CompressedTexture2D" uid="uid://dtc6ckladq0td" -path="res://.godot/imported/circle.svg-ca71b895eb1c5e7e6f2f2afe081d28dd.ctex" +path="res://.godot/imported/circle.svg-d0b0579c9433c6250a5869daf4f70024.ctex" metadata={ "vram_texture": false } [deps] -source_file="res://addons/discord-sdk-gd/nodes/assets/circle.svg" -dest_files=["res://.godot/imported/circle.svg-ca71b895eb1c5e7e6f2f2afe081d28dd.ctex"] +source_file="res://addons/discord-rpc-gd/nodes/assets/circle.svg" +dest_files=["res://.godot/imported/circle.svg-d0b0579c9433c6250a5869daf4f70024.ctex"] [params] diff --git a/project/addons/discord-sdk-gd/nodes/debug.gd b/project/addons/discord-rpc-gd/nodes/debug.gd similarity index 64% rename from project/addons/discord-sdk-gd/nodes/debug.gd rename to project/addons/discord-rpc-gd/nodes/debug.gd index a4e8ee0..d960441 100644 --- a/project/addons/discord-sdk-gd/nodes/debug.gd +++ b/project/addons/discord-rpc-gd/nodes/debug.gd @@ -1,11 +1,11 @@ ## This is a Debug Node wich will show some usefull info and buttons/input ## -## The DiscordSDK Debug Node will show info about the current values of its variables and some buttons to change them. +## The DiscordRPC Debug Node will show info about the current values of its variables and some buttons to change them. ## -## @tutorial: https://github.com/vaporvee/discord-sdk-godot/wiki +## @tutorial: https://github.com/vaporvee/discord-rpc-godot/wiki @tool extends Node func _ready() -> void: - const DebugNodeGroup: PackedScene = preload("res://addons/discord-sdk-gd/nodes/Debug.tscn") + const DebugNodeGroup: PackedScene = preload("res://addons/discord-rpc-gd/nodes/Debug.tscn") add_child(DebugNodeGroup.instantiate()) diff --git a/project/addons/discord-sdk-gd/nodes/discord_autoload.gd b/project/addons/discord-rpc-gd/nodes/discord_autoload.gd similarity index 67% rename from project/addons/discord-sdk-gd/nodes/discord_autoload.gd rename to project/addons/discord-rpc-gd/nodes/discord_autoload.gd index 8cdeac2..cfc6e60 100644 --- a/project/addons/discord-sdk-gd/nodes/discord_autoload.gd +++ b/project/addons/discord-rpc-gd/nodes/discord_autoload.gd @@ -1,13 +1,13 @@ ## This is a GDscript Node wich gets automatically added as Autoload while installing the addon. ## ## It can run in the background to comunicate with Discord. -## You don't need to use it. If you remove it make sure to run [code]DiscordSDK.run_callbacks()[/code] in a [code]_process[/code] function. +## You don't need to use it. If you remove it make sure to run [code]DiscordRPC.run_callbacks()[/code] in a [code]_process[/code] function. ## -## @tutorial: https://github.com/vaporvee/discord-sdk-godot/wiki +## @tutorial: https://github.com/vaporvee/discord-rpc-godot/wiki extends Node func _ready() -> void: pass func _process(_delta) -> void: - DiscordSDK.run_callbacks() + DiscordRPC.run_callbacks() diff --git a/project/addons/discord-rpc-gd/plugin.cfg b/project/addons/discord-rpc-gd/plugin.cfg new file mode 100644 index 0000000..07e1c99 --- /dev/null +++ b/project/addons/discord-rpc-gd/plugin.cfg @@ -0,0 +1,7 @@ +[plugin] + +name="DiscordRPC" +description="Discord RPC Plugin for GDScript in Godot" +author="vaporvee" +version="1.2.0" +script="plugin.gd" diff --git a/project/addons/discord-sdk-gd/plugin.gd b/project/addons/discord-rpc-gd/plugin.gd similarity index 63% rename from project/addons/discord-sdk-gd/plugin.gd rename to project/addons/discord-rpc-gd/plugin.gd index f890de7..03985b6 100644 --- a/project/addons/discord-sdk-gd/plugin.gd +++ b/project/addons/discord-rpc-gd/plugin.gd @@ -1,42 +1,42 @@ @tool extends EditorPlugin -const DiscordSDKDebug = preload("res://addons/discord-sdk-gd/nodes/debug.gd") -const DiscordSDKDebug_icon = preload("res://addons/discord-sdk-gd/Debug.svg") -var loaded_DiscordSDKDebug = DiscordSDKDebug.new() -var restart_window: ConfirmationDialog = preload("res://addons/discord-sdk-gd/restart_window.tscn").instantiate() +const DiscordRPCDebug = preload("res://addons/discord-rpc-gd/nodes/debug.gd") +const DiscordRPCDebug_icon = preload("res://addons/discord-rpc-gd/Debug.svg") +var loaded_DiscordRPCDebug = DiscordRPCDebug.new() +var restart_window: ConfirmationDialog = preload("res://addons/discord-rpc-gd/restart_window.tscn").instantiate() var plugin_cfg: ConfigFile = ConfigFile.new() const plugin_data_filename = "/plugin_data.cfg" func _enter_tree() -> void: - add_custom_type("DiscordSDKDebug","Node",DiscordSDKDebug,DiscordSDKDebug_icon) + add_custom_type("DiscordRPCDebug","Node",DiscordRPCDebug,DiscordRPCDebug_icon) get_editor_interface().get_editor_settings().settings_changed.connect(_on_editor_settings_changed) func _ready() -> void: await get_tree().create_timer(0.5).timeout plugin_cfg.load(get_editor_interface().get_editor_paths().get_data_dir() + plugin_data_filename) - if !get_editor_interface().get_editor_settings().has_setting("DiscordSDK/EditorPresence/enabled"): - get_editor_interface().get_editor_settings().set_setting("DiscordSDK/EditorPresence/enabled",plugin_cfg.get_value("Discord","editor_presence",false)) + if !get_editor_interface().get_editor_settings().has_setting("DiscordRPC/EditorPresence/enabled"): + get_editor_interface().get_editor_settings().set_setting("DiscordRPC/EditorPresence/enabled",plugin_cfg.get_value("Discord","editor_presence",false)) func _exit_tree(): - if get_editor_interface().get_editor_settings().has_setting("DiscordSDK/EditorPresence/enabled"): - get_editor_interface().get_editor_settings().erase("DiscordSDK/EditorPresence/enabled") + if get_editor_interface().get_editor_settings().has_setting("DiscordRPC/EditorPresence/enabled"): + get_editor_interface().get_editor_settings().erase("DiscordRPC/EditorPresence/enabled") func _enable_plugin() -> void: - if FileAccess.file_exists(ProjectSettings.globalize_path("res://") + "addons/discord-sdk-gd/bin/.gdignore"): - DirAccess.remove_absolute(ProjectSettings.globalize_path("res://") + "addons/discord-sdk-gd/bin/.gdignore") - add_autoload_singleton("DiscordSDKLoader","res://addons/discord-sdk-gd/nodes/discord_autoload.gd") + if FileAccess.file_exists(ProjectSettings.globalize_path("res://") + "addons/discord-rpc-gd/bin/.gdignore"): + DirAccess.remove_absolute(ProjectSettings.globalize_path("res://") + "addons/discord-rpc-gd/bin/.gdignore") + add_autoload_singleton("DiscordRPCLoader","res://addons/discord-rpc-gd/nodes/discord_autoload.gd") restart_window.connect("confirmed", save_no_restart) restart_window.connect("canceled", save_and_restart) get_editor_interface().popup_dialog_centered(restart_window) print("IGNORE RED ERROR MESSAGES BEFORE THE SECOND RESTART!") func _disable_plugin() -> void: - remove_autoload_singleton("DiscordSDKLoader") - FileAccess.open("res://addons/discord-sdk-gd/bin/.gdignore",FileAccess.WRITE) - remove_custom_type("DiscordSDKDebug") - get_editor_interface().get_editor_settings().erase("DiscordSDK/EditorPresence/enabled") - push_warning("Please restart the editor to fully disable the DiscordSDK plugin") + remove_autoload_singleton("DiscordRPCLoader") + FileAccess.open("res://addons/discord-rpc-gd/bin/.gdignore",FileAccess.WRITE) + remove_custom_type("DiscordRPCDebug") + get_editor_interface().get_editor_settings().erase("DiscordRPC/EditorPresence/enabled") + push_warning("Please restart the editor to fully disable the DiscordRPC plugin") func save_and_restart() -> void: get_editor_interface().restart_editor(true) @@ -46,11 +46,11 @@ func save_no_restart() -> void: var editor_presence: Node func _on_editor_settings_changed() -> void: - plugin_cfg.set_value("Discord","editor_presence",get_editor_interface().get_editor_settings().get_setting("DiscordSDK/EditorPresence/enabled")) + plugin_cfg.set_value("Discord","editor_presence",get_editor_interface().get_editor_settings().get_setting("DiscordRPC/EditorPresence/enabled")) plugin_cfg.save(get_editor_interface().get_editor_paths().get_data_dir() + plugin_data_filename) if ClassDB.class_exists("EditorPresence") && editor_presence == null: editor_presence = ClassDB.instantiate("EditorPresence") - if get_editor_interface().get_editor_settings().has_setting("DiscordSDK/EditorPresence/enabled") && get_editor_interface().get_editor_settings().get_setting("DiscordSDK/EditorPresence/enabled"): + if get_editor_interface().get_editor_settings().has_setting("DiscordRPC/EditorPresence/enabled") && get_editor_interface().get_editor_settings().get_setting("DiscordRPC/EditorPresence/enabled"): add_child(editor_presence) else: editor_presence.queue_free() diff --git a/project/addons/discord-sdk-gd/restart_window.tscn b/project/addons/discord-rpc-gd/restart_window.tscn similarity index 98% rename from project/addons/discord-sdk-gd/restart_window.tscn rename to project/addons/discord-rpc-gd/restart_window.tscn index 0559c3e..436b6cc 100644 --- a/project/addons/discord-sdk-gd/restart_window.tscn +++ b/project/addons/discord-rpc-gd/restart_window.tscn @@ -1,6 +1,6 @@ [gd_scene load_steps=8 format=3 uid="uid://byc4c6d5tpomq"] -[ext_resource type="Texture2D" uid="uid://csl0e2px0cwc1" path="res://addons/discord-sdk-gd/Logo_V2_No_Bg.png" id="1_0svbg"] +[ext_resource type="Texture2D" uid="uid://csl0e2px0cwc1" path="res://addons/discord-rpc-gd/Logo_V2_No_Bg.png" id="1_0svbg"] [sub_resource type="StyleBoxEmpty" id="StyleBoxEmpty_1t7mm"] @@ -82,7 +82,7 @@ size_flags_vertical = 8 mouse_default_cursor_shape = 16 theme_override_font_sizes/font_size = 20 text = "HOW TO USE" -uri = "https://vaporvee.com/docs/discord-sdk-godot#quick-start" +uri = "https://vaporvee.com/docs/discord-rpc-godot#quick-start" [node name="TextureRect" type="TextureRect" parent="Panel/VBoxContainer"] custom_minimum_size = Vector2(128, 128) diff --git a/project/addons/discord-sdk-gd/bin/windows/discord_game_sdk_binding_debug.dll b/project/addons/discord-sdk-gd/bin/windows/discord_game_sdk_binding_debug.dll deleted file mode 100644 index 3e93cf0..0000000 Binary files a/project/addons/discord-sdk-gd/bin/windows/discord_game_sdk_binding_debug.dll and /dev/null differ diff --git a/project/addons/discord-sdk-gd/plugin.cfg b/project/addons/discord-sdk-gd/plugin.cfg deleted file mode 100644 index 4c72d16..0000000 --- a/project/addons/discord-sdk-gd/plugin.cfg +++ /dev/null @@ -1,7 +0,0 @@ -[plugin] - -name="DiscordSDK" -description="Discord Game SDK support for GDScript in Godot" -author="vaporvee" -version="1.2.0" -script="plugin.gd" diff --git a/project/assets/Banner.svg b/project/assets/Banner.svg deleted file mode 100644 index 9ea1c89..0000000 --- a/project/assets/Banner.svg +++ /dev/null @@ -1,813 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/project/assets/Banner_v1.png b/project/assets/Banner_v1.png deleted file mode 100644 index e8ba85e..0000000 Binary files a/project/assets/Banner_v1.png and /dev/null differ diff --git a/project/assets/discordgodot_banner.png b/project/assets/discordgodot_banner.png new file mode 100644 index 0000000..1c491a0 Binary files /dev/null and b/project/assets/discordgodot_banner.png differ diff --git a/project/assets/Banner.svg.import b/project/assets/discordgodot_banner.png.import similarity index 62% rename from project/assets/Banner.svg.import rename to project/assets/discordgodot_banner.png.import index c1f8d15..fc863ce 100644 --- a/project/assets/Banner.svg.import +++ b/project/assets/discordgodot_banner.png.import @@ -2,16 +2,16 @@ importer="texture" type="CompressedTexture2D" -uid="uid://c0i5gy8pvdnwt" -path="res://.godot/imported/Banner.svg-5bd63979daa8dcc3afce0089ffa91a12.ctex" +uid="uid://c7h7lup1lw58j" +path="res://.godot/imported/discordgodot_banner.png-eb84eabd38610228ef9dc43dbd0407a1.ctex" metadata={ "vram_texture": false } [deps] -source_file="res://assets/Banner.svg" -dest_files=["res://.godot/imported/Banner.svg-5bd63979daa8dcc3afce0089ffa91a12.ctex"] +source_file="res://assets/discordgodot_banner.png" +dest_files=["res://.godot/imported/discordgodot_banner.png-eb84eabd38610228ef9dc43dbd0407a1.ctex"] [params] @@ -32,6 +32,3 @@ process/hdr_as_srgb=false process/hdr_clamp_exposure=false process/size_limit=0 detect_3d/compress_to=1 -svg/scale=1.0 -editor/scale_with_editor_scale=false -editor/convert_colors_with_editor_theme=false diff --git a/project/assets/discordgodot_cover.png b/project/assets/discordgodot_cover.png new file mode 100644 index 0000000..8551b9b Binary files /dev/null and b/project/assets/discordgodot_cover.png differ diff --git a/project/assets/Banner_v1.png.import b/project/assets/discordgodot_cover.png.import similarity index 66% rename from project/assets/Banner_v1.png.import rename to project/assets/discordgodot_cover.png.import index 9f480aa..a6decf6 100644 --- a/project/assets/Banner_v1.png.import +++ b/project/assets/discordgodot_cover.png.import @@ -2,16 +2,16 @@ importer="texture" type="CompressedTexture2D" -uid="uid://bwdma28ey44h0" -path="res://.godot/imported/Banner_v1.png-5ed14d0906a04274d823c02cd90d1aad.ctex" +uid="uid://dumc28wi63nnc" +path="res://.godot/imported/discordgodot_cover.png-5ee32fcd652e9995745e14429baed069.ctex" metadata={ "vram_texture": false } [deps] -source_file="res://assets/Banner_v1.png" -dest_files=["res://.godot/imported/Banner_v1.png-5ed14d0906a04274d823c02cd90d1aad.ctex"] +source_file="res://assets/discordgodot_cover.png" +dest_files=["res://.godot/imported/discordgodot_cover.png-5ee32fcd652e9995745e14429baed069.ctex"] [params] diff --git a/project/export_presets.cfg b/project/export_presets.cfg index 0bf7554..6ca76b3 100644 --- a/project/export_presets.cfg +++ b/project/export_presets.cfg @@ -8,7 +8,7 @@ custom_features="" export_filter="all_resources" include_filter="" exclude_filter="" -export_path="export/windows/discord-sdk-godot-demo.exe" +export_path="export/windows/discord-rpc-godot-demo.exe" encryption_include_filters="" encryption_exclude_filters="" encrypt_pck=false @@ -39,7 +39,7 @@ application/file_version="" application/product_version="" application/company_name="" application/product_name="" -application/file_description="Discord SDK Godot Test" +application/file_description="Discord RPC Godot Test" application/copyright="" application/trademarks="" application/export_angle=0 @@ -71,7 +71,7 @@ custom_features="" export_filter="all_resources" include_filter="" exclude_filter="" -export_path="export/linux/discord-sdk-godot-demo.x86_64" +export_path="export/linux/discord-rpc-godot-demo.x86_64" encryption_include_filters="" encryption_exclude_filters="" encrypt_pck=false @@ -111,7 +111,7 @@ custom_features="" export_filter="all_resources" include_filter="" exclude_filter="" -export_path="export/macos/discord-sdk-godot-demo.zip" +export_path="export/macos/discord-rpc-godot-demo.zip" encryption_include_filters="" encryption_exclude_filters="" encrypt_pck=false @@ -126,7 +126,7 @@ custom_template/release="" debug/export_console_wrapper=1 application/icon="" application/icon_interpolation=4 -application/bundle_identifier="com.vaporvee.discord-sdk-godot-demo" +application/bundle_identifier="com.vaporvee.discord-rpc-godot-demo" application/signature="" application/app_category="Games" application/short_version="" diff --git a/project/main.gd b/project/main.gd index cab40d6..68a649f 100644 --- a/project/main.gd +++ b/project/main.gd @@ -2,40 +2,40 @@ extends Node func _ready() -> void: set_activity() - DiscordSDK.connect("activity_join_request",_on_activity_join_request) - DiscordSDK.connect("activity_join",_on_activity_join) - DiscordSDK.connect("activity_spectate",_on_activity_spectate) - DiscordSDK.connect("relationships_init",_on_relationship_init) - DiscordSDK.connect("updated_relationship", _on_updated_relationship) + DiscordRPC.connect("activity_join_request",_on_activity_join_request) + DiscordRPC.connect("activity_join",_on_activity_join) + DiscordRPC.connect("activity_spectate",_on_activity_spectate) + DiscordRPC.connect("relationships_init",_on_relationship_init) + DiscordRPC.connect("updated_relationship", _on_updated_relationship) func set_activity() -> void: - DiscordSDK.clear(false) - DiscordSDK.app_id = 1099618430065324082 - DiscordSDK.details = "A demo activity by vaporvee#1231" - DiscordSDK.state = "Checkpoint 23/23" + DiscordRPC.clear(false) + DiscordRPC.app_id = 1099618430065324082 + DiscordRPC.details = "A demo activity by vaporvee#1231" + DiscordRPC.state = "Checkpoint 23/23" - DiscordSDK.large_image = "example_game" - DiscordSDK.large_image_text = "Try it now!" - DiscordSDK.small_image = "boss" - DiscordSDK.small_image_text = "Fighting the end boss! D:" - DiscordSDK.end_timestamp = int(Time.get_unix_time_from_system()) + 3600 # +1 hour in unix time + DiscordRPC.large_image = "example_game" + DiscordRPC.large_image_text = "Try it now!" + DiscordRPC.small_image = "boss" + DiscordRPC.small_image_text = "Fighting the end boss! D:" + DiscordRPC.end_timestamp = int(Time.get_unix_time_from_system()) + 3600 # +1 hour in unix time # It is NOT recommended to manage secrets locally! It's meant to be a payload wich the server understands and # returns the other variables like current_party_size, party_id etc. Most of the values must differ from the others. var my_secret: String = str(randi_range(0,999999)) - DiscordSDK.party_id = "mylobbycanbeeverything_" + my_secret - DiscordSDK.current_party_size = 1 - DiscordSDK.max_party_size = 4 - DiscordSDK.match_secret = "m_" + my_secret #better use seeds with 1 to 1 range instead of just chars - DiscordSDK.join_secret = "j_" + my_secret - DiscordSDK.spectate_secret = "s_" + my_secret - DiscordSDK.is_public_party = true - DiscordSDK.instanced = true #required for spectate - #DiscordSDK.start_timestamp = int(Time.get_unix_time_from_system()) - DiscordSDK.register_command("C:\\Users\\yanni\\Desktop\\demo\\DiscordSDK.exe") - #DiscordSDK.register_steam(1389990) - DiscordSDK.refresh() + DiscordRPC.party_id = "mylobbycanbeeverything_" + my_secret + DiscordRPC.current_party_size = 1 + DiscordRPC.max_party_size = 4 + DiscordRPC.match_secret = "m_" + my_secret #better use seeds with 1 to 1 range instead of just chars + DiscordRPC.join_secret = "j_" + my_secret + DiscordRPC.spectate_secret = "s_" + my_secret + DiscordRPC.is_public_party = true + DiscordRPC.instanced = true #required for spectate + #DiscordRPC.start_timestamp = int(Time.get_unix_time_from_system()) + DiscordRPC.register_command("C:\\Users\\yanni\\Desktop\\demo\\DiscordRPC.exe") + #DiscordRPC.register_steam(1389990) + DiscordRPC.refresh() var user_request: Dictionary; @@ -44,13 +44,13 @@ func _on_activity_join_request(user_requesting) -> void: user_request = user_requesting func _on_activity_join(secret) -> void: - if(DiscordSDK.join_secret != secret): - DiscordSDK.current_party_size = clamp(int(secret) + 1, 0, DiscordSDK.max_party_size) - DiscordSDK.party_id = secret.replace("j_","mylobbycanbeeverything_") - DiscordSDK.match_secret = secret.replace("j_","m_") - DiscordSDK.join_secret = secret - DiscordSDK.spectate_secret = secret.replace("j_","s_") - DiscordSDK.refresh() + if(DiscordRPC.join_secret != secret): + DiscordRPC.current_party_size = clamp(int(secret) + 1, 0, DiscordRPC.max_party_size) + DiscordRPC.party_id = secret.replace("j_","mylobbycanbeeverything_") + DiscordRPC.match_secret = secret.replace("j_","m_") + DiscordRPC.join_secret = secret + DiscordRPC.spectate_secret = secret.replace("j_","s_") + DiscordRPC.refresh() func _on_activity_spectate(secret) -> void: print(secret) diff --git a/project/main.tscn b/project/main.tscn index 662b902..fb1cfb8 100644 --- a/project/main.tscn +++ b/project/main.tscn @@ -2,7 +2,7 @@ [ext_resource type="Script" path="res://main.gd" id="1_kl8ri"] [ext_resource type="Texture2D" uid="uid://b3qm246m7pnsx" path="res://assets/Logo_V2.png" id="2_gd222"] -[ext_resource type="Script" path="res://addons/discord-sdk-gd/nodes/debug.gd" id="6_ujijw"] +[ext_resource type="Script" path="res://addons/discord-rpc-gd/nodes/debug.gd" id="6_ujijw"] [node name="Node" type="Node"] script = ExtResource("1_kl8ri") @@ -23,7 +23,7 @@ position = Vector2(789, 330.5) scale = Vector2(0.408203, 0.408203) texture = ExtResource("2_gd222") -[node name="DiscordSDK Test" type="RichTextLabel" parent="."] +[node name="DiscordRPC Test" type="RichTextLabel" parent="."] anchors_preset = -1 anchor_left = 0.293 anchor_top = 0.59 @@ -38,7 +38,7 @@ grow_vertical = 2 size_flags_horizontal = 4 size_flags_vertical = 4 bbcode_enabled = true -text = "[center][font s=60]DiscordSDK Test" +text = "[center][font s=60]DiscordRPC Test" -[node name="DiscordSDKDebug" type="Node" parent="."] +[node name="DiscordRPCDebug" type="Node" parent="."] script = ExtResource("6_ujijw") diff --git a/project/project.godot b/project/project.godot index 9649c03..05a1491 100644 --- a/project/project.godot +++ b/project/project.godot @@ -10,18 +10,18 @@ config_version=5 [application] -config/name="GDExtension DiscordSDK Test Project" +config/name="GDExtension DiscordRPC Test Project" config/tags=PackedStringArray("vaporvee") run/main_scene="res://main.tscn" config/features=PackedStringArray("4.2") boot_splash/bg_color=Color(0.25098, 0.305882, 0.929412, 1) -boot_splash/image="res://assets/Banner_v1.png" +boot_splash/image="res://assets/discordgodot_cover.png" boot_splash/fullsize=false config/icon="res://assets/Logo_V2.png" [autoload] -DiscordSDKLoader="*res://addons/discord-sdk-gd/nodes/discord_autoload.gd" +DiscordRPCLoader="*res://addons/discord-rpc-gd/nodes/discord_autoload.gd" [display] @@ -33,7 +33,7 @@ project/assembly_name="GDExtension Test Project" [editor_plugins] -enabled=PackedStringArray("res://addons/discord-sdk-gd/plugin.cfg") +enabled=PackedStringArray("res://addons/discord-rpc-gd/plugin.cfg") [filesystem] diff --git a/release.py b/release.py index 2855525..b03bc50 100644 --- a/release.py +++ b/release.py @@ -2,21 +2,21 @@ import os import shutil from distutils.dir_util import copy_tree -win_folder_path = "project/addons/discord-sdk-gd/bin/windows" +win_folder_path = "project/addons/discord-rpc-gd/bin/windows" matching_files = [file for file in os.listdir(win_folder_path) if file.endswith(("TMP", "exp", "lib"))] for file in matching_files: file_path = os.path.join(win_folder_path, file) os.remove(file_path) -if os.path.exists("release/ADDON-Discord-SDK-Godot/addons"): - shutil.rmtree("release/ADDON-Discord-SDK-Godot/addons", ignore_errors=True) +if os.path.exists("release/ADDON-Discord-RPC-Godot/addons"): + shutil.rmtree("release/ADDON-Discord-RPC-Godot/addons", ignore_errors=True) -copy_tree("project/addons/", "release/temp/ADDON-Discord-SDK-Godot/addons") +copy_tree("project/addons/", "release/temp/ADDON-Discord-RPC-Godot/addons") -open("release/temp/ADDON-Discord-SDK-Godot/addons/discord-sdk-gd/bin/.gdignore", "a").close() +open("release/temp/ADDON-Discord-RPC-Godot/addons/discord-RPC-gd/bin/.gdignore", "a").close() -shutil.make_archive('release/ADDON-Discord-SDK-Godot', 'zip', 'release/temp/') +shutil.make_archive('release/ADDON-Discord-RPC-Godot', 'zip', 'release/temp/') shutil.rmtree("release/temp/") # Export Demos @@ -34,4 +34,4 @@ shutil.make_archive('release/Demo-Export', 'zip', temp_dir) shutil.rmtree(temp_dir) -print("ADDON-Discord-SDK-Godot.zip and Demo-Export.zip have been created successfully.") +print("ADDON-Discord-RPC-Godot.zip and Demo-Export.zip have been created successfully.") diff --git a/src/discordgodot.cpp b/src/discordgodot.cpp index 7cfc042..c229499 100644 --- a/src/discordgodot.cpp +++ b/src/discordgodot.cpp @@ -3,27 +3,27 @@ #include #include -#define BIND_METHOD(method, ...) godot::ClassDB::bind_method(D_METHOD(#method, ##__VA_ARGS__), &DiscordSDK::method) +#define BIND_METHOD(method, ...) godot::ClassDB::bind_method(D_METHOD(#method, ##__VA_ARGS__), &DiscordRPC::method) #define BIND_SET_GET(property_name, variant_type) \ - godot::ClassDB::bind_method(D_METHOD("get_" #property_name), &DiscordSDK::get_##property_name); \ - godot::ClassDB::bind_method(D_METHOD("set_" #property_name, #variant_type), &DiscordSDK::set_##property_name); \ + godot::ClassDB::bind_method(D_METHOD("get_" #property_name), &DiscordRPC::get_##property_name); \ + godot::ClassDB::bind_method(D_METHOD("set_" #property_name, #variant_type), &DiscordRPC::set_##property_name); \ godot::ClassDB::add_property(get_class_static(), PropertyInfo(variant_type, #property_name), "set_" #property_name, "get_" #property_name) #define BIND_SIGNAL(signal_name, ...) godot::ClassDB::add_signal(get_class_static(), MethodInfo(#signal_name, ##__VA_ARGS__)) #define SET_GET(variable, setter, ...) /*getter isn't mandatory for this project*/ \ - decltype(DiscordSDK::variable) DiscordSDK::get_##variable() { return variable; } \ - void DiscordSDK::set_##variable(decltype(DiscordSDK::variable) value) \ + decltype(DiscordRPC::variable) DiscordRPC::get_##variable() { return variable; } \ + void DiscordRPC::set_##variable(decltype(DiscordRPC::variable) value) \ { \ variable = value; \ setter; \ } -DiscordSDK *DiscordSDK::singleton = nullptr; +DiscordRPC *DiscordRPC::singleton = nullptr; discord::Core *core{}; discord::Result result; discord::Activity activity{}; discord::User user{}; -void DiscordSDK::_bind_methods() +void DiscordRPC::_bind_methods() { BIND_SET_GET(app_id, Variant::INT); BIND_SET_GET(state, Variant::STRING); @@ -51,7 +51,7 @@ void DiscordSDK::_bind_methods() BIND_METHOD(debug); BIND_METHOD(run_callbacks); BIND_METHOD(refresh); - ClassDB::bind_method(D_METHOD("clear", "reset_values"), &DiscordSDK::clear, DEFVAL(false)); + ClassDB::bind_method(D_METHOD("clear", "reset_values"), &DiscordRPC::clear, DEFVAL(false)); BIND_METHOD(unclear); BIND_METHOD(register_command, "command"); BIND_METHOD(register_steam, "steam_id"); @@ -85,13 +85,13 @@ SET_GET(spectate_secret, activity.GetSecrets().SetSpectate(value.utf8().get_data SET_GET(instanced, activity.SetInstance(value)) SET_GET(is_public_party, activity.GetParty().SetPrivacy(static_cast(value))) -DiscordSDK::DiscordSDK() +DiscordRPC::DiscordRPC() { ERR_FAIL_COND(singleton != nullptr); singleton = this; } -DiscordSDK::~DiscordSDK() +DiscordRPC::~DiscordRPC() { app_id = 0; delete core; // couldn't use destructor because it would not compile on linux @@ -100,17 +100,17 @@ DiscordSDK::~DiscordSDK() singleton = nullptr; } -DiscordSDK *DiscordSDK::get_singleton() +DiscordRPC *DiscordRPC::get_singleton() { return singleton; } -void DiscordSDK::run_callbacks() +void DiscordRPC::run_callbacks() { if (result == discord::Result::Ok && app_id > 0) ::core->RunCallbacks(); } -void DiscordSDK::debug() +void DiscordRPC::debug() { result = discord::Core::Create(1080224638845591692, DiscordCreateFlags_NoRequireDiscord, &core); activity.SetState("Test from Godot!"); @@ -128,7 +128,7 @@ void DiscordSDK::debug() UtilityFunctions::push_warning("Discord Activity couldn't be updated. It could be that Discord isn't running!"); } -void DiscordSDK::set_app_id(int64_t value) +void DiscordRPC::set_app_id(int64_t value) { app_id = value; if (app_id > 0) @@ -143,34 +143,34 @@ void DiscordSDK::set_app_id(int64_t value) core->UserManager().GetCurrentUser(&user); }); // signals core->ActivityManager().OnActivityJoin.Connect([](const char *secret) - { DiscordSDK::get_singleton() + { DiscordRPC::get_singleton() ->emit_signal("activity_join", secret); }); core->ActivityManager().OnActivitySpectate.Connect([](const char *secret) - { DiscordSDK::get_singleton() + { DiscordRPC::get_singleton() ->emit_signal("activity_spectate", secret); }); core->ActivityManager().OnActivityJoinRequest.Connect([this](discord::User const &user) - { DiscordSDK::get_singleton() + { DiscordRPC::get_singleton() ->emit_signal("activity_join_request", user2dict(user)); }); core->OverlayManager().OnToggle.Connect([](bool is_locked) - { DiscordSDK::get_singleton() + { DiscordRPC::get_singleton() ->emit_signal("overlay_toggle", is_locked); }); core->RelationshipManager().OnRefresh.Connect([&]() - { DiscordSDK::get_singleton() + { DiscordRPC::get_singleton() ->emit_signal("relationships_init"); }); core->RelationshipManager().OnRelationshipUpdate.Connect([&](discord::Relationship const &relationship) - { DiscordSDK::get_singleton() + { DiscordRPC::get_singleton() ->emit_signal("updated_relationship", relationship2dict(relationship)); }); } } } -int64_t DiscordSDK::get_app_id() +int64_t DiscordRPC::get_app_id() { if (app_id != 0) return app_id; return old_app_id; } -void DiscordSDK::refresh() +void DiscordRPC::refresh() { if (get_is_discord_working()) { @@ -182,7 +182,7 @@ void DiscordSDK::refresh() UtilityFunctions::push_warning("Discord Activity couldn't be updated. It could be that Discord isn't running!"); } -void DiscordSDK::clear(bool reset_values = false) +void DiscordRPC::clear(bool reset_values = false) { if (get_is_discord_working()) { @@ -216,7 +216,7 @@ void DiscordSDK::clear(bool reset_values = false) } } -void DiscordSDK::unclear() +void DiscordRPC::unclear() { if (old_app_id > 0) { @@ -228,69 +228,69 @@ void DiscordSDK::unclear() UtilityFunctions::push_warning("Discord Activity couldn't be uncleared. Maybe it didn't get cleared before?"); } -bool DiscordSDK::get_is_overlay_enabled() +bool DiscordRPC::get_is_overlay_enabled() { bool ie; if (get_is_discord_working()) core->OverlayManager().IsEnabled(&ie); return ie; } -bool DiscordSDK::get_is_overlay_locked() +bool DiscordRPC::get_is_overlay_locked() { bool il; if (get_is_discord_working()) core->OverlayManager().IsLocked(&il); return il; } -void DiscordSDK::set_is_overlay_locked(bool value) +void DiscordRPC::set_is_overlay_locked(bool value) { is_overlay_locked = value; if (get_is_discord_working()) core->OverlayManager().SetLocked(value, {}); } -void DiscordSDK::open_invite_overlay(bool is_spectate) +void DiscordRPC::open_invite_overlay(bool is_spectate) { if (get_is_discord_working()) core->OverlayManager().OpenActivityInvite(static_cast(is_spectate + 1), {}); } -void DiscordSDK::open_server_invite_overlay(String invite_code) +void DiscordRPC::open_server_invite_overlay(String invite_code) { if (get_is_discord_working()) core->OverlayManager().OpenGuildInvite(invite_code.utf8().get_data(), {}); } -void DiscordSDK::open_voice_settings() +void DiscordRPC::open_voice_settings() { if (get_is_discord_working()) core->OverlayManager().OpenVoiceSettings({}); } -void DiscordSDK::accept_join_request(int64_t user_id) +void DiscordRPC::accept_join_request(int64_t user_id) { if (get_is_discord_working()) core->ActivityManager().SendRequestReply(user_id, static_cast(1), {}); } -void DiscordSDK::send_invite(int64_t user_id, bool is_spectate = false, String message_content = "") +void DiscordRPC::send_invite(int64_t user_id, bool is_spectate = false, String message_content = "") { if (get_is_discord_working()) core->ActivityManager().SendInvite(user_id, static_cast(is_spectate + 1), message_content.utf8().get_data(), {}); } -void DiscordSDK::accept_invite(int64_t user_id) +void DiscordRPC::accept_invite(int64_t user_id) { if (get_is_discord_working()) core->ActivityManager().AcceptInvite(user_id, {}); } -void DiscordSDK::register_command(String value) +void DiscordRPC::register_command(String value) { if (get_is_discord_working()) core->ActivityManager().RegisterCommand(value.utf8().get_data()); } -void DiscordSDK::register_steam(int32_t value) +void DiscordRPC::register_steam(int32_t value) { if (get_is_discord_working()) core->ActivityManager().RegisterSteam(value); } -Dictionary DiscordSDK::get_current_user() +Dictionary DiscordRPC::get_current_user() { Dictionary userdict; if (get_is_discord_working()) @@ -302,7 +302,7 @@ Dictionary DiscordSDK::get_current_user() return userdict; } -Dictionary DiscordSDK::get_relationship(int64_t user_id) +Dictionary DiscordRPC::get_relationship(int64_t user_id) { if (get_is_discord_working()) { @@ -314,7 +314,7 @@ Dictionary DiscordSDK::get_relationship(int64_t user_id) return dict; } -Array DiscordSDK::get_all_relationships() +Array DiscordRPC::get_all_relationships() { Array all_relationships; core->RelationshipManager().Filter( @@ -331,12 +331,12 @@ Array DiscordSDK::get_all_relationships() return all_relationships; } -int DiscordSDK::get_result_int() +int DiscordRPC::get_result_int() { return static_cast(result); } -Dictionary DiscordSDK::user2dict(discord::User user) +Dictionary DiscordRPC::user2dict(discord::User user) { Dictionary userdict; userdict["avatar"] = user.GetAvatar(); // can be empty when user has no avatar @@ -352,7 +352,7 @@ Dictionary DiscordSDK::user2dict(discord::User user) return userdict; } -Dictionary DiscordSDK::relationship2dict(discord::Relationship relationship) +Dictionary DiscordRPC::relationship2dict(discord::Relationship relationship) { Dictionary dict_relationship; Dictionary presence; @@ -424,7 +424,7 @@ Dictionary DiscordSDK::relationship2dict(discord::Relationship relationship) return dict_relationship; } -bool DiscordSDK::get_is_discord_working() +bool DiscordRPC::get_is_discord_working() { return result == discord::Result::Ok && app_id > 0; } \ No newline at end of file diff --git a/src/discordgodot.h b/src/discordgodot.h index a0db287..c34995e 100644 --- a/src/discordgodot.h +++ b/src/discordgodot.h @@ -13,21 +13,21 @@ using namespace godot; -class DiscordSDK : public Object +class DiscordRPC : public Object { - GDCLASS(DiscordSDK, Object); + GDCLASS(DiscordRPC, Object); - static DiscordSDK *singleton; + static DiscordRPC *singleton; protected: static void _bind_methods(); public: - static DiscordSDK * + static DiscordRPC * get_singleton(); - DiscordSDK(); - ~DiscordSDK(); + DiscordRPC(); + ~DiscordRPC(); // INTERBNAL int64_t old_app_id; diff --git a/src/lib/discord_game_sdk/bin/discord_game_sdk.bundle b/src/lib/discord_game_sdk/bin/discord_game_sdk.bundle new file mode 100644 index 0000000..3402426 Binary files /dev/null and b/src/lib/discord_game_sdk/bin/discord_game_sdk.bundle differ diff --git a/src/lib/discord_game_sdk/bin/discord_game_sdk.dll b/src/lib/discord_game_sdk/bin/discord_game_sdk.dll new file mode 100644 index 0000000..be946ea Binary files /dev/null and b/src/lib/discord_game_sdk/bin/discord_game_sdk.dll differ diff --git a/src/lib/discord_game_sdk/bin/discord_game_sdk.dylib b/src/lib/discord_game_sdk/bin/discord_game_sdk.dylib new file mode 100644 index 0000000..3402426 Binary files /dev/null and b/src/lib/discord_game_sdk/bin/discord_game_sdk.dylib differ diff --git a/src/lib/discord_game_sdk/bin/discord_game_sdk_aarch64.dylib b/src/lib/discord_game_sdk/bin/discord_game_sdk_aarch64.dylib new file mode 100644 index 0000000..8f08606 Binary files /dev/null and b/src/lib/discord_game_sdk/bin/discord_game_sdk_aarch64.dylib differ diff --git a/src/lib/discord_game_sdk/bin/discord_game_sdk_x86.dll b/src/lib/discord_game_sdk/bin/discord_game_sdk_x86.dll new file mode 100644 index 0000000..45b9bb1 Binary files /dev/null and b/src/lib/discord_game_sdk/bin/discord_game_sdk_x86.dll differ diff --git a/src/lib/discord_game_sdk/bin/libdiscord_game_sdk.so b/src/lib/discord_game_sdk/bin/libdiscord_game_sdk.so new file mode 100644 index 0000000..9dacf94 Binary files /dev/null and b/src/lib/discord_game_sdk/bin/libdiscord_game_sdk.so differ diff --git a/src/lib/discord_game_sdk/cpp/achievement_manager.cpp b/src/lib/discord_game_sdk/cpp/achievement_manager.cpp new file mode 100644 index 0000000..43a6d4c --- /dev/null +++ b/src/lib/discord_game_sdk/cpp/achievement_manager.cpp @@ -0,0 +1,99 @@ +#if !defined(_CRT_SECURE_NO_WARNINGS) +#define _CRT_SECURE_NO_WARNINGS +#endif + +#include "achievement_manager.h" + +#include "core.h" + +#include +#include + +namespace discord { + +class AchievementEvents final { +public: + static void DISCORD_CALLBACK OnUserAchievementUpdate(void* callbackData, + DiscordUserAchievement* userAchievement) + { + auto* core = reinterpret_cast(callbackData); + if (!core) { + return; + } + + auto& module = core->AchievementManager(); + module.OnUserAchievementUpdate(*reinterpret_cast(userAchievement)); + } +}; + +IDiscordAchievementEvents AchievementManager::events_{ + &AchievementEvents::OnUserAchievementUpdate, +}; + +void AchievementManager::SetUserAchievement(Snowflake achievementId, + std::uint8_t percentComplete, + std::function callback) +{ + static auto wrapper = [](void* callbackData, EDiscordResult result) -> void { + std::unique_ptr> cb( + reinterpret_cast*>(callbackData)); + if (!cb || !(*cb)) { + return; + } + (*cb)(static_cast(result)); + }; + std::unique_ptr> cb{}; + cb.reset(new std::function(std::move(callback))); + internal_->set_user_achievement( + internal_, achievementId, percentComplete, cb.release(), wrapper); +} + +void AchievementManager::FetchUserAchievements(std::function callback) +{ + static auto wrapper = [](void* callbackData, EDiscordResult result) -> void { + std::unique_ptr> cb( + reinterpret_cast*>(callbackData)); + if (!cb || !(*cb)) { + return; + } + (*cb)(static_cast(result)); + }; + std::unique_ptr> cb{}; + cb.reset(new std::function(std::move(callback))); + internal_->fetch_user_achievements(internal_, cb.release(), wrapper); +} + +void AchievementManager::CountUserAchievements(std::int32_t* count) +{ + if (!count) { + return; + } + + internal_->count_user_achievements(internal_, reinterpret_cast(count)); +} + +Result AchievementManager::GetUserAchievement(Snowflake userAchievementId, + UserAchievement* userAchievement) +{ + if (!userAchievement) { + return Result::InternalError; + } + + auto result = internal_->get_user_achievement( + internal_, userAchievementId, reinterpret_cast(userAchievement)); + return static_cast(result); +} + +Result AchievementManager::GetUserAchievementAt(std::int32_t index, + UserAchievement* userAchievement) +{ + if (!userAchievement) { + return Result::InternalError; + } + + auto result = internal_->get_user_achievement_at( + internal_, index, reinterpret_cast(userAchievement)); + return static_cast(result); +} + +} // namespace discord diff --git a/src/lib/discord_game_sdk/cpp/achievement_manager.h b/src/lib/discord_game_sdk/cpp/achievement_manager.h new file mode 100644 index 0000000..1f58c8e --- /dev/null +++ b/src/lib/discord_game_sdk/cpp/achievement_manager.h @@ -0,0 +1,34 @@ +#pragma once + +#include "types.h" + +namespace discord { + +class AchievementManager final { +public: + ~AchievementManager() = default; + + void SetUserAchievement(Snowflake achievementId, + std::uint8_t percentComplete, + std::function callback); + void FetchUserAchievements(std::function callback); + void CountUserAchievements(std::int32_t* count); + Result GetUserAchievement(Snowflake userAchievementId, UserAchievement* userAchievement); + Result GetUserAchievementAt(std::int32_t index, UserAchievement* userAchievement); + + Event OnUserAchievementUpdate; + +private: + friend class Core; + + AchievementManager() = default; + AchievementManager(AchievementManager const& rhs) = delete; + AchievementManager& operator=(AchievementManager const& rhs) = delete; + AchievementManager(AchievementManager&& rhs) = delete; + AchievementManager& operator=(AchievementManager&& rhs) = delete; + + IDiscordAchievementManager* internal_; + static IDiscordAchievementEvents events_; +}; + +} // namespace discord diff --git a/src/lib/discord_game_sdk/cpp/activity_manager.cpp b/src/lib/discord_game_sdk/cpp/activity_manager.cpp new file mode 100644 index 0000000..3c20074 --- /dev/null +++ b/src/lib/discord_game_sdk/cpp/activity_manager.cpp @@ -0,0 +1,177 @@ +#if !defined(_CRT_SECURE_NO_WARNINGS) +#define _CRT_SECURE_NO_WARNINGS +#endif + +#include "activity_manager.h" + +#include "core.h" + +#include +#include + +namespace discord { + +class ActivityEvents final { +public: + static void DISCORD_CALLBACK OnActivityJoin(void* callbackData, char const* secret) + { + auto* core = reinterpret_cast(callbackData); + if (!core) { + return; + } + + auto& module = core->ActivityManager(); + module.OnActivityJoin(static_cast(secret)); + } + + static void DISCORD_CALLBACK OnActivitySpectate(void* callbackData, char const* secret) + { + auto* core = reinterpret_cast(callbackData); + if (!core) { + return; + } + + auto& module = core->ActivityManager(); + module.OnActivitySpectate(static_cast(secret)); + } + + static void DISCORD_CALLBACK OnActivityJoinRequest(void* callbackData, DiscordUser* user) + { + auto* core = reinterpret_cast(callbackData); + if (!core) { + return; + } + + auto& module = core->ActivityManager(); + module.OnActivityJoinRequest(*reinterpret_cast(user)); + } + + static void DISCORD_CALLBACK OnActivityInvite(void* callbackData, + EDiscordActivityActionType type, + DiscordUser* user, + DiscordActivity* activity) + { + auto* core = reinterpret_cast(callbackData); + if (!core) { + return; + } + + auto& module = core->ActivityManager(); + module.OnActivityInvite(static_cast(type), + *reinterpret_cast(user), + *reinterpret_cast(activity)); + } +}; + +IDiscordActivityEvents ActivityManager::events_{ + &ActivityEvents::OnActivityJoin, + &ActivityEvents::OnActivitySpectate, + &ActivityEvents::OnActivityJoinRequest, + &ActivityEvents::OnActivityInvite, +}; + +Result ActivityManager::RegisterCommand(char const* command) +{ + auto result = internal_->register_command(internal_, const_cast(command)); + return static_cast(result); +} + +Result ActivityManager::RegisterSteam(std::uint32_t steamId) +{ + auto result = internal_->register_steam(internal_, steamId); + return static_cast(result); +} + +void ActivityManager::UpdateActivity(Activity const& activity, std::function callback) +{ + static auto wrapper = [](void* callbackData, EDiscordResult result) -> void { + std::unique_ptr> cb( + reinterpret_cast*>(callbackData)); + if (!cb || !(*cb)) { + return; + } + (*cb)(static_cast(result)); + }; + std::unique_ptr> cb{}; + cb.reset(new std::function(std::move(callback))); + internal_->update_activity(internal_, + reinterpret_cast(const_cast(&activity)), + cb.release(), + wrapper); +} + +void ActivityManager::ClearActivity(std::function callback) +{ + static auto wrapper = [](void* callbackData, EDiscordResult result) -> void { + std::unique_ptr> cb( + reinterpret_cast*>(callbackData)); + if (!cb || !(*cb)) { + return; + } + (*cb)(static_cast(result)); + }; + std::unique_ptr> cb{}; + cb.reset(new std::function(std::move(callback))); + internal_->clear_activity(internal_, cb.release(), wrapper); +} + +void ActivityManager::SendRequestReply(UserId userId, + ActivityJoinRequestReply reply, + std::function callback) +{ + static auto wrapper = [](void* callbackData, EDiscordResult result) -> void { + std::unique_ptr> cb( + reinterpret_cast*>(callbackData)); + if (!cb || !(*cb)) { + return; + } + (*cb)(static_cast(result)); + }; + std::unique_ptr> cb{}; + cb.reset(new std::function(std::move(callback))); + internal_->send_request_reply(internal_, + userId, + static_cast(reply), + cb.release(), + wrapper); +} + +void ActivityManager::SendInvite(UserId userId, + ActivityActionType type, + char const* content, + std::function callback) +{ + static auto wrapper = [](void* callbackData, EDiscordResult result) -> void { + std::unique_ptr> cb( + reinterpret_cast*>(callbackData)); + if (!cb || !(*cb)) { + return; + } + (*cb)(static_cast(result)); + }; + std::unique_ptr> cb{}; + cb.reset(new std::function(std::move(callback))); + internal_->send_invite(internal_, + userId, + static_cast(type), + const_cast(content), + cb.release(), + wrapper); +} + +void ActivityManager::AcceptInvite(UserId userId, std::function callback) +{ + static auto wrapper = [](void* callbackData, EDiscordResult result) -> void { + std::unique_ptr> cb( + reinterpret_cast*>(callbackData)); + if (!cb || !(*cb)) { + return; + } + (*cb)(static_cast(result)); + }; + std::unique_ptr> cb{}; + cb.reset(new std::function(std::move(callback))); + internal_->accept_invite(internal_, userId, cb.release(), wrapper); +} + +} // namespace discord diff --git a/src/lib/discord_game_sdk/cpp/activity_manager.h b/src/lib/discord_game_sdk/cpp/activity_manager.h new file mode 100644 index 0000000..c107be2 --- /dev/null +++ b/src/lib/discord_game_sdk/cpp/activity_manager.h @@ -0,0 +1,42 @@ +#pragma once + +#include "types.h" + +namespace discord { + +class ActivityManager final { +public: + ~ActivityManager() = default; + + Result RegisterCommand(char const* command); + Result RegisterSteam(std::uint32_t steamId); + void UpdateActivity(Activity const& activity, std::function callback); + void ClearActivity(std::function callback); + void SendRequestReply(UserId userId, + ActivityJoinRequestReply reply, + std::function callback); + void SendInvite(UserId userId, + ActivityActionType type, + char const* content, + std::function callback); + void AcceptInvite(UserId userId, std::function callback); + + Event OnActivityJoin; + Event OnActivitySpectate; + Event OnActivityJoinRequest; + Event OnActivityInvite; + +private: + friend class Core; + + ActivityManager() = default; + ActivityManager(ActivityManager const& rhs) = delete; + ActivityManager& operator=(ActivityManager const& rhs) = delete; + ActivityManager(ActivityManager&& rhs) = delete; + ActivityManager& operator=(ActivityManager&& rhs) = delete; + + IDiscordActivityManager* internal_; + static IDiscordActivityEvents events_; +}; + +} // namespace discord diff --git a/src/lib/discord_game_sdk/cpp/application_manager.cpp b/src/lib/discord_game_sdk/cpp/application_manager.cpp new file mode 100644 index 0000000..0e05f3f --- /dev/null +++ b/src/lib/discord_game_sdk/cpp/application_manager.cpp @@ -0,0 +1,78 @@ +#if !defined(_CRT_SECURE_NO_WARNINGS) +#define _CRT_SECURE_NO_WARNINGS +#endif + +#include "application_manager.h" + +#include "core.h" + +#include +#include + +namespace discord { + +void ApplicationManager::ValidateOrExit(std::function callback) +{ + static auto wrapper = [](void* callbackData, EDiscordResult result) -> void { + std::unique_ptr> cb( + reinterpret_cast*>(callbackData)); + if (!cb || !(*cb)) { + return; + } + (*cb)(static_cast(result)); + }; + std::unique_ptr> cb{}; + cb.reset(new std::function(std::move(callback))); + internal_->validate_or_exit(internal_, cb.release(), wrapper); +} + +void ApplicationManager::GetCurrentLocale(char locale[128]) +{ + if (!locale) { + return; + } + + internal_->get_current_locale(internal_, reinterpret_cast(locale)); +} + +void ApplicationManager::GetCurrentBranch(char branch[4096]) +{ + if (!branch) { + return; + } + + internal_->get_current_branch(internal_, reinterpret_cast(branch)); +} + +void ApplicationManager::GetOAuth2Token(std::function callback) +{ + static auto wrapper = + [](void* callbackData, EDiscordResult result, DiscordOAuth2Token* oauth2Token) -> void { + std::unique_ptr> cb( + reinterpret_cast*>(callbackData)); + if (!cb || !(*cb)) { + return; + } + (*cb)(static_cast(result), *reinterpret_cast(oauth2Token)); + }; + std::unique_ptr> cb{}; + cb.reset(new std::function(std::move(callback))); + internal_->get_oauth2_token(internal_, cb.release(), wrapper); +} + +void ApplicationManager::GetTicket(std::function callback) +{ + static auto wrapper = [](void* callbackData, EDiscordResult result, char const* data) -> void { + std::unique_ptr> cb( + reinterpret_cast*>(callbackData)); + if (!cb || !(*cb)) { + return; + } + (*cb)(static_cast(result), static_cast(data)); + }; + std::unique_ptr> cb{}; + cb.reset(new std::function(std::move(callback))); + internal_->get_ticket(internal_, cb.release(), wrapper); +} + +} // namespace discord diff --git a/src/lib/discord_game_sdk/cpp/application_manager.h b/src/lib/discord_game_sdk/cpp/application_manager.h new file mode 100644 index 0000000..ab0e856 --- /dev/null +++ b/src/lib/discord_game_sdk/cpp/application_manager.h @@ -0,0 +1,30 @@ +#pragma once + +#include "types.h" + +namespace discord { + +class ApplicationManager final { +public: + ~ApplicationManager() = default; + + void ValidateOrExit(std::function callback); + void GetCurrentLocale(char locale[128]); + void GetCurrentBranch(char branch[4096]); + void GetOAuth2Token(std::function callback); + void GetTicket(std::function callback); + +private: + friend class Core; + + ApplicationManager() = default; + ApplicationManager(ApplicationManager const& rhs) = delete; + ApplicationManager& operator=(ApplicationManager const& rhs) = delete; + ApplicationManager(ApplicationManager&& rhs) = delete; + ApplicationManager& operator=(ApplicationManager&& rhs) = delete; + + IDiscordApplicationManager* internal_; + static IDiscordApplicationEvents events_; +}; + +} // namespace discord diff --git a/src/lib/discord_game_sdk/cpp/core.cpp b/src/lib/discord_game_sdk/cpp/core.cpp new file mode 100644 index 0000000..110c9ef --- /dev/null +++ b/src/lib/discord_game_sdk/cpp/core.cpp @@ -0,0 +1,182 @@ +#if !defined(_CRT_SECURE_NO_WARNINGS) +#define _CRT_SECURE_NO_WARNINGS +#endif + +#include "core.h" + +#include +#include + +namespace discord { + +Result Core::Create(ClientId clientId, std::uint64_t flags, Core** instance) +{ + if (!instance) { + return Result::InternalError; + } + + (*instance) = new Core(); + DiscordCreateParams params{}; + DiscordCreateParamsSetDefault(¶ms); + params.client_id = clientId; + params.flags = flags; + params.events = nullptr; + params.event_data = *instance; + params.user_events = &UserManager::events_; + params.activity_events = &ActivityManager::events_; + params.relationship_events = &RelationshipManager::events_; + params.lobby_events = &LobbyManager::events_; + params.network_events = &NetworkManager::events_; + params.overlay_events = &OverlayManager::events_; + params.store_events = &StoreManager::events_; + params.voice_events = &VoiceManager::events_; + params.achievement_events = &AchievementManager::events_; + auto result = DiscordCreate(DISCORD_VERSION, ¶ms, &((*instance)->internal_)); + if (result != DiscordResult_Ok || !(*instance)->internal_) { + delete (*instance); + (*instance) = nullptr; + } + + return static_cast(result); +} + +Core::~Core() +{ + if (internal_) { + internal_->destroy(internal_); + internal_ = nullptr; + } +} + +Result Core::RunCallbacks() +{ + auto result = internal_->run_callbacks(internal_); + return static_cast(result); +} + +void Core::SetLogHook(LogLevel minLevel, std::function hook) +{ + setLogHook_.DisconnectAll(); + setLogHook_.Connect(std::move(hook)); + static auto wrapper = + [](void* callbackData, EDiscordLogLevel level, char const* message) -> void { + auto cb(reinterpret_cast(callbackData)); + if (!cb) { + return; + } + (*cb)(static_cast(level), static_cast(message)); + }; + + internal_->set_log_hook( + internal_, static_cast(minLevel), &setLogHook_, wrapper); +} + +discord::ApplicationManager& Core::ApplicationManager() +{ + if (!applicationManager_.internal_) { + applicationManager_.internal_ = internal_->get_application_manager(internal_); + } + + return applicationManager_; +} + +discord::UserManager& Core::UserManager() +{ + if (!userManager_.internal_) { + userManager_.internal_ = internal_->get_user_manager(internal_); + } + + return userManager_; +} + +discord::ImageManager& Core::ImageManager() +{ + if (!imageManager_.internal_) { + imageManager_.internal_ = internal_->get_image_manager(internal_); + } + + return imageManager_; +} + +discord::ActivityManager& Core::ActivityManager() +{ + if (!activityManager_.internal_) { + activityManager_.internal_ = internal_->get_activity_manager(internal_); + } + + return activityManager_; +} + +discord::RelationshipManager& Core::RelationshipManager() +{ + if (!relationshipManager_.internal_) { + relationshipManager_.internal_ = internal_->get_relationship_manager(internal_); + } + + return relationshipManager_; +} + +discord::LobbyManager& Core::LobbyManager() +{ + if (!lobbyManager_.internal_) { + lobbyManager_.internal_ = internal_->get_lobby_manager(internal_); + } + + return lobbyManager_; +} + +discord::NetworkManager& Core::NetworkManager() +{ + if (!networkManager_.internal_) { + networkManager_.internal_ = internal_->get_network_manager(internal_); + } + + return networkManager_; +} + +discord::OverlayManager& Core::OverlayManager() +{ + if (!overlayManager_.internal_) { + overlayManager_.internal_ = internal_->get_overlay_manager(internal_); + } + + return overlayManager_; +} + +discord::StorageManager& Core::StorageManager() +{ + if (!storageManager_.internal_) { + storageManager_.internal_ = internal_->get_storage_manager(internal_); + } + + return storageManager_; +} + +discord::StoreManager& Core::StoreManager() +{ + if (!storeManager_.internal_) { + storeManager_.internal_ = internal_->get_store_manager(internal_); + } + + return storeManager_; +} + +discord::VoiceManager& Core::VoiceManager() +{ + if (!voiceManager_.internal_) { + voiceManager_.internal_ = internal_->get_voice_manager(internal_); + } + + return voiceManager_; +} + +discord::AchievementManager& Core::AchievementManager() +{ + if (!achievementManager_.internal_) { + achievementManager_.internal_ = internal_->get_achievement_manager(internal_); + } + + return achievementManager_; +} + +} // namespace discord diff --git a/src/lib/discord_game_sdk/cpp/core.h b/src/lib/discord_game_sdk/cpp/core.h new file mode 100644 index 0000000..8af6fca --- /dev/null +++ b/src/lib/discord_game_sdk/cpp/core.h @@ -0,0 +1,64 @@ +#pragma once + +#include "types.h" +#include "application_manager.h" +#include "user_manager.h" +#include "image_manager.h" +#include "activity_manager.h" +#include "relationship_manager.h" +#include "lobby_manager.h" +#include "network_manager.h" +#include "overlay_manager.h" +#include "storage_manager.h" +#include "store_manager.h" +#include "voice_manager.h" +#include "achievement_manager.h" + +namespace discord { + +class Core final { +public: + static Result Create(ClientId clientId, std::uint64_t flags, Core** instance); + + ~Core(); + + Result RunCallbacks(); + void SetLogHook(LogLevel minLevel, std::function hook); + + discord::ApplicationManager& ApplicationManager(); + discord::UserManager& UserManager(); + discord::ImageManager& ImageManager(); + discord::ActivityManager& ActivityManager(); + discord::RelationshipManager& RelationshipManager(); + discord::LobbyManager& LobbyManager(); + discord::NetworkManager& NetworkManager(); + discord::OverlayManager& OverlayManager(); + discord::StorageManager& StorageManager(); + discord::StoreManager& StoreManager(); + discord::VoiceManager& VoiceManager(); + discord::AchievementManager& AchievementManager(); + +private: + Core() = default; + Core(Core const& rhs) = delete; + Core& operator=(Core const& rhs) = delete; + Core(Core&& rhs) = delete; + Core& operator=(Core&& rhs) = delete; + + IDiscordCore* internal_; + Event setLogHook_; + discord::ApplicationManager applicationManager_; + discord::UserManager userManager_; + discord::ImageManager imageManager_; + discord::ActivityManager activityManager_; + discord::RelationshipManager relationshipManager_; + discord::LobbyManager lobbyManager_; + discord::NetworkManager networkManager_; + discord::OverlayManager overlayManager_; + discord::StorageManager storageManager_; + discord::StoreManager storeManager_; + discord::VoiceManager voiceManager_; + discord::AchievementManager achievementManager_; +}; + +} // namespace discord diff --git a/src/lib/discord_game_sdk/cpp/discord.h b/src/lib/discord_game_sdk/cpp/discord.h new file mode 100644 index 0000000..c991212 --- /dev/null +++ b/src/lib/discord_game_sdk/cpp/discord.h @@ -0,0 +1,16 @@ +#pragma once + +#include "types.h" +#include "core.h" +#include "application_manager.h" +#include "user_manager.h" +#include "image_manager.h" +#include "activity_manager.h" +#include "relationship_manager.h" +#include "lobby_manager.h" +#include "network_manager.h" +#include "overlay_manager.h" +#include "storage_manager.h" +#include "store_manager.h" +#include "voice_manager.h" +#include "achievement_manager.h" diff --git a/src/lib/discord_game_sdk/cpp/event.h b/src/lib/discord_game_sdk/cpp/event.h new file mode 100644 index 0000000..610887d --- /dev/null +++ b/src/lib/discord_game_sdk/cpp/event.h @@ -0,0 +1,59 @@ +#pragma once + +#include +#include + +namespace discord { + +template +class Event final { +public: + using Token = int; + + Event() { slots_.reserve(4); } + + Event(Event const&) = default; + Event(Event&&) = default; + ~Event() = default; + + Event& operator=(Event const&) = default; + Event& operator=(Event&&) = default; + + template + Token Connect(EventHandler slot) + { + slots_.emplace_back(Slot{nextToken_, std::move(slot)}); + return nextToken_++; + } + + void Disconnect(Token token) + { + for (auto& slot : slots_) { + if (slot.token == token) { + slot = slots_.back(); + slots_.pop_back(); + break; + } + } + } + + void DisconnectAll() { slots_ = {}; } + + void operator()(Args... args) + { + for (auto const& slot : slots_) { + slot.fn(std::forward(args)...); + } + } + +private: + struct Slot { + Token token; + std::function fn; + }; + + Token nextToken_{}; + std::vector slots_{}; +}; + +} // namespace discord diff --git a/src/lib/discord_game_sdk/cpp/ffi.h b/src/lib/discord_game_sdk/cpp/ffi.h new file mode 100644 index 0000000..4a21057 --- /dev/null +++ b/src/lib/discord_game_sdk/cpp/ffi.h @@ -0,0 +1,1113 @@ +#ifndef _DISCORD_GAME_SDK_H_ +#define _DISCORD_GAME_SDK_H_ + +#ifdef _WIN32 +#include +#include +#endif + +#ifdef _WIN32 +#ifdef _WIN64 +#define DISCORD_API +#else +#define DISCORD_API __stdcall +#endif +#else +#define DISCORD_API +#endif + +#define DISCORD_CALLBACK DISCORD_API + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include +#ifndef __cplusplus +#include +#endif + +#define DISCORD_VERSION 3 +#define DISCORD_APPLICATION_MANAGER_VERSION 1 +#define DISCORD_USER_MANAGER_VERSION 1 +#define DISCORD_IMAGE_MANAGER_VERSION 1 +#define DISCORD_ACTIVITY_MANAGER_VERSION 1 +#define DISCORD_RELATIONSHIP_MANAGER_VERSION 1 +#define DISCORD_LOBBY_MANAGER_VERSION 1 +#define DISCORD_NETWORK_MANAGER_VERSION 1 +#define DISCORD_OVERLAY_MANAGER_VERSION 2 +#define DISCORD_STORAGE_MANAGER_VERSION 1 +#define DISCORD_STORE_MANAGER_VERSION 1 +#define DISCORD_VOICE_MANAGER_VERSION 1 +#define DISCORD_ACHIEVEMENT_MANAGER_VERSION 1 + +enum EDiscordResult { + DiscordResult_Ok = 0, + DiscordResult_ServiceUnavailable = 1, + DiscordResult_InvalidVersion = 2, + DiscordResult_LockFailed = 3, + DiscordResult_InternalError = 4, + DiscordResult_InvalidPayload = 5, + DiscordResult_InvalidCommand = 6, + DiscordResult_InvalidPermissions = 7, + DiscordResult_NotFetched = 8, + DiscordResult_NotFound = 9, + DiscordResult_Conflict = 10, + DiscordResult_InvalidSecret = 11, + DiscordResult_InvalidJoinSecret = 12, + DiscordResult_NoEligibleActivity = 13, + DiscordResult_InvalidInvite = 14, + DiscordResult_NotAuthenticated = 15, + DiscordResult_InvalidAccessToken = 16, + DiscordResult_ApplicationMismatch = 17, + DiscordResult_InvalidDataUrl = 18, + DiscordResult_InvalidBase64 = 19, + DiscordResult_NotFiltered = 20, + DiscordResult_LobbyFull = 21, + DiscordResult_InvalidLobbySecret = 22, + DiscordResult_InvalidFilename = 23, + DiscordResult_InvalidFileSize = 24, + DiscordResult_InvalidEntitlement = 25, + DiscordResult_NotInstalled = 26, + DiscordResult_NotRunning = 27, + DiscordResult_InsufficientBuffer = 28, + DiscordResult_PurchaseCanceled = 29, + DiscordResult_InvalidGuild = 30, + DiscordResult_InvalidEvent = 31, + DiscordResult_InvalidChannel = 32, + DiscordResult_InvalidOrigin = 33, + DiscordResult_RateLimited = 34, + DiscordResult_OAuth2Error = 35, + DiscordResult_SelectChannelTimeout = 36, + DiscordResult_GetGuildTimeout = 37, + DiscordResult_SelectVoiceForceRequired = 38, + DiscordResult_CaptureShortcutAlreadyListening = 39, + DiscordResult_UnauthorizedForAchievement = 40, + DiscordResult_InvalidGiftCode = 41, + DiscordResult_PurchaseError = 42, + DiscordResult_TransactionAborted = 43, + DiscordResult_DrawingInitFailed = 44, +}; + +enum EDiscordCreateFlags { + DiscordCreateFlags_Default = 0, + DiscordCreateFlags_NoRequireDiscord = 1, +}; + +enum EDiscordLogLevel { + DiscordLogLevel_Error = 1, + DiscordLogLevel_Warn, + DiscordLogLevel_Info, + DiscordLogLevel_Debug, +}; + +enum EDiscordUserFlag { + DiscordUserFlag_Partner = 2, + DiscordUserFlag_HypeSquadEvents = 4, + DiscordUserFlag_HypeSquadHouse1 = 64, + DiscordUserFlag_HypeSquadHouse2 = 128, + DiscordUserFlag_HypeSquadHouse3 = 256, +}; + +enum EDiscordPremiumType { + DiscordPremiumType_None = 0, + DiscordPremiumType_Tier1 = 1, + DiscordPremiumType_Tier2 = 2, +}; + +enum EDiscordImageType { + DiscordImageType_User, +}; + +enum EDiscordActivityPartyPrivacy { + DiscordActivityPartyPrivacy_Private = 0, + DiscordActivityPartyPrivacy_Public = 1, +}; + +enum EDiscordActivityType { + DiscordActivityType_Playing, + DiscordActivityType_Streaming, + DiscordActivityType_Listening, + DiscordActivityType_Watching, +}; + +enum EDiscordActivityActionType { + DiscordActivityActionType_Join = 1, + DiscordActivityActionType_Spectate, +}; + +enum EDiscordActivitySupportedPlatformFlags { + DiscordActivitySupportedPlatformFlags_Desktop = 1, + DiscordActivitySupportedPlatformFlags_Android = 2, + DiscordActivitySupportedPlatformFlags_iOS = 4, +}; + +enum EDiscordActivityJoinRequestReply { + DiscordActivityJoinRequestReply_No, + DiscordActivityJoinRequestReply_Yes, + DiscordActivityJoinRequestReply_Ignore, +}; + +enum EDiscordStatus { + DiscordStatus_Offline = 0, + DiscordStatus_Online = 1, + DiscordStatus_Idle = 2, + DiscordStatus_DoNotDisturb = 3, +}; + +enum EDiscordRelationshipType { + DiscordRelationshipType_None, + DiscordRelationshipType_Friend, + DiscordRelationshipType_Blocked, + DiscordRelationshipType_PendingIncoming, + DiscordRelationshipType_PendingOutgoing, + DiscordRelationshipType_Implicit, +}; + +enum EDiscordLobbyType { + DiscordLobbyType_Private = 1, + DiscordLobbyType_Public, +}; + +enum EDiscordLobbySearchComparison { + DiscordLobbySearchComparison_LessThanOrEqual = -2, + DiscordLobbySearchComparison_LessThan, + DiscordLobbySearchComparison_Equal, + DiscordLobbySearchComparison_GreaterThan, + DiscordLobbySearchComparison_GreaterThanOrEqual, + DiscordLobbySearchComparison_NotEqual, +}; + +enum EDiscordLobbySearchCast { + DiscordLobbySearchCast_String = 1, + DiscordLobbySearchCast_Number, +}; + +enum EDiscordLobbySearchDistance { + DiscordLobbySearchDistance_Local, + DiscordLobbySearchDistance_Default, + DiscordLobbySearchDistance_Extended, + DiscordLobbySearchDistance_Global, +}; + +enum EDiscordKeyVariant { + DiscordKeyVariant_Normal, + DiscordKeyVariant_Right, + DiscordKeyVariant_Left, +}; + +enum EDiscordMouseButton { + DiscordMouseButton_Left, + DiscordMouseButton_Middle, + DiscordMouseButton_Right, +}; + +enum EDiscordEntitlementType { + DiscordEntitlementType_Purchase = 1, + DiscordEntitlementType_PremiumSubscription, + DiscordEntitlementType_DeveloperGift, + DiscordEntitlementType_TestModePurchase, + DiscordEntitlementType_FreePurchase, + DiscordEntitlementType_UserGift, + DiscordEntitlementType_PremiumPurchase, +}; + +enum EDiscordSkuType { + DiscordSkuType_Application = 1, + DiscordSkuType_DLC, + DiscordSkuType_Consumable, + DiscordSkuType_Bundle, +}; + +enum EDiscordInputModeType { + DiscordInputModeType_VoiceActivity = 0, + DiscordInputModeType_PushToTalk, +}; + +typedef int64_t DiscordClientId; +typedef int32_t DiscordVersion; +typedef int64_t DiscordSnowflake; +typedef int64_t DiscordTimestamp; +typedef DiscordSnowflake DiscordUserId; +typedef char DiscordLocale[128]; +typedef char DiscordBranch[4096]; +typedef DiscordSnowflake DiscordLobbyId; +typedef char DiscordLobbySecret[128]; +typedef char DiscordMetadataKey[256]; +typedef char DiscordMetadataValue[4096]; +typedef uint64_t DiscordNetworkPeerId; +typedef uint8_t DiscordNetworkChannelId; +#ifdef __APPLE__ +typedef void IDXGISwapChain; +#endif +#ifdef __linux__ +typedef void IDXGISwapChain; +#endif +#ifdef __APPLE__ +typedef void MSG; +#endif +#ifdef __linux__ +typedef void MSG; +#endif +typedef char DiscordPath[4096]; +typedef char DiscordDateTime[64]; + +struct DiscordUser { + DiscordUserId id; + char username[256]; + char discriminator[8]; + char avatar[128]; + bool bot; +}; + +struct DiscordOAuth2Token { + char access_token[128]; + char scopes[1024]; + DiscordTimestamp expires; +}; + +struct DiscordImageHandle { + enum EDiscordImageType type; + int64_t id; + uint32_t size; +}; + +struct DiscordImageDimensions { + uint32_t width; + uint32_t height; +}; + +struct DiscordActivityTimestamps { + DiscordTimestamp start; + DiscordTimestamp end; +}; + +struct DiscordActivityAssets { + char large_image[128]; + char large_text[128]; + char small_image[128]; + char small_text[128]; +}; + +struct DiscordPartySize { + int32_t current_size; + int32_t max_size; +}; + +struct DiscordActivityParty { + char id[128]; + struct DiscordPartySize size; + enum EDiscordActivityPartyPrivacy privacy; +}; + +struct DiscordActivitySecrets { + char match[128]; + char join[128]; + char spectate[128]; +}; + +struct DiscordActivity { + enum EDiscordActivityType type; + int64_t application_id; + char name[128]; + char state[128]; + char details[128]; + struct DiscordActivityTimestamps timestamps; + struct DiscordActivityAssets assets; + struct DiscordActivityParty party; + struct DiscordActivitySecrets secrets; + bool instance; + uint32_t supported_platforms; +}; + +struct DiscordPresence { + enum EDiscordStatus status; + struct DiscordActivity activity; +}; + +struct DiscordRelationship { + enum EDiscordRelationshipType type; + struct DiscordUser user; + struct DiscordPresence presence; +}; + +struct DiscordLobby { + DiscordLobbyId id; + enum EDiscordLobbyType type; + DiscordUserId owner_id; + DiscordLobbySecret secret; + uint32_t capacity; + bool locked; +}; + +struct DiscordImeUnderline { + int32_t from; + int32_t to; + uint32_t color; + uint32_t background_color; + bool thick; +}; + +struct DiscordRect { + int32_t left; + int32_t top; + int32_t right; + int32_t bottom; +}; + +struct DiscordFileStat { + char filename[260]; + uint64_t size; + uint64_t last_modified; +}; + +struct DiscordEntitlement { + DiscordSnowflake id; + enum EDiscordEntitlementType type; + DiscordSnowflake sku_id; +}; + +struct DiscordSkuPrice { + uint32_t amount; + char currency[16]; +}; + +struct DiscordSku { + DiscordSnowflake id; + enum EDiscordSkuType type; + char name[256]; + struct DiscordSkuPrice price; +}; + +struct DiscordInputMode { + enum EDiscordInputModeType type; + char shortcut[256]; +}; + +struct DiscordUserAchievement { + DiscordSnowflake user_id; + DiscordSnowflake achievement_id; + uint8_t percent_complete; + DiscordDateTime unlocked_at; +}; + +struct IDiscordLobbyTransaction { + enum EDiscordResult(DISCORD_API* set_type)(struct IDiscordLobbyTransaction* lobby_transaction, + enum EDiscordLobbyType type); + enum EDiscordResult(DISCORD_API* set_owner)(struct IDiscordLobbyTransaction* lobby_transaction, + DiscordUserId owner_id); + enum EDiscordResult(DISCORD_API* set_capacity)( + struct IDiscordLobbyTransaction* lobby_transaction, + uint32_t capacity); + enum EDiscordResult(DISCORD_API* set_metadata)( + struct IDiscordLobbyTransaction* lobby_transaction, + DiscordMetadataKey key, + DiscordMetadataValue value); + enum EDiscordResult(DISCORD_API* delete_metadata)( + struct IDiscordLobbyTransaction* lobby_transaction, + DiscordMetadataKey key); + enum EDiscordResult(DISCORD_API* set_locked)(struct IDiscordLobbyTransaction* lobby_transaction, + bool locked); +}; + +struct IDiscordLobbyMemberTransaction { + enum EDiscordResult(DISCORD_API* set_metadata)( + struct IDiscordLobbyMemberTransaction* lobby_member_transaction, + DiscordMetadataKey key, + DiscordMetadataValue value); + enum EDiscordResult(DISCORD_API* delete_metadata)( + struct IDiscordLobbyMemberTransaction* lobby_member_transaction, + DiscordMetadataKey key); +}; + +struct IDiscordLobbySearchQuery { + enum EDiscordResult(DISCORD_API* filter)(struct IDiscordLobbySearchQuery* lobby_search_query, + DiscordMetadataKey key, + enum EDiscordLobbySearchComparison comparison, + enum EDiscordLobbySearchCast cast, + DiscordMetadataValue value); + enum EDiscordResult(DISCORD_API* sort)(struct IDiscordLobbySearchQuery* lobby_search_query, + DiscordMetadataKey key, + enum EDiscordLobbySearchCast cast, + DiscordMetadataValue value); + enum EDiscordResult(DISCORD_API* limit)(struct IDiscordLobbySearchQuery* lobby_search_query, + uint32_t limit); + enum EDiscordResult(DISCORD_API* distance)(struct IDiscordLobbySearchQuery* lobby_search_query, + enum EDiscordLobbySearchDistance distance); +}; + +typedef void* IDiscordApplicationEvents; + +struct IDiscordApplicationManager { + void(DISCORD_API* validate_or_exit)(struct IDiscordApplicationManager* manager, + void* callback_data, + void(DISCORD_API* callback)(void* callback_data, + enum EDiscordResult result)); + void(DISCORD_API* get_current_locale)(struct IDiscordApplicationManager* manager, + DiscordLocale* locale); + void(DISCORD_API* get_current_branch)(struct IDiscordApplicationManager* manager, + DiscordBranch* branch); + void(DISCORD_API* get_oauth2_token)( + struct IDiscordApplicationManager* manager, + void* callback_data, + void(DISCORD_API* callback)(void* callback_data, + enum EDiscordResult result, + struct DiscordOAuth2Token* oauth2_token)); + void(DISCORD_API* get_ticket)(struct IDiscordApplicationManager* manager, + void* callback_data, + void(DISCORD_API* callback)(void* callback_data, + enum EDiscordResult result, + const char* data)); +}; + +struct IDiscordUserEvents { + void(DISCORD_API* on_current_user_update)(void* event_data); +}; + +struct IDiscordUserManager { + enum EDiscordResult(DISCORD_API* get_current_user)(struct IDiscordUserManager* manager, + struct DiscordUser* current_user); + void(DISCORD_API* get_user)(struct IDiscordUserManager* manager, + DiscordUserId user_id, + void* callback_data, + void(DISCORD_API* callback)(void* callback_data, + enum EDiscordResult result, + struct DiscordUser* user)); + enum EDiscordResult(DISCORD_API* get_current_user_premium_type)( + struct IDiscordUserManager* manager, + enum EDiscordPremiumType* premium_type); + enum EDiscordResult(DISCORD_API* current_user_has_flag)(struct IDiscordUserManager* manager, + enum EDiscordUserFlag flag, + bool* has_flag); +}; + +typedef void* IDiscordImageEvents; + +struct IDiscordImageManager { + void(DISCORD_API* fetch)(struct IDiscordImageManager* manager, + struct DiscordImageHandle handle, + bool refresh, + void* callback_data, + void(DISCORD_API* callback)(void* callback_data, + enum EDiscordResult result, + struct DiscordImageHandle handle_result)); + enum EDiscordResult(DISCORD_API* get_dimensions)(struct IDiscordImageManager* manager, + struct DiscordImageHandle handle, + struct DiscordImageDimensions* dimensions); + enum EDiscordResult(DISCORD_API* get_data)(struct IDiscordImageManager* manager, + struct DiscordImageHandle handle, + uint8_t* data, + uint32_t data_length); +}; + +struct IDiscordActivityEvents { + void(DISCORD_API* on_activity_join)(void* event_data, const char* secret); + void(DISCORD_API* on_activity_spectate)(void* event_data, const char* secret); + void(DISCORD_API* on_activity_join_request)(void* event_data, struct DiscordUser* user); + void(DISCORD_API* on_activity_invite)(void* event_data, + enum EDiscordActivityActionType type, + struct DiscordUser* user, + struct DiscordActivity* activity); +}; + +struct IDiscordActivityManager { + enum EDiscordResult(DISCORD_API* register_command)(struct IDiscordActivityManager* manager, + const char* command); + enum EDiscordResult(DISCORD_API* register_steam)(struct IDiscordActivityManager* manager, + uint32_t steam_id); + void(DISCORD_API* update_activity)(struct IDiscordActivityManager* manager, + struct DiscordActivity* activity, + void* callback_data, + void(DISCORD_API* callback)(void* callback_data, + enum EDiscordResult result)); + void(DISCORD_API* clear_activity)(struct IDiscordActivityManager* manager, + void* callback_data, + void(DISCORD_API* callback)(void* callback_data, + enum EDiscordResult result)); + void(DISCORD_API* send_request_reply)(struct IDiscordActivityManager* manager, + DiscordUserId user_id, + enum EDiscordActivityJoinRequestReply reply, + void* callback_data, + void(DISCORD_API* callback)(void* callback_data, + enum EDiscordResult result)); + void(DISCORD_API* send_invite)(struct IDiscordActivityManager* manager, + DiscordUserId user_id, + enum EDiscordActivityActionType type, + const char* content, + void* callback_data, + void(DISCORD_API* callback)(void* callback_data, + enum EDiscordResult result)); + void(DISCORD_API* accept_invite)(struct IDiscordActivityManager* manager, + DiscordUserId user_id, + void* callback_data, + void(DISCORD_API* callback)(void* callback_data, + enum EDiscordResult result)); +}; + +struct IDiscordRelationshipEvents { + void(DISCORD_API* on_refresh)(void* event_data); + void(DISCORD_API* on_relationship_update)(void* event_data, + struct DiscordRelationship* relationship); +}; + +struct IDiscordRelationshipManager { + void(DISCORD_API* filter)(struct IDiscordRelationshipManager* manager, + void* filter_data, + bool(DISCORD_API* filter)(void* filter_data, + struct DiscordRelationship* relationship)); + enum EDiscordResult(DISCORD_API* count)(struct IDiscordRelationshipManager* manager, + int32_t* count); + enum EDiscordResult(DISCORD_API* get)(struct IDiscordRelationshipManager* manager, + DiscordUserId user_id, + struct DiscordRelationship* relationship); + enum EDiscordResult(DISCORD_API* get_at)(struct IDiscordRelationshipManager* manager, + uint32_t index, + struct DiscordRelationship* relationship); +}; + +struct IDiscordLobbyEvents { + void(DISCORD_API* on_lobby_update)(void* event_data, int64_t lobby_id); + void(DISCORD_API* on_lobby_delete)(void* event_data, int64_t lobby_id, uint32_t reason); + void(DISCORD_API* on_member_connect)(void* event_data, int64_t lobby_id, int64_t user_id); + void(DISCORD_API* on_member_update)(void* event_data, int64_t lobby_id, int64_t user_id); + void(DISCORD_API* on_member_disconnect)(void* event_data, int64_t lobby_id, int64_t user_id); + void(DISCORD_API* on_lobby_message)(void* event_data, + int64_t lobby_id, + int64_t user_id, + uint8_t* data, + uint32_t data_length); + void(DISCORD_API* on_speaking)(void* event_data, + int64_t lobby_id, + int64_t user_id, + bool speaking); + void(DISCORD_API* on_network_message)(void* event_data, + int64_t lobby_id, + int64_t user_id, + uint8_t channel_id, + uint8_t* data, + uint32_t data_length); +}; + +struct IDiscordLobbyManager { + enum EDiscordResult(DISCORD_API* get_lobby_create_transaction)( + struct IDiscordLobbyManager* manager, + struct IDiscordLobbyTransaction** transaction); + enum EDiscordResult(DISCORD_API* get_lobby_update_transaction)( + struct IDiscordLobbyManager* manager, + DiscordLobbyId lobby_id, + struct IDiscordLobbyTransaction** transaction); + enum EDiscordResult(DISCORD_API* get_member_update_transaction)( + struct IDiscordLobbyManager* manager, + DiscordLobbyId lobby_id, + DiscordUserId user_id, + struct IDiscordLobbyMemberTransaction** transaction); + void(DISCORD_API* create_lobby)(struct IDiscordLobbyManager* manager, + struct IDiscordLobbyTransaction* transaction, + void* callback_data, + void(DISCORD_API* callback)(void* callback_data, + enum EDiscordResult result, + struct DiscordLobby* lobby)); + void(DISCORD_API* update_lobby)(struct IDiscordLobbyManager* manager, + DiscordLobbyId lobby_id, + struct IDiscordLobbyTransaction* transaction, + void* callback_data, + void(DISCORD_API* callback)(void* callback_data, + enum EDiscordResult result)); + void(DISCORD_API* delete_lobby)(struct IDiscordLobbyManager* manager, + DiscordLobbyId lobby_id, + void* callback_data, + void(DISCORD_API* callback)(void* callback_data, + enum EDiscordResult result)); + void(DISCORD_API* connect_lobby)(struct IDiscordLobbyManager* manager, + DiscordLobbyId lobby_id, + DiscordLobbySecret secret, + void* callback_data, + void(DISCORD_API* callback)(void* callback_data, + enum EDiscordResult result, + struct DiscordLobby* lobby)); + void(DISCORD_API* connect_lobby_with_activity_secret)( + struct IDiscordLobbyManager* manager, + DiscordLobbySecret activity_secret, + void* callback_data, + void(DISCORD_API* callback)(void* callback_data, + enum EDiscordResult result, + struct DiscordLobby* lobby)); + void(DISCORD_API* disconnect_lobby)(struct IDiscordLobbyManager* manager, + DiscordLobbyId lobby_id, + void* callback_data, + void(DISCORD_API* callback)(void* callback_data, + enum EDiscordResult result)); + enum EDiscordResult(DISCORD_API* get_lobby)(struct IDiscordLobbyManager* manager, + DiscordLobbyId lobby_id, + struct DiscordLobby* lobby); + enum EDiscordResult(DISCORD_API* get_lobby_activity_secret)( + struct IDiscordLobbyManager* manager, + DiscordLobbyId lobby_id, + DiscordLobbySecret* secret); + enum EDiscordResult(DISCORD_API* get_lobby_metadata_value)(struct IDiscordLobbyManager* manager, + DiscordLobbyId lobby_id, + DiscordMetadataKey key, + DiscordMetadataValue* value); + enum EDiscordResult(DISCORD_API* get_lobby_metadata_key)(struct IDiscordLobbyManager* manager, + DiscordLobbyId lobby_id, + int32_t index, + DiscordMetadataKey* key); + enum EDiscordResult(DISCORD_API* lobby_metadata_count)(struct IDiscordLobbyManager* manager, + DiscordLobbyId lobby_id, + int32_t* count); + enum EDiscordResult(DISCORD_API* member_count)(struct IDiscordLobbyManager* manager, + DiscordLobbyId lobby_id, + int32_t* count); + enum EDiscordResult(DISCORD_API* get_member_user_id)(struct IDiscordLobbyManager* manager, + DiscordLobbyId lobby_id, + int32_t index, + DiscordUserId* user_id); + enum EDiscordResult(DISCORD_API* get_member_user)(struct IDiscordLobbyManager* manager, + DiscordLobbyId lobby_id, + DiscordUserId user_id, + struct DiscordUser* user); + enum EDiscordResult(DISCORD_API* get_member_metadata_value)( + struct IDiscordLobbyManager* manager, + DiscordLobbyId lobby_id, + DiscordUserId user_id, + DiscordMetadataKey key, + DiscordMetadataValue* value); + enum EDiscordResult(DISCORD_API* get_member_metadata_key)(struct IDiscordLobbyManager* manager, + DiscordLobbyId lobby_id, + DiscordUserId user_id, + int32_t index, + DiscordMetadataKey* key); + enum EDiscordResult(DISCORD_API* member_metadata_count)(struct IDiscordLobbyManager* manager, + DiscordLobbyId lobby_id, + DiscordUserId user_id, + int32_t* count); + void(DISCORD_API* update_member)(struct IDiscordLobbyManager* manager, + DiscordLobbyId lobby_id, + DiscordUserId user_id, + struct IDiscordLobbyMemberTransaction* transaction, + void* callback_data, + void(DISCORD_API* callback)(void* callback_data, + enum EDiscordResult result)); + void(DISCORD_API* send_lobby_message)(struct IDiscordLobbyManager* manager, + DiscordLobbyId lobby_id, + uint8_t* data, + uint32_t data_length, + void* callback_data, + void(DISCORD_API* callback)(void* callback_data, + enum EDiscordResult result)); + enum EDiscordResult(DISCORD_API* get_search_query)(struct IDiscordLobbyManager* manager, + struct IDiscordLobbySearchQuery** query); + void(DISCORD_API* search)(struct IDiscordLobbyManager* manager, + struct IDiscordLobbySearchQuery* query, + void* callback_data, + void(DISCORD_API* callback)(void* callback_data, + enum EDiscordResult result)); + void(DISCORD_API* lobby_count)(struct IDiscordLobbyManager* manager, int32_t* count); + enum EDiscordResult(DISCORD_API* get_lobby_id)(struct IDiscordLobbyManager* manager, + int32_t index, + DiscordLobbyId* lobby_id); + void(DISCORD_API* connect_voice)(struct IDiscordLobbyManager* manager, + DiscordLobbyId lobby_id, + void* callback_data, + void(DISCORD_API* callback)(void* callback_data, + enum EDiscordResult result)); + void(DISCORD_API* disconnect_voice)(struct IDiscordLobbyManager* manager, + DiscordLobbyId lobby_id, + void* callback_data, + void(DISCORD_API* callback)(void* callback_data, + enum EDiscordResult result)); + enum EDiscordResult(DISCORD_API* connect_network)(struct IDiscordLobbyManager* manager, + DiscordLobbyId lobby_id); + enum EDiscordResult(DISCORD_API* disconnect_network)(struct IDiscordLobbyManager* manager, + DiscordLobbyId lobby_id); + enum EDiscordResult(DISCORD_API* flush_network)(struct IDiscordLobbyManager* manager); + enum EDiscordResult(DISCORD_API* open_network_channel)(struct IDiscordLobbyManager* manager, + DiscordLobbyId lobby_id, + uint8_t channel_id, + bool reliable); + enum EDiscordResult(DISCORD_API* send_network_message)(struct IDiscordLobbyManager* manager, + DiscordLobbyId lobby_id, + DiscordUserId user_id, + uint8_t channel_id, + uint8_t* data, + uint32_t data_length); +}; + +struct IDiscordNetworkEvents { + void(DISCORD_API* on_message)(void* event_data, + DiscordNetworkPeerId peer_id, + DiscordNetworkChannelId channel_id, + uint8_t* data, + uint32_t data_length); + void(DISCORD_API* on_route_update)(void* event_data, const char* route_data); +}; + +struct IDiscordNetworkManager { + /** + * Get the local peer ID for this process. + */ + void(DISCORD_API* get_peer_id)(struct IDiscordNetworkManager* manager, + DiscordNetworkPeerId* peer_id); + /** + * Send pending network messages. + */ + enum EDiscordResult(DISCORD_API* flush)(struct IDiscordNetworkManager* manager); + /** + * Open a connection to a remote peer. + */ + enum EDiscordResult(DISCORD_API* open_peer)(struct IDiscordNetworkManager* manager, + DiscordNetworkPeerId peer_id, + const char* route_data); + /** + * Update the route data for a connected peer. + */ + enum EDiscordResult(DISCORD_API* update_peer)(struct IDiscordNetworkManager* manager, + DiscordNetworkPeerId peer_id, + const char* route_data); + /** + * Close the connection to a remote peer. + */ + enum EDiscordResult(DISCORD_API* close_peer)(struct IDiscordNetworkManager* manager, + DiscordNetworkPeerId peer_id); + /** + * Open a message channel to a connected peer. + */ + enum EDiscordResult(DISCORD_API* open_channel)(struct IDiscordNetworkManager* manager, + DiscordNetworkPeerId peer_id, + DiscordNetworkChannelId channel_id, + bool reliable); + /** + * Close a message channel to a connected peer. + */ + enum EDiscordResult(DISCORD_API* close_channel)(struct IDiscordNetworkManager* manager, + DiscordNetworkPeerId peer_id, + DiscordNetworkChannelId channel_id); + /** + * Send a message to a connected peer over an opened message channel. + */ + enum EDiscordResult(DISCORD_API* send_message)(struct IDiscordNetworkManager* manager, + DiscordNetworkPeerId peer_id, + DiscordNetworkChannelId channel_id, + uint8_t* data, + uint32_t data_length); +}; + +struct IDiscordOverlayEvents { + void(DISCORD_API* on_toggle)(void* event_data, bool locked); +}; + +struct IDiscordOverlayManager { + void(DISCORD_API* is_enabled)(struct IDiscordOverlayManager* manager, bool* enabled); + void(DISCORD_API* is_locked)(struct IDiscordOverlayManager* manager, bool* locked); + void(DISCORD_API* set_locked)(struct IDiscordOverlayManager* manager, + bool locked, + void* callback_data, + void(DISCORD_API* callback)(void* callback_data, + enum EDiscordResult result)); + void(DISCORD_API* open_activity_invite)( + struct IDiscordOverlayManager* manager, + enum EDiscordActivityActionType type, + void* callback_data, + void(DISCORD_API* callback)(void* callback_data, enum EDiscordResult result)); + void(DISCORD_API* open_guild_invite)(struct IDiscordOverlayManager* manager, + const char* code, + void* callback_data, + void(DISCORD_API* callback)(void* callback_data, + enum EDiscordResult result)); + void(DISCORD_API* open_voice_settings)(struct IDiscordOverlayManager* manager, + void* callback_data, + void(DISCORD_API* callback)(void* callback_data, + enum EDiscordResult result)); + enum EDiscordResult(DISCORD_API* init_drawing_dxgi)(struct IDiscordOverlayManager* manager, + IDXGISwapChain* swapchain, + bool use_message_forwarding); + void(DISCORD_API* on_present)(struct IDiscordOverlayManager* manager); + void(DISCORD_API* forward_message)(struct IDiscordOverlayManager* manager, MSG* message); + void(DISCORD_API* key_event)(struct IDiscordOverlayManager* manager, + bool down, + const char* key_code, + enum EDiscordKeyVariant variant); + void(DISCORD_API* char_event)(struct IDiscordOverlayManager* manager, const char* character); + void(DISCORD_API* mouse_button_event)(struct IDiscordOverlayManager* manager, + uint8_t down, + int32_t click_count, + enum EDiscordMouseButton which, + int32_t x, + int32_t y); + void(DISCORD_API* mouse_motion_event)(struct IDiscordOverlayManager* manager, + int32_t x, + int32_t y); + void(DISCORD_API* ime_commit_text)(struct IDiscordOverlayManager* manager, const char* text); + void(DISCORD_API* ime_set_composition)(struct IDiscordOverlayManager* manager, + const char* text, + struct DiscordImeUnderline* underlines, + uint32_t underlines_length, + int32_t from, + int32_t to); + void(DISCORD_API* ime_cancel_composition)(struct IDiscordOverlayManager* manager); + void(DISCORD_API* set_ime_composition_range_callback)( + struct IDiscordOverlayManager* manager, + void* on_ime_composition_range_changed_data, + void(DISCORD_API* on_ime_composition_range_changed)( + void* on_ime_composition_range_changed_data, + int32_t from, + int32_t to, + struct DiscordRect* bounds, + uint32_t bounds_length)); + void(DISCORD_API* set_ime_selection_bounds_callback)( + struct IDiscordOverlayManager* manager, + void* on_ime_selection_bounds_changed_data, + void(DISCORD_API* on_ime_selection_bounds_changed)(void* on_ime_selection_bounds_changed_data, + struct DiscordRect anchor, + struct DiscordRect focus, + bool is_anchor_first)); + bool(DISCORD_API* is_point_inside_click_zone)(struct IDiscordOverlayManager* manager, + int32_t x, + int32_t y); +}; + +typedef void* IDiscordStorageEvents; + +struct IDiscordStorageManager { + enum EDiscordResult(DISCORD_API* read)(struct IDiscordStorageManager* manager, + const char* name, + uint8_t* data, + uint32_t data_length, + uint32_t* read); + void(DISCORD_API* read_async)(struct IDiscordStorageManager* manager, + const char* name, + void* callback_data, + void(DISCORD_API* callback)(void* callback_data, + enum EDiscordResult result, + uint8_t* data, + uint32_t data_length)); + void(DISCORD_API* read_async_partial)(struct IDiscordStorageManager* manager, + const char* name, + uint64_t offset, + uint64_t length, + void* callback_data, + void(DISCORD_API* callback)(void* callback_data, + enum EDiscordResult result, + uint8_t* data, + uint32_t data_length)); + enum EDiscordResult(DISCORD_API* write)(struct IDiscordStorageManager* manager, + const char* name, + uint8_t* data, + uint32_t data_length); + void(DISCORD_API* write_async)(struct IDiscordStorageManager* manager, + const char* name, + uint8_t* data, + uint32_t data_length, + void* callback_data, + void(DISCORD_API* callback)(void* callback_data, + enum EDiscordResult result)); + enum EDiscordResult(DISCORD_API* delete_)(struct IDiscordStorageManager* manager, + const char* name); + enum EDiscordResult(DISCORD_API* exists)(struct IDiscordStorageManager* manager, + const char* name, + bool* exists); + void(DISCORD_API* count)(struct IDiscordStorageManager* manager, int32_t* count); + enum EDiscordResult(DISCORD_API* stat)(struct IDiscordStorageManager* manager, + const char* name, + struct DiscordFileStat* stat); + enum EDiscordResult(DISCORD_API* stat_at)(struct IDiscordStorageManager* manager, + int32_t index, + struct DiscordFileStat* stat); + enum EDiscordResult(DISCORD_API* get_path)(struct IDiscordStorageManager* manager, + DiscordPath* path); +}; + +struct IDiscordStoreEvents { + void(DISCORD_API* on_entitlement_create)(void* event_data, + struct DiscordEntitlement* entitlement); + void(DISCORD_API* on_entitlement_delete)(void* event_data, + struct DiscordEntitlement* entitlement); +}; + +struct IDiscordStoreManager { + void(DISCORD_API* fetch_skus)(struct IDiscordStoreManager* manager, + void* callback_data, + void(DISCORD_API* callback)(void* callback_data, + enum EDiscordResult result)); + void(DISCORD_API* count_skus)(struct IDiscordStoreManager* manager, int32_t* count); + enum EDiscordResult(DISCORD_API* get_sku)(struct IDiscordStoreManager* manager, + DiscordSnowflake sku_id, + struct DiscordSku* sku); + enum EDiscordResult(DISCORD_API* get_sku_at)(struct IDiscordStoreManager* manager, + int32_t index, + struct DiscordSku* sku); + void(DISCORD_API* fetch_entitlements)(struct IDiscordStoreManager* manager, + void* callback_data, + void(DISCORD_API* callback)(void* callback_data, + enum EDiscordResult result)); + void(DISCORD_API* count_entitlements)(struct IDiscordStoreManager* manager, int32_t* count); + enum EDiscordResult(DISCORD_API* get_entitlement)(struct IDiscordStoreManager* manager, + DiscordSnowflake entitlement_id, + struct DiscordEntitlement* entitlement); + enum EDiscordResult(DISCORD_API* get_entitlement_at)(struct IDiscordStoreManager* manager, + int32_t index, + struct DiscordEntitlement* entitlement); + enum EDiscordResult(DISCORD_API* has_sku_entitlement)(struct IDiscordStoreManager* manager, + DiscordSnowflake sku_id, + bool* has_entitlement); + void(DISCORD_API* start_purchase)(struct IDiscordStoreManager* manager, + DiscordSnowflake sku_id, + void* callback_data, + void(DISCORD_API* callback)(void* callback_data, + enum EDiscordResult result)); +}; + +struct IDiscordVoiceEvents { + void(DISCORD_API* on_settings_update)(void* event_data); +}; + +struct IDiscordVoiceManager { + enum EDiscordResult(DISCORD_API* get_input_mode)(struct IDiscordVoiceManager* manager, + struct DiscordInputMode* input_mode); + void(DISCORD_API* set_input_mode)(struct IDiscordVoiceManager* manager, + struct DiscordInputMode input_mode, + void* callback_data, + void(DISCORD_API* callback)(void* callback_data, + enum EDiscordResult result)); + enum EDiscordResult(DISCORD_API* is_self_mute)(struct IDiscordVoiceManager* manager, + bool* mute); + enum EDiscordResult(DISCORD_API* set_self_mute)(struct IDiscordVoiceManager* manager, + bool mute); + enum EDiscordResult(DISCORD_API* is_self_deaf)(struct IDiscordVoiceManager* manager, + bool* deaf); + enum EDiscordResult(DISCORD_API* set_self_deaf)(struct IDiscordVoiceManager* manager, + bool deaf); + enum EDiscordResult(DISCORD_API* is_local_mute)(struct IDiscordVoiceManager* manager, + DiscordSnowflake user_id, + bool* mute); + enum EDiscordResult(DISCORD_API* set_local_mute)(struct IDiscordVoiceManager* manager, + DiscordSnowflake user_id, + bool mute); + enum EDiscordResult(DISCORD_API* get_local_volume)(struct IDiscordVoiceManager* manager, + DiscordSnowflake user_id, + uint8_t* volume); + enum EDiscordResult(DISCORD_API* set_local_volume)(struct IDiscordVoiceManager* manager, + DiscordSnowflake user_id, + uint8_t volume); +}; + +struct IDiscordAchievementEvents { + void(DISCORD_API* on_user_achievement_update)(void* event_data, + struct DiscordUserAchievement* user_achievement); +}; + +struct IDiscordAchievementManager { + void(DISCORD_API* set_user_achievement)( + struct IDiscordAchievementManager* manager, + DiscordSnowflake achievement_id, + uint8_t percent_complete, + void* callback_data, + void(DISCORD_API* callback)(void* callback_data, enum EDiscordResult result)); + void(DISCORD_API* fetch_user_achievements)( + struct IDiscordAchievementManager* manager, + void* callback_data, + void(DISCORD_API* callback)(void* callback_data, enum EDiscordResult result)); + void(DISCORD_API* count_user_achievements)(struct IDiscordAchievementManager* manager, + int32_t* count); + enum EDiscordResult(DISCORD_API* get_user_achievement)( + struct IDiscordAchievementManager* manager, + DiscordSnowflake user_achievement_id, + struct DiscordUserAchievement* user_achievement); + enum EDiscordResult(DISCORD_API* get_user_achievement_at)( + struct IDiscordAchievementManager* manager, + int32_t index, + struct DiscordUserAchievement* user_achievement); +}; + +typedef void* IDiscordCoreEvents; + +struct IDiscordCore { + void(DISCORD_API* destroy)(struct IDiscordCore* core); + enum EDiscordResult(DISCORD_API* run_callbacks)(struct IDiscordCore* core); + void(DISCORD_API* set_log_hook)(struct IDiscordCore* core, + enum EDiscordLogLevel min_level, + void* hook_data, + void(DISCORD_API* hook)(void* hook_data, + enum EDiscordLogLevel level, + const char* message)); + struct IDiscordApplicationManager*(DISCORD_API* get_application_manager)( + struct IDiscordCore* core); + struct IDiscordUserManager*(DISCORD_API* get_user_manager)(struct IDiscordCore* core); + struct IDiscordImageManager*(DISCORD_API* get_image_manager)(struct IDiscordCore* core); + struct IDiscordActivityManager*(DISCORD_API* get_activity_manager)(struct IDiscordCore* core); + struct IDiscordRelationshipManager*(DISCORD_API* get_relationship_manager)( + struct IDiscordCore* core); + struct IDiscordLobbyManager*(DISCORD_API* get_lobby_manager)(struct IDiscordCore* core); + struct IDiscordNetworkManager*(DISCORD_API* get_network_manager)(struct IDiscordCore* core); + struct IDiscordOverlayManager*(DISCORD_API* get_overlay_manager)(struct IDiscordCore* core); + struct IDiscordStorageManager*(DISCORD_API* get_storage_manager)(struct IDiscordCore* core); + struct IDiscordStoreManager*(DISCORD_API* get_store_manager)(struct IDiscordCore* core); + struct IDiscordVoiceManager*(DISCORD_API* get_voice_manager)(struct IDiscordCore* core); + struct IDiscordAchievementManager*(DISCORD_API* get_achievement_manager)( + struct IDiscordCore* core); +}; + +struct DiscordCreateParams { + DiscordClientId client_id; + uint64_t flags; + IDiscordCoreEvents* events; + void* event_data; + IDiscordApplicationEvents* application_events; + DiscordVersion application_version; + struct IDiscordUserEvents* user_events; + DiscordVersion user_version; + IDiscordImageEvents* image_events; + DiscordVersion image_version; + struct IDiscordActivityEvents* activity_events; + DiscordVersion activity_version; + struct IDiscordRelationshipEvents* relationship_events; + DiscordVersion relationship_version; + struct IDiscordLobbyEvents* lobby_events; + DiscordVersion lobby_version; + struct IDiscordNetworkEvents* network_events; + DiscordVersion network_version; + struct IDiscordOverlayEvents* overlay_events; + DiscordVersion overlay_version; + IDiscordStorageEvents* storage_events; + DiscordVersion storage_version; + struct IDiscordStoreEvents* store_events; + DiscordVersion store_version; + struct IDiscordVoiceEvents* voice_events; + DiscordVersion voice_version; + struct IDiscordAchievementEvents* achievement_events; + DiscordVersion achievement_version; +}; + +#ifdef __cplusplus +inline +#else +static +#endif + void + DiscordCreateParamsSetDefault(struct DiscordCreateParams* params) +{ + memset(params, 0, sizeof(struct DiscordCreateParams)); + params->application_version = DISCORD_APPLICATION_MANAGER_VERSION; + params->user_version = DISCORD_USER_MANAGER_VERSION; + params->image_version = DISCORD_IMAGE_MANAGER_VERSION; + params->activity_version = DISCORD_ACTIVITY_MANAGER_VERSION; + params->relationship_version = DISCORD_RELATIONSHIP_MANAGER_VERSION; + params->lobby_version = DISCORD_LOBBY_MANAGER_VERSION; + params->network_version = DISCORD_NETWORK_MANAGER_VERSION; + params->overlay_version = DISCORD_OVERLAY_MANAGER_VERSION; + params->storage_version = DISCORD_STORAGE_MANAGER_VERSION; + params->store_version = DISCORD_STORE_MANAGER_VERSION; + params->voice_version = DISCORD_VOICE_MANAGER_VERSION; + params->achievement_version = DISCORD_ACHIEVEMENT_MANAGER_VERSION; +} + +enum EDiscordResult DISCORD_API DiscordCreate(DiscordVersion version, + struct DiscordCreateParams* params, + struct IDiscordCore** result); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/src/lib/discord_game_sdk/cpp/image_manager.cpp b/src/lib/discord_game_sdk/cpp/image_manager.cpp new file mode 100644 index 0000000..03b1db4 --- /dev/null +++ b/src/lib/discord_game_sdk/cpp/image_manager.cpp @@ -0,0 +1,57 @@ +#if !defined(_CRT_SECURE_NO_WARNINGS) +#define _CRT_SECURE_NO_WARNINGS +#endif + +#include "image_manager.h" + +#include "core.h" + +#include +#include + +namespace discord { + +void ImageManager::Fetch(ImageHandle handle, + bool refresh, + std::function callback) +{ + static auto wrapper = + [](void* callbackData, EDiscordResult result, DiscordImageHandle handleResult) -> void { + std::unique_ptr> cb( + reinterpret_cast*>(callbackData)); + if (!cb || !(*cb)) { + return; + } + (*cb)(static_cast(result), *reinterpret_cast(&handleResult)); + }; + std::unique_ptr> cb{}; + cb.reset(new std::function(std::move(callback))); + internal_->fetch(internal_, + *reinterpret_cast(&handle), + (refresh ? 1 : 0), + cb.release(), + wrapper); +} + +Result ImageManager::GetDimensions(ImageHandle handle, ImageDimensions* dimensions) +{ + if (!dimensions) { + return Result::InternalError; + } + + auto result = internal_->get_dimensions(internal_, + *reinterpret_cast(&handle), + reinterpret_cast(dimensions)); + return static_cast(result); +} + +Result ImageManager::GetData(ImageHandle handle, std::uint8_t* data, std::uint32_t dataLength) +{ + auto result = internal_->get_data(internal_, + *reinterpret_cast(&handle), + reinterpret_cast(data), + dataLength); + return static_cast(result); +} + +} // namespace discord diff --git a/src/lib/discord_game_sdk/cpp/image_manager.h b/src/lib/discord_game_sdk/cpp/image_manager.h new file mode 100644 index 0000000..b096b17 --- /dev/null +++ b/src/lib/discord_game_sdk/cpp/image_manager.h @@ -0,0 +1,28 @@ +#pragma once + +#include "types.h" + +namespace discord { + +class ImageManager final { +public: + ~ImageManager() = default; + + void Fetch(ImageHandle handle, bool refresh, std::function callback); + Result GetDimensions(ImageHandle handle, ImageDimensions* dimensions); + Result GetData(ImageHandle handle, std::uint8_t* data, std::uint32_t dataLength); + +private: + friend class Core; + + ImageManager() = default; + ImageManager(ImageManager const& rhs) = delete; + ImageManager& operator=(ImageManager const& rhs) = delete; + ImageManager(ImageManager&& rhs) = delete; + ImageManager& operator=(ImageManager&& rhs) = delete; + + IDiscordImageManager* internal_; + static IDiscordImageEvents events_; +}; + +} // namespace discord diff --git a/src/lib/discord_game_sdk/cpp/lobby_manager.cpp b/src/lib/discord_game_sdk/cpp/lobby_manager.cpp new file mode 100644 index 0000000..3a95b1a --- /dev/null +++ b/src/lib/discord_game_sdk/cpp/lobby_manager.cpp @@ -0,0 +1,554 @@ +#if !defined(_CRT_SECURE_NO_WARNINGS) +#define _CRT_SECURE_NO_WARNINGS +#endif + +#include "lobby_manager.h" + +#include "core.h" + +#include +#include + +namespace discord { + +class LobbyEvents final { +public: + static void DISCORD_CALLBACK OnLobbyUpdate(void* callbackData, int64_t lobbyId) + { + auto* core = reinterpret_cast(callbackData); + if (!core) { + return; + } + + auto& module = core->LobbyManager(); + module.OnLobbyUpdate(lobbyId); + } + + static void DISCORD_CALLBACK OnLobbyDelete(void* callbackData, int64_t lobbyId, uint32_t reason) + { + auto* core = reinterpret_cast(callbackData); + if (!core) { + return; + } + + auto& module = core->LobbyManager(); + module.OnLobbyDelete(lobbyId, reason); + } + + static void DISCORD_CALLBACK OnMemberConnect(void* callbackData, + int64_t lobbyId, + int64_t userId) + { + auto* core = reinterpret_cast(callbackData); + if (!core) { + return; + } + + auto& module = core->LobbyManager(); + module.OnMemberConnect(lobbyId, userId); + } + + static void DISCORD_CALLBACK OnMemberUpdate(void* callbackData, int64_t lobbyId, int64_t userId) + { + auto* core = reinterpret_cast(callbackData); + if (!core) { + return; + } + + auto& module = core->LobbyManager(); + module.OnMemberUpdate(lobbyId, userId); + } + + static void DISCORD_CALLBACK OnMemberDisconnect(void* callbackData, + int64_t lobbyId, + int64_t userId) + { + auto* core = reinterpret_cast(callbackData); + if (!core) { + return; + } + + auto& module = core->LobbyManager(); + module.OnMemberDisconnect(lobbyId, userId); + } + + static void DISCORD_CALLBACK OnLobbyMessage(void* callbackData, + int64_t lobbyId, + int64_t userId, + uint8_t* data, + uint32_t dataLength) + { + auto* core = reinterpret_cast(callbackData); + if (!core) { + return; + } + + auto& module = core->LobbyManager(); + module.OnLobbyMessage(lobbyId, userId, data, dataLength); + } + + static void DISCORD_CALLBACK OnSpeaking(void* callbackData, + int64_t lobbyId, + int64_t userId, + bool speaking) + { + auto* core = reinterpret_cast(callbackData); + if (!core) { + return; + } + + auto& module = core->LobbyManager(); + module.OnSpeaking(lobbyId, userId, (speaking != 0)); + } + + static void DISCORD_CALLBACK OnNetworkMessage(void* callbackData, + int64_t lobbyId, + int64_t userId, + uint8_t channelId, + uint8_t* data, + uint32_t dataLength) + { + auto* core = reinterpret_cast(callbackData); + if (!core) { + return; + } + + auto& module = core->LobbyManager(); + module.OnNetworkMessage(lobbyId, userId, channelId, data, dataLength); + } +}; + +IDiscordLobbyEvents LobbyManager::events_{ + &LobbyEvents::OnLobbyUpdate, + &LobbyEvents::OnLobbyDelete, + &LobbyEvents::OnMemberConnect, + &LobbyEvents::OnMemberUpdate, + &LobbyEvents::OnMemberDisconnect, + &LobbyEvents::OnLobbyMessage, + &LobbyEvents::OnSpeaking, + &LobbyEvents::OnNetworkMessage, +}; + +Result LobbyManager::GetLobbyCreateTransaction(LobbyTransaction* transaction) +{ + if (!transaction) { + return Result::InternalError; + } + + auto result = internal_->get_lobby_create_transaction(internal_, transaction->Receive()); + return static_cast(result); +} + +Result LobbyManager::GetLobbyUpdateTransaction(LobbyId lobbyId, LobbyTransaction* transaction) +{ + if (!transaction) { + return Result::InternalError; + } + + auto result = + internal_->get_lobby_update_transaction(internal_, lobbyId, transaction->Receive()); + return static_cast(result); +} + +Result LobbyManager::GetMemberUpdateTransaction(LobbyId lobbyId, + UserId userId, + LobbyMemberTransaction* transaction) +{ + if (!transaction) { + return Result::InternalError; + } + + auto result = + internal_->get_member_update_transaction(internal_, lobbyId, userId, transaction->Receive()); + return static_cast(result); +} + +void LobbyManager::CreateLobby(LobbyTransaction const& transaction, + std::function callback) +{ + static auto wrapper = + [](void* callbackData, EDiscordResult result, DiscordLobby* lobby) -> void { + std::unique_ptr> cb( + reinterpret_cast*>(callbackData)); + if (!cb || !(*cb)) { + return; + } + (*cb)(static_cast(result), *reinterpret_cast(lobby)); + }; + std::unique_ptr> cb{}; + cb.reset(new std::function(std::move(callback))); + internal_->create_lobby( + internal_, const_cast(transaction).Internal(), cb.release(), wrapper); +} + +void LobbyManager::UpdateLobby(LobbyId lobbyId, + LobbyTransaction const& transaction, + std::function callback) +{ + static auto wrapper = [](void* callbackData, EDiscordResult result) -> void { + std::unique_ptr> cb( + reinterpret_cast*>(callbackData)); + if (!cb || !(*cb)) { + return; + } + (*cb)(static_cast(result)); + }; + std::unique_ptr> cb{}; + cb.reset(new std::function(std::move(callback))); + internal_->update_lobby(internal_, + lobbyId, + const_cast(transaction).Internal(), + cb.release(), + wrapper); +} + +void LobbyManager::DeleteLobby(LobbyId lobbyId, std::function callback) +{ + static auto wrapper = [](void* callbackData, EDiscordResult result) -> void { + std::unique_ptr> cb( + reinterpret_cast*>(callbackData)); + if (!cb || !(*cb)) { + return; + } + (*cb)(static_cast(result)); + }; + std::unique_ptr> cb{}; + cb.reset(new std::function(std::move(callback))); + internal_->delete_lobby(internal_, lobbyId, cb.release(), wrapper); +} + +void LobbyManager::ConnectLobby(LobbyId lobbyId, + LobbySecret secret, + std::function callback) +{ + static auto wrapper = + [](void* callbackData, EDiscordResult result, DiscordLobby* lobby) -> void { + std::unique_ptr> cb( + reinterpret_cast*>(callbackData)); + if (!cb || !(*cb)) { + return; + } + (*cb)(static_cast(result), *reinterpret_cast(lobby)); + }; + std::unique_ptr> cb{}; + cb.reset(new std::function(std::move(callback))); + internal_->connect_lobby(internal_, lobbyId, const_cast(secret), cb.release(), wrapper); +} + +void LobbyManager::ConnectLobbyWithActivitySecret( + LobbySecret activitySecret, + std::function callback) +{ + static auto wrapper = + [](void* callbackData, EDiscordResult result, DiscordLobby* lobby) -> void { + std::unique_ptr> cb( + reinterpret_cast*>(callbackData)); + if (!cb || !(*cb)) { + return; + } + (*cb)(static_cast(result), *reinterpret_cast(lobby)); + }; + std::unique_ptr> cb{}; + cb.reset(new std::function(std::move(callback))); + internal_->connect_lobby_with_activity_secret( + internal_, const_cast(activitySecret), cb.release(), wrapper); +} + +void LobbyManager::DisconnectLobby(LobbyId lobbyId, std::function callback) +{ + static auto wrapper = [](void* callbackData, EDiscordResult result) -> void { + std::unique_ptr> cb( + reinterpret_cast*>(callbackData)); + if (!cb || !(*cb)) { + return; + } + (*cb)(static_cast(result)); + }; + std::unique_ptr> cb{}; + cb.reset(new std::function(std::move(callback))); + internal_->disconnect_lobby(internal_, lobbyId, cb.release(), wrapper); +} + +Result LobbyManager::GetLobby(LobbyId lobbyId, Lobby* lobby) +{ + if (!lobby) { + return Result::InternalError; + } + + auto result = internal_->get_lobby(internal_, lobbyId, reinterpret_cast(lobby)); + return static_cast(result); +} + +Result LobbyManager::GetLobbyActivitySecret(LobbyId lobbyId, char secret[128]) +{ + if (!secret) { + return Result::InternalError; + } + + auto result = internal_->get_lobby_activity_secret( + internal_, lobbyId, reinterpret_cast(secret)); + return static_cast(result); +} + +Result LobbyManager::GetLobbyMetadataValue(LobbyId lobbyId, MetadataKey key, char value[4096]) +{ + if (!value) { + return Result::InternalError; + } + + auto result = internal_->get_lobby_metadata_value( + internal_, lobbyId, const_cast(key), reinterpret_cast(value)); + return static_cast(result); +} + +Result LobbyManager::GetLobbyMetadataKey(LobbyId lobbyId, std::int32_t index, char key[256]) +{ + if (!key) { + return Result::InternalError; + } + + auto result = internal_->get_lobby_metadata_key( + internal_, lobbyId, index, reinterpret_cast(key)); + return static_cast(result); +} + +Result LobbyManager::LobbyMetadataCount(LobbyId lobbyId, std::int32_t* count) +{ + if (!count) { + return Result::InternalError; + } + + auto result = + internal_->lobby_metadata_count(internal_, lobbyId, reinterpret_cast(count)); + return static_cast(result); +} + +Result LobbyManager::MemberCount(LobbyId lobbyId, std::int32_t* count) +{ + if (!count) { + return Result::InternalError; + } + + auto result = internal_->member_count(internal_, lobbyId, reinterpret_cast(count)); + return static_cast(result); +} + +Result LobbyManager::GetMemberUserId(LobbyId lobbyId, std::int32_t index, UserId* userId) +{ + if (!userId) { + return Result::InternalError; + } + + auto result = + internal_->get_member_user_id(internal_, lobbyId, index, reinterpret_cast(userId)); + return static_cast(result); +} + +Result LobbyManager::GetMemberUser(LobbyId lobbyId, UserId userId, User* user) +{ + if (!user) { + return Result::InternalError; + } + + auto result = + internal_->get_member_user(internal_, lobbyId, userId, reinterpret_cast(user)); + return static_cast(result); +} + +Result LobbyManager::GetMemberMetadataValue(LobbyId lobbyId, + UserId userId, + MetadataKey key, + char value[4096]) +{ + if (!value) { + return Result::InternalError; + } + + auto result = + internal_->get_member_metadata_value(internal_, + lobbyId, + userId, + const_cast(key), + reinterpret_cast(value)); + return static_cast(result); +} + +Result LobbyManager::GetMemberMetadataKey(LobbyId lobbyId, + UserId userId, + std::int32_t index, + char key[256]) +{ + if (!key) { + return Result::InternalError; + } + + auto result = internal_->get_member_metadata_key( + internal_, lobbyId, userId, index, reinterpret_cast(key)); + return static_cast(result); +} + +Result LobbyManager::MemberMetadataCount(LobbyId lobbyId, UserId userId, std::int32_t* count) +{ + if (!count) { + return Result::InternalError; + } + + auto result = internal_->member_metadata_count( + internal_, lobbyId, userId, reinterpret_cast(count)); + return static_cast(result); +} + +void LobbyManager::UpdateMember(LobbyId lobbyId, + UserId userId, + LobbyMemberTransaction const& transaction, + std::function callback) +{ + static auto wrapper = [](void* callbackData, EDiscordResult result) -> void { + std::unique_ptr> cb( + reinterpret_cast*>(callbackData)); + if (!cb || !(*cb)) { + return; + } + (*cb)(static_cast(result)); + }; + std::unique_ptr> cb{}; + cb.reset(new std::function(std::move(callback))); + internal_->update_member(internal_, + lobbyId, + userId, + const_cast(transaction).Internal(), + cb.release(), + wrapper); +} + +void LobbyManager::SendLobbyMessage(LobbyId lobbyId, + std::uint8_t* data, + std::uint32_t dataLength, + std::function callback) +{ + static auto wrapper = [](void* callbackData, EDiscordResult result) -> void { + std::unique_ptr> cb( + reinterpret_cast*>(callbackData)); + if (!cb || !(*cb)) { + return; + } + (*cb)(static_cast(result)); + }; + std::unique_ptr> cb{}; + cb.reset(new std::function(std::move(callback))); + internal_->send_lobby_message( + internal_, lobbyId, reinterpret_cast(data), dataLength, cb.release(), wrapper); +} + +Result LobbyManager::GetSearchQuery(LobbySearchQuery* query) +{ + if (!query) { + return Result::InternalError; + } + + auto result = internal_->get_search_query(internal_, query->Receive()); + return static_cast(result); +} + +void LobbyManager::Search(LobbySearchQuery const& query, std::function callback) +{ + static auto wrapper = [](void* callbackData, EDiscordResult result) -> void { + std::unique_ptr> cb( + reinterpret_cast*>(callbackData)); + if (!cb || !(*cb)) { + return; + } + (*cb)(static_cast(result)); + }; + std::unique_ptr> cb{}; + cb.reset(new std::function(std::move(callback))); + internal_->search( + internal_, const_cast(query).Internal(), cb.release(), wrapper); +} + +void LobbyManager::LobbyCount(std::int32_t* count) +{ + if (!count) { + return; + } + + internal_->lobby_count(internal_, reinterpret_cast(count)); +} + +Result LobbyManager::GetLobbyId(std::int32_t index, LobbyId* lobbyId) +{ + if (!lobbyId) { + return Result::InternalError; + } + + auto result = internal_->get_lobby_id(internal_, index, reinterpret_cast(lobbyId)); + return static_cast(result); +} + +void LobbyManager::ConnectVoice(LobbyId lobbyId, std::function callback) +{ + static auto wrapper = [](void* callbackData, EDiscordResult result) -> void { + std::unique_ptr> cb( + reinterpret_cast*>(callbackData)); + if (!cb || !(*cb)) { + return; + } + (*cb)(static_cast(result)); + }; + std::unique_ptr> cb{}; + cb.reset(new std::function(std::move(callback))); + internal_->connect_voice(internal_, lobbyId, cb.release(), wrapper); +} + +void LobbyManager::DisconnectVoice(LobbyId lobbyId, std::function callback) +{ + static auto wrapper = [](void* callbackData, EDiscordResult result) -> void { + std::unique_ptr> cb( + reinterpret_cast*>(callbackData)); + if (!cb || !(*cb)) { + return; + } + (*cb)(static_cast(result)); + }; + std::unique_ptr> cb{}; + cb.reset(new std::function(std::move(callback))); + internal_->disconnect_voice(internal_, lobbyId, cb.release(), wrapper); +} + +Result LobbyManager::ConnectNetwork(LobbyId lobbyId) +{ + auto result = internal_->connect_network(internal_, lobbyId); + return static_cast(result); +} + +Result LobbyManager::DisconnectNetwork(LobbyId lobbyId) +{ + auto result = internal_->disconnect_network(internal_, lobbyId); + return static_cast(result); +} + +Result LobbyManager::FlushNetwork() +{ + auto result = internal_->flush_network(internal_); + return static_cast(result); +} + +Result LobbyManager::OpenNetworkChannel(LobbyId lobbyId, std::uint8_t channelId, bool reliable) +{ + auto result = + internal_->open_network_channel(internal_, lobbyId, channelId, (reliable ? 1 : 0)); + return static_cast(result); +} + +Result LobbyManager::SendNetworkMessage(LobbyId lobbyId, + UserId userId, + std::uint8_t channelId, + std::uint8_t* data, + std::uint32_t dataLength) +{ + auto result = internal_->send_network_message( + internal_, lobbyId, userId, channelId, reinterpret_cast(data), dataLength); + return static_cast(result); +} + +} // namespace discord diff --git a/src/lib/discord_game_sdk/cpp/lobby_manager.h b/src/lib/discord_game_sdk/cpp/lobby_manager.h new file mode 100644 index 0000000..96380cb --- /dev/null +++ b/src/lib/discord_game_sdk/cpp/lobby_manager.h @@ -0,0 +1,88 @@ +#pragma once + +#include "types.h" + +namespace discord { + +class LobbyManager final { +public: + ~LobbyManager() = default; + + Result GetLobbyCreateTransaction(LobbyTransaction* transaction); + Result GetLobbyUpdateTransaction(LobbyId lobbyId, LobbyTransaction* transaction); + Result GetMemberUpdateTransaction(LobbyId lobbyId, + UserId userId, + LobbyMemberTransaction* transaction); + void CreateLobby(LobbyTransaction const& transaction, + std::function callback); + void UpdateLobby(LobbyId lobbyId, + LobbyTransaction const& transaction, + std::function callback); + void DeleteLobby(LobbyId lobbyId, std::function callback); + void ConnectLobby(LobbyId lobbyId, + LobbySecret secret, + std::function callback); + void ConnectLobbyWithActivitySecret(LobbySecret activitySecret, + std::function callback); + void DisconnectLobby(LobbyId lobbyId, std::function callback); + Result GetLobby(LobbyId lobbyId, Lobby* lobby); + Result GetLobbyActivitySecret(LobbyId lobbyId, char secret[128]); + Result GetLobbyMetadataValue(LobbyId lobbyId, MetadataKey key, char value[4096]); + Result GetLobbyMetadataKey(LobbyId lobbyId, std::int32_t index, char key[256]); + Result LobbyMetadataCount(LobbyId lobbyId, std::int32_t* count); + Result MemberCount(LobbyId lobbyId, std::int32_t* count); + Result GetMemberUserId(LobbyId lobbyId, std::int32_t index, UserId* userId); + Result GetMemberUser(LobbyId lobbyId, UserId userId, User* user); + Result GetMemberMetadataValue(LobbyId lobbyId, + UserId userId, + MetadataKey key, + char value[4096]); + Result GetMemberMetadataKey(LobbyId lobbyId, UserId userId, std::int32_t index, char key[256]); + Result MemberMetadataCount(LobbyId lobbyId, UserId userId, std::int32_t* count); + void UpdateMember(LobbyId lobbyId, + UserId userId, + LobbyMemberTransaction const& transaction, + std::function callback); + void SendLobbyMessage(LobbyId lobbyId, + std::uint8_t* data, + std::uint32_t dataLength, + std::function callback); + Result GetSearchQuery(LobbySearchQuery* query); + void Search(LobbySearchQuery const& query, std::function callback); + void LobbyCount(std::int32_t* count); + Result GetLobbyId(std::int32_t index, LobbyId* lobbyId); + void ConnectVoice(LobbyId lobbyId, std::function callback); + void DisconnectVoice(LobbyId lobbyId, std::function callback); + Result ConnectNetwork(LobbyId lobbyId); + Result DisconnectNetwork(LobbyId lobbyId); + Result FlushNetwork(); + Result OpenNetworkChannel(LobbyId lobbyId, std::uint8_t channelId, bool reliable); + Result SendNetworkMessage(LobbyId lobbyId, + UserId userId, + std::uint8_t channelId, + std::uint8_t* data, + std::uint32_t dataLength); + + Event OnLobbyUpdate; + Event OnLobbyDelete; + Event OnMemberConnect; + Event OnMemberUpdate; + Event OnMemberDisconnect; + Event OnLobbyMessage; + Event OnSpeaking; + Event OnNetworkMessage; + +private: + friend class Core; + + LobbyManager() = default; + LobbyManager(LobbyManager const& rhs) = delete; + LobbyManager& operator=(LobbyManager const& rhs) = delete; + LobbyManager(LobbyManager&& rhs) = delete; + LobbyManager& operator=(LobbyManager&& rhs) = delete; + + IDiscordLobbyManager* internal_; + static IDiscordLobbyEvents events_; +}; + +} // namespace discord diff --git a/src/lib/discord_game_sdk/cpp/network_manager.cpp b/src/lib/discord_game_sdk/cpp/network_manager.cpp new file mode 100644 index 0000000..36031b3 --- /dev/null +++ b/src/lib/discord_game_sdk/cpp/network_manager.cpp @@ -0,0 +1,103 @@ +#if !defined(_CRT_SECURE_NO_WARNINGS) +#define _CRT_SECURE_NO_WARNINGS +#endif + +#include "network_manager.h" + +#include "core.h" + +#include +#include + +namespace discord { + +class NetworkEvents final { +public: + static void DISCORD_CALLBACK OnMessage(void* callbackData, + DiscordNetworkPeerId peerId, + DiscordNetworkChannelId channelId, + uint8_t* data, + uint32_t dataLength) + { + auto* core = reinterpret_cast(callbackData); + if (!core) { + return; + } + + auto& module = core->NetworkManager(); + module.OnMessage(peerId, channelId, data, dataLength); + } + + static void DISCORD_CALLBACK OnRouteUpdate(void* callbackData, char const* routeData) + { + auto* core = reinterpret_cast(callbackData); + if (!core) { + return; + } + + auto& module = core->NetworkManager(); + module.OnRouteUpdate(static_cast(routeData)); + } +}; + +IDiscordNetworkEvents NetworkManager::events_{ + &NetworkEvents::OnMessage, + &NetworkEvents::OnRouteUpdate, +}; + +void NetworkManager::GetPeerId(NetworkPeerId* peerId) +{ + if (!peerId) { + return; + } + + internal_->get_peer_id(internal_, reinterpret_cast(peerId)); +} + +Result NetworkManager::Flush() +{ + auto result = internal_->flush(internal_); + return static_cast(result); +} + +Result NetworkManager::OpenPeer(NetworkPeerId peerId, char const* routeData) +{ + auto result = internal_->open_peer(internal_, peerId, const_cast(routeData)); + return static_cast(result); +} + +Result NetworkManager::UpdatePeer(NetworkPeerId peerId, char const* routeData) +{ + auto result = internal_->update_peer(internal_, peerId, const_cast(routeData)); + return static_cast(result); +} + +Result NetworkManager::ClosePeer(NetworkPeerId peerId) +{ + auto result = internal_->close_peer(internal_, peerId); + return static_cast(result); +} + +Result NetworkManager::OpenChannel(NetworkPeerId peerId, NetworkChannelId channelId, bool reliable) +{ + auto result = internal_->open_channel(internal_, peerId, channelId, (reliable ? 1 : 0)); + return static_cast(result); +} + +Result NetworkManager::CloseChannel(NetworkPeerId peerId, NetworkChannelId channelId) +{ + auto result = internal_->close_channel(internal_, peerId, channelId); + return static_cast(result); +} + +Result NetworkManager::SendMessage(NetworkPeerId peerId, + NetworkChannelId channelId, + std::uint8_t* data, + std::uint32_t dataLength) +{ + auto result = internal_->send_message( + internal_, peerId, channelId, reinterpret_cast(data), dataLength); + return static_cast(result); +} + +} // namespace discord diff --git a/src/lib/discord_game_sdk/cpp/network_manager.h b/src/lib/discord_game_sdk/cpp/network_manager.h new file mode 100644 index 0000000..e374670 --- /dev/null +++ b/src/lib/discord_game_sdk/cpp/network_manager.h @@ -0,0 +1,63 @@ +#pragma once + +#include "types.h" + +namespace discord { + +class NetworkManager final { +public: + ~NetworkManager() = default; + + /** + * Get the local peer ID for this process. + */ + void GetPeerId(NetworkPeerId* peerId); + /** + * Send pending network messages. + */ + Result Flush(); + /** + * Open a connection to a remote peer. + */ + Result OpenPeer(NetworkPeerId peerId, char const* routeData); + /** + * Update the route data for a connected peer. + */ + Result UpdatePeer(NetworkPeerId peerId, char const* routeData); + /** + * Close the connection to a remote peer. + */ + Result ClosePeer(NetworkPeerId peerId); + /** + * Open a message channel to a connected peer. + */ + Result OpenChannel(NetworkPeerId peerId, NetworkChannelId channelId, bool reliable); + /** + * Close a message channel to a connected peer. + */ + Result CloseChannel(NetworkPeerId peerId, NetworkChannelId channelId); + /** + * Send a message to a connected peer over an opened message channel. + */ + Result SendMessage(NetworkPeerId peerId, + NetworkChannelId channelId, + std::uint8_t* data, + std::uint32_t dataLength); + + Event OnMessage; + Event OnRouteUpdate; + +private: + friend class Core; + + NetworkManager() = default; + NetworkManager(NetworkManager const& rhs) = delete; + NetworkManager& operator=(NetworkManager const& rhs) = delete; + NetworkManager(NetworkManager&& rhs) = delete; + NetworkManager& operator=(NetworkManager&& rhs) = delete; + + IDiscordNetworkManager* internal_; + static IDiscordNetworkEvents events_; +}; + +} // namespace discord diff --git a/src/lib/discord_game_sdk/cpp/overlay_manager.cpp b/src/lib/discord_game_sdk/cpp/overlay_manager.cpp new file mode 100644 index 0000000..f4b1fba --- /dev/null +++ b/src/lib/discord_game_sdk/cpp/overlay_manager.cpp @@ -0,0 +1,229 @@ +#if !defined(_CRT_SECURE_NO_WARNINGS) +#define _CRT_SECURE_NO_WARNINGS +#endif + +#include "overlay_manager.h" + +#include "core.h" + +#include +#include + +namespace discord { + +class OverlayEvents final { +public: + static void DISCORD_CALLBACK OnToggle(void* callbackData, bool locked) + { + auto* core = reinterpret_cast(callbackData); + if (!core) { + return; + } + + auto& module = core->OverlayManager(); + module.OnToggle((locked != 0)); + } +}; + +IDiscordOverlayEvents OverlayManager::events_{ + &OverlayEvents::OnToggle, +}; + +void OverlayManager::IsEnabled(bool* enabled) +{ + if (!enabled) { + return; + } + + internal_->is_enabled(internal_, reinterpret_cast(enabled)); +} + +void OverlayManager::IsLocked(bool* locked) +{ + if (!locked) { + return; + } + + internal_->is_locked(internal_, reinterpret_cast(locked)); +} + +void OverlayManager::SetLocked(bool locked, std::function callback) +{ + static auto wrapper = [](void* callbackData, EDiscordResult result) -> void { + std::unique_ptr> cb( + reinterpret_cast*>(callbackData)); + if (!cb || !(*cb)) { + return; + } + (*cb)(static_cast(result)); + }; + std::unique_ptr> cb{}; + cb.reset(new std::function(std::move(callback))); + internal_->set_locked(internal_, (locked ? 1 : 0), cb.release(), wrapper); +} + +void OverlayManager::OpenActivityInvite(ActivityActionType type, + std::function callback) +{ + static auto wrapper = [](void* callbackData, EDiscordResult result) -> void { + std::unique_ptr> cb( + reinterpret_cast*>(callbackData)); + if (!cb || !(*cb)) { + return; + } + (*cb)(static_cast(result)); + }; + std::unique_ptr> cb{}; + cb.reset(new std::function(std::move(callback))); + internal_->open_activity_invite( + internal_, static_cast(type), cb.release(), wrapper); +} + +void OverlayManager::OpenGuildInvite(char const* code, std::function callback) +{ + static auto wrapper = [](void* callbackData, EDiscordResult result) -> void { + std::unique_ptr> cb( + reinterpret_cast*>(callbackData)); + if (!cb || !(*cb)) { + return; + } + (*cb)(static_cast(result)); + }; + std::unique_ptr> cb{}; + cb.reset(new std::function(std::move(callback))); + internal_->open_guild_invite(internal_, const_cast(code), cb.release(), wrapper); +} + +void OverlayManager::OpenVoiceSettings(std::function callback) +{ + static auto wrapper = [](void* callbackData, EDiscordResult result) -> void { + std::unique_ptr> cb( + reinterpret_cast*>(callbackData)); + if (!cb || !(*cb)) { + return; + } + (*cb)(static_cast(result)); + }; + std::unique_ptr> cb{}; + cb.reset(new std::function(std::move(callback))); + internal_->open_voice_settings(internal_, cb.release(), wrapper); +} + +Result OverlayManager::InitDrawingDxgi(IDXGISwapChain* swapchain, bool useMessageForwarding) +{ + auto result = + internal_->init_drawing_dxgi(internal_, swapchain, (useMessageForwarding ? 1 : 0)); + return static_cast(result); +} + +void OverlayManager::OnPresent() +{ + internal_->on_present(internal_); +} + +void OverlayManager::ForwardMessage(MSG* message) +{ + internal_->forward_message(internal_, message); +} + +void OverlayManager::KeyEvent(bool down, char const* keyCode, KeyVariant variant) +{ + internal_->key_event(internal_, + (down ? 1 : 0), + const_cast(keyCode), + static_cast(variant)); +} + +void OverlayManager::CharEvent(char const* character) +{ + internal_->char_event(internal_, const_cast(character)); +} + +void OverlayManager::MouseButtonEvent(std::uint8_t down, + std::int32_t clickCount, + MouseButton which, + std::int32_t x, + std::int32_t y) +{ + internal_->mouse_button_event( + internal_, down, clickCount, static_cast(which), x, y); +} + +void OverlayManager::MouseMotionEvent(std::int32_t x, std::int32_t y) +{ + internal_->mouse_motion_event(internal_, x, y); +} + +void OverlayManager::ImeCommitText(char const* text) +{ + internal_->ime_commit_text(internal_, const_cast(text)); +} + +void OverlayManager::ImeSetComposition(char const* text, + ImeUnderline* underlines, + std::uint32_t underlinesLength, + std::int32_t from, + std::int32_t to) +{ + internal_->ime_set_composition(internal_, + const_cast(text), + reinterpret_cast(underlines), + underlinesLength, + from, + to); +} + +void OverlayManager::ImeCancelComposition() +{ + internal_->ime_cancel_composition(internal_); +} + +void OverlayManager::SetImeCompositionRangeCallback( + std::function + onImeCompositionRangeChanged) +{ + static auto wrapper = [](void* callbackData, + int32_t from, + int32_t to, + DiscordRect* bounds, + uint32_t boundsLength) -> void { + std::unique_ptr> cb( + reinterpret_cast*>( + callbackData)); + if (!cb || !(*cb)) { + return; + } + (*cb)(from, to, reinterpret_cast(bounds), boundsLength); + }; + std::unique_ptr> cb{}; + cb.reset(new std::function( + std::move(onImeCompositionRangeChanged))); + internal_->set_ime_composition_range_callback(internal_, cb.release(), wrapper); +} + +void OverlayManager::SetImeSelectionBoundsCallback( + std::function onImeSelectionBoundsChanged) +{ + static auto wrapper = + [](void* callbackData, DiscordRect anchor, DiscordRect focus, bool isAnchorFirst) -> void { + std::unique_ptr> cb( + reinterpret_cast*>(callbackData)); + if (!cb || !(*cb)) { + return; + } + (*cb)(*reinterpret_cast(&anchor), + *reinterpret_cast(&focus), + (isAnchorFirst != 0)); + }; + std::unique_ptr> cb{}; + cb.reset(new std::function(std::move(onImeSelectionBoundsChanged))); + internal_->set_ime_selection_bounds_callback(internal_, cb.release(), wrapper); +} + +bool OverlayManager::IsPointInsideClickZone(std::int32_t x, std::int32_t y) +{ + auto result = internal_->is_point_inside_click_zone(internal_, x, y); + return (result != 0); +} + +} // namespace discord diff --git a/src/lib/discord_game_sdk/cpp/overlay_manager.h b/src/lib/discord_game_sdk/cpp/overlay_manager.h new file mode 100644 index 0000000..5f73a36 --- /dev/null +++ b/src/lib/discord_game_sdk/cpp/overlay_manager.h @@ -0,0 +1,57 @@ +#pragma once + +#include "types.h" + +namespace discord { + +class OverlayManager final { +public: + ~OverlayManager() = default; + + void IsEnabled(bool* enabled); + void IsLocked(bool* locked); + void SetLocked(bool locked, std::function callback); + void OpenActivityInvite(ActivityActionType type, std::function callback); + void OpenGuildInvite(char const* code, std::function callback); + void OpenVoiceSettings(std::function callback); + Result InitDrawingDxgi(IDXGISwapChain* swapchain, bool useMessageForwarding); + void OnPresent(); + void ForwardMessage(MSG* message); + void KeyEvent(bool down, char const* keyCode, KeyVariant variant); + void CharEvent(char const* character); + void MouseButtonEvent(std::uint8_t down, + std::int32_t clickCount, + MouseButton which, + std::int32_t x, + std::int32_t y); + void MouseMotionEvent(std::int32_t x, std::int32_t y); + void ImeCommitText(char const* text); + void ImeSetComposition(char const* text, + ImeUnderline* underlines, + std::uint32_t underlinesLength, + std::int32_t from, + std::int32_t to); + void ImeCancelComposition(); + void SetImeCompositionRangeCallback( + std::function + onImeCompositionRangeChanged); + void SetImeSelectionBoundsCallback( + std::function onImeSelectionBoundsChanged); + bool IsPointInsideClickZone(std::int32_t x, std::int32_t y); + + Event OnToggle; + +private: + friend class Core; + + OverlayManager() = default; + OverlayManager(OverlayManager const& rhs) = delete; + OverlayManager& operator=(OverlayManager const& rhs) = delete; + OverlayManager(OverlayManager&& rhs) = delete; + OverlayManager& operator=(OverlayManager&& rhs) = delete; + + IDiscordOverlayManager* internal_; + static IDiscordOverlayEvents events_; +}; + +} // namespace discord diff --git a/src/lib/discord_game_sdk/cpp/relationship_manager.cpp b/src/lib/discord_game_sdk/cpp/relationship_manager.cpp new file mode 100644 index 0000000..dce874e --- /dev/null +++ b/src/lib/discord_game_sdk/cpp/relationship_manager.cpp @@ -0,0 +1,91 @@ +#if !defined(_CRT_SECURE_NO_WARNINGS) +#define _CRT_SECURE_NO_WARNINGS +#endif + +#include "relationship_manager.h" + +#include "core.h" + +#include +#include + +namespace discord { + +class RelationshipEvents final { +public: + static void DISCORD_CALLBACK OnRefresh(void* callbackData) + { + auto* core = reinterpret_cast(callbackData); + if (!core) { + return; + } + + auto& module = core->RelationshipManager(); + module.OnRefresh(); + } + + static void DISCORD_CALLBACK OnRelationshipUpdate(void* callbackData, + DiscordRelationship* relationship) + { + auto* core = reinterpret_cast(callbackData); + if (!core) { + return; + } + + auto& module = core->RelationshipManager(); + module.OnRelationshipUpdate(*reinterpret_cast(relationship)); + } +}; + +IDiscordRelationshipEvents RelationshipManager::events_{ + &RelationshipEvents::OnRefresh, + &RelationshipEvents::OnRelationshipUpdate, +}; + +void RelationshipManager::Filter(std::function filter) +{ + static auto wrapper = [](void* callbackData, DiscordRelationship* relationship) -> bool { + auto cb(reinterpret_cast*>(callbackData)); + if (!cb || !(*cb)) { + return {}; + } + return (*cb)(*reinterpret_cast(relationship)); + }; + std::unique_ptr> cb{}; + cb.reset(new std::function(std::move(filter))); + internal_->filter(internal_, cb.get(), wrapper); +} + +Result RelationshipManager::Count(std::int32_t* count) +{ + if (!count) { + return Result::InternalError; + } + + auto result = internal_->count(internal_, reinterpret_cast(count)); + return static_cast(result); +} + +Result RelationshipManager::Get(UserId userId, Relationship* relationship) +{ + if (!relationship) { + return Result::InternalError; + } + + auto result = + internal_->get(internal_, userId, reinterpret_cast(relationship)); + return static_cast(result); +} + +Result RelationshipManager::GetAt(std::uint32_t index, Relationship* relationship) +{ + if (!relationship) { + return Result::InternalError; + } + + auto result = + internal_->get_at(internal_, index, reinterpret_cast(relationship)); + return static_cast(result); +} + +} // namespace discord diff --git a/src/lib/discord_game_sdk/cpp/relationship_manager.h b/src/lib/discord_game_sdk/cpp/relationship_manager.h new file mode 100644 index 0000000..e9cd016 --- /dev/null +++ b/src/lib/discord_game_sdk/cpp/relationship_manager.h @@ -0,0 +1,32 @@ +#pragma once + +#include "types.h" + +namespace discord { + +class RelationshipManager final { +public: + ~RelationshipManager() = default; + + void Filter(std::function filter); + Result Count(std::int32_t* count); + Result Get(UserId userId, Relationship* relationship); + Result GetAt(std::uint32_t index, Relationship* relationship); + + Event<> OnRefresh; + Event OnRelationshipUpdate; + +private: + friend class Core; + + RelationshipManager() = default; + RelationshipManager(RelationshipManager const& rhs) = delete; + RelationshipManager& operator=(RelationshipManager const& rhs) = delete; + RelationshipManager(RelationshipManager&& rhs) = delete; + RelationshipManager& operator=(RelationshipManager&& rhs) = delete; + + IDiscordRelationshipManager* internal_; + static IDiscordRelationshipEvents events_; +}; + +} // namespace discord diff --git a/src/lib/discord_game_sdk/cpp/storage_manager.cpp b/src/lib/discord_game_sdk/cpp/storage_manager.cpp new file mode 100644 index 0000000..fbf9ca7 --- /dev/null +++ b/src/lib/discord_game_sdk/cpp/storage_manager.cpp @@ -0,0 +1,158 @@ +#if !defined(_CRT_SECURE_NO_WARNINGS) +#define _CRT_SECURE_NO_WARNINGS +#endif + +#include "storage_manager.h" + +#include "core.h" + +#include +#include + +namespace discord { + +Result StorageManager::Read(char const* name, + std::uint8_t* data, + std::uint32_t dataLength, + std::uint32_t* read) +{ + if (!read) { + return Result::InternalError; + } + + auto result = internal_->read(internal_, + const_cast(name), + reinterpret_cast(data), + dataLength, + reinterpret_cast(read)); + return static_cast(result); +} + +void StorageManager::ReadAsync(char const* name, + std::function callback) +{ + static auto wrapper = + [](void* callbackData, EDiscordResult result, uint8_t* data, uint32_t dataLength) -> void { + std::unique_ptr> cb( + reinterpret_cast*>( + callbackData)); + if (!cb || !(*cb)) { + return; + } + (*cb)(static_cast(result), data, dataLength); + }; + std::unique_ptr> cb{}; + cb.reset(new std::function(std::move(callback))); + internal_->read_async(internal_, const_cast(name), cb.release(), wrapper); +} + +void StorageManager::ReadAsyncPartial( + char const* name, + std::uint64_t offset, + std::uint64_t length, + std::function callback) +{ + static auto wrapper = + [](void* callbackData, EDiscordResult result, uint8_t* data, uint32_t dataLength) -> void { + std::unique_ptr> cb( + reinterpret_cast*>( + callbackData)); + if (!cb || !(*cb)) { + return; + } + (*cb)(static_cast(result), data, dataLength); + }; + std::unique_ptr> cb{}; + cb.reset(new std::function(std::move(callback))); + internal_->read_async_partial( + internal_, const_cast(name), offset, length, cb.release(), wrapper); +} + +Result StorageManager::Write(char const* name, std::uint8_t* data, std::uint32_t dataLength) +{ + auto result = internal_->write( + internal_, const_cast(name), reinterpret_cast(data), dataLength); + return static_cast(result); +} + +void StorageManager::WriteAsync(char const* name, + std::uint8_t* data, + std::uint32_t dataLength, + std::function callback) +{ + static auto wrapper = [](void* callbackData, EDiscordResult result) -> void { + std::unique_ptr> cb( + reinterpret_cast*>(callbackData)); + if (!cb || !(*cb)) { + return; + } + (*cb)(static_cast(result)); + }; + std::unique_ptr> cb{}; + cb.reset(new std::function(std::move(callback))); + internal_->write_async(internal_, + const_cast(name), + reinterpret_cast(data), + dataLength, + cb.release(), + wrapper); +} + +Result StorageManager::Delete(char const* name) +{ + auto result = internal_->delete_(internal_, const_cast(name)); + return static_cast(result); +} + +Result StorageManager::Exists(char const* name, bool* exists) +{ + if (!exists) { + return Result::InternalError; + } + + auto result = + internal_->exists(internal_, const_cast(name), reinterpret_cast(exists)); + return static_cast(result); +} + +void StorageManager::Count(std::int32_t* count) +{ + if (!count) { + return; + } + + internal_->count(internal_, reinterpret_cast(count)); +} + +Result StorageManager::Stat(char const* name, FileStat* stat) +{ + if (!stat) { + return Result::InternalError; + } + + auto result = + internal_->stat(internal_, const_cast(name), reinterpret_cast(stat)); + return static_cast(result); +} + +Result StorageManager::StatAt(std::int32_t index, FileStat* stat) +{ + if (!stat) { + return Result::InternalError; + } + + auto result = internal_->stat_at(internal_, index, reinterpret_cast(stat)); + return static_cast(result); +} + +Result StorageManager::GetPath(char path[4096]) +{ + if (!path) { + return Result::InternalError; + } + + auto result = internal_->get_path(internal_, reinterpret_cast(path)); + return static_cast(result); +} + +} // namespace discord diff --git a/src/lib/discord_game_sdk/cpp/storage_manager.h b/src/lib/discord_game_sdk/cpp/storage_manager.h new file mode 100644 index 0000000..5d6d17b --- /dev/null +++ b/src/lib/discord_game_sdk/cpp/storage_manager.h @@ -0,0 +1,46 @@ +#pragma once + +#include "types.h" + +namespace discord { + +class StorageManager final { +public: + ~StorageManager() = default; + + Result Read(char const* name, + std::uint8_t* data, + std::uint32_t dataLength, + std::uint32_t* read); + void ReadAsync(char const* name, + std::function callback); + void ReadAsyncPartial(char const* name, + std::uint64_t offset, + std::uint64_t length, + std::function callback); + Result Write(char const* name, std::uint8_t* data, std::uint32_t dataLength); + void WriteAsync(char const* name, + std::uint8_t* data, + std::uint32_t dataLength, + std::function callback); + Result Delete(char const* name); + Result Exists(char const* name, bool* exists); + void Count(std::int32_t* count); + Result Stat(char const* name, FileStat* stat); + Result StatAt(std::int32_t index, FileStat* stat); + Result GetPath(char path[4096]); + +private: + friend class Core; + + StorageManager() = default; + StorageManager(StorageManager const& rhs) = delete; + StorageManager& operator=(StorageManager const& rhs) = delete; + StorageManager(StorageManager&& rhs) = delete; + StorageManager& operator=(StorageManager&& rhs) = delete; + + IDiscordStorageManager* internal_; + static IDiscordStorageEvents events_; +}; + +} // namespace discord diff --git a/src/lib/discord_game_sdk/cpp/store_manager.cpp b/src/lib/discord_game_sdk/cpp/store_manager.cpp new file mode 100644 index 0000000..40c7e65 --- /dev/null +++ b/src/lib/discord_game_sdk/cpp/store_manager.cpp @@ -0,0 +1,162 @@ +#if !defined(_CRT_SECURE_NO_WARNINGS) +#define _CRT_SECURE_NO_WARNINGS +#endif + +#include "store_manager.h" + +#include "core.h" + +#include +#include + +namespace discord { + +class StoreEvents final { +public: + static void DISCORD_CALLBACK OnEntitlementCreate(void* callbackData, + DiscordEntitlement* entitlement) + { + auto* core = reinterpret_cast(callbackData); + if (!core) { + return; + } + + auto& module = core->StoreManager(); + module.OnEntitlementCreate(*reinterpret_cast(entitlement)); + } + + static void DISCORD_CALLBACK OnEntitlementDelete(void* callbackData, + DiscordEntitlement* entitlement) + { + auto* core = reinterpret_cast(callbackData); + if (!core) { + return; + } + + auto& module = core->StoreManager(); + module.OnEntitlementDelete(*reinterpret_cast(entitlement)); + } +}; + +IDiscordStoreEvents StoreManager::events_{ + &StoreEvents::OnEntitlementCreate, + &StoreEvents::OnEntitlementDelete, +}; + +void StoreManager::FetchSkus(std::function callback) +{ + static auto wrapper = [](void* callbackData, EDiscordResult result) -> void { + std::unique_ptr> cb( + reinterpret_cast*>(callbackData)); + if (!cb || !(*cb)) { + return; + } + (*cb)(static_cast(result)); + }; + std::unique_ptr> cb{}; + cb.reset(new std::function(std::move(callback))); + internal_->fetch_skus(internal_, cb.release(), wrapper); +} + +void StoreManager::CountSkus(std::int32_t* count) +{ + if (!count) { + return; + } + + internal_->count_skus(internal_, reinterpret_cast(count)); +} + +Result StoreManager::GetSku(Snowflake skuId, Sku* sku) +{ + if (!sku) { + return Result::InternalError; + } + + auto result = internal_->get_sku(internal_, skuId, reinterpret_cast(sku)); + return static_cast(result); +} + +Result StoreManager::GetSkuAt(std::int32_t index, Sku* sku) +{ + if (!sku) { + return Result::InternalError; + } + + auto result = internal_->get_sku_at(internal_, index, reinterpret_cast(sku)); + return static_cast(result); +} + +void StoreManager::FetchEntitlements(std::function callback) +{ + static auto wrapper = [](void* callbackData, EDiscordResult result) -> void { + std::unique_ptr> cb( + reinterpret_cast*>(callbackData)); + if (!cb || !(*cb)) { + return; + } + (*cb)(static_cast(result)); + }; + std::unique_ptr> cb{}; + cb.reset(new std::function(std::move(callback))); + internal_->fetch_entitlements(internal_, cb.release(), wrapper); +} + +void StoreManager::CountEntitlements(std::int32_t* count) +{ + if (!count) { + return; + } + + internal_->count_entitlements(internal_, reinterpret_cast(count)); +} + +Result StoreManager::GetEntitlement(Snowflake entitlementId, Entitlement* entitlement) +{ + if (!entitlement) { + return Result::InternalError; + } + + auto result = internal_->get_entitlement( + internal_, entitlementId, reinterpret_cast(entitlement)); + return static_cast(result); +} + +Result StoreManager::GetEntitlementAt(std::int32_t index, Entitlement* entitlement) +{ + if (!entitlement) { + return Result::InternalError; + } + + auto result = internal_->get_entitlement_at( + internal_, index, reinterpret_cast(entitlement)); + return static_cast(result); +} + +Result StoreManager::HasSkuEntitlement(Snowflake skuId, bool* hasEntitlement) +{ + if (!hasEntitlement) { + return Result::InternalError; + } + + auto result = + internal_->has_sku_entitlement(internal_, skuId, reinterpret_cast(hasEntitlement)); + return static_cast(result); +} + +void StoreManager::StartPurchase(Snowflake skuId, std::function callback) +{ + static auto wrapper = [](void* callbackData, EDiscordResult result) -> void { + std::unique_ptr> cb( + reinterpret_cast*>(callbackData)); + if (!cb || !(*cb)) { + return; + } + (*cb)(static_cast(result)); + }; + std::unique_ptr> cb{}; + cb.reset(new std::function(std::move(callback))); + internal_->start_purchase(internal_, skuId, cb.release(), wrapper); +} + +} // namespace discord diff --git a/src/lib/discord_game_sdk/cpp/store_manager.h b/src/lib/discord_game_sdk/cpp/store_manager.h new file mode 100644 index 0000000..8e0df8a --- /dev/null +++ b/src/lib/discord_game_sdk/cpp/store_manager.h @@ -0,0 +1,38 @@ +#pragma once + +#include "types.h" + +namespace discord { + +class StoreManager final { +public: + ~StoreManager() = default; + + void FetchSkus(std::function callback); + void CountSkus(std::int32_t* count); + Result GetSku(Snowflake skuId, Sku* sku); + Result GetSkuAt(std::int32_t index, Sku* sku); + void FetchEntitlements(std::function callback); + void CountEntitlements(std::int32_t* count); + Result GetEntitlement(Snowflake entitlementId, Entitlement* entitlement); + Result GetEntitlementAt(std::int32_t index, Entitlement* entitlement); + Result HasSkuEntitlement(Snowflake skuId, bool* hasEntitlement); + void StartPurchase(Snowflake skuId, std::function callback); + + Event OnEntitlementCreate; + Event OnEntitlementDelete; + +private: + friend class Core; + + StoreManager() = default; + StoreManager(StoreManager const& rhs) = delete; + StoreManager& operator=(StoreManager const& rhs) = delete; + StoreManager(StoreManager&& rhs) = delete; + StoreManager& operator=(StoreManager&& rhs) = delete; + + IDiscordStoreManager* internal_; + static IDiscordStoreEvents events_; +}; + +} // namespace discord diff --git a/src/lib/discord_game_sdk/cpp/types.cpp b/src/lib/discord_game_sdk/cpp/types.cpp new file mode 100644 index 0000000..b60dded --- /dev/null +++ b/src/lib/discord_game_sdk/cpp/types.cpp @@ -0,0 +1,879 @@ +#if !defined(_CRT_SECURE_NO_WARNINGS) +#define _CRT_SECURE_NO_WARNINGS +#endif + +#include "types.h" + +#include +#include + +namespace discord { + +void User::SetId(UserId id) +{ + internal_.id = id; +} + +UserId User::GetId() const +{ + return internal_.id; +} + +void User::SetUsername(char const* username) +{ + strncpy(internal_.username, username, 256); + internal_.username[256 - 1] = '\0'; +} + +char const* User::GetUsername() const +{ + return internal_.username; +} + +void User::SetDiscriminator(char const* discriminator) +{ + strncpy(internal_.discriminator, discriminator, 8); + internal_.discriminator[8 - 1] = '\0'; +} + +char const* User::GetDiscriminator() const +{ + return internal_.discriminator; +} + +void User::SetAvatar(char const* avatar) +{ + strncpy(internal_.avatar, avatar, 128); + internal_.avatar[128 - 1] = '\0'; +} + +char const* User::GetAvatar() const +{ + return internal_.avatar; +} + +void User::SetBot(bool bot) +{ + internal_.bot = bot; +} + +bool User::GetBot() const +{ + return internal_.bot != 0; +} + +void OAuth2Token::SetAccessToken(char const* accessToken) +{ + strncpy(internal_.access_token, accessToken, 128); + internal_.access_token[128 - 1] = '\0'; +} + +char const* OAuth2Token::GetAccessToken() const +{ + return internal_.access_token; +} + +void OAuth2Token::SetScopes(char const* scopes) +{ + strncpy(internal_.scopes, scopes, 1024); + internal_.scopes[1024 - 1] = '\0'; +} + +char const* OAuth2Token::GetScopes() const +{ + return internal_.scopes; +} + +void OAuth2Token::SetExpires(Timestamp expires) +{ + internal_.expires = expires; +} + +Timestamp OAuth2Token::GetExpires() const +{ + return internal_.expires; +} + +void ImageHandle::SetType(ImageType type) +{ + internal_.type = static_cast(type); +} + +ImageType ImageHandle::GetType() const +{ + return static_cast(internal_.type); +} + +void ImageHandle::SetId(std::int64_t id) +{ + internal_.id = id; +} + +std::int64_t ImageHandle::GetId() const +{ + return internal_.id; +} + +void ImageHandle::SetSize(std::uint32_t size) +{ + internal_.size = size; +} + +std::uint32_t ImageHandle::GetSize() const +{ + return internal_.size; +} + +void ImageDimensions::SetWidth(std::uint32_t width) +{ + internal_.width = width; +} + +std::uint32_t ImageDimensions::GetWidth() const +{ + return internal_.width; +} + +void ImageDimensions::SetHeight(std::uint32_t height) +{ + internal_.height = height; +} + +std::uint32_t ImageDimensions::GetHeight() const +{ + return internal_.height; +} + +void ActivityTimestamps::SetStart(Timestamp start) +{ + internal_.start = start; +} + +Timestamp ActivityTimestamps::GetStart() const +{ + return internal_.start; +} + +void ActivityTimestamps::SetEnd(Timestamp end) +{ + internal_.end = end; +} + +Timestamp ActivityTimestamps::GetEnd() const +{ + return internal_.end; +} + +void ActivityAssets::SetLargeImage(char const* largeImage) +{ + strncpy(internal_.large_image, largeImage, 128); + internal_.large_image[128 - 1] = '\0'; +} + +char const* ActivityAssets::GetLargeImage() const +{ + return internal_.large_image; +} + +void ActivityAssets::SetLargeText(char const* largeText) +{ + strncpy(internal_.large_text, largeText, 128); + internal_.large_text[128 - 1] = '\0'; +} + +char const* ActivityAssets::GetLargeText() const +{ + return internal_.large_text; +} + +void ActivityAssets::SetSmallImage(char const* smallImage) +{ + strncpy(internal_.small_image, smallImage, 128); + internal_.small_image[128 - 1] = '\0'; +} + +char const* ActivityAssets::GetSmallImage() const +{ + return internal_.small_image; +} + +void ActivityAssets::SetSmallText(char const* smallText) +{ + strncpy(internal_.small_text, smallText, 128); + internal_.small_text[128 - 1] = '\0'; +} + +char const* ActivityAssets::GetSmallText() const +{ + return internal_.small_text; +} + +void PartySize::SetCurrentSize(std::int32_t currentSize) +{ + internal_.current_size = currentSize; +} + +std::int32_t PartySize::GetCurrentSize() const +{ + return internal_.current_size; +} + +void PartySize::SetMaxSize(std::int32_t maxSize) +{ + internal_.max_size = maxSize; +} + +std::int32_t PartySize::GetMaxSize() const +{ + return internal_.max_size; +} + +void ActivityParty::SetId(char const* id) +{ + strncpy(internal_.id, id, 128); + internal_.id[128 - 1] = '\0'; +} + +char const* ActivityParty::GetId() const +{ + return internal_.id; +} + +PartySize& ActivityParty::GetSize() +{ + return reinterpret_cast(internal_.size); +} + +PartySize const& ActivityParty::GetSize() const +{ + return reinterpret_cast(internal_.size); +} + +void ActivityParty::SetPrivacy(ActivityPartyPrivacy privacy) +{ + internal_.privacy = static_cast(privacy); +} + +ActivityPartyPrivacy ActivityParty::GetPrivacy() const +{ + return static_cast(internal_.privacy); +} + +void ActivitySecrets::SetMatch(char const* match) +{ + strncpy(internal_.match, match, 128); + internal_.match[128 - 1] = '\0'; +} + +char const* ActivitySecrets::GetMatch() const +{ + return internal_.match; +} + +void ActivitySecrets::SetJoin(char const* join) +{ + strncpy(internal_.join, join, 128); + internal_.join[128 - 1] = '\0'; +} + +char const* ActivitySecrets::GetJoin() const +{ + return internal_.join; +} + +void ActivitySecrets::SetSpectate(char const* spectate) +{ + strncpy(internal_.spectate, spectate, 128); + internal_.spectate[128 - 1] = '\0'; +} + +char const* ActivitySecrets::GetSpectate() const +{ + return internal_.spectate; +} + +void Activity::SetType(ActivityType type) +{ + internal_.type = static_cast(type); +} + +ActivityType Activity::GetType() const +{ + return static_cast(internal_.type); +} + +void Activity::SetApplicationId(std::int64_t applicationId) +{ + internal_.application_id = applicationId; +} + +std::int64_t Activity::GetApplicationId() const +{ + return internal_.application_id; +} + +void Activity::SetName(char const* name) +{ + strncpy(internal_.name, name, 128); + internal_.name[128 - 1] = '\0'; +} + +char const* Activity::GetName() const +{ + return internal_.name; +} + +void Activity::SetState(char const* state) +{ + strncpy(internal_.state, state, 128); + internal_.state[128 - 1] = '\0'; +} + +char const* Activity::GetState() const +{ + return internal_.state; +} + +void Activity::SetDetails(char const* details) +{ + strncpy(internal_.details, details, 128); + internal_.details[128 - 1] = '\0'; +} + +char const* Activity::GetDetails() const +{ + return internal_.details; +} + +ActivityTimestamps& Activity::GetTimestamps() +{ + return reinterpret_cast(internal_.timestamps); +} + +ActivityTimestamps const& Activity::GetTimestamps() const +{ + return reinterpret_cast(internal_.timestamps); +} + +ActivityAssets& Activity::GetAssets() +{ + return reinterpret_cast(internal_.assets); +} + +ActivityAssets const& Activity::GetAssets() const +{ + return reinterpret_cast(internal_.assets); +} + +ActivityParty& Activity::GetParty() +{ + return reinterpret_cast(internal_.party); +} + +ActivityParty const& Activity::GetParty() const +{ + return reinterpret_cast(internal_.party); +} + +ActivitySecrets& Activity::GetSecrets() +{ + return reinterpret_cast(internal_.secrets); +} + +ActivitySecrets const& Activity::GetSecrets() const +{ + return reinterpret_cast(internal_.secrets); +} + +void Activity::SetInstance(bool instance) +{ + internal_.instance = instance; +} + +bool Activity::GetInstance() const +{ + return internal_.instance != 0; +} + +void Activity::SetSupportedPlatforms(std::uint32_t supportedPlatforms) +{ + internal_.supported_platforms = supportedPlatforms; +} + +std::uint32_t Activity::GetSupportedPlatforms() const +{ + return internal_.supported_platforms; +} + +void Presence::SetStatus(Status status) +{ + internal_.status = static_cast(status); +} + +Status Presence::GetStatus() const +{ + return static_cast(internal_.status); +} + +Activity& Presence::GetActivity() +{ + return reinterpret_cast(internal_.activity); +} + +Activity const& Presence::GetActivity() const +{ + return reinterpret_cast(internal_.activity); +} + +void Relationship::SetType(RelationshipType type) +{ + internal_.type = static_cast(type); +} + +RelationshipType Relationship::GetType() const +{ + return static_cast(internal_.type); +} + +User& Relationship::GetUser() +{ + return reinterpret_cast(internal_.user); +} + +User const& Relationship::GetUser() const +{ + return reinterpret_cast(internal_.user); +} + +Presence& Relationship::GetPresence() +{ + return reinterpret_cast(internal_.presence); +} + +Presence const& Relationship::GetPresence() const +{ + return reinterpret_cast(internal_.presence); +} + +void Lobby::SetId(LobbyId id) +{ + internal_.id = id; +} + +LobbyId Lobby::GetId() const +{ + return internal_.id; +} + +void Lobby::SetType(LobbyType type) +{ + internal_.type = static_cast(type); +} + +LobbyType Lobby::GetType() const +{ + return static_cast(internal_.type); +} + +void Lobby::SetOwnerId(UserId ownerId) +{ + internal_.owner_id = ownerId; +} + +UserId Lobby::GetOwnerId() const +{ + return internal_.owner_id; +} + +void Lobby::SetSecret(LobbySecret secret) +{ + strncpy(internal_.secret, secret, 128); + internal_.secret[128 - 1] = '\0'; +} + +LobbySecret Lobby::GetSecret() const +{ + return internal_.secret; +} + +void Lobby::SetCapacity(std::uint32_t capacity) +{ + internal_.capacity = capacity; +} + +std::uint32_t Lobby::GetCapacity() const +{ + return internal_.capacity; +} + +void Lobby::SetLocked(bool locked) +{ + internal_.locked = locked; +} + +bool Lobby::GetLocked() const +{ + return internal_.locked != 0; +} + +void ImeUnderline::SetFrom(std::int32_t from) +{ + internal_.from = from; +} + +std::int32_t ImeUnderline::GetFrom() const +{ + return internal_.from; +} + +void ImeUnderline::SetTo(std::int32_t to) +{ + internal_.to = to; +} + +std::int32_t ImeUnderline::GetTo() const +{ + return internal_.to; +} + +void ImeUnderline::SetColor(std::uint32_t color) +{ + internal_.color = color; +} + +std::uint32_t ImeUnderline::GetColor() const +{ + return internal_.color; +} + +void ImeUnderline::SetBackgroundColor(std::uint32_t backgroundColor) +{ + internal_.background_color = backgroundColor; +} + +std::uint32_t ImeUnderline::GetBackgroundColor() const +{ + return internal_.background_color; +} + +void ImeUnderline::SetThick(bool thick) +{ + internal_.thick = thick; +} + +bool ImeUnderline::GetThick() const +{ + return internal_.thick != 0; +} + +void Rect::SetLeft(std::int32_t left) +{ + internal_.left = left; +} + +std::int32_t Rect::GetLeft() const +{ + return internal_.left; +} + +void Rect::SetTop(std::int32_t top) +{ + internal_.top = top; +} + +std::int32_t Rect::GetTop() const +{ + return internal_.top; +} + +void Rect::SetRight(std::int32_t right) +{ + internal_.right = right; +} + +std::int32_t Rect::GetRight() const +{ + return internal_.right; +} + +void Rect::SetBottom(std::int32_t bottom) +{ + internal_.bottom = bottom; +} + +std::int32_t Rect::GetBottom() const +{ + return internal_.bottom; +} + +void FileStat::SetFilename(char const* filename) +{ + strncpy(internal_.filename, filename, 260); + internal_.filename[260 - 1] = '\0'; +} + +char const* FileStat::GetFilename() const +{ + return internal_.filename; +} + +void FileStat::SetSize(std::uint64_t size) +{ + internal_.size = size; +} + +std::uint64_t FileStat::GetSize() const +{ + return internal_.size; +} + +void FileStat::SetLastModified(std::uint64_t lastModified) +{ + internal_.last_modified = lastModified; +} + +std::uint64_t FileStat::GetLastModified() const +{ + return internal_.last_modified; +} + +void Entitlement::SetId(Snowflake id) +{ + internal_.id = id; +} + +Snowflake Entitlement::GetId() const +{ + return internal_.id; +} + +void Entitlement::SetType(EntitlementType type) +{ + internal_.type = static_cast(type); +} + +EntitlementType Entitlement::GetType() const +{ + return static_cast(internal_.type); +} + +void Entitlement::SetSkuId(Snowflake skuId) +{ + internal_.sku_id = skuId; +} + +Snowflake Entitlement::GetSkuId() const +{ + return internal_.sku_id; +} + +void SkuPrice::SetAmount(std::uint32_t amount) +{ + internal_.amount = amount; +} + +std::uint32_t SkuPrice::GetAmount() const +{ + return internal_.amount; +} + +void SkuPrice::SetCurrency(char const* currency) +{ + strncpy(internal_.currency, currency, 16); + internal_.currency[16 - 1] = '\0'; +} + +char const* SkuPrice::GetCurrency() const +{ + return internal_.currency; +} + +void Sku::SetId(Snowflake id) +{ + internal_.id = id; +} + +Snowflake Sku::GetId() const +{ + return internal_.id; +} + +void Sku::SetType(SkuType type) +{ + internal_.type = static_cast(type); +} + +SkuType Sku::GetType() const +{ + return static_cast(internal_.type); +} + +void Sku::SetName(char const* name) +{ + strncpy(internal_.name, name, 256); + internal_.name[256 - 1] = '\0'; +} + +char const* Sku::GetName() const +{ + return internal_.name; +} + +SkuPrice& Sku::GetPrice() +{ + return reinterpret_cast(internal_.price); +} + +SkuPrice const& Sku::GetPrice() const +{ + return reinterpret_cast(internal_.price); +} + +void InputMode::SetType(InputModeType type) +{ + internal_.type = static_cast(type); +} + +InputModeType InputMode::GetType() const +{ + return static_cast(internal_.type); +} + +void InputMode::SetShortcut(char const* shortcut) +{ + strncpy(internal_.shortcut, shortcut, 256); + internal_.shortcut[256 - 1] = '\0'; +} + +char const* InputMode::GetShortcut() const +{ + return internal_.shortcut; +} + +void UserAchievement::SetUserId(Snowflake userId) +{ + internal_.user_id = userId; +} + +Snowflake UserAchievement::GetUserId() const +{ + return internal_.user_id; +} + +void UserAchievement::SetAchievementId(Snowflake achievementId) +{ + internal_.achievement_id = achievementId; +} + +Snowflake UserAchievement::GetAchievementId() const +{ + return internal_.achievement_id; +} + +void UserAchievement::SetPercentComplete(std::uint8_t percentComplete) +{ + internal_.percent_complete = percentComplete; +} + +std::uint8_t UserAchievement::GetPercentComplete() const +{ + return internal_.percent_complete; +} + +void UserAchievement::SetUnlockedAt(DateTime unlockedAt) +{ + strncpy(internal_.unlocked_at, unlockedAt, 64); + internal_.unlocked_at[64 - 1] = '\0'; +} + +DateTime UserAchievement::GetUnlockedAt() const +{ + return internal_.unlocked_at; +} + +Result LobbyTransaction::SetType(LobbyType type) +{ + auto result = internal_->set_type(internal_, static_cast(type)); + return static_cast(result); +} + +Result LobbyTransaction::SetOwner(UserId ownerId) +{ + auto result = internal_->set_owner(internal_, ownerId); + return static_cast(result); +} + +Result LobbyTransaction::SetCapacity(std::uint32_t capacity) +{ + auto result = internal_->set_capacity(internal_, capacity); + return static_cast(result); +} + +Result LobbyTransaction::SetMetadata(MetadataKey key, MetadataValue value) +{ + auto result = + internal_->set_metadata(internal_, const_cast(key), const_cast(value)); + return static_cast(result); +} + +Result LobbyTransaction::DeleteMetadata(MetadataKey key) +{ + auto result = internal_->delete_metadata(internal_, const_cast(key)); + return static_cast(result); +} + +Result LobbyTransaction::SetLocked(bool locked) +{ + auto result = internal_->set_locked(internal_, (locked ? 1 : 0)); + return static_cast(result); +} + +Result LobbyMemberTransaction::SetMetadata(MetadataKey key, MetadataValue value) +{ + auto result = + internal_->set_metadata(internal_, const_cast(key), const_cast(value)); + return static_cast(result); +} + +Result LobbyMemberTransaction::DeleteMetadata(MetadataKey key) +{ + auto result = internal_->delete_metadata(internal_, const_cast(key)); + return static_cast(result); +} + +Result LobbySearchQuery::Filter(MetadataKey key, + LobbySearchComparison comparison, + LobbySearchCast cast, + MetadataValue value) +{ + auto result = internal_->filter(internal_, + const_cast(key), + static_cast(comparison), + static_cast(cast), + const_cast(value)); + return static_cast(result); +} + +Result LobbySearchQuery::Sort(MetadataKey key, LobbySearchCast cast, MetadataValue value) +{ + auto result = internal_->sort(internal_, + const_cast(key), + static_cast(cast), + const_cast(value)); + return static_cast(result); +} + +Result LobbySearchQuery::Limit(std::uint32_t limit) +{ + auto result = internal_->limit(internal_, limit); + return static_cast(result); +} + +Result LobbySearchQuery::Distance(LobbySearchDistance distance) +{ + auto result = + internal_->distance(internal_, static_cast(distance)); + return static_cast(result); +} + +} // namespace discord diff --git a/src/lib/discord_game_sdk/cpp/types.h b/src/lib/discord_game_sdk/cpp/types.h new file mode 100644 index 0000000..96154cd --- /dev/null +++ b/src/lib/discord_game_sdk/cpp/types.h @@ -0,0 +1,568 @@ +#include +#pragma once + +#include "ffi.h" +#include "event.h" +#ifdef _WIN32 +#include +#include +#endif + +namespace discord { + +enum class 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, + DrawingInitFailed = 44, +}; + +enum class CreateFlags { + Default = 0, + NoRequireDiscord = 1, +}; + +enum class LogLevel { + Error = 1, + Warn, + Info, + Debug, +}; + +enum class UserFlag { + Partner = 2, + HypeSquadEvents = 4, + HypeSquadHouse1 = 64, + HypeSquadHouse2 = 128, + HypeSquadHouse3 = 256, +}; + +enum class PremiumType { + None = 0, + Tier1 = 1, + Tier2 = 2, +}; + +enum class ImageType { + User, +}; + +enum class ActivityPartyPrivacy { + Private = 0, + Public = 1, +}; + +enum class ActivityType { + Playing, + Streaming, + Listening, + Watching, +}; + +enum class ActivityActionType { + Join = 1, + Spectate, +}; + +enum class ActivitySupportedPlatformFlags { + Desktop = 1, + Android = 2, + iOS = 4, +}; + +enum class ActivityJoinRequestReply { + No, + Yes, + Ignore, +}; + +enum class Status { + Offline = 0, + Online = 1, + Idle = 2, + DoNotDisturb = 3, +}; + +enum class RelationshipType { + None, + Friend, + Blocked, + PendingIncoming, + PendingOutgoing, + Implicit, +}; + +enum class LobbyType { + Private = 1, + Public, +}; + +enum class LobbySearchComparison { + LessThanOrEqual = -2, + LessThan, + Equal, + GreaterThan, + GreaterThanOrEqual, + NotEqual, +}; + +enum class LobbySearchCast { + String = 1, + Number, +}; + +enum class LobbySearchDistance { + Local, + Default, + Extended, + Global, +}; + +enum class KeyVariant { + Normal, + Right, + Left, +}; + +enum class MouseButton { + Left, + Middle, + Right, +}; + +enum class EntitlementType { + Purchase = 1, + PremiumSubscription, + DeveloperGift, + TestModePurchase, + FreePurchase, + UserGift, + PremiumPurchase, +}; + +enum class SkuType { + Application = 1, + DLC, + Consumable, + Bundle, +}; + +enum class InputModeType { + VoiceActivity = 0, + PushToTalk, +}; + +using ClientId = std::int64_t; +using Version = std::int32_t; +using Snowflake = std::int64_t; +using Timestamp = std::int64_t; +using UserId = Snowflake; +using Locale = char const*; +using Branch = char const*; +using LobbyId = Snowflake; +using LobbySecret = char const*; +using MetadataKey = char const*; +using MetadataValue = char const*; +using NetworkPeerId = std::uint64_t; +using NetworkChannelId = std::uint8_t; +#ifdef __APPLE__ +using IDXGISwapChain = void; +#endif +#ifdef __linux__ +using IDXGISwapChain = void; +#endif +#ifdef __APPLE__ +using MSG = void; +#endif +#ifdef __linux__ +using MSG = void; +#endif +using Path = char const*; +using DateTime = char const*; + +class User final { +public: + void SetId(UserId id); + UserId GetId() const; + void SetUsername(char const* username); + char const* GetUsername() const; + void SetDiscriminator(char const* discriminator); + char const* GetDiscriminator() const; + void SetAvatar(char const* avatar); + char const* GetAvatar() const; + void SetBot(bool bot); + bool GetBot() const; + +private: + DiscordUser internal_; +}; + +class OAuth2Token final { +public: + void SetAccessToken(char const* accessToken); + char const* GetAccessToken() const; + void SetScopes(char const* scopes); + char const* GetScopes() const; + void SetExpires(Timestamp expires); + Timestamp GetExpires() const; + +private: + DiscordOAuth2Token internal_; +}; + +class ImageHandle final { +public: + void SetType(ImageType type); + ImageType GetType() const; + void SetId(std::int64_t id); + std::int64_t GetId() const; + void SetSize(std::uint32_t size); + std::uint32_t GetSize() const; + +private: + DiscordImageHandle internal_; +}; + +class ImageDimensions final { +public: + void SetWidth(std::uint32_t width); + std::uint32_t GetWidth() const; + void SetHeight(std::uint32_t height); + std::uint32_t GetHeight() const; + +private: + DiscordImageDimensions internal_; +}; + +class ActivityTimestamps final { +public: + void SetStart(Timestamp start); + Timestamp GetStart() const; + void SetEnd(Timestamp end); + Timestamp GetEnd() const; + +private: + DiscordActivityTimestamps internal_; +}; + +class ActivityAssets final { +public: + void SetLargeImage(char const* largeImage); + char const* GetLargeImage() const; + void SetLargeText(char const* largeText); + char const* GetLargeText() const; + void SetSmallImage(char const* smallImage); + char const* GetSmallImage() const; + void SetSmallText(char const* smallText); + char const* GetSmallText() const; + +private: + DiscordActivityAssets internal_; +}; + +class PartySize final { +public: + void SetCurrentSize(std::int32_t currentSize); + std::int32_t GetCurrentSize() const; + void SetMaxSize(std::int32_t maxSize); + std::int32_t GetMaxSize() const; + +private: + DiscordPartySize internal_; +}; + +class ActivityParty final { +public: + void SetId(char const* id); + char const* GetId() const; + PartySize& GetSize(); + PartySize const& GetSize() const; + void SetPrivacy(ActivityPartyPrivacy privacy); + ActivityPartyPrivacy GetPrivacy() const; + +private: + DiscordActivityParty internal_; +}; + +class ActivitySecrets final { +public: + void SetMatch(char const* match); + char const* GetMatch() const; + void SetJoin(char const* join); + char const* GetJoin() const; + void SetSpectate(char const* spectate); + char const* GetSpectate() const; + +private: + DiscordActivitySecrets internal_; +}; + +class Activity final { +public: + void SetType(ActivityType type); + ActivityType GetType() const; + void SetApplicationId(std::int64_t applicationId); + std::int64_t GetApplicationId() const; + void SetName(char const* name); + char const* GetName() const; + void SetState(char const* state); + char const* GetState() const; + void SetDetails(char const* details); + char const* GetDetails() const; + ActivityTimestamps& GetTimestamps(); + ActivityTimestamps const& GetTimestamps() const; + ActivityAssets& GetAssets(); + ActivityAssets const& GetAssets() const; + ActivityParty& GetParty(); + ActivityParty const& GetParty() const; + ActivitySecrets& GetSecrets(); + ActivitySecrets const& GetSecrets() const; + void SetInstance(bool instance); + bool GetInstance() const; + void SetSupportedPlatforms(std::uint32_t supportedPlatforms); + std::uint32_t GetSupportedPlatforms() const; + +private: + DiscordActivity internal_; +}; + +class Presence final { +public: + void SetStatus(Status status); + Status GetStatus() const; + Activity& GetActivity(); + Activity const& GetActivity() const; + +private: + DiscordPresence internal_; +}; + +class Relationship final { +public: + void SetType(RelationshipType type); + RelationshipType GetType() const; + User& GetUser(); + User const& GetUser() const; + Presence& GetPresence(); + Presence const& GetPresence() const; + +private: + DiscordRelationship internal_; +}; + +class Lobby final { +public: + void SetId(LobbyId id); + LobbyId GetId() const; + void SetType(LobbyType type); + LobbyType GetType() const; + void SetOwnerId(UserId ownerId); + UserId GetOwnerId() const; + void SetSecret(LobbySecret secret); + LobbySecret GetSecret() const; + void SetCapacity(std::uint32_t capacity); + std::uint32_t GetCapacity() const; + void SetLocked(bool locked); + bool GetLocked() const; + +private: + DiscordLobby internal_; +}; + +class ImeUnderline final { +public: + void SetFrom(std::int32_t from); + std::int32_t GetFrom() const; + void SetTo(std::int32_t to); + std::int32_t GetTo() const; + void SetColor(std::uint32_t color); + std::uint32_t GetColor() const; + void SetBackgroundColor(std::uint32_t backgroundColor); + std::uint32_t GetBackgroundColor() const; + void SetThick(bool thick); + bool GetThick() const; + +private: + DiscordImeUnderline internal_; +}; + +class Rect final { +public: + void SetLeft(std::int32_t left); + std::int32_t GetLeft() const; + void SetTop(std::int32_t top); + std::int32_t GetTop() const; + void SetRight(std::int32_t right); + std::int32_t GetRight() const; + void SetBottom(std::int32_t bottom); + std::int32_t GetBottom() const; + +private: + DiscordRect internal_; +}; + +class FileStat final { +public: + void SetFilename(char const* filename); + char const* GetFilename() const; + void SetSize(std::uint64_t size); + std::uint64_t GetSize() const; + void SetLastModified(std::uint64_t lastModified); + std::uint64_t GetLastModified() const; + +private: + DiscordFileStat internal_; +}; + +class Entitlement final { +public: + void SetId(Snowflake id); + Snowflake GetId() const; + void SetType(EntitlementType type); + EntitlementType GetType() const; + void SetSkuId(Snowflake skuId); + Snowflake GetSkuId() const; + +private: + DiscordEntitlement internal_; +}; + +class SkuPrice final { +public: + void SetAmount(std::uint32_t amount); + std::uint32_t GetAmount() const; + void SetCurrency(char const* currency); + char const* GetCurrency() const; + +private: + DiscordSkuPrice internal_; +}; + +class Sku final { +public: + void SetId(Snowflake id); + Snowflake GetId() const; + void SetType(SkuType type); + SkuType GetType() const; + void SetName(char const* name); + char const* GetName() const; + SkuPrice& GetPrice(); + SkuPrice const& GetPrice() const; + +private: + DiscordSku internal_; +}; + +class InputMode final { +public: + void SetType(InputModeType type); + InputModeType GetType() const; + void SetShortcut(char const* shortcut); + char const* GetShortcut() const; + +private: + DiscordInputMode internal_; +}; + +class UserAchievement final { +public: + void SetUserId(Snowflake userId); + Snowflake GetUserId() const; + void SetAchievementId(Snowflake achievementId); + Snowflake GetAchievementId() const; + void SetPercentComplete(std::uint8_t percentComplete); + std::uint8_t GetPercentComplete() const; + void SetUnlockedAt(DateTime unlockedAt); + DateTime GetUnlockedAt() const; + +private: + DiscordUserAchievement internal_; +}; + +class LobbyTransaction final { +public: + Result SetType(LobbyType type); + Result SetOwner(UserId ownerId); + Result SetCapacity(std::uint32_t capacity); + Result SetMetadata(MetadataKey key, MetadataValue value); + Result DeleteMetadata(MetadataKey key); + Result SetLocked(bool locked); + + IDiscordLobbyTransaction** Receive() { return &internal_; } + IDiscordLobbyTransaction* Internal() { return internal_; } + +private: + IDiscordLobbyTransaction* internal_; +}; + +class LobbyMemberTransaction final { +public: + Result SetMetadata(MetadataKey key, MetadataValue value); + Result DeleteMetadata(MetadataKey key); + + IDiscordLobbyMemberTransaction** Receive() { return &internal_; } + IDiscordLobbyMemberTransaction* Internal() { return internal_; } + +private: + IDiscordLobbyMemberTransaction* internal_; +}; + +class LobbySearchQuery final { +public: + Result Filter(MetadataKey key, + LobbySearchComparison comparison, + LobbySearchCast cast, + MetadataValue value); + Result Sort(MetadataKey key, LobbySearchCast cast, MetadataValue value); + Result Limit(std::uint32_t limit); + Result Distance(LobbySearchDistance distance); + + IDiscordLobbySearchQuery** Receive() { return &internal_; } + IDiscordLobbySearchQuery* Internal() { return internal_; } + +private: + IDiscordLobbySearchQuery* internal_; +}; + +} // namespace discord diff --git a/src/lib/discord_game_sdk/cpp/user_manager.cpp b/src/lib/discord_game_sdk/cpp/user_manager.cpp new file mode 100644 index 0000000..ddb6d5c --- /dev/null +++ b/src/lib/discord_game_sdk/cpp/user_manager.cpp @@ -0,0 +1,80 @@ +#if !defined(_CRT_SECURE_NO_WARNINGS) +#define _CRT_SECURE_NO_WARNINGS +#endif + +#include "user_manager.h" + +#include "core.h" + +#include +#include + +namespace discord { + +class UserEvents final { +public: + static void DISCORD_CALLBACK OnCurrentUserUpdate(void* callbackData) + { + auto* core = reinterpret_cast(callbackData); + if (!core) { + return; + } + + auto& module = core->UserManager(); + module.OnCurrentUserUpdate(); + } +}; + +IDiscordUserEvents UserManager::events_{ + &UserEvents::OnCurrentUserUpdate, +}; + +Result UserManager::GetCurrentUser(User* currentUser) +{ + if (!currentUser) { + return Result::InternalError; + } + + auto result = + internal_->get_current_user(internal_, reinterpret_cast(currentUser)); + return static_cast(result); +} + +void UserManager::GetUser(UserId userId, std::function callback) +{ + static auto wrapper = [](void* callbackData, EDiscordResult result, DiscordUser* user) -> void { + std::unique_ptr> cb( + reinterpret_cast*>(callbackData)); + if (!cb || !(*cb)) { + return; + } + (*cb)(static_cast(result), *reinterpret_cast(user)); + }; + std::unique_ptr> cb{}; + cb.reset(new std::function(std::move(callback))); + internal_->get_user(internal_, userId, cb.release(), wrapper); +} + +Result UserManager::GetCurrentUserPremiumType(PremiumType* premiumType) +{ + if (!premiumType) { + return Result::InternalError; + } + + auto result = internal_->get_current_user_premium_type( + internal_, reinterpret_cast(premiumType)); + return static_cast(result); +} + +Result UserManager::CurrentUserHasFlag(UserFlag flag, bool* hasFlag) +{ + if (!hasFlag) { + return Result::InternalError; + } + + auto result = internal_->current_user_has_flag( + internal_, static_cast(flag), reinterpret_cast(hasFlag)); + return static_cast(result); +} + +} // namespace discord diff --git a/src/lib/discord_game_sdk/cpp/user_manager.h b/src/lib/discord_game_sdk/cpp/user_manager.h new file mode 100644 index 0000000..d85de1b --- /dev/null +++ b/src/lib/discord_game_sdk/cpp/user_manager.h @@ -0,0 +1,31 @@ +#pragma once + +#include "types.h" + +namespace discord { + +class UserManager final { +public: + ~UserManager() = default; + + Result GetCurrentUser(User* currentUser); + void GetUser(UserId userId, std::function callback); + Result GetCurrentUserPremiumType(PremiumType* premiumType); + Result CurrentUserHasFlag(UserFlag flag, bool* hasFlag); + + Event<> OnCurrentUserUpdate; + +private: + friend class Core; + + UserManager() = default; + UserManager(UserManager const& rhs) = delete; + UserManager& operator=(UserManager const& rhs) = delete; + UserManager(UserManager&& rhs) = delete; + UserManager& operator=(UserManager&& rhs) = delete; + + IDiscordUserManager* internal_; + static IDiscordUserEvents events_; +}; + +} // namespace discord diff --git a/src/lib/discord_game_sdk/cpp/voice_manager.cpp b/src/lib/discord_game_sdk/cpp/voice_manager.cpp new file mode 100644 index 0000000..014ceb3 --- /dev/null +++ b/src/lib/discord_game_sdk/cpp/voice_manager.cpp @@ -0,0 +1,124 @@ +#if !defined(_CRT_SECURE_NO_WARNINGS) +#define _CRT_SECURE_NO_WARNINGS +#endif + +#include "voice_manager.h" + +#include "core.h" + +#include +#include + +namespace discord { + +class VoiceEvents final { +public: + static void DISCORD_CALLBACK OnSettingsUpdate(void* callbackData) + { + auto* core = reinterpret_cast(callbackData); + if (!core) { + return; + } + + auto& module = core->VoiceManager(); + module.OnSettingsUpdate(); + } +}; + +IDiscordVoiceEvents VoiceManager::events_{ + &VoiceEvents::OnSettingsUpdate, +}; + +Result VoiceManager::GetInputMode(InputMode* inputMode) +{ + if (!inputMode) { + return Result::InternalError; + } + + auto result = + internal_->get_input_mode(internal_, reinterpret_cast(inputMode)); + return static_cast(result); +} + +void VoiceManager::SetInputMode(InputMode inputMode, std::function callback) +{ + static auto wrapper = [](void* callbackData, EDiscordResult result) -> void { + std::unique_ptr> cb( + reinterpret_cast*>(callbackData)); + if (!cb || !(*cb)) { + return; + } + (*cb)(static_cast(result)); + }; + std::unique_ptr> cb{}; + cb.reset(new std::function(std::move(callback))); + internal_->set_input_mode( + internal_, *reinterpret_cast(&inputMode), cb.release(), wrapper); +} + +Result VoiceManager::IsSelfMute(bool* mute) +{ + if (!mute) { + return Result::InternalError; + } + + auto result = internal_->is_self_mute(internal_, reinterpret_cast(mute)); + return static_cast(result); +} + +Result VoiceManager::SetSelfMute(bool mute) +{ + auto result = internal_->set_self_mute(internal_, (mute ? 1 : 0)); + return static_cast(result); +} + +Result VoiceManager::IsSelfDeaf(bool* deaf) +{ + if (!deaf) { + return Result::InternalError; + } + + auto result = internal_->is_self_deaf(internal_, reinterpret_cast(deaf)); + return static_cast(result); +} + +Result VoiceManager::SetSelfDeaf(bool deaf) +{ + auto result = internal_->set_self_deaf(internal_, (deaf ? 1 : 0)); + return static_cast(result); +} + +Result VoiceManager::IsLocalMute(Snowflake userId, bool* mute) +{ + if (!mute) { + return Result::InternalError; + } + + auto result = internal_->is_local_mute(internal_, userId, reinterpret_cast(mute)); + return static_cast(result); +} + +Result VoiceManager::SetLocalMute(Snowflake userId, bool mute) +{ + auto result = internal_->set_local_mute(internal_, userId, (mute ? 1 : 0)); + return static_cast(result); +} + +Result VoiceManager::GetLocalVolume(Snowflake userId, std::uint8_t* volume) +{ + if (!volume) { + return Result::InternalError; + } + + auto result = + internal_->get_local_volume(internal_, userId, reinterpret_cast(volume)); + return static_cast(result); +} + +Result VoiceManager::SetLocalVolume(Snowflake userId, std::uint8_t volume) +{ + auto result = internal_->set_local_volume(internal_, userId, volume); + return static_cast(result); +} + +} // namespace discord diff --git a/src/lib/discord_game_sdk/cpp/voice_manager.h b/src/lib/discord_game_sdk/cpp/voice_manager.h new file mode 100644 index 0000000..95b20e9 --- /dev/null +++ b/src/lib/discord_game_sdk/cpp/voice_manager.h @@ -0,0 +1,37 @@ +#pragma once + +#include "types.h" + +namespace discord { + +class VoiceManager final { +public: + ~VoiceManager() = default; + + Result GetInputMode(InputMode* inputMode); + void SetInputMode(InputMode inputMode, std::function callback); + Result IsSelfMute(bool* mute); + Result SetSelfMute(bool mute); + Result IsSelfDeaf(bool* deaf); + Result SetSelfDeaf(bool deaf); + Result IsLocalMute(Snowflake userId, bool* mute); + Result SetLocalMute(Snowflake userId, bool mute); + Result GetLocalVolume(Snowflake userId, std::uint8_t* volume); + Result SetLocalVolume(Snowflake userId, std::uint8_t volume); + + Event<> OnSettingsUpdate; + +private: + friend class Core; + + VoiceManager() = default; + VoiceManager(VoiceManager const& rhs) = delete; + VoiceManager& operator=(VoiceManager const& rhs) = delete; + VoiceManager(VoiceManager&& rhs) = delete; + VoiceManager& operator=(VoiceManager&& rhs) = delete; + + IDiscordVoiceManager* internal_; + static IDiscordVoiceEvents events_; +}; + +} // namespace discord diff --git a/src/register_types.cpp b/src/register_types.cpp index 2894a37..2d2e112 100644 --- a/src/register_types.cpp +++ b/src/register_types.cpp @@ -10,36 +10,36 @@ #include "editor_presence.h" using namespace godot; -static DiscordSDK *discordsdk; +static DiscordRPC *discordrpc; -void initialize_discordsdk_module(ModuleInitializationLevel p_level) +void initialize_discordrpc_module(ModuleInitializationLevel p_level) { if (p_level == MODULE_INITIALIZATION_LEVEL_SCENE) { - ClassDB::register_class(); - discordsdk = memnew(DiscordSDK); - Engine::get_singleton()->register_singleton("DiscordSDK", DiscordSDK::get_singleton()); + ClassDB::register_class(); + discordrpc = memnew(DiscordRPC); + Engine::get_singleton()->register_singleton("DiscordRPC", DiscordRPC::get_singleton()); ClassDB::register_class(); } } -void uninitialize_discordsdk_module(ModuleInitializationLevel p_level) +void uninitialize_discordrpc_module(ModuleInitializationLevel p_level) { if (p_level == MODULE_INITIALIZATION_LEVEL_SCENE) { - Engine::get_singleton()->unregister_singleton("DiscordSDK"); - memdelete(discordsdk); + Engine::get_singleton()->unregister_singleton("DiscordRPC"); + memdelete(discordrpc); } } extern "C" { - GDExtensionBool GDE_EXPORT discordsdkgd_library_init(GDExtensionInterfaceGetProcAddress p_get_proc_address, GDExtensionClassLibraryPtr p_library, GDExtensionInitialization *r_initialization) + GDExtensionBool GDE_EXPORT discordrpcgd_library_init(GDExtensionInterfaceGetProcAddress p_get_proc_address, GDExtensionClassLibraryPtr p_library, GDExtensionInitialization *r_initialization) { godot::GDExtensionBinding::InitObject init_obj(p_get_proc_address, p_library, r_initialization); - init_obj.register_initializer(initialize_discordsdk_module); - init_obj.register_terminator(uninitialize_discordsdk_module); + init_obj.register_initializer(initialize_discordrpc_module); + init_obj.register_terminator(uninitialize_discordrpc_module); init_obj.set_minimum_library_initialization_level(MODULE_INITIALIZATION_LEVEL_SCENE); return init_obj.init(); diff --git a/src/register_types.h b/src/register_types.h index ca12a98..61012a7 100644 --- a/src/register_types.h +++ b/src/register_types.h @@ -1,7 +1,7 @@ #ifndef REGISTER_TYPES_H #define REGISTER_TYPES_H -void initialize_discordsdk_module(); -void uninitialize_discordsdk_module(); +void initialize_discordrpc_module(); +void uninitialize_discordrpc_module(); #endif // REGISTER_TYPES_H \ No newline at end of file