<?xml version="1.0" encoding="UTF-8"?>
<commit>
  <added type="array"/>
  <modified type="array">
    <modified>
      <diff>@@ -43,7 +43,12 @@ sub speak {
   my @output;
   if ($target =~ /^#/) {
 # public
-    push @output, &quot;:$global_setting{nickname}!~$global_setting{nickname}\@$global_setting{hostname} PRIVMSG $target :$nick: $_&quot; foreach (split(/\n/, $message));
+    if ($nick){
+      $nick = &quot;$nick:&quot;;
+    } else {
+      $nick = &quot;&quot;;
+    }
+    push @output, &quot;:$global_setting{nickname}!~$global_setting{nickname}\@$global_setting{hostname} PRIVMSG $target :$nick $_&quot; foreach (split(/\n/, $message));
   } else {
 # private
     push @output, &quot;PRIVMSG $nick :$_&quot; foreach (split(/\n/, $message));
@@ -55,6 +60,10 @@ sub error_log {
 	print STDERR &quot;[$$] !! @_\n&quot;;
 }
 
+sub message_log {
+	print STDERR &quot;[$$] ## @_\n&quot;;
+}
+
 sub register_message_func
 {
   my ($command, $func) = @_;
@@ -66,11 +75,9 @@ sub install_message_module
 {
   my @module_file = grep (-x, glob(&quot;$Bin/modules/*&quot;));
   foreach (sort @module_file) {
-#    print STDERR &quot;[$$] ## Loading module $_\n&quot;;
     eval {require $_;};
-    print STDERR &quot;[$$] ## Error on loading module $_: $@&quot; if $@;
+    &amp;error_log(&quot;Error on loading module $_: $@&quot;) if $@;
   }
-  #print STDERR Dumper(\%global_message_func);
 }
 
 sub extract_nick
@@ -85,30 +92,41 @@ sub start_message_loop
 {
   while (&lt;&gt;) {
     s/(\r|\n)$//g;
+    if (m{^\.}) {
+# Control Message
+      &amp;message_log(&quot;&gt;&gt; ctrl_recv: $_&quot;);
+      my ($command, $argument)  = split(/\s+/, $_, 2);
+      my @arguments;
+      @arguments = split(/\s+/, $argument) if $argument;
+      if ($command &amp;&amp; exists $global_message_func{$command}) {
+        my $funcs = $global_message_func{$command};
+        for (my $index = 0; $index &lt; @$funcs; $index++) {
+          eval {
+            $funcs-&gt;[$index]-&gt;(@arguments);
+          };
+          &amp;error_log(&quot;$@&quot;) if $@;
+        }
+      }
+    } else {
+# IRC Message
+      &amp;message_log(&quot;[$$] &gt;&gt; irc_recv: $_&quot;);
 # message template: :pratchett.freenode.net 001 merlin2 :Welcome to the freenode IRC Network merlin2
 # message template: :merlin2!~merlin2@jianing-macbook.local JOIN :#jianingy
 # message tempalte: PING :not.configured
-    print STDERR &quot;[$$] &gt;&gt; irc_recv: $_&quot;.&quot;\n&quot;;
-    m{
-      ^(.)?                       # if it is a control command
-      (?::(\S+))?                 # from
-      (?:^|\s)(\S+)               # command
-      \s(\S+)                     # target
-      (?:\s:(.+))?                # message
-    }xs;
-    my ($is_control, $from, $command, $target, $message) = ($1, $2, $3, $4, $5);
-    #print STDERR &quot;!! $is_control:$from:$command:$target:$message\n&quot;;
-    #print STDERR Dumper(\%global_message_func);
-    if ($is_control) {
-# control message
-    } else {
+      m{
+        (?:^:(\S+))?                # from
+        (?:^|\s)(\S+)               # command
+        \s(\S+)                     # target
+        (?:\s:(.+))?                # message
+      }xs;
+      my ($from, $command, $target, $message) = ($1, $2, $3, $4, $5);
       if ($command &amp;&amp; exists $global_message_func{$command}) {
         my $funcs = $global_message_func{$command};
         for (my $index = 0; $index &lt; @$funcs; $index++) {
           eval {
             $funcs-&gt;[$index]-&gt;($from, $command, $target, $message);
           };
-          print STDERR &quot;!! $@\n&quot; if $@;
+          &amp;error_log(&quot;$@&quot;) if $@;
         }
       }
     }</diff>
      <filename>droids/merlin/core</filename>
    </modified>
    <modified>
      <diff>@@ -25,9 +25,16 @@ sub base_nick_in_use {
     &amp;send_message([&quot;NICK &quot;.&amp;get_nickname()]);
 }
 
+sub base_ctrl_speak {
+	my $target = shift;
+	my $message = join(&quot; &quot;, @_);
+	&amp;speak($target, undef, $message);
+}
+
 
 &amp;register_message_func('376', \&amp;base_join_channel);
 &amp;register_message_func('433', \&amp;base_nick_in_use);
 &amp;register_message_func('PING', \&amp;base_ping);
+&amp;register_message_func('.SPEAK', \&amp;base_ctrl_speak);
 
 1;</diff>
      <filename>droids/merlin/modules/00-base</filename>
    </modified>
  </modified>
  <removed type="array"/>
  <parents type="array">
    <parent>
      <id>66e8e53f318784fbbe64b7b07ab02f27f536ccc9</id>
    </parent>
  </parents>
  <author>
    <name>Jianing Yang</name>
    <email>jianingy.yang@gmail.com</email>
  </author>
  <url>http://github.com/jianingy/idroid/commit/2c39e049c7ef91f7288f7b0c728fc8c1088b69fd</url>
  <id>2c39e049c7ef91f7288f7b0c728fc8c1088b69fd</id>
  <committed-date>2009-10-31T18:55:46-07:00</committed-date>
  <authored-date>2009-10-31T18:55:46-07:00</authored-date>
  <message>added ctrl command support</message>
  <tree>55925e7e4aae21157059bb0587220df120086408</tree>
  <committer>
    <name>Jianing Yang</name>
    <email>jianingy.yang@gmail.com</email>
  </committer>
</commit>
