mirror of
https://github.com/brian8544/turtle-wow.git
synced 2025-01-05 22:34:35 +00:00
281 lines
8.6 KiB
C++
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);
|
|
}
|
|
|
|
};
|