diff --git a/Makefile b/Makefile
index 88c9e8c..19d6ee9 100644
--- a/Makefile
+++ b/Makefile
@@ -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 \
diff --git a/include/saerom.h b/include/saerom.h
index 49edff7..3bdc110 100644
--- a/include/saerom.h
+++ b/include/saerom.h
@@ -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"
@@ -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;
@@ -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);
@@ -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` 명령어를 생성한다. */
diff --git a/src/bot.c b/src/bot.c
index be5137d..591e60f 100644
--- a/src/bot.c
+++ b/src/bot.c
@@ -15,7 +15,6 @@
along with this program. If not, see .
*/
-#include
#include
#include
@@ -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 봇의 클라이언트가 준비되었을 때 호출된다. */
@@ -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);
@@ -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);
@@ -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");
@@ -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 봇의 명령어 목록을 반환한다. */
@@ -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 사용량 최적화
@@ -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);
@@ -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);
@@ -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);
diff --git a/src/config.c b/src/config.c
new file mode 100644
index 0000000..998244d
--- /dev/null
+++ b/src/config.c
@@ -0,0 +1,203 @@
+/*
+ Copyright (c) 2022 jdeokkim
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see .
+*/
+
+#include
+#include
+
+#include
+
+#include "saerom.h"
+
+/* | `config` 모듈 자료형 정의... | */
+
+/* Discord 봇의 환경 설정을 나타내는 구조체. */
+struct sr_config {
+ u64snowflake application_id;
+ u64snowflake application_owner_id;
+ struct {
+ u64bitmask module;
+ u64bitmask status;
+ } flags;
+ struct {
+ char api_key[MAX_STRING_SIZE];
+ } krdict;
+ struct {
+ char client_id[MAX_STRING_SIZE];
+ char client_secret[MAX_STRING_SIZE];
+ } papago;
+ pthread_mutex_t lock;
+};
+
+/* | `config` 모듈 상수 및 변수... | */
+
+/* Discord 봇의 환경 설정. */
+static struct sr_config config;
+
+/* | `config` 모듈 함수... | */
+
+/* (Discord 봇의 환경 설정을 초기화한다.) */
+static void _sr_config_init(
+ struct discord *client,
+ struct discord_response *resp,
+ const struct discord_application *ret
+) {
+ pthread_mutex_lock(&config.lock);
+
+ config.application_owner_id = ret->owner->id;
+
+ pthread_mutex_unlock(&config.lock);
+}
+
+/* Discord 봇의 환경 설정을 초기화한다. */
+void sr_config_init(void) {
+ if (get_client() == NULL) return;
+
+ struct discord *client = get_client();
+
+ pthread_mutex_init(&config.lock, NULL);
+
+ 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);
+
+ {
+ pthread_mutex_lock(&config.lock);
+
+ config.application_id = strtoull(buffer, NULL, 10);
+
+ pthread_mutex_unlock(&config.lock);
+ }
+
+ field = discord_config_get_field(
+ client, (char *[3]) { "saerom", "krdict", "enable" }, 3
+ );
+
+ if (strncmp("true", field.start, field.size) == 0) {
+ pthread_mutex_lock(&config.lock);
+
+ config.flags.module |= SR_MODULE_KRDICT;
+
+ field = discord_config_get_field(
+ client, (char *[3]) { "saerom", "krdict", "api_key" }, 3
+ );
+
+ strncpy(config.krdict.api_key, field.start, field.size);
+
+ pthread_mutex_unlock(&config.lock);
+ }
+
+ field = discord_config_get_field(
+ client, (char *[3]) { "saerom", "papago", "enable" }, 3
+ );
+
+ if (strncmp("true", field.start, field.size) == 0) {
+ pthread_mutex_lock(&config.lock);
+
+ config.flags.module |= SR_MODULE_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);
+
+ pthread_mutex_unlock(&config.lock);
+ }
+
+ {
+ pthread_mutex_lock(&config.lock);
+
+ config.flags.status = SR_STATUS_RUNNING;
+
+ pthread_mutex_unlock(&config.lock);
+ }
+
+ discord_get_current_bot_application_information(
+ client,
+ &(struct discord_ret_application) {
+ .done = _sr_config_init
+ }
+ );
+}
+
+/* Discord 봇의 환경 설정에 할당된 메모리를 해제한다. */
+void sr_config_cleanup(void) {
+ pthread_mutex_destroy(&config.lock);
+}
+
+/* Discord 봇의 애플리케이션 ID를 반환한다. */
+u64snowflake sr_config_get_application_id(void) {
+ return config.application_id;
+}
+
+/* Discord 봇의 애플리케이션 소유자 ID를 반환한다. */
+u64snowflake sr_config_get_application_owner_id(void) {
+ return config.application_owner_id;
+}
+
+/* Discord 봇의 모듈 플래그 데이터를 반환한다. */
+u64bitmask sr_config_get_module_flags(void) {
+ return config.flags.module;
+}
+
+/* Discord 봇의 상태 플래그 데이터를 반환한다. */
+u64bitmask sr_config_get_status_flags(void) {
+ return config.flags.status;
+}
+
+/* Discord 봇의 국립국어원 한국어기초사전 API 키를 반환한다. */
+const char *sr_config_get_krdict_api_key(void) {
+ return config.krdict.api_key;
+}
+
+/* Discord 봇의 NAVER™ 파파고 NMT API 클라이언트 ID를 반환한다. */
+const char *sr_config_get_papago_client_id(void) {
+ return config.papago.client_id;
+}
+
+/* Discord 봇의 NAVER™ 파파고 NMT API 클라이언트 시크릿을 반환한다. */
+const char *sr_config_get_papago_client_secret(void) {
+ return config.papago.client_secret;
+}
+
+/* Discord 봇의 모듈 플래그 데이터를 `flags`로 설정한다. */
+void sr_config_set_module_flags(u64bitmask flags) {
+ pthread_mutex_lock(&config.lock);
+
+ config.flags.module = flags;
+
+ pthread_mutex_unlock(&config.lock);
+}
+
+/* Discord 봇의 상태 플래그 데이터를 `flags`로 설정한다. */
+void sr_config_set_status_flags(u64bitmask flags) {
+ pthread_mutex_lock(&config.lock);
+
+ config.flags.status = flags;
+
+ pthread_mutex_unlock(&config.lock);
+}
\ No newline at end of file
diff --git a/src/info.c b/src/info.c
index 52be4db..edb9473 100644
--- a/src/info.c
+++ b/src/info.c
@@ -34,7 +34,7 @@ static struct discord_create_global_application_command params = {
void create_info_command(struct discord *client) {
discord_create_global_application_command(
client,
- get_application_id(),
+ sr_config_get_application_id(),
¶ms,
NULL
);
@@ -56,8 +56,6 @@ void run_info_command(
char uptime_str[MAX_STRING_SIZE];
char ping_str[MAX_STRING_SIZE];
char flags_str[MAX_STRING_SIZE];
-
- struct sr_config *config = get_sr_config();
time_t uptime_in_seconds = get_uptime() * 0.001f;
@@ -66,7 +64,7 @@ void run_info_command(
strftime(uptime_str, sizeof(uptime_str), "%T", gmtime(&uptime_in_seconds));
snprintf(ping_str, sizeof(ping_str), "%dms", discord_get_ping(client));
- snprintf(flags_str, sizeof(flags_str), "0x%02hhX", config->flags);
+ snprintf(flags_str, sizeof(flags_str), "0x%02" PRIu64 "X", sr_config_get_module_flags());
if (event == NULL) {
log_info("[SAEROM] %s: %s", APPLICATION_NAME, APPLICATION_DESCRIPTION);
diff --git a/src/krdict.c b/src/krdict.c
index 3498e44..3f4122d 100644
--- a/src/krdict.c
+++ b/src/krdict.c
@@ -110,7 +110,7 @@ static void handle_error(struct krdict_context *context, const char *code);
void create_krdict_command(struct discord *client) {
discord_create_global_application_command(
client,
- get_application_id(),
+ sr_config_get_application_id(),
¶ms,
NULL
);
@@ -152,15 +152,13 @@ void run_krdict_command(
char buffer[DISCORD_MAX_MESSAGE_LEN] = "";
- struct sr_config *config = get_sr_config();
-
snprintf(
buffer,
DISCORD_MAX_MESSAGE_LEN,
streq(translated, "true")
? "key=%s&q=%s&advanced=y&translated=y&trans_lang=1"
: "key=%s&q=%s&advanced=y",
- config->krdict.api_key,
+ sr_config_get_krdict_api_key(),
query
);
@@ -532,7 +530,7 @@ static void on_response(CURLV_STR res, void *user_data) {
discord_edit_original_interaction_response(
context->client,
- get_application_id(),
+ sr_config_get_application_id(),
context->event.token,
&(struct discord_edit_original_interaction_response) {
.components = &(struct discord_components){
@@ -578,7 +576,7 @@ static void handle_error(struct krdict_context *context, const char *code) {
discord_edit_original_interaction_response(
context->client,
- get_application_id(),
+ sr_config_get_application_id(),
context->event.token,
&(struct discord_edit_original_interaction_response) {
.embeds = &(struct discord_embeds) {
diff --git a/src/main.c b/src/main.c
index 6652537..3820e98 100644
--- a/src/main.c
+++ b/src/main.c
@@ -18,11 +18,11 @@
#include "saerom.h"
int main(int argc, char *argv[]) {
- init_bot(argc, argv);
+ sr_bot_init(argc, argv);
- run_bot();
+ sr_bot_run();
- deinit_bot();
+ sr_bot_cleanup();
return 0;
}
\ No newline at end of file
diff --git a/src/owner.c b/src/owner.c
index c565f71..08db4d9 100644
--- a/src/owner.c
+++ b/src/owner.c
@@ -85,7 +85,7 @@ void create_msg_command(struct discord *client) {
discord_create_global_application_command(
client,
- get_application_id(),
+ sr_config_get_application_id(),
¶ms,
NULL
);
@@ -111,7 +111,7 @@ void run_msg_command(
? event->member->user
: event->user;
- if (user->id != get_owner_id()) {
+ if (user->id != sr_config_get_application_owner_id()) {
const struct discord_user *self = discord_get_self(client);
struct discord_embed embeds[] = {
@@ -218,7 +218,7 @@ void create_stop_command(struct discord *client) {
discord_create_global_application_command(
client,
- get_application_id(),
+ sr_config_get_application_id(),
¶ms,
NULL
);
@@ -229,6 +229,15 @@ void release_stop_command(struct discord *client) {
/* no-op */
}
+/* (`/stop` 명령어를 실행한다.) */
+static void _run_stop_command(
+ struct discord *client,
+ struct discord_response *resp,
+ const struct discord_interaction_response *ret
+) {
+ sr_config_set_status_flags(0);
+}
+
/* `/stop` 명령어를 실행한다. */
void run_stop_command(
struct discord *client,
@@ -239,9 +248,9 @@ void run_stop_command(
? event->member->user
: event->user;
- if (user->id != get_owner_id()) {
- const struct discord_user *self = discord_get_self(client);
+ const struct discord_user *self = discord_get_self(client);
+ if (user->id != sr_config_get_application_owner_id()) {
struct discord_embed embeds[] = {
{
.description = "This command can only be invoked by the bot owner.",
@@ -280,11 +289,14 @@ void run_stop_command(
struct discord_embed embeds[] = {
{
- .title = APPLICATION_NAME,
.description = "Shutting down the bot...",
.timestamp = discord_timestamp(client),
.footer = &(struct discord_embed_footer) {
.text = "⚡"
+ },
+ .author = &(struct discord_embed_author) {
+ .name = self->username,
+ .icon_url = (char *) get_avatar_url(self)
}
}
};
@@ -305,14 +317,14 @@ void run_stop_command(
event->token,
¶ms,
&(struct discord_ret_interaction_response) {
- .done = sr_shutdown
+ .done = _run_stop_command
}
);
return;
}
- sr_shutdown(NULL, NULL, NULL);
+ sr_config_set_status_flags(0);
}
/* 채널 메시지 전송에 성공했을 때 호출되는 함수. */
@@ -402,17 +414,4 @@ static void on_message_complete(struct discord *client, void *data) {
free(event->token);
free(event);
-}
-
-/* Discord 봇을 종료한다. */
-static void sr_shutdown(
- struct discord *client,
- struct discord_response *resp,
- const struct discord_interaction_response *ret
-) {
- log_info("[SAEROM] Shutting down the bot");
-
- deinit_bot();
-
- exit(EXIT_SUCCESS);
}
\ No newline at end of file
diff --git a/src/papago.c b/src/papago.c
index 1518a2c..3c14be2 100644
--- a/src/papago.c
+++ b/src/papago.c
@@ -107,7 +107,7 @@ static void handle_error(struct papago_context *context, const char *code);
void create_papago_command(struct discord *client) {
discord_create_global_application_command(
client,
- get_application_id(),
+ sr_config_get_application_id(),
¶ms,
NULL
);
@@ -160,8 +160,6 @@ void run_papago_command(
curl_easy_setopt(request.easy, CURLOPT_COPYPOSTFIELDS, buffer);
curl_easy_setopt(request.easy, CURLOPT_POST, 1);
- struct sr_config *config = get_sr_config();
-
request.header = curl_slist_append(
request.header,
"Content-Type: application/x-www-form-urlencoded; charset=UTF-8"
@@ -171,7 +169,7 @@ void run_papago_command(
buffer,
sizeof(buffer),
"X-Naver-Client-Id: %s",
- config->papago.client_id
+ sr_config_get_papago_client_id()
);
request.header = curl_slist_append(request.header, buffer);
@@ -180,7 +178,7 @@ void run_papago_command(
buffer,
sizeof(buffer),
"X-Naver-Client-Secret: %s",
- config->papago.client_secret
+ sr_config_get_papago_client_secret()
);
request.header = curl_slist_append(request.header, buffer);
@@ -272,7 +270,7 @@ static void on_response(CURLV_STR res, void *user_data) {
discord_edit_original_interaction_response(
context->client,
- get_application_id(),
+ sr_config_get_application_id(),
context->event.token,
&(struct discord_edit_original_interaction_response) {
.embeds = &(struct discord_embeds) {
@@ -323,7 +321,7 @@ static void handle_error(struct papago_context *context, const char *code) {
discord_edit_original_interaction_response(
context->client,
- get_application_id(),
+ sr_config_get_application_id(),
context->event.token,
&(struct discord_edit_original_interaction_response) {
.embeds = &(struct discord_embeds) {