aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSergey Nazaryev <sergey@nazaryev.ru>2016-05-18 00:52:10 +0300
committerSergey Nazaryev <sergey@nazaryev.ru>2016-05-18 00:52:10 +0300
commit28994f5e1fb63af77187fc9f99c91a56118f96da (patch)
treefe2fba14584afb3b6e0b38175a6770f067a5e1db
downloadircbot-28994f5e1fb63af77187fc9f99c91a56118f96da.zip
ircbot-28994f5e1fb63af77187fc9f99c91a56118f96da.tar.gz
ircbot-28994f5e1fb63af77187fc9f99c91a56118f96da.tar.bz2
Initial commit.
-rw-r--r--README.md6
-rw-r--r--commands1
-rw-r--r--irc.c178
-rw-r--r--msg.py38
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 @@
+зар=Зар — мой создатель
diff --git a/irc.c b/irc.c
new file mode 100644
index 0000000..470b82a
--- /dev/null
+++ b/irc.c
@@ -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;
+}
+
diff --git a/msg.py b/msg.py
new file mode 100644
index 0000000..c964682
--- /dev/null
+++ b/msg.py
@@ -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])