a lot of social sdk progress

This commit is contained in:
2025-03-23 22:36:54 +01:00
parent 80bcfbd98d
commit e9a48bba97
29 changed files with 370 additions and 255 deletions

View File

@@ -21,7 +21,7 @@ body:
id: version
attributes:
label: Version
description: What version of the Discord RPC Godot plugin are you running?
description: What version of the Discord Social SDK Godot plugin are you running?
options:
- 1.3.1
- 1.3.0

View File

@@ -6,7 +6,7 @@ Discord recently released its new SDK. This plugin will get a huge overhaul and
---
### This is for the Discord Game SDK NOT the Embedded App SDK
**Discord RPC Plugin for GDScript with an easy-to-use code pattern in Godot Engine 4.1+, with optional Editor Rich Presence! (Compatible with Linux, Windows, & MacOS)**<br><br>
**Discord Social SDK Plugin for GDScript with an easy-to-use code pattern in Godot Engine 4.1+, with optional Editor Rich Presence! (Compatible with Linux, Windows, & MacOS)**<br><br>
<br />
### [My Discord Server](https://discord.gg/3gqUrtbaur)
# [Quick start :rocket: (click here)](https://docs.vaporvee.com/discord-rpc-godot#quick-start)

View File

@@ -3,8 +3,8 @@ import os
env = SConscript("src/lib/godot-cpp/SConstruct")
env.Append(CPPPATH=["src/", "src/lib/discord_social_sdk/include/"])
sources = Glob("src/*.cpp")
env.Append(CPPPATH=["src/","src/nodes/", "src/lib/discord_social_sdk/include/"])
sources = Glob("src/*.cpp") + Glob("src/nodes/*.cpp")
if env["platform"] == "macos":
discord_library = "libdiscord_partner_sdk.dylib"

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.9 KiB

View File

@@ -1,34 +0,0 @@
[remap]
importer="texture"
type="CompressedTexture2D"
uid="uid://csl0e2px0cwc1"
path="res://.godot/imported/Logo_V2_No_Bg.png-ed667fb599fe1e17ebcfc361ff7c9c93.ctex"
metadata={
"vram_texture": false
}
[deps]
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]
compress/mode=0
compress/high_quality=false
compress/lossy_quality=0.7
compress/hdr_compression=1
compress/normal_map=0
compress/channel_pack=0
mipmaps/generate=false
mipmaps/limit=-1
roughness/mode=0
roughness/src_normal=""
process/fix_alpha_border=true
process/premult_alpha=false
process/normal_map_invert_y=false
process/hdr_as_srgb=false
process/hdr_clamp_exposure=false
process/size_limit=0
detect_3d/compress_to=1

View File

@@ -1,6 +1,6 @@
MINIMUM GODOT VERSION: 4.2
PLEASE ACTIVATE THE PLUGIN UNDER Project -> Project Settings... -> Plugins -> DiscordRPC -> Status
PLEASE ACTIVATE THE PLUGIN UNDER Project -> Project Settings... -> Plugins -> DiscordUtil -> Status
IGNORE THE RED ERRORS ON THE FIRST 2 RESTARTS
READ THE TUTORIAL LINKED IN THE WINDOW THAT WILL OPEN ON PLUGIN ENABLE

View File

@@ -1,6 +1,6 @@
[configuration]
entry_symbol = "discordrpcgd_library_init"
entry_symbol = "DiscordUtilgd_library_init"
compatibility_minimum = 4.1
[libraries]

View File

@@ -1,8 +1,8 @@
class_name DiscordRPCTutorial
class_name DiscordUtilTutorial
extends Node
## 1. Put the addons/ folder in your Godot project[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]
## 2. Enable the addon in your Project Settings under "Plugins" and "DiscordUtil". [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,27 +11,27 @@ extends Node
## [codeblock]
## func _ready():
## # Application ID
## DiscordRPC.app_id = 1099618430065324082
## DiscordUtil.app_id = 1099618430065324082
## # this is boolean if everything worked
## print("Discord working: " + str(DiscordRPC.get_is_discord_working()))
## print("Discord working: " + str(DiscordUtil.get_is_discord_working()))
## # Set the first custom text row of the activity here
## DiscordRPC.details = "A demo activity by vaporvee#1231"
## DiscordUtil.details = "A demo activity by vaporvee#1231"
## # Set the second custom text row of the activity here
## DiscordRPC.state = "Checkpoint 23/23"
## DiscordUtil.state = "Checkpoint 23/23"
## # Image key for small image from "Art Assets" from the Discord Developer website
## DiscordRPC.large_image = "game"
## DiscordUtil.large_image = "game"
## # Tooltip text for the large image
## DiscordRPC.large_image_text = "Try it now!"
## DiscordUtil.large_image_text = "Try it now!"
## # Image key for large image from "Art Assets" from the Discord Developer website
## DiscordRPC.small_image = "boss"
## DiscordUtil.small_image = "boss"
## # Tooltip text for the small image
## DiscordRPC.small_image_text = "Fighting the end boss! D:"
## DiscordUtil.small_image_text = "Fighting the end boss! D:"
## # "02:41 elapsed" timestamp for the activity
## DiscordRPC.start_timestamp = int(Time.get_unix_time_from_system())
## DiscordUtil.start_timestamp = int(Time.get_unix_time_from_system())
## # "59:59 remaining" timestamp for the activity
## DiscordRPC.end_timestamp = int(Time.get_unix_time_from_system()) + 3600
## DiscordUtil.end_timestamp = int(Time.get_unix_time_from_system()) + 3600
## # Always refresh after changing the values!
## DiscordRPC.refresh()
## DiscordUtil.refresh()
## [/codeblock]
##
## @tutorial(More information here): https://github.com/vaporvee/discord-rpc-godot/wiki/Quick-start

