$ git clone https://tcclient.ion.nu/tc_client.git
commit b727a94707f15923256728a95b926488841c40df
Author: Alicia <...>
Date: Fri Jul 31 23:15:53 2015 +0200
tc_client-gtk and camviewer: added support for captchas
diff --git a/ChangeLog b/ChangeLog
index 1a64135..110da90 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -4,6 +4,7 @@ Send account username in AMF0 "connect" command at startup regardless of whether
If an RTMP chunk already has a buffer allocated when a packet sets the length, free it and start over.
Added support for captchas.
irchack: added a check for whether tc_client is installed or should be run from the source directory (should have been added along with the 'install' target)
+tc_client-gtk and camviewer: added support for captchas
0.34:
Fixed memory alignment in rtmp/amf code (for CPU architectures that are picky about it)
Print version info when called with -v/--version (contributed by Jade)
diff --git a/gtkgui.glade b/gtkgui.glade
index ae7f240..7956c40 100644
--- a/gtkgui.glade
+++ b/gtkgui.glade
@@ -88,6 +88,44 @@
</object>
</child>
</object>
+ <object class="GtkWindow" id="captcha">
+ <property name="can_focus">False</property>
+ <property name="title" translatable="yes">tc_client (captcha)</property>
+ <child>
+ <object class="GtkBox" id="box10">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="orientation">vertical</property>
+ <child>
+ <object class="GtkLabel" id="captcha_link">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="xpad">50</property>
+ <property name="ypad">50</property>
+ <property name="use_markup">True</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkButton" id="captcha_done">
+ <property name="label" translatable="yes">Done</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ </child>
+ </object>
<object class="GtkWindow" id="channelconfig">
<property name="can_focus">False</property>
<property name="title" translatable="yes">tc_client</property>
diff --git a/utilities/camviewer/camviewer.c b/utilities/camviewer/camviewer.c
index 6a72ea4..73fb318 100644
--- a/utilities/camviewer/camviewer.c
+++ b/utilities/camviewer/camviewer.c
@@ -155,6 +155,12 @@ void camera_remove(struct viddata* data, const char* nick)
}
}
+void captcha_done(GtkButton* button, GtkWidget* box)
+{
+ gtk_widget_destroy(box);
+ write(tc_client_in[1], "\n", 1);
+}
+
char buf[1024];
gboolean handledata(GIOChannel* channel, GIOCondition condition, gpointer datap)
{
@@ -197,6 +203,21 @@ gboolean handledata(GIOChannel* channel, GIOCondition condition, gpointer datap)
camera_remove(data, buf);
return 1;
}
+ if(!strncmp(buf, "Captcha: ", 9))
+ {
+ GtkWidget* box=gtk_box_new(GTK_ORIENTATION_VERTICAL, 0);
+ GtkWidget* label=gtk_label_new(0);
+ char link[snprintf(0,0,"Captcha: <a href=\"%s\">%s</a>", &buf[9], &buf[9])+1];
+ sprintf(link, "Captcha: <a href=\"%s\">%s</a>", &buf[9], &buf[9]);
+ gtk_label_set_markup(GTK_LABEL(label), link);
+ gtk_box_pack_start(GTK_BOX(box), label, 0, 0, 0);
+ GtkWidget* button=gtk_button_new_with_label("Done");
+ g_signal_connect(button, "clicked", G_CALLBACK(captcha_done), box);
+ gtk_box_pack_start(GTK_BOX(box), button, 0, 0, 0);
+ gtk_box_pack_start(GTK_BOX(data->box), box, 0, 0, 0);
+ gtk_widget_show_all(box);
+ return 1;
+ }
if(!strncmp(buf, "Starting media stream for ", 26))
{
char* nick=&buf[26];
diff --git a/utilities/gtk/camviewer.c b/utilities/gtk/camviewer.c
index b536ae4..b76d210 100644
--- a/utilities/gtk/camviewer.c
+++ b/utilities/gtk/camviewer.c
@@ -205,11 +205,21 @@ gboolean handledata(GIOChannel* iochannel, GIOCondition condition, gpointer data
}
if(!strncmp(buf, "Connection ID: ", 15)) // Our initial nickname is "guest-" plus our connection ID
{
+ write(tc_client_in[1], "/color\n", 7); // Check which random color tc_client picked
unsigned int length=strlen(&buf[15]);
nickname=malloc(length+strlen("guest-")+1);
sprintf(nickname, "guest-%s", &(buf[15]));
return 1;
}
+ if(!strncmp(buf, "Captcha: ", 9))
+ {
+ gtk_widget_hide(GTK_WIDGET(gtk_builder_get_object(gui, "main")));
+ gtk_widget_show_all(GTK_WIDGET(gtk_builder_get_object(gui, "captcha")));
+ char link[snprintf(0,0,"Captcha: <a href=\"%s\">%s</a>", &buf[9], &buf[9])+1];
+ sprintf(link, "Captcha: <a href=\"%s\">%s</a>", &buf[9], &buf[9]);
+ gtk_label_set_markup(GTK_LABEL(gtk_builder_get_object(gui, "captcha_link")), link);
+ return 1;
+ }
// Start streams once we're properly connected
if(!strncmp(buf, "Currently on cam: ", 18))
{
@@ -851,12 +861,18 @@ void startsession(GtkButton* button, void* x)
}
#endif
if(acc_user[0]){dprintf(tc_client_in[1], "%s\n", acc_pass);}
- write(tc_client_in[1], "/color\n", 7);
GIOChannel* tcchannel=g_io_channel_unix_new(tc_client[0]);
g_io_channel_set_encoding(tcchannel, 0, 0);
g_io_add_watch(tcchannel, G_IO_IN, handledata, data);
}
+void captcha_done(GtkWidget* button, void* x)
+{
+ gtk_widget_hide(GTK_WIDGET(gtk_builder_get_object(gui, "captcha")));
+ gtk_widget_show_all(GTK_WIDGET(gtk_builder_get_object(gui, "main")));
+ write(tc_client_in[1], "\n", 1);
+}
+
int main(int argc, char** argv)
{
if(!strncmp(argv[0], "./", 2)){frombuild=1;}
@@ -998,6 +1014,8 @@ int main(int argc, char** argv)
// Connect signal for tab changing (to un-highlight)
item=GTK_WIDGET(gtk_builder_get_object(gui, "tabs"));
g_signal_connect(item, "switch-page", G_CALLBACK(pm_select), 0);
+ // Connect signal for captcha
+ g_signal_connect(gtk_builder_get_object(gui, "captcha_done"), "clicked", G_CALLBACK(captcha_done), 0);
// Populate saved channels
GtkWidget* startbox=GTK_WIDGET(gtk_builder_get_object(gui, "startbox"));
int channelcount=config_get_int("channelcount");