$ git clone https://tcclient.ion.nu/tc_client.git
commit c23b9dbbd53766d67989338142bd8e5696671c1a
Author: Alicia <...>
Date: Tue Apr 7 06:49:01 2015 +0200
Version 0.19
diff --git a/ChangeLog b/ChangeLog
index 179ed1f..cd2abe0 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,10 @@
+0.19:
+Got unicode characters working, as it turns out tinychat doesn't use ISO-8859-1 but UTF-16 (which shares character codes with ISO-8859-1 below 256)
+Enable keepalive on the TCP socket.
+irchack: end session upon bad reads from tc_client.
+modbot: handle playlist links properly (youtube-dl gives us a newline-separated list of IDs)
+modbot: added '!approve entire queue', mostly for playlists.
+modbot: allow searching for ID also in !badvid
0.18:
This release only affects modbot:
Switched to using youtube-dl for getting IDs (including proper searching)
diff --git a/Makefile b/Makefile
index 25bad9c..105b5d1 100644
--- a/Makefile
+++ b/Makefile
@@ -1,4 +1,4 @@
-VERSION=0.18
+VERSION=0.19
CFLAGS=-g3 -Wall $(shell curl-config --cflags)
LIBS=-g3 $(shell curl-config --libs)
ifneq ($(wildcard config.mk),)
diff --git a/client.c b/client.c
index a8a25a5..7df618d 100644
--- a/client.c
+++ b/client.c
@@ -24,6 +24,7 @@
#include <netinet/in.h>
#include <netdb.h>
#include <poll.h>
+#include <sys/socket.h>
#include <locale.h>
#include <ctype.h>
#include <curl/curl.h>
@@ -257,6 +258,8 @@ int main(int argc, char** argv)
return 1;
}
freeaddrinfo(res);
+ i=1;
+ setsockopt(sock, SOL_SOCKET, SO_KEEPALIVE, &i, sizeof(i));
int random=open("/dev/urandom", O_RDONLY);
// RTMP handshake
unsigned char handshake[1536];
diff --git a/irchack.c b/irchack.c
index dca0f14..fa527f8 100644
--- a/irchack.c
+++ b/irchack.c
@@ -233,11 +233,13 @@ char session(int sock, const char* nick, const char* channel, const char* pass,
{
pfd[0].revents=0;
len=0;
+ int r;
while(len<2047)
{
- if(read(tc_out[0], &buf[len], 1)!=1 || buf[len]=='\r' || buf[len]=='\n'){break;}
+ if((r=read(tc_out[0], &buf[len], 1))!=1 || buf[len]=='\r' || buf[len]=='\n'){break;}
++len;
}
+ if(r!=1){break;}
buf[len]=0;
printf("Got from tc_client: '%s'\n", buf);
if(!strncmp(buf, "Currently online: ", 18))
diff --git a/modbot.c b/modbot.c
index 2f25305..d6b8dde 100644
--- a/modbot.c
+++ b/modbot.c
@@ -41,23 +41,37 @@ int tc_client;
void list_del(struct list* list, const char* item)
{
unsigned int i;
- for(i=0; i<list->itemcount; ++i)
+ unsigned int len;
+ while(item[0])
{
- if(!strcmp(list->items[i], item))
+ if(item[0]=='\r' || item[0]=='\n'){item=&item[1]; continue;} // Skip empty lines
+ for(len=0; item[len] && item[len]!='\r' && item[len]!='\n'; ++len);
+ for(i=0; i<list->itemcount; ++i)
{
- free(list->items[i]);
- --list->itemcount;
- memmove(&list->items[i], &list->items[i+1], sizeof(char*)*(list->itemcount-i));
+ if(!strncmp(list->items[i], item, len) && !list->items[i][len])
+ {
+ free(list->items[i]);
+ --list->itemcount;
+ memmove(&list->items[i], &list->items[i+1], sizeof(char*)*(list->itemcount-i));
+ }
}
+ item=&item[len];
}
}
void list_add(struct list* list, const char* item)
{
list_del(list, item);
- ++list->itemcount;
- list->items=realloc(list->items, sizeof(char*)*list->itemcount);
- list->items[list->itemcount-1]=strdup(item);
+ unsigned int len;
+ while(item[0])
+ {
+ if(item[0]=='\r' || item[0]=='\n'){item=&item[1]; continue;} // Skip empty lines
+ for(len=0; item[len] && item[len]!='\r' && item[len]!='\n'; ++len);
+ ++list->itemcount;
+ list->items=realloc(list->items, sizeof(char*)*list->itemcount);
+ list->items[list->itemcount-1]=strndup(item, len);
+ item=&item[len];
+ }
}
void list_switch(struct list* list, char* olditem, char* newitem)
@@ -76,9 +90,16 @@ void list_switch(struct list* list, char* olditem, char* newitem)
int list_getpos(struct list* list, char* item)
{
int i;
- for(i=0; i<list->itemcount; ++i)
+ unsigned int len;
+ while(item[0])
{
- if(!strcmp(list->items[i], item)){return i;}
+ if(item[0]=='\r' || item[0]=='\n'){item=&item[1]; continue;} // Skip empty lines
+ for(len=0; item[len] && item[len]!='\r' && item[len]!='\n'; ++len);
+ for(i=0; i<list->itemcount; ++i)
+ {
+ if(!strncmp(list->items[i], item, len) && !list->items[i][len]){return i;}
+ }
+ item=&item[len];
}
return -1;
}
@@ -307,12 +328,23 @@ int main(int argc, char** argv)
if(!strncmp(msg, "!request ", 9))
{
char title[256];
- char vid[256];
- getvidinfo(&msg[9], "--get-id", vid, 256);
+ char vid[1024];
+ getvidinfo(&msg[9], "--get-id", vid, 1024);
if(!vid[0]){say(pm, "No video found, sorry\n"); continue;} // Nothing found
- getvidinfo(vid, "--get-title", title, 256);
+ char* plist;
+ for(plist=vid; plist[0] && plist[0]!='\r' && plist[0]!='\n'; plist=&plist[1]);
+ if(plist[0]) // Link was a playlist, do some trickery to get the title of the first video (instead of getting nothing)
+ {
+ strcpy(title, "Playlist, starting with ");
+ plist[0]=0;
+ getvidinfo(vid, "--get-title", &title[24], 256-24);
+ plist[0]='\n';
+ }else{
+ plist=0;
+ getvidinfo(vid, "--get-title", title, 256);
+ }
printf("Requested ID '%s' by '%s'\n", vid, nick);
- // Check if it's already queued and mention which spot it's in
+ // Check if it's already queued and mention which spot it's in, or if it's marked as bad and shouldn't be queued
int pos;
if((pos=list_getpos(&queue, vid))>-1)
{
@@ -324,20 +356,23 @@ int main(int argc, char** argv)
say(pm, "Video '%s' is marked as bad, won't add to queue\n", title);
continue;
}
- if(list_contains(&mods, nick))
+ if(list_contains(&mods, nick)) // Auto-approve for mods
{
-// printf("is mod, video auto-approved\n");
list_add(&goodvids, vid);
list_del(&badvids, vid);
list_save(&goodvids, "goodvids.txt");
list_save(&badvids, "badvids.txt");
- list_add(&queue, vid);
- }else{ // Not a mod
- list_add(&queue, vid);
}
+
+ list_add(&queue, vid);
if(!list_contains(&goodvids, vid))
{
- say(pm, "Video '%s' (%s) is added to the queue but will need to be approved by mods\n", vid, title);
+ if(plist)
+ {
+ say(pm, "Playlist '%s' is added to the queue but will need to be approved by a mod\n", title);
+ }else{
+ say(pm, "Video '%s' (%s) is added to the queue but will need to be approved by a mod\n", vid, title);
+ }
}
else if(!playing){playnext(0);}
else{say(pm, "Added to queue\n");}
@@ -390,6 +425,7 @@ int main(int argc, char** argv)
usleep(100000);
say(nick, "!approve <link> = mark the specified video as okay\n");
say(nick, "!approve next = mark the next not yet approved video as okay\n");
+ say(nick, "!approve entire queue = approve all videos in queue (for playlists)\n");
usleep(100000);
say(nick, "!badvid = stop playing the current video and mark it as bad\n");
usleep(100000);
@@ -435,6 +471,25 @@ int main(int argc, char** argv)
if(!list_contains(&goodvids, queue.items[i])){vid=queue.items[i]; break;}
}
if(i==queue.itemcount){say(pm, "Nothing more to approve :)\n"); continue;}
+ }
+ else if(!strcmp(vid, "entire queue"))
+ {
+ char approved=0;
+ unsigned int i;
+ for(i=0; i<queue.itemcount; ++i)
+ {
+ if(list_contains(&goodvids, queue.items[i])){continue;}
+ list_add(&goodvids, queue.items[i]);
+ approved=1;
+ }
+ if(approved)
+ {
+ list_save(&goodvids, "goodvids.txt");
+ if(!playing){playnext(0);} // Next in queue just got approved, so play it
+ }else{
+ say(0, "%s: there is nothing in the queue that isn't already approved, please do not overuse this function\n", nick);
+ }
+ continue;
}else{
getvidinfo(vid, "--get-id", vidbuf, 256);
vid=vidbuf;
@@ -447,14 +502,19 @@ int main(int argc, char** argv)
}
else if(!strcmp(msg, "!badvid") || !strncmp(msg, "!badvid ", 8))
{
- char* vid=(msg[7]?&msg[8]:playing);
- if(!vid){say(pm, "Nothing is playing, please use !badvid <URL/ID> instead\n"); continue;}
+ if(!msg[7] && !playing){say(pm, "Nothing is playing, please use !badvid <URL/ID> instead\n"); continue;}
+ char vid[1024];
+ if(msg[7])
+ {
+ getvidinfo(&msg[8], "--get-id", vid, 256);
+ }else{strncpy(vid, playing, 1023); vid[1023]=0;}
+ if(!vid[0]){say(pm, "Video not found, sorry\n");}
list_del(&queue, vid);
list_del(&goodvids, vid);
list_add(&badvids, vid);
list_save(&goodvids, "goodvids.txt");
list_save(&badvids, "badvids.txt");
- if(vid==playing){say(0, "/mbc youTube\n"); playnext(0);}
+ if(!strcmp(vid, playing)){say(0, "/mbc youTube\n"); playnext(0);}
}
else if(!strncmp(msg, "/mbs youTube ", 13))
{
diff --git a/numlist.c b/numlist.c
index 5051d26..b6b15e5 100644
--- a/numlist.c
+++ b/numlist.c
@@ -31,7 +31,7 @@ char* fromnumlist(char* in, size_t* outlen)
++len;
x=&x[1];
}
- char string[len+1];
+ unsigned short string[len+1];
int i;
for(i=0; i<len; ++i)
{
@@ -41,12 +41,13 @@ char* fromnumlist(char* in, size_t* outlen)
}
string[len]=0;
- iconv_t cd=iconv_open("", "iso-8859-1");
+ iconv_t cd=iconv_open("", "utf-16");
char* outbuf=malloc(len*4);
char* i_out=outbuf;
- char* i_in=string;
+ char* i_in=(char*)string;
size_t remaining=len*4;
*outlen=remaining;
+ len*=2; // 2 bytes per number/character in utf-16
while(outlen>0 && len>0 && iconv(cd, &i_in, &len, &i_out, &remaining)>0);
i_out[0]=0; // null-terminates 'outbuf'
iconv_close(cd);
@@ -56,21 +57,21 @@ char* fromnumlist(char* in, size_t* outlen)
char* tonumlist(char* i_in, size_t len)
{
- iconv_t cd=iconv_open("iso-8859-1", "");
- char in[len+1];
- char* i_out=in;
- size_t outlen=len;
+ iconv_t cd=iconv_open("utf-16le", "");
+ unsigned short in[len+1];
+ char* i_out=(char*)in;
+ size_t outlen=len*2; // 2 bytes per character in utf-16
while(outlen>0 && len>0 && iconv(cd, &i_in, &len, &i_out, &outlen)>0);
- i_out[0]=0; // null-terminates the 'in' buffer
iconv_close(cd);
+ len=((void*)i_out-(void*)in)/2;
- char* out=malloc(strlen(in)*strlen("255,"));
+ char* out=malloc(len*strlen("65535,"));
out[0]=0;
char* x=out;
int i;
- for(i=0; in[i]; ++i)
+ for(i=0; i<len; ++i)
{
- sprintf(x, "%s%i", x==out?"":",", (int)in[i]&0xff);
+ sprintf(x, "%s%u", x==out?"":",", (unsigned int)in[i]&0xffff);
x=&x[strlen(x)];
}
return out;