From d4efeb70dfa7d236b1feee5eb9b4b6202585d383 Mon Sep 17 00:00:00 2001 From: Trumeet Date: Wed, 15 Sep 2021 20:19:41 -0700 Subject: feat: support multiple administrators --- README | 4 ++-- environ.c | 71 +++++++++++++++++++++++++++++++++++++++++++++++++++++---------- environ.h | 4 +++- main.c | 11 +++++++++- 4 files changed, 75 insertions(+), 15 deletions(-) diff --git a/README b/README index b9af43f..383eb7c 100644 --- a/README +++ b/README @@ -18,7 +18,7 @@ make install CONFIGURATION -TG_ADMIN=114514 # UID allowed to execute more rcon commands other than /list. A complete list of commands supported is listed below. +TG_ADMIN=114514,1919810 # UIDs allowed to execute more rcon commands other than /list. A complete list of commands supported is listed below. TG_CHAT=-114514 # Chat that is allowed to send message to and from. TG_LINK_FMT=https://t.me/c/xxx/%d # Format of Telegram links. %d: Message ID. TG_API=114514:1919810 # Telegram bot API Key. @@ -38,7 +38,7 @@ COMMANDS Any users in the chat can use `/list` or `/list uuids` to check online players. -In additional to these two commands, the administrator can use the following commands as well: +In additional to these two commands, administrators can use the following commands as well: `/debug ` `/data ` diff --git a/environ.c b/environ.c index 821514f..d264f08 100644 --- a/environ.c +++ b/environ.c @@ -10,6 +10,8 @@ int environ_read(Environ *out) { + int r = 0; + out->tg_api = getenv("TG_API"); out->tg_chat_raw = getenv("TG_CHAT"); char *tg_admin_raw = getenv("TG_ADMIN"); @@ -25,32 +27,79 @@ int environ_read(Environ *out) out->rcon_port == NULL) { fprintf(stderr, _("Required environment variables are missing.\n")); - return EX_USAGE; + r = EX_USAGE; + goto cleanup; } char *endptr; intmax_t num = strtoimax(out->tg_chat_raw, &endptr, 10); if(strcmp(endptr, "") || (num == INTMAX_MAX && errno == ERANGE)) { fprintf(stderr, _("TG_CHAT is invalid\n")); - return EX_USAGE; + r = EX_USAGE; + goto cleanup; } if(num > INT64_MAX || num < INT64_MIN) { fprintf(stderr, _("TG_CHAT is invalid\n")); - return EX_USAGE; + r = EX_USAGE; + goto cleanup; } out->tg_chat = (int64_t)num; - uintmax_t unum = strtoumax(tg_admin_raw, &endptr, 10); - if(strcmp(endptr, "") || (unum == UINTMAX_MAX && errno == ERANGE)) + char *token = strtok(tg_admin_raw, ","); + out->tg_admins_size = 0; + out->tg_admins = NULL; + while(token != NULL) { - fprintf(stderr, _("TG_ADMIN is invalid\n")); - return EX_USAGE; + out->tg_admins_size ++; + if(out->tg_admins == NULL) + { + out->tg_admins = calloc(out->tg_admins_size, sizeof(uint32_t)); + if(out->tg_admins == NULL) + { + r = errno; + fprintf(stderr, _("Cannot allocate memory: %s.\n"), strerror(r)); + goto cleanup; + } + } + else + { + if((out->tg_admins = realloc(out->tg_admins, out->tg_admins_size * sizeof(uint32_t))) == NULL) + { + r = errno; + fprintf(stderr, _("Cannot allocate memory: %s.\n"), strerror(r)); + free(out->tg_admins); + goto cleanup; + } + } + uintmax_t unum = strtoumax(token, &endptr, 10); + if(strcmp(endptr, "") || (unum == UINTMAX_MAX && errno == ERANGE)) + { + fprintf(stderr, _("TG_ADMIN is invalid\n")); + r = EX_USAGE; + goto cleanup; + } + if(unum > UINT32_MAX || unum < 0) + { + fprintf(stderr, _("TG_ADMIN is invalid\n")); + r = EX_USAGE; + goto cleanup; + } + out->tg_admins[out->tg_admins_size - 1] = (uint32_t)unum; + token = strtok(NULL, ","); } - if(unum > UINT32_MAX || unum < 0) +cleanup: + if(r) { - fprintf(stderr, _("TG_ADMIN is invalid\n")); - return EX_USAGE; + environ_free(out); } - out->tg_admin = (uint32_t)unum; return 0; } + +void environ_free(Environ *env) +{ + if(env->tg_admins != NULL) + { + free(env->tg_admins); + env->tg_admins = NULL; + } +} diff --git a/environ.h b/environ.h index 2aaaebf..421d983 100644 --- a/environ.h +++ b/environ.h @@ -7,7 +7,8 @@ typedef struct environ { char *tg_api; char *tg_chat_raw; int64_t tg_chat; - uint32_t tg_admin; + unsigned int tg_admins_size; + uint32_t *tg_admins; char *tg_link_fmt; char *rcon_host; char *rcon_port; @@ -16,5 +17,6 @@ typedef struct environ { } Environ; int environ_read(Environ *out); +void environ_free(Environ *env); #endif // _ENVIRON_H diff --git a/main.c b/main.c index dc066af..a4f695d 100644 --- a/main.c +++ b/main.c @@ -114,7 +114,15 @@ run: if(entity.offset == 0 && !strcmp(entity.type, "bot_command")) { - char is_admin = tgmsg->from->id == env->tg_admin; + char is_admin = 0; + for(int i = 0; i < env->tg_admins_size; i ++) + { + if(tgmsg->from->id == env->tg_admins[i]) + { + is_admin = 1; + break; + } + } if((is_admin && ( !strncmp(tgmsg->text, "/whitelist ", strlen("/whitelist ")) || !strncmp(tgmsg->text, "/debug ", strlen("/debug ")) || @@ -359,6 +367,7 @@ read: goto cleanup; cleanup: + environ_free(&environ); if(curl != NULL) curl_easy_cleanup(curl); curl_global_cleanup(); if(sd != 0) net_close(sd); -- cgit v1.2.3