implemented rich presences and better naming

This commit is contained in:
2025-03-27 15:22:43 +01:00
parent bd7a102d3d
commit 98a4b4783c
12 changed files with 209 additions and 217 deletions

View File

@@ -1,17 +1,16 @@
extends DiscordConnector extends DiscordConnector
func _on_user_connected(access_token: String, refresh_token: String, expires_in: int) -> void: @onready var discord_activity: DiscordActivity = $DiscordActivity
func _on_authenticated(access_token: String, refresh_token: String, expires_in: int) -> void:
print_debug("Access token: %s \nRefresh Token: %s \nExpires in: %s" % [access_token, refresh_token, expires_in]) print_debug("Access token: %s \nRefresh Token: %s \nExpires in: %s" % [access_token, refresh_token, expires_in])
func _on_user_connection_failed(error: String) -> void: func _on_authentication_failed(error: String) -> void:
push_error("User connection failed! Error: " + error) push_error("Auth failed! Error: " + error)
func _on_user_update_failed(error: String) -> void:
push_error("User update failed! Error: " + error)
func _on_connection_ready() -> void:
print_debug("CONNECTION READY")
$DiscordLobby.create_or_join_lobby("beanis")
func _on_connection_error(error: String) -> void: func _on_connection_error(error: String) -> void:
push_error(error) push_error(error)
func _on_connection_ready() -> void:
print_debug("CONNECTION READY")
discord_activity.update_rich_presence()

View File

@@ -1,9 +1,17 @@
[gd_scene load_steps=4 format=3 uid="uid://dyc3kseph4el7"] [gd_scene load_steps=5 format=3 uid="uid://dyc3kseph4el7"]
[ext_resource type="Texture2D" uid="uid://b3qm246m7pnsx" path="res://assets/Logo_V2.png" id="2_gd222"] [ext_resource type="Texture2D" uid="uid://b3qm246m7pnsx" path="res://assets/Logo_V2.png" id="2_gd222"]
[ext_resource type="Script" uid="uid://kmubk5a6i385" path="res://discord_connector.gd" id="3_h2yge"] [ext_resource type="Script" uid="uid://kmubk5a6i385" path="res://discord_connector.gd" id="3_h2yge"]
[ext_resource type="Script" uid="uid://46tue7u6crd6" path="res://addons/discord-rpc-gd/nodes/debug.gd" id="6_ujijw"] [ext_resource type="Script" uid="uid://46tue7u6crd6" path="res://addons/discord-rpc-gd/nodes/debug.gd" id="6_ujijw"]
[sub_resource type="RichPresence" id="RichPresence_h2yge"]
state = "Inside a Node"
details = "Godot -> Discord Social SDK"
large_image = &"example_game"
large_text = "Example"
small_image = &"boss"
small_text = "Fighting the boss D:"
[node name="Node" type="Node"] [node name="Node" type="Node"]
[node name="ColorRect" type="ColorRect" parent="."] [node name="ColorRect" type="ColorRect" parent="."]
@@ -45,10 +53,10 @@ script = ExtResource("6_ujijw")
[node name="DiscordConnector" type="DiscordConnector" parent="."] [node name="DiscordConnector" type="DiscordConnector" parent="."]
app_id = 1099618430065324082 app_id = 1099618430065324082
auto_connect = true auto_connect = true
auto_token_manage = true
script = ExtResource("3_h2yge") script = ExtResource("3_h2yge")
[node name="DiscordActivity" type="DiscordActivity" parent="DiscordConnector"] [node name="DiscordActivity" type="DiscordActivity" parent="DiscordConnector"]
rich_presence = SubResource("RichPresence_h2yge")
root_connector = NodePath("..") root_connector = NodePath("..")
[node name="DiscordLobby" type="DiscordLobby" parent="DiscordConnector"] [node name="DiscordLobby" type="DiscordLobby" parent="DiscordConnector"]
@@ -58,8 +66,7 @@ root_connector = NodePath("..")
position = Vector2(789, 330.5) position = Vector2(789, 330.5)
scale = Vector2(0.408203, 0.408203) scale = Vector2(0.408203, 0.408203)
[connection signal="authenticated" from="DiscordConnector" to="DiscordConnector" method="_on_authenticated"]
[connection signal="authentication_failed" from="DiscordConnector" to="DiscordConnector" method="_on_authentication_failed"]
[connection signal="connection_error" from="DiscordConnector" to="DiscordConnector" method="_on_connection_error"] [connection signal="connection_error" from="DiscordConnector" to="DiscordConnector" method="_on_connection_error"]
[connection signal="connection_ready" from="DiscordConnector" to="DiscordConnector" method="_on_connection_ready"] [connection signal="connection_ready" from="DiscordConnector" to="DiscordConnector" method="_on_connection_ready"]
[connection signal="user_connected" from="DiscordConnector" to="DiscordConnector" method="_on_user_connected"]
[connection signal="user_connection_failed" from="DiscordConnector" to="DiscordConnector" method="_on_user_connection_failed"]
[connection signal="user_update_failed" from="DiscordConnector" to="DiscordConnector" method="_on_user_update_failed"]

