summaryrefslogtreecommitdiff
path: root/discord
diff options
context:
space:
mode:
Diffstat (limited to 'discord')
-rw-r--r--discord/activity.hpp14
-rw-r--r--discord/discord.cpp46
-rw-r--r--discord/discord.hpp7
-rw-r--r--discord/errors.hpp36
-rw-r--r--discord/objects.cpp9
-rw-r--r--discord/objects.hpp14
6 files changed, 126 insertions, 0 deletions
diff --git a/discord/activity.hpp b/discord/activity.hpp
index b50d176..76ba9cd 100644
--- a/discord/activity.hpp
+++ b/discord/activity.hpp
@@ -26,6 +26,20 @@ constexpr inline const char *GetPresenceString(PresenceStatus s) {
return "";
}
+constexpr inline const char* GetPresenceDisplayString(PresenceStatus s) {
+ switch (s) {
+ case PresenceStatus::Online:
+ return "Online";
+ case PresenceStatus::Offline:
+ return "Offline";
+ case PresenceStatus::Idle:
+ return "Away";
+ case PresenceStatus::DND:
+ return "Do Not Disturb";
+ }
+ return "";
+}
+
enum class ActivityType : int {
Game = 0,
Streaming = 1,
diff --git a/discord/discord.cpp b/discord/discord.cpp
index e4592ca..0e06e39 100644
--- a/discord/discord.cpp
+++ b/discord/discord.cpp
@@ -691,6 +691,33 @@ std::optional<GuildApplicationData> DiscordClient::GetGuildApplication(Snowflake
return it->second;
}
+void DiscordClient::RemoveRelationship(Snowflake id, sigc::slot<void(bool success)> callback) {
+ m_http.MakeDELETE("/users/@me/relationships/" + std::to_string(id), [this, callback](const http::response_type &response) {
+ callback(CheckCode(response));
+ });
+}
+
+void DiscordClient::SendFriendRequest(const Glib::ustring &username, int discriminator, sigc::slot<void(bool success, DiscordError code)> callback) {
+ FriendRequestObject obj;
+ obj.Username = username;
+ obj.Discriminator = discriminator;
+ m_http.MakePOST("/users/@me/relationships", nlohmann::json(obj).dump(), [this, callback](const http::response_type &response) {
+ if (CheckCode(response, 204))
+ callback(true, DiscordError::NONE);
+ else
+ callback(false, GetCodeFromResponse(response));
+ });
+}
+
+void DiscordClient::PutRelationship(Snowflake id, sigc::slot<void(bool success, DiscordError code)> callback) {
+ m_http.MakePUT("/users/@me/relationships/" + std::to_string(id), "{}", [this, callback](const http::response_type &response) {
+ if (CheckCode(response, 204))
+ callback(true, DiscordError::NONE);
+ else
+ callback(false, GetCodeFromResponse(response));
+ });
+}
+
bool DiscordClient::CanModifyRole(Snowflake guild_id, Snowflake role_id, Snowflake user_id) const {
const auto guild = *GetGuild(guild_id);
if (guild.OwnerID == user_id) return true;
@@ -850,6 +877,10 @@ PresenceStatus DiscordClient::GetUserStatus(Snowflake id) const {
return PresenceStatus::Offline;
}
+std::unordered_map<Snowflake, RelationshipType> DiscordClient::GetRelationships() const {
+ return m_user_relationships;
+}
+
std::unordered_set<Snowflake> DiscordClient::GetRelationships(RelationshipType type) const {
std::unordered_set<Snowflake> ret;
for (const auto &[id, rtype] : m_user_relationships)
@@ -858,6 +889,12 @@ std::unordered_set<Snowflake> DiscordClient::GetRelationships(RelationshipType t
return ret;
}
+std::optional<RelationshipType> DiscordClient::GetRelationship(Snowflake id) const {
+ if (auto it = m_user_relationships.find(id); it != m_user_relationships.end())
+ return it->second;
+ return std::nullopt;
+}
+
void DiscordClient::HandleGatewayMessageRaw(std::string str) {
// handles multiple zlib compressed messages, calling HandleGatewayMessage when a full message is received
std::vector<uint8_t> buf(str.begin(), str.end());
@@ -1067,6 +1104,15 @@ void DiscordClient::HandleGatewayHello(const GatewayMessage &msg) {
SendIdentify();
}
+DiscordError DiscordClient::GetCodeFromResponse(const http::response_type &response) {
+ try {
+ // pull me somewhere else?
+ const auto data = nlohmann::json::parse(response.text);
+ return data.at("code").get<DiscordError>();
+ } catch (...) {}
+ return DiscordError::GENERIC;
+}
+
void DiscordClient::ProcessNewGuild(GuildData &guild) {
if (guild.IsUnavailable) {
printf("guild (%lld) unavailable\n", static_cast<uint64_t>(guild.ID));
diff --git a/discord/discord.hpp b/discord/discord.hpp
index 6bdeb37..ff4fe2e 100644
--- a/discord/discord.hpp
+++ b/discord/discord.hpp
@@ -138,6 +138,9 @@ public:
void ModifyEmojiName(Snowflake guild_id, Snowflake emoji_id, const Glib::ustring &name, sigc::slot<void(bool success)> callback);
void DeleteEmoji(Snowflake guild_id, Snowflake emoji_id, sigc::slot<void(bool success)> callback);
std::optional<GuildApplicationData> GetGuildApplication(Snowflake guild_id) const;
+ void RemoveRelationship(Snowflake id, sigc::slot<void(bool success)> callback);
+ void SendFriendRequest(const Glib::ustring &username, int discriminator, sigc::slot<void(bool success, DiscordError code)> callback);
+ void PutRelationship(Snowflake id, sigc::slot<void(bool success, DiscordError code)> callback); // send fr by id, accept incoming
bool CanModifyRole(Snowflake guild_id, Snowflake role_id) const;
bool CanModifyRole(Snowflake guild_id, Snowflake role_id, Snowflake user_id) const;
@@ -178,7 +181,9 @@ public:
PresenceStatus GetUserStatus(Snowflake id) const;
+ std::unordered_map<Snowflake, RelationshipType> GetRelationships() const;
std::unordered_set<Snowflake> GetRelationships(RelationshipType type) const;
+ std::optional<RelationshipType> GetRelationship(Snowflake id) const;
private:
static const constexpr int InflateChunkSize = 0x10000;
@@ -186,6 +191,8 @@ private:
std::vector<uint8_t> m_decompress_buf;
z_stream m_zstream;
+ static DiscordError GetCodeFromResponse(const http::response_type &response);
+
void ProcessNewGuild(GuildData &guild);
void HandleGatewayMessageRaw(std::string str);
diff --git a/discord/errors.hpp b/discord/errors.hpp
new file mode 100644
index 0000000..4579563
--- /dev/null
+++ b/discord/errors.hpp
@@ -0,0 +1,36 @@
+#pragma once
+
+enum class DiscordError {
+ GENERIC = 0,
+ INVALID_FORM_BODY = 50035,
+ RELATIONSHIP_INCOMING_DISABLED = 80000,
+ RELATIONSHIP_INCOMING_BLOCKED = 80001,
+ RELATIONSHIP_INVALID_USER_BOT = 80002, // this is misspelled in discord's source lul
+ RELATIONSHIP_INVALID_SELF = 80003,
+ RELATIONSHIP_INVALID_DISCORD_TAG = 80004,
+ RELATIONSHIP_ALREADY_FRIENDS = 80007,
+
+ NONE = -1,
+};
+
+constexpr const char *GetDiscordErrorDisplayString(DiscordError error) {
+ switch (error) {
+ case DiscordError::INVALID_FORM_BODY:
+ return "Something's wrong with your input";
+ case DiscordError::RELATIONSHIP_INCOMING_DISABLED:
+ return "This user isn't accepting friend requests";
+ case DiscordError::RELATIONSHIP_INCOMING_BLOCKED:
+ return "You are blocked by this user";
+ case DiscordError::RELATIONSHIP_INVALID_USER_BOT:
+ return "You can't send a request to a bot";
+ case DiscordError::RELATIONSHIP_INVALID_SELF:
+ return "You can't send a request to yourself";
+ case DiscordError::RELATIONSHIP_INVALID_DISCORD_TAG:
+ return "No users with that tag exist";
+ case DiscordError::RELATIONSHIP_ALREADY_FRIENDS:
+ return "You are already friends with that user";
+ case DiscordError::GENERIC:
+ default:
+ return "An error occurred";
+ }
+}
diff --git a/discord/objects.cpp b/discord/objects.cpp
index 95f7fa6..8588b30 100644
--- a/discord/objects.cpp
+++ b/discord/objects.cpp
@@ -463,3 +463,12 @@ void from_json(const nlohmann::json &j, RelationshipAddData &m) {
JS_D("type", m.Type);
JS_D("user", m.User);
}
+
+void to_json(nlohmann::json &j, const FriendRequestObject &m) {
+ j["username"] = m.Username;
+ j["discriminator"] = m.Discriminator;
+}
+
+void to_json(nlohmann::json &j, const PutRelationshipObject &m) {
+ JS_IF("type", m.Type);
+}
diff --git a/discord/objects.hpp b/discord/objects.hpp
index 56191df..11c8df4 100644
--- a/discord/objects.hpp
+++ b/discord/objects.hpp
@@ -19,6 +19,7 @@
#include "ban.hpp"
#include "auditlog.hpp"
#include "relationship.hpp"
+#include "errors.hpp"
// most stuff below should just be objects that get processed and thrown away immediately
@@ -645,3 +646,16 @@ struct RelationshipAddData {
friend void from_json(const nlohmann::json &j, RelationshipAddData &m);
};
+
+struct FriendRequestObject {
+ std::string Username;
+ int Discriminator;
+
+ friend void to_json(nlohmann::json &j, const FriendRequestObject &m);
+};
+
+struct PutRelationshipObject {
+ std::optional<RelationshipType> Type;
+
+ friend void to_json(nlohmann::json &j, const PutRelationshipObject &m);
+};