Added the TellHandler.

git-svn-id: svn+ssh://src.earth.threerings.net/narya/trunk@4168 542714f4-19e9-0310-aa3c-eee0fc999fb1
This commit is contained in:
Ray Greenwell
2006-06-01 17:35:23 +00:00
parent 56216c27e8
commit 86dd34a0f4
8 changed files with 203 additions and 65 deletions
@@ -93,11 +93,12 @@ public class ChatDirector extends BasicDirector
}
var msg :MessageBundle = _msgmgr.getBundle(_bundle);
// register our default chat handlers
registerCommandHandler(msg, "help", new HelpHandler(this));
registerCommandHandler(msg, "clear", new ClearHandler(this));
registerCommandHandler(msg, "speak", new SpeakHandler(this));
registerCommandHandler(msg, "emote", new EmoteHandler(this));
registerCommandHandler(msg, "think", new ThinkHandler(this));
registerCommandHandler(msg, "help", new HelpHandler());
registerCommandHandler(msg, "clear", new ClearHandler());
registerCommandHandler(msg, "speak", new SpeakHandler());
registerCommandHandler(msg, "emote", new EmoteHandler());
registerCommandHandler(msg, "think", new ThinkHandler());
registerCommandHandler(msg, "tell", new TellHandler());
}
/**
@@ -320,7 +321,7 @@ public class ChatDirector extends BasicDirector
var cmd :CommandHandler =
(possibleCommands.get(cmdName) as CommandHandler);
var result :String =
cmd.handleCommand(speakSvc, cmdName, args, hist);
cmd.handleCommand(_cctx, speakSvc, cmdName, args, hist);
if (result != ChatCodes.SUCCESS) {
return result;
}
@@ -836,6 +837,15 @@ public class ChatDirector extends BasicDirector
return text;
}
/**
* Check that after mogrification the message is not too long.
* @return an error mesage if it is too long, or null.
*/
internal function checkLength (msg :String) :String
{
return null; // TODO
}
/**
* Returns a hashmap containing all command handlers that match the
* specified command (i.e. the specified command is a prefix of their
@@ -860,6 +870,11 @@ public class ChatDirector extends BasicDirector
return matches;
}
internal function accessHistory () :Array
{
return _history;
}
/**
* Adds a chatter to our list of recent chatters.
*/
@@ -1,23 +1,17 @@
package com.threerings.crowd.chat.client {
import com.threerings.crowd.util.CrowdContext;
import com.threerings.crowd.chat.data.ChatCodes;
public class ClearHandler extends CommandHandler
{
public function ClearHandler (chatdir :ChatDirector)
{
_chatdir = chatdir;
}
public override function handleCommand (
speakSvc :SpeakService, cmd :String, args :String, history :Array)
:String
ctx :CrowdContext, speakSvc :SpeakService,
cmd :String, args :String, history :Array) :String
{
_chatdir.clearDisplays();
ctx.getChatDirector().clearDisplays();
return ChatCodes.SUCCESS;
}
/** Our ChatDirector. */
protected var _chatdir :ChatDirector;
}
}
@@ -1,6 +1,7 @@
package com.threerings.crowd.chat.client {
import com.threerings.crowd.data.BodyObject;
import com.threerings.crowd.util.CrowdContext;
/**
* Used to implement a slash command (e.g. <code>/who</code>).
@@ -26,8 +27,8 @@ public /* abstract */ class CommandHandler
* ChatCodes#SUCCESS}.
*/
public function handleCommand (
speakSvc :SpeakService, cmd :String, args :String, history :Array)
:String
ctx :CrowdContext, speakSvc :SpeakService,
cmd :String, args :String, history :Array) :String
{
throw new Error("abstract");
}
@@ -2,27 +2,22 @@ package com.threerings.crowd.chat.client {
import com.threerings.util.StringUtil;
import com.threerings.crowd.util.CrowdContext;
import com.threerings.crowd.chat.data.ChatCodes;
public class EmoteHandler extends CommandHandler
{
public function EmoteHandler (chatdir :ChatDirector)
{
_chatdir = chatdir;
}
public override function handleCommand (
speakSvc :SpeakService, cmd :String, args :String, history :Array)
:String
ctx :CrowdContext, speakSvc :SpeakService,
cmd :String, args :String, history :Array) :String
{
if (StringUtil.isBlank(args)) {
return "m.usage_emote";
}
history[0] = cmd + " ";
return _chatdir.deliverChat(speakSvc, args, ChatCodes.EMOTE_MODE);
return ctx.getChatDirector().deliverChat(
speakSvc, args, ChatCodes.EMOTE_MODE);
}
/** Our ChatDirector. */
protected var _chatdir :ChatDirector;
}
}
@@ -4,18 +4,15 @@ import com.threerings.util.Map;
import com.threerings.util.MessageBundle;
import com.threerings.util.StringUtil;
import com.threerings.crowd.util.CrowdContext;
import com.threerings.crowd.chat.data.ChatCodes;
public class HelpHandler extends CommandHandler
{
public function HelpHandler (chatdir :ChatDirector)
{
_chatdir = chatdir;
}
public override function handleCommand (
speakSvc :SpeakService, cmd :String, args :String, history :Array)
:String
ctx :CrowdContext, speakSvc :SpeakService,
cmd :String, args :String, history :Array) :String
{
var hcmd :String = "";
@@ -33,16 +30,18 @@ public class HelpHandler extends CommandHandler
hcmd = hcmd.substring(1);
}
var chatdir :ChatDirector = ctx.getChatDirector();
// handle "/help help" and "/help boguscmd"
var possibleCmds :Map = _chatdir.getCommandHandlers(hcmd);
var possibleCmds :Map = chatdir.getCommandHandlers(hcmd);
if ((hcmd === "help") || (possibleCmds.size() == 0)) {
possibleCmds = _chatdir.getCommandHandlers("");
possibleCmds = chatdir.getCommandHandlers("");
possibleCmds.remove("help"); // remove help from the list
}
switch (possibleCmds.size()) {
case 1:
_chatdir.displayFeedback(null, "m.usage_" + possibleCmds.keys()[0]);
chatdir.displayFeedback(null, "m.usage_" + possibleCmds.keys()[0]);
return ChatCodes.SUCCESS;
default:
@@ -55,8 +54,5 @@ public class HelpHandler extends CommandHandler
return MessageBundle.tcompose("m.usage_help", cmdList);
}
}
/** Our ChatDirector. */
protected var _chatdir :ChatDirector;
}
}
@@ -2,27 +2,21 @@ package com.threerings.crowd.chat.client {
import com.threerings.util.StringUtil;
import com.threerings.crowd.util.CrowdContext;
import com.threerings.crowd.chat.data.ChatCodes;
public class SpeakHandler extends CommandHandler
{
public function SpeakHandler (chatdir :ChatDirector)
{
_chatdir = chatdir;
}
public override function handleCommand (
speakSvc :SpeakService, cmd :String, args :String, history :Array)
:String
ctx :CrowdContext, speakSvc :SpeakService,
cmd :String, args :String, history :Array) :String
{
if (StringUtil.isBlank(args)) {
return "m.usage_speak";
}
history[0] = cmd + " ";
return _chatdir.requestChat(null, args, true);
return ctx.getChatDirector().requestChat(null, args, true);
}
/** Our ChatDirector. */
protected var _chatdir :ChatDirector;
}
}
@@ -0,0 +1,148 @@
package com.threerings.crowd.chat.client {
import com.threerings.util.Name;
import com.threerings.util.StringUtil;
import com.threerings.crowd.data.BodyObject;
import com.threerings.crowd.util.CrowdContext;
import com.threerings.crowd.chat.data.ChatCodes;
public class TellHandler extends CommandHandler
{
public override function handleCommand (
ctx :CrowdContext, speakSvc :SpeakService,
cmd :String, args :String, history :Array) :String
{
if (StringUtil.isBlank(args)) {
return "m.usage_tell";
}
var chatdir :ChatDirector = ctx.getChatDirector();
var useQuotes :Boolean = (args.charAt(0) == "\"");
var bits :Array = parseTell(args);
var handle :String = (bits[0] as String);
var message :String = (bits[1] as String);
// validate that we didn't eat all the tokens making the handle
if (StringUtil.isBlank(message)) {
return "m.usage_tell";
}
// make sure we're not trying to tell something to ourselves
var self :BodyObject =
(ctx.getClient().getClientObject() as BodyObject);
if (handle.toLowerCase() ===
self.getVisibleName().toString().toLowerCase()) {
return "m.talk_self";
}
// and lets just give things an opportunity to sanitize the name
var target :Name = normalizeAsName(handle);
// mogrify the chat
message = chatdir.mogrifyChat(message);
var err :String = chatdir.checkLength(message);
if (err != null) {
return err;
}
// clear out from the history any tells that are mistypes
var fullHist :Array = chatdir.accessHistory();
for (var ii :int = fullHist.length - 1; ii >= 0; ii--) {
var hist :String = (fullHist[ii] as String);
if (0 == hist.indexOf("/" + cmd)) {
var harg :String = StringUtil.trim(
hist.substring(cmd.length + 1));
// we blow away any historic tells that have msg content
if (!StringUtil.isBlank(parseTell(harg)[1] as String)) {
fullHist.splice(ii, 1);
}
}
}
// store the full command in the history, even if it was mistyped
var histEntry :String = cmd + " " +
(useQuotes ? ("\"" + target + "\"") : target.toString()) +
" " + message;
history[0] = histEntry;
var rl :ResultListener = new ResultAdapter(
function (result :Object) :void {
// replace the full one in the history with just:
// /tell "<handle>"
var newEntry :String = "/" + cmd + " " +
(useQuotes ? ("\"" + result + "\"")
: result.toString()) + " ";
var fullHist :Array = chatdir.accessHistory();
var dex :int = fullHist.indexOf(newEntry);
if (dex != -1) {
fullHist.splice(dex, 1);
}
var del :int = fullHist.lastIndexOf("/" + histEntry);
if (del >= 0) {
fullHist[del] = newEntry;
} else {
fullHist.push(newEntry);
}
}, null);
chatdir.requestTell(target, message, rl);
return ChatCodes.SUCCESS;
}
/**
* Parse the tell into two strings, handle and message. If either
* one is null then the parsing did not succeed.
*/
protected function parseTell (args :String) :Array
{
var handle :String;
var message :String;
if (args.charAt(0) == "\"") {
var nextQuote :int = args.indexOf("\"", 1);
if (nextQuote == -1 || nextQuote == 1) {
handle = message = null; // bogus parsing
} else {
handle = StringUtil.trim(args.substring(1, nextQuote));
message = StringUtil.trim(args.substring(nextQuote + 1));
}
} else {
var idx :int = args.search(/\s/);
if (idx == -1) {
handle = args;
message = "";
} else {
handle = StringUtil.trim(args.substring(0, idx));
message = StringUtil.trim(args.substring(idx));
}
}
return [ handle, message ];
}
/**
* Turn the user-entered string into a Name object, doing
* any particular normalization we want to do along the way
* so that "/tell Bob" and "/tell BoB" don't both show up in history.
*/
protected function normalizeAsName (handle :String) :Name
{
return new Name(handle);
}
/**
* Escape or otherwise do any final processing on the message
* prior to sending it.
*/
protected function escapeMessage (msg :String) :String
{
return msg;
}
}
}
@@ -2,27 +2,22 @@ package com.threerings.crowd.chat.client {
import com.threerings.util.StringUtil;
import com.threerings.crowd.util.CrowdContext;
import com.threerings.crowd.chat.data.ChatCodes;
public class ThinkHandler extends CommandHandler
{
public function ThinkHandler (chatdir :ChatDirector)
{
_chatdir = chatdir;
}
public override function handleCommand (
speakSvc :SpeakService, cmd :String, args :String, history :Array)
:String
ctx :CrowdContext, speakSvc :SpeakService,
cmd :String, args :String, history :Array) :String
{
if (StringUtil.isBlank(args)) {
return "m.usage_think";
}
history[0] = cmd + " ";
return _chatdir.deliverChat(speakSvc, args, ChatCodes.THINK_MODE);
return ctx.getChatDirector().deliverChat(
speakSvc, args, ChatCodes.THINK_MODE);
}
/** Our ChatDirector. */
protected var _chatdir :ChatDirector;
}
}