View File

@@ -2,10 +2,8 @@
void DiscordActivity::_bind_methods() void DiscordActivity::_bind_methods()
{ {
BIND_SET_GET(DiscordActivity, rich_presence, Variant::OBJECT, PROPERTY_HINT_RESOURCE_TYPE, "RichPresence");
ClassDB::bind_method(D_METHOD("get_activities"), &DiscordActivity::get_activities); BIND_METHOD(DiscordActivity, update_rich_presence);
ClassDB::bind_method(D_METHOD("set_activities", "value"), &DiscordActivity::set_activities);
ADD_PROPERTY(PropertyInfo(Variant::ARRAY, "activities", PROPERTY_HINT_ARRAY_TYPE, MAKE_RESOURCE_TYPE_HINT("ActivityResource")), "set_activities", "get_activities");
} }
DiscordActivity::DiscordActivity() DiscordActivity::DiscordActivity()
{ {
@@ -14,12 +12,29 @@ DiscordActivity::~DiscordActivity()
{ {
} }
TypedArray<ActivityResource> DiscordActivity::get_activities() Ref<RichPresence> DiscordActivity::get_rich_presence()
{ {
return activities; return rich_presence;
} }
void DiscordActivity::set_activities(TypedArray<ActivityResource> value) void DiscordActivity::set_rich_presence(Ref<RichPresence> value)
{ {
activities = value; rich_presence = value;
}
void DiscordActivity::update_rich_presence()
{
if(rich_presence.is_valid()){
discordpp::Activity activity;
activity.SetState(rich_presence->get_state().utf8().get_data());
activity.SetDetails(rich_presence->get_details().utf8().get_data());
discordpp::ActivityAssets assets;
assets.SetSmallImage(String(rich_presence->get_small_image()).utf8().get_data());
assets.SetSmallText(rich_presence->get_small_text().utf8().get_data());
assets.SetLargeImage(String(rich_presence->get_large_image()).utf8().get_data());
assets.SetLargeText(rich_presence->get_large_text().utf8().get_data());
activity.SetAssets(assets);
connector->client->UpdateRichPresence(activity, [](discordpp::ClientResult result){});
}
} }

View File

@@ -2,7 +2,7 @@
#define DISCORD_ACTIVITY_H #define DISCORD_ACTIVITY_H
#include "discord_connected.h" #include "discord_connected.h"
#include "../resources/activity.h" #include "../resources/rich_presence.h"
using namespace godot; using namespace godot;
@@ -14,9 +14,11 @@ protected:
static void _bind_methods(); static void _bind_methods();
public: public:
TypedArray<ActivityResource> activities; Ref<RichPresence> rich_presence;
TypedArray<ActivityResource> get_activities(); Ref<RichPresence> get_rich_presence();
void set_activities(TypedArray<ActivityResource> value); void set_rich_presence(Ref<RichPresence> value);
void update_rich_presence();
DiscordActivity(); DiscordActivity();
~DiscordActivity(); ~DiscordActivity();

View File

@@ -7,16 +7,15 @@ void DiscordConnector::_bind_methods()
BIND_SET_GET(DiscordConnector, auto_connect, Variant::BOOL); BIND_SET_GET(DiscordConnector, auto_connect, Variant::BOOL);
BIND_SET_GET(DiscordConnector, auto_token_manage, Variant::BOOL); BIND_SET_GET(DiscordConnector, auto_token_manage, Variant::BOOL);
BIND_SET_GET(DiscordConnector, auto_encryption_key, Variant::STRING, godot::PROPERTY_HINT_NONE, "", godot::PROPERTY_USAGE_NO_EDITOR); BIND_SET_GET(DiscordConnector, auto_encryption_key, Variant::STRING, godot::PROPERTY_HINT_NONE, "", godot::PROPERTY_USAGE_NO_EDITOR);
BIND_METHOD(DiscordConnector, connect_user); BIND_METHOD(DiscordConnector, auth);
BIND_METHOD(DiscordConnector, update_user_token, "access_token"); BIND_METHOD(DiscordConnector, token_connect, "access_token");
BIND_METHOD(DiscordConnector, refresh_user_token, "current_refresh_token"); BIND_METHOD(DiscordConnector, token_refresh, "current_refresh_token");
BIND_SIGNAL(user_connected, PropertyInfo(Variant::STRING, "access_token"), PropertyInfo(Variant::STRING, "refresh_token"), PropertyInfo(Variant::INT, "expires_in")); BIND_SIGNAL(authenticated, PropertyInfo(Variant::STRING, "access_token"), PropertyInfo(Variant::STRING, "refresh_token"), PropertyInfo(Variant::INT, "expires_in"));
BIND_SIGNAL(user_connection_failed, PropertyInfo(Variant::STRING, "error")); BIND_SIGNAL(authentication_failed, PropertyInfo(Variant::STRING, "error"));
BIND_SIGNAL(connection_ready); BIND_SIGNAL(connection_ready);
BIND_SIGNAL(connection_error, PropertyInfo(Variant::STRING, "error")); BIND_SIGNAL(connection_error, PropertyInfo(Variant::STRING, "error"));
BIND_SIGNAL(user_update_failed, PropertyInfo(Variant::STRING, "error")); BIND_SIGNAL(token_refreshed, PropertyInfo(Variant::STRING, "access_token"), PropertyInfo(Variant::STRING, "refresh_token"), PropertyInfo(Variant::INT, "expires_in"));
BIND_SIGNAL(user_token_refreshed, PropertyInfo(Variant::STRING, "access_token"), PropertyInfo(Variant::STRING, "refresh_token"), PropertyInfo(Variant::INT, "expires_in")); BIND_SIGNAL(token_refresh_failed, PropertyInfo(Variant::STRING, "error"));
BIND_SIGNAL(user_token_refresh_failed, PropertyInfo(Variant::STRING, "error"));
} }
DiscordConnector::DiscordConnector() DiscordConnector::DiscordConnector()
@@ -59,14 +58,14 @@ void DiscordConnector::_ready()
access_token = config->get_value("tokens", "access_token"); access_token = config->get_value("tokens", "access_token");
refresh_token = config->get_value("tokens", "refresh_token"); refresh_token = config->get_value("tokens", "refresh_token");
expires_in = config->get_value("tokens", "expires_in"); expires_in = config->get_value("tokens", "expires_in");
update_user_token(access_token); token_connect(access_token);
} }
else else
{ {
DiscordUtil::get_singleton()->delete_tokens(); DiscordUtil::get_singleton()->delete_tokens();
if (auto_connect) if (auto_connect)
{ {
connect_user(); auth();
} }
} }
} }
@@ -74,7 +73,7 @@ void DiscordConnector::_ready()
{ {
if (auto_connect) if (auto_connect)
{ {
connect_user(); auth();
} }
} }
} }
@@ -127,7 +126,7 @@ String DiscordConnector::get_auto_encryption_key()
return auto_encryption_key; return auto_encryption_key;
} }
void DiscordConnector::connect_user() void DiscordConnector::auth()
{ {
auto codeVerifier = client->CreateAuthorizationCodeVerifier(); auto codeVerifier = client->CreateAuthorizationCodeVerifier();
@@ -140,7 +139,7 @@ void DiscordConnector::connect_user()
client->Authorize(args, [this, codeVerifier](auto result, auto code, auto redirectUri) client->Authorize(args, [this, codeVerifier](auto result, auto code, auto redirectUri)
{ {
if (!result.Successful()) { if (!result.Successful()) {
emit_signal("user_connection_failed", result.Error().c_str()); emit_signal("authentication_failed", result.Error().c_str());
return; return;
} else { } else {
client->GetToken(app_id, code, codeVerifier.Verifier(), redirectUri, client->GetToken(app_id, code, codeVerifier.Verifier(), redirectUri,
@@ -156,40 +155,40 @@ void DiscordConnector::connect_user()
DiscordUtil::get_singleton()->save_tokens(accessToken.c_str(), refreshToken.c_str(), expiresIn, auto_encryption_key); DiscordUtil::get_singleton()->save_tokens(accessToken.c_str(), refreshToken.c_str(), expiresIn, auto_encryption_key);
} }
} else { } else {
emit_signal("user_connection_failed", result.Error().c_str()); emit_signal("authenticated", result.Error().c_str());
return; return;
} }
update_user_token(accessToken.c_str()); token_connect(accessToken.c_str());
}); });
} }); } });
} }
void DiscordConnector::update_user_token(String access_token) void DiscordConnector::token_connect(String access_token)
{ {
client->UpdateToken(discordpp::AuthorizationTokenType::Bearer, access_token.utf8().get_data(), [this](discordpp::ClientResult result) client->UpdateToken(discordpp::AuthorizationTokenType::Bearer, access_token.utf8().get_data(), [this](discordpp::ClientResult result)
{ {
if(result.Successful()) { if(result.Successful()) {
client->Connect(); client->Connect();
} else { } else {
emit_signal("user_update_failed", result.Error().c_str()); emit_signal("connection_error", result.Error().c_str());
} }); } });
} }
void DiscordConnector::refresh_user_token(String current_refresh_token) void DiscordConnector::token_refresh(String current_refresh_token)
{ {
client->RefreshToken(std::stoull(refresh_token.utf8().get_data()), refresh_token.utf8().get_data(), [this, current_refresh_token](discordpp::ClientResult result, std::string accessToken, std::string refreshToken, discordpp::AuthorizationTokenType tokenType, int32_t expiresIn, std::string scopes) client->RefreshToken(std::stoull(refresh_token.utf8().get_data()), refresh_token.utf8().get_data(), [this, current_refresh_token](discordpp::ClientResult result, std::string accessToken, std::string refreshToken, discordpp::AuthorizationTokenType tokenType, int32_t expiresIn, std::string scopes)
{ {
if (result.Successful()) if (result.Successful())
{ {
emit_signal("user_token_refreshed", accessToken.c_str(), refreshToken.c_str(), expiresIn); emit_signal("token_refreshed", accessToken.c_str(), refreshToken.c_str(), expiresIn);
if (auto_token_manage) if (auto_token_manage)
{ {
DiscordUtil::get_singleton()->save_tokens(accessToken.c_str(), refreshToken.c_str(), expiresIn, auto_encryption_key); DiscordUtil::get_singleton()->save_tokens(accessToken.c_str(), refreshToken.c_str(), expiresIn, auto_encryption_key);
update_user_token(accessToken.c_str()); token_connect(accessToken.c_str());
} }
} }
else else
{ {
emit_signal("user_token_refresh_failed", result.Error().c_str()); emit_signal("token_refresh_failed", result.Error().c_str());
} }); } });
} }

