Skip to content

Commit

Permalink
Add config module and refactor code
Browse files Browse the repository at this point in the history
  • Loading branch information
jdeokkim committed Jul 26, 2022
1 parent 513ccda commit 94c8fee
Show file tree
Hide file tree
Showing 9 changed files with 333 additions and 174 deletions.
1 change: 1 addition & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ INCLUDE_PATH += $(SOURCE_PATH)/external

SOURCES := \
$(SOURCE_PATH)/bot.c \
$(SOURCE_PATH)/config.c \
$(SOURCE_PATH)/info.c \
$(SOURCE_PATH)/json.c \
$(SOURCE_PATH)/krdict.c \
Expand Down
82 changes: 52 additions & 30 deletions include/saerom.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@
/* | 매크로 정의... | */

#define APPLICATION_NAME "jdeokkim/saerom"
#define APPLICATION_VERSION "v0.2.0"
#define APPLICATION_VERSION "v0.2.1-dev"
#define APPLICATION_DESCRIPTION "A C99 Discord bot for Korean learning servers."
#define APPLICATION_PROJECT_URL "https://github.com/jdeokkim/saerom"

Expand All @@ -39,18 +39,6 @@

/* | 자료형 정의... | */

/* Discord 봇의 환경 설정을 나타내는 구조체. */
struct sr_config {
unsigned char flags;
struct {
char api_key[MAX_STRING_SIZE];
} krdict;
struct {
char client_id[MAX_STRING_SIZE];
char client_secret[MAX_STRING_SIZE];
} papago;
};

/* Discord 봇의 명령어를 나타내는 구조체. */
struct sr_command {
const char *name;
Expand All @@ -62,35 +50,34 @@ struct sr_command {
);
};

