diff options
| author | Emil | 2023-08-04 09:13:47 -0600 |
|---|---|---|
| committer | Emil | 2023-08-04 09:13:47 -0600 |
| commit | 935243d8b4ea992c50315f0c8fcb300365a5762d (patch) | |
| tree | c22d800773997b7b267d5d6cba5931f22ee2be64 /src/irc.c | |
| download | emil-probotic-935243d8b4ea992c50315f0c8fcb300365a5762d.tar.xz emil-probotic-935243d8b4ea992c50315f0c8fcb300365a5762d.tar.zst | |
Diffstat (limited to 'src/irc.c')
| -rw-r--r-- | src/irc.c | 173 |
1 files changed, 173 insertions, 0 deletions
diff --git a/src/irc.c b/src/irc.c new file mode 100644 index 0000000..a9b8ffb --- /dev/null +++ b/src/irc.c @@ -0,0 +1,173 @@ +/* irc.c - IRC interface + + Probotic is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License version 3 only as + published by the Free Software Foundation. + + Probotic 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 version 3 for more details. + + You should have received a copy of the GNU General Public License + version 3 along with Probotic. + +*/ + +VARDECL char const * help_msg = +IRC_GREEN "!help " IRC_STOP " : This message\n" +IRC_GREEN "!remind " IRC_STOP " : Dump current assignment\n" +IRC_GREEN "!reroll " IRC_STOP " : Rerolls assignment\n" +IRC_GREEN "!set_repo <link>" IRC_STOP " : Sets project repository link\n" +IRC_GREEN "!raw <sql> " IRC_STOP " : Execute raw SQL\n" +IRC_GREEN "!dump " IRC_STOP " : List all possible projects\n" +IRC_GREEN "!request " IRC_STOP " : Request personal project\n" +IRC_GREEN "!remind " IRC_STOP " : Prints your assignment\n"; + +VARDECL char const * fmsg = +"%s\x2C\x20\x79\x6F\x75\x20\x61\x72\x65\x20\x66\x61\x67\x67" + "\x6F\x74\x20\x66\x6F\x72\x20\x74\x68\x61\x74\x20\x6F\x70" + "\x69\x6E\x69\x6F\x6E\x2E"; + +#define PREFIX_COMMAND_CHAR '!' +#define PREFIX_CHANNEL_COMMAND_CHAR '%' + +VARDECL irc_session_t * session; +VARDECL irc_callbacks_t callbacks; + +VARDECL char * current_username = NULL; +/* Do you have any idea how many things this breaks? */ +int stupid_shit = -1; + +#define IRCMSG(msg) irc_cmd_msg(session, creds.channel, msg) + +DECL char * +get_username(const char * origin) +{ + const char USERNAME_TERMINATOR = '!'; + int i = 0; + char * r; + while (origin[i] != USERNAME_TERMINATOR) + { i++; } + r = (char *) malloc(i + 1); + strncpy(r, origin, i); + r[i] = '\00'; + return r; +} + +DECL void +ircmsg(const char* fmt, + ...) +{ + if(!strcmp(fmt, "") || fmt == NULL){ return; } + va_list args; + char * fmtdmsg; + char * swp; + + va_start(args, fmt); + if(vasprintf(&fmtdmsg, fmt, args) == -1) + { exit(1); } + + puts(fmtdmsg); + const char* delim = "\n"; + char* data = strtok(fmtdmsg, delim); + do{ + swp = irc_color_convert_to_mirc(data); + IRCMSG(swp); + free(swp); + }while((data = strtok(NULL, delim), data)); + + free(fmtdmsg); + va_end(args); +} + +DECL void +event_connect(irc_session_t * session, + const char * event, + const char * origin, + const char ** params, + unsigned int count) +{ + (void) event; + (void) origin; + (void) params; + (void) count; + /* msg ChanServ IDENTIFY? */ + irc_cmd_join(session, creds.channel, 0); + if(is_no_assignment(creds.channel)){ + ircmsg(IRC_RED "No assignment for this channel. Finding a new..." IRC_STOP); + random_assign(creds.channel); + } + ircmsg(remind(creds.channel)); +} + +DECL void +event_channel(irc_session_t * session, + char const * event, + char const * origin, + char const ** params, + unsigned int count) +{ + /* char const * channel = params[0]; */ + char const * message = params[1]; + (void) session; + (void) event; + (void) origin; + /* (void) channel; */ + (void) message; + (void) count; + /* parses the command */ + switch(*message){ + case PREFIX_CHANNEL_COMMAND_CHAR: + current_username = strdup(creds.channel); + break; + case PREFIX_COMMAND_CHAR: + current_username = get_username(origin); + break; + } + if(!current_username || *(message+1) == '\00'){ return; } + --stupid_shit; + if(stupid_shit == 0) + { ircmsg(fmsg, current_username); } + parse_command(message+1); + free(current_username); + current_username = NULL; +} + +DECL int +init(void) +{ + srand(time(NULL)); + if(api_init()) + { ERR(DB_ERROR, "Error initializing database."); } + memset(&callbacks, 0, sizeof(callbacks)); + callbacks.event_connect = event_connect; + callbacks.event_channel = event_channel; + session = irc_create_session(&callbacks); + if (!session) + { + ERRMSG("Error creating IRC session"); + goto fail; + } + assert(creds.username != NULL); + assert(creds.server != NULL); + irc_connect(session, + creds.server, creds.port, creds.password, + creds.username, creds.username, creds.username); + creds_free_password(); + atexit(rope); + return 0; +fail: + creds_free_password(); + return 1; +} + +DECL int +loop(void) +{ + /* We should figure out how the failure happens so we can tell the user that. */ + if (irc_run(session) != 0) + { ERR(1, "Error running IRC session\nPossible issue: bad URL," + " no network connection, bad port, refused connection."); } + return 0; +} |
