From 3c7ea3a14659330d859c11b408f38bd06f1f467e Mon Sep 17 00:00:00 2001
From: Jeffrey Phillips Freeman <jeffrey.freeman@syncleus.com>
Date: Thu, 18 Apr 2019 14:56:46 -0400
Subject: [PATCH] Moved communication commands over to the new format.

---
 lib/aethyr/core/commands/command_parser.rb |  29 ----
 lib/aethyr/core/commands/communication.rb  | 190 ---------------------
 lib/aethyr/core/commands/say.rb            | 179 +++++++++++++++++++
 lib/aethyr/core/commands/tell.rb           | 105 ++++++++++++
 lib/aethyr/core/commands/whisper.rb        | 104 +++++++++++
 lib/aethyr/core/help/reply.help            |   6 -
 lib/aethyr/core/help/say.help              |  18 --
 lib/aethyr/core/help/sayto.help            |  16 --
 lib/aethyr/core/help/tell.help             |  10 --
 lib/aethyr/core/help/whisper.help          |  15 --
 10 files changed, 388 insertions(+), 284 deletions(-)
 delete mode 100644 lib/aethyr/core/commands/communication.rb
 create mode 100644 lib/aethyr/core/commands/say.rb
 create mode 100644 lib/aethyr/core/commands/tell.rb
 create mode 100644 lib/aethyr/core/commands/whisper.rb
 delete mode 100644 lib/aethyr/core/help/reply.help
 delete mode 100644 lib/aethyr/core/help/say.help
 delete mode 100644 lib/aethyr/core/help/sayto.help
 delete mode 100644 lib/aethyr/core/help/tell.help
 delete mode 100644 lib/aethyr/core/help/whisper.help

diff --git a/lib/aethyr/core/commands/command_parser.rb b/lib/aethyr/core/commands/command_parser.rb
index 3d4a54b..8aad2c6 100644
--- a/lib/aethyr/core/commands/command_parser.rb
+++ b/lib/aethyr/core/commands/command_parser.rb
@@ -7,14 +7,6 @@ include Aethyr::Direction
 #CommandParser parses commands into commands for the event handler.
 module CommandParser
 