/* Discord 봇의 환경 설정 플래그를 나타내는 열거형. */
enum sr_flag {
SR_FLAG_KRDICT = (1 << 0),
SR_FLAG_PAPAGO = (1 << 1)
/* Discord 봇의 모듈 플래그를 나타내는 열거형. */
enum sr_module_flag {
SR_MODULE_KRDICT = (1 << 0),
SR_MODULE_PAPAGO = (1 << 1)
};

/* Discord 봇의 상태 플래그를 나타내는 열거형. */
enum sr_status_flag {
SR_STATUS_RUNNING = (1 << 0)
};

/* | `bot` 모듈 함수... | */

/* Discord 봇을 초기화한다. */
void init_bot(int argc, char *argv[]);
void sr_bot_init(int argc, char *argv[]);

/* Discord 봇에 할당된 메모리를 해제한다. */
void sr_bot_cleanup(void);

/* Discord 봇을 실행한다. */
void run_bot(void);
void sr_bot_run(void);

/* Discord 봇에 할당된 메모리를 해제한다. */
void deinit_bot(void);
/* Discord 봇의 클라이언트 객체를 반환한다. */
struct discord *get_client(void);

/* `CURLV` 인터페이스를 반환한다. */
void *get_curlv(void);

/* Discord 봇의 애플리케이션 고유 번호를 반환한다. */
u64snowflake get_application_id(void);

/* Discord 봇 관리자의 고유 번호를 반환한다. */
u64snowflake get_owner_id(void);

/* Discord 봇의 환경 설정 정보를 반환한다. */
struct sr_config *get_sr_config(void);

/* Discord 봇의 명령어 목록을 반환한다. */
const struct sr_command *get_commands(int *len);

Expand All @@ -103,6 +90,41 @@ double get_ram_usage(void);
/* Discord 봇의 작동 시간 (단위: 밀리초)을 반환한다. */
uint64_t get_uptime(void);

/* | `config` 모듈 함수... | */

/* Discord 봇의 환경 설정을 초기화한다. */
void sr_config_init(void);

/* Discord 봇의 환경 설정에 할당된 메모리를 해제한다. */
void sr_config_cleanup(void);

/* Discord 봇의 애플리케이션 ID를 반환한다. */
u64snowflake sr_config_get_application_id(void);

/* Discord 봇의 애플리케이션 소유자 ID를 반환한다. */
u64snowflake sr_config_get_application_owner_id(void);

/* Discord 봇의 모듈 플래그 데이터를 반환한다. */
u64bitmask sr_config_get_module_flags(void);

/* Discord 봇의 상태 플래그 데이터를 반환한다. */
u64bitmask sr_config_get_status_flags(void);

/* Discord 봇의 국립국어원 한국어기초사전 API 키를 반환한다. */
const char *sr_config_get_krdict_api_key(void);

/* Discord 봇의 NAVER™ 파파고 NMT API 클라이언트 ID를 반환한다. */
const char *sr_config_get_papago_client_id(void);

/* Discord 봇의 NAVER™ 파파고 NMT API 클라이언트 시크릿을 반환한다. */
const char *sr_config_get_papago_client_secret(void);

/* Discord 봇의 모듈 플래그 데이터를 `flags`로 설정한다. */
void sr_config_set_module_flags(u64bitmask flags);

/* Discord 봇의 상태 플래그 데이터를 `flags`로 설정한다. */
void sr_config_set_status_flags(u64bitmask flags);

/* | `info` 모듈 함수... | */

/* `/info` 명령어를 생성한다. */
Expand Down
146 changes: 43 additions & 103 deletions src/bot.c
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@
along with this program. If not, see <https://www.gnu.org/licenses/>.
*/

#include <stdlib.h>
#include <string.h>
#include <sigar.h>

Expand Down Expand Up @@ -73,21 +72,12 @@ static sigar_t *sigar;
/* Discord 봇의 클라이언트 객체. */
static struct discord *client;

/* Discord 봇의 환경 설정. */
static struct sr_config config;

/* Discord 봇의 애플리케이션 고유 번호. */
static u64snowflake application_id;

/* Discord 봇 관리자의 고유 번호. */
static u64snowflake owner_id;

/* Discord 봇의 시작 시간. */
static uint64_t timestamp;

/* | `bot` 모듈 함수... | */

/* Discord 봇이 실행 중일 때 주기적으로 호출된다. */
/* Discord 봇이 대기 중일 때 주기적으로 호출된다. */
static void on_idle(struct discord *client);

/* Discord 봇의 클라이언트가 준비되었을 때 호출된다. */
Expand All @@ -103,10 +93,10 @@ static void on_interaction_create(
);

/* Discord 봇의 추가 정보를 초기화한다. */
static void sr_config_init(void);
static void sr_core_init(void);

/* Discord 봇의 추가 정보에 할당된 메모리를 해제한다. */
static void sr_config_cleanup(void);
static void sr_core_cleanup(void);

/* 표준 입력 스트림에서 명령어를 입력받는 스레드를 생성한다. */
static void sr_input_reader_init(void);
Expand All @@ -118,13 +108,12 @@ static void create_commands(struct discord *client);
static void release_commands(struct discord *client);

/* Discord 봇을 초기화한다. */
void init_bot(int argc, char *argv[]) {
void sr_bot_init(int argc, char *argv[]) {
ccord_global_init();

client = discord_config_init((argc > 1) ? argv[1] : CONFIG_PATH);

sr_config_init();
sr_input_reader_init();
sr_core_init();

discord_set_on_idle(client, on_idle);
discord_set_on_ready(client, on_ready);
Expand All @@ -133,16 +122,11 @@ void init_bot(int argc, char *argv[]) {
create_commands(client);
}

/* Discord 봇을 실행한다. */
void run_bot(void) {
discord_run(client);
}

/* Discord 봇에 할당된 메모리를 해제한다. */
void deinit_bot(void) {
void sr_bot_cleanup(void) {
release_commands(client);

sr_config_cleanup();
sr_core_cleanup();

log_info("[SAEROM] Cleaning up global resources");

Expand All @@ -151,24 +135,19 @@ void deinit_bot(void) {
ccord_global_cleanup();
}

/* `CURLV` 인터페이스를 반환한다. */
void *get_curlv(void) {
return (void *) curlv;
}

/* Discord 봇의 애플리케이션 고유 번호를 반환한다. */
u64snowflake get_application_id(void) {
return application_id;
/* Discord 봇을 실행한다. */
void sr_bot_run(void) {
discord_run(client);
}

/* Discord 봇 관리자의 고유 번호를 반환한다. */
u64snowflake get_owner_id(void) {
return owner_id;
/* Discord 봇의 클라이언트 객체를 반환한다. */
struct discord *get_client(void) {
return client;
}

/* Discord 봇의 환경 설정 정보를 반환한다. */
struct sr_config *get_sr_config(void) {
return &config;
/* `CURLV` 인터페이스를 반환한다. */
void *get_curlv(void) {
return (void *) curlv;
}

/* Discord 봇의 명령어 목록을 반환한다. */
Expand Down Expand Up @@ -211,8 +190,18 @@ uint64_t get_uptime(void) {
return discord_timestamp(client) - timestamp;
}

/* Discord 봇이 실행 중일 때 주기적으로 호출된다. */
/* Discord 봇이 대기 중일 때 주기적으로 호출된다. */
static void on_idle(struct discord *client) {
if (!(sr_config_get_status_flags() & SR_STATUS_RUNNING)) {
sr_config_set_status_flags(0);

log_info("[SAEROM] Shutting down the bot");

sr_bot_cleanup();

exit(EXIT_SUCCESS);
}

curlv_read_requests(curlv);

// CPU 사용량 최적화
Expand Down Expand Up @@ -318,77 +307,24 @@ static void on_interaction_create(
}
}

/* (Discord 봇의 추가 정보를 초기화한다.) */
static void _sr_config_init(
struct discord *client,
struct discord_response *resp,
const struct discord_application *ret
) {
owner_id = ret->owner->id;
}

/* Discord 봇의 추가 정보를 초기화한다. */
static void sr_config_init(void) {
static void sr_core_init(void) {
if (client == NULL) return;

curlv = curlv_init();

sigar_open(&sigar);

struct ccord_szbuf_readonly field = discord_config_get_field(
client, (char *[2]) { "discord", "application_id" }, 2
);

char buffer[MAX_STRING_SIZE];

strncpy(buffer, field.start, field.size);

application_id = strtoull(buffer, NULL, 10);

field = discord_config_get_field(
client, (char *[3]) { "saerom", "krdict", "enable" }, 3
);

if (strncmp("true", field.start, field.size) == 0) {
config.flags |= SR_FLAG_KRDICT;

field = discord_config_get_field(
client, (char *[3]) { "saerom", "krdict", "api_key" }, 3
);

strncpy(config.krdict.api_key, field.start, field.size);
}

field = discord_config_get_field(
client, (char *[3]) { "saerom", "papago", "enable" }, 3
);

if (strncmp("true", field.start, field.size) == 0) {
config.flags |= SR_FLAG_PAPAGO;

field = discord_config_get_field(
client, (char *[3]) { "saerom", "papago", "client_id" }, 3
);

strncpy(config.papago.client_id, field.start, field.size);

field = discord_config_get_field(
client, (char *[3]) { "saerom", "papago", "client_secret" }, 3
);

strncpy(config.papago.client_secret, field.start, field.size);
}

discord_get_current_bot_application_information(
client,
&(struct discord_ret_application) {
.done = _sr_config_init
}
);
sr_config_init();
sr_input_reader_init();
}

/* Discord 봇의 추가 정보에 할당된 메모리를 해제한다. */
static void sr_config_cleanup(void) {
static void sr_core_cleanup(void) {
if (client == NULL) return;

sr_config_cleanup();

curlv_cleanup(curlv);

sigar_close(sigar);
Expand All @@ -412,14 +348,16 @@ static void sr_input_reader_init(void) {
static void create_commands(struct discord *client) {
const int commands_len = sizeof(commands) / sizeof(*commands);

const u64bitmask module_flags = sr_config_get_module_flags();

log_info("[SAEROM] Creating %d global application command(s)", commands_len);

for (int i = 0; i < commands_len; i++) {
if (streq(commands[i].name, "krd")
&& !(config.flags & SR_FLAG_KRDICT)) continue;
&& !(module_flags & SR_MODULE_KRDICT)) continue;

if (streq(commands[i].name, "ppg")
&& !(config.flags & SR_FLAG_PAPAGO)) continue;
&& !(module_flags & SR_MODULE_PAPAGO)) continue;

if (commands[i].on_create != NULL)
commands[i].on_create(client);
Expand All @@ -430,14 +368,16 @@ static void create_commands(struct discord *client) {
static void release_commands(struct discord *client) {
const int commands_len = sizeof(commands) / sizeof(*commands);

const u64bitmask module_flags = sr_config_get_module_flags();

log_info("[SAEROM] Releasing %d global application command(s)", commands_len);

for (int i = 0; i < commands_len; i++) {
if (streq(commands[i].name, "krd")
&& !(config.flags & SR_FLAG_KRDICT)) continue;
&& !(module_flags & SR_MODULE_KRDICT)) continue;

if (streq(commands[i].name, "ppg")
&& !(config.flags & SR_FLAG_PAPAGO)) continue;
&& !(module_flags & SR_MODULE_PAPAGO)) continue;

if (commands[i].on_release != NULL)
commands[i].on_release(client);
Expand Down
Loading

0 comments on commit 94c8fee

Please sign in to comment.