중간저장(다시 큐 방식으로 돌아가되, 실시간 스트리밍 방식으로 비동기 처리를 구현할 것임)

This commit is contained in:
2024-10-19 01:12:19 +09:00
parent c276065a65
commit b4476c68d7
38 changed files with 297 additions and 1106 deletions

View File

@@ -0,0 +1,40 @@
#pragma once
#ifndef _ASYNCDOWNLOADMANAGER_HPP_
#define _ASYNCDOWNLOADMANAGER_HPP_
#include <queue>
#include <string>
#include <thread>
#include <condition_variable>
#include <curl/curl.h>
#define WORKER_COUNT 5
namespace bumbleBee {
class AsyncDownloadManager {
public:
static void enqueue(std::string query) {
static AsyncDownloadManager dl;
std::thread th(&bumbleBee::AsyncDownloadManager::enqueueAsyncDL, &dl, query);
th.detach();
}
private:
AsyncDownloadManager(){
for (int i=0; i<WORKER_COUNT; i++) {
std::thread th(&bumbleBee::AsyncDownloadManager::downloadWorker, &(*this));
th.detach();
}
}
~AsyncDownloadManager(){}
AsyncDownloadManager(const AsyncDownloadManager& ref) = delete;
AsyncDownloadManager& operator=(const AsyncDownloadManager& ref) = delete;
void enqueueAsyncDL(std::string query);
void downloadWorker();
std::queue<std::string> downloadQueue;
std::condition_variable dlQueueCondition;
std::mutex dlQueueMutex;
};
}
#endif

View File

@@ -1,27 +0,0 @@
#pragma once
#include <Commands/CommandType.hpp>
#include <dpp/dpp.h>
#include <memory>
#include <mariadb/conncpp.hpp>
class IBot {
public:
IBot(std::string token, int clusterCount = 0);
virtual void start();
virtual void onCommand(const dpp::slashcommand_t &event);
virtual void onReady(const dpp::ready_t &event);
std::shared_ptr<dpp::cluster> botCluster;
std::vector<std::shared_ptr<commands::ICommand>> commandsArray;
std::function<void(const dpp::log_t&)> logger() {
return [&](const dpp::log_t& event){
if (event.severity >= dpp::ll_error)
std::cerr << "[" << dpp::utility::current_date_time() << "] " << dpp::utility::loglevel(event.severity) << ": " << event.message << std::endl;
else if (event.severity - logLevel >= 0)
std::clog << "[" << dpp::utility::current_date_time() << "] " << dpp::utility::loglevel(event.severity) << ": " << event.message << std::endl;
};
};
dpp::loglevel logLevel = dpp::ll_debug;
};

71
include/BumbleBee.hpp Normal file
View File

@@ -0,0 +1,71 @@
#pragma once
#ifndef _BUMBLEBEE_HPP_
#define _BUMBLEBEE_HPP_
#include <dpp/dpp.h>
#include <dpp/nlohmann/json.hpp>
#include <boost/asio.hpp>
#include <memory>
#include <BumbleBeeCommand.hpp>
#include <MusicQueue.hpp>
#include <mariadb/conncpp.hpp>
namespace bumbleBee {
/**
* @file BumbleBee.hpp
* @brief 메인 봇 클래스
**/
class BumbleBee {
public:
/**
* @fn BumbleBee(nlohmann::json settings)
* @brief 생성자
* @param settings 설정 json
**/
BumbleBee(nlohmann::json settings);
/**
* @fn ~BumbleBee()
* @brief 파괴자
* @details BumbleBee의 모든 Property를 책임지고 파괴합니다
**/
~BumbleBee();
/**
* @fn void start()
* @brief 봇 시작
**/
void start();
/**
* @fn bool addCommand(commands::ICommand cmd)
* @brief ICommand 인터페이스에 맞는 커맨드를 추가
* @warning 이 메소드는 start()메소드가 호출되기 전에 호출되어야 함
**/
bool addCommand(commands::ICommand cmd);
/**
* @fn void on_slashcommand(const dpp::slashcommand_t& event)
* @brief slashcommand 이벤트 인지시 콜백되는 함수
* @param event
**/
void on_slashcommand(const dpp::slashcommand_t& event);
/**
* @fn void on_ready(const dpp::ready_t &event)
* @brief ready 이벤트 인지시 콜백되는 함수
* @param event
**/
void on_ready(const dpp::ready_t &event);
private:
/// @brief DPP 기본 클러스터 객체
std::unique_ptr<dpp::cluster> cluster;
/// @brief db 드라이버
sql::Driver* dbDriver;
/// @brief db 접속 URL
std::shared_ptr<sql::SQLString> dbURL;
/// @brief db 접속 속성
std::shared_ptr<sql::Properties> dbProperties;
/// @brief Command 목록
std::vector<commands::ICommand> commands;
/// @brief 음악 큐
std::shared_ptr<MusicQueue> queue;
};
}
#endif

