All the latest and ... well, the latest anyway.
git-svn-id: svn+ssh://src.earth.threerings.net/narya/trunk@3950 542714f4-19e9-0310-aa3c-eee0fc999fb1
This commit is contained in:
@@ -23,37 +23,8 @@ package com.threerings.crowd.chat.client {
|
|||||||
|
|
||||||
import mx.collections.ArrayCollection;
|
import mx.collections.ArrayCollection;
|
||||||
|
|
||||||
|
import com.threerings.util.ArrayUtil;
|
||||||
// TODO: this class is in progress
|
import com.threerings.util.SimpleMap;
|
||||||
//
|
|
||||||
//
|
|
||||||
//
|
|
||||||
//
|
|
||||||
//
|
|
||||||
//
|
|
||||||
//
|
|
||||||
//
|
|
||||||
//
|
|
||||||
//
|
|
||||||
//
|
|
||||||
//
|
|
||||||
//
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.Arrays;
|
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.Iterator;
|
|
||||||
import java.util.LinkedList;
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.StringTokenizer;
|
|
||||||
import java.util.regex.Matcher;
|
|
||||||
import java.util.regex.Pattern;
|
|
||||||
|
|
||||||
import com.samskivert.util.Collections;
|
|
||||||
import com.samskivert.util.HashIntMap;
|
|
||||||
import com.samskivert.util.ObserverList;
|
|
||||||
import com.samskivert.util.ResultListener;
|
|
||||||
import com.samskivert.util.StringUtil;
|
|
||||||
|
|
||||||
import com.threerings.presents.client.BasicDirector;
|
import com.threerings.presents.client.BasicDirector;
|
||||||
import com.threerings.presents.client.Client;
|
import com.threerings.presents.client.Client;
|
||||||
@@ -104,12 +75,12 @@ public class ChatDirector extends BasicDirector
|
|||||||
super(ctx);
|
super(ctx);
|
||||||
|
|
||||||
// keep the context around
|
// keep the context around
|
||||||
_ctx = ctx;
|
_cctx = ctx;
|
||||||
_msgmgr = msgmgr;
|
_msgmgr = msgmgr;
|
||||||
_bundle = bundle;
|
_bundle = bundle;
|
||||||
|
|
||||||
// register ourselves as a location observer
|
// register ourselves as a location observer
|
||||||
_ctx.getLocationDirector().addLocationObserver(this);
|
_cctx.getLocationDirector().addLocationObserver(this);
|
||||||
|
|
||||||
if (_bundle == null || _msgmgr == null) {
|
if (_bundle == null || _msgmgr == null) {
|
||||||
Log.warning("Null bundle or message manager given to ChatDirector");
|
Log.warning("Null bundle or message manager given to ChatDirector");
|
||||||
@@ -252,18 +223,6 @@ public class ChatDirector extends BasicDirector
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Display a system INFO message as if it had come from the server.
|
|
||||||
* The localtype of the message will be PLACE_CHAT_TYPE.
|
|
||||||
*
|
|
||||||
* Info messages are sent when something happens that was neither
|
|
||||||
* directly triggered by the user, nor requires direct action.
|
|
||||||
*/
|
|
||||||
public function displayInfo (bundle :String, message :String) :void
|
|
||||||
{
|
|
||||||
displaySystem(bundle, message, SystemMessage.INFO, PLACE_CHAT_TYPE);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Display a system INFO message as if it had come from the server.
|
* Display a system INFO message as if it had come from the server.
|
||||||
*
|
*
|
||||||
@@ -271,8 +230,11 @@ public class ChatDirector extends BasicDirector
|
|||||||
* directly triggered by the user, nor requires direct action.
|
* directly triggered by the user, nor requires direct action.
|
||||||
*/
|
*/
|
||||||
public function displayInfo (
|
public function displayInfo (
|
||||||
bundle :String, message :String, localtype :String) :void
|
bundle :String, message :String, localtype :String = null) :void
|
||||||
{
|
{
|
||||||
|
if (localtype == null) {
|
||||||
|
localtype = ChatCodes.PLACE_CHAT_TYPE;
|
||||||
|
}
|
||||||
displaySystem(bundle, message, SystemMessage.INFO, localtype);
|
displaySystem(bundle, message, SystemMessage.INFO, localtype);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -415,7 +377,7 @@ public class ChatDirector extends BasicDirector
|
|||||||
}
|
}
|
||||||
|
|
||||||
// dispatch a speak request using the supplied speak service
|
// dispatch a speak request using the supplied speak service
|
||||||
speakService.speak(_ctx.getClient(), message, mode);
|
speakService.speak(_cctx.getClient(), message, mode);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -432,15 +394,14 @@ public class ChatDirector extends BasicDirector
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
_cservice.broadcast(_ctx.getClient(), message,
|
var failure :Function = function (reason :String) :void
|
||||||
new InvocationAdapter(broadcastFailed));
|
{
|
||||||
}
|
reason = MessageBundle.compose("m.broadcast_failed", reason);
|
||||||
|
displayFeedback(_bundle, reason);
|
||||||
|
};
|
||||||
|
|
||||||
// Called above, when we fail to broadcast
|
_cservice.broadcast(_cctx.getClient(), message,
|
||||||
private function broadcastFailed (reason :String) :void
|
new InvocationAdapter(failure));
|
||||||
{
|
|
||||||
reason = MessageBundle.compose("m.broadcast_failed", reason);
|
|
||||||
displayFeedback(_bundle, reason);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -465,67 +426,50 @@ public class ChatDirector extends BasicDirector
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// create a listener that will report success or failure
|
var failure :Function = function (reason :String) :void
|
||||||
ChatService.TellListener listener = new ChatService.TellListener() {
|
{
|
||||||
public void tellSucceeded (long idletime, String awayMessage) {
|
var msg :String = MessageBundle.compose(
|
||||||
|
"m.tell_failed", MessageBundle.taint(target), reason);
|
||||||
|
displayFeedback(_bundle, msg);
|
||||||
|
if (rl != null) {
|
||||||
|
rl.requestFailed(null);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
var success :Function = function (
|
||||||
|
idleTime :long, awayMessage :String) :void
|
||||||
|
{
|
||||||
|
var feedback :String = xlate(_bundle, MessageBundle.tcompose(
|
||||||
|
"m.told_format", target, message));
|
||||||
|
dispatchMessage(new TellFeedbackMessage(feedback));
|
||||||
|
addChatter(target);
|
||||||
|
if (rl != null) {
|
||||||
|
rl.requestCompleted(target);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void success (String feedback) {
|
// if they have an away message, report that
|
||||||
|
if (awayMessage != null) {
|
||||||
|
awayMessage = filter(awayMessage, target, false);
|
||||||
|
if (awayMessage != null) {
|
||||||
|
var msg :String = MessageBundle.tcompose(
|
||||||
|
"m.recipient_afk", target, awayMessage);
|
||||||
|
displayFeedback(_bundle, msg);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void requestFailed (String reason) {
|
// if they are idle, report that
|
||||||
|
if (idletime > 0) {
|
||||||
|
// adjust by the time it took them to become idle
|
||||||
|
idletime += _cctx.getConfig().getValue(
|
||||||
|
IDLE_TIME_KEY, DEFAULT_IDLE_TIME);
|
||||||
|
var msg :String = MessageBundle.compose(
|
||||||
|
"m.recipient_idle", MessageBundle.taint(target),
|
||||||
|
TimeUtil.getTimeOrderString(idletime, TimeUtil.MINUTE));
|
||||||
|
displayFeedback(_bundle, msg);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
_cservice.tell(_ctx.getClient(), target, message,
|
_cservice.tell(_cctx.getClient(), target, message,
|
||||||
new TellAdapter(tellFailed, tellSucceeded, [target, message, rl]));
|
new TellAdapter(failure, success));
|
||||||
}
|
|
||||||
|
|
||||||
private function tellFailed (reason :String, args :Array) :void
|
|
||||||
{
|
|
||||||
var msg :String = MessageBundle.compose(
|
|
||||||
"m.tell_failed", MessageBundle.taint(args[0]), reason);
|
|
||||||
displayFeedback(_bundle, msg);
|
|
||||||
var rl:ResultListener = (args[2] as ResultListener);
|
|
||||||
if (rl != null) {
|
|
||||||
rl.requestFailed(null);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private function tellSucceeded (
|
|
||||||
idleTime :long, awayMessage :String, args :Array) :void
|
|
||||||
{
|
|
||||||
var target :Name = (args[0] as Target);
|
|
||||||
var message :String = (args[1] as String);
|
|
||||||
var rl:ResultListener = (args[2] as ResultListener);
|
|
||||||
var feedback :String = xlate(_bundle, MessageBundle.tcompose(
|
|
||||||
"m.told_format", target, message));
|
|
||||||
dispatchMessage(new TellFeedbackMessage(feedback));
|
|
||||||
addChatter(target);
|
|
||||||
if (rl != null) {
|
|
||||||
rl.requestCompleted(target);
|
|
||||||
}
|
|
||||||
|
|
||||||
// if they have an away message, report that
|
|
||||||
if (awayMessage != null) {
|
|
||||||
awayMessage = filter(awayMessage, target, false);
|
|
||||||
if (awayMessage != null) {
|
|
||||||
var msg :String = MessageBundle.tcompose(
|
|
||||||
"m.recipient_afk", target, awayMessage);
|
|
||||||
displayFeedback(_bundle, msg);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// if they are idle, report that
|
|
||||||
if (idletime > 0) {
|
|
||||||
// adjust by the time it took them to become idle
|
|
||||||
idletime += _ctx.getConfig().getValue(
|
|
||||||
IDLE_TIME_KEY, DEFAULT_IDLE_TIME);
|
|
||||||
var msg :String = MessageBundle.compose(
|
|
||||||
"m.recipient_idle", MessageBundle.taint(target),
|
|
||||||
TimeUtil.getTimeOrderString(idletime, TimeUtil.MINUTE));
|
|
||||||
displayFeedback(_bundle, msg);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -533,7 +477,7 @@ public class ChatDirector extends BasicDirector
|
|||||||
* that sends a tell message to this client to indicate that we are
|
* that sends a tell message to this client to indicate that we are
|
||||||
* busy or away from the keyboard.
|
* busy or away from the keyboard.
|
||||||
*/
|
*/
|
||||||
public void setAwayMessage (String message)
|
public function setAwayMessage (message :String) :void
|
||||||
{
|
{
|
||||||
if (message != null) {
|
if (message != null) {
|
||||||
message = filter(message, null, true);
|
message = filter(message, null, true);
|
||||||
@@ -544,7 +488,7 @@ public class ChatDirector extends BasicDirector
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
// pass the buck right on along
|
// pass the buck right on along
|
||||||
_cservice.away(_ctx.getClient(), message);
|
_cservice.away(_cctx.getClient(), message);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -556,7 +500,7 @@ public class ChatDirector extends BasicDirector
|
|||||||
* @param localtype a type to be associated with all chat messages
|
* @param localtype a type to be associated with all chat messages
|
||||||
* that arrive on the specified DObject.
|
* that arrive on the specified DObject.
|
||||||
*/
|
*/
|
||||||
public void addAuxiliarySource (DObject source, String localtype)
|
public function addAuxiliarySource (source :DObject, localtype :String) :void
|
||||||
{
|
{
|
||||||
source.addListener(this);
|
source.addListener(this);
|
||||||
_auxes.put(source.getOid(), localtype);
|
_auxes.put(source.getOid(), localtype);
|
||||||
@@ -565,7 +509,7 @@ public class ChatDirector extends BasicDirector
|
|||||||
/**
|
/**
|
||||||
* Removes a previously added auxiliary chat source.
|
* Removes a previously added auxiliary chat source.
|
||||||
*/
|
*/
|
||||||
public void removeAuxiliarySource (DObject source)
|
public function removeAuxiliarySource (source :DObject) :void
|
||||||
{
|
{
|
||||||
source.removeListener(this);
|
source.removeListener(this);
|
||||||
_auxes.remove(source.getOid());
|
_auxes.remove(source.getOid());
|
||||||
@@ -587,20 +531,20 @@ public class ChatDirector extends BasicDirector
|
|||||||
/**
|
/**
|
||||||
* Runs the supplied message through the various chat mogrifications.
|
* Runs the supplied message through the various chat mogrifications.
|
||||||
*/
|
*/
|
||||||
public String mogrifyChat (String text)
|
public function mogrifyChat (text :String) :String
|
||||||
{
|
{
|
||||||
return mogrifyChat(text, false, true);
|
return mogrifyChatImpl(text, false, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
// documentation inherited
|
// documentation inherited from interface LocationObserver
|
||||||
public boolean locationMayChange (int placeId)
|
public function locationMayChange (placeId :int) :Boolean
|
||||||
{
|
{
|
||||||
// we accept all location change requests
|
// we accept all location change requests
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// documentation inherited
|
// documentation inherited from interface LocationObserver
|
||||||
public void locationDidChange (PlaceObject place)
|
public function locationDidChange (place :PlaceObject) :void
|
||||||
{
|
{
|
||||||
if (_place != null) {
|
if (_place != null) {
|
||||||
// unlisten to our old object
|
// unlisten to our old object
|
||||||
@@ -614,31 +558,31 @@ public class ChatDirector extends BasicDirector
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// documentation inherited
|
// documentation inherited from interface LocationObserver
|
||||||
public void locationChangeFailed (int placeId, String reason)
|
public function locationChangeFailed (placeId :int, reason :String) :void
|
||||||
{
|
{
|
||||||
// nothing we care about
|
// nothing we care about
|
||||||
}
|
}
|
||||||
|
|
||||||
// documentation inherited
|
// documentation inherited from interface MessageListener
|
||||||
public void messageReceived (MessageEvent event)
|
public function messageReceived (event :MessageEvent) :void
|
||||||
{
|
{
|
||||||
if (CHAT_NOTIFICATION.equals(event.getName())) {
|
if (ChatCodes.CHAT_NOTIFICATION === event.getName()) {
|
||||||
ChatMessage msg = (ChatMessage) event.getArgs()[0];
|
var msg :ChatMessage = (event.getArgs()[0] as ChatMessage);
|
||||||
String localtype = getLocalType(event.getTargetOid());
|
var localtype :String = getLocalType(event.getTargetOid());
|
||||||
String message = msg.message;
|
var message :String = msg.message;
|
||||||
String autoResponse = null;
|
var autoResponse :String = null;
|
||||||
Name speaker = null;
|
var speaker :Name = null;
|
||||||
byte mode = (byte) -1;
|
var mode :int = -1;
|
||||||
|
|
||||||
// figure out if the message was triggered by another user
|
// figure out if the message was triggered by another user
|
||||||
if (msg instanceof UserMessage) {
|
if (msg is UserMessage) {
|
||||||
UserMessage umsg = (UserMessage)msg;
|
var umsg :UserMessage = (msg as UserMessage);
|
||||||
speaker = umsg.speaker;
|
speaker = umsg.speaker;
|
||||||
mode = umsg.mode;
|
mode = umsg.mode;
|
||||||
|
|
||||||
} else if (msg instanceof UserSystemMessage) {
|
} else if (msg is UserSystemMessage) {
|
||||||
speaker = ((UserSystemMessage) msg).speaker;
|
speaker = (msg as UserSystemMessage).speaker;
|
||||||
}
|
}
|
||||||
|
|
||||||
// if there was an originating speaker, see if we want to hear it
|
// if there was an originating speaker, see if we want to hear it
|
||||||
@@ -647,14 +591,14 @@ public class ChatDirector extends BasicDirector
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (USER_CHAT_TYPE.equals(localtype) &&
|
if (ChatCodes.USER_CHAT_TYPE == localtype &&
|
||||||
mode == ChatCodes.DEFAULT_MODE) {
|
mode == ChatCodes.DEFAULT_MODE) {
|
||||||
// if it was a tell, add the speaker as a chatter
|
// if it was a tell, add the speaker as a chatter
|
||||||
addChatter(speaker);
|
addChatter(speaker);
|
||||||
|
|
||||||
// note whether or not we have an auto-response
|
// note whether or not we have an auto-response
|
||||||
BodyObject self = (BodyObject)
|
var self :BodyObject =
|
||||||
_ctx.getClient().getClientObject();
|
(_cctx.getClient().getClientObject() as BodyObject);
|
||||||
if (!StringUtil.isBlank(self.awayMessage)) {
|
if (!StringUtil.isBlank(self.awayMessage)) {
|
||||||
autoResponse = self.awayMessage;
|
autoResponse = self.awayMessage;
|
||||||
}
|
}
|
||||||
@@ -669,7 +613,7 @@ public class ChatDirector extends BasicDirector
|
|||||||
|
|
||||||
// if we auto-responded, report as much
|
// if we auto-responded, report as much
|
||||||
if (autoResponse != null) {
|
if (autoResponse != null) {
|
||||||
String amsg = MessageBundle.tcompose(
|
var amsg :String = MessageBundle.tcompose(
|
||||||
"m.auto_responded", speaker, autoResponse);
|
"m.auto_responded", speaker, autoResponse);
|
||||||
displayFeedback(_bundle, amsg);
|
displayFeedback(_bundle, amsg);
|
||||||
}
|
}
|
||||||
@@ -677,28 +621,30 @@ public class ChatDirector extends BasicDirector
|
|||||||
}
|
}
|
||||||
|
|
||||||
// documentation inherited
|
// documentation inherited
|
||||||
public void clientDidLogon (Client client)
|
public override function clientDidLogon (client :Client) :void
|
||||||
{
|
{
|
||||||
super.clientDidLogon(client);
|
super.clientDidLogon(client);
|
||||||
|
|
||||||
// listen on the client object for tells
|
// listen on the client object for tells
|
||||||
addAuxiliarySource(_clobj = client.getClientObject(), USER_CHAT_TYPE);
|
addAuxiliarySource(_clobj = client.getClientObject(),
|
||||||
|
ChatCodes.USER_CHAT_TYPE);
|
||||||
}
|
}
|
||||||
|
|
||||||
// documentation inherited
|
// documentation inherited
|
||||||
public void clientObjectDidChange (Client client)
|
public override function clientObjectDidChange (client :Client) :void
|
||||||
{
|
{
|
||||||
super.clientObjectDidChange(client);
|
super.clientObjectDidChange(client);
|
||||||
|
|
||||||
// change what we're listening to for tells
|
// change what we're listening to for tells
|
||||||
removeAuxiliarySource(_clobj);
|
removeAuxiliarySource(_clobj);
|
||||||
addAuxiliarySource(_clobj = client.getClientObject(), USER_CHAT_TYPE);
|
addAuxiliarySource(_clobj = client.getClientObject(),
|
||||||
|
ChatCodes.USER_CHAT_TYPE);
|
||||||
|
|
||||||
clearDisplays();
|
clearDisplays();
|
||||||
}
|
}
|
||||||
|
|
||||||
// documentation inherited
|
// documentation inherited
|
||||||
public void clientDidLogoff (Client client)
|
public override function clientDidLogoff (client :Client) :void
|
||||||
{
|
{
|
||||||
super.clientDidLogoff(client);
|
super.clientDidLogoff(client);
|
||||||
|
|
||||||
@@ -712,9 +658,9 @@ public class ChatDirector extends BasicDirector
|
|||||||
|
|
||||||
clearDisplays();
|
clearDisplays();
|
||||||
|
|
||||||
// clear out the list of people we've chatted with
|
// // clear out the list of people we've chatted with
|
||||||
_chatters.clear();
|
// _chatters.clear();
|
||||||
notifyChatterObservers();
|
// notifyChatterObservers();
|
||||||
|
|
||||||
// clear the _place
|
// clear the _place
|
||||||
locationDidChange(null);
|
locationDidChange(null);
|
||||||
@@ -732,8 +678,8 @@ public class ChatDirector extends BasicDirector
|
|||||||
* and has already been dealt with, or a translatable string
|
* and has already been dealt with, or a translatable string
|
||||||
* indicating the reason for rejection if not.
|
* indicating the reason for rejection if not.
|
||||||
*/
|
*/
|
||||||
protected String checkCanChat (
|
protected function checkCanChat (
|
||||||
SpeakService speakSvc, String message, byte mode)
|
speakSvc :SpeakService , message :String, mode :int) :String
|
||||||
{
|
{
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
@@ -746,11 +692,11 @@ public class ChatDirector extends BasicDirector
|
|||||||
* @return {@link ChatCodes#SUCCESS} if the message was delivered or a
|
* @return {@link ChatCodes#SUCCESS} if the message was delivered or a
|
||||||
* string indicating why it failed.
|
* string indicating why it failed.
|
||||||
*/
|
*/
|
||||||
internal String deliverChat (
|
internal function deliverChat (
|
||||||
SpeakService speakSvc, String message, byte mode)
|
speakSvc :SpeakService, message :String, mode :int) :String
|
||||||
{
|
{
|
||||||
// run the message through our mogrification process
|
// run the message through our mogrification process
|
||||||
message = mogrifyChat(message, true, mode != ChatCodes.EMOTE_MODE);
|
message = mogrifyChatImpl(message, true, mode != ChatCodes.EMOTE_MODE);
|
||||||
|
|
||||||
// mogrification may result in something being turned into a slash
|
// mogrification may result in something being turned into a slash
|
||||||
// command, in which case we have to run everything through again
|
// command, in which case we have to run everything through again
|
||||||
@@ -761,7 +707,7 @@ public class ChatDirector extends BasicDirector
|
|||||||
|
|
||||||
// make sure this client is not restricted from performing this
|
// make sure this client is not restricted from performing this
|
||||||
// chat message for some reason or other
|
// chat message for some reason or other
|
||||||
String errmsg = checkCanChat(speakSvc, message, mode);
|
var errmsg :String = checkCanChat(speakSvc, message, mode);
|
||||||
if (errmsg != null) {
|
if (errmsg != null) {
|
||||||
return errmsg;
|
return errmsg;
|
||||||
}
|
}
|
||||||
@@ -775,17 +721,17 @@ public class ChatDirector extends BasicDirector
|
|||||||
/**
|
/**
|
||||||
* Add the specified command to the history.
|
* Add the specified command to the history.
|
||||||
*/
|
*/
|
||||||
protected void addToHistory (String cmd)
|
protected function addToHistory (cmd :String) :void
|
||||||
{
|
{
|
||||||
// remove any previous instance of this command
|
// remove any previous instance of this command
|
||||||
_history.remove(cmd);
|
ArrayUtil.removeAll(_history, cmd);
|
||||||
|
|
||||||
// append it to the end
|
// append it to the end
|
||||||
_history.add(cmd);
|
_history.push(cmd);
|
||||||
|
|
||||||
// prune the history once it extends beyond max size
|
// prune the history once it extends beyond max size
|
||||||
if (_history.size() > MAX_COMMAND_HISTORY) {
|
if (_history.length > MAX_COMMAND_HISTORY) {
|
||||||
_history.remove(0);
|
_history.shift();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -798,19 +744,24 @@ public class ChatDirector extends BasicDirector
|
|||||||
* @param capFirst if true, the first letter of the text is
|
* @param capFirst if true, the first letter of the text is
|
||||||
* capitalized. This is not desired if the chat is already an emote.
|
* capitalized. This is not desired if the chat is already an emote.
|
||||||
*/
|
*/
|
||||||
protected String mogrifyChat (
|
protected function mogrifyChatImpl (
|
||||||
String text, boolean transformsAllowed, boolean capFirst)
|
text :String, transformsAllowed :Boolean, capFirst :Boolean) :String
|
||||||
{
|
{
|
||||||
int tlen = text.length();
|
var tlen :int = text.length;
|
||||||
if (tlen == 0) {
|
if (tlen == 0) {
|
||||||
return text;
|
return text;
|
||||||
|
|
||||||
// check to make sure there aren't too many caps
|
// check to make sure there aren't too many caps
|
||||||
} else if (tlen > 7) {
|
} else if (tlen > 7) {
|
||||||
// count caps
|
// count caps
|
||||||
int caps = 0;
|
var caps :int = 0;
|
||||||
for (int ii=0; ii < tlen; ii++) {
|
for (var ii :int = 0; ii < tlen; ii++) {
|
||||||
if (Character.isUpperCase(text.charAt(ii))) {
|
var ch :String = text.charAt(ii);
|
||||||
|
// do a fucked-up test to see if it's uppercase
|
||||||
|
// make sure the uppercase version is the same as the orig
|
||||||
|
// and the lowercase version is different
|
||||||
|
var chU :String = ch.toUpperCase();
|
||||||
|
if (ch == chU && chU != ch.toLowerCase()) {
|
||||||
caps++;
|
caps++;
|
||||||
if (caps > (tlen / 2)) {
|
if (caps > (tlen / 2)) {
|
||||||
// lowercase the whole string if there are
|
// lowercase the whole string if there are
|
||||||
@@ -821,21 +772,19 @@ public class ChatDirector extends BasicDirector
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
StringBuffer buf = new StringBuffer(text);
|
return mogrifyChatText(text, transformsAllowed, capFirst);
|
||||||
buf = mogrifyChat(buf, transformsAllowed, capFirst);
|
|
||||||
return buf.toString();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Helper function for {@link #mogrifyChat}. */
|
/** Helper function for {@link #mogrifyChat}. */
|
||||||
protected StringBuffer mogrifyChat (
|
protected function mogrifyChatText (
|
||||||
StringBuffer buf, boolean transformsAllowed, boolean capFirst)
|
text :String, transformsAllowed :Boolean, capFirst :Boolean) :String
|
||||||
{
|
{
|
||||||
// do the generic mogrifications and translations
|
// do the generic mogrifications and translations
|
||||||
buf = translatedReplacements("x.mogrifies", buf);
|
text = translatedReplacements("x.mogrifies", text);
|
||||||
|
|
||||||
// perform themed expansions and transformations
|
// perform themed expansions and transformations
|
||||||
if (transformsAllowed) {
|
if (transformsAllowed) {
|
||||||
buf = translatedReplacements("x.transforms", buf);
|
text = translatedReplacements("x.transforms", text);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -856,37 +805,28 @@ public class ChatDirector extends BasicDirector
|
|||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
|
|
||||||
return buf;
|
return text;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Do all the replacements (mogrifications) specified in the
|
* Do all the replacements (mogrifications) specified in the
|
||||||
* translation string specified by the key.
|
* translation string specified by the key.
|
||||||
*/
|
*/
|
||||||
protected StringBuffer translatedReplacements (String key, StringBuffer buf)
|
protected function translatedReplacements (
|
||||||
|
key :String, text :String) :String
|
||||||
{
|
{
|
||||||
MessageBundle bundle = _msgmgr.getBundle(_bundle);
|
var bundle :MessageBundle = _msgmgr.getBundle(_bundle);
|
||||||
if (!bundle.exists(key)) {
|
if (!bundle.exists(key)) {
|
||||||
return buf;
|
return buf;
|
||||||
}
|
}
|
||||||
StringTokenizer st = new StringTokenizer(bundle.get(key), "#");
|
var repls :Array = bundle.get(key).split("#");
|
||||||
// apply the replacements to each mogrification that matches
|
// apply the replacements to each mogrification that matches
|
||||||
while (st.hasMoreTokens()) {
|
for (var ii :int = 0; ii < repls.length; ii++) {
|
||||||
String pattern = st.nextToken();
|
var pattern :RegExp = new RegExp((repls[ii] as String), "gim");
|
||||||
String replace = st.nextToken();
|
var replace :String = (repls[++ii] as String);
|
||||||
Matcher m = Pattern.compile(pattern, Pattern.CASE_INSENSITIVE).
|
text = text.replace(pattern, replace);
|
||||||
matcher(buf);
|
|
||||||
if (m.find()) {
|
|
||||||
buf = new StringBuffer();
|
|
||||||
m.appendReplacement(buf, replace);
|
|
||||||
// they may match more than once
|
|
||||||
while (m.find()) {
|
|
||||||
m.appendReplacement(buf, replace);
|
|
||||||
}
|
|
||||||
m.appendTail(buf);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return buf;
|
return text;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -894,22 +834,21 @@ public class ChatDirector extends BasicDirector
|
|||||||
* specified command (i.e. the specified command is a prefix of their
|
* specified command (i.e. the specified command is a prefix of their
|
||||||
* registered command string).
|
* registered command string).
|
||||||
*/
|
*/
|
||||||
protected HashMap getCommandHandlers (String command)
|
protected function getCommandHandlers (command :String) :SimpleMap
|
||||||
{
|
{
|
||||||
HashMap matches = new HashMap();
|
var matches :SimpleMap = new SimpleMap();
|
||||||
BodyObject user = (BodyObject)_ctx.getClient().getClientObject();
|
var user :BodyObject =
|
||||||
Iterator itr = _handlers.entrySet().iterator();
|
(_cctx.getClient().getClientObject() as BodyObject);
|
||||||
while (itr.hasNext()) {
|
var keys :Array = _handlers.keys();
|
||||||
Map.Entry entry = (Map.Entry) itr.next();
|
for (var ii :int = 0; ii < keys.length; ii++) {
|
||||||
String cmd = (String) entry.getKey();
|
var cmd :String = (keys[ii] as String);
|
||||||
if (!cmd.startsWith(command)) {
|
if (cmd.indexOf(command) != 0) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
CommandHandler handler = (CommandHandler)entry.getValue();
|
var handler :CommandHandler = (_handlers.get(cmd) as CommandHandler);
|
||||||
if (!handler.checkAccess(user)) {
|
if (handler.checkAccess(user)) {
|
||||||
continue;
|
matches.put(cmd, handler);
|
||||||
}
|
}
|
||||||
matches.put(cmd, handler);
|
|
||||||
}
|
}
|
||||||
return matches;
|
return matches;
|
||||||
}
|
}
|
||||||
@@ -917,48 +856,48 @@ public class ChatDirector extends BasicDirector
|
|||||||
/**
|
/**
|
||||||
* Adds a chatter to our list of recent chatters.
|
* Adds a chatter to our list of recent chatters.
|
||||||
*/
|
*/
|
||||||
protected void addChatter (Name name)
|
protected function addChatter (name :Name) :void
|
||||||
{
|
{
|
||||||
// check to see if the chatter validator approves..
|
// // check to see if the chatter validator approves..
|
||||||
if ((_chatterValidator != null) &&
|
// if ((_chatterValidator != null) &&
|
||||||
(!_chatterValidator.isChatterValid(name))) {
|
// (!_chatterValidator.isChatterValid(name))) {
|
||||||
return;
|
// return;
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
boolean wasthere = _chatters.remove(name);
|
// boolean wasthere = _chatters.remove(name);
|
||||||
_chatters.addFirst(name);
|
// _chatters.addFirst(name);
|
||||||
|
//
|
||||||
if (!wasthere) {
|
// if (!wasthere) {
|
||||||
if (_chatters.size() > MAX_CHATTERS) {
|
// if (_chatters.size() > MAX_CHATTERS) {
|
||||||
_chatters.removeLast();
|
// _chatters.removeLast();
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
notifyChatterObservers();
|
// notifyChatterObservers();
|
||||||
}
|
// }
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Notifies all registered {@link ChatterObserver}s that the list of
|
* Notifies all registered {@link ChatterObserver}s that the list of
|
||||||
* chatters has changed.
|
* chatters has changed.
|
||||||
*/
|
*/
|
||||||
protected void notifyChatterObservers ()
|
// protected void notifyChatterObservers ()
|
||||||
{
|
// {
|
||||||
_chatterObservers.apply(new ObserverList.ObserverOp() {
|
// _chatterObservers.apply(new ObserverList.ObserverOp() {
|
||||||
public boolean apply (Object observer) {
|
// public boolean apply (Object observer) {
|
||||||
((ChatterObserver)observer).chattersUpdated(
|
// ((ChatterObserver)observer).chattersUpdated(
|
||||||
_chatters.listIterator());
|
// _chatters.listIterator());
|
||||||
return true;
|
// return true;
|
||||||
}
|
// }
|
||||||
});
|
// });
|
||||||
}
|
// }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Translates the specified message using the specified bundle.
|
* Translates the specified message using the specified bundle.
|
||||||
*/
|
*/
|
||||||
protected String xlate (String bundle, String message)
|
protected function xlate (bundle :String, message :String) :String
|
||||||
{
|
{
|
||||||
if (bundle != null && _msgmgr != null) {
|
if (bundle != null && _msgmgr != null) {
|
||||||
MessageBundle msgb = _msgmgr.getBundle(bundle);
|
var msgb :MessageBundle = _msgmgr.getBundle(bundle);
|
||||||
if (msgb == null) {
|
if (msgb == null) {
|
||||||
Log.warning(
|
Log.warning(
|
||||||
"No message bundle available to translate message " +
|
"No message bundle available to translate message " +
|
||||||
@@ -973,15 +912,16 @@ public class ChatDirector extends BasicDirector
|
|||||||
/**
|
/**
|
||||||
* Display the specified system message as if it had come from the server.
|
* Display the specified system message as if it had come from the server.
|
||||||
*/
|
*/
|
||||||
protected void displaySystem (
|
protected function displaySystem (
|
||||||
String bundle, String message, byte attLevel, String localtype)
|
bundle :String, message :String, attLevel :int,
|
||||||
|
localtype :String) :void
|
||||||
{
|
{
|
||||||
// nothing should be untranslated, so pass the default bundle if need
|
// nothing should be untranslated, so pass the default bundle if need
|
||||||
// be.
|
// be.
|
||||||
if (bundle == null) {
|
if (bundle == null) {
|
||||||
bundle = _bundle;
|
bundle = _bundle;
|
||||||
}
|
}
|
||||||
SystemMessage msg = new SystemMessage();
|
var msg :SystemMessage = new SystemMessage();
|
||||||
msg.attentionLevel = attLevel;
|
msg.attentionLevel = attLevel;
|
||||||
msg.setClientInfo(xlate(bundle, message), localtype);
|
msg.setClientInfo(xlate(bundle, message), localtype);
|
||||||
dispatchMessage(msg);
|
dispatchMessage(msg);
|
||||||
@@ -991,79 +931,21 @@ public class ChatDirector extends BasicDirector
|
|||||||
* Looks up and returns the message type associated with the specified
|
* Looks up and returns the message type associated with the specified
|
||||||
* oid.
|
* oid.
|
||||||
*/
|
*/
|
||||||
protected String getLocalType (int oid)
|
protected function getLocalType (oid :int) :String
|
||||||
{
|
{
|
||||||
String type = (String)_auxes.get(oid);
|
var typ :String = (_auxes.get(oid) as String);
|
||||||
return (type == null) ? PLACE_CHAT_TYPE : type;
|
return (typ == null) ? ChatCodes.PLACE_CHAT_TYPE : typ;
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Used to assign unique ids to all speak requests.
|
|
||||||
*/
|
|
||||||
protected synchronized int nextRequestId ()
|
|
||||||
{
|
|
||||||
return _requestId++;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// documentation inherited from interface
|
// documentation inherited from interface
|
||||||
protected void fetchServices (Client client)
|
protected override function fetchServices (client :Client) :void
|
||||||
{
|
{
|
||||||
// get a handle on our chat service
|
// get a handle on our chat service
|
||||||
_cservice = (ChatService)client.requireService(ChatService.class);
|
_cservice = (client.requireService(ChatService) as ChatService);
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* An operation that checks with all chat filters to properly filter
|
|
||||||
* a message prior to sending to the server or displaying.
|
|
||||||
*/
|
|
||||||
protected static class FilterMessageOp implements ObserverList.ObserverOp
|
|
||||||
{
|
|
||||||
public void setMessage (String msg, Name otherUser, boolean outgoing)
|
|
||||||
{
|
|
||||||
_msg = msg;
|
|
||||||
_otherUser = otherUser;
|
|
||||||
_out = outgoing;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean apply (Object observer)
|
|
||||||
{
|
|
||||||
if (_msg != null) {
|
|
||||||
_msg = ((ChatFilter) observer).filter(_msg, _otherUser, _out);
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getMessage ()
|
|
||||||
{
|
|
||||||
return _msg;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected Name _otherUser;
|
|
||||||
protected String _msg;
|
|
||||||
protected boolean _out;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* An observer op used to dispatch ChatMessages on the client.
|
|
||||||
*/
|
|
||||||
protected static class DisplayMessageOp implements ObserverList.ObserverOp
|
|
||||||
{
|
|
||||||
public void setMessage (ChatMessage message)
|
|
||||||
{
|
|
||||||
_message = message;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean apply (Object observer)
|
|
||||||
{
|
|
||||||
((ChatDisplay)observer).displayMessage(_message);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected ChatMessage _message;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Our active chat context. */
|
/** Our active chat context. */
|
||||||
protected var _ctx :CrowdContext;
|
protected var _cctx :CrowdContext;
|
||||||
|
|
||||||
/** Provides access to chat-related server-side services. */
|
/** Provides access to chat-related server-side services. */
|
||||||
protected var _cservice :ChatService;
|
protected var _cservice :ChatService;
|
||||||
@@ -1107,12 +989,6 @@ public class ChatDirector extends BasicDirector
|
|||||||
/** A history of chat commands. */
|
/** A history of chat commands. */
|
||||||
protected static const _history :Array = new Array();
|
protected static const _history :Array = new Array();
|
||||||
|
|
||||||
/** Used by {@link #nextRequestId}. */
|
|
||||||
protected var _requestId :int;
|
|
||||||
|
|
||||||
// /** Operation used to filter chat messages. */
|
|
||||||
// protected FilterMessageOp _filterMessageOp = new FilterMessageOp();
|
|
||||||
|
|
||||||
/** The maximum number of chatter usernames to track. */
|
/** The maximum number of chatter usernames to track. */
|
||||||
protected static const MAX_CHATTERS :int = 6;
|
protected static const MAX_CHATTERS :int = 6;
|
||||||
|
|
||||||
|
|||||||
@@ -33,13 +33,13 @@ public interface ChatDisplay
|
|||||||
/**
|
/**
|
||||||
* Called to clear the chat display.
|
* Called to clear the chat display.
|
||||||
*/
|
*/
|
||||||
public function clear () :void;
|
function clear () :void;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Called to display a chat message.
|
* Called to display a chat message.
|
||||||
*
|
*
|
||||||
* @see ChatMessage
|
* @see ChatMessage
|
||||||
*/
|
*/
|
||||||
public function displayMessage (msg :ChatMessage) :void;
|
function displayMessage (msg :ChatMessage) :void;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,17 +7,16 @@ import com.threerings.presents.client.InvocationAdapter;
|
|||||||
public class TellAdapter extends InvocationAdapter
|
public class TellAdapter extends InvocationAdapter
|
||||||
implements TellListener
|
implements TellListener
|
||||||
{
|
{
|
||||||
public function TellAdapter (
|
public function TellAdapter (failedFunc :Function, successFunc :Function)
|
||||||
failedFunc :Function, successFunc :Function, args :Array = null)
|
|
||||||
{
|
{
|
||||||
super(failedFunc, args);
|
super(failedFunc);
|
||||||
_successFunc = successFunc;
|
_successFunc = successFunc;
|
||||||
}
|
}
|
||||||
|
|
||||||
// documentation inherited from interface TellListener
|
// documentation inherited from interface TellListener
|
||||||
public function tellSucceeded (idleTime :long, awayMsg :String)
|
public function tellSucceeded (idleTime :long, awayMsg :String) :void
|
||||||
{
|
{
|
||||||
_successFunc(idleTime, awayMsg, args);
|
_successFunc(idleTime, awayMsg);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** The method to call on success. */
|
/** The method to call on success. */
|
||||||
|
|||||||
@@ -21,6 +21,9 @@
|
|||||||
|
|
||||||
package com.threerings.crowd.chat.data {
|
package com.threerings.crowd.chat.data {
|
||||||
|
|
||||||
|
import com.threerings.io.ObjectInputStream;
|
||||||
|
import com.threerings.io.ObjectOutputStream;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A ChatMessage that represents a message that came from the server
|
* A ChatMessage that represents a message that came from the server
|
||||||
* and did not result from direct user action.
|
* and did not result from direct user action.
|
||||||
|
|||||||
@@ -145,7 +145,7 @@ public class BodyObject extends ClientObject
|
|||||||
*/
|
*/
|
||||||
public function setUsername (value :Name) :void
|
public function setUsername (value :Name) :void
|
||||||
{
|
{
|
||||||
Name ovalue = this.username;
|
var ovalue :Name = this.username;
|
||||||
requestAttributeChange(
|
requestAttributeChange(
|
||||||
USERNAME, value, ovalue);
|
USERNAME, value, ovalue);
|
||||||
this.username = value;
|
this.username = value;
|
||||||
@@ -161,7 +161,7 @@ public class BodyObject extends ClientObject
|
|||||||
*/
|
*/
|
||||||
public function setLocation (value :int) :void
|
public function setLocation (value :int) :void
|
||||||
{
|
{
|
||||||
int ovalue = this.location;
|
var ovalue :int = this.location;
|
||||||
requestAttributeChange(
|
requestAttributeChange(
|
||||||
LOCATION, value, ovalue);
|
LOCATION, value, ovalue);
|
||||||
this.location = value;
|
this.location = value;
|
||||||
|
|||||||
@@ -60,7 +60,7 @@ public class OccupantInfo
|
|||||||
public static const DISCONNECTED :int = 2;
|
public static const DISCONNECTED :int = 2;
|
||||||
|
|
||||||
/** Maps status codes to human readable strings. */
|
/** Maps status codes to human readable strings. */
|
||||||
public static const X_STATUS :Array = { "active", "idle", "discon" };
|
public static const X_STATUS :Array = [ "active", "idle", "discon" ];
|
||||||
|
|
||||||
/** The body object id of this occupant (and our entry key). */
|
/** The body object id of this occupant (and our entry key). */
|
||||||
public var bodyOid :Integer;
|
public var bodyOid :Integer;
|
||||||
|
|||||||
@@ -156,7 +156,7 @@ public class PlaceObject extends DObject
|
|||||||
public function setOccupantInfo (value :DSet) :void
|
public function setOccupantInfo (value :DSet) :void
|
||||||
{
|
{
|
||||||
requestAttributeChange(OCCUPANT_INFO, value, this.occupantInfo);
|
requestAttributeChange(OCCUPANT_INFO, value, this.occupantInfo);
|
||||||
this.occupantInfo = (value == null) ? null : (DSet)value.clone();
|
this.occupantInfo = (value == null) ? null : value;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -0,0 +1,39 @@
|
|||||||
|
package com.threerings.msoy.client {
|
||||||
|
|
||||||
|
import flash.util.describeType;
|
||||||
|
|
||||||
|
import mx.collections.ArrayCollection;
|
||||||
|
|
||||||
|
import com.threerings.util.Name;
|
||||||
|
import com.threerings.presents.Log;
|
||||||
|
import com.threerings.presents.client.Client;
|
||||||
|
import com.threerings.presents.data.TimeBaseMarshaller;
|
||||||
|
import com.threerings.presents.dobj.DSet;
|
||||||
|
import com.threerings.presents.dobj.QSet;
|
||||||
|
import com.threerings.presents.net.UsernamePasswordCreds;
|
||||||
|
|
||||||
|
import com.threerings.presents.dobj.DObjectManager;
|
||||||
|
|
||||||
|
import com.threerings.presents.net.BootstrapData;
|
||||||
|
|
||||||
|
|
||||||
|
public class MsoyClient extends Client
|
||||||
|
{
|
||||||
|
public function MsoyClient ()
|
||||||
|
{
|
||||||
|
super(new UsernamePasswordCreds(new Name("Ray"), "fork-u-2"));
|
||||||
|
|
||||||
|
_ctx = new MsoyContext(this);
|
||||||
|
|
||||||
|
setServer("tasman.sea.earth.threerings.net", DEFAULT_SERVER_PORT);
|
||||||
|
logon();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function fuckingCompiler () :void
|
||||||
|
{
|
||||||
|
var i :int = TimeBaseMarshaller.GET_TIME_OID;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected var _ctx :MsoyContext;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,74 @@
|
|||||||
|
package com.threerings.msoy.client {
|
||||||
|
|
||||||
|
import com.threerings.presents.client.Client;
|
||||||
|
import com.threerings.presents.dobj.DObjectManager;
|
||||||
|
|
||||||
|
import com.threerings.crowd.client.ChatDirector;
|
||||||
|
import com.threerings.crowd.client.LocationDirector;
|
||||||
|
import com.threerings.crowd.client.OccupantDirector;
|
||||||
|
import com.threerings.crowd.client.PlaceView;
|
||||||
|
import com.threerings.crowd.util.CrowdContext;
|
||||||
|
|
||||||
|
import com.threerings.crowd.chat.client.ChatDirector;
|
||||||
|
|
||||||
|
public class MsoyContext
|
||||||
|
implements CrowdContext
|
||||||
|
{
|
||||||
|
public function MsoyContext (client :Client)
|
||||||
|
{
|
||||||
|
_client = client;
|
||||||
|
|
||||||
|
// TODO: verify params to these constructors
|
||||||
|
_msgmgr = new MessageManager("rsrc");
|
||||||
|
_chatdir = new ChatDirector(this, _msgmgr, "general");
|
||||||
|
}
|
||||||
|
|
||||||
|
// documentation inherited from superinterface PresentsContext
|
||||||
|
public function getClient () :Client
|
||||||
|
{
|
||||||
|
return _client;
|
||||||
|
}
|
||||||
|
|
||||||
|
// documentation inherited from superinterface PresentsContext
|
||||||
|
public function getDObjectManager () :DObjectManager
|
||||||
|
{
|
||||||
|
return _client.getDObjectManager();
|
||||||
|
}
|
||||||
|
|
||||||
|
// documentation inherited from interface CrowdContext
|
||||||
|
public function getLocationDirector () :LocationDirector
|
||||||
|
{
|
||||||
|
return null; // TODO
|
||||||
|
}
|
||||||
|
|
||||||
|
// documentation inherited from interface CrowdContext
|
||||||
|
public function getOccupantDirector () :OccupantDirector
|
||||||
|
{
|
||||||
|
return null; // TODO
|
||||||
|
}
|
||||||
|
|
||||||
|
// documentation inherited from interface CrowdContext
|
||||||
|
public function getChatDirector () :ChatDirector
|
||||||
|
{
|
||||||
|
return _chatdir;
|
||||||
|
}
|
||||||
|
|
||||||
|
// documentation inherited from interface CrowdContext
|
||||||
|
public function setPlaceView (view :PlaceView) :void
|
||||||
|
{
|
||||||
|
// TODO
|
||||||
|
}
|
||||||
|
|
||||||
|
// documentation inherited from interface CrowdContext
|
||||||
|
public function clearPlaceView (view :PlaceView) :void
|
||||||
|
{
|
||||||
|
// TODO
|
||||||
|
}
|
||||||
|
|
||||||
|
protected var _client :Client;
|
||||||
|
|
||||||
|
protected var _msgmgr :MessageManager;
|
||||||
|
|
||||||
|
protected var _chatdir :ChatDirector;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -38,7 +38,7 @@ public class BasicDirector
|
|||||||
* context that it can use to register itself with the necessary
|
* context that it can use to register itself with the necessary
|
||||||
* entities.
|
* entities.
|
||||||
*/
|
*/
|
||||||
protected function BasicDirector (ctx :PresentsContext)
|
public function BasicDirector (ctx :PresentsContext)
|
||||||
{
|
{
|
||||||
// save context
|
// save context
|
||||||
_ctx = ctx;
|
_ctx = ctx;
|
||||||
|
|||||||
@@ -7,22 +7,18 @@ public class InvocationAdapter
|
|||||||
* Construct an InvocationAdapter that will call the specified
|
* Construct an InvocationAdapter that will call the specified
|
||||||
* function on error.
|
* function on error.
|
||||||
*/
|
*/
|
||||||
public function InvocationAdapter (failedFunc :Function, args :Array = null)
|
public function InvocationAdapter (failedFunc :Function)
|
||||||
{
|
{
|
||||||
_failedFunc = failedFunc;
|
_failedFunc = failedFunc;
|
||||||
_args = args;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// documentation inherited from interface InvocationListener
|
// documentation inherited from interface InvocationListener
|
||||||
public function requestFailed (cause :String) :void
|
public function requestFailed (cause :String) :void
|
||||||
{
|
{
|
||||||
_failedFunc(cause, _args);
|
_failedFunc(cause);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** The Function to call when we've recevied our failure response. */
|
/** The Function to call when we've recevied our failure response. */
|
||||||
protected var _failedFunc :Function;
|
protected var _failedFunc :Function;
|
||||||
|
|
||||||
/** Any other extra information to pass along to the function. */
|
|
||||||
protected var _args :Array;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -35,6 +35,15 @@ public class InvocationDirector
|
|||||||
_omgr = omgr;
|
_omgr = omgr;
|
||||||
_client = client;
|
_client = client;
|
||||||
|
|
||||||
|
var subby :Object = new Object();
|
||||||
|
subby.objectAvailable = function (obj :DObject) :void {
|
||||||
|
gotClientObject(obj as ClientObject);
|
||||||
|
}
|
||||||
|
subby.requestFailed = function (
|
||||||
|
oid :int, cause :ObjectAccessError) :void {
|
||||||
|
gotClientObjectFailed(oid, cause);
|
||||||
|
}
|
||||||
|
|
||||||
_omgr.subscribeToObject(cloid, new ClientSubscriber(this));
|
_omgr.subscribeToObject(cloid, new ClientSubscriber(this));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -11,6 +11,11 @@ import com.threerings.presents.dobj.DSet;
|
|||||||
import com.threerings.presents.dobj.QSet;
|
import com.threerings.presents.dobj.QSet;
|
||||||
import com.threerings.presents.net.UsernamePasswordCreds;
|
import com.threerings.presents.net.UsernamePasswordCreds;
|
||||||
|
|
||||||
|
import com.threerings.presents.dobj.DObjectManager;
|
||||||
|
|
||||||
|
import com.threerings.presents.net.BootstrapData;
|
||||||
|
|
||||||
|
|
||||||
public class TestClient extends Client
|
public class TestClient extends Client
|
||||||
{
|
{
|
||||||
public function TestClient ()
|
public function TestClient ()
|
||||||
@@ -61,7 +66,18 @@ public class TestClient extends Client
|
|||||||
list.addItem(bob);
|
list.addItem(bob);
|
||||||
Log.debug("jim's indeX: " + list.getItemIndex(jim));
|
Log.debug("jim's indeX: " + list.getItemIndex(jim));
|
||||||
Log.debug("bob2's indeX: " + list.getItemIndex(bob2));
|
Log.debug("bob2's indeX: " + list.getItemIndex(bob2));
|
||||||
|
Log.debug("function: " + describeType(testFunc).toXMLString());
|
||||||
|
Log.debug("func length: " + testFunc.length);
|
||||||
|
Log.debug("funcToString: " + testFunc);
|
||||||
|
Log.debug("interfaces: " + describeType(Bint));
|
||||||
|
|
||||||
|
var funcy :Function = function (i :int) :void {
|
||||||
|
Log.debug("i is " + i);
|
||||||
|
Log.debug("first list item is " + list[0]);
|
||||||
|
}
|
||||||
|
|
||||||
|
_savedFunc = funcy;
|
||||||
|
_listy = list;
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -109,6 +125,13 @@ public class TestClient extends Client
|
|||||||
//var ta3 :TypedArray = new TypedArray(Pork);
|
//var ta3 :TypedArray = new TypedArray(Pork);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public override function gotBootstrap (
|
||||||
|
data :BootstrapData, omgr :DObjectManager) :void
|
||||||
|
{
|
||||||
|
_listy.addItemAt("new item 0", 0);
|
||||||
|
super.gotBootstrap(data, omgr);
|
||||||
|
_savedFunc(3);
|
||||||
|
}
|
||||||
|
|
||||||
// If a class isn't used anywhere, it won't get added to the .swf.
|
// If a class isn't used anywhere, it won't get added to the .swf.
|
||||||
// Here, I hack.
|
// Here, I hack.
|
||||||
@@ -117,19 +140,30 @@ public class TestClient extends Client
|
|||||||
var i :int = TimeBaseMarshaller.GET_TIME_OID;
|
var i :int = TimeBaseMarshaller.GET_TIME_OID;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testFunc (one :int, two :int = 0) :void
|
public function testFunc (one :int, two :int = 0, three :int = -1) :void
|
||||||
{
|
{
|
||||||
Log.debug("this: " + ", args: " + arguments.length +
|
Log.debug("this: " + ", args: " + arguments.length +
|
||||||
": " + arguments);
|
": " + arguments);
|
||||||
}
|
}
|
||||||
|
|
||||||
prototype var _foo :String;
|
prototype var _foo :String;
|
||||||
|
|
||||||
|
protected var _savedFunc :Function;
|
||||||
|
protected var _listy :ArrayCollection;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
import com.threerings.presents.Log;
|
import com.threerings.presents.Log;
|
||||||
import com.threerings.presents.client.TestClient;
|
import com.threerings.presents.client.TestClient;
|
||||||
|
|
||||||
|
interface Aint {
|
||||||
|
function foo () :void;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface Bint extends Aint {
|
||||||
|
function bar () :void;
|
||||||
|
}
|
||||||
|
|
||||||
class Person
|
class Person
|
||||||
{
|
{
|
||||||
public function Person (name :String)
|
public function Person (name :String)
|
||||||
|
|||||||
@@ -0,0 +1,50 @@
|
|||||||
|
package com.threerings.util {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Contains methods that should be in Array, but aren't.
|
||||||
|
*/
|
||||||
|
public class ArrayUtil
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Remove the first instance of the specified element from the array.
|
||||||
|
*/
|
||||||
|
public static function removeFirst (arr :Array, element :Object) :void
|
||||||
|
{
|
||||||
|
removeImpl(arr, element, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Remove the last instance of the specified element from the array.
|
||||||
|
*/
|
||||||
|
public static function removeLast (arr :Array, element :Object) :void
|
||||||
|
{
|
||||||
|
arr.reverse();
|
||||||
|
removeFirst(arr, element);
|
||||||
|
arr.reverse();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Removes all instances of the specified element from the array.
|
||||||
|
*/
|
||||||
|
public static function removeAll (arr :Array, element :Object) :void
|
||||||
|
{
|
||||||
|
removeImpl(arr, element, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Implementation of remove methods.
|
||||||
|
*/
|
||||||
|
private static function removeImpl (
|
||||||
|
arr :Array, element :Object, firstOnly :Boolean) :void
|
||||||
|
{
|
||||||
|
for (var ii :int = 0; ii < arr.length; ii++) {
|
||||||
|
if (arr[ii] === element) {
|
||||||
|
arr.splice(ii--, 1);
|
||||||
|
if (firstOnly) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -19,7 +19,7 @@
|
|||||||
// License along with this library; if not, write to the Free Software
|
// License along with this library; if not, write to the Free Software
|
||||||
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
|
|
||||||
package com.threerings.util;
|
package com.threerings.util {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A message bundle provides an easy mechanism by which to obtain
|
* A message bundle provides an easy mechanism by which to obtain
|
||||||
@@ -54,14 +54,6 @@ public class MessageBundle
|
|||||||
return getResourceString(key, false) != null;
|
return getResourceString(key, false) != null;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Get a String from the resource bundle, or null if there was an error.
|
|
||||||
*/
|
|
||||||
protected function getResourceString (key :String) :String
|
|
||||||
{
|
|
||||||
return getResourceString(key, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get a String from the resource bundle, or null if there was an
|
* Get a String from the resource bundle, or null if there was an
|
||||||
* error.
|
* error.
|
||||||
@@ -71,7 +63,7 @@ public class MessageBundle
|
|||||||
* if the resource didn't exist.
|
* if the resource didn't exist.
|
||||||
*/
|
*/
|
||||||
protected function getResourceString (
|
protected function getResourceString (
|
||||||
key :String, reportMissing :Boolean) :String
|
key :String, reportMissing :Boolean = true) :String
|
||||||
{
|
{
|
||||||
// TODO!!!
|
// TODO!!!
|
||||||
// try {
|
// try {
|
||||||
@@ -391,3 +383,4 @@ public class MessageBundle
|
|||||||
protected static const QUAL_PREFIX :String = "%";
|
protected static const QUAL_PREFIX :String = "%";
|
||||||
protected static const QUAL_SEP :String = ":";
|
protected static const QUAL_SEP :String = ":";
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -127,7 +127,7 @@ public class MessageManager
|
|||||||
// } else {
|
// } else {
|
||||||
rbundle = ResourceBundle.getBundle(fqpath, _locale);
|
rbundle = ResourceBundle.getBundle(fqpath, _locale);
|
||||||
// }
|
// }
|
||||||
} catch (MissingResourceException mre) {
|
} catch (mre :Error) {
|
||||||
Log.warning("Unable to resolve resource bundle " +
|
Log.warning("Unable to resolve resource bundle " +
|
||||||
"[path=" + fqpath + ", locale=" + _locale + "].");
|
"[path=" + fqpath + ", locale=" + _locale + "].");
|
||||||
}
|
}
|
||||||
@@ -136,7 +136,7 @@ public class MessageManager
|
|||||||
// interpret that as a derivation of MessageBundle to instantiate
|
// interpret that as a derivation of MessageBundle to instantiate
|
||||||
// for handling that class
|
// for handling that class
|
||||||
if (rbundle != null) {
|
if (rbundle != null) {
|
||||||
String mbclass = null;
|
var mbclass :String = null;
|
||||||
try {
|
try {
|
||||||
mbclass = rbundle.getString(MBUNDLE_CLASS_KEY);
|
mbclass = rbundle.getString(MBUNDLE_CLASS_KEY);
|
||||||
if (!StringUtil.isBlank(mbclass)) {
|
if (!StringUtil.isBlank(mbclass)) {
|
||||||
@@ -144,10 +144,10 @@ public class MessageManager
|
|||||||
Class.forName(mbclass).newInstance();
|
Class.forName(mbclass).newInstance();
|
||||||
}
|
}
|
||||||
|
|
||||||
} catch (MissingResourceException mre) {
|
} catch (mre :Error) {
|
||||||
// nothing to worry about
|
// nothing to worry about
|
||||||
|
|
||||||
} catch (Throwable t) {
|
} catch (t :Error) {
|
||||||
Log.warning("Failure instantiating custom message bundle " +
|
Log.warning("Failure instantiating custom message bundle " +
|
||||||
"[mbclass=" + mbclass + ", error=" + t + "].");
|
"[mbclass=" + mbclass + ", error=" + t + "].");
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -12,19 +12,7 @@ public class StringUtil
|
|||||||
*/
|
*/
|
||||||
public static function trim (str :String) :String
|
public static function trim (str :String) :String
|
||||||
{
|
{
|
||||||
while (str.search(/\s/) == 0) {
|
return mx.utils.StringUtil.trim(str);
|
||||||
str = str.substring(1);
|
|
||||||
}
|
|
||||||
do {
|
|
||||||
var endstr :String = str.substring(str.length - 1);
|
|
||||||
if (endstr.search(/\s/) != -1) {
|
|
||||||
str = str.substring(0, str.length - 1);
|
|
||||||
} else {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
} while (true);
|
|
||||||
|
|
||||||
return str;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,140 @@
|
|||||||
|
//
|
||||||
|
// $Id: TimeUtil.java 3372 2005-03-01 01:16:01Z ray $
|
||||||
|
//
|
||||||
|
// Narya library - tools for developing networked games
|
||||||
|
// Copyright (C) 2002-2004 Three Rings Design, Inc., All Rights Reserved
|
||||||
|
// http://www.threerings.net/code/narya/
|
||||||
|
//
|
||||||
|
// This library is free software; you can redistribute it and/or modify it
|
||||||
|
// under the terms of the GNU Lesser General Public License as published
|
||||||
|
// by the Free Software Foundation; either version 2.1 of the License, or
|
||||||
|
// (at your option) any later version.
|
||||||
|
//
|
||||||
|
// This library is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
// Lesser General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU Lesser General Public
|
||||||
|
// License along with this library; if not, write to the Free Software
|
||||||
|
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
|
|
||||||
|
package com.threerings.util {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Utility for times.
|
||||||
|
*/
|
||||||
|
public class TimeUtil
|
||||||
|
{
|
||||||
|
/** Time unit constant. */
|
||||||
|
public static const MILLISECOND :int = 0;
|
||||||
|
|
||||||
|
/** Time unit constant. */
|
||||||
|
public static const SECOND :int = 1;
|
||||||
|
|
||||||
|
/** Time unit constant. */
|
||||||
|
public static const MINUTE :int = 2;
|
||||||
|
|
||||||
|
/** Time unit constant. */
|
||||||
|
public static const HOUR :int = 3;
|
||||||
|
|
||||||
|
/** Time unit constant. */
|
||||||
|
public static const DAY :int = 4;
|
||||||
|
|
||||||
|
// TODO: Weeks?, months?
|
||||||
|
protected static const MAX_UNIT :int = DAY;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get a translatable string specifying the magnitude of the specified
|
||||||
|
* duration. Results will be between "1 second" and "X hours", with
|
||||||
|
* all times rounded to the nearest unit. "0 units" will never be
|
||||||
|
* displayed, the minimum is 1.
|
||||||
|
*/
|
||||||
|
public static function getTimeOrderString (
|
||||||
|
duration :long, minUnit :int, maxUnit :int = -1) :String
|
||||||
|
{
|
||||||
|
// enforce sanity
|
||||||
|
if (maxUnit == -1) {
|
||||||
|
maxUnit = MAX_UNIT;
|
||||||
|
}
|
||||||
|
minUnit = Math.min(minUnit, maxUnit);
|
||||||
|
maxUnit = Math.min(maxUnit, MAX_UNIT);
|
||||||
|
|
||||||
|
for (var uu :int = MILLISECOND; uu <= MAX_UNIT; uu++) {
|
||||||
|
var quantity :int = getQuantityPerUnit(uu);
|
||||||
|
if ((minUnit <= uu) && (duration < quantity || maxUnit == uu)) {
|
||||||
|
duration = Math.max(1, duration);
|
||||||
|
return MessageBundle.tcompose(getTransKey(uu),
|
||||||
|
String(duration));
|
||||||
|
}
|
||||||
|
duration = Math.round(duration / quantity);
|
||||||
|
}
|
||||||
|
|
||||||
|
// will not happen, because eventually uu will be MAX_UNIT
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get a translatable string specifying the duration, down to the
|
||||||
|
* minimum granularity.
|
||||||
|
*/
|
||||||
|
public static function getTimeString (duration :long, minUnit :int) :String
|
||||||
|
{
|
||||||
|
// sanity
|
||||||
|
minUnit = Math.min(minUnit, MAX_UNIT);
|
||||||
|
duration = Math.abs(duration);
|
||||||
|
|
||||||
|
var list :Array = new Array();
|
||||||
|
var parts :int = 0; // how many parts are in the translation string?
|
||||||
|
for (var uu :int = MILLISECOND; uu <= MAX_UNIT; uu++) {
|
||||||
|
var quantity :int = getQuantityPerUnit(uu);
|
||||||
|
if (minUnit <= uu) {
|
||||||
|
list.push(MessageBundle.tcompose(getTransKey(uu),
|
||||||
|
String(duration % quantity)));
|
||||||
|
parts++;
|
||||||
|
}
|
||||||
|
duration /= quantity;
|
||||||
|
if (duration <= 0 && parts > 0) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (parts == 1) {
|
||||||
|
return (list[0] as String);
|
||||||
|
} else {
|
||||||
|
return MessageBundle.compose("m.times_" + parts, list);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Internal method to get the quantity for the specified unit.
|
||||||
|
* (Not very OO)
|
||||||
|
*/
|
||||||
|
protected static function getQuantityPerUnit (unit :int) :int
|
||||||
|
{
|
||||||
|
switch (unit) {
|
||||||
|
case MILLISECOND: return 1000;
|
||||||
|
case SECOND: case MINUTE: return 60;
|
||||||
|
case HOUR: return 24;
|
||||||
|
case DAY: return Integer.MAX_VALUE;
|
||||||
|
default: return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Internal method to get the translation key for the specified unit.
|
||||||
|
* (Not very OO)
|
||||||
|
*/
|
||||||
|
protected static function getTransKey (unit :int) :String
|
||||||
|
{
|
||||||
|
switch (unit) {
|
||||||
|
case MILLISECOND: return "m.millisecond";
|
||||||
|
case SECOND: return "m.second";
|
||||||
|
case MINUTE: return "m.minute";
|
||||||
|
case HOUR: return "m.hour";
|
||||||
|
case DAY: return "m.day";
|
||||||
|
default: return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user