View File

@@ -20,16 +20,16 @@ public:
H_SET_GET(app_id, 0) H_SET_GET(app_id, 0)
H_SET_GET(auto_encryption_key, "") H_SET_GET(auto_encryption_key, "")
H_SET_GET(auto_token_manage, false) H_SET_GET(auto_token_manage, true)
H_SET_GET(auto_connect, false) H_SET_GET(auto_connect, false)
String access_token; String access_token;
String refresh_token; String refresh_token;
int64_t expires_in; int64_t expires_in;
void connect_user(); void auth();
void update_user_token(String access_token); void token_connect(String access_token);
void refresh_user_token(String refresh_token); void token_refresh(String refresh_token);
void refresh_auto_encryption_key(); void refresh_auto_encryption_key();

View File

@@ -18,7 +18,7 @@ void initialize_DiscordUtil_module(ModuleInitializationLevel p_level)
ClassDB::register_class<DiscordLobby>(); ClassDB::register_class<DiscordLobby>();
ClassDB::register_class<DiscordLinkedChannel>(); ClassDB::register_class<DiscordLinkedChannel>();
ClassDB::register_class<DiscordActivity>(); ClassDB::register_class<DiscordActivity>();
ClassDB::register_class<ActivityResource>(); ClassDB::register_class<RichPresence>();
} }
} }

