diff options
author | Sergey Nazaryev <sergey@nazaryev.ru> | 2016-05-18 00:52:10 +0300 |
---|---|---|
committer | Sergey Nazaryev <sergey@nazaryev.ru> | 2016-05-18 00:52:10 +0300 |
commit | 28994f5e1fb63af77187fc9f99c91a56118f96da (patch) | |
tree | fe2fba14584afb3b6e0b38175a6770f067a5e1db | |
download | ircbot-28994f5e1fb63af77187fc9f99c91a56118f96da.zip ircbot-28994f5e1fb63af77187fc9f99c91a56118f96da.tar.gz ircbot-28994f5e1fb63af77187fc9f99c91a56118f96da.tar.bz2 |
Initial commit.
-rw-r--r-- | README.md | 6 | ||||
-rw-r--r-- | commands | 1 | ||||
-rw-r--r-- | irc.c | 178 | ||||
-rw-r--r-- | msg.py | 38 |
4 files changed, 223 insertions, 0 deletions
diff --git a/README.md b/README.md new file mode 100644 index 0000000..27f9ba9 --- /dev/null +++ b/README.md @@ -0,0 +1,6 @@ +ircbot -- zar's irc bot +======================= + +Это простой IRC-бот: на Си написана реализация IRC-клиента, на Python'е -- +полезная нагрузка IRC-бота. Умеет он пока только учиться другим командам от +пользователей. diff --git a/commands b/commands new file mode 100644 index 0000000..b366946 --- /dev/null +++ b/commands @@ -0,0 +1 @@ +зар=Зар — мой создатель
@@ -0,0 +1,178 @@ +#include <stdio.h> + +#ifdef WIN32 +#include <winsock.h> +#else +#include <sys/types.h> +#include <sys/socket.h> +#include <netinet/in.h> +typedef struct sockaddr_in SOCKADDR_IN; +typedef int SOCKET; +typedef struct sockaddr SOCKADDR; +#endif + +#define MAX_DATA 512 + +SOCKET sock; +char* channel; + +void error(errnum) { + switch(errnum) { + case 1: + fprintf(stderr, "irc [ip] [port] [nick] [channel] [passwd]\n"); + break; + default: + fprintf(stderr, "error %d", errnum); + break; + } + + exit(errnum); +} + +#ifdef WIN32 +int sockets_init() { + WSADATA wsaData; + if(WSAStartup(MAKEWORD(1,1), &wsaData) != 0) + return -1; + return 0; +} +#endif + +int send_data(SOCKET sock, char* data) { + char cmd[MAX_DATA]; + u_short data_size = strlen(data); + memcpy(cmd, data, data_size); + memcpy(cmd+data_size, "\r\n\0", 3); + int bytes_sent = send(sock, cmd, strlen(cmd), 0); + return (bytes_sent ? 0 : -1); +} + +void pong(char *data) { + char* msg[MAX_DATA]; + sprintf(msg, "PONG :%s", data+6); + send_data(sock, msg); +} + +void send_msg(char* msg) { + char* data[MAX_DATA]; + sprintf(data, "PRIVMSG #%s :%s", channel, msg); + send_data(sock, data); + fprintf(stderr, msg); +} + +void msg_handler(char* msg) { + fprintf(stdout, "%s", msg); + char data[MAX_DATA]; + sprintf(data, "python msg.py \"%s\"", msg); + FILE *ls = popen(data, "r"); + while (fgets(data, sizeof(data), ls) != 0) + send_msg(data); + pclose(ls); + + fflush(stdout); +} + +void join_handler(char* nick) { + char msg[MAX_DATA]; +} + +void data_handler(char* data) { + fprintf(stderr, data); + if(strstr(data, "PING :") != NULL) { + pong(data); + return; + } + char* colon = strstr(data, " :"); + char* privmsg = strstr(data, "PRIVMSG"); + + if(privmsg != NULL && colon != NULL && colon - privmsg > 0) { + msg_handler(colon+2); + return; + } + + char* join = strstr(data, " JOIN"); + if(join != NULL && colon == NULL) { + char* name_end = strstr(data, "!"); + if(name_end != NULL) { + *name_end = '\0'; + join_handler(data+1); + } + return; + } +} + +void join(SOCKET sock, char* channel) { + char join[MAX_DATA]; + u_short channel_size = strlen(channel); + memcpy(join, "JOIN #", 6); + memcpy(join+6, channel, channel_size); + memcpy(join+6+channel_size, "\0", 1); + send_data(sock, join); +} + +void passwd(SOCKET sock, char* password) { + char passwd[MAX_DATA]; + u_short password_size = strlen(password); + send_data(sock, "a"); + send_data(sock, "f"); + memcpy(passwd, "PASS ", 5); + memcpy(passwd+5, password, password_size); + memcpy(passwd+5+password_size, "\0", 1); + send_data(sock, passwd); +} + +void handshake(SOCKET sock, char* nick) { + char handshake_nick[MAX_DATA]; + u_short nick_size = strlen(nick); + memcpy(handshake_nick, "NICK ", 5); + memcpy(handshake_nick+5, nick, nick_size); + memcpy(handshake_nick+5+nick_size, "\0", 1); + send_data(sock, handshake_nick); + send_data(sock, "USER x x x :Twitch bot"); +} + +int main(int argc, char** argv) { + //if(argc != 5 && argc != 6) + // error(1); + channel = argv[4]; +#ifdef WIN32 + if(sockets_init()) + error(2); +#endif + if ((sock = socket(AF_INET, SOCK_STREAM, 0)) < 0) + error(3); + SOCKADDR_IN address; + memset(&address, 0, sizeof (address)); + address.sin_family = AF_INET; + address.sin_addr.s_addr = inet_addr(argv[1]); + address.sin_port = htons(atoi(argv[2])); + fprintf(stderr, "CONNECTING...\n"); + fflush(stderr); + if (connect(sock, (SOCKADDR*)&address, sizeof(address)) < 0) + error(4); + + char buf[MAX_DATA]; + int size; + int messages_count = 0; + + if(argc == 6) passwd(sock, argv[5]); + handshake(sock, argv[3]); + while(size = recv(sock, buf, MAX_DATA-1, 0)) { + buf[size] = '\0'; + //puts(buf); + switch(++messages_count) { + case 1: + case 2: + break; + case 3: + join(sock, argv[4]); + break; + default: + data_handler(buf); + break; + } + } + + return 0; +} + @@ -0,0 +1,38 @@ +# -*- coding: utf-8 -*- +from __future__ import print_function + +def warning(*objs): + print("WARNING: ", *objs, file=sys.stderr) + +import sys +reload(sys) +sys.setdefaultencoding('utf-8') + +msg = sys.argv[1]; + +commands = {} +with open("commands") as f: + for line in f.readlines(): + seperator = line.find("=") + commands[line[:seperator]] = line[seperator+1:] + +seperator = msg.find(" ") + +if msg[0] != '!': + sys.exit(0) + +command = msg[1:seperator].strip() +if command == u"научить": + args = msg.split(" ") + if len(args) >= 3: + if args[2][0] == '!': + args[2][0] = '.' + if args[1] in commands: + print("Команда уже есть.") + else: + with open('commands', 'a') as file: + file.write(args[1] + '=' + ' '.join(args[2:])) + print("Команда записана! Используйте !" + args[1]) +else: + if command in commands: + print (commands[command]) |