$ git clone https://tcclient.ion.nu/tc_client.git
commit f0b1b786971d35cebfea30b58e4c9353ed8b786e
Author: Alicia <...>
Date: Tue Apr 7 06:49:01 2015 +0200
Version 0.24
diff --git a/ChangeLog b/ChangeLog
index 1c9f9f1..d5c1eaa 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,10 @@
+0.24:
+Fixed endianness of RTMP set-chunk-size handling.
+modbot: fixed a bug where '!wrongrequest' would claim no request was found when (and only when) the request was last in queue.
+modbot: added the options -d/--daemon and -l/--log plus better handling of -h/--help.
+modbot: moved and changed the note about '!approve entire queue' overuse to a note about making sure none of the videos were inappropriate in the "Queue approved" message.
+camviewer: fixed a bug introduced in 0.23 where audio data was handled improperly, resulting in audio/video data being missed.
+camviewer: ignore 0-byte audio/video packets.
0.23:
Added the moderator commands /mute and /push2talk (contributed by Jade)
Set tc_client as a dependency of utils.
diff --git a/Makefile b/Makefile
index e780924..9735d2d 100644
--- a/Makefile
+++ b/Makefile
@@ -1,4 +1,4 @@
-VERSION=0.23
+VERSION=0.24
CFLAGS=-g3 -Wall $(shell curl-config --cflags)
LIBS=-g3 $(shell curl-config --libs)
ifneq ($(wildcard config.mk),)
diff --git a/rtmp.c b/rtmp.c
index 443a484..4cb900d 100644
--- a/rtmp.c
+++ b/rtmp.c
@@ -114,6 +114,7 @@ char rtmp_get(int sock, struct rtmp* rtmp)
if(chunk->type==RTMP_SET_PACKET_SIZE)
{
memcpy(&chunksize_in, chunk->buf, sizeof(unsigned int));
+ chunksize_in=be32(chunksize_in);
// printf("Server set chunk size to %u (packet size: %u)\n", chunksize_in, chunk->length);
}
// printf("Got chunk: chunkid=%u, type=%u, length=%u, streamid=%u\n", chunk->id, chunk->type, chunk->length, chunk->streamid);
diff --git a/utilities/camviewer/camviewer.c b/utilities/camviewer/camviewer.c
index 2b25607..a1a8a6b 100644
--- a/utilities/camviewer/camviewer.c
+++ b/utilities/camviewer/camviewer.c
@@ -139,8 +139,10 @@ gboolean handledata(GIOChannel* channel, GIOCondition condition, gpointer datap)
char* sizestr=strchr(&buf[7], ' ');
if(!sizestr){return 1;}
unsigned int size=strtoul(&sizestr[1], 0, 0);
+ if(!size){return 1;}
unsigned char frameinfo;
read(tc_client[0], &frameinfo, 1);
+ --size; // For the byte we read above
unsigned char buf[size];
unsigned int pos=0;
while(pos<size)
@@ -160,6 +162,7 @@ gboolean handledata(GIOChannel* channel, GIOCondition condition, gpointer datap)
if(!strcmp(data->cams[i].id, &buf[7])){cam=&data->cams[i]; break;}
}
unsigned int size=strtoul(&sizestr[1], 0, 0);
+ if(!size){return 1;}
// Mostly ignore the first byte (contains frame type (e.g. keyframe etc.) in 4 bits and codec in the other 4)
--size;
AVPacket pkt;
diff --git a/utilities/modbot/modbot.c b/utilities/modbot/modbot.c
index 54a3ac5..5967088 100644
--- a/utilities/modbot/modbot.c
+++ b/utilities/modbot/modbot.c
@@ -150,6 +150,40 @@ void playnext(int x)
int main(int argc, char** argv)
{
+ // Handle arguments (-d, -l, -h additions, the rest are handled by tc_client)
+ char daemon=0;
+ char* logfile=0;
+ unsigned int i;
+ for(i=1; i<argc; ++i)
+ {
+ if(!strcmp(argv[i], "-d") || !strcmp(argv[i], "--daemon"))
+ {
+ daemon=1;
+ // Remove non-tc_client argument
+ --argc;
+ memmove(&argv[i], &argv[i+1], sizeof(char*)*(argc-i));
+ argv[argc]=0;
+ --i;
+ }
+ else if(i+1<argc && (!strcmp(argv[i], "-l") || !strcmp(argv[i], "--log")))
+ {
+ logfile=argv[i+1];
+ // Remove non-tc_client argument
+ argc-=2;
+ memmove(&argv[i], &argv[i+2], sizeof(char*)*(argc-i));
+ argv[argc]=0;
+ --i;
+ }
+ else if(!strcmp(argv[i], "-h") || !strcmp(argv[i], "--help"))
+ {
+ printf("Additional options for modbot:\n"
+ "-d/--daemon = daemonize after startup\n"
+ "-l/--log <file> = log output into <file>\n"
+ "\n");
+ execv("./tc_client", argv);
+ return 1;
+ }
+ }
int in[2];
int out[2];
pipe(in);
@@ -204,6 +238,21 @@ int main(int argc, char** argv)
}
len=0;
// printf("Got line '%s'\n", buf);
+ // Note: daemonizing and setting up logging here to avoid interfering with account password entry
+ if(daemon)
+ {
+ if(fork()){return 0;}
+ daemon=0;
+ if(!logfile){logfile="/dev/null";} // Prevent writing to stdout as a daemon
+ }
+ if(logfile)
+ {
+ int f=open(logfile, O_WRONLY|O_CREAT|O_APPEND, 0600);
+ dup2(f, 1);
+ dup2(f, 2);
+ close(f);
+ logfile=0;
+ }
char* space=strchr(buf, ' ');
if(!space){continue;}
if(!strcmp(space, " is a moderator."))
@@ -301,10 +350,11 @@ int main(int argc, char** argv)
{
queue_del(&queue, queue.items[i].video);
if(!playing && i==0){playnext(0);}
+ i=1; // distinguish from just having reached the front of the queue
break;
}
}
- if(i==queue.itemcount)
+ if(!i)
{
say(pm, "I can't find any request by you, sorry\n");
}
@@ -458,9 +508,9 @@ int main(int argc, char** argv)
{
list_save(&goodvids, "goodvids.txt");
if(!playing){playnext(0);} // Next in queue just got approved, so play it
- else{say(pm, "Queue approved\n");}
+ else{say(pm, "Queue approved. Make sure none of the videos were inappropriate\n");}
}else{
- say(0, "%s: there is nothing in the queue that isn't already approved, please do not overuse this function\n", nick);
+ say(pm, "The queue is already approved (or empty)\n");
}
continue;
}else{