#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;
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))
;
else
irc->bufptr++;
}
}
}
return 0;
}
int irc_parse_action(irc_t *irc) {
if (strncmp(irc->servbuf, "PING :", 6) == 0) {
return irc_pong(irc->s, &irc->servbuf[6]);
} else if (strncmp(irc->servbuf, "NOTICE AUTH :", 13) == 0) {
return 0;
} else if (strncmp(irc->servbuf, "ERROR :", 7) == 0) {
return 0;
}
else {
char *ptr;
int privmsg = 0;
char irc_nick[128];
char irc_msg[512];
*irc_nick = '\0';
*irc_msg = '\0';
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) {
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);
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);
}
int irc_pong(int s, const char *data) {
return sck_sendf(s, "PONG :%s\r\n", data);
}
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);
}
int irc_join(int s, const char *data) {
return sck_sendf(s, "JOIN %s\r\n", data);
}
int irc_part(int s, const char *data) {
return sck_sendf(s, "PART %s\r\n", data);
}
int irc_nick(int s, const char *data) {
return sck_sendf(s, "NICK %s\r\n", data);
}
int irc_quit(int s, const char *data) {
return sck_sendf(s, "QUIT :%s\r\n", data);
}
int irc_topic(int s, const char *channel, const char *data) {
return sck_sendf(s, "TOPIC %s :%s\r\n", channel, data);
}
int irc_action(int s, const char *channel, const char *data) {
return sck_sendf(s, "PRIVMSG %s :\001ACTION %s\001\r\n", channel, data);
}
int irc_msg(int s, const char *channel, const char *data) {
return sck_sendf(s, "PRIVMSG %s :%s\r\n", channel, data);
}