$ git clone http://tcclient.ion.nu/tc_client.git
commit a2997335eda39e8ea2682039980f6b275a3759cb
Author: Alicia <...>
Date:   Wed May 24 21:57:22 2017 +0200

    Use curl's curl_easy_unescape() for from_owner notices instead of doing it ourselves (contributed by Aida)

diff --git a/ChangeLog b/ChangeLog
index a7aee0c..770d904 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -14,6 +14,7 @@ When getting site and channel from a URL, ignore anything after a slash after th
 Added a /quit command.
 Workaround for the new captcha mechanism.
 Bugfix: use //IGNORE to skip characters instead of freezing if the locale can't represent them.
+Use curl's curl_easy_unescape() for from_owner notices instead of doing it ourselves (contributed by Aida)
 modbot: use https instead of http and use the tcclient subdomain since some DNSes have trouble with underscores.
 modbot: added an option (--no-unapproved) to not add any unapproved videos to queue (videos still get approved by mods requesting or playing them manually)
 tc_client-gtk: fixed a race-condition in the builtin video player.
diff --git a/tinychat.c b/tinychat.c
index ae49299..884ae0e 100644
--- a/tinychat.c
+++ b/tinychat.c
@@ -2,6 +2,7 @@
     tc_client, a simple non-flash client for tinychat(.com)
     Copyright (C) 2014-2017  alicia@ion.nu
     Copyright (C) 2014-2015  Jade Lea
+    Copyright (C) 2017  Aida
 
     This program is free software: you can redistribute it and/or modify
     it under the terms of the GNU Affero General Public License as published by
@@ -21,6 +22,7 @@
 #include <stdio.h>
 #include <fcntl.h>
 #include <time.h>
+#include <curl/curl.h>
 #include "client.h"
 #include "idlist.h"
 #include "rtmp.h"
@@ -454,15 +456,11 @@ static void fromowner(struct amf* amfin, int sock)
   if(amfin->items[2].type!=AMF_STRING){return;}
   if(!strncmp("notice", amfin->items[2].string.string, 6))
   {
-    char* notice=strdup(&amfin->items[2].string.string[6]);
-    // replace "%20" with spaces
-    char* space;
-    while((space=strstr(notice, "%20")))
-    {
-      memmove(space, &space[2], strlen(&space[2])+1);
-      space[0]=' ';
-    }
-    printf("%s %s\n", timestamp(), notice);
+    const char* notice=&amfin->items[2].string.string[6];
+    // Notices are partially URL-encoded, unescape them
+    char* unescaped=curl_easy_unescape(NULL, notice, 0, NULL);
+    printf("%s %s\n", timestamp(), unescaped);
+    curl_free(unescaped);
   }
   else if(!strcmp("mute", amfin->items[2].string.string))
   {