mirror of
https://github.com/celisej567/abaddon.git
synced 2026-09-27 16:16:35 +03:00
rudimentary chat
This commit is contained in:
@@ -84,6 +84,13 @@ std::vector<std::pair<Snowflake, GuildData>> DiscordClient::GetUserSortedGuilds(
|
||||
return sorted_guilds;
|
||||
}
|
||||
|
||||
std::unordered_set<const MessageData *> DiscordClient::GetMessagesForChannel(Snowflake id) const {
|
||||
auto it = m_chan_to_message_map.find(id);
|
||||
if (it == m_chan_to_message_map.end())
|
||||
return std::unordered_set<const MessageData *>();
|
||||
return it->second;
|
||||
}
|
||||
|
||||
void DiscordClient::UpdateSettingsGuildPositions(const std::vector<Snowflake> &pos) {
|
||||
assert(pos.size() == m_guilds.size());
|
||||
nlohmann::json body;
|
||||
@@ -94,6 +101,18 @@ void DiscordClient::UpdateSettingsGuildPositions(const std::vector<Snowflake> &p
|
||||
});
|
||||
}
|
||||
|
||||
void DiscordClient::FetchMessagesInChannel(Snowflake id, std::function<void(const std::vector<MessageData> &)> cb) {
|
||||
std::string path = "/channels/" + std::to_string(id) + "/messages?limit=50";
|
||||
m_http.MakeGET(path, [this, id, cb](cpr::Response r) {
|
||||
std::vector<MessageData> msgs;
|
||||
nlohmann::json::parse(r.text).get_to(msgs);
|
||||
for (const auto &msg : msgs)
|
||||
StoreMessage(msg.ID, msg);
|
||||
|
||||
cb(msgs);
|
||||
});
|
||||
}
|
||||
|
||||
void DiscordClient::UpdateToken(std::string token) {
|
||||
m_token = token;
|
||||
m_http.SetAuth(token);
|
||||
@@ -153,6 +172,15 @@ void DiscordClient::StoreGuild(Snowflake id, const GuildData &g) {
|
||||
m_guilds[id] = g;
|
||||
}
|
||||
|
||||
void DiscordClient::StoreMessage(Snowflake id, const MessageData &m) {
|
||||
assert(id.IsValid());
|
||||
m_messages[id] = m;
|
||||
auto it = m_chan_to_message_map.find(m.ChannelID);
|
||||
if (it == m_chan_to_message_map.end())
|
||||
m_chan_to_message_map[m.ChannelID] = decltype(m_chan_to_message_map)::mapped_type();
|
||||
m_chan_to_message_map[m.ChannelID].insert(&m_messages[id]);
|
||||
}
|
||||
|
||||
void DiscordClient::HeartbeatThread() {
|
||||
while (m_client_connected) {
|
||||
if (!m_heartbeat_acked) {
|
||||
@@ -308,6 +336,33 @@ void from_json(const nlohmann::json &j, ChannelData &m) {
|
||||
JS_ON("last_pin_timestamp", m.LastPinTimestamp);
|
||||
}
|
||||
|
||||
void from_json(const nlohmann::json &j, MessageData &m) {
|
||||
JS_D("id", m.ID);
|
||||
JS_D("channel_id", m.ChannelID);
|
||||
JS_O("guild_id", m.GuildID);
|
||||
JS_D("author", m.Author);
|
||||
// JS_O("member", m.Member);
|
||||
JS_D("content", m.Content);
|
||||
JS_D("timestamp", m.Timestamp);
|
||||
JS_N("edited_timestamp", m.EditedTimestamp);
|
||||
JS_D("tts", m.IsTTS);
|
||||
JS_D("mention_everyone", m.DoesMentionEveryone);
|
||||
JS_D("mentions", m.Mentions);
|
||||
// JS_D("mention_roles", m.MentionRoles);
|
||||
// JS_O("mention_channels", m.MentionChannels);
|
||||
// JS_D("attachments", m.Attachments);
|
||||
// JS_D("embeds", m.Embeds);
|
||||
// JS_O("reactions", m.Reactions);
|
||||
JS_O("nonce", m.Nonce);
|
||||
JS_D("pinned", m.IsPinned);
|
||||
JS_O("webhook_id", m.WebhookID);
|
||||
JS_D("type", m.Type);
|
||||
// JS_O("activity", m.Activity);
|
||||
// JS_O("application", m.Application);
|
||||
// JS_O("message_reference", m.MessageReference);
|
||||
JS_O("flags", m.Flags);
|
||||
}
|
||||
|
||||
void from_json(const nlohmann::json &j, ReadyEventData &m) {
|
||||
JS_D("v", m.GatewayVersion);
|
||||
JS_D("user", m.User);
|
||||
@@ -400,7 +455,7 @@ void from_json(const nlohmann::json &j, Snowflake &s) {
|
||||
s.m_num = std::stoull(tmp);
|
||||
}
|
||||
|
||||
void to_json(nlohmann::json& j, const Snowflake& s) {
|
||||
void to_json(nlohmann::json &j, const Snowflake &s) {
|
||||
j = std::to_string(s);
|
||||
}
|
||||
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
#include <nlohmann/json.hpp>
|
||||
#include <thread>
|
||||
#include <unordered_map>
|
||||
#include <unordered_set>
|
||||
#include <mutex>
|
||||
|
||||
struct Snowflake {
|
||||
@@ -33,6 +34,7 @@ struct Snowflake {
|
||||
|
||||
private:
|
||||
friend struct std::hash<Snowflake>;
|
||||
friend struct std::less<Snowflake>;
|
||||
unsigned long long m_num;
|
||||
};
|
||||
|
||||
@@ -43,6 +45,13 @@ struct hash<Snowflake> {
|
||||
return k.m_num;
|
||||
}
|
||||
};
|
||||
|
||||
template<>
|
||||
struct less<Snowflake> {
|
||||
bool operator()(const Snowflake &l, const Snowflake &r) const {
|
||||
return l.m_num < r.m_num;
|
||||
}
|
||||
};
|
||||
} // namespace std
|
||||
|
||||
enum class GatewayOp : int {
|
||||
@@ -222,6 +231,62 @@ struct UserSettingsData {
|
||||
friend void from_json(const nlohmann::json &j, UserSettingsData &m);
|
||||
};
|
||||
|
||||
enum class MessageType {
|
||||
DEFAULT = 0,
|
||||
RECIPIENT_ADD = 1,
|
||||
RECIPIENT_REMOVE = 2,
|
||||
CALL = 3,
|
||||
CHANNEL_NaME_CHANGE = 4,
|
||||
CHANNEL_ICON_CHANGE = 5,
|
||||
CHANNEL_PINNED_MESSAGE = 6,
|
||||
GUILD_MEMBER_JOIN = 6,
|
||||
USER_PREMIUM_GUILD_SUBSCRIPTION = 7,
|
||||
USER_PREMIUM_GUILD_SUBSCRIPTION_TIER_1 = 8,
|
||||
USER_PREMIUM_GUILD_SUBSCRIPTION_TIER_2 = 9,
|
||||
USER_PREMIUM_GUILD_SUBSCRIPTION_TIER_3 = 10,
|
||||
CHANNEL_FOLLOW_ADD = 12,
|
||||
GUILD_DISCOVERY_DISQUALIFIED = 13,
|
||||
GUILD_DISCOVERY_REQUALIFIED = 14,
|
||||
};
|
||||
|
||||
enum class MessageFlags {
|
||||
NONE = 0,
|
||||
CROSSPOSTED = 1 << 0,
|
||||
IS_CROSSPOST = 1 << 1,
|
||||
SUPPRESS_EMBEDS = 1 << 2,
|
||||
SOURCE_MESSAGE_DELETE = 1 << 3,
|
||||
URGENT = 1 << 4,
|
||||
};
|
||||
|
||||
struct MessageData {
|
||||
Snowflake ID; //
|
||||
Snowflake ChannelID; //
|
||||
Snowflake GuildID; // opt
|
||||
UserData Author; //
|
||||
// GuildMemberData Member; // opt
|
||||
std::string Content; //
|
||||
std::string Timestamp; //
|
||||
std::string EditedTimestamp; // null
|
||||
bool IsTTS; //
|
||||
bool DoesMentionEveryone; //
|
||||
std::vector<UserData> Mentions; //
|
||||
// std::vector<RoleData> MentionRoles; //
|
||||
// std::vector<ChannelMentionData> MentionChannels; // opt
|
||||
// std::vector<AttachmentData> Attachments; //
|
||||
// std::vector<EmbedData> Embeds; //
|
||||
// std::vector<ReactionData> Reactions; // opt
|
||||
std::string Nonce; // opt
|
||||
bool IsPinned; //
|
||||
Snowflake WebhookID; // opt
|
||||
MessageType Type; //
|
||||
// MessageActivityData Activity; // opt
|
||||
// MessageApplicationData Application; // opt
|
||||
// MessageReferenceData MessageReference; // opt
|
||||
MessageFlags Flags = MessageFlags::NONE; // opt
|
||||
|
||||
friend void from_json(const nlohmann::json &j, MessageData &m);
|
||||
};
|
||||
|
||||
struct ReadyEventData {
|
||||
int GatewayVersion; //
|
||||
UserData User; //
|
||||
@@ -307,10 +372,15 @@ public:
|
||||
bool IsStarted() const;
|
||||
|
||||
using Guilds_t = std::unordered_map<Snowflake, GuildData>;
|
||||
using Messages_t = std::unordered_map<Snowflake, MessageData>;
|
||||
|
||||
const Guilds_t &GetGuilds() const;
|
||||
const UserSettingsData &GetUserSettings() const;
|
||||
std::vector<std::pair<Snowflake, GuildData>> GetUserSortedGuilds() const;
|
||||
std::unordered_set<const MessageData *> GetMessagesForChannel(Snowflake id) const;
|
||||
|
||||
void UpdateSettingsGuildPositions(const std::vector<Snowflake> &pos);
|
||||
void FetchMessagesInChannel(Snowflake id, std::function<void(const std::vector<MessageData> &)> cb);
|
||||
|
||||
void UpdateToken(std::string token);
|
||||
|
||||
@@ -330,6 +400,10 @@ private:
|
||||
void StoreGuild(Snowflake id, const GuildData &g);
|
||||
Guilds_t m_guilds;
|
||||
|
||||
void StoreMessage(Snowflake id, const MessageData &m);
|
||||
Messages_t m_messages;
|
||||
std::unordered_map<Snowflake, std::unordered_set<const MessageData *>> m_chan_to_message_map;
|
||||
|
||||
UserSettingsData m_user_settings;
|
||||
|
||||
Websocket m_websocket;
|
||||
|
||||
@@ -36,6 +36,37 @@ void HTTPClient::MakePOST(std::string path, std::string payload, std::function<v
|
||||
{ "Content-Type", "application/json" },
|
||||
};
|
||||
auto body = cpr::Body { payload };
|
||||
#ifdef USE_LOCAL_PROXY
|
||||
m_futures.push_back(cpr::GetCallback(
|
||||
std::bind(&HTTPClient::OnResponse, this, std::placeholders::_1, cb),
|
||||
url, headers, body,
|
||||
cpr::Proxies { { "http", "127.0.0.1:8888" }, { "https", "127.0.0.1:8888" } },
|
||||
cpr::VerifySsl { false }));
|
||||
#else
|
||||
m_futures.push_back(cpr::PatchCallback(
|
||||
std::bind(&HTTPClient::OnResponse, this, std::placeholders::_1, cb),
|
||||
url, headers, body));
|
||||
#endif
|
||||
}
|
||||
|
||||
void HTTPClient::MakeGET(std::string path, std::function<void(cpr::Response r)> cb) {
|
||||
printf("POST %s\n", path.c_str());
|
||||
auto url = cpr::Url { m_api_base + path };
|
||||
auto headers = cpr::Header {
|
||||
{ "Authorization", m_authorization },
|
||||
{ "Content-Type", "application/json" },
|
||||
};
|
||||
#ifdef USE_LOCAL_PROXY
|
||||
m_futures.push_back(cpr::GetCallback(
|
||||
std::bind(&HTTPClient::OnResponse, this, std::placeholders::_1, cb),
|
||||
url, headers,
|
||||
cpr::Proxies { { "http", "127.0.0.1:8888" }, { "https", "127.0.0.1:8888" } },
|
||||
cpr::VerifySsl { false }));
|
||||
#else
|
||||
m_futures.push_back(cpr::GetCallback(
|
||||
std::bind(&HTTPClient::OnResponse, this, std::placeholders::_1, cb),
|
||||
url, headers));
|
||||
#endif
|
||||
}
|
||||
|
||||
void HTTPClient::CleanupFutures() {
|
||||
|
||||
@@ -19,6 +19,7 @@ public:
|
||||
HTTPClient(std::string api_base);
|
||||
|
||||
void SetAuth(std::string auth);
|
||||
void MakeGET(std::string path, std::function<void(cpr::Response r)> cb);
|
||||
void MakePATCH(std::string path, std::string payload, std::function<void(cpr::Response r)> cb);
|
||||
void MakePOST(std::string path, std::string payload, std::function<void(cpr::Response r)> cb);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user