View File

@@ -11,10 +11,10 @@ script/source = "extends Node
@onready var animation_player: AnimationPlayer = $Panel/TextureRect/AnimationPlayer
func _ready():
DiscordRPC.connect(\"activity_join_request\",_on_activity_join_request)
DiscordUtil.connect(\"activity_join_request\",_on_activity_join_request)
func _process(_delta) -> void:
if(DiscordRPC.get_is_discord_working()):
if(DiscordUtil.get_is_discord_working()):
$Panel/TextureRect.self_modulate = Color(\"#3eff8d\")
if !animation_player.is_playing():
animation_player.play(\"pulsate\")
@@ -48,7 +48,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(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))
#$Panel/Info.text = $Panel/Info.text.replace(\"{ppublic}\",str(DiscordUtil.is_public_party)).replace(\"{instanced}\",str(DiscordUtil.instanced)).replace(\"{ssecret}\",DiscordUtil.spectate_secret).replace(\"{jsecret}\",DiscordUtil.join_secret).replace(\"{msecret}\",DiscordUtil.match_secret).replace(\"{mpartysize}\",str(DiscordUtil.max_party_size)).replace(\"{cpartysize}\",str(DiscordUtil.current_party_size)).replace(\"{partyid}\",DiscordUtil.party_id).replace(\"{id}\",str(DiscordUtil.app_id)).replace(\"{details}\",DiscordUtil.details).replace(\"{state}\",DiscordUtil.state).replace(\"{lkey}\",DiscordUtil.large_image).replace(\"{ltext}\",DiscordUtil.large_image_text).replace(\"{skey}\",DiscordUtil.small_image).replace(\"{stext}\",DiscordUtil.small_image_text).replace(\"{stimestamp}\",str(DiscordUtil.start_timestamp)).replace(\"{etimestamp}\",str(DiscordUtil.end_timestamp))
var user_request: Dictionary = {};
@@ -58,25 +58,25 @@ func _on_activity_join_request(user_requesting: Dictionary) -> void:
func _on_accept_join_request_pressed() -> void:
if(!user_request.is_empty()):
DiscordRPC.accept_join_request(user_request.id)
DiscordUtil.accept_join_request(user_request.id)
func _on_invite_with_user_id_text_submitted(new_text: String) -> void:
DiscordRPC.send_invite(int(new_text),true,\"this is a test invite sent from godot\")
DiscordUtil.send_invite(int(new_text),true,\"this is a test invite sent from godot\")
func _on_accept_with_user_id_text_submitted(new_text: String) -> void:
DiscordRPC.accept_invite(int(new_text))
DiscordUtil.accept_invite(int(new_text))
func _on_print_current_user_on_console_pressed() -> void:
print(DiscordRPC.get_current_user())
print(DiscordUtil.get_current_user())
func _on_toggle_sdk_toggled(button_pressed: bool) -> void:
if(button_pressed):
DiscordRPC.unclear()
DiscordUtil.unclear()
else:
DiscordRPC.clear(false)
DiscordUtil.clear(false)
func _on_print_friends_pressed() -> void:
print(DiscordRPC.get_all_relationships())
print(DiscordUtil.get_all_relationships())
"
[sub_resource type="StyleBoxEmpty" id="StyleBoxEmpty_8abo6"]

View File

@@ -1,6 +1,6 @@
## This is a Debug Node wich will show some usefull info and buttons/input
##
## The DiscordRPC Debug Node will show info about the current values of its variables and some buttons to change them.
## The DiscordUtil Debug Node will show info about the current values of its variables and some buttons to change them.
##
## @tutorial: https://github.com/vaporvee/discord-rpc-godot/wiki
@tool

View File

@@ -1,7 +1,7 @@
## 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]DiscordRPC.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]DiscordUtil.run_callbacks()[/code] in a [code]_process[/code] function.
##
## @tutorial: https://github.com/vaporvee/discord-rpc-godot/wiki
extends Node
@@ -10,4 +10,4 @@ func _ready() -> void:
pass
func _process(_delta) -> void:
DiscordRPC.run_callbacks()
DiscordUtil.run_callbacks()

View File

@@ -1 +1 @@
uid://d1ohgxo4k3cdf
uid://dc5abjov0ebdr

View File

@@ -1,7 +1,7 @@
[plugin]
name="DiscordRPC"
description="Discord RPC Plugin for GDScript in Godot"
name="Discord Social SDK"
description="Discord Social SDK Plugin for GDScript in Godot"
author="vaporvee"
version="1.3.2"
script="plugin.gd"

View File

@@ -1,42 +1,43 @@
@tool
extends EditorPlugin
const DiscordRPCDebug: GDScript = preload("res://addons/discord-rpc-gd/nodes/debug.gd")
const DiscordRPCDebug_icon: Texture2D = preload("res://addons/discord-rpc-gd/Debug.svg")
var loaded_DiscordRPCDebug: DiscordRPCDebug = DiscordRPCDebug.new()
const DiscordSocialSDKDebug: GDScript = preload("res://addons/discord-rpc-gd/nodes/debug.gd")
const DiscordSocialSDKDebug_icon: Texture2D = preload("res://addons/discord-rpc-gd/Debug.svg")
var loaded_DiscordSocialSDKDebug: DiscordSocialSDKDebug = DiscordSocialSDKDebug.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: String = "/plugin_data.cfg"
func _enter_tree() -> void:
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("DiscordRPC/EditorPresence/enabled"):
get_editor_interface().get_editor_settings().set_setting("DiscordRPC/EditorPresence/enabled",plugin_cfg.get_value("Discord","editor_presence",false))
if !get_editor_interface().get_editor_settings().has_setting("DiscordSocialSDK/EditorPresence/enabled"):
get_editor_interface().get_editor_settings().set_setting("DiscordSocialSDK/EditorPresence/enabled",plugin_cfg.get_value("Discord","editor_presence",false))
func _enter_tree() -> void:
add_custom_type("DiscordSocialSDKDebug","Node",DiscordSocialSDKDebug,DiscordSocialSDKDebug_icon)
get_editor_interface().get_editor_settings().settings_changed.connect(_on_editor_settings_changed)
func _exit_tree() -> void:
if get_editor_interface().get_editor_settings().has_setting("DiscordRPC/EditorPresence/enabled"):
get_editor_interface().get_editor_settings().erase("DiscordRPC/EditorPresence/enabled")
if get_editor_interface().get_editor_settings().has_setting("DiscordSocialSDK/EditorPresence/enabled"):
get_editor_interface().get_editor_settings().erase("DiscordSocialSDK/EditorPresence/enabled")
func _enable_plugin() -> void:
add_custom_type("DiscordSocialSDKDebug","Node",DiscordSocialSDKDebug,DiscordSocialSDKDebug_icon)
get_editor_interface().get_editor_settings().settings_changed.connect(_on_editor_settings_changed)
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("DiscordRPCLoader")
remove_autoload_singleton("DiscordUtilLoader")
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")
remove_custom_type("DiscordSocialSDKDebug")
get_editor_interface().get_editor_settings().erase("DiscordSocialSDK/EditorPresence/enabled")
push_warning("Please restart the editor to fully disable the DiscordUtil plugin")
func save_and_restart() -> void:
get_editor_interface().restart_editor(true)
@@ -46,11 +47,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("DiscordRPC/EditorPresence/enabled"))
plugin_cfg.set_value("Discord","editor_presence",get_editor_interface().get_editor_settings().get_setting("DiscordSocialSDK/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("DiscordRPC/EditorPresence/enabled") && get_editor_interface().get_editor_settings().get_setting("DiscordRPC/EditorPresence/enabled"):
if get_editor_interface().get_editor_settings().has_setting("DiscordSocialSDK/EditorPresence/enabled") && get_editor_interface().get_editor_settings().get_setting("DiscordSocialSDK/EditorPresence/enabled"):
add_child(editor_presence)
else:
editor_presence.queue_free()

View File

@@ -40,7 +40,7 @@ application/file_version=""
application/product_version=""
application/company_name=""
application/product_name=""
application/file_description="Discord RPC Godot Test"
application/file_description="Discord Social SDK Godot Test"
application/copyright=""
application/trademarks=""
application/export_angle=0

View File

@@ -3,41 +3,41 @@ extends Node
func _ready() -> void:
if GDExtensionManager.is_extension_loaded("res://addons/discord-rpc-gd/bin/discord-rpc-gd.gdextension"):
set_activity()
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)
DiscordUtil.connect("activity_join_request",_on_activity_join_request)
#DiscordUtil.connect("activity_join",_on_activity_join)
DiscordUtil.connect("activity_spectate",_on_activity_spectate)
DiscordUtil.connect("relationships_init",_on_relationship_init)
DiscordUtil.connect("updated_relationship", _on_updated_relationship)
func set_activity() -> void:
#DiscordRPC.clear(false)
DiscordRPC.app_id = 1099618430065324082
DiscordRPC.debug()
#DiscordRPC.details = "A demo activity by vaporvee#1231"
#DiscordRPC.state = "Checkpoint 23/23"
#DiscordUtil.clear(false)
DiscordUtil.app_id = 1099618430065324082
DiscordUtil.debug()
#DiscordUtil.details = "A demo activity by vaporvee#1231"
#DiscordUtil.state = "Checkpoint 23/23"
#
#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
#DiscordUtil.large_image = "example_game"
#DiscordUtil.large_image_text = "Try it now!"
#DiscordUtil.small_image = "boss"
#DiscordUtil.small_image_text = "Fighting the end boss! D:"
#DiscordUtil.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))
#var my_secret: String = str(randi_range(0,999999))
#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()
#DiscordUtil.party_id = "mylobbycanbeeverything_" + my_secret
#DiscordUtil.current_party_size = 1
#DiscordUtil.max_party_size = 4
#DiscordUtil.match_secret = "m_" + my_secret #better use seeds with 1 to 1 range instead of just chars
#DiscordUtil.join_secret = "j_" + my_secret
#DiscordUtil.spectate_secret = "s_" + my_secret
#DiscordUtil.is_public_party = true
#DiscordUtil.instanced = true #required for spectate
#DiscordUtil.start_timestamp = int(Time.get_unix_time_from_system())
DiscordUtil.register_command("C:\\Users\\yanni\\Desktop\\demo\\DiscordUtil.exe")
#DiscordUtil.register_steam(1389990)
DiscordUtil.refresh()
var user_request: Dictionary;
@@ -46,13 +46,13 @@ func _on_activity_join_request(user_requesting: Dictionary) -> void:
user_request = user_requesting
#func _on_activity_join(secret: String) -> void:
#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()
#if(DiscordUtil.join_secret != secret):
#DiscordUtil.current_party_size = clamp(int(secret) + 1, 0, DiscordUtil.max_party_size)
#DiscordUtil.party_id = secret.replace("j_","mylobbycanbeeverything_")
#DiscordUtil.match_secret = secret.replace("j_","m_")
#DiscordUtil.join_secret = secret
#DiscordUtil.spectate_secret = secret.replace("j_","s_")
#DiscordUtil.refresh()
func _on_activity_spectate(secret: String) -> void:
print(secret)

View File

@@ -23,7 +23,7 @@ position = Vector2(789, 330.5)
scale = Vector2(0.408203, 0.408203)
texture = ExtResource("2_gd222")
[node name="DiscordRPC Test" type="RichTextLabel" parent="."]
[node name="DiscordUtil Test" type="RichTextLabel" parent="."]
anchors_preset = -1
anchor_left = 0.293
anchor_top = 0.59
@@ -38,7 +38,10 @@ grow_vertical = 2
size_flags_horizontal = 4
size_flags_vertical = 4
bbcode_enabled = true
text = "[center][font s=60]DiscordRPC Test"
text = "[center][font s=60]DiscordUtil Test"
[node name="DiscordRPCDebug" type="Node" parent="."]
[node name="DiscordSocialSDKDebug" type="Node" parent="."]
script = ExtResource("6_ujijw")
[node name="DiscordConnector" type="DiscordConnector" parent="."]
process_mode = 4

View File

@@ -10,7 +10,7 @@ config_version=5
[application]
config/name="GDExtension DiscordRPC Test Project"
config/name="GDExtension DiscordUtil Test Project"
config/tags=PackedStringArray("vaporvee")
run/main_scene="res://main.tscn"
config/features=PackedStringArray("4.4")
@@ -22,7 +22,6 @@ config/icon="res://assets/Logo_V2.png"
[autoload]
PluginManager="*res://plugin_manager.gd"
DiscordRPCLoader="*res://addons/discord-rpc-gd/nodes/discord_autoload.gd"
[debug]
@@ -36,6 +35,7 @@ gdscript/warnings/unsafe_call_argument=1
[display]
window/size/resizable=false
display_server/driver.linuxbsd="wayland"
[dotnet]

13
src/definitions.h Normal file
View File

@@ -0,0 +1,13 @@
#define BIND_METHOD(class_name, method, ...) godot::ClassDB::bind_method(D_METHOD(#method, ##__VA_ARGS__), &class_name::method)
#define BIND_SET_GET(class_name, property_name, variant_type, ...) \
godot::ClassDB::bind_method(D_METHOD("get_" #property_name), &class_name::get_##property_name); \
godot::ClassDB::bind_method(D_METHOD("set_" #property_name, #variant_type), &class_name::set_##property_name); \
godot::ClassDB::add_property(class_name::get_class_static(), PropertyInfo(variant_type, #property_name, ##__VA_ARGS__), "set_" #property_name, "get_" #property_name)
#define BIND_SIGNAL(class_name, signal_name, ...) godot::ClassDB::add_signal(class_name::get_class_static(), MethodInfo(#signal_name, ##__VA_ARGS__))
// getter isn't mandatory for this project
#define SET_GET(class_name, variable, setter, ...) decltype(class_name::variable) class_name::get_##variable() { return variable; } void class_name::set_##variable(decltype(class_name::variable) value) { variable = value; setter; }
#define RESOLVE_TYPE(default_value) \
typename std::conditional<std::is_same<decltype(default_value), int>::value, uint64_t, decltype(default_value)>::type
#define H_SET_GET(property_name, default_value) private: RESOLVE_TYPE(default_value) property_name = default_value; public: RESOLVE_TYPE(default_value) get_##property_name(); void set_##property_name(RESOLVE_TYPE(default_value) value);

View File

@@ -0,0 +1,65 @@
#include "discord_connector.h"
DiscordConnector *DiscordConnector::singleton = nullptr;
void DiscordConnector::_bind_methods()
{
BIND_SET_GET(DiscordConnector, app_id, Variant::INT, godot::PROPERTY_HINT_RANGE, "-99999,99999,or_less,or_greater,hide_slider");
BIND_SET_GET(DiscordConnector, auto_connect, Variant::BOOL);
BIND_SET_GET(DiscordConnector, token_auto_manage, Variant::BOOL);
}
DiscordConnector::DiscordConnector()
{
singleton = this;
}
DiscordConnector::~DiscordConnector()
{
singleton = nullptr;
}
DiscordConnector *DiscordConnector::get_singleton()
{
return singleton;
}
void DiscordConnector::_ready()
{
client = std::make_shared<discordpp::Client>();
}
void DiscordConnector::_process(double delta)
{
if (Engine::get_singleton()->is_editor_hint() && !editor_process)
{
discordpp::RunCallbacks();
}
}
void DiscordConnector::set_app_id(uint64_t value)
{
app_id = value;
}
uint64_t DiscordConnector::get_app_id()
{
return app_id;
}
void DiscordConnector::set_token_auto_manage(bool value)
{
token_auto_manage = value;
}
bool DiscordConnector::get_token_auto_manage()
{
return token_auto_manage;
}
void DiscordConnector::set_auto_connect(bool value)
{
auto_connect = value;
}
bool DiscordConnector::get_auto_connect()
{
return auto_connect;
}

View File

@@ -0,0 +1,35 @@
#ifndef DISCORD_CONNECTOR_H
#define DISCORD_CONNECTOR_H
#include "discord_social_sdk.h"
using namespace godot;
class DiscordConnector : public DiscordSocialSDK
{
GDCLASS(DiscordConnector, DiscordSocialSDK);
static DiscordConnector *singleton;
protected:
static void _bind_methods();
public:
static DiscordConnector *
get_singleton();
bool editor_process = false;
std::shared_ptr<discordpp::Client> client;
H_SET_GET(app_id, 0)
H_SET_GET(token_auto_manage, true)
H_SET_GET(auto_connect, false)
DiscordConnector();
~DiscordConnector();
void _ready() override;
void _process(double delta) override;
};
#endif

View File

@@ -0,0 +1,19 @@
#include "discord_social_sdk.h"
DiscordSocialSDK *DiscordSocialSDK::singleton = nullptr;
void DiscordSocialSDK::_bind_methods()
{
}
DiscordSocialSDK::DiscordSocialSDK()
{
singleton = this;
}
DiscordSocialSDK::~DiscordSocialSDK()
{
singleton = nullptr;
}
DiscordSocialSDK *DiscordSocialSDK::get_singleton()
{
return singleton;
}

View File

@@ -0,0 +1,37 @@
#ifndef DISCORD_SOCIAL_SDK_H
#define DISCORD_SOCIAL_SDK_H
#include "discordpp.h"
#include "../definitions.h"
#include <stdio.h>
#include <godot_cpp/classes/node.hpp>
#include <godot_cpp/core/class_db.hpp>
#include <godot_cpp/classes/project_settings.hpp>
#include <godot_cpp/classes/engine.hpp>
#include <godot_cpp/classes/time.hpp>
#include <godot_cpp/classes/tree.hpp>
#include <godot_cpp/core/class_db.hpp>
#include <godot_cpp/variant/utility_functions.hpp>
#include <godot_cpp/classes/scene_tree.hpp>
using namespace godot;
class DiscordSocialSDK : public Node
{
GDCLASS(DiscordSocialSDK, Node);
static DiscordSocialSDK *singleton;
protected:
static void _bind_methods();
public:
static DiscordSocialSDK *
get_singleton();
DiscordSocialSDK();
~DiscordSocialSDK();
};
#endif

View File

@@ -1,7 +1,4 @@
#include "editor_presence.h"
#include <godot_cpp/core/class_db.hpp>
#include <godot_cpp/variant/utility_functions.hpp>
#include <godot_cpp/classes/scene_tree.hpp>
EditorPresence *EditorPresence::singleton = nullptr;

View File

@@ -1,20 +1,13 @@
#ifndef EDITOR_PRESENCE_H
#define EDITOR_PRESENCE_H
#include <stdio.h>
#include "discordpp.h"
#include <godot_cpp/classes/node.hpp>
#include <godot_cpp/core/class_db.hpp>
#include <godot_cpp/classes/project_settings.hpp>
#include <godot_cpp/classes/engine.hpp>
#include <godot_cpp/classes/time.hpp>
#include <godot_cpp/classes/tree.hpp>
#include "discord_social_sdk.h"
using namespace godot;
class EditorPresence : public Node
class EditorPresence : public DiscordSocialSDK
{
GDCLASS(EditorPresence, Node);
GDCLASS(EditorPresence, DiscordSocialSDK);
static EditorPresence *singleton;

View File

@@ -1,46 +1,39 @@
#include "register_types.h"
#include <gdextension_interface.h>
#include <godot_cpp/core/class_db.hpp>
#include <godot_cpp/core/defs.hpp>
#include <godot_cpp/classes/engine.hpp>
#include <godot_cpp/godot.hpp>
#include "discordpp.h"
#include "discordgodot.h"
#include "editor_presence.h"
using namespace godot;
static DiscordRPC *discordrpc;
static DiscordUtil *discordutil;
void initialize_discordrpc_module(ModuleInitializationLevel p_level)
void initialize_DiscordUtil_module(ModuleInitializationLevel p_level)
{
if (p_level == MODULE_INITIALIZATION_LEVEL_SCENE)
{
ClassDB::register_class<DiscordRPC>();
discordrpc = memnew(DiscordRPC);
Engine::get_singleton()->register_singleton("DiscordRPC", DiscordRPC::get_singleton());
ClassDB::register_abstract_class<DiscordSocialSDK>();
ClassDB::register_class<DiscordUtil>();
discordutil = memnew(DiscordUtil);
Engine::get_singleton()->register_singleton("DiscordUtil", DiscordUtil::get_singleton());
ClassDB::register_class<EditorPresence>();
ClassDB::register_class<DiscordConnector>();
}
}
void uninitialize_discordrpc_module(ModuleInitializationLevel p_level)
void uninitialize_DiscordUtil_module(ModuleInitializationLevel p_level)
{
if (p_level == MODULE_INITIALIZATION_LEVEL_SCENE)
{
Engine::get_singleton()->unregister_singleton("DiscordRPC");
memdelete(discordrpc);
Engine::get_singleton()->unregister_singleton("DiscordUtil");
memdelete(discordutil);
}
}
extern "C"
{
GDExtensionBool GDE_EXPORT discordrpcgd_library_init(GDExtensionInterfaceGetProcAddress p_get_proc_address, GDExtensionClassLibraryPtr p_library, GDExtensionInitialization *r_initialization)
GDExtensionBool GDE_EXPORT DiscordUtilgd_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_discordrpc_module);
init_obj.register_terminator(uninitialize_discordrpc_module);
init_obj.register_initializer(initialize_DiscordUtil_module);
init_obj.register_terminator(uninitialize_DiscordUtil_module);
init_obj.set_minimum_library_initialization_level(MODULE_INITIALIZATION_LEVEL_SCENE);
return init_obj.init();

View File

@@ -1,7 +1,20 @@
#ifndef REGISTER_TYPES_H
#define REGISTER_TYPES_H
void initialize_discordrpc_module();
void uninitialize_discordrpc_module();
#define DISCORDPP_IMPLEMENTATION // this is way too important to forget
void initialize_DiscordUtil_module();
void uninitialize_DiscordUtil_module();
#include <gdextension_interface.h>
#include <godot_cpp/core/class_db.hpp>
#include <godot_cpp/core/defs.hpp>
#include <godot_cpp/classes/engine.hpp>
#include <godot_cpp/godot.hpp>
#include "util.h"
#include "nodes/discord_social_sdk.h"
#include "nodes/editor_presence.h"
#include "nodes/discord_connector.h"
#endif // REGISTER_TYPES_H

View File

@@ -1,77 +1,59 @@
#define DISCORDPP_IMPLEMENTATION // this is way too important to forget
#include "discordpp.h"
#include "discordgodot.h"
#include <godot_cpp/core/class_db.hpp>
#include <godot_cpp/variant/utility_functions.hpp>
#include "util.h"
#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), &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(DiscordRPC::variable) DiscordRPC::get_##variable() { return variable; } \
void DiscordRPC::set_##variable(decltype(DiscordRPC::variable) value) \
{ \
variable = value; \
setter; \
}
DiscordUtil *DiscordUtil::singleton = nullptr;
DiscordRPC *DiscordRPC::singleton = nullptr;
void DiscordRPC::_bind_methods()
void DiscordUtil::_bind_methods()
{
BIND_SET_GET(app_id, Variant::INT);
BIND_SIGNAL(activity_join, PropertyInfo(Variant::STRING, "join_secret"));
BIND_SIGNAL(activity_spectate, PropertyInfo(Variant::STRING, "spectate_secret"));
BIND_SIGNAL(activity_join_request, PropertyInfo(Variant::DICTIONARY, "user_requesting"));
BIND_SIGNAL(updated_relationship, PropertyInfo(Variant::DICTIONARY, "relationship"));
BIND_SIGNAL(overlay_toggle, PropertyInfo(Variant::BOOL, "is_locked"));
BIND_SIGNAL(relationships_init);
BIND_METHOD(debug);
BIND_METHOD(run_callbacks);
BIND_METHOD(refresh);
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");
BIND_METHOD(accept_join_request, "user_id");
BIND_METHOD(send_invite, "user_id", "is_spectate", "message_content");
BIND_METHOD(accept_invite, "user_id");
BIND_METHOD(get_current_user);
BIND_METHOD(get_all_relationships);
BIND_METHOD(get_is_overlay_enabled);
BIND_METHOD(get_is_overlay_locked);
BIND_METHOD(open_invite_overlay, "is_spectate");
BIND_METHOD(open_server_invite_overlay, "invite_code");
BIND_METHOD(open_voice_settings);
BIND_METHOD(get_is_discord_working);
BIND_SET_GET(DiscordUtil, app_id, Variant::INT);
BIND_SIGNAL(DiscordUtil, activity_join, PropertyInfo(Variant::STRING, "join_secret"));
BIND_SIGNAL(DiscordUtil, activity_spectate, PropertyInfo(Variant::STRING, "spectate_secret"));
BIND_SIGNAL(DiscordUtil, activity_join_request, PropertyInfo(Variant::DICTIONARY, "user_requesting"));
BIND_SIGNAL(DiscordUtil, updated_relationship, PropertyInfo(Variant::DICTIONARY, "relationship"));
BIND_SIGNAL(DiscordUtil, overlay_toggle, PropertyInfo(Variant::BOOL, "is_locked"));
BIND_SIGNAL(DiscordUtil, relationships_init);
BIND_METHOD(DiscordUtil, debug);
BIND_METHOD(DiscordUtil, run_callbacks);
BIND_METHOD(DiscordUtil, refresh);
ClassDB::bind_method(D_METHOD("clear", "reset_values"), &DiscordUtil::clear, DEFVAL(false));
BIND_METHOD(DiscordUtil, unclear);
BIND_METHOD(DiscordUtil, register_command, "command");
BIND_METHOD(DiscordUtil, register_steam, "steam_id");
BIND_METHOD(DiscordUtil, accept_join_request, "user_id");
BIND_METHOD(DiscordUtil, send_invite, "user_id", "is_spectate", "message_content");
BIND_METHOD(DiscordUtil, accept_invite, "user_id");
BIND_METHOD(DiscordUtil, get_current_user);
BIND_METHOD(DiscordUtil, get_all_relationships);
BIND_METHOD(DiscordUtil, get_is_overlay_enabled);
BIND_METHOD(DiscordUtil, get_is_overlay_locked);
BIND_METHOD(DiscordUtil, open_invite_overlay, "is_spectate");
BIND_METHOD(DiscordUtil, open_server_invite_overlay, "invite_code");
BIND_METHOD(DiscordUtil, open_voice_settings);
BIND_METHOD(DiscordUtil, get_is_discord_working);
}
DiscordRPC::DiscordRPC()
DiscordUtil::DiscordUtil()
{
ERR_FAIL_COND(singleton != nullptr);
singleton = this;
}
DiscordRPC::~DiscordRPC()
DiscordUtil::~DiscordUtil()
{
app_id = 0;
ERR_FAIL_COND(singleton != this);
singleton = nullptr;
}
DiscordRPC *DiscordRPC::get_singleton()
DiscordUtil *DiscordUtil::get_singleton()
{
return singleton;
}
void DiscordRPC::run_callbacks()
void DiscordUtil::run_callbacks()
{
discordpp::RunCallbacks();
}
void DiscordRPC::debug()
void DiscordUtil::debug()
{
auto client = std::make_shared<discordpp::Client>();
@@ -149,7 +131,7 @@ void DiscordRPC::debug()
} });
}
void DiscordRPC::set_app_id(uint64_t value)
void DiscordUtil::set_app_id(uint64_t value)
{
app_id = value;
if (app_id > 0)
@@ -164,35 +146,35 @@ void DiscordRPC::set_app_id(uint64_t value)
core->UserManager().GetCurrentUser(&user); });
// signals
core->ActivityManager().OnActivityJoin.Connect([](const char *secret)
{ DiscordRPC::get_singleton()
{ DiscordUtil::get_singleton()
->emit_signal("activity_join", secret); });
core->ActivityManager().OnActivitySpectate.Connect([](const char *secret)
{ DiscordRPC::get_singleton()
{ DiscordUtil::get_singleton()
->emit_signal("activity_spectate", secret); });
core->ActivityManager().OnActivityJoinRequest.Connect([this](discordpp::User const &user)
{ DiscordRPC::get_singleton()
{ DiscordUtil::get_singleton()
->emit_signal("activity_join_request", user2dict(user)); });
core->OverlayManager().OnToggle.Connect([](bool is_locked)
{ DiscordRPC::get_singleton()
{ DiscordUtil::get_singleton()
->emit_signal("overlay_toggle", is_locked); });
core->RelationshipManager().OnRefresh.Connect([&]()
{ DiscordRPC::get_singleton()
{ DiscordUtil::get_singleton()
->emit_signal("relationships_init"); });
core->RelationshipManager().OnRelationshipUpdate.Connect([&](discordpp::Relationship const &relationship)
{ DiscordRPC::get_singleton()
{ DiscordUtil::get_singleton()
->emit_signal("updated_relationship", relationship2dict(relationship)); });
}
*/
}
}
uint64_t DiscordRPC::get_app_id()
uint64_t DiscordUtil::get_app_id()
{
if (app_id != 0)
return app_id;
return old_app_id;
}
void DiscordRPC::refresh()
void DiscordUtil::refresh()
{
if (get_is_discord_working())
{
@@ -205,7 +187,7 @@ void DiscordRPC::refresh()
UtilityFunctions::push_warning("Discord Activity couldn't be updated. It could be that Discord isn't running!");
}
void DiscordRPC::clear(bool reset_values = false)
void DiscordUtil::clear(bool reset_values = false)
{
if (get_is_discord_working())
{
@@ -221,7 +203,7 @@ void DiscordRPC::clear(bool reset_values = false)
}
}
void DiscordRPC::unclear()
void DiscordUtil::unclear()
{
if (old_app_id > 0)
{
@@ -233,7 +215,7 @@ void DiscordRPC::unclear()
UtilityFunctions::push_warning("Discord Activity couldn't be uncleared. Maybe it didn't get cleared before?");
}
bool DiscordRPC::get_is_overlay_enabled()
bool DiscordUtil::get_is_overlay_enabled()
{
bool ie;
if (get_is_discord_working())
@@ -243,7 +225,7 @@ bool DiscordRPC::get_is_overlay_enabled()
}
return ie;
}
bool DiscordRPC::get_is_overlay_locked()
bool DiscordUtil::get_is_overlay_locked()
{
bool il;
if (get_is_discord_working())
@@ -253,64 +235,64 @@ bool DiscordRPC::get_is_overlay_locked()
}
return il;
}
void DiscordRPC::set_is_overlay_locked(bool value)
void DiscordUtil::set_is_overlay_locked(bool value)
{
is_overlay_locked = value;
if (get_is_discord_working())
// core->OverlayManager().SetLocked(value, {});
return;
}
void DiscordRPC::open_invite_overlay(bool is_spectate)
void DiscordUtil::open_invite_overlay(bool is_spectate)
{
if (get_is_discord_working())
// core->OverlayManager().OpenActivityInvite(static_cast<discordpp::ActivityActionType>(is_spectate + 1), {});
return;
}
void DiscordRPC::open_server_invite_overlay(String invite_code)
void DiscordUtil::open_server_invite_overlay(String invite_code)
{
if (get_is_discord_working())
// core->OverlayManager().OpenGuildInvite(invite_code.utf8().get_data(), {});
return;
}
void DiscordRPC::open_voice_settings()
void DiscordUtil::open_voice_settings()
{
if (get_is_discord_working())
// core->OverlayManager().OpenVoiceSettings({});
return;
}
void DiscordRPC::accept_join_request(uint64_t user_id)
void DiscordUtil::accept_join_request(uint64_t user_id)
{
if (get_is_discord_working())
// core->ActivityManager().SendRequestReply(user_id, static_cast<discordpp::ActivityJoinRequestReply>(1), {});
return;
}
void DiscordRPC::send_invite(uint64_t user_id, bool is_spectate = false, String message_content = "")
void DiscordUtil::send_invite(uint64_t user_id, bool is_spectate = false, String message_content = "")
{
if (get_is_discord_working())
// core->ActivityManager().SendInvite(user_id, static_cast<discordpp::ActivityActionType>(is_spectate + 1), message_content.utf8().get_data(), {});
return;
}
void DiscordRPC::accept_invite(uint64_t user_id)
void DiscordUtil::accept_invite(uint64_t user_id)
{
if (get_is_discord_working())
// core->ActivityManager().AcceptInvite(user_id, {});
return;
}
void DiscordRPC::register_command(String value)
void DiscordUtil::register_command(String value)
{
if (get_is_discord_working())
// core->ActivityManager().RegisterCommand(value.utf8().get_data());
return;
}
void DiscordRPC::register_steam(int32_t value)
void DiscordUtil::register_steam(int32_t value)
{
if (get_is_discord_working())
// core->ActivityManager().RegisterSteam(value);
return;
}
Dictionary DiscordRPC::get_current_user()
Dictionary DiscordUtil::get_current_user()
{
Dictionary userdict;
if (get_is_discord_working())
@@ -322,7 +304,7 @@ Dictionary DiscordRPC::get_current_user()
return userdict;
}
Dictionary DiscordRPC::get_relationship(uint64_t user_id)
Dictionary DiscordUtil::get_relationship(uint64_t user_id)
{
Dictionary dict;
if (get_is_discord_working())
@@ -334,7 +316,7 @@ Dictionary DiscordRPC::get_relationship(uint64_t user_id)
return dict;
}
Array DiscordRPC::get_all_relationships()
Array DiscordUtil::get_all_relationships()
{
Array all_relationships;
/*core->RelationshipManager().Filter(
@@ -351,7 +333,7 @@ Array DiscordRPC::get_all_relationships()
return all_relationships;
}
Dictionary DiscordRPC::user2dict(discordpp::UserHandle user)
Dictionary DiscordUtil::user2dict(discordpp::UserHandle user)
{
Dictionary userdict;
/*userdict["avatar"] = user.GetAvatar(); // can be empty when user has no avatar
@@ -367,7 +349,7 @@ Dictionary DiscordRPC::user2dict(discordpp::UserHandle user)
return userdict;
}
Dictionary DiscordRPC::relationship2dict(discordpp::RelationshipHandle relationship)
Dictionary DiscordUtil::relationship2dict(discordpp::RelationshipHandle relationship)
{
Dictionary dict_relationship;
Dictionary presence;
@@ -439,7 +421,7 @@ Dictionary DiscordRPC::relationship2dict(discordpp::RelationshipHandle relations
return dict_relationship;
}
bool DiscordRPC::get_is_discord_working()
bool DiscordUtil::get_is_discord_working()
{
return app_id > 0; /*result.Successful() &&*/
}

View File

@@ -1,33 +1,31 @@
#ifndef DISCORDGODOT_H
#define DISCORDGODOT_H
#include <stdio.h>
#include "definitions.h"
#include "discordpp.h"
#include <stdio.h>
#include <godot_cpp/classes/object.hpp>
#include <godot_cpp/core/class_db.hpp>
#define H_SET_GET(variable_type, property_name) \
variable_type property_name; \
variable_type get_##property_name(); \
void set_##property_name(variable_type value);
#include <godot_cpp/core/class_db.hpp>
#include <godot_cpp/variant/utility_functions.hpp>
using namespace godot;
class DiscordRPC : public Object
class DiscordUtil : public Object
{
GDCLASS(DiscordRPC, Object);
GDCLASS(DiscordUtil, Object);
static DiscordRPC *singleton;
static DiscordUtil *singleton;
protected:
static void _bind_methods();
public:
static DiscordRPC *
static DiscordUtil *
get_singleton();
DiscordRPC();
~DiscordRPC();
DiscordUtil();
~DiscordUtil();
// INTERBNAL
uint64_t old_app_id;
@@ -37,7 +35,7 @@ public:
void set_app_id(uint64_t value);
uint64_t get_app_id();
uint64_t app_id = 0; // needs to be directly set to 0 or it will crash randomly
H_SET_GET(bool, is_overlay_locked)
H_SET_GET(is_overlay_locked, false)
void debug();
void run_callbacks();