View File

@@ -0,0 +1,91 @@
#pragma once
#ifndef _BUMBLEBEECOMMAND_HPP_
#define _BUMBLEBEECOMMAND_HPP_
#include <dpp/dpp.h>
#include <MusicQueue.hpp>
namespace bumbleBee::commands {
class ICommand {
public:
/// @brief 기본 생성자
/// @param botID 명령어 등록을 위한 봇 아이디
/// @param queue 음악이 저장되어 있는 큐
ICommand(dpp::snowflake botID, std::weak_ptr<MusicQueue> queue) {
this->botID = botID;
this->queue = queue;
}
/// @brief 명령어 호출 시에 콜백되는 함수
/// @param event
virtual void operator()(const dpp::slashcommand_t &event){};
/// @brief 봇 명령어들의 이름과 별명들을 저장하는 벡터
std::vector<dpp::slashcommand> nameAndAliases;
private:
/// @brief 봇 ID
dpp::snowflake botID;
/// @brief 음악 큐에 대한 약한 포인터
std::weak_ptr<MusicQueue> queue;
};
}
/**
* @fn _DECLARE_BUMBLEBEE_COMMAND_one_PARAM_one_ALIAS(name, alias, description, option_name, option_desc)
* @brief 명령어 인자가 없는 명령어의 boilerplate 대체 매크로
* @param name 명령어 이름 및 클래스명
* @param alias 명령어 별명
* @param description 명령어 설명
**/
#define _DECLARE_BUMBLEBEE_COMMAND_one_ALIAS(name, alias, description) \
namespace bumbleBee::commands { \
class name : public ICommand { \
public: \
name (dpp::snowflake botID, std::weak_ptr<MusicQueue> q) \
: ICommand(botID, q) { \
dpp::slashcommand command = dpp::slashcommand(#name, description, botID); \
dpp::slashcommand aliasCommand = dpp::slashcommand(alias, description, botID); \
nameAndAliases.push_back(command); \
nameAndAliases.push_back(aliasCommand); \
} \
virtual void operator()(const dpp::slashcommand_t &event) override; \
}; \
}
/**
* @fn _DECLARE_BUMBLEBEE_COMMAND_one_PARAM_one_ALIAS(name, alias, description, option_name, option_desc)
* @brief 명령어 인자를 하나 갖는 명령어의 boilerplate 대체 매크로
* @param name 명령어 이름 및 클래스명
* @param alias 명령어 별명
* @param description 명령어 설명
* @param option_name 명령어 인자 이름
* @param option_desc 명령어 인자 설명
**/
#define _DECLARE_BUMBLEBEE_COMMAND_one_PARAM_one_ALIAS(name, alias, description, option_name, option_desc) \
namespace bumbleBee::commands { \
class name : public ICommand { \
public: \
name (dpp::snowflake botID, std::weak_ptr<MusicQueue> q) \
: ICommand(botID, q) { \
dpp::slashcommand command = dpp::slashcommand(#name, description, botID); \
dpp::slashcommand aliasCommand = dpp::slashcommand(alias, description, botID); \
command.add_option( \
dpp::command_option(dpp::co_string, option_name, option_desc, botID) \
); \
aliasCommand.add_option( \
dpp::command_option(dpp::co_string, option_name, option_desc, botID) \
); \
nameAndAliases.push_back(command); \
nameAndAliases.push_back(aliasCommand); \
} \
virtual void operator()(const dpp::slashcommand_t &event) override; \
}; \
}
_DECLARE_BUMBLEBEE_COMMAND_one_PARAM_one_ALIAS(Delete, "d", "큐의 해당하는 번호의 노래를 지웁니다", "pos", "큐 번호")
_DECLARE_BUMBLEBEE_COMMAND_one_ALIAS(Leave, "l", "음성 채팅방을 떠납니다")
_DECLARE_BUMBLEBEE_COMMAND_one_PARAM_one_ALIAS(Play, "p", "노래 재생", "query", "링크 또는 검색어")
_DECLARE_BUMBLEBEE_COMMAND_one_ALIAS(Queue, "q", "노래 예약 큐를 출력합니다")
_DECLARE_BUMBLEBEE_COMMAND_one_ALIAS(Repeat, "r", "반복을 켜거나 끕니다")
_DECLARE_BUMBLEBEE_COMMAND_one_ALIAS(Skip, "s", "현재 재생중인 곡을 스킵합니다")
#endif

View File

@@ -1,38 +0,0 @@
#pragma once
#include <string>
#include <Bot.hpp>
#include <dpp/dpp.h>
#include <memory>
#include <unordered_map>
#include <FQueueElement.hpp>
class BumbleCeepp : public IBot {
public:
BumbleCeepp(std::string token, std::string DBURL, std::string DBID, std::string DBPassword, int clusterCount = 0);
~BumbleCeepp();
void enqueueMusic(FQueueElement item, dpp::discord_voice_client* vc);
std::shared_ptr<dpp::embed> findEmbed(std::string musicID);
bool insertDB(
std::string webpage_url,
std::string title,
std::string uploader,
std::string id,
std::string thumbnail,
time_t duration);
std::shared_ptr<dpp::embed> makeEmbed(
std::string webpage_url,
std::string title,
std::string uploader,
std::string id,
std::string thumbnail,
time_t duration);
bool repeat;
std::string nowPlayingMusic;
private:
//<guild_id, queueMutex> 쌍임.
std::unordered_map<dpp::snowflake, std::mutex> enqueuingMutexMap;
sql::Connection* conn;
};

View File

@@ -1,22 +0,0 @@
#pragma once
#include <dpp/dpp.h>
#include <vector>
#include <list>
class BumbleCeepp;
namespace commands {
class ICommand {
public:
ICommand(dpp::snowflake botID, BumbleCeepp* Bot)
{
this->botID = botID;
this->Bot = Bot;
}
virtual void operator()(const dpp::slashcommand_t &event) = 0;
std::vector<dpp::slashcommand> commandObjectVector;
dpp::snowflake botID;
BumbleCeepp* Bot;
};
}

View File

@@ -1,7 +0,0 @@
#pragma once
#include <Commands/Play.hpp>
#include <Commands/Repeat.hpp>
#include <Commands/Queue.hpp>
#include <Commands/Skip.hpp>
#include <Commands/Leave.hpp>
#include <Commands/Delete.hpp>

View File

@@ -1,13 +0,0 @@
#pragma once
#include <Commands/CommandType.hpp>
#include <BumbleCeepp.hpp>
#include <memory>
namespace commands {
class Delete : public ICommand {
public:
Delete(dpp::snowflake botID, BumbleCeepp* Bot);
void operator()(const dpp::slashcommand_t& event);
};
}

View File

@@ -1,13 +0,0 @@
#pragma once
#include <Commands/CommandType.hpp>
#include <BumbleCeepp.hpp>
#include <memory>
namespace commands {
class Leave : public ICommand {
public:
Leave(dpp::snowflake botID, BumbleCeepp* Bot);
void operator()(const dpp::slashcommand_t& event);
};
}

View File

@@ -1,14 +0,0 @@
#pragma once
#include <Commands/CommandType.hpp>
#include <BumbleCeepp.hpp>
#include <memory>
namespace commands {
class Play : public ICommand {
public:
Play(dpp::snowflake botID, BumbleCeepp* Bot);
void operator()(const dpp::slashcommand_t& event);
void on_DLCompleted(std::string musicID, dpp::embed embed, const dpp::slashcommand_t& event);
};
}

View File

@@ -1,13 +0,0 @@
#pragma once
#include <Commands/CommandType.hpp>
#include <BumbleCeepp.hpp>
#include <memory>
namespace commands {
class Queue : public ICommand {
public:
Queue(dpp::snowflake botID, BumbleCeepp* Bot);
void operator()(const dpp::slashcommand_t& event);
};
}

View File

@@ -1,13 +0,0 @@
#pragma once
#include <Commands/CommandType.hpp>
#include <BumbleCeepp.hpp>
#include <memory>
namespace commands {
class Repeat : public ICommand {
public:
Repeat(dpp::snowflake botID, BumbleCeepp* Bot);
void operator()(const dpp::slashcommand_t& event);
};
}

View File

@@ -1,13 +0,0 @@
#pragma once
#include <Commands/CommandType.hpp>
#include <BumbleCeepp.hpp>
#include <memory>
namespace commands {
class Skip : public ICommand {
public:
Skip(dpp::snowflake botID, BumbleCeepp* Bot);
void operator()(const dpp::slashcommand_t& event);
};
}

View File

@@ -1,9 +0,0 @@
#pragma once
#include <string>
#include <dpp/dpp.h>
struct FQueueElement {
std::string ID;
dpp::embed embed;
bool skip = false;
};

11
include/MusicQueue.hpp Normal file
View File

@@ -0,0 +1,11 @@
#pragma once
#ifndef _MUSICQUEUE_HPP_
#define _MUSICQUEUE_HPP_
namespace bumbleBee {
class MusicQueue {
public:
};
}
#endif