Chat global
Chat
Loading the chat ...
Notificações via Discord
Tutoriais
4
Posts
4
Usuários
5
Reactions
46
Visualizações
Topic starter
Salvee
Esse é um sistema que desenvolvi há bastante tempo. Acabei deixando de lado, mas revisitando achei interessante — e acredito que possa ser útil para alguém.
O sistema envia notificações em um canal do Discord por meio de Webhooks.
Atualmente está configurado para alertas de Boss, Drops e Kills, mas é fácil adaptar, adicionar novas funções e melhorar o que já existe.
Arquivos principais:
Spoiler
AlertaDiscord.cpp
#include "alertadiscord.h"
#include <iostream>
#include <thread>
#include <chrono>
#include <nlohmann/json.hpp>
#include <string>
#include <curl/curl.h>
#include <sstream>
DiscordAlertManager::DiscordAlertManager(size_t numThreads, std::chrono::milliseconds delay)
: stop(false), sendDelay(delay) {
for (size_t i = 0; i < numThreads; ++i) {
threads.emplace_back(&DiscordAlertManager::worker, this);
}
}
DiscordAlertManager::~DiscordAlertManager() {
{
std::unique_lock<std::mutex> lock(queueMutex);
stop = true;
}
cv.notify_all();
for (std::thread& thread : threads) {
if (thread.joinable()) {
thread.join();
}
}
}
void DiscordAlertManager::sendDiscordAlert(const std::string& webhook_url, const std::string& message) {
if (!validateWebhookUrl(webhook_url)) {
std::cerr << "[Discord] URL de webhook invalida: " << webhook_url << std::endl;
return;
}
{
std::lock_guard<std::mutex> lock(queueMutex);
taskQueue.emplace(webhook_url, message);
}
cv.notify_one();
}
void DiscordAlertManager::worker() {
while (true) {
std::tuple<std::string, std::string> task;
{
std::unique_lock<std::mutex> lock(queueMutex);
cv.wait(lock, [this] { return stop || !taskQueue.empty(); });
if (stop && taskQueue.empty()) {
return;
}
task = std::move(taskQueue.front());
taskQueue.pop();
}
alertadiscord_impl(std::get<0>(task), std::get<1>(task));
std::this_thread::sleep_for(sendDelay);
}
}
// Callback para capturar a resposta do Discord
static size_t WriteCallback(void* contents, size_t size, size_t nmemb, std::string* response) {
size_t totalSize = size * nmemb;
response->append((char*)contents, totalSize);
return totalSize;
}
bool DiscordAlertManager::validateWebhookUrl(const std::string& url) {
// Valida se a URL é um webhook do Discord
return url.find("https://discord.com/api/webhooks/") == 0 ||
url.find("https://discordapp.com/api/webhooks/") == 0;
}
void DiscordAlertManager::alertadiscord_impl(const std::string& webhook_url, const std::string& message) {
using json = nlohmann::json;
CURL* curl = curl_easy_init();
if (!curl) {
std::cerr << "[Discord] Falha ao inicializar cURL" << std::endl;
return;
}
// Cria o JSON usando a biblioteca nlohmann (escape automático)
json payload = {
{"content", nullptr},
{"embeds", json::array({
{
{"description", message},
{"color", 4062976}
}
})},
{"attachments", json::array()}
};
std::string json_data = payload.dump();
std::string response;
// Configura headers
struct curl_slist* headers = nullptr;
headers = curl_slist_append(headers, "Content-Type: application/json");
// Configura opções do cURL
curl_easy_setopt(curl, CURLOPT_URL, webhook_url.c_str());
curl_easy_setopt(curl, CURLOPT_POST, 1L);
curl_easy_setopt(curl, CURLOPT_POSTFIELDS, json_data.c_str());
curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers);
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, WriteCallback);
curl_easy_setopt(curl, CURLOPT_WRITEDATA, &response);
curl_easy_setopt(curl, CURLOPT_TIMEOUT, 10L); // Timeout de 10 segundos
curl_easy_setopt(curl, CURLOPT_CONNECTTIMEOUT, 5L); // Timeout de conexão de 5 segundos
// Executa a requisição
CURLcode res = curl_easy_perform(curl);
if (res != CURLE_OK) {
std::cerr << "[Discord] Erro ao enviar: " << curl_easy_strerror(res) << std::endl;
} else {
long http_code = 0;
curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &http_code);
if (http_code >= 200 && http_code < 300) {
std::cout << "[Discord] Mensagem enviada com sucesso (HTTP " << http_code << ")" << std::endl;
} else {
std::cerr << "[Discord] Erro HTTP " << http_code << ": " << response << std::endl;
}
}
// Limpeza
curl_slist_free_all(headers);
curl_easy_cleanup(curl);
}
Spoiler
AlertaDiscord.h
#ifndef ALERTADISCORD_H
#define ALERTADISCORD_H
#include <string>
#include <queue>
#include <mutex>
#include <condition_variable>
#include <thread>
#include <tuple>
#include <vector>
#include <chrono>
class DiscordAlertManager {
public:
static DiscordAlertManager& getInstance(size_t numThreads = 5, std::chrono::milliseconds delay = std::chrono::milliseconds(5000)) {
static DiscordAlertManager instance(numThreads, delay);
return instance;
}
DiscordAlertManager(const DiscordAlertManager&) = delete;
DiscordAlertManager& operator=(const DiscordAlertManager&) = delete;
void sendDiscordAlert(const std::string& webhook_url, const std::string& message);
~DiscordAlertManager();
private:
DiscordAlertManager(size_t numThreads, std::chrono::milliseconds delay);
void worker();
void alertadiscord_impl(const std::string& webhook_url, const std::string& message);
bool validateWebhookUrl(const std::string& url);
std::queue<std::tuple<std::string, std::string>> taskQueue;
std::mutex queueMutex;
std::condition_variable cv;
bool stop;
std::vector<std::thread> threads;
std::chrono::milliseconds sendDelay;
};
#endif // ALERTADISCORD_H
No server.ini, adicione as WebHooks:
Spoiler
Server.ini
[DiscordAlerta] WebhookDrops= https://discord.com/api/webhooks/123456789/SuaWebhookKeyAqui WebhookPVP= https://discord.com/api/webhooks/987654321/OutraWebhookKeyAqui WebhookBOSS= https://discord.com/api/webhooks/555555555/MaisUmaWebhookKey
No fileread.cpp, faça a chamada para carregar e salvar as WebHooks:
Spoiler
fileread.cpp
std::string WebhookURLDrops;
std::string WebhookURLPVP;
std::string WebhookURLBOSS;
{
char szBuf[512] = { 0 };
LeIniStr("DiscordAlerta", "WebhookDrops", "Server\\Config\\Server.ini", szBuf);
WebhookURLDrops = szBuf;
}
{
char szBuf[512] = { 0 };
LeIniStr("DiscordAlerta", "WebhookPVP", "Server\\Config\\Server.ini", szBuf);
WebhookURLPVP = szBuf;
}
{
char szBuf[512] = { 0 };
LeIniStr("DiscordAlerta", "WebhookBOSS", "Server\\Config\\Server.ini", szBuf);
WebhookURLBOSS = szBuf;
}
Exemplos de uso
Exemplo no OnServer para notificar sobre Boss:
Spoiler
Onsever.cpp
#include "..//alertadiscord.h"
extern std::string WebhookURLDrops;
extern std::string WebhookURLPVP;
extern std::string WebhookURLBOSS;
// Boss Alert
char mensagemBOSS[70] = { 0 };
wsprintf(mensagemBOSS, " Alerta Boss> %s nasce em 5 minutos no mapa %s!",
lpBossMonster->MasterMonster->szName,
MapasEventos[lpStgArea->lpField->FieldCode][1]);
DiscordAlertManager::getInstance().sendDiscordAlert(WebhookURLBOSS, mensagemBOSS);
Exemplo para notificar sobre Drop:
Spoiler
Alerta.cpp
#include "..//alertadiscord.h" extern std::string WebhookURLDrops; extern std::string WebhookURLPVP; extern std::string WebhookURLBOSS; wsprintf(mensagem, " [ %s ] Dropou [ %s ]. ", PlayerName, sLog.ItemName); DiscordAlertManager::getInstance().sendDiscordAlert(WebhookURLDrops, mensagem);
show! 😉
Apenas criando um legado 😊
Postado : 04/12/2025 11:49 am
Top demais!
Postado : 04/12/2025 1:04 pm
eu uso um que avisa , "coisas importantes" direto no telegram.
#DEFINE -> | |
The Witcher
Postado : 04/12/2025 1:19 pm
Forum Information
- 20 Fóruns
- 253 Tópicos
- 1,448 Posts
- 2 Online
- 267 Membros
Novos novos membros: dreeezao
Post Recente: Eventos Mob Automáticos
Ícones do Fórum:
Fórum não contém posts não lidos
Fórum contém posts não lidos
Ícones dos Tópicos:
Não Respondido
Respondido
Ativo
Em Alta
Fixar
Reprovado
Resolvido
Privado
Fechado

