turtle-wow-source-kinda/Dumps/Source Code/16 - Development_server/patch_1171/dep/dpp/presence.cpp
Brian Oost a1d5bb70b2 Init
2024-08-06 18:06:40 +02:00

281 lines
8.6 KiB
C++

/************************************************************************************
*
* D++, A Lightweight C++ library for Discord
*
* Copyright 2021 Craig Edwards and D++ contributors
* (https://github.com/brainboxdotcc/DPP/graphs/contributors)
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
************************************************************************************/
#include <dpp/presence.h>
#include <dpp/discordevents.h>
#include <dpp/utility.h>
#include <dpp/emoji.h>
#include <dpp/nlohmann/json.hpp>
using json = nlohmann::json;
namespace dpp {
std::string activity::get_large_asset_url(uint16_t size) const {
// https://discord.com/developers/docs/topics/gateway#activity-object-activity-asset-image
if (!this->assets.large_image.empty() && this->application_id &&
this->assets.large_image.find(':') == std::string::npos) { // make sure it's not a prefixed proxy image
return utility::cdn_host + "/app-assets/" + std::to_string(this->application_id) + "/" + this->assets.large_image + ".png" + utility::avatar_size(size);
} else {
return std::string();
}
}
std::string activity::get_small_asset_url(uint16_t size) const {
// https://discord.com/developers/docs/topics/gateway#activity-object-activity-asset-image
if (!this->assets.small_image.empty() && this->application_id &&
this->assets.small_image.find(':') == std::string::npos) { // make sure it's not a prefixed proxy image
return utility::cdn_host + "/app-assets/" + std::to_string(this->application_id) + "/" + this->assets.small_image + ".png" + utility::avatar_size(size);
} else {
return std::string();
}
}
activity_party::activity_party() : id(0), current_size(0), maximum_size(0)
{
}
activity::activity(const activity_type typ, const std::string& nam, const std::string& stat, const std::string& url_) :
name(nam), state(stat), url(url_), type(typ), created_at(0), start(0), end(0), application_id(0), flags(0), is_instance(false)
{
}
activity::activity(): created_at(0), start(0), end(0), application_id(0), flags(0), is_instance(false)
{
}
presence::presence() : user_id(0), guild_id(0), flags(0)
{
}
presence::presence(presence_status status, activity_type type, const std::string& activity_description) {
dpp::activity a;
a.name = activity_description;
a.type = type;
activities.clear();
activities.emplace_back(a);
flags &= PF_CLEAR_STATUS;
if (status == ps_online)
flags |= p_status_online;
else if (status == ps_idle)
flags |= p_status_idle;
else if (status == ps_dnd)
flags |= p_status_dnd;
}
presence::presence(presence_status status, const activity &a) {
activities.clear();
activities.emplace_back(a);
flags &= PF_CLEAR_STATUS;
if (status == ps_online)
flags |= p_status_online;
else if (status == ps_idle)
flags |= p_status_idle;
else if (status == ps_dnd)
flags |= p_status_dnd;
}
presence::~presence() = default;
presence& presence::fill_from_json(nlohmann::json* j) {
guild_id = snowflake_not_null(j, "guild_id");
user_id = snowflake_not_null(&((*j)["user"]), "id");
auto f = j->find("client_status");
if (f != j->end()) {
bool update_desktop = false, update_web = false, update_mobile = false;
std::string desktop, mobile, web;
if (f->find("desktop") != f->end()) {
desktop = string_not_null(&((*j)["client_status"]), "desktop");
update_desktop = true;
}
if (f->find("mobile") != f->end()) {
mobile = string_not_null(&((*j)["client_status"]), "mobile");
update_mobile = true;
}
if (f->find("web") != f->end()) {
web = string_not_null(&((*j)["client_status"]), "web");
update_web = true;
}
if (update_desktop) {
flags &= PF_CLEAR_DESKTOP;
if (desktop == "online")
flags |= p_desktop_online;
else if (desktop == "idle")
flags |= p_desktop_idle;
else if (desktop == "dnd")
flags |= p_desktop_dnd;
}
if (update_mobile) {
flags &= PF_CLEAR_MOBILE;
if (mobile == "online")
flags |= p_mobile_online;
else if (mobile == "idle")
flags |= p_mobile_idle;
else if (mobile == "dnd")
flags |= p_mobile_dnd;
}
if (update_web) {
flags &= PF_CLEAR_WEB;
if (web == "online")
flags |= p_web_online;
else if (web == "idle")
flags |= p_web_idle;
else if (web == "dnd")
flags |= p_web_dnd;
}
}
if (j->contains("status")) {
flags &= PF_CLEAR_STATUS;
std::string main = string_not_null(j, "status");
if (main == "online")
flags |= p_status_online;
else if (main == "idle")
flags |= p_status_idle;
else if (main == "dnd")
flags |= p_status_dnd;
}
if (j->contains("activities")) {
activities.clear();
for (auto & act : (*j)["activities"]) {
activity a;
a.name = string_not_null(&act, "name");
a.details = string_not_null(&act, "details");
if (act.find("assets") != act.end()) {
a.assets.large_image = string_not_null(&act["assets"], "large_image");
a.assets.large_text = string_not_null(&act["assets"], "large_text");
a.assets.small_image = string_not_null(&act["assets"], "small_image");
a.assets.small_text = string_not_null(&act["assets"], "small_text");
}
a.state = string_not_null(&act, "state");
a.type = (activity_type)int8_not_null(&act, "type");
a.url = string_not_null(&act, "url");
if (act.find("buttons") != act.end()) {
for (auto &b : act["buttons"]) {
activity_button btn;
if (b.is_string()) { // its may be just a string (label) because normal bots cannot access the button URLs
btn.label = b.get<std::string>();;
} else {
btn.label = string_not_null(&b, "label");
btn.url = string_not_null(&b, "url");
}
a.buttons.push_back(btn);
}
}
if (act.find("emoji") != act.end()) {
a.emoji.name = string_not_null(&act["emoji"], "name");
a.emoji.id = snowflake_not_null(&act["emoji"], "id");
if (bool_not_null(&act["emoji"], "animated"))
a.emoji.flags |= e_animated;
}
if (act.find("party") != act.end()) {
a.party.id = snowflake_not_null(&act["party"], "id");
if (act["party"].find("size") != act["party"].end()) { // "size" is an array of two integers
try {
a.party.current_size = act["party"]["size"][0].get<int32_t>();
a.party.maximum_size = act["party"]["size"][1].get<int32_t>();
} catch ([[maybe_unused]] std::exception &exception) {}
}
}
if (act.find("secrets") != act.end()) {
a.secrets.join = string_not_null(&act["secret"], "join");
a.secrets.spectate = string_not_null(&act["secret"], "spectate");
a.secrets.match = string_not_null(&act["secret"], "match");
}
a.created_at = int64_not_null(&act, "created_at");
if (act.find("timestamps") != act.end()) {
a.start = int64_not_null(&act["timestamps"], "start");
a.end = int64_not_null(&act["timestamps"], "end");
}
a.application_id = snowflake_not_null(&act, "application_id");
a.flags = int8_not_null(&act, "flags");
a.is_instance = bool_not_null(&act, "instance");
activities.push_back(a);
}
}
return *this;
}
std::string presence::build_json(bool with_id) const {
std::map<presence_status, std::string> status_name_mapping = {
{ps_online, "online"},
{ps_offline, "offline"},
{ps_idle, "idle"},
{ps_dnd, "dnd"}
};
json j({
{"op", 3},
{"d",
{
{ "status", status_name_mapping[status()] },
{ "since", json::value_t::null },
{ "afk", false }
}
}
});
if (activities.size()) {
for(const auto& i : activities){
json j2({
{ "name", i.name },
{ "type", i.type }
});
if (!i.url.empty()) j2["url"] = i.url;
if (!i.state.empty()) j2["details"] = i.state; // bot activity is details, not state
j["d"]["activities"].push_back(j2);
}
/*j["d"]["game"] = json({ // use activities instead.
{ "name", activities[0].name },
{ "type", activities[0].type }
});*/
}
return j.dump();
}
presence_status presence::desktop_status() const {
return (presence_status)((flags >> PF_SHIFT_DESKTOP) & PF_STATUS_MASK);
}
presence_status presence::web_status() const {
return (presence_status)((flags >> PF_SHIFT_WEB) & PF_STATUS_MASK);
}
presence_status presence::mobile_status() const {
return (presence_status)((flags >> PF_SHIFT_MOBILE) & PF_STATUS_MASK);
}
presence_status presence::status() const {
return (presence_status)((flags >> PF_SHIFT_MAIN) & PF_STATUS_MASK);
}
};