#include "irc.h" #include "run.h" #include "socket.h" #include <netdb.h> #include <stdio.h> #include <string.h> #include <sys/socket.h> #include <time.h> #include <unistd.h> int irc_connect(irc_t *irc, const char *server, const char *port) { if ((irc->s = get_socket(server, port)) < 0) { return -1; } irc->bufptr = 0; return 0; } int irc_login(irc_t *irc, const char *nick) { irc_reg(irc->s, nick, "RUNBOT", "STRAVA"); sleep(1); return irc_msg(irc->s, "NickServ", ⚡"IDENTIFY RUNBOT hunter2"); } int irc_join_channel(irc_t *irc, const char *channel) { strncpy(irc->channel, channel, 254); irc->channel[254] = '\0'; return irc_join(irc->s, channel); } int irc_leave_channel(irc_t *irc) { return irc_part(irc->s, irc->channel); } int irc_handle_data(irc_t *irc) { char tempbuffer[512]; int rc, i; /* int first; */ /* if (first == NULL) { */ /* irc_msg(irc->s, "NickServ", "IDENTIFY RUNBOT hunter2"); */ /* first = 1; */ /* } */ if ((rc = sck_recv(irc->s, tempbuffer, sizeof(tempbuffer) - 2)) <= 0) { fprintf(stderr, ":v\n"); return -1; } tempbuffer[rc] = '\0'; for (i = 0; i < rc; ++i) { switch (tempbuffer[i]) { case '\r': case '\n': { irc->servbuf[irc->bufptr] = '\0'; irc->bufptr = 0; if (irc_parse_action(irc) < 0) return -1; break; } default: { irc->servbuf[irc->bufptr] = tempbuffer[i]; if (irc->bufptr >= (sizeof(irc->servbuf) - 1)) // Overflow! ; else irc->bufptr++; } } } return 0; } int irc_parse_action(irc_t *irc) { /* char irc_nick[128]; */ /* char irc_msg[512]; */ if (strncmp(irc->servbuf, "PING :", 6) == 0) { return irc_pong(irc->s, &irc->servbuf[6]); } else if (strncmp(irc->servbuf, "NOTICE AUTH :", 13) == 0) { // Don't care return 0; } else if (strncmp(irc->servbuf, "ERROR :", 7) == 0) { // Still don't care return 0; } // Here be lvl. 42 dragonn boss // Parses IRC message that pulls out nick and message. else { char *ptr; int privmsg = 0; char irc_nick[128]; char irc_msg[512]; *irc_nick = '\0'; *irc_msg = '\0'; // Checks if we have non-message string if (strchr(irc->servbuf, 1) != NULL) return 0; if (irc->servbuf[0] == ':') { ptr = strtok(irc->servbuf, "!"); if (ptr == NULL) { printf("ptr == NULL\n"); return 0; } else { strncpy(irc_nick, &ptr[1], 127); irc_nick[127] = '\0'; } while ((ptr = strtok(NULL, " ")) != NULL) { if (strcmp(ptr, "PRIVMSG") == 0) { privmsg = 1; break; } } if (privmsg) { if ((ptr = strtok(NULL, ":")) != NULL && (ptr = strtok(NULL, "")) != NULL) { strncpy(irc_msg, ptr, 511); irc_msg[511] = '\0'; } } if (privmsg == 1 && strlen(irc_nick) > 0 && strlen(irc_msg) > 0) { irc_log_message(irc, irc_nick, irc_msg); if (irc_reply_message(irc, irc_nick, irc_msg) < 0) return -1; } } } return 0; } int irc_set_output(irc_t *irc, const char *file) { irc->file = fopen(file, "w"); if (irc->file == NULL) return -1; return 0; } char *getRandomLine() { FILE *file = fopen("theo.txt", "r"); if (!file) return NULL; int lineCount = 0; char buffer[1024]; while (fgets(buffer, sizeof(buffer), file)) { lineCount++; } if (lineCount == 0) { fclose(file); return NULL; } srand(time(NULL)); int targetLine = rand() % lineCount; rewind(file); int currentLine = 0; while (currentLine < targetLine && fgets(buffer, sizeof(buffer), file)) { currentLine++; } if (fgets(buffer, sizeof(buffer), file)) { size_t len = strlen(buffer); if (len > 0 && buffer[len - 1] == '\n') { buffer[len - 1] = '\0'; } char *theo = strdup(buffer); fclose(file); return theo; } fclose(file); return NULL; } int irc_reply_message(irc_t *irc, char *irc_nick, char *msg) { /* if ( *msg != '!' ) */ /* return 0; */ sleep(1); char *command = NULL; char *arg = NULL; char *msg_copy = strdup(msg); command = strtok(&msg[0], " "); arg = strtok(NULL, ""); if (arg != NULL) while (*arg == ' ') arg++; if (command == NULL) return 0; if (strcmp(command, "ping") == 0) { if (irc_msg(irc->s, irc->channel, "pong") < 0) return -1; } else if (strcmp(command, "war") == 0) { if (irc_msg(irc->s, irc->channel, "WMs again? gtfo.") < 0) return -1; } else if (strcmp(command, "slap") == 0) { char mesg[512]; snprintf(mesg, 511, "%s slaps %s around a bit with a large trout", irc_nick, arg); mesg[511] = '\0'; if (irc_msg(irc->s, irc->channel, mesg) < 0) return -1; } else if (strcmp(command, "stats") == 0) { char *stats = malloc(512); irc_nick = arg; goto get_stats; } else if (strstr(msg_copy, "theo") != NULL || strstr(msg_copy, "Theo") != NULL) { char *theo = getRandomLine(); if (irc_msg(irc->s, irc->channel, theo) < 0) return -1; free(theo); } else if (strstr(msg_copy, "run") != NULL) { if (irc_msg(irc->s, irc->channel, "RUN FASTER!") < 0) return -1; } else if (strcmp(command, "addtime") == 0) { if (arg == NULL || strlen(arg) == 0 || strcmp(command, "addtime") == 0) { irc_msg(irc->s, irc->channel, "Error: Invalid syntax, use addtime HH:MM:SS DISTANCE"); return 0; } char time_str[10]; char distance_str[10]; char *token = strtok(msg_copy, " "); token = strtok(NULL, " "); strcpy(time_str, token); token = strtok(NULL, " "); strcpy(distance_str, token); float distance = atof(distance_str); char *stats = malloc(512); if (add_run(time_str, distance, irc_nick, &stats) == 0) { get_stats: stats = get_user_stats(irc_nick); } char *copy = strdup(stats), *line; for (line = strtok(copy, "\n"); line; line = strtok(NULL, "\n")) { sleep(1); irc_msg(irc->s, irc->channel, line); } free(msg_copy); return 0; } else if (strcmp(command, "smack") == 0) { char mesg[512]; srand(time(NULL)); int critical; critical = (rand() % 10) / 8; if (arg != NULL && strlen(arg) > 0) { if (critical) snprintf(mesg, 511, "I smack thee, %s, for %d damage (it's super effective).", arg, rand() % 20 + 21); else snprintf(mesg, 511, "I smack thee, %s, for %d damage.", arg, rand() % 20 + 1); mesg[511] = '\0'; } else { snprintf(mesg, 511, "Behold, I smack thee, %s, for %d damage.", irc_nick, rand() % 20 + 1); mesg[511] = '\0'; } if (irc_msg(irc->s, irc->channel, mesg) < 0) return -1; } else if (strcmp(command, "pacman") == 0) { if (irc_msg(irc->s, irc->channel, "Wocka, wocka, bitches!") < 0) return -1; } else if (strstr(msg_copy, "youtube.com") != NULL || strstr(msg_copy, "www.youtube.com") != NULL || strstr(msg_copy, "youtu.be") != NULL) { char *new_msg = malloc(strlen(msg_copy) * 2); strcpy(new_msg, msg_copy); // this handling is dumb char *found = strstr(new_msg, "www.youtube.com"); if (found != NULL) { memmove(found + strlen("inv.nadeko.net"), found + strlen("www.youtube.com"), strlen(found + strlen("www.youtube.com")) + 1); memcpy(found, "inv.nadeko.net", strlen("inv.nadeko.net")); } found = strstr(new_msg, "youtube.com"); if (found != NULL) { memmove(found + strlen("inv.nadeko.net"), found + strlen("youtube.com"), strlen(found + strlen("youtube.com")) + 1); memcpy(found, "inv.nadeko.net", strlen("inv.nadeko.net")); } found = strstr(new_msg, "youtu.be"); if (found != NULL) { memmove(found + strlen("inv.nadeko.net"), found + strlen("youtu.be"), strlen(found + strlen("youtu.be")) + 1); memcpy(found, "inv.nadeko.net", strlen("inv.nadeko.net")); } if (irc_msg(irc->s, irc->channel, new_msg) < 0) { free(msg_copy); free(new_msg); return -1; } free(new_msg); free(msg_copy); return 0; } return 0; } int irc_log_message(irc_t *irc, const char *nick, const char *message) { char timestring[128]; time_t curtime; time(&curtime); strftime(timestring, 127, "%F - %H:%M:%S", localtime(&curtime)); timestring[127] = '\0'; fprintf(irc->file, "%s - [%s] <%s> %s\n", irc->channel, timestring, nick, message); fflush(irc->file); return 0; } void irc_close(irc_t *irc) { close(irc->s); fclose(irc->file); } // irc_pong: For answering pong requests... int irc_pong(int s, const char *data) { return sck_sendf(s, "PONG :%s\r\n", data); } // irc_reg: For registering upon login int irc_reg(int s, const char *nick, const char *username, const char *fullname) { return sck_sendf(s, "NICK %s\r\nUSER %s localhost 0 :%s\r\n", nick, username, fullname); } // irc_join: For joining a channel int irc_join(int s, const char *data) { return sck_sendf(s, "JOIN %s\r\n", data); } // irc_part: For leaving a channel int irc_part(int s, const char *data) { return sck_sendf(s, "PART %s\r\n", data); } // irc_nick: For changing your nick int irc_nick(int s, const char *data) { return sck_sendf(s, "NICK %s\r\n", data); } // irc_quit: For quitting IRC int irc_quit(int s, const char *data) { return sck_sendf(s, "QUIT :%s\r\n", data); } // irc_topic: For setting or removing a topic int irc_topic(int s, const char *channel, const char *data) { return sck_sendf(s, "TOPIC %s :%s\r\n", channel, data); } // irc_action: For executing an action (.e.g /me is hungry) int irc_action(int s, const char *channel, const char *data) { return sck_sendf(s, "PRIVMSG %s :\001ACTION %s\001\r\n", channel, data); } // irc_msg: For sending a channel message or a query int irc_msg(int s, const char *channel, const char *data) { return sck_sendf(s, "PRIVMSG %s :%s\r\n", channel, data); }
Generated by Getz using scpaste at Mon Feb 24 22:51:57 2025. CET. (original)