From 91d592c484eac7c4e79cdc0d2cc79f7eeac6d83b Mon Sep 17 00:00:00 2001 From: vaporvee Date: Mon, 24 Mar 2025 17:45:00 +0100 Subject: [PATCH] added option to manage token automatically --- .../addons/discord-rpc-gd/nodes/Debug.tscn | 3 - project/main.tscn | 3 +- src/definitions.h | 5 +- src/nodes/discord_connector.cpp | 100 +++++++++++++++--- src/nodes/discord_connector.h | 11 ++ src/util.cpp | 42 +++++++- src/util.h | 6 ++ 7 files changed, 147 insertions(+), 23 deletions(-) diff --git a/project/addons/discord-rpc-gd/nodes/Debug.tscn b/project/addons/discord-rpc-gd/nodes/Debug.tscn index b9b06a0..da83016 100644 --- a/project/addons/discord-rpc-gd/nodes/Debug.tscn +++ b/project/addons/discord-rpc-gd/nodes/Debug.tscn @@ -10,9 +10,6 @@ script/source = "extends Node @onready var animation_player: AnimationPlayer = $Panel/TextureRect/AnimationPlayer -func _ready(): - DiscordUtil.connect(\"activity_join_request\",_on_activity_join_request) - func _process(_delta) -> void: if(false): $Panel/TextureRect.self_modulate = Color(\"#3eff8d\") diff --git a/project/main.tscn b/project/main.tscn index 4bb9000..f41a695 100644 --- a/project/main.tscn +++ b/project/main.tscn @@ -43,8 +43,9 @@ text = "[center][font s=60]DiscordUtil Test" script = ExtResource("6_ujijw") [node name="DiscordConnector" type="DiscordConnector" parent="."] -app_id = 1099618430065324082 auto_connect = true +app_id = 1099618430065324082 +encryption_key = "H8jOL;.+F9B7&/jLb:Yr_,V'He/nRQw.wII8GE1$l_P,&YG)Yc" script = ExtResource("3_h2yge") [connection signal="user_connected" from="DiscordConnector" to="DiscordConnector" method="_on_user_connected"] diff --git a/src/definitions.h b/src/definitions.h index b93bf34..85d1edc 100644 --- a/src/definitions.h +++ b/src/definitions.h @@ -8,6 +8,9 @@ #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::value, int64_t, decltype(default_value)>::type + typename std::conditional::value, godot::String, \ + typename std::conditional::value, bool, \ + typename std::conditional::value, int64_t, \ + decltype(default_value)>::type>::type>::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); \ No newline at end of file diff --git a/src/nodes/discord_connector.cpp b/src/nodes/discord_connector.cpp index 78dd6ec..dd677bd 100644 --- a/src/nodes/discord_connector.cpp +++ b/src/nodes/discord_connector.cpp @@ -4,10 +4,15 @@ DiscordConnector *DiscordConnector::singleton = nullptr; void DiscordConnector::_bind_methods() { - BIND_SET_GET(DiscordConnector, app_id, Variant::STRING, godot::PROPERTY_HINT_RANGE, "-99999,99999,or_less,or_greater,hide_slider"); BIND_SET_GET(DiscordConnector, auto_connect, Variant::BOOL); + BIND_SET_GET(DiscordConnector, app_id, Variant::STRING, godot::PROPERTY_HINT_RANGE, "-99999,99999,or_less,or_greater,hide_slider"); + BIND_SET_GET(DiscordConnector, encryption_key, Variant::STRING, godot::PROPERTY_HINT_PASSWORD); BIND_SET_GET(DiscordConnector, token_auto_manage, Variant::BOOL); - BIND_METHOD(DiscordConnector, connect); + BIND_METHOD(DiscordConnector, connect_user); + BIND_METHOD(DiscordConnector, update_user_token); + BIND_METHOD(DiscordConnector, get_access_token); + BIND_METHOD(DiscordConnector, get_refresh_token); + BIND_METHOD(DiscordConnector, get_expires_in); BIND_SIGNAL(user_connected, PropertyInfo(Variant::STRING, "access_token"), PropertyInfo(Variant::STRING, "refresh_token"), PropertyInfo(Variant::INT, "expires_in")); } DiscordConnector::DiscordConnector() @@ -26,10 +31,32 @@ DiscordConnector *DiscordConnector::get_singleton() void DiscordConnector::_ready() { client = std::make_shared(); - if (!Engine::get_singleton()->is_editor_hint() && !editor_process) + if (encryption_key == "") { - if (auto_connect) - connect_user(); + if (!Engine::get_singleton()->is_editor_hint() && !editor_process) + { + if (auto_connect) + connect_user(); + } + } + else if (token_auto_manage) + { + ConfigFile config = DiscordUtil::get_singleton()->get_tokens(encryption_key); + if (config.has_section_key("tokens", "access_token") && config.has_section_key("tokens", "refresh_token") && config.has_section_key("tokens", "expires_in")) + { + access_token = config.get_value("tokens", "access_token"); + refresh_token = config.get_value("tokens", "refresh_token"); + expires_in = config.get_value("tokens", "expires_in"); + update_user_token(access_token); + } + else + { + if (!Engine::get_singleton()->is_editor_hint() && !editor_process) + { + if (auto_connect) + connect_user(); + } + } } } @@ -39,6 +66,21 @@ void DiscordConnector::_process(double delta) { discordpp::RunCallbacks(); } + if (encryption_key == "") + { + DiscordUtil::get_singleton()->delete_tokens(); + encryption_key = DiscordUtil::get_singleton()->generate_encryption_key(); + } +} + +void DiscordConnector::set_auto_connect(bool value) +{ + auto_connect = value; +} + +bool DiscordConnector::get_auto_connect() +{ + return auto_connect; } void DiscordConnector::set_app_id(int64_t value) @@ -61,14 +103,14 @@ bool DiscordConnector::get_token_auto_manage() return token_auto_manage; } -void DiscordConnector::set_auto_connect(bool value) +void DiscordConnector::set_encryption_key(String value) { - auto_connect = value; + encryption_key = value; } -bool DiscordConnector::get_auto_connect() +String DiscordConnector::get_encryption_key() { - return auto_connect; + return encryption_key; } void DiscordConnector::connect_user() @@ -95,18 +137,42 @@ void DiscordConnector::connect_user() int32_t expiresIn, std::string scope) { if (result.Successful()) { - DiscordConnector::get_singleton()->emit_signal("user_connected", accessToken.c_str(), refreshToken.c_str(), expiresIn); + emit_signal("user_connected", accessToken.c_str(), refreshToken.c_str(), expiresIn); + if (token_auto_manage) + { + DiscordUtil::get_singleton()->save_tokens(accessToken.c_str(), refreshToken.c_str(), expiresIn, encryption_key); + } } else { UtilityFunctions::push_error("Access token error: " + String(result.Error().c_str())); return; } - client->UpdateToken(discordpp::AuthorizationTokenType::Bearer, accessToken, [this](discordpp::ClientResult result) { - if(result.Successful()) { - client->Connect(); - } else { - UtilityFunctions::push_error("Token update error: " + String(result.Error().c_str())); - } - }); + update_user_token(accessToken.c_str()); }); } }); +} + +void DiscordConnector::update_user_token(String access_token) +{ + client->UpdateToken(discordpp::AuthorizationTokenType::Bearer, access_token.utf8().get_data(), [this](discordpp::ClientResult result) + { + if(result.Successful()) { + client->Connect(); + } else { + UtilityFunctions::push_error("Token update error: " + String(result.Error().c_str())); + } }); +} + +String DiscordConnector::get_access_token() +{ + return access_token; +} + +String DiscordConnector::get_refresh_token() +{ + return refresh_token; +} + +int64_t DiscordConnector::get_expires_in() +{ + return expires_in; } \ No newline at end of file diff --git a/src/nodes/discord_connector.h b/src/nodes/discord_connector.h index d29875c..8d0dd38 100644 --- a/src/nodes/discord_connector.h +++ b/src/nodes/discord_connector.h @@ -2,6 +2,7 @@ #define DISCORD_CONNECTOR_H #include "discord_social_sdk.h" +#include "../util.h" using namespace godot; @@ -23,10 +24,20 @@ public: std::shared_ptr client; H_SET_GET(app_id, 0) + H_SET_GET(encryption_key, "") H_SET_GET(token_auto_manage, true) H_SET_GET(auto_connect, false) + String access_token; + String refresh_token; + int64_t expires_in; + String get_access_token(); + String get_refresh_token(); + int64_t get_expires_in(); + void connect_user(); + void update_user_token(String access_token); + String refresh_user_token(String refresh_token); DiscordConnector(); ~DiscordConnector(); diff --git a/src/util.cpp b/src/util.cpp index 7d75283..0d374e2 100644 --- a/src/util.cpp +++ b/src/util.cpp @@ -6,6 +6,8 @@ void DiscordUtil::_bind_methods() { BIND_METHOD(DiscordUtil, debug); BIND_METHOD(DiscordUtil, run_callbacks); + BIND_METHOD(DiscordUtil, save_tokens, "access_token", "refresh_token", "expires_in", "encryption_key"); + BIND_METHOD(DiscordUtil, generate_encryption_key); } DiscordUtil::DiscordUtil() @@ -79,7 +81,7 @@ void DiscordUtil::debug() args.SetCodeChallenge(codeVerifier.Challenge()); // Begin authentication process // TODO: option to open browser - client->Authorize(args, [client, codeVerifier](auto result, auto code, auto redirectUri) + client->Authorize(args, [client, codeVerifier](auto result, auto code, auto redirectUri) { if (!result.Successful()) { UtilityFunctions::push_error("Authentication Error: " + String(result.Error().c_str())); @@ -193,4 +195,42 @@ Dictionary DiscordUtil::relationship2dict(discordpp::RelationshipHandle relation dict_relationship["presence"] = presence; dict_relationship.make_read_only();*/ return dict_relationship; +} + +String DiscordUtil::generate_encryption_key() +{ + const char *charset = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!\"$%&/()=?*+#-.,;:_'"; + String key; + for (int i = 0; i < 50; i++) + { + key += charset[rand() % strlen(charset)]; + } + return key; +} + +void DiscordUtil::save_tokens(String access_token, String refresh_token, int64_t expires_in, String encryption_key) +{ + ConfigFile config; + config.set_value("tokens", "access_token", access_token); + config.set_value("tokens", "refresh_token", refresh_token); + config.set_value("tokens", "expires_in", expires_in); + config.save_encrypted_pass("user://discord_data.binary", encryption_key); +} + +void DiscordUtil::delete_tokens() +{ + ConfigFile config; + config.save("user://discord_data.binary"); +} + +ConfigFile DiscordUtil::get_tokens(String encryption_key) +{ + ConfigFile config; + Error err = config.load_encrypted_pass("user://discord_data.binary", encryption_key); + if (err != OK) + { + config.save("user://discord_data.binary"); + return ConfigFile(); + } + return config; } \ No newline at end of file diff --git a/src/util.h b/src/util.h index 74c6ac8..4c92067 100644 --- a/src/util.h +++ b/src/util.h @@ -8,6 +8,7 @@ #include #include #include +#include using namespace godot; @@ -30,6 +31,11 @@ public: Dictionary relationship2dict(discordpp::RelationshipHandle relationship); Dictionary user2dict(discordpp::UserHandle user); + void save_tokens(String access_token, String refresh_token, int64_t expires_in, String encryption_key); + String generate_encryption_key(); + void delete_tokens(); + ConfigFile get_tokens(String encryption_key); + void debug(); void run_callbacks(); };