forked from OpenGamers/abaddon
spoof a bunch of headers like the web client
This commit is contained in:
parent
baf96da80c
commit
dc28eae95a
@ -647,12 +647,17 @@ void Abaddon::ActionJoinGuildDialog() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void Abaddon::ActionChannelOpened(Snowflake id, bool expand_to) {
|
void Abaddon::ActionChannelOpened(Snowflake id, bool expand_to) {
|
||||||
if (!id.IsValid() || id == m_main_window->GetChatActiveChannel()) return;
|
if (!id.IsValid()) {
|
||||||
|
m_discord.SetReferringChannel(Snowflake::Invalid);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (id == m_main_window->GetChatActiveChannel()) return;
|
||||||
|
|
||||||
m_main_window->GetChatWindow()->SetTopic("");
|
m_main_window->GetChatWindow()->SetTopic("");
|
||||||
|
|
||||||
const auto channel = m_discord.GetChannel(id);
|
const auto channel = m_discord.GetChannel(id);
|
||||||
if (!channel.has_value()) {
|
if (!channel.has_value()) {
|
||||||
|
m_discord.SetReferringChannel(Snowflake::Invalid);
|
||||||
m_main_window->UpdateChatActiveChannel(Snowflake::Invalid, false);
|
m_main_window->UpdateChatActiveChannel(Snowflake::Invalid, false);
|
||||||
m_main_window->UpdateChatWindowContents();
|
m_main_window->UpdateChatWindowContents();
|
||||||
return;
|
return;
|
||||||
@ -701,6 +706,7 @@ void Abaddon::ActionChannelOpened(Snowflake id, bool expand_to) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
m_main_window->UpdateMenus();
|
m_main_window->UpdateMenus();
|
||||||
|
m_discord.SetReferringChannel(id);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Abaddon::ActionChatLoadHistory(Snowflake id) {
|
void Abaddon::ActionChatLoadHistory(Snowflake id) {
|
||||||
|
@ -30,6 +30,7 @@ void DiscordClient::Start() {
|
|||||||
if (m_client_started) return;
|
if (m_client_started) return;
|
||||||
|
|
||||||
m_http.SetBase(GetAPIURL());
|
m_http.SetBase(GetAPIURL());
|
||||||
|
SetHeaders();
|
||||||
|
|
||||||
std::memset(&m_zstream, 0, sizeof(m_zstream));
|
std::memset(&m_zstream, 0, sizeof(m_zstream));
|
||||||
inflateInit2(&m_zstream, MAX_WBITS + 32);
|
inflateInit2(&m_zstream, MAX_WBITS + 32);
|
||||||
@ -1110,6 +1111,25 @@ void DiscordClient::AcceptVerificationGate(Snowflake guild_id, VerificationGateI
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void DiscordClient::SetReferringChannel(Snowflake id) {
|
||||||
|
if (!id.IsValid()) {
|
||||||
|
m_http.SetPersistentHeader("Referer", "https://discord.com/channels/@me");
|
||||||
|
} else {
|
||||||
|
const auto channel = GetChannel(id);
|
||||||
|
if (channel.has_value()) {
|
||||||
|
if (channel->IsDM()) {
|
||||||
|
m_http.SetPersistentHeader("Referer", "https://discord.com/channels/@me/" + std::to_string(id));
|
||||||
|
} else if (channel->GuildID.has_value()) {
|
||||||
|
m_http.SetPersistentHeader("Referer", "https://discord.com/channels/" + std::to_string(*channel->GuildID) + "/" + std::to_string(id));
|
||||||
|
} else {
|
||||||
|
m_http.SetPersistentHeader("Referer", "https://discord.com/channels/@me");
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
m_http.SetPersistentHeader("Referer", "https://discord.com/channels/@me");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void DiscordClient::UpdateToken(const std::string &token) {
|
void DiscordClient::UpdateToken(const std::string &token) {
|
||||||
if (!IsStarted()) {
|
if (!IsStarted()) {
|
||||||
m_token = token;
|
m_token = token;
|
||||||
@ -2245,6 +2265,7 @@ void DiscordClient::SendIdentify() {
|
|||||||
msg.ClientState.HighestLastMessageID = "0";
|
msg.ClientState.HighestLastMessageID = "0";
|
||||||
msg.ClientState.ReadStateVersion = 0;
|
msg.ClientState.ReadStateVersion = 0;
|
||||||
msg.ClientState.UserGuildSettingsVersion = -1;
|
msg.ClientState.UserGuildSettingsVersion = -1;
|
||||||
|
SetSuperPropertiesFromIdentity(msg);
|
||||||
const bool b = m_websocket.GetPrintMessages();
|
const bool b = m_websocket.GetPrintMessages();
|
||||||
m_websocket.SetPrintMessages(false);
|
m_websocket.SetPrintMessages(false);
|
||||||
m_websocket.Send(msg);
|
m_websocket.Send(msg);
|
||||||
@ -2259,6 +2280,36 @@ void DiscordClient::SendResume() {
|
|||||||
m_websocket.Send(msg);
|
m_websocket.Send(msg);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void DiscordClient::SetHeaders() {
|
||||||
|
m_http.SetPersistentHeader("Sec-Fetch-Dest", "empty");
|
||||||
|
m_http.SetPersistentHeader("Sec-Fetch-Mode", "cors");
|
||||||
|
m_http.SetPersistentHeader("Sec-Fetch-Site", "same-origin");
|
||||||
|
m_http.SetPersistentHeader("X-Debug-Options", "bugReporterEnabled");
|
||||||
|
m_http.SetPersistentHeader("Accept-Language", "en-US,en;q=0.9");
|
||||||
|
|
||||||
|
SetReferringChannel(Snowflake::Invalid);
|
||||||
|
}
|
||||||
|
|
||||||
|
void DiscordClient::SetSuperPropertiesFromIdentity(const IdentifyMessage &identity) {
|
||||||
|
nlohmann::ordered_json j;
|
||||||
|
j["os"] = identity.Properties.OS;
|
||||||
|
j["browser"] = identity.Properties.Browser;
|
||||||
|
j["device"] = identity.Properties.Device;
|
||||||
|
j["system_locale"] = identity.Properties.SystemLocale;
|
||||||
|
j["browser_user_agent"] = identity.Properties.BrowserUserAgent;
|
||||||
|
j["browser_version"] = identity.Properties.BrowserVersion;
|
||||||
|
j["os_version"] = identity.Properties.OSVersion;
|
||||||
|
j["referrer"] = identity.Properties.Referrer;
|
||||||
|
j["referring_domain"] = identity.Properties.ReferringDomain;
|
||||||
|
j["referrer_current"] = identity.Properties.ReferrerCurrent;
|
||||||
|
j["referring_domain_current"] = identity.Properties.ReferringDomainCurrent;
|
||||||
|
j["release_channel"] = identity.Properties.ReleaseChannel;
|
||||||
|
j["client_build_number"] = identity.Properties.ClientBuildNumber;
|
||||||
|
j["client_event_source"] = nullptr; // probably will never be non-null ("") anyways
|
||||||
|
m_http.SetPersistentHeader("X-Super-Properties", Glib::Base64::encode(j.dump()));
|
||||||
|
m_http.SetPersistentHeader("X-Discord-Locale", identity.Properties.SystemLocale);
|
||||||
|
}
|
||||||
|
|
||||||
void DiscordClient::HandleSocketOpen() {
|
void DiscordClient::HandleSocketOpen() {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -201,6 +201,8 @@ public:
|
|||||||
void GetVerificationGateInfo(Snowflake guild_id, const sigc::slot<void(std::optional<VerificationGateInfoObject>)> &callback);
|
void GetVerificationGateInfo(Snowflake guild_id, const sigc::slot<void(std::optional<VerificationGateInfoObject>)> &callback);
|
||||||
void AcceptVerificationGate(Snowflake guild_id, VerificationGateInfoObject info, const sigc::slot<void(DiscordError code)> &callback);
|
void AcceptVerificationGate(Snowflake guild_id, VerificationGateInfoObject info, const sigc::slot<void(DiscordError code)> &callback);
|
||||||
|
|
||||||
|
void SetReferringChannel(Snowflake id);
|
||||||
|
|
||||||
void UpdateToken(const std::string &token);
|
void UpdateToken(const std::string &token);
|
||||||
void SetUserAgent(const std::string &agent);
|
void SetUserAgent(const std::string &agent);
|
||||||
|
|
||||||
@ -282,6 +284,9 @@ private:
|
|||||||
void SendIdentify();
|
void SendIdentify();
|
||||||
void SendResume();
|
void SendResume();
|
||||||
|
|
||||||
|
void SetHeaders();
|
||||||
|
void SetSuperPropertiesFromIdentity(const IdentifyMessage &identity);
|
||||||
|
|
||||||
void HandleSocketOpen();
|
void HandleSocketOpen();
|
||||||
void HandleSocketClose(uint16_t code);
|
void HandleSocketClose(uint16_t code);
|
||||||
|
|
||||||
|
@ -19,11 +19,17 @@ void HTTPClient::SetAuth(std::string auth) {
|
|||||||
m_authorization = std::move(auth);
|
m_authorization = std::move(auth);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void HTTPClient::SetPersistentHeader(std::string name, std::string value) {
|
||||||
|
m_headers.insert_or_assign(std::move(name), std::move(value));
|
||||||
|
}
|
||||||
|
|
||||||
void HTTPClient::MakeDELETE(const std::string &path, const std::function<void(http::response_type r)> &cb) {
|
void HTTPClient::MakeDELETE(const std::string &path, const std::function<void(http::response_type r)> &cb) {
|
||||||
printf("DELETE %s\n", path.c_str());
|
printf("DELETE %s\n", path.c_str());
|
||||||
m_futures.push_back(std::async(std::launch::async, [this, path, cb] {
|
m_futures.push_back(std::async(std::launch::async, [this, path, cb] {
|
||||||
http::request req(http::REQUEST_DELETE, m_api_base + path);
|
http::request req(http::REQUEST_DELETE, m_api_base + path);
|
||||||
|
AddHeaders(req);
|
||||||
req.set_header("Authorization", m_authorization);
|
req.set_header("Authorization", m_authorization);
|
||||||
|
req.set_header("Origin", "https://discord.com");
|
||||||
req.set_user_agent(!m_agent.empty() ? m_agent : "Abaddon");
|
req.set_user_agent(!m_agent.empty() ? m_agent : "Abaddon");
|
||||||
#ifdef USE_LOCAL_PROXY
|
#ifdef USE_LOCAL_PROXY
|
||||||
req.set_proxy("http://127.0.0.1:8888");
|
req.set_proxy("http://127.0.0.1:8888");
|
||||||
@ -40,8 +46,10 @@ void HTTPClient::MakePATCH(const std::string &path, const std::string &payload,
|
|||||||
printf("PATCH %s\n", path.c_str());
|
printf("PATCH %s\n", path.c_str());
|
||||||
m_futures.push_back(std::async(std::launch::async, [this, path, cb, payload] {
|
m_futures.push_back(std::async(std::launch::async, [this, path, cb, payload] {
|
||||||
http::request req(http::REQUEST_PATCH, m_api_base + path);
|
http::request req(http::REQUEST_PATCH, m_api_base + path);
|
||||||
|
AddHeaders(req);
|
||||||
req.set_header("Authorization", m_authorization);
|
req.set_header("Authorization", m_authorization);
|
||||||
req.set_header("Content-Type", "application/json");
|
req.set_header("Content-Type", "application/json");
|
||||||
|
req.set_header("Origin", "https://discord.com");
|
||||||
req.set_user_agent(!m_agent.empty() ? m_agent : "Abaddon");
|
req.set_user_agent(!m_agent.empty() ? m_agent : "Abaddon");
|
||||||
req.set_body(payload);
|
req.set_body(payload);
|
||||||
#ifdef USE_LOCAL_PROXY
|
#ifdef USE_LOCAL_PROXY
|
||||||
@ -59,8 +67,10 @@ void HTTPClient::MakePOST(const std::string &path, const std::string &payload, c
|
|||||||
printf("POST %s\n", path.c_str());
|
printf("POST %s\n", path.c_str());
|
||||||
m_futures.push_back(std::async(std::launch::async, [this, path, cb, payload] {
|
m_futures.push_back(std::async(std::launch::async, [this, path, cb, payload] {
|
||||||
http::request req(http::REQUEST_POST, m_api_base + path);
|
http::request req(http::REQUEST_POST, m_api_base + path);
|
||||||
|
AddHeaders(req);
|
||||||
req.set_header("Authorization", m_authorization);
|
req.set_header("Authorization", m_authorization);
|
||||||
req.set_header("Content-Type", "application/json");
|
req.set_header("Content-Type", "application/json");
|
||||||
|
req.set_header("Origin", "https://discord.com");
|
||||||
req.set_user_agent(!m_agent.empty() ? m_agent : "Abaddon");
|
req.set_user_agent(!m_agent.empty() ? m_agent : "Abaddon");
|
||||||
req.set_body(payload);
|
req.set_body(payload);
|
||||||
#ifdef USE_LOCAL_PROXY
|
#ifdef USE_LOCAL_PROXY
|
||||||
@ -78,7 +88,9 @@ void HTTPClient::MakePUT(const std::string &path, const std::string &payload, co
|
|||||||
printf("PUT %s\n", path.c_str());
|
printf("PUT %s\n", path.c_str());
|
||||||
m_futures.push_back(std::async(std::launch::async, [this, path, cb, payload] {
|
m_futures.push_back(std::async(std::launch::async, [this, path, cb, payload] {
|
||||||
http::request req(http::REQUEST_PUT, m_api_base + path);
|
http::request req(http::REQUEST_PUT, m_api_base + path);
|
||||||
|
AddHeaders(req);
|
||||||
req.set_header("Authorization", m_authorization);
|
req.set_header("Authorization", m_authorization);
|
||||||
|
req.set_header("Origin", "https://discord.com");
|
||||||
if (!payload.empty())
|
if (!payload.empty())
|
||||||
req.set_header("Content-Type", "application/json");
|
req.set_header("Content-Type", "application/json");
|
||||||
req.set_user_agent(!m_agent.empty() ? m_agent : "Abaddon");
|
req.set_user_agent(!m_agent.empty() ? m_agent : "Abaddon");
|
||||||
@ -98,8 +110,8 @@ void HTTPClient::MakeGET(const std::string &path, const std::function<void(http:
|
|||||||
printf("GET %s\n", path.c_str());
|
printf("GET %s\n", path.c_str());
|
||||||
m_futures.push_back(std::async(std::launch::async, [this, path, cb] {
|
m_futures.push_back(std::async(std::launch::async, [this, path, cb] {
|
||||||
http::request req(http::REQUEST_GET, m_api_base + path);
|
http::request req(http::REQUEST_GET, m_api_base + path);
|
||||||
|
AddHeaders(req);
|
||||||
req.set_header("Authorization", m_authorization);
|
req.set_header("Authorization", m_authorization);
|
||||||
req.set_header("Content-Type", "application/json");
|
|
||||||
req.set_user_agent(!m_agent.empty() ? m_agent : "Abaddon");
|
req.set_user_agent(!m_agent.empty() ? m_agent : "Abaddon");
|
||||||
#ifdef USE_LOCAL_PROXY
|
#ifdef USE_LOCAL_PROXY
|
||||||
req.set_proxy("http://127.0.0.1:8888");
|
req.set_proxy("http://127.0.0.1:8888");
|
||||||
@ -128,6 +140,13 @@ void HTTPClient::RunCallbacks() {
|
|||||||
m_mutex.unlock();
|
m_mutex.unlock();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void HTTPClient::AddHeaders(http::request &r) {
|
||||||
|
for (const auto &[name, val] : m_headers) {
|
||||||
|
r.set_header(name, val);
|
||||||
|
}
|
||||||
|
curl_easy_setopt(r.get_curl(), CURLOPT_ACCEPT_ENCODING, "gzip, deflate, br");
|
||||||
|
}
|
||||||
|
|
||||||
void HTTPClient::OnResponse(const http::response_type &r, const std::function<void(http::response_type r)> &cb) {
|
void HTTPClient::OnResponse(const http::response_type &r, const std::function<void(http::response_type r)> &cb) {
|
||||||
CleanupFutures();
|
CleanupFutures();
|
||||||
try {
|
try {
|
||||||
|
@ -17,6 +17,8 @@ public:
|
|||||||
|
|
||||||
void SetUserAgent(std::string agent);
|
void SetUserAgent(std::string agent);
|
||||||
void SetAuth(std::string auth);
|
void SetAuth(std::string auth);
|
||||||
|
void SetPersistentHeader(std::string name, std::string value);
|
||||||
|
|
||||||
void MakeDELETE(const std::string &path, const std::function<void(http::response_type r)> &cb);
|
void MakeDELETE(const std::string &path, const std::function<void(http::response_type r)> &cb);
|
||||||
void MakeGET(const std::string &path, const std::function<void(http::response_type r)> &cb);
|
void MakeGET(const std::string &path, const std::function<void(http::response_type r)> &cb);
|
||||||
void MakePATCH(const std::string &path, const std::string &payload, const std::function<void(http::response_type r)> &cb);
|
void MakePATCH(const std::string &path, const std::string &payload, const std::function<void(http::response_type r)> &cb);
|
||||||
@ -24,6 +26,8 @@ public:
|
|||||||
void MakePUT(const std::string &path, const std::string &payload, const std::function<void(http::response_type r)> &cb);
|
void MakePUT(const std::string &path, const std::string &payload, const std::function<void(http::response_type r)> &cb);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
void AddHeaders(http::request &r);
|
||||||
|
|
||||||
void OnResponse(const http::response_type &r, const std::function<void(http::response_type r)> &cb);
|
void OnResponse(const http::response_type &r, const std::function<void(http::response_type r)> &cb);
|
||||||
void CleanupFutures();
|
void CleanupFutures();
|
||||||
|
|
||||||
@ -36,4 +40,5 @@ private:
|
|||||||
std::string m_api_base;
|
std::string m_api_base;
|
||||||
std::string m_authorization;
|
std::string m_authorization;
|
||||||
std::string m_agent;
|
std::string m_agent;
|
||||||
|
std::unordered_map<std::string, std::string> m_headers;
|
||||||
};
|
};
|
||||||
|
@ -262,6 +262,7 @@ void to_json(nlohmann::json &j, const ClientStateProperties &m) {
|
|||||||
j["highest_last_message_id"] = m.HighestLastMessageID;
|
j["highest_last_message_id"] = m.HighestLastMessageID;
|
||||||
j["read_state_version"] = m.ReadStateVersion;
|
j["read_state_version"] = m.ReadStateVersion;
|
||||||
j["user_guild_settings_version"] = m.UserGuildSettingsVersion;
|
j["user_guild_settings_version"] = m.UserGuildSettingsVersion;
|
||||||
|
j["user_settings_version"] = m.UserSettingsVersion;
|
||||||
}
|
}
|
||||||
|
|
||||||
void to_json(nlohmann::json &j, const IdentifyMessage &m) {
|
void to_json(nlohmann::json &j, const IdentifyMessage &m) {
|
||||||
|
@ -382,6 +382,7 @@ struct ClientStateProperties {
|
|||||||
std::string HighestLastMessageID = "0";
|
std::string HighestLastMessageID = "0";
|
||||||
int ReadStateVersion = 0;
|
int ReadStateVersion = 0;
|
||||||
int UserGuildSettingsVersion = -1;
|
int UserGuildSettingsVersion = -1;
|
||||||
|
int UserSettingsVersion = -1;
|
||||||
|
|
||||||
friend void to_json(nlohmann::json &j, const ClientStateProperties &m);
|
friend void to_json(nlohmann::json &j, const ClientStateProperties &m);
|
||||||
};
|
};
|
||||||
|
@ -57,6 +57,10 @@ void request::set_user_agent(const std::string &data) {
|
|||||||
curl_easy_setopt(m_curl, CURLOPT_USERAGENT, data.c_str());
|
curl_easy_setopt(m_curl, CURLOPT_USERAGENT, data.c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
CURL *request::get_curl() {
|
||||||
|
return m_curl;
|
||||||
|
}
|
||||||
|
|
||||||
response request::execute() {
|
response request::execute() {
|
||||||
if (m_curl == nullptr) {
|
if (m_curl == nullptr) {
|
||||||
auto response = detail::make_response(m_url, EStatusCode::ClientErrorCURLInit);
|
auto response = detail::make_response(m_url, EStatusCode::ClientErrorCURLInit);
|
||||||
|
@ -108,6 +108,8 @@ struct request {
|
|||||||
|
|
||||||
response execute();
|
response execute();
|
||||||
|
|
||||||
|
CURL *get_curl();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void prepare();
|
void prepare();
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user