View File

@@ -20,6 +20,6 @@ void uninitialize_DiscordUtil_module();
#include "nodes/discord_lobby.h" #include "nodes/discord_lobby.h"
#include "nodes/discord_linked_channel.h" #include "nodes/discord_linked_channel.h"
#include "nodes/discord_activity.h" #include "nodes/discord_activity.h"
#include "resources/activity.h" #include "resources/rich_presence.h"
#endif // REGISTER_TYPES_H #endif // REGISTER_TYPES_H

View File

@@ -1,116 +0,0 @@
#include "activity.h"
void ActivityResource::_bind_methods()
{
BIND_SET_GET(ActivityResource, type, Variant::INT, PROPERTY_HINT_ENUM, "Playing,Streaming,Listening,Watching,Custom Status,Competing,Hang Status");
BIND_SET_GET(ActivityResource, state, Variant::STRING);
BIND_SET_GET(ActivityResource, details, Variant::STRING);
BIND_SET_GET(ActivityResource, large_image, Variant::STRING);
BIND_SET_GET(ActivityResource, large_text, Variant::STRING);
BIND_SET_GET(ActivityResource, small_image, Variant::STRING);
BIND_SET_GET(ActivityResource, small_text, Variant::STRING);
BIND_SET_GET(ActivityResource, timestamps_start, Variant::INT);
BIND_SET_GET(ActivityResource, timestamps_end, Variant::INT);
BIND_ENUM_CONSTANT(TYPE_PLAYING);
BIND_ENUM_CONSTANT(TYPE_STREAMING);
BIND_ENUM_CONSTANT(TYPE_LISTENING);
BIND_ENUM_CONSTANT(TYPE_WATCHING);
BIND_ENUM_CONSTANT(TYPE_CUSTOM_STATUS);
BIND_ENUM_CONSTANT(TYPE_COMPETING);
BIND_ENUM_CONSTANT(TYPE_HANG_STATUS);
}
ActivityResource::ActivityResource()
{
}
void ActivityResource::set_type(ActivityType p_type)
{
type = p_type;
}
ActivityResource::ActivityType ActivityResource::get_type()
{
return type;
}
void ActivityResource::set_state(String p_state)
{
state = p_state;
}
String ActivityResource::get_state()
{
return state;
}
void ActivityResource::set_details(String value)
{
details = value;
}
String ActivityResource::get_details()
{
return details;
}
void ActivityResource::set_large_image(String value)
{
large_image = value;
}
String ActivityResource::get_large_image()
{
return large_image;
}
void ActivityResource::set_large_text(String value)
{
large_text = value;
}
String ActivityResource::get_large_text()
{
return large_text;
}
void ActivityResource::set_small_image(String value)
{
small_image = value;
}
String ActivityResource::get_small_image()
{
return small_image;
}
void ActivityResource::set_small_text(String value)
{
small_text = value;
}
String ActivityResource::get_small_text()
{
return small_text;
}
void ActivityResource::set_timestamps_start(int64_t value)
{
timestamps_start = value;
}
int64_t ActivityResource::get_timestamps_start()
{
return timestamps_start;
}
void ActivityResource::set_timestamps_end(int64_t value)
{
timestamps_end = value;
}
int64_t ActivityResource::get_timestamps_end()
{
return timestamps_end;
}