-  @communication = Set.new([
-  'say',
-  'sayto',
-  'whisper',
-  'tell',
-  'reply'
-  ])
-
   @movement = Set.new([
   'sit',
   'stand',
@@ -174,8 +166,6 @@ module CommandParser
           parse_weapon_combat input
         elsif @martial_combat.include? command
           parse_martial_combat input
-        elsif @communication.include? command
-          parse_communication input
         elsif @news.include? command
           parse_news input
         elsif @mobile.include? command and player.is_a? Mobile
@@ -199,25 +189,6 @@ module CommandParser
 
     private
 
-    def parse_communication(input)
-      e = case input
-          when /^say\s+(\((.*?)\)\s*)?(.*)$/i
-            { :action => :say, :phrase => $3, :pre => $2 }
-          when /^sayto\s+(\w+)\s+(\((.*?)\)\s*)?(.*)$/i
-            { :action => :say, :target => $1, :phrase => $4, :pre => $3 }
-          when /^whisper\s+(\w+)\s+(\((.*?)\)\s*)?(.*)$/i
-            { :action => :whisper, :to => $1, :phrase => $4, :pre => $3 }
-          when /^tell\s+(\w+)\s+(.*)$/i
-            { :action => :tell, :target => $1, :message => $2 }
-          when /^reply\s+(.*)$/i
-            { :action => :reply, :message => $1 }
-          else
-            nil
-          end
-
-      Event.new(:Communication, e) if e
-    end
-
     def parse_emote(input)
       event = Event.new(:Emote)
 
diff --git a/lib/aethyr/core/commands/communication.rb b/lib/aethyr/core/commands/communication.rb
deleted file mode 100644
index 98dd7dd..0000000
--- a/lib/aethyr/core/commands/communication.rb
+++ /dev/null
@@ -1,190 +0,0 @@
-#Communication commands.
-module Communication
-  class << self
-    #Says something to the room or to a specific player.
-    def say(event, player, room)
-      phrase = event[:phrase]
-      target = event[:target] && room.find(event[:target])
-      prefix = event[:pre]
-
-      if prefix
-        prefix << ", "
-      else
-        prefix = ""
-      end
-
-      if phrase.nil?
-        player.output("Huh?")
-        return
-      elsif event[:target] and target.nil?
-        player.output("Say what to whom?")
-        return
-      elsif target and target == player
-        player.output "Talking to yourself again?"
-        return
-      elsif target
-        to_clause = " to #{target.name}"
-        ask_clause = " #{target.name}"
-      else
-        to_clause = ""
-        ask_clause = ""
-      end
-
-      phrase[0,1] = phrase[0,1].capitalize
-      phrase.gsub!(/(\s|^|\W)(i)(\s|$|\W)/) { |match| match.sub('i', 'I') }
-
-      case phrase
-      when /:\)$/
-        rvoice = "smiles and "
-        pvoice = "smile and "
-      when /:\($/
-        rvoice = "frowns and "
-        pvoice = "frown and "
-      when /:D$/
-        rvoice = "laughs as #{player.pronoun} "
-        pvoice = "laugh as you "
-      else
-        rvoice = ""
-        pvoice = ""
-      end
-
-      phrase = phrase.gsub(/\s*(:\)|:\()|:D/, '').strip.gsub(/\s{2,}/, ' ')
-
-      case phrase[-1..-1]
-      when "!"
-        pvoice += "exclaim"
-        rvoice += "exclaims"
-      when "?"
-        pvoice += "ask"
-        rvoice += "asks"
-      when "."
-        pvoice += "say"
-        rvoice += "says"
-      else
-        pvoice += "say"
-        rvoice += "says"
-        ender = "."
-      end
-
-      phrase = "<say>\"#{phrase}#{ender}\"</say>"
-
-      event[:target] = target
-      if target and pvoice == "ask"
-        event[:to_target] = prefix + "#{player.name} #{rvoice} you, #{phrase}"
-        event[:to_player] = prefix + "you #{pvoice} #{target.name}, #{phrase}"
-        event[:to_other] = prefix + "#{player.name} #{rvoice} #{target.name}, #{phrase}"
-        event[:to_blind_target] = "Someone asks, #{phrase}"
-        event[:to_blind_other] = "Someone asks, #{phrase}"
-        event[:to_deaf_target] = "#{player.name} seems to be asking you something."
-        event[:to_deaf_other] = "#{player.name} seems to be asking #{target.name} something."
-      elsif target
-        event[:to_target] = prefix + "#{player.name} #{rvoice} to you, #{phrase}"
-        event[:to_player] = prefix + "you #{pvoice} to #{target.name}, #{phrase}"
-        event[:to_other] = prefix + "#{player.name} #{rvoice} to #{target.name}, #{phrase}"
-        event[:to_blind_target] = "Someone #{rvoice}, #{phrase}"
-        event[:to_blind_other] = "Someone #{rvoice}, #{phrase}"
-        event[:to_deaf_target] = "You see #{player.name} say something to you."
-        event[:to_deaf_other] = "You see #{player.name} say something to #{target.name}."
-      else
-        event[:to_player] = prefix + "you #{pvoice}, #{phrase}"
-        event[:to_other] = prefix + "#{player.name} #{rvoice}, #{phrase}"
-        event[:to_blind_other] = "Someone #{rvoice}, #{phrase}"
-        event[:to_deaf_target] = "You see #{player.name} say something."
-        event[:to_deaf_other] = "You see #{player.name} say something."
-      end
-
-      room.out_event(event)
-    end
-
-    #Whispers to another thing.
-    def whisper(event, player, room)
-      object = room.find(event[:to], Player)
-
-      if object.nil?
-        player.output("To whom are you trying to whisper?")
-        return
-      elsif object == player
-        player.output("Whispering to yourself again?")
-        event[:to_other] = "#{player.name} whispers to #{player.pronoun(:reflexive)}."
-        room.out_event(event, player)
-        return
-      end
-
-      phrase = event[:phrase]
-
-      if phrase.nil?
-        player.ouput "What are you trying to whisper?"
-        return
-      end
-
-      prefix = event[:pre]
-
-      if prefix
-        prefix << ", "
-      else
-        prefix = ""
-      end
-
-      phrase[0,1] = phrase[0,1].capitalize
-
-      last_char = phrase[-1..-1]
-
-      unless ["!", "?", "."].include? last_char
-        ender = "."
-      end
-
-      phrase = ", <say>\"#{phrase}#{ender}\"</say>"
-
-      event[:target] = object
-      event[:to_player] = prefix + "you whisper to #{object.name}#{phrase}"
-      event[:to_target] = prefix + "#{player.name} whispers to you#{phrase}"
-      event[:to_other] = prefix + "#{player.name} whispers quietly into #{object.name}'s ear."
-      event[:to_other_blind] = "#{player.name} whispers."
-      event[:to_target_blind] = "Someone whispers to you#{phrase}"
-
-      room.out_event(event)
-    end
-
-    #Tells someone something.
-    def tell(event, player, room)
-      target = $manager.find event[:target]
-      unless target and target.is_a? Player
-        player.output "That person is not available."
-        return
-      end
-
-      if target == player
-        player.output "Talking to yourself?"
-        return
-      end
-
-      phrase = event[:message]
-
-      last_char = phrase[-1..-1]
-
-      unless ["!", "?", "."].include? last_char
-        phrase << "."
-      end
-
-      phrase[0,1] = phrase[0,1].upcase
-      phrase = phrase.strip.gsub(/\s{2,}/, ' ')
-
-      player.output "You tell #{target.name}, <tell>\"#{phrase}\"</tell>"
-      target.output "#{player.name} tells you, <tell>\"#{phrase}\"</tell>"
-      target.reply_to = player.name
-    end
-
-    #Reply to a tell.
-    def reply(event, player, room)
-      unless player.reply_to
-        player.output "There is no one to reply to."
-        return
-      end
-
-      event[:target] = player.reply_to
-
-      tell(event, player, room)
-    end
-  end
-end
-
diff --git a/lib/aethyr/core/commands/say.rb b/lib/aethyr/core/commands/say.rb
new file mode 100644
index 0000000..798cbde
--- /dev/null
+++ b/lib/aethyr/core/commands/say.rb
@@ -0,0 +1,179 @@
+require "aethyr/core/registry"
+require "aethyr/core/commands/command_handler"
+
+module Aethyr
+  module Core
+    module Commands
+      module Say
+        class SayHandler < Aethyr::Extend::CommandHandler
+          def initialize(player)
+            super(player, ["say", "sayto"])
+          end
+
+          def self.object_added(data)
+            return unless data[:game_object].is_a? Player
+            data[:game_object].subscribe(SayHandler.new(data[:game_object]))
+          end
+
+          def player_input(data)
+            super(data)
+            case data[:input]
+            when /^say\s+(\((.*?)\)\s*)?(.*)$/i
+              action({ :phrase => $3, :pre => $2 })
+            when /^sayto\s+(\w+)\s+(\((.*?)\)\s*)?(.*)$/i
+              action({:target => $1, :phrase => $4, :pre => $3 })
+            when /^help (sayto)$/i
+              action_help_sayto({})
+            when /^help (say)$/i
+              action_help_say({})
+            end
+          end
+
+          private
+          def action_help_say(event)
+            @player.output <<'EOF'
+Command: Say
+Syntax: SAY [message]
+
+This is the basic command for communication.  Everyone in the room hears what you say.
+Some formatting is automatic, and a few emoticons are supported at the end of the command.
+
+Example: say i like cheese
+Output:  You say, "I like cheese."
+
+Example: say i like cheese! :)
+Output:  You smile and exclaim, "I like cheese!"
+
+You can also specify a prefix in parentheses after the say command.
+
+Example: say (in trepidation) are you going to take my cheese?
+Output:  In trepidation, you ask, "Are you going to take my cheese?"
+
+See also: WHISPER, SAYTO
+EOF
+          end
+
+          def action_help_sayto(event)
+            @player.output <<'EOF'
+Command: Say to
+Syntax: SAYTO [name] [message]
+
+Say something to someone in particular, who is in the same room:
+
+Example:
+
+sayto bob i like cheese
+
+Output:
+
+You say to Bob, "I like cheese."
+
+Also supports the same variations as the SAY command.
+
+See also: WHISPER, SAY
+EOF
+          end
+
+          #Says something to the room or to a specific player.
+          def action(event)
+            room = $manager.get_object(@player.container)
+
+            phrase = event[:phrase]
+            target = event[:target] && room.find(event[:target])
+            prefix = event[:pre]
+
+            if prefix
+              prefix << ", "
+            else
+              prefix = ""
+            end
+
+            if phrase.nil?
+              @player.output("Huh?")
+              return
+            elsif event[:target] and target.nil?
+              @player.output("Say what to whom?")
+              return
+            elsif target and target == @player
+              @player.output "Talking to yourself again?"
+              return
+            elsif target
+              to_clause = " to #{target.name}"
+              ask_clause = " #{target.name}"
+            else
+              to_clause = ""
+              ask_clause = ""
+            end
+
+            phrase[0,1] = phrase[0,1].capitalize
+            phrase.gsub!(/(\s|^|\W)(i)(\s|$|\W)/) { |match| match.sub('i', 'I') }
+
+            case phrase
+            when /:\)$/
+              rvoice = "smiles and "
+              pvoice = "smile and "
+            when /:\($/
+              rvoice = "frowns and "
+              pvoice = "frown and "
+            when /:D$/
+              rvoice = "laughs as #{@player.pronoun} "
+              pvoice = "laugh as you "
+            else
+              rvoice = ""
+              pvoice = ""
+            end
+
+            phrase = phrase.gsub(/\s*(:\)|:\()|:D/, '').strip.gsub(/\s{2,}/, ' ')
+
+            case phrase[-1..-1]
+            when "!"
+              pvoice += "exclaim"
+              rvoice += "exclaims"
+            when "?"
+              pvoice += "ask"
+              rvoice += "asks"
+            when "."
+              pvoice += "say"
+              rvoice += "says"
+            else
+              pvoice += "say"
+              rvoice += "says"
+              ender = "."
+            end
+
+            phrase = "<say>\"#{phrase}#{ender}\"</say>"
+
+            event[:target] = target
+            if target and pvoice == "ask"
+              event[:to_target] = prefix + "#{@player.name} #{rvoice} you, #{phrase}"
+              event[:to_player] = prefix + "you #{pvoice} #{target.name}, #{phrase}"
+              event[:to_other] = prefix + "#{@player.name} #{rvoice} #{target.name}, #{phrase}"
+              event[:to_blind_target] = "Someone asks, #{phrase}"
+              event[:to_blind_other] = "Someone asks, #{phrase}"
+              event[:to_deaf_target] = "#{@player.name} seems to be asking you something."
+              event[:to_deaf_other] = "#{@player.name} seems to be asking #{target.name} something."
+            elsif target
+              event[:to_target] = prefix + "#{@player.name} #{rvoice} to you, #{phrase}"
+              event[:to_player] = prefix + "you #{pvoice} to #{target.name}, #{phrase}"
+              event[:to_other] = prefix + "#{@player.name} #{rvoice} to #{target.name}, #{phrase}"
+              event[:to_blind_target] = "Someone #{rvoice}, #{phrase}"
+              event[:to_blind_other] = "Someone #{rvoice}, #{phrase}"
+              event[:to_deaf_target] = "You see #{@player.name} say something to you."
+              event[:to_deaf_other] = "You see #{@player.name} say something to #{target.name}."
+            else
+              event[:to_player] = prefix + "you #{pvoice}, #{phrase}"
+              event[:to_other] = prefix + "#{@player.name} #{rvoice}, #{phrase}"
+              event[:to_blind_other] = "Someone #{rvoice}, #{phrase}"
+              event[:to_deaf_target] = "You see #{@player.name} say something."
+              event[:to_deaf_other] = "You see #{@player.name} say something."
+            end
+
+            room.out_event(event)
+          end
+        end
+
+        Aethyr::Extend::HandlerRegistry.register_handler(SayHandler)
+      end
+    end
+  end
+end
diff --git a/lib/aethyr/core/commands/tell.rb b/lib/aethyr/core/commands/tell.rb
new file mode 100644
index 0000000..a66f538
--- /dev/null
+++ b/lib/aethyr/core/commands/tell.rb
@@ -0,0 +1,105 @@
+require "aethyr/core/registry"
+require "aethyr/core/commands/command_handler"
+
+module Aethyr
+  module Core
+    module Commands
+      module Tell
+        class TellHandler < Aethyr::Extend::CommandHandler
+          def initialize(player)
+            super(player, ["tell", "reply"])
+          end
+
+          def self.object_added(data)
+            return unless data[:game_object].is_a? Player
+            data[:game_object].subscribe(TellHandler.new(data[:game_object]))
+          end
+
+          def player_input(data)
+            super(data)
+            case data[:input]
+            when /^tell\s+(\w+)\s+(.*)$/i
+              action_tell({:target => $1, :message => $2 })
+            when /^reply\s+(.*)$/i
+              action_reply({:message => $1 })
+            when /^help (tell)$/i
+              action_help_tell({})
+            when /^help (reply)$/i
+              action_help_reply({})
+            end
+          end
+
+          private
+          def action_help_tell(event)
+            @player.output <<'EOF'
+Command: Tell
+Syntax: TELL [player] [message]
+
+All inhabitants of Aethyr have the ability to communicate privately with each other over long distances. This is done through the TELL command. Those who investigate these kinds of things claim there is some kind of latent telepathy in all of us. However, while no one knows for certain how it works, everyone knows it does.
+
+Example:
+TELL Justin Hey, how's it going?
+
+
+See also: SAY, SAYTO, WHISPER, REPLY
+EOF
+          end
+
+          def action_help_reply(event)
+            @player.output <<'EOF'
+Command: Reply
+Syntax: REPLY [message]
+
+Reply is a shortcut to send a tell to the last person who sent you a tell.
+
+See also: TELL
+EOF
+          end
+
+          #Tells someone something.
+          def action_tell(event)
+            target = $manager.find event[:target]
+            unless target and target.is_a? Player
+              @player.output "That person is not available."
+              return
+            end
+
+            if target == @player
+              @player.output "Talking to yourself?"
+              return
+            end
+
+            phrase = event[:message]
+
+            last_char = phrase[-1..-1]
+
+            unless ["!", "?", "."].include? last_char
+              phrase << "."
+            end
+
+            phrase[0,1] = phrase[0,1].upcase
+            phrase = phrase.strip.gsub(/\s{2,}/, ' ')
+
+            @player.output "You tell #{target.name}, <tell>\"#{phrase}\"</tell>"
+            target.output "#{@player.name} tells you, <tell>\"#{phrase}\"</tell>"
+            target.reply_to = @player.name
+          end
+
+          #Reply to a tell.
+          def action_reply(event)
+            unless @player.reply_to
+              @player.output "There is no one to reply to."
+              return
+            end
+
+            event[:target] = @player.reply_to
+
+            action_tell(event)
+          end
+        end
+
+        Aethyr::Extend::HandlerRegistry.register_handler(TellHandler)
+      end
+    end
+  end
+end
diff --git a/lib/aethyr/core/commands/whisper.rb b/lib/aethyr/core/commands/whisper.rb
new file mode 100644
index 0000000..537c785
--- /dev/null
+++ b/lib/aethyr/core/commands/whisper.rb
@@ -0,0 +1,104 @@
+require "aethyr/core/registry"
+require "aethyr/core/commands/command_handler"
+
+module Aethyr
+  module Core
+    module Commands
+      module Whisper
+        class WhisperHandler < Aethyr::Extend::CommandHandler
+          def initialize(player)
+            super(player, ["whisper"])
+          end
+
+          def self.object_added(data)
+            return unless data[:game_object].is_a? Player
+            data[:game_object].subscribe(WhisperHandler.new(data[:game_object]))
+          end
+
+          def player_input(data)
+            super(data)
+            case data[:input]
+            when /^whisper\s+(\w+)\s+(\((.*?)\)\s*)?(.*)$/i
+              action({ :to => $1, :phrase => $4, :pre => $3 })
+            when /^help (whisper)$/i
+              action_help({})
+            end
+          end
+
+          private
+          def action_help(event)
+            @player.output <<'EOF'
+Command: Whisper
+Syntax: WHISPER [person] [message]
+
+To communicate with someone in the same room, but privately, use this command.
+
+Example:
+
+whisper justin that dog needs a bath
+
+Output:
+
+You whisper to Justin, "That dog needs a bath."
+
+
+See also: SAY
+EOF
+          end
+
+          #Whispers to another thing.
+          def action(event)
+            room = $manager.get_object(@player.container)
+            object = room.find(event[:to], Player)
+
+            if object.nil?
+              @player.output("To whom are you trying to whisper?")
+              return
+            elsif object == @player
+              @player.output("Whispering to yourself again?")
+              event[:to_other] = "#{@player.name} whispers to #{@player.pronoun(:reflexive)}."
+              room.out_event(event, @player)
+              return
+            end
+
+            phrase = event[:phrase]
+
+            if phrase.nil?
+              @player.ouput "What are you trying to whisper?"
+              return
+            end
+
+            prefix = event[:pre]
+
+            if prefix
+              prefix << ", "
+            else
+              prefix = ""
+            end
+
+            phrase[0,1] = phrase[0,1].capitalize
+
+            last_char = phrase[-1..-1]
+
+            unless ["!", "?", "."].include? last_char
+              ender = "."
+            end
+
+            phrase = ", <say>\"#{phrase}#{ender}\"</say>"
+
+            event[:target] = object
+            event[:to_player] = prefix + "you whisper to #{object.name}#{phrase}"
+            event[:to_target] = prefix + "#{@player.name} whispers to you#{phrase}"
+            event[:to_other] = prefix + "#{@player.name} whispers quietly into #{object.name}'s ear."
+            event[:to_other_blind] = "#{@player.name} whispers."
+            event[:to_target_blind] = "Someone whispers to you#{phrase}"
+
+            room.out_event(event)
+          end
+        end
+
+        Aethyr::Extend::HandlerRegistry.register_handler(WhisperHandler)
+      end
+    end
+  end
+end
diff --git a/lib/aethyr/core/help/reply.help b/lib/aethyr/core/help/reply.help
deleted file mode 100644
index ab61018..0000000
--- a/lib/aethyr/core/help/reply.help
+++ /dev/null
@@ -1,6 +0,0 @@
-Command: Reply
-Syntax: REPLY <message>
-
-Reply is a shortcut to send a tell to the last person who sent you a tell.
-
-See also: TELL
diff --git a/lib/aethyr/core/help/say.help b/lib/aethyr/core/help/say.help
deleted file mode 100644
index 9c68186..0000000
--- a/lib/aethyr/core/help/say.help
+++ /dev/null
@@ -1,18 +0,0 @@
-Command: Say
-Syntax: SAY <message>
-
-This is the basic command for communication.  Everyone in the room hears what you say.
-Some formatting is automatic, and a few emoticons are supported at the end of the command.
-
-Example: say i like cheese
-Output:  You say, "I like cheese."
-
-Example: say i like cheese! :)
-Output:  You smile and exclaim, "I like cheese!"
-
-You can also specify a prefix in parentheses after the say command.
-
-Example: say (in trepidation) are you going to take my cheese?
-Output:  In trepidation, you ask, "Are you going to take my cheese?"
-
-See also: WHISPER, SAYTO
diff --git a/lib/aethyr/core/help/sayto.help b/lib/aethyr/core/help/sayto.help
deleted file mode 100644
index 8157465..0000000
--- a/lib/aethyr/core/help/sayto.help
+++ /dev/null
@@ -1,16 +0,0 @@
-Command: Say to
-Syntax: SAYTO <name> <message>
-
-Say something to someone in particular, who is in the same room:
-
-Example:
-
-sayto bob i like cheese
-
-Output:
-
-You say to Bob, "I like cheese."
-
-Also supports the same variations as the SAY command.
-
-See also: WHISPER, SAY
diff --git a/lib/aethyr/core/help/tell.help b/lib/aethyr/core/help/tell.help
deleted file mode 100644
index 8eb5665..0000000
--- a/lib/aethyr/core/help/tell.help
+++ /dev/null
@@ -1,10 +0,0 @@
-Command: Tell
-Syntax: TELL <player> <message>
-
-All inhabitants of Aethyr have the ability to communicate privately with each other over long distances. This is done through the TELL command. Those who investigate these kinds of things claim there is some kind of latent telepathy in all of us. However, while no one knows for certain how it works, everyone knows it does.
-
-Example:
-TELL Justin Hey, how's it going?
-
-
-See also: SAY, SAYTO, WHISPER, REPLY
diff --git a/lib/aethyr/core/help/whisper.help b/lib/aethyr/core/help/whisper.help
deleted file mode 100644
index fa4806a..0000000
--- a/lib/aethyr/core/help/whisper.help
+++ /dev/null
@@ -1,15 +0,0 @@
-Command: Whisper
-Syntax: WHISPER <person> <message>
-
-To communicate with someone in the same room, but privately, use this command.
-
-Example:
-
-whisper justin that dog needs a bath
-
-Output:
-
-You whisper to Justin, "That dog needs a bath."
-
-
-See also: SAY
-- 
GitLab