$ git clone http://tcclient.ion.nu/tc_client.git
commit 558b36edfa2066bdc6f418eab32bd8280bb15e7d
Author: Alicia <...>
Date: Tue Apr 7 06:49:01 2015 +0200
Version 0.8
diff --git a/ChangeLog b/ChangeLog
index 6eaf8e9..5079b35 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,7 @@
+0.8:
+irchack: convert tc_client's ANSI codes to IRC color codes.
+irchack: convert IRC color codes to '/color <number>' commands for tc_client.
+Made it possible to turn off/on colors being displayed with '/color off' and '/color on'
0.7:
Added command handling (/color <number>, /colors, /nick <newnick>, and adding the privacy field for /msg)
0.6:
diff --git a/Makefile b/Makefile
index 75a8eb9..76be707 100644
--- a/Makefile
+++ b/Makefile
@@ -1,4 +1,4 @@
-VERSION=0.7
+VERSION=0.8
CFLAGS=-g3 -Wall $(shell curl-config --cflags)
LIBS=-g3 $(shell curl-config --libs)
diff --git a/client.c b/client.c
index 97dfe99..5fddd11 100644
--- a/client.c
+++ b/client.c
@@ -39,6 +39,8 @@ struct writebuf
int len;
};
+char showcolor=1;
+
unsigned int flip(unsigned int bits, int bytecount)
{
unsigned int ret=0;
@@ -271,6 +273,7 @@ int main(int argc, char** argv)
{
pfd[0].revents=0;
len=read(0, buf, 2047);
+ if(len<1){break;}
while(len>0 && (buf[len-1]=='\n'||buf[len-1]=='\r')){--len;}
if(!len){continue;} // Don't send empty lines
buf[len]=0;
@@ -282,6 +285,8 @@ int main(int argc, char** argv)
{
if(buf[6]) // Color specified
{
+ if(!strcmp((char*)&buf[7], "off")){showcolor=0; continue;}
+ if(!strcmp((char*)&buf[7], "on")){showcolor=1; continue;}
currentcolor=atoi((char*)&buf[7]);
printf("\x1b[%smChanged color\x1b[0m\n", termcolors[currentcolor%16]);
}else{ // No color specified, state our current color
@@ -397,7 +402,7 @@ int main(int argc, char** argv)
else if(amfin->itemcount>5 && amfin->items[0].type==AMF_STRING && amf_comparestrings_c(&amfin->items[0].string, "privmsg") && amfin->items[3].type==AMF_STRING && amfin->items[4].type==AMF_STRING && amfin->items[5].type==AMF_STRING)
{
wchar_t* msg=fromnumlist(amfin->items[3].string.string);
- const char* color=resolvecolor(amfin->items[4].string.string);
+ const char* color=(showcolor?resolvecolor(amfin->items[4].string.string):"0");
printf("%s \x1b[%sm%s: %ls\x1b[0m\n", timestamp(), color, amfin->items[5].string.string, msg);
free(msg);
fflush(stdout);
@@ -480,5 +485,6 @@ int main(int argc, char** argv)
}
// ++outnum; (Debugging)
}
+ close(sock);
return 0;
}
diff --git a/irchack.c b/irchack.c
index 7257bda..92ce025 100644
--- a/irchack.c
+++ b/irchack.c
@@ -21,6 +21,61 @@
#include <stdlib.h>
#include <stdio.h>
#include <sys/socket.h>
+#include <ctype.h>
+
+// ANSI colors and their IRC equivalents
+struct color{const char* ansi; const char* irc;};
+struct color colortable[]={
+ {"31", "\x03""05"},
+ {"31;1", "\x03""04"},
+ {"33", "\x03""07"},
+ {"33", "\x03""07"},
+ {"33;1", "\x03""08"},
+ {"32;1", "\x03""09"},
+ {"32;1", "\x03""09"},
+ {"32", "\x03""03"},
+ {"36", "\x03""10"},
+ {"34;1", "\x03""12"},
+ {"34;1", "\x03""12"},
+ {"34", "\x03""02"},
+ {"35", "\x03""06"},
+ {"35;1", "\x03""13"},
+ {"35;1", "\x03""13"},
+ {"35;1", "\x03""13"}
+};
+
+const char* findcolor_irc(const char* ansi)
+{
+ int len;
+ for(len=0; ansi[len]&&ansi[len]!='m'; ++len);
+ int i;
+ for(i=0; i<16; ++i)
+ {
+ if(!strncmp(colortable[i].ansi, ansi, len) && !colortable[i].ansi[len])
+ {
+ return colortable[i].irc;
+ }
+ }
+ return 0;
+}
+
+int findcolor_ansi(char* irc, char** end)
+{
+ char color[4];
+ strncpy(color, irc, 3);
+ color[3]=0;
+ if(!isdigit(color[1])){*end=&irc[1]; return -1;}
+ if(!isdigit(color[2])){*end=&irc[2]; color[2]=color[1]; color[1]='0';}else{*end=&irc[3];}
+ int i;
+ for(i=0; i<16; ++i)
+ {
+ if(!strcmp(colortable[i].irc, color))
+ {
+ return i;
+ }
+ }
+ return -1;
+}
int main(int argc, char** argv)
{
@@ -146,13 +201,16 @@ printf("Got from tc_client: '%s'\n", buf);
continue;
}
if(buf[0]!='['){continue;} // Beyond this we only care about timestamped lines
- // Strip out ANSI escape codes (TODO: translate them to IRC color codes instead)
+ // Translate ANSI escape codes to IRC color code instead
char* ansi;
+ const char* color="";
while((ansi=strstr(buf, "\x1b[")))
{
int len;
for(len=0; ansi[len]&&ansi[len]!='m'; ++len);
if(ansi[len]=='m'){++len;}
+ const char* c=findcolor_irc(&ansi[2]);
+ if(c){color=c;}
memmove(ansi, &ansi[len], strlen(&ansi[len])+1);
}
@@ -171,9 +229,9 @@ printf("Got from tc_client: '%s'\n", buf);
msg=strchr(&msg[5], ' ');
if(!msg){continue;}
msg=&msg[1];
- dprintf(sock, ":%s!user@host PRIVMSG %s :%s\n", name, nick, msg);
+ dprintf(sock, ":%s!user@host PRIVMSG %s :%s%s\n", name, nick, color, msg);
}else{ // Regular channel message
- dprintf(sock, ":%s!user@host PRIVMSG #%s :%s\n", name, channel, msg);
+ dprintf(sock, ":%s!user@host PRIVMSG #%s :%s%s\n", name, channel, color, msg);
}
}else{ // action, parse the actions and send them as JOINs, NICKs and QUITs etc. instead
msg[0]=0;
@@ -206,7 +264,6 @@ printf("Got from tc_client: '%s'\n", buf);
++len;
}
if(len<=0){continue;}
- while(len>0 && (buf[len-1]=='\n'||buf[len-1]=='\r')){--len;}
buf[len]=0;
printf("Got from IRC client: '%s'\n", buf);
if(!strncmp(buf, "PRIVMSG ", 8))
@@ -217,6 +274,14 @@ printf("Got from IRC client: '%s'\n", buf);
msg[0]=0;
msg=&msg[1];
if(msg[0]==':'){msg=&msg[1];}
+ char* color;
+ while((color=strchr(msg, '\x03')))
+ {
+ char* end;
+ int c=findcolor_ansi(color, &end);
+ if(c!=-1){dprintf(tc_in[1], "/color %i\n", c);}
+ memmove(color, end, strlen(end)+1);
+ }
if(target[0]=='#' && !strcmp(&target[1], channel))
{
dprintf(tc_in[1], "%s\n", msg);
@@ -234,9 +299,12 @@ printf("Got from IRC client: '%s'\n", buf);
{
dprintf(sock, ":irchack PONG %s\n", &buf[5]);
}
+ else if(!strncmp(buf, "QUIT ", 5)){break;}
}
}
+ close(tc_in[1]);
+ close(tc_out[0]);
shutdown(sock, SHUT_RDWR);
return 0;
}