code: public void speak (ClientObject caller, String message, byte mode)
      {
          // ensure that the caller has normal chat privileges
          BodyObject source = (_locator != null) ? _locator.forClient(caller) :
              (BodyObject) caller;
  
          String errmsg = source.checkAccess(ChatCodes.CHAT_ACCESS, null);
          if (errmsg != null) {
              // we normally don't listen for responses to speak messages so we can't just throw an
              // InvocationException, we have to specifically communicate the error to the user
              SpeakUtil.sendFeedback(source, MessageManager.GLOBAL_BUNDLE, errmsg);
              return;
          }
  
          // TODO: broadcast should be handled more like a system message rather than as a mode for a
          // user message so that we don't have to do this validation here. Or not.
  
          // ensure that the speaker is valid
          if ((mode == ChatCodes.BROADCAST_MODE) ||
              (_validator != null && !_validator.isValidSpeaker(_speakObj, source, mode))) {
              log.warning("Refusing invalid speak request", "source", source.who(),
                          "speakObj", _speakObj.which(), "message", message, "mode", mode);
  
          } else {
              // issue the speak message on our speak object
              sendSpeak(source, message, mode);
          }
      }
docs: from interface SpeakProvider