View File

@@ -1,47 +0,0 @@
#ifndef ACTIVITY_H
#define ACTIVITY_H
#include <godot_cpp/core/class_db.hpp>
#include <godot_cpp/core/defs.hpp>
#include <godot_cpp/godot.hpp>
#include <godot_cpp/classes/resource.hpp>
#include "../util.h"
using namespace godot;
class ActivityResource : public Resource {
GDCLASS(ActivityResource, Resource);
protected:
static void _bind_methods();
public:
enum ActivityType {
TYPE_PLAYING = 0,
TYPE_STREAMING = 1,
TYPE_LISTENING = 2,
TYPE_WATCHING = 3,
TYPE_CUSTOM_STATUS = 4,
TYPE_COMPETING = 5,
TYPE_HANG_STATUS = 6,
};
ActivityType type = TYPE_PLAYING;
ActivityType get_type();
void set_type(ActivityType p_type);
H_SET_GET(state, "")
H_SET_GET(details, "")
H_SET_GET(large_image, "")
H_SET_GET(large_text, "")
H_SET_GET(small_image, "")
H_SET_GET(small_text, "")
H_SET_GET(timestamps_start, 0)
H_SET_GET(timestamps_end, 0)
ActivityResource();
};
VARIANT_ENUM_CAST(ActivityResource::ActivityType);
#endif

View File

@@ -0,0 +1,97 @@
#include "rich_presence.h"
void RichPresence::_bind_methods()
{
BIND_SET_GET(RichPresence, state, Variant::STRING);
BIND_SET_GET(RichPresence, details, Variant::STRING);
ADD_GROUP("Large Image", "large_");
BIND_SET_GET(RichPresence, large_image, Variant::STRING_NAME);
BIND_SET_GET(RichPresence, large_text, Variant::STRING);
ADD_GROUP("Small Image", "small_");
BIND_SET_GET(RichPresence, small_image, Variant::STRING_NAME);
BIND_SET_GET(RichPresence, small_text, Variant::STRING);
}
RichPresence::RichPresence()
{
}
void RichPresence::set_state(String p_state)
{
state = p_state;
}
String RichPresence::get_state()
{
return state;
}
void RichPresence::set_details(String value)
{
details = value;
}
String RichPresence::get_details()
{
return details;
}
void RichPresence::set_large_image(StringName value)
{
large_image = value;
}
StringName RichPresence::get_large_image()
{
return large_image;
}
void RichPresence::set_large_text(String value)
{
large_text = value;
}
String RichPresence::get_large_text()
{
return large_text;
}
void RichPresence::set_small_image(StringName value)
{
small_image = value;
}
StringName RichPresence::get_small_image()
{
return small_image;
}
void RichPresence::set_small_text(String value)
{
small_text = value;
}
String RichPresence::get_small_text()
{
return small_text;
}
void RichPresence::set_timestamps_start(int64_t value)
{
timestamps_start = value;
}
int64_t RichPresence::get_timestamps_start()
{
return timestamps_start;
}
void RichPresence::set_timestamps_end(int64_t value)
{
timestamps_end = value;
}
int64_t RichPresence::get_timestamps_end()
{
return timestamps_end;
}

View File

@@ -0,0 +1,36 @@
#ifndef RICH_PRESENCE_H
#define RICH_PRESENCE_H
#include <godot_cpp/core/class_db.hpp>
#include <godot_cpp/core/defs.hpp>
#include <godot_cpp/godot.hpp>
#include <godot_cpp/classes/resource.hpp>
#include "../util.h"
using namespace godot;
class RichPresence : public Resource {
GDCLASS(RichPresence, Resource);
protected:
static void _bind_methods();
public:
H_SET_GET(state, "")
H_SET_GET(details, "")
StringName large_image;
StringName get_large_image();
void set_large_image(StringName value);
H_SET_GET(large_text, "")
StringName small_image;
StringName get_small_image();
void set_small_image(StringName value);
H_SET_GET(small_text, "")
H_SET_GET(timestamps_start, 0)
H_SET_GET(timestamps_end, 0)
RichPresence();
};
#endif