Obtain our ActionScript dependencies from Maven as well, and publish our swc
artifacts thereto. git-svn-id: svn+ssh://src.earth.threerings.net/narya/trunk@6289 542714f4-19e9-0310-aa3c-eee0fc999fb1
This commit is contained in:
@@ -0,0 +1,61 @@
|
||||
//
|
||||
// $Id$
|
||||
//
|
||||
// Narya library - tools for developing networked games
|
||||
// Copyright (C) 2002-2010 Three Rings Design, Inc., All Rights Reserved
|
||||
// http://code.google.com/p/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.bureau.client {
|
||||
|
||||
import com.threerings.bureau.data.AgentObject;
|
||||
|
||||
/**
|
||||
* Represents an agent running within a bureau client.
|
||||
*/
|
||||
public class Agent
|
||||
{
|
||||
/**
|
||||
* Initializes the Agent with the distributed agent object.
|
||||
*/
|
||||
public function init (agentObj :AgentObject) :void
|
||||
{
|
||||
_agentObj = agentObj;
|
||||
}
|
||||
|
||||
/**
|
||||
* Starts the code running in the agent.
|
||||
*/
|
||||
public function start () :void
|
||||
{
|
||||
throw new Error("Abstract method");
|
||||
}
|
||||
|
||||
/**
|
||||
* Stops the code running in the agent.
|
||||
*/
|
||||
public function stop () :void
|
||||
{
|
||||
throw new Error("Abstract method");
|
||||
}
|
||||
|
||||
/**
|
||||
* The shared agent object.
|
||||
*/
|
||||
protected var _agentObj :AgentObject;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,115 @@
|
||||
//
|
||||
// $Id$
|
||||
//
|
||||
// Narya library - tools for developing networked games
|
||||
// Copyright (C) 2002-2010 Three Rings Design, Inc., All Rights Reserved
|
||||
// http://code.google.com/p/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.bureau.client {
|
||||
|
||||
import com.threerings.presents.client.Client;
|
||||
import com.threerings.presents.dobj.DObjectManager;
|
||||
|
||||
import com.threerings.bureau.data.BureauAuthName;
|
||||
import com.threerings.bureau.data.BureauCredentials;
|
||||
import com.threerings.bureau.util.BureauContext;
|
||||
|
||||
/**
|
||||
* Represents a client embedded in a bureau.
|
||||
*/
|
||||
public class BureauClient extends Client
|
||||
{
|
||||
// statically reference classes we require
|
||||
BureauAuthName
|
||||
|
||||
/**
|
||||
* Creates a new client.
|
||||
* @param creds the credentials supplied during connection
|
||||
* @param runQueue the place to post tasks required by clients
|
||||
*/
|
||||
public function BureauClient (token :String, bureauId :String)
|
||||
{
|
||||
super(null);
|
||||
_bureauId = bureauId;
|
||||
_creds = new BureauCredentials(_bureauId, token);
|
||||
_ctx = createContext();
|
||||
_director = createDirector();
|
||||
}
|
||||
|
||||
public function getBureauDirector () :BureauDirector
|
||||
{
|
||||
return _director;
|
||||
}
|
||||
|
||||
public function getBureauId () :String
|
||||
{
|
||||
return _bureauId;
|
||||
}
|
||||
|
||||
protected function createDirector () :BureauDirector
|
||||
{
|
||||
throw new Error("Abstract method");
|
||||
}
|
||||
|
||||
protected function createContext () :BureauContext
|
||||
{
|
||||
return new Context(this);
|
||||
}
|
||||
|
||||
protected var _ctx :BureauContext;
|
||||
protected var _bureauId :String;
|
||||
protected var _director :BureauDirector;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
import com.threerings.bureau.client.BureauClient;
|
||||
import com.threerings.bureau.client.BureauDirector;
|
||||
import com.threerings.presents.dobj.DObjectManager;
|
||||
import com.threerings.presents.client.Client;
|
||||
import com.threerings.bureau.util.BureauContext;
|
||||
|
||||
class Context
|
||||
implements BureauContext
|
||||
{
|
||||
function Context (client :BureauClient)
|
||||
{
|
||||
_client = client;
|
||||
}
|
||||
|
||||
public function getBureauDirector () :BureauDirector
|
||||
{
|
||||
return _client.getBureauDirector();
|
||||
}
|
||||
|
||||
public function getDObjectManager () :DObjectManager
|
||||
{
|
||||
return _client.getDObjectManager();
|
||||
}
|
||||
|
||||
public function getClient () :Client
|
||||
{
|
||||
return _client;
|
||||
}
|
||||
|
||||
public function getBureauId () :String
|
||||
{
|
||||
return _client.getBureauId();
|
||||
}
|
||||
|
||||
protected var _client :BureauClient;
|
||||
}
|
||||
@@ -0,0 +1,80 @@
|
||||
//
|
||||
// $Id$
|
||||
//
|
||||
// Narya library - tools for developing networked games
|
||||
// Copyright (C) 2002-2010 Three Rings Design, Inc., All Rights Reserved
|
||||
// http://code.google.com/p/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.bureau.client {
|
||||
|
||||
import com.threerings.bureau.client.BureauReceiver;
|
||||
import com.threerings.presents.client.InvocationDecoder;
|
||||
|
||||
/**
|
||||
* Dispatches calls to a {@link BureauReceiver} instance.
|
||||
*/
|
||||
public class BureauDecoder extends InvocationDecoder
|
||||
{
|
||||
/** The generated hash code used to identify this receiver class. */
|
||||
public static const RECEIVER_CODE :String = "3e98f7a30deb5a8e25e05c71c6081bf4";
|
||||
|
||||
/** The method id used to dispatch {@link BureauReceiver#createAgent}
|
||||
* notifications. */
|
||||
public static const CREATE_AGENT :int = 1;
|
||||
|
||||
/** The method id used to dispatch {@link BureauReceiver#destroyAgent}
|
||||
* notifications. */
|
||||
public static const DESTROY_AGENT :int = 2;
|
||||
|
||||
/**
|
||||
* Creates a decoder that may be registered to dispatch invocation
|
||||
* service notifications to the specified receiver.
|
||||
*/
|
||||
public function BureauDecoder (receiver :BureauReceiver)
|
||||
{
|
||||
this.receiver = receiver;
|
||||
}
|
||||
|
||||
// documentation inherited
|
||||
public override function getReceiverCode () :String
|
||||
{
|
||||
return RECEIVER_CODE;
|
||||
}
|
||||
|
||||
// documentation inherited
|
||||
public override function dispatchNotification (methodId :int, args :Array) :void
|
||||
{
|
||||
switch (methodId) {
|
||||
case CREATE_AGENT:
|
||||
BureauReceiver(receiver).createAgent(
|
||||
args[0] as int
|
||||
);
|
||||
return;
|
||||
|
||||
case DESTROY_AGENT:
|
||||
BureauReceiver(receiver).destroyAgent(
|
||||
args[0] as int
|
||||
);
|
||||
return;
|
||||
|
||||
default:
|
||||
super.dispatchNotification(methodId, args);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,214 @@
|
||||
//
|
||||
// $Id$
|
||||
//
|
||||
// Narya library - tools for developing networked games
|
||||
// Copyright (C) 2002-2010 Three Rings Design, Inc., All Rights Reserved
|
||||
// http://code.google.com/p/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.bureau.client {
|
||||
|
||||
import com.threerings.util.Map;
|
||||
import com.threerings.util.Maps;
|
||||
import com.threerings.util.Log;
|
||||
|
||||
import com.threerings.presents.client.BasicDirector;
|
||||
import com.threerings.presents.client.Client;
|
||||
import com.threerings.presents.client.ClientEvent;
|
||||
import com.threerings.presents.dobj.ObjectAccessError;
|
||||
import com.threerings.presents.util.SafeSubscriber;
|
||||
|
||||
import com.threerings.bureau.data.AgentObject;
|
||||
import com.threerings.bureau.data.BureauClientObject;
|
||||
import com.threerings.bureau.data.BureauCodes;
|
||||
import com.threerings.bureau.util.BureauContext;
|
||||
|
||||
/**
|
||||
* Allows the server to create and destroy agents on a client.
|
||||
* @see BureauRegistry
|
||||
*/
|
||||
public class BureauDirector extends BasicDirector
|
||||
{
|
||||
BureauClientObject;
|
||||
|
||||
/**
|
||||
* Creates a new BureauDirector.
|
||||
*/
|
||||
public function BureauDirector (ctx :BureauContext)
|
||||
{
|
||||
super(ctx);
|
||||
}
|
||||
|
||||
// from BasicDirector
|
||||
public override function clientDidLogon (event :ClientEvent) :void
|
||||
{
|
||||
super.clientDidLogon(event);
|
||||
var id :String = BureauContext(_ctx).getBureauId();
|
||||
_bureauService.bureauInitialized(id);
|
||||
}
|
||||
|
||||
/**
|
||||
* Lets the server know that a fatal error has occurred and the bureau needs to be terminated.
|
||||
*/
|
||||
public function fatalError (message :String) :void
|
||||
{
|
||||
_bureauService.bureauError(message);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new agent when the server requests it.
|
||||
*/
|
||||
protected function createAgentFromId (agentId :int) :void
|
||||
{
|
||||
log.info("Subscribing to object", "agentId", agentId);
|
||||
|
||||
var subscriber :SafeSubscriber =
|
||||
new SafeSubscriber(agentId, objectAvailable, requestFailed);
|
||||
_subscribers.put(agentId, subscriber);
|
||||
subscriber.subscribe(_ctx.getDObjectManager());
|
||||
}
|
||||
|
||||
/**
|
||||
* Destroys an agent at the server's request.
|
||||
*/
|
||||
protected function destroyAgent (agentId :int) :void
|
||||
{
|
||||
var agent :Agent = null;
|
||||
agent = _agents.remove(agentId);
|
||||
|
||||
if (agent == null) {
|
||||
log.warning("Lost an agent", "id", agentId);
|
||||
}
|
||||
else {
|
||||
try {
|
||||
agent.stop();
|
||||
} catch (e :Error) {
|
||||
log.warning("Stopping an agent caused an exception", e);
|
||||
}
|
||||
var subscriber :SafeSubscriber = _subscribers.remove(agentId);
|
||||
if (subscriber == null) {
|
||||
log.warning("Lost a subscriber for agent", "agent", agent);
|
||||
}
|
||||
else {
|
||||
subscriber.unsubscribe(_ctx.getDObjectManager());
|
||||
}
|
||||
_bureauService.agentDestroyed(agentId);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Callback for when the a request to subscribe to an object finishes and the object is available.
|
||||
*/
|
||||
protected function objectAvailable (agentObject :AgentObject) :void
|
||||
{
|
||||
var oid :int = agentObject.getOid();
|
||||
|
||||
log.info("Object available", "oid", oid);
|
||||
|
||||
var agent :Agent;
|
||||
try {
|
||||
agent = createAgent(agentObject);
|
||||
agent.init(agentObject);
|
||||
agent.start();
|
||||
}
|
||||
catch (e :Error) {
|
||||
log.warning("Could not create agent", "obj", agentObject, e);
|
||||
_bureauService.agentCreationFailed(oid);
|
||||
return;
|
||||
}
|
||||
|
||||
_agents.put(oid, agent);
|
||||
_bureauService.agentCreated(oid);
|
||||
}
|
||||
|
||||
/**
|
||||
* Callback for when the a request to subscribe to an object fails.
|
||||
*/
|
||||
protected function requestFailed (oid :int, cause :ObjectAccessError) :void
|
||||
{
|
||||
log.warning("Could not subscribe to agent", "oid", oid, cause);
|
||||
}
|
||||
|
||||
// from BasicDirector
|
||||
protected override function registerServices (client :Client) :void
|
||||
{
|
||||
super.registerServices(client);
|
||||
|
||||
// Require the bureau services
|
||||
client.addServiceGroup(BureauCodes.BUREAU_GROUP);
|
||||
|
||||
// Set up our decoder so we can receive method calls
|
||||
// from the server
|
||||
var receiver :BureauReceiver =
|
||||
new ReceiverDelegator(createAgentFromId, destroyAgent);
|
||||
|
||||
client.getInvocationDirector().
|
||||
registerReceiver(new BureauDecoder(receiver));
|
||||
}
|
||||
|
||||
// from BasicDirector
|
||||
protected override function fetchServices (client :Client) :void
|
||||
{
|
||||
super.fetchServices(client);
|
||||
|
||||
_bureauService = client.getService(BureauService) as BureauService;
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when it is time to create an Agent. Subclasses should read the
|
||||
* <code>agentObject</code>'s type and/or properties to determine what kind of Agent to
|
||||
* create.
|
||||
* @param agentObj the distributed and object
|
||||
* @return a new Agent that will govern the distributed object
|
||||
*/
|
||||
protected function createAgent (agentObj :AgentObject) :Agent
|
||||
{
|
||||
throw new Error("Abstract function");
|
||||
}
|
||||
|
||||
/** Create a logger for the entire package.. */
|
||||
protected var log :Log = Log.getLog("com.threerings.bureau");
|
||||
|
||||
protected var _bureauService :BureauService;
|
||||
protected var _agents :Map = Maps.newMapOf(int);
|
||||
protected var _subscribers :Map = Maps.newMapOf(int);
|
||||
}
|
||||
}
|
||||
|
||||
import com.threerings.bureau.client.BureauReceiver;
|
||||
|
||||
class ReceiverDelegator implements BureauReceiver
|
||||
{
|
||||
public function ReceiverDelegator (createFn :Function, destroyFn :Function)
|
||||
{
|
||||
_createFn = createFn;
|
||||
_destroyFn = destroyFn;
|
||||
}
|
||||
|
||||
public function createAgent (agentId :int) :void
|
||||
{
|
||||
_createFn(agentId);
|
||||
}
|
||||
|
||||
public function destroyAgent (agentId :int) :void
|
||||
{
|
||||
_destroyFn(agentId);
|
||||
}
|
||||
|
||||
protected var _createFn :Function;
|
||||
protected var _destroyFn :Function;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,50 @@
|
||||
//
|
||||
// $Id$
|
||||
//
|
||||
// Narya library - tools for developing networked games
|
||||
// Copyright (C) 2002-2010 Three Rings Design, Inc., All Rights Reserved
|
||||
// http://code.google.com/p/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.bureau.client {
|
||||
|
||||
import com.threerings.presents.client.InvocationReceiver;
|
||||
|
||||
/**
|
||||
* Hooks for controlling a previously launched bureau client.
|
||||
*/
|
||||
public interface BureauReceiver extends InvocationReceiver
|
||||
{
|
||||
/**
|
||||
* Creates a new agent. Implementors should create a new {@link Agent} and give it access to
|
||||
* the {@link AgentObject} referred to by the <code>agentId</code> parameter and must notify
|
||||
* the service that the agent has been created using {@link BureauService#agentCreated}.
|
||||
* @param client the client receiving the request
|
||||
* @param agentId the id of the <code>AgentObject</code> that needs an <code>Agent</code>
|
||||
*/
|
||||
function createAgent (agentId :int) :void;
|
||||
|
||||
/**
|
||||
* Destroys a previously created agent. Implementors should destroy the agent that was created
|
||||
* by the call to <code>createAgent</code> with the same agent id and must notify
|
||||
* the service that the agent has been created using {@link BureauService#agentDestroyed}.
|
||||
* @param client the client receiving the request
|
||||
* @param agentId the id of the <code>AgentObject</code> whose <code>Agent</code>
|
||||
* should be destroyed
|
||||
*/
|
||||
function destroyAgent (agentId :int) :void;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
//
|
||||
// $Id$
|
||||
//
|
||||
// Narya library - tools for developing networked games
|
||||
// Copyright (C) 2002-2010 Three Rings Design, Inc., All Rights Reserved
|
||||
// http://code.google.com/p/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.bureau.client {
|
||||
|
||||
import com.threerings.presents.client.Client;
|
||||
import com.threerings.presents.client.InvocationService;
|
||||
|
||||
/**
|
||||
* An ActionScript version of the Java BureauService interface.
|
||||
*/
|
||||
public interface BureauService extends InvocationService
|
||||
{
|
||||
// from Java interface BureauService
|
||||
function agentCreated (arg1 :int) :void;
|
||||
|
||||
// from Java interface BureauService
|
||||
function agentCreationFailed (arg1 :int) :void;
|
||||
|
||||
// from Java interface BureauService
|
||||
function agentDestroyed (arg1 :int) :void;
|
||||
|
||||
// from Java interface BureauService
|
||||
function bureauError (arg1 :String) :void;
|
||||
|
||||
// from Java interface BureauService
|
||||
function bureauInitialized (arg1 :String) :void;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,160 @@
|
||||
//
|
||||
// $Id$
|
||||
//
|
||||
// Narya library - tools for developing networked games
|
||||
// Copyright (C) 2002-2010 Three Rings Design, Inc., All Rights Reserved
|
||||
// http://code.google.com/p/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.bureau.data {
|
||||
|
||||
import com.threerings.io.ObjectInputStream;
|
||||
import com.threerings.presents.dobj.DObject;
|
||||
|
||||
public class AgentObject extends DObject
|
||||
{
|
||||
// AUTO-GENERATED: FIELDS START
|
||||
/** The field name of the <code>bureauId</code> field. */
|
||||
public static const BUREAU_ID :String = "bureauId";
|
||||
|
||||
/** The field name of the <code>bureauType</code> field. */
|
||||
public static const BUREAU_TYPE :String = "bureauType";
|
||||
|
||||
/** The field name of the <code>code</code> field. */
|
||||
public static const CODE :String = "code";
|
||||
|
||||
/** The field name of the <code>className</code> field. */
|
||||
public static const CLASS_NAME :String = "className";
|
||||
|
||||
/** The field name of the <code>clientOid</code> field. */
|
||||
public static const CLIENT_OID :String = "clientOid";
|
||||
// AUTO-GENERATED: FIELDS END
|
||||
|
||||
/** The id of the bureau the agent is running in. This is normally a unique id corresponding
|
||||
* to the game or item that requires some server-side processing. */
|
||||
public var bureauId :String;
|
||||
|
||||
/** The type of bureau that the agent is running in. This is normally derived from the kind
|
||||
* of media that the game or item has specified for its code and determines the method of
|
||||
* launching the bureau when the first agent is requested. */
|
||||
public var bureauType :String;
|
||||
|
||||
/** The location of the code for the agent. This could be a URL to an action script file or
|
||||
* some other description that the bureau can use to load and execute the agent's code. */
|
||||
public var code :String;
|
||||
|
||||
/** The main class within the code to use when launching an agent. Whther this value is
|
||||
* used depends on the type of bureau and will be resolve in the bureau client. */
|
||||
public var className :String;
|
||||
|
||||
/** The id of the client running this agent (only set after the agent is assigned to a
|
||||
* bureau and is running). */
|
||||
public var clientOid :int;
|
||||
|
||||
// AUTO-GENERATED: METHODS START
|
||||
// /**
|
||||
// * Requests that the <code>bureauId</code> field be set to the
|
||||
// * specified value. The local value will be updated immediately and an
|
||||
// * event will be propagated through the system to notify all listeners
|
||||
// * that the attribute did change. Proxied copies of this object (on
|
||||
// * clients) will apply the value change when they received the
|
||||
// * attribute changed notification.
|
||||
// */
|
||||
// public function setBureauId (value :String) :void
|
||||
// {
|
||||
// var ovalue :String = this.bureauId;
|
||||
// requestAttributeChange(
|
||||
// BUREAU_ID, value, ovalue);
|
||||
// this.bureauId = value;
|
||||
// }
|
||||
|
||||
// /**
|
||||
// * Requests that the <code>bureauType</code> field be set to the
|
||||
// * specified value. The local value will be updated immediately and an
|
||||
// * event will be propagated through the system to notify all listeners
|
||||
// * that the attribute did change. Proxied copies of this object (on
|
||||
// * clients) will apply the value change when they received the
|
||||
// * attribute changed notification.
|
||||
// */
|
||||
// public function setBureauType (value :String) :void
|
||||
// {
|
||||
// var ovalue :String = this.bureauType;
|
||||
// requestAttributeChange(
|
||||
// BUREAU_TYPE, value, ovalue);
|
||||
// this.bureauType = value;
|
||||
// }
|
||||
|
||||
// /**
|
||||
// * Requests that the <code>code</code> field be set to the
|
||||
// * specified value. The local value will be updated immediately and an
|
||||
// * event will be propagated through the system to notify all listeners
|
||||
// * that the attribute did change. Proxied copies of this object (on
|
||||
// * clients) will apply the value change when they received the
|
||||
// * attribute changed notification.
|
||||
// */
|
||||
// public function setCode (value :String) :void
|
||||
// {
|
||||
// var ovalue :String = this.code;
|
||||
// requestAttributeChange(
|
||||
// CODE, value, ovalue);
|
||||
// this.code = value;
|
||||
// }
|
||||
|
||||
// /**
|
||||
// * Requests that the <code>className</code> field be set to the
|
||||
// * specified value. The local value will be updated immediately and an
|
||||
// * event will be propagated through the system to notify all listeners
|
||||
// * that the attribute did change. Proxied copies of this object (on
|
||||
// * clients) will apply the value change when they received the
|
||||
// * attribute changed notification.
|
||||
// */
|
||||
// public function setClassName (value :String) :void
|
||||
// {
|
||||
// var ovalue :String = this.className;
|
||||
// requestAttributeChange(
|
||||
// CLASS_NAME, value, ovalue);
|
||||
// this.className = value;
|
||||
// }
|
||||
|
||||
// /**
|
||||
// * Requests that the <code>clientOid</code> field be set to the
|
||||
// * specified value. The local value will be updated immediately and an
|
||||
// * event will be propagated through the system to notify all listeners
|
||||
// * that the attribute did change. Proxied copies of this object (on
|
||||
// * clients) will apply the value change when they received the
|
||||
// * attribute changed notification.
|
||||
// */
|
||||
// public function setClientOid (value :int) :void
|
||||
// {
|
||||
// var ovalue :int = this.clientOid;
|
||||
// requestAttributeChange(
|
||||
// CLIENT_OID, Integer.valueOf(value), Integer.valueOf(ovalue));
|
||||
// this.clientOid = value;
|
||||
// }
|
||||
// // AUTO-GENERATED: METHODS END
|
||||
|
||||
// from interface Streamable
|
||||
override public function readObject (ins :ObjectInputStream) :void
|
||||
{
|
||||
super.readObject(ins);
|
||||
bureauId = ins.readField(String) as String;
|
||||
bureauType = ins.readField(String) as String;
|
||||
code = ins.readField(String) as String;
|
||||
className = ins.readField(String) as String;
|
||||
clientOid = ins.readInt();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
//
|
||||
// $Id$
|
||||
//
|
||||
// Narya library - tools for developing networked games
|
||||
// Copyright (C) 2002-2010 Three Rings Design, Inc., All Rights Reserved
|
||||
// http://code.google.com/p/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.bureau.data {
|
||||
|
||||
import com.threerings.util.Name;
|
||||
|
||||
/**
|
||||
* Represents an authenticated bureau client.
|
||||
*/
|
||||
public class BureauAuthName extends Name
|
||||
{
|
||||
public function BureauAuthName (bureauId :String = "")
|
||||
{
|
||||
super(bureauId);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
//
|
||||
// $Id$
|
||||
//
|
||||
// Narya library - tools for developing networked games
|
||||
// Copyright (C) 2002-2010 Three Rings Design, Inc., All Rights Reserved
|
||||
// http://code.google.com/p/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.bureau.data {
|
||||
|
||||
import com.threerings.presents.data.ClientObject;
|
||||
|
||||
/**
|
||||
* An object representing a Bureau connection. This is currently just a marker class.
|
||||
*/
|
||||
public class BureauClientObject extends ClientObject
|
||||
{
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
//
|
||||
// $Id$
|
||||
//
|
||||
// Narya library - tools for developing networked games
|
||||
// Copyright (C) 2002-2010 Three Rings Design, Inc., All Rights Reserved
|
||||
// http://code.google.com/p/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.bureau.data {
|
||||
|
||||
import com.threerings.presents.data.InvocationCodes;
|
||||
|
||||
/**
|
||||
* Codes and constants global to the Bureau services.
|
||||
*/
|
||||
public class BureauCodes extends InvocationCodes
|
||||
{
|
||||
/** Defines our invocation services group. */
|
||||
public static const BUREAU_GROUP :String = "bureau";
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
//
|
||||
// $Id$
|
||||
//
|
||||
// Narya library - tools for developing networked games
|
||||
// Copyright (C) 2002-2010 Three Rings Design, Inc., All Rights Reserved
|
||||
// http://code.google.com/p/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.bureau.data {
|
||||
|
||||
import com.threerings.presents.net.ServiceCreds;
|
||||
|
||||
/**
|
||||
* Extends the basic credentials to provide bureau-specific fields.
|
||||
*/
|
||||
public class BureauCredentials extends ServiceCreds
|
||||
{
|
||||
/**
|
||||
* Creates new credentials for a specific bureau.
|
||||
*/
|
||||
public function BureauCredentials (bureauId :String = null, sharedSecret :String = null)
|
||||
{
|
||||
super(bureauId, sharedSecret);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,94 @@
|
||||
//
|
||||
// $Id$
|
||||
//
|
||||
// Narya library - tools for developing networked games
|
||||
// Copyright (C) 2002-2010 Three Rings Design, Inc., All Rights Reserved
|
||||
// http://code.google.com/p/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.bureau.data {
|
||||
|
||||
import com.threerings.bureau.client.BureauService;
|
||||
import com.threerings.presents.client.Client;
|
||||
import com.threerings.presents.data.InvocationMarshaller;
|
||||
import com.threerings.util.Integer;
|
||||
|
||||
/**
|
||||
* Provides the implementation of the <code>BureauService</code> interface
|
||||
* that marshalls the arguments and delivers the request to the provider
|
||||
* on the server. Also provides an implementation of the response listener
|
||||
* interfaces that marshall the response arguments and deliver them back
|
||||
* to the requesting client.
|
||||
*/
|
||||
public class BureauMarshaller extends InvocationMarshaller
|
||||
implements BureauService
|
||||
{
|
||||
/** The method id used to dispatch <code>agentCreated</code> requests. */
|
||||
public static const AGENT_CREATED :int = 1;
|
||||
|
||||
// from interface BureauService
|
||||
public function agentCreated (arg1 :int) :void
|
||||
{
|
||||
sendRequest(AGENT_CREATED, [
|
||||
Integer.valueOf(arg1)
|
||||
]);
|
||||
}
|
||||
|
||||
/** The method id used to dispatch <code>agentCreationFailed</code> requests. */
|
||||
public static const AGENT_CREATION_FAILED :int = 2;
|
||||
|
||||
// from interface BureauService
|
||||
public function agentCreationFailed (arg1 :int) :void
|
||||
{
|
||||
sendRequest(AGENT_CREATION_FAILED, [
|
||||
Integer.valueOf(arg1)
|
||||
]);
|
||||
}
|
||||
|
||||
/** The method id used to dispatch <code>agentDestroyed</code> requests. */
|
||||
public static const AGENT_DESTROYED :int = 3;
|
||||
|
||||
// from interface BureauService
|
||||
public function agentDestroyed (arg1 :int) :void
|
||||
{
|
||||
sendRequest(AGENT_DESTROYED, [
|
||||
Integer.valueOf(arg1)
|
||||
]);
|
||||
}
|
||||
|
||||
/** The method id used to dispatch <code>bureauError</code> requests. */
|
||||
public static const BUREAU_ERROR :int = 4;
|
||||
|
||||
// from interface BureauService
|
||||
public function bureauError (arg1 :String) :void
|
||||
{
|
||||
sendRequest(BUREAU_ERROR, [
|
||||
arg1
|
||||
]);
|
||||
}
|
||||
|
||||
/** The method id used to dispatch <code>bureauInitialized</code> requests. */
|
||||
public static const BUREAU_INITIALIZED :int = 5;
|
||||
|
||||
// from interface BureauService
|
||||
public function bureauInitialized (arg1 :String) :void
|
||||
{
|
||||
sendRequest(BUREAU_INITIALIZED, [
|
||||
arg1
|
||||
]);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,44 @@
|
||||
//
|
||||
// $Id$
|
||||
//
|
||||
// Narya library - tools for developing networked games
|
||||
// Copyright (C) 2002-2010 Three Rings Design, Inc., All Rights Reserved
|
||||
// http://code.google.com/p/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.bureau.util {
|
||||
|
||||
import com.threerings.presents.util.PresentsContext;
|
||||
import com.threerings.bureau.client.BureauDirector;
|
||||
|
||||
/**
|
||||
* Defines the objects held on a bureau client. This includes usual set of objects found on a
|
||||
* standard presents client.
|
||||
*/
|
||||
public interface BureauContext extends PresentsContext
|
||||
{
|
||||
/**
|
||||
* Access the director object.
|
||||
*/
|
||||
function getBureauDirector () :BureauDirector;
|
||||
|
||||
/**
|
||||
* Access the bureau id.
|
||||
*/
|
||||
function getBureauId () :String;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,73 @@
|
||||
//
|
||||
// $Id$
|
||||
//
|
||||
// Narya library - tools for developing networked games
|
||||
// Copyright (C) 2002-2010 Three Rings Design, Inc., All Rights Reserved
|
||||
// http://code.google.com/p/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.crowd.chat.client {
|
||||
|
||||
import com.threerings.util.MessageBundle;
|
||||
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 BroadcastHandler extends CommandHandler
|
||||
{
|
||||
override public function handleCommand (
|
||||
ctx :CrowdContext, speakSvc :SpeakService,
|
||||
cmd :String, args :String, history :Array) :String
|
||||
{
|
||||
if (StringUtil.isBlank(args)) {
|
||||
return "m.usage_broadcast";
|
||||
}
|
||||
|
||||
// mogrify and verify length
|
||||
var chatdir :ChatDirector = ctx.getChatDirector();
|
||||
args = chatdir.mogrifyChat(args);
|
||||
args = chatdir.filter(args, null, true);
|
||||
if (args == null) {
|
||||
return MessageBundle.compose("m.broadcast_failed", "m.filtered");
|
||||
}
|
||||
var err :String = chatdir.checkLength(args);
|
||||
if (err != null) {
|
||||
return err;
|
||||
}
|
||||
|
||||
doBroadcast(ctx, args);
|
||||
|
||||
history[0] = cmd + " ";
|
||||
return ChatCodes.SUCCESS;
|
||||
}
|
||||
|
||||
override public function checkAccess (user :BodyObject) :Boolean
|
||||
{
|
||||
return (null == user.checkAccess(ChatCodes.BROADCAST_ACCESS, null));
|
||||
}
|
||||
|
||||
/**
|
||||
* Actually do the broadcast.
|
||||
*/
|
||||
protected function doBroadcast (ctx :CrowdContext, msg :String) :void
|
||||
{
|
||||
ctx.getChatDirector().requestBroadcast(msg);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
//
|
||||
// $Id$
|
||||
//
|
||||
// Narya library - tools for developing networked games
|
||||
// Copyright (C) 2002-2010 Three Rings Design, Inc., All Rights Reserved
|
||||
// http://code.google.com/p/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.crowd.chat.client {
|
||||
|
||||
import com.threerings.crowd.chat.data.ChatChannel;
|
||||
import com.threerings.presents.client.Client;
|
||||
import com.threerings.presents.client.InvocationService;
|
||||
|
||||
/**
|
||||
* An ActionScript version of the Java ChannelSpeakService interface.
|
||||
*/
|
||||
public interface ChannelSpeakService extends InvocationService
|
||||
{
|
||||
// from Java interface ChannelSpeakService
|
||||
function speak (arg1 :ChatChannel, arg2 :String, arg3 :int) :void;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
//
|
||||
// $Id$
|
||||
//
|
||||
// Narya library - tools for developing networked games
|
||||
// Copyright (C) 2002-2010 Three Rings Design, Inc., All Rights Reserved
|
||||
// http://code.google.com/p/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.crowd.chat.client {
|
||||
|
||||
/**
|
||||
* A marker interface to be implemented by components such that
|
||||
* the chat system will not try to steal focus from them when a chat-like
|
||||
* character is entered.
|
||||
*/
|
||||
public interface ChatCantStealFocus
|
||||
{
|
||||
// nothing!
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,45 @@
|
||||
//
|
||||
// $Id$
|
||||
//
|
||||
// Narya library - tools for developing networked games
|
||||
// Copyright (C) 2002-2010 Three Rings Design, Inc., All Rights Reserved
|
||||
// http://code.google.com/p/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.crowd.chat.client {
|
||||
|
||||
import com.threerings.crowd.chat.data.ChatMessage;
|
||||
|
||||
/**
|
||||
* A chat display provides a means by which chat messages can be
|
||||
* displayed. The chat display will be notified when chat messages of
|
||||
* various sorts have been received by the client.
|
||||
*/
|
||||
public interface ChatDisplay
|
||||
{
|
||||
/**
|
||||
* Called to clear the chat display.
|
||||
*/
|
||||
function clear () :void;
|
||||
|
||||
/**
|
||||
* Called to display a chat message.
|
||||
*
|
||||
* @see ChatMessage
|
||||
*/
|
||||
function displayMessage (msg :ChatMessage) :void;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
//
|
||||
// $Id$
|
||||
//
|
||||
// Narya library - tools for developing networked games
|
||||
// Copyright (C) 2002-2010 Three Rings Design, Inc., All Rights Reserved
|
||||
// http://code.google.com/p/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.crowd.chat.client {
|
||||
|
||||
import com.threerings.util.Name;
|
||||
|
||||
/**
|
||||
* Filters messages chat messages to or from the server.
|
||||
*/
|
||||
public interface ChatFilter
|
||||
{
|
||||
/**
|
||||
* Filter a chat message.
|
||||
* @param msg the message text to be filtered.
|
||||
* @param otherUser an optional argument that represents the target or the
|
||||
* speaker, depending on 'outgoing', and can be considered in filtering if
|
||||
* it is provided.
|
||||
* @param outgoing true if the message is going out to the server.
|
||||
*
|
||||
* @return the filtered message, or null to block it completely.
|
||||
*/
|
||||
function filter (msg :String, otherUser :Name, outgoing :Boolean) :String;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
//
|
||||
// $Id$
|
||||
//
|
||||
// Narya library - tools for developing networked games
|
||||
// Copyright (C) 2002-2010 Three Rings Design, Inc., All Rights Reserved
|
||||
// http://code.google.com/p/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.crowd.chat.client {
|
||||
|
||||
import com.threerings.presents.client.Client;
|
||||
import com.threerings.presents.client.InvocationService;
|
||||
import com.threerings.presents.client.InvocationService_InvocationListener;
|
||||
import com.threerings.util.Name;
|
||||
|
||||
/**
|
||||
* An ActionScript version of the Java ChatService interface.
|
||||
*/
|
||||
public interface ChatService extends InvocationService
|
||||
{
|
||||
// from Java interface ChatService
|
||||
function away (arg1 :String) :void;
|
||||
|
||||
// from Java interface ChatService
|
||||
function broadcast (arg1 :String, arg2 :InvocationService_InvocationListener) :void;
|
||||
|
||||
// from Java interface ChatService
|
||||
function tell (arg1 :Name, arg2 :String, arg3 :ChatService_TellListener) :void;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
//
|
||||
// $Id$
|
||||
//
|
||||
// Narya library - tools for developing networked games
|
||||
// Copyright (C) 2002-2010 Three Rings Design, Inc., All Rights Reserved
|
||||
// http://code.google.com/p/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.crowd.chat.client {
|
||||
|
||||
import com.threerings.presents.client.InvocationService_InvocationListener;
|
||||
import com.threerings.util.Long;
|
||||
|
||||
/**
|
||||
* An ActionScript version of the Java ChatService_TellListener interface.
|
||||
*/
|
||||
public interface ChatService_TellListener
|
||||
extends InvocationService_InvocationListener
|
||||
{
|
||||
// from Java ChatService_TellListener
|
||||
function tellSucceeded (arg1 :Long, arg2 :String) :void
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
//
|
||||
// $Id$
|
||||
//
|
||||
// Narya library - tools for developing networked games
|
||||
// Copyright (C) 2002-2010 Three Rings Design, Inc., All Rights Reserved
|
||||
// http://code.google.com/p/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.crowd.chat.client {
|
||||
|
||||
import com.threerings.crowd.chat.data.ChatMessage;
|
||||
|
||||
/**
|
||||
* An interface for listening to chat received from the server, prior
|
||||
* to it being filtered/muted/whatever.
|
||||
*/
|
||||
public interface ChatSnooper
|
||||
{
|
||||
/**
|
||||
* Handle the arrival of chat. Do not modify the chat message! That would be a filter!
|
||||
*/
|
||||
function snoopChat (msg :ChatMessage) :void;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
//
|
||||
// $Id$
|
||||
//
|
||||
// Narya library - tools for developing networked games
|
||||
// Copyright (C) 2002-2010 Three Rings Design, Inc., All Rights Reserved
|
||||
// http://code.google.com/p/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.crowd.chat.client {
|
||||
|
||||
/**
|
||||
* An interface to receive information about the most recent users
|
||||
* that we've been chatting with.
|
||||
*/
|
||||
public interface ChatterObserver
|
||||
{
|
||||
/**
|
||||
* Called when the list of chatters has been changed.
|
||||
*/
|
||||
function chattersUpdated (chatterNames :Array) :void;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
//
|
||||
// $Id$
|
||||
//
|
||||
// Narya library - tools for developing networked games
|
||||
// Copyright (C) 2002-2010 Three Rings Design, Inc., All Rights Reserved
|
||||
// http://code.google.com/p/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.crowd.chat.client {
|
||||
|
||||
import com.threerings.util.Name;
|
||||
|
||||
/**
|
||||
* An interface used with the ChatDirector to validate which usernames
|
||||
* may be added to the chatter list.
|
||||
*/
|
||||
public interface ChatterValidator
|
||||
{
|
||||
/**
|
||||
* Arbitrates whether the username may be added to the chatters list.
|
||||
*/
|
||||
function isChatterValid (username :Name) :Boolean;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
//
|
||||
// $Id$
|
||||
//
|
||||
// Narya library - tools for developing networked games
|
||||
// Copyright (C) 2002-2010 Three Rings Design, Inc., All Rights Reserved
|
||||
// http://code.google.com/p/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.crowd.chat.client {
|
||||
|
||||
import com.threerings.crowd.util.CrowdContext;
|
||||
|
||||
import com.threerings.crowd.chat.data.ChatCodes;
|
||||
|
||||
public class ClearHandler extends CommandHandler
|
||||
{
|
||||
override public function handleCommand (
|
||||
ctx :CrowdContext, speakSvc :SpeakService,
|
||||
cmd :String, args :String, history :Array) :String
|
||||
{
|
||||
ctx.getChatDirector().clearDisplays();
|
||||
return ChatCodes.SUCCESS;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,66 @@
|
||||
//
|
||||
// $Id$
|
||||
//
|
||||
// Narya library - tools for developing networked games
|
||||
// Copyright (C) 2002-2010 Three Rings Design, Inc., All Rights Reserved
|
||||
// http://code.google.com/p/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.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>).
|
||||
*/
|
||||
public /* abstract */ class CommandHandler
|
||||
{
|
||||
/**
|
||||
* Handles the specified chat command.
|
||||
*
|
||||
* @param speakSvc an optional SpeakService object representing
|
||||
* the object to send the chat message on.
|
||||
* @param command the slash command that was used to invoke this
|
||||
* handler (e.g. <code>/tell</code>).
|
||||
* @param args the arguments provided along with the command (e.g.
|
||||
* <code>Bob hello</code>) or <code>null</code> if no arguments
|
||||
* were supplied.
|
||||
* @param history an in/out parameter that allows the command to
|
||||
* modify the text that will be appended to the chat history. If
|
||||
* this is set to null, nothing will be appended.
|
||||
*
|
||||
* @return an untranslated string that will be reported to the
|
||||
* chat box to convey an error response to the user, or {@link
|
||||
* ChatCodes#SUCCESS}.
|
||||
*/
|
||||
public function handleCommand (
|
||||
ctx :CrowdContext, speakSvc :SpeakService,
|
||||
cmd :String, args :String, history :Array) :String
|
||||
{
|
||||
throw new Error("abstract");
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if this user should have access to this chat
|
||||
* command.
|
||||
*/
|
||||
public function checkAccess (user :BodyObject) :Boolean
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,237 @@
|
||||
//
|
||||
// $Id$
|
||||
//
|
||||
// Narya library - tools for developing networked games
|
||||
// Copyright (C) 2002-2010 Three Rings Design, Inc., All Rights Reserved
|
||||
// http://code.google.com/p/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.crowd.chat.client {
|
||||
|
||||
import com.threerings.util.Log;
|
||||
import com.threerings.util.Name;
|
||||
import com.threerings.util.StringUtil;
|
||||
|
||||
/**
|
||||
* A chat filter that can filter out curse words from user chat.
|
||||
*/
|
||||
public /*abstract*/ class CurseFilter implements ChatFilter
|
||||
{
|
||||
/** Filtration constants. */
|
||||
public static const DROP :int = 0;
|
||||
public static const COMIC :int = 1;
|
||||
public static const VERNACULAR :int = 2;
|
||||
public static const UNFILTERED :int = 3;
|
||||
|
||||
/**
|
||||
* Creates a curse filter. The curse words should be a string in the
|
||||
* following format:
|
||||
*
|
||||
* <pre>
|
||||
* *penis*=John_Thomas shit*=barnacle muff=britches
|
||||
* </pre>
|
||||
*
|
||||
* The key/value pairs are separated by spaces, * matches word characters
|
||||
* and the value after the = is the string into which to convert the text
|
||||
* when converting to the vernacular. Underscores in the target string will
|
||||
* be turned into spaces.
|
||||
*
|
||||
* <p> And stopWords should be in the following format:
|
||||
*
|
||||
* <pre>
|
||||
* *faggot* rape rapes raped raping
|
||||
* </pre>
|
||||
*
|
||||
* Words are separated by spaces and * matches any other word characters.
|
||||
*/
|
||||
public function CurseFilter (curseWords :String, stopWords :String)
|
||||
{
|
||||
configureCurseWords(curseWords);
|
||||
configureStopWords(stopWords);
|
||||
}
|
||||
|
||||
/**
|
||||
* The client will need to provide a way to look up our current chat filter
|
||||
* mode.
|
||||
*/
|
||||
public function getFilterMode () :int
|
||||
{
|
||||
throw new Error("abstract");
|
||||
}
|
||||
|
||||
// from interface ChatFilter
|
||||
public function filter (
|
||||
msg :String, otherUser :Name, outgoing :Boolean) :String
|
||||
{
|
||||
// first, check against the drop-always list
|
||||
if (_stopExp.test(msg)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// then see what kind of curse filtering the user has configured
|
||||
var level :int = getFilterMode();
|
||||
if (level == UNFILTERED) {
|
||||
return msg;
|
||||
}
|
||||
|
||||
var numStops :int = _curseExps.length;
|
||||
for (var ii :int = 0; ii < numStops; ii++) {
|
||||
var regexp :RegExp = (_curseExps[ii] as RegExp);
|
||||
regexp.lastIndex = 0; // reset the matcher
|
||||
|
||||
var result :Object;
|
||||
var replacement :String;
|
||||
while (null != (result = regexp.exec(msg))) {
|
||||
switch (level) {
|
||||
case DROP:
|
||||
return null;
|
||||
|
||||
case COMIC: default:
|
||||
replacement = comicChars(int(_comicLength[ii]));
|
||||
break;
|
||||
|
||||
case VERNACULAR:
|
||||
replacement = String(_vernacular[ii]);
|
||||
// preserve the case of the first letter of the text
|
||||
// we're replacing
|
||||
if (StringUtil.isUpperCase(String(result[2]))) {
|
||||
replacement = replacement.charAt(0).toUpperCase() +
|
||||
replacement.substring(1);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
// sub in the replacement text, carrying over the pre/post
|
||||
// matching groups
|
||||
replacement = StringUtil.substitute(String(_replacements[ii]),
|
||||
String(result[1]), replacement, String(result[3]));
|
||||
|
||||
// do the replacement. Note the jimmying of lastIndex:
|
||||
// abjectscript does not make this smooth!
|
||||
var matchLength :int = String(result[0]).length;
|
||||
var matchIndex :int = int(result.index);
|
||||
msg = msg.substring(0, matchIndex) + replacement +
|
||||
msg.substring(matchIndex + matchLength);
|
||||
regexp.lastIndex += (replacement.length - matchLength);
|
||||
}
|
||||
}
|
||||
|
||||
return msg;
|
||||
}
|
||||
|
||||
/**
|
||||
* Configure the curse word portion of our filtering.
|
||||
*/
|
||||
protected function configureCurseWords (curseWords :String) :void
|
||||
{
|
||||
var tokens :Array = curseWords.split(" ");
|
||||
for each (var token :String in tokens) {
|
||||
token = StringUtil.trim(token);
|
||||
if (token == "") {
|
||||
continue;
|
||||
}
|
||||
var bits :Array = token.split("=");
|
||||
if (bits.length != 2) {
|
||||
Log.getLog(this).warning("Something looks wrong with " +
|
||||
"your cursewords (" + token + "), skipping.");
|
||||
continue;
|
||||
}
|
||||
|
||||
var curse :String = String(bits[0]);
|
||||
var sub :String = "";
|
||||
var patPre :String = "()";
|
||||
var patPost :String = "";
|
||||
if (curse.charAt(0) == "*") {
|
||||
curse = curse.substring(1);
|
||||
patPre = "([a-zA-Z]*)";
|
||||
sub += "{0}";
|
||||
}
|
||||
sub += "{1}";
|
||||
if (curse.charAt(curse.length - 1) == "*") {
|
||||
curse = curse.substring(0, curse.length - 1);
|
||||
patPost = "([a-zA-Z]*)";
|
||||
sub += "{2}";
|
||||
}
|
||||
|
||||
var regexp :RegExp = new RegExp(
|
||||
"\\b" + patPre + "(" + curse + ")" + patPost + "\\b", "gi");
|
||||
_curseExps.push(regexp);
|
||||
_replacements.push(sub);
|
||||
|
||||
var slang :String = StringUtil.trim(String(bits[1]));
|
||||
slang = slang.replace(/_/g, " ");
|
||||
_vernacular.push(slang);
|
||||
_comicLength.push(curse.length);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Configure the words that will stop.
|
||||
*/
|
||||
protected function configureStopWords (stopWords :String) :void
|
||||
{
|
||||
var tokens :Array = stopWords.split(" ");
|
||||
var pattern :String = "";
|
||||
for each (var token :String in tokens) {
|
||||
token = StringUtil.trim(token);
|
||||
if (token == "") {
|
||||
continue;
|
||||
}
|
||||
if ("" == pattern) {
|
||||
pattern += "(";
|
||||
} else {
|
||||
pattern += "|";
|
||||
}
|
||||
pattern += "\\b" +
|
||||
token.replace(/\*/g, "[A-Za-z]*") + "\\b";
|
||||
}
|
||||
pattern += ")";
|
||||
|
||||
_stopExp = new RegExp(pattern, "i");
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a comicy replacement of the specified length;
|
||||
*/
|
||||
protected function comicChars (length :int) :String
|
||||
{
|
||||
var str :String = "";
|
||||
while (length-- > 0) {
|
||||
str += COMIC_CHARS.charAt(int(Math.random() * COMIC_CHARS.length));
|
||||
}
|
||||
return str;
|
||||
}
|
||||
|
||||
/** A regexp that will always cause a message to be dropped if it
|
||||
* matches. */
|
||||
protected var _stopExp :RegExp;
|
||||
|
||||
/** Regexps for each curseword. */
|
||||
protected var _curseExps :Array = [];
|
||||
|
||||
/** Length of comic-y replacements for each curseword. */
|
||||
protected var _comicLength :Array = [];
|
||||
|
||||
/** Replacements. */
|
||||
protected var _replacements :Array = [];
|
||||
|
||||
/** Replacements for each curseword "in the vernacular". */
|
||||
protected var _vernacular :Array = [];
|
||||
|
||||
/** Comic replacement characters. */
|
||||
protected const COMIC_CHARS :String = "!@#%&*";
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,44 @@
|
||||
//
|
||||
// $Id$
|
||||
//
|
||||
// Narya library - tools for developing networked games
|
||||
// Copyright (C) 2002-2010 Three Rings Design, Inc., All Rights Reserved
|
||||
// http://code.google.com/p/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.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
|
||||
{
|
||||
override public function handleCommand (
|
||||
ctx :CrowdContext, speakSvc :SpeakService,
|
||||
cmd :String, args :String, history :Array) :String
|
||||
{
|
||||
if (StringUtil.isBlank(args)) {
|
||||
return "m.usage_emote";
|
||||
}
|
||||
history[0] = cmd + " ";
|
||||
return ctx.getChatDirector().deliverChat(
|
||||
speakSvc, args, ChatCodes.EMOTE_MODE);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,79 @@
|
||||
//
|
||||
// $Id$
|
||||
//
|
||||
// Narya library - tools for developing networked games
|
||||
// Copyright (C) 2002-2010 Three Rings Design, Inc., All Rights Reserved
|
||||
// http://code.google.com/p/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.crowd.chat.client {
|
||||
|
||||
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
|
||||
{
|
||||
override public function handleCommand (
|
||||
ctx :CrowdContext, speakSvc :SpeakService,
|
||||
cmd :String, args :String, history :Array) :String
|
||||
{
|
||||
var hcmd :String = "";
|
||||
|
||||
// grab the command they want help on
|
||||
if (!StringUtil.isBlank(args)) {
|
||||
hcmd = args;
|
||||
var sidx :int = args.indexOf(" ");
|
||||
if (sidx != -1) {
|
||||
hcmd = args.substring(0, sidx);
|
||||
}
|
||||
}
|
||||
|
||||
// let the user give commands with or without the /
|
||||
if (hcmd.charAt(0) == "/") {
|
||||
hcmd = hcmd.substring(1);
|
||||
}
|
||||
|
||||
var chatdir :ChatDirector = ctx.getChatDirector();
|
||||
|
||||
// handle "/help help" and "/help boguscmd"
|
||||
var possibleCmds :Map = chatdir.getCommandHandlers(hcmd);
|
||||
if ((hcmd === "help") || (possibleCmds.size() == 0)) {
|
||||
possibleCmds = chatdir.getCommandHandlers("");
|
||||
possibleCmds.remove("help"); // remove help from the list
|
||||
}
|
||||
|
||||
switch (possibleCmds.size()) {
|
||||
case 1:
|
||||
chatdir.displayFeedback(null, "m.usage_" + possibleCmds.keys()[0]);
|
||||
return ChatCodes.SUCCESS;
|
||||
|
||||
default:
|
||||
var cmds :Array = possibleCmds.keys();
|
||||
cmds.sort();
|
||||
var cmdList :String = "";
|
||||
for each (var skey :String in cmds) {
|
||||
cmdList += " /" + skey;
|
||||
}
|
||||
return MessageBundle.tcompose("m.usage_help", cmdList);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,161 @@
|
||||
//
|
||||
// $Id$
|
||||
//
|
||||
// Narya library - tools for developing networked games
|
||||
// Copyright (C) 2002-2010 Three Rings Design, Inc., All Rights Reserved
|
||||
// http://code.google.com/p/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.crowd.chat.client {
|
||||
|
||||
import com.threerings.util.MessageBundle;
|
||||
import com.threerings.util.Name;
|
||||
import com.threerings.util.ObserverList;
|
||||
import com.threerings.util.Set;
|
||||
import com.threerings.util.Sets;
|
||||
|
||||
import com.threerings.presents.client.BasicDirector;
|
||||
|
||||
import com.threerings.crowd.util.CrowdContext;
|
||||
|
||||
/**
|
||||
* Manages the mutelist.
|
||||
*
|
||||
* TODO: This class right now is pretty much just a placeholder.
|
||||
*/
|
||||
public class MuteDirector extends BasicDirector
|
||||
implements ChatFilter
|
||||
{
|
||||
/**
|
||||
* Should be instantiated after the ChatDirector.
|
||||
*/
|
||||
public function MuteDirector (ctx :CrowdContext)
|
||||
{
|
||||
super(ctx);
|
||||
}
|
||||
|
||||
/**
|
||||
* Called to shut down the mute director.
|
||||
*/
|
||||
public function shutdown () :void
|
||||
{
|
||||
if (_chatdir != null) {
|
||||
_chatdir.removeChatFilter(this);
|
||||
_chatdir = null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the required ChatDirector.
|
||||
*/
|
||||
public function setChatDirector (chatdir :ChatDirector) :void
|
||||
{
|
||||
if (_chatdir == null) {
|
||||
_chatdir = chatdir;
|
||||
_chatdir.addChatFilter(this);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Add the specified mutelist observer.
|
||||
*/
|
||||
public function addMuteObserver (obs :MuteObserver) :void
|
||||
{
|
||||
_observers.add(obs);
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove the specified mutelist observer.
|
||||
*/
|
||||
public function removeMuteObserver (obs :MuteObserver) :void
|
||||
{
|
||||
_observers.remove(obs);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check to see if the specified user is muted.
|
||||
*/
|
||||
public function isMuted (username :Name) :Boolean
|
||||
{
|
||||
return _mutelist.contains(username);
|
||||
}
|
||||
|
||||
/**
|
||||
* Mute or unmute the specified user.
|
||||
*/
|
||||
public function setMuted (username :Name, mute :Boolean, giveFeedback :Boolean = true) :void
|
||||
{
|
||||
var changed :Boolean = mute ? _mutelist.add(username) : _mutelist.remove(username);
|
||||
|
||||
if (giveFeedback) {
|
||||
var feedback :String = mute ? "m.muted"
|
||||
: (changed ? "m.unmuted" : "m.notmuted");
|
||||
_chatdir.displayFeedback(null, MessageBundle.tcompose(feedback, username));
|
||||
}
|
||||
|
||||
// if the mutelist actually changed, notify observers
|
||||
if (changed) {
|
||||
notifyObservers(username, mute);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return a list of the currently muted players.
|
||||
*
|
||||
* This list may be out of date immediately upon returning from this method.
|
||||
*/
|
||||
public function getMuted () :Array /* of Name */
|
||||
{
|
||||
return _mutelist.toArray();
|
||||
}
|
||||
|
||||
// documentation inherited from interface ChatFilter
|
||||
public function filter (msg :String, otherUser :Name, outgoing :Boolean) :String
|
||||
{
|
||||
// we are only concerned with filtering things going to or coming
|
||||
// from muted users
|
||||
if ((otherUser != null) && isMuted(otherUser)) {
|
||||
// if it was outgoing, explain the dropped message, otherwise
|
||||
// silently drop
|
||||
if (outgoing) {
|
||||
_chatdir.displayFeedback(null, "m.no_tell_mute");
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
return msg;
|
||||
}
|
||||
|
||||
/**
|
||||
* Notify our observers of a change in the mutelist.
|
||||
*/
|
||||
protected function notifyObservers (username :Name, muted :Boolean) :void
|
||||
{
|
||||
_observers.apply(function (observer :MuteObserver) :void {
|
||||
observer.muteChanged(username, muted);
|
||||
});
|
||||
}
|
||||
|
||||
/** The chat director that we're working hard for. */
|
||||
protected var _chatdir :ChatDirector;
|
||||
|
||||
/** The mutelist. */
|
||||
protected var _mutelist :Set = Sets.newSetOf(Name);
|
||||
|
||||
/** List of mutelist observers. */
|
||||
protected var _observers :ObserverList = new ObserverList(ObserverList.FAST_UNSAFE_NOTIFY);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
//
|
||||
// $Id$
|
||||
//
|
||||
// Narya library - tools for developing networked games
|
||||
// Copyright (C) 2002-2010 Three Rings Design, Inc., All Rights Reserved
|
||||
// http://code.google.com/p/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.crowd.chat.client {
|
||||
|
||||
import com.threerings.util.Name;
|
||||
|
||||
/**
|
||||
* An interface that can be registered with the MuteDirector to receive
|
||||
* notifications to the mutelist.
|
||||
*/
|
||||
public interface MuteObserver
|
||||
{
|
||||
/**
|
||||
* The specified player was added or removed from the mutelist.
|
||||
*/
|
||||
function muteChanged (playername :Name, nowMuted :Boolean) :void;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
//
|
||||
// $Id$
|
||||
//
|
||||
// Narya library - tools for developing networked games
|
||||
// Copyright (C) 2002-2010 Three Rings Design, Inc., All Rights Reserved
|
||||
// http://code.google.com/p/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.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
|
||||
{
|
||||
override public function handleCommand (
|
||||
ctx :CrowdContext, speakSvc :SpeakService,
|
||||
cmd :String, args :String, history :Array) :String
|
||||
{
|
||||
if (StringUtil.isBlank(args)) {
|
||||
return "m.usage_speak";
|
||||
}
|
||||
history[0] = cmd + " ";
|
||||
return ctx.getChatDirector().requestChat(null, args, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
//
|
||||
// $Id$
|
||||
//
|
||||
// Narya library - tools for developing networked games
|
||||
// Copyright (C) 2002-2010 Three Rings Design, Inc., All Rights Reserved
|
||||
// http://code.google.com/p/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.crowd.chat.client {
|
||||
|
||||
import com.threerings.presents.client.Client;
|
||||
import com.threerings.presents.client.InvocationService;
|
||||
|
||||
/**
|
||||
* An ActionScript version of the Java SpeakService interface.
|
||||
*/
|
||||
public interface SpeakService extends InvocationService
|
||||
{
|
||||
// from Java interface SpeakService
|
||||
function speak (arg1 :String, arg2 :int) :void;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
//
|
||||
// $Id$
|
||||
//
|
||||
// Narya library - tools for developing networked games
|
||||
// Copyright (C) 2002-2010 Three Rings Design, Inc., All Rights Reserved
|
||||
// http://code.google.com/p/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.crowd.chat.client {
|
||||
|
||||
import com.threerings.util.Long;
|
||||
|
||||
import com.threerings.presents.client.InvocationAdapter;
|
||||
|
||||
public class TellAdapter extends InvocationAdapter
|
||||
implements ChatService_TellListener
|
||||
{
|
||||
public function TellAdapter (failedFunc :Function, successFunc :Function)
|
||||
{
|
||||
super(failedFunc);
|
||||
_successFunc = successFunc;
|
||||
}
|
||||
|
||||
// documentation inherited from interface TellListener
|
||||
public function tellSucceeded (idleTime :Long, awayMsg :String) :void
|
||||
{
|
||||
_successFunc(idleTime, awayMsg);
|
||||
}
|
||||
|
||||
/** The method to call on success. */
|
||||
protected var _successFunc :Function;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,171 @@
|
||||
//
|
||||
// $Id$
|
||||
//
|
||||
// Narya library - tools for developing networked games
|
||||
// Copyright (C) 2002-2010 Three Rings Design, Inc., All Rights Reserved
|
||||
// http://code.google.com/p/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.crowd.chat.client {
|
||||
|
||||
import com.threerings.util.Name;
|
||||
import com.threerings.util.ResultAdapter;
|
||||
import com.threerings.util.ResultListener;
|
||||
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
|
||||
{
|
||||
override public 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,44 @@
|
||||
//
|
||||
// $Id$
|
||||
//
|
||||
// Narya library - tools for developing networked games
|
||||
// Copyright (C) 2002-2010 Three Rings Design, Inc., All Rights Reserved
|
||||
// http://code.google.com/p/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.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
|
||||
{
|
||||
override public function handleCommand (
|
||||
ctx :CrowdContext, speakSvc :SpeakService,
|
||||
cmd :String, args :String, history :Array) :String
|
||||
{
|
||||
if (StringUtil.isBlank(args)) {
|
||||
return "m.usage_think";
|
||||
}
|
||||
history[0] = cmd + " ";
|
||||
return ctx.getChatDirector().deliverChat(
|
||||
speakSvc, args, ChatCodes.THINK_MODE);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,50 @@
|
||||
//
|
||||
// $Id$
|
||||
//
|
||||
// Narya library - tools for developing networked games
|
||||
// Copyright (C) 2002-2010 Three Rings Design, Inc., All Rights Reserved
|
||||
// http://code.google.com/p/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.crowd.chat.data {
|
||||
|
||||
import com.threerings.crowd.chat.client.ChannelSpeakService;
|
||||
import com.threerings.presents.client.Client;
|
||||
import com.threerings.presents.data.InvocationMarshaller;
|
||||
import com.threerings.util.Byte;
|
||||
|
||||
/**
|
||||
* Provides the implementation of the <code>ChannelSpeakService</code> interface
|
||||
* that marshalls the arguments and delivers the request to the provider
|
||||
* on the server. Also provides an implementation of the response listener
|
||||
* interfaces that marshall the response arguments and deliver them back
|
||||
* to the requesting client.
|
||||
*/
|
||||
public class ChannelSpeakMarshaller extends InvocationMarshaller
|
||||
implements ChannelSpeakService
|
||||
{
|
||||
/** The method id used to dispatch <code>speak</code> requests. */
|
||||
public static const SPEAK :int = 1;
|
||||
|
||||
// from interface ChannelSpeakService
|
||||
public function speak (arg1 :ChatChannel, arg2 :String, arg3 :int) :void
|
||||
{
|
||||
sendRequest(SPEAK, [
|
||||
arg1, arg2, Byte.valueOf(arg3)
|
||||
]);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,61 @@
|
||||
//
|
||||
// $Id$
|
||||
//
|
||||
// Narya library - tools for developing networked games
|
||||
// Copyright (C) 2002-2010 Three Rings Design, Inc., All Rights Reserved
|
||||
// http://code.google.com/p/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.crowd.chat.data {
|
||||
|
||||
import com.threerings.io.SimpleStreamableObject;
|
||||
import com.threerings.util.Comparable;
|
||||
import com.threerings.util.Equalable;
|
||||
import com.threerings.util.Hashable;
|
||||
|
||||
import com.threerings.presents.dobj.DSet_Entry;
|
||||
|
||||
/**
|
||||
* Represents a chat channel.
|
||||
*/
|
||||
public /*abstract*/ class ChatChannel extends SimpleStreamableObject
|
||||
implements Comparable, Hashable, Equalable, DSet_Entry
|
||||
{
|
||||
// from interface Comparable
|
||||
public function compareTo (other :Object) :int
|
||||
{
|
||||
throw new Error("abstract");
|
||||
}
|
||||
|
||||
// from interface Hashable
|
||||
public function hashCode () :int
|
||||
{
|
||||
throw new Error("abstract");
|
||||
}
|
||||
|
||||
// from interface Equalable
|
||||
public function equals (other :Object) :Boolean
|
||||
{
|
||||
return compareTo(other) == 0;
|
||||
}
|
||||
|
||||
// from interface DSet_Entry
|
||||
public function getKey () :Object
|
||||
{
|
||||
return this;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,94 @@
|
||||
//
|
||||
// $Id$
|
||||
//
|
||||
// Narya library - tools for developing networked games
|
||||
// Copyright (C) 2002-2010 Three Rings Design, Inc., All Rights Reserved
|
||||
// http://code.google.com/p/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.crowd.chat.data {
|
||||
|
||||
import com.threerings.presents.data.InvocationCodes;
|
||||
import com.threerings.presents.data.Permission;
|
||||
|
||||
import com.threerings.crowd.data.BodyObject;
|
||||
|
||||
/**
|
||||
* Contains codes used by the chat invocation services.
|
||||
*/
|
||||
public class ChatCodes extends InvocationCodes
|
||||
{
|
||||
/** A return value used by the ChatDirector and possibly other entities
|
||||
* to indicate successful processing of chat. */
|
||||
public static const SUCCESS :String = "success";
|
||||
|
||||
/** The message identifier for a chat notification message. */
|
||||
public static const CHAT_NOTIFICATION :String = "crowd.chat";
|
||||
|
||||
/** The message identifier for a chat channel notification message. */
|
||||
public static const CHAT_CHANNEL_NOTIFICATION :String = "crowd.chat.channel";
|
||||
|
||||
/** The access control identifier for normal chat privileges. */
|
||||
public static const CHAT_ACCESS :Permission = new Permission();
|
||||
|
||||
/** The access control identifier for broadcast chat privileges. */
|
||||
public static const BROADCAST_ACCESS :Permission = new Permission();
|
||||
|
||||
/** The configuration key for idle time. */
|
||||
public static const IDLE_TIME_KEY :String = "narya.chat.idle_time";
|
||||
|
||||
/** The default time after which a player is assumed idle. */
|
||||
public static const DEFAULT_IDLE_TIME :Number = 3 * 60 * 1000;
|
||||
|
||||
/** The chat localtype code for chat messages delivered on the place
|
||||
* object currently occupied by the client. This is the only type of
|
||||
* chat message that will be delivered unless the chat director is
|
||||
* explicitly provided with other chat message sources via {@link
|
||||
* ChatDirector#addAuxiliarySource}. */
|
||||
public static const PLACE_CHAT_TYPE :String = "placeChat";
|
||||
|
||||
/** The chat localtype for messages received on the user object. */
|
||||
public static const USER_CHAT_TYPE :String = "userChat";
|
||||
|
||||
/** The default mode used by {@link SpeakService#speak} requests. */
|
||||
public static const DEFAULT_MODE :int = 0;
|
||||
|
||||
/** A {@link SpeakService#speak} mode to indicate that the user is
|
||||
* thinking what they're saying, or is it that they're saying what
|
||||
* they're thinking? */
|
||||
public static const THINK_MODE :int = 1;
|
||||
|
||||
/** A {@link SpeakService#speak} mode to indicate that a speak is
|
||||
* actually an emote. */
|
||||
public static const EMOTE_MODE :int = 2;
|
||||
|
||||
/** A {@link SpeakService#speak} mode to indicate that a speak is
|
||||
* actually a shout. */
|
||||
public static const SHOUT_MODE :int = 3;
|
||||
|
||||
/** A {@link SpeakService#speak} mode to indicate that a speak is
|
||||
* actually a server-wide broadcast. */
|
||||
public static const BROADCAST_MODE :int = 4;
|
||||
|
||||
/** An error code delivered when the user targeted for a tell
|
||||
* notification is not online. */
|
||||
public static const USER_NOT_ONLINE :String = "m.user_not_online";
|
||||
|
||||
/** An error code delivered when the user targeted for a tell
|
||||
* notification is disconnected. */
|
||||
public static const USER_DISCONNECTED :String = "m.user_disconnected";
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,79 @@
|
||||
//
|
||||
// $Id$
|
||||
//
|
||||
// Narya library - tools for developing networked games
|
||||
// Copyright (C) 2002-2010 Three Rings Design, Inc., All Rights Reserved
|
||||
// http://code.google.com/p/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.crowd.chat.data {
|
||||
|
||||
import com.threerings.crowd.chat.client.ChatService;
|
||||
import com.threerings.crowd.chat.client.ChatService_TellListener;
|
||||
import com.threerings.presents.client.Client;
|
||||
import com.threerings.presents.client.InvocationService_InvocationListener;
|
||||
import com.threerings.presents.data.InvocationMarshaller;
|
||||
import com.threerings.presents.data.InvocationMarshaller_ListenerMarshaller;
|
||||
import com.threerings.util.Name;
|
||||
|
||||
/**
|
||||
* Provides the implementation of the <code>ChatService</code> interface
|
||||
* that marshalls the arguments and delivers the request to the provider
|
||||
* on the server. Also provides an implementation of the response listener
|
||||
* interfaces that marshall the response arguments and deliver them back
|
||||
* to the requesting client.
|
||||
*/
|
||||
public class ChatMarshaller extends InvocationMarshaller
|
||||
implements ChatService
|
||||
{
|
||||
/** The method id used to dispatch <code>away</code> requests. */
|
||||
public static const AWAY :int = 1;
|
||||
|
||||
// from interface ChatService
|
||||
public function away (arg1 :String) :void
|
||||
{
|
||||
sendRequest(AWAY, [
|
||||
arg1
|
||||
]);
|
||||
}
|
||||
|
||||
/** The method id used to dispatch <code>broadcast</code> requests. */
|
||||
public static const BROADCAST :int = 2;
|
||||
|
||||
// from interface ChatService
|
||||
public function broadcast (arg1 :String, arg2 :InvocationService_InvocationListener) :void
|
||||
{
|
||||
var listener2 :InvocationMarshaller_ListenerMarshaller = new InvocationMarshaller_ListenerMarshaller();
|
||||
listener2.listener = arg2;
|
||||
sendRequest(BROADCAST, [
|
||||
arg1, listener2
|
||||
]);
|
||||
}
|
||||
|
||||
/** The method id used to dispatch <code>tell</code> requests. */
|
||||
public static const TELL :int = 3;
|
||||
|
||||
// from interface ChatService
|
||||
public function tell (arg1 :Name, arg2 :String, arg3 :ChatService_TellListener) :void
|
||||
{
|
||||
var listener3 :ChatMarshaller_TellMarshaller = new ChatMarshaller_TellMarshaller();
|
||||
listener3.listener = arg3;
|
||||
sendRequest(TELL, [
|
||||
arg1, arg2, listener3
|
||||
]);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,52 @@
|
||||
//
|
||||
// $Id$
|
||||
//
|
||||
// Narya library - tools for developing networked games
|
||||
// Copyright (C) 2002-2010 Three Rings Design, Inc., All Rights Reserved
|
||||
// http://code.google.com/p/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.crowd.chat.data {
|
||||
|
||||
import com.threerings.crowd.chat.client.ChatService_TellListener;
|
||||
import com.threerings.presents.data.InvocationMarshaller_ListenerMarshaller;
|
||||
import com.threerings.util.Long;
|
||||
|
||||
/**
|
||||
* Marshalls instances of the ChatService_TellMarshaller interface.
|
||||
*/
|
||||
public class ChatMarshaller_TellMarshaller
|
||||
extends InvocationMarshaller_ListenerMarshaller
|
||||
{
|
||||
/** The method id used to dispatch <code>tellSucceeded</code> responses. */
|
||||
public static const TELL_SUCCEEDED :int = 1;
|
||||
|
||||
// from InvocationMarshaller_ListenerMarshaller
|
||||
override public function dispatchResponse (methodId :int, args :Array) :void
|
||||
{
|
||||
switch (methodId) {
|
||||
case TELL_SUCCEEDED:
|
||||
(listener as ChatService_TellListener).tellSucceeded(
|
||||
(args[0] as Long), (args[1] as String));
|
||||
return;
|
||||
|
||||
default:
|
||||
super.dispatchResponse(methodId, args);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,100 @@
|
||||
//
|
||||
// $Id$
|
||||
//
|
||||
// Narya library - tools for developing networked games
|
||||
// Copyright (C) 2002-2010 Three Rings Design, Inc., All Rights Reserved
|
||||
// http://code.google.com/p/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.crowd.chat.data {
|
||||
|
||||
import flash.utils.getTimer; // function import
|
||||
|
||||
import com.threerings.util.ClassUtil;
|
||||
|
||||
import com.threerings.io.ObjectInputStream;
|
||||
import com.threerings.io.ObjectOutputStream;
|
||||
import com.threerings.io.Streamable;
|
||||
|
||||
/**
|
||||
* The abstract base class of all the client-side ChatMessage objects.
|
||||
*/
|
||||
public /*abstract*/ class ChatMessage
|
||||
implements Streamable
|
||||
{
|
||||
/** The actual text of the message. */
|
||||
public var message :String;
|
||||
|
||||
/** The bundle to use when translating this message. */
|
||||
public var bundle :String;
|
||||
|
||||
/** The client side 'localtype' of this chat, set to the type registered with an auxiliary
|
||||
* source in the ChatDirector. */
|
||||
public var localtype :String;
|
||||
|
||||
/** The client time that this message was created. */
|
||||
public var timestamp :int;
|
||||
|
||||
public function ChatMessage (msg :String = null, bundle :String = null)
|
||||
{
|
||||
this.message = msg;
|
||||
this.bundle = bundle;
|
||||
}
|
||||
|
||||
/**
|
||||
* Once this message reaches the client, the information contained within
|
||||
* is changed around a bit.
|
||||
*/
|
||||
public function setClientInfo (msg :String, localtype :String) :void
|
||||
{
|
||||
message = msg;
|
||||
this.localtype = localtype;
|
||||
bundle = null;
|
||||
timestamp = getTimer();
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates a string representation of this instance.
|
||||
*/
|
||||
public function toString () :String
|
||||
{
|
||||
return ClassUtil.shortClassName(this) +
|
||||
" [message=" + message + ", bundle=" + bundle + "]";
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the appropriate message format for this message.
|
||||
*/
|
||||
public function getFormat () :String
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
// from interface Streamable
|
||||
public function readObject (ins :ObjectInputStream) :void
|
||||
{
|
||||
message = (ins.readField(String) as String);
|
||||
bundle = (ins.readField(String) as String);
|
||||
}
|
||||
|
||||
// from interface Streamable
|
||||
public function writeObject (out :ObjectOutputStream) :void
|
||||
{
|
||||
out.writeField(message);
|
||||
out.writeField(bundle);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,50 @@
|
||||
//
|
||||
// $Id$
|
||||
//
|
||||
// Narya library - tools for developing networked games
|
||||
// Copyright (C) 2002-2010 Three Rings Design, Inc., All Rights Reserved
|
||||
// http://code.google.com/p/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.crowd.chat.data {
|
||||
|
||||
import com.threerings.crowd.chat.client.SpeakService;
|
||||
import com.threerings.presents.client.Client;
|
||||
import com.threerings.presents.data.InvocationMarshaller;
|
||||
import com.threerings.util.Byte;
|
||||
|
||||
/**
|
||||
* Provides the implementation of the <code>SpeakService</code> interface
|
||||
* that marshalls the arguments and delivers the request to the provider
|
||||
* on the server. Also provides an implementation of the response listener
|
||||
* interfaces that marshall the response arguments and deliver them back
|
||||
* to the requesting client.
|
||||
*/
|
||||
public class SpeakMarshaller extends InvocationMarshaller
|
||||
implements SpeakService
|
||||
{
|
||||
/** The method id used to dispatch <code>speak</code> requests. */
|
||||
public static const SPEAK :int = 1;
|
||||
|
||||
// from interface SpeakService
|
||||
public function speak (arg1 :String, arg2 :int) :void
|
||||
{
|
||||
sendRequest(SPEAK, [
|
||||
arg1, Byte.valueOf(arg2)
|
||||
]);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,67 @@
|
||||
//
|
||||
// $Id$
|
||||
//
|
||||
// Narya library - tools for developing networked games
|
||||
// Copyright (C) 2002-2010 Three Rings Design, Inc., All Rights Reserved
|
||||
// http://code.google.com/p/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.crowd.chat.data {
|
||||
|
||||
import com.threerings.io.ObjectInputStream;
|
||||
import com.threerings.io.ObjectOutputStream;
|
||||
|
||||
/**
|
||||
* A ChatMessage that represents a message that came from the server
|
||||
* and did not result from direct user action.
|
||||
*/
|
||||
public class SystemMessage extends ChatMessage
|
||||
{
|
||||
/** Attention level constant to indicate that this message is merely providing the user with
|
||||
* information. */
|
||||
public static const INFO :int = 0;
|
||||
|
||||
/** Attention level constant to indicate that this message is the result of a user action. */
|
||||
public static const FEEDBACK :int = 1;
|
||||
|
||||
/** Attention level constant to indicate that some action is required. */
|
||||
public static const ATTENTION :int = 2;
|
||||
|
||||
/** The attention level of this message. */
|
||||
public var attentionLevel :int;
|
||||
|
||||
public function SystemMessage (
|
||||
msg :String = null, bundle :String = null, attLevel :int = 0)
|
||||
{
|
||||
super(msg, bundle);
|
||||
this.attentionLevel = attLevel;
|
||||
}
|
||||
|
||||
// from interface Streamable
|
||||
override public function readObject (ins :ObjectInputStream) :void
|
||||
{
|
||||
super.readObject(ins);
|
||||
attentionLevel = ins.readByte();
|
||||
}
|
||||
|
||||
// from interface Streamable
|
||||
override public function writeObject (out :ObjectOutputStream) :void
|
||||
{
|
||||
super.writeObject(out);
|
||||
out.writeByte(attentionLevel);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,71 @@
|
||||
//
|
||||
// $Id$
|
||||
//
|
||||
// Narya library - tools for developing networked games
|
||||
// Copyright (C) 2002-2010 Three Rings Design, Inc., All Rights Reserved
|
||||
// http://code.google.com/p/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.crowd.chat.data {
|
||||
|
||||
import com.threerings.io.ObjectInputStream;
|
||||
import com.threerings.io.ObjectOutputStream;
|
||||
import com.threerings.util.Name;
|
||||
|
||||
/**
|
||||
* A feedback message to indicate that a tell succeeded.
|
||||
*/
|
||||
public class TellFeedbackMessage extends UserMessage
|
||||
{
|
||||
/**
|
||||
* A tell feedback message is only composed on the client.
|
||||
*/
|
||||
public function TellFeedbackMessage (target :Name, message :String, failed :Boolean = false)
|
||||
{
|
||||
super(target, null, message);
|
||||
_failure = failed;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if this is a failure feedback, false if it is successful tell feedback.
|
||||
*/
|
||||
public function isFailure () :Boolean
|
||||
{
|
||||
return _failure;
|
||||
}
|
||||
|
||||
override public function getFormat () :String
|
||||
{
|
||||
return _failure ? null : "m.told_format";
|
||||
}
|
||||
|
||||
// from interface Streamable
|
||||
override public function readObject (ins :ObjectInputStream) :void
|
||||
{
|
||||
super.readObject(ins);
|
||||
_failure = ins.readBoolean();
|
||||
}
|
||||
|
||||
// from interface Streamable
|
||||
override public function writeObject (out :ObjectOutputStream) :void
|
||||
{
|
||||
super.writeObject(out);
|
||||
out.writeBoolean(_failure);
|
||||
}
|
||||
|
||||
protected var _failure :Boolean;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,93 @@
|
||||
//
|
||||
// $Id$
|
||||
//
|
||||
// Narya library - tools for developing networked games
|
||||
// Copyright (C) 2002-2010 Three Rings Design, Inc., All Rights Reserved
|
||||
// http://code.google.com/p/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.crowd.chat.data {
|
||||
|
||||
import com.threerings.util.Name;
|
||||
|
||||
import com.threerings.io.ObjectInputStream;
|
||||
import com.threerings.io.ObjectOutputStream;
|
||||
|
||||
/**
|
||||
* A ChatMessage representing a message that came from another user.
|
||||
*/
|
||||
public class UserMessage extends ChatMessage
|
||||
{
|
||||
/** The user that the message came from. */
|
||||
public var speaker :Name;
|
||||
|
||||
/** The mode of the message. @see ChatCodes.DEFAULT_MODE */
|
||||
public var mode :int;
|
||||
|
||||
/**
|
||||
* Constructs a user message for a player originated tell (which has no
|
||||
* bundle and is in the default mode).
|
||||
*/
|
||||
public function UserMessage (speaker :Name = null, bundle :String = null,
|
||||
message :String = null, mode :int = 0)
|
||||
{
|
||||
super(message, bundle);
|
||||
this.speaker = speaker;
|
||||
this.mode = mode;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the name to display for the speaker. Some types of messages
|
||||
* may wish to not use the canonical name for the speaker and should thus
|
||||
* override this function.
|
||||
*/
|
||||
public function getSpeakerDisplayName () :Name
|
||||
{
|
||||
return speaker;
|
||||
}
|
||||
|
||||
override public function getFormat () :String
|
||||
{
|
||||
switch (mode) {
|
||||
case ChatCodes.THINK_MODE: return "m.think_format";
|
||||
case ChatCodes.EMOTE_MODE: return "m.emote_format";
|
||||
case ChatCodes.SHOUT_MODE: return "m.shout_format";
|
||||
case ChatCodes.BROADCAST_MODE: return "m.broadcast_format";
|
||||
}
|
||||
|
||||
if (ChatCodes.USER_CHAT_TYPE === localtype) {
|
||||
return "m.tell_format";
|
||||
}
|
||||
return "m.speak_format";
|
||||
}
|
||||
|
||||
// from interface Streamable
|
||||
override public function readObject (ins :ObjectInputStream) :void
|
||||
{
|
||||
super.readObject(ins);
|
||||
speaker = Name(ins.readObject());
|
||||
mode = ins.readByte();
|
||||
}
|
||||
|
||||
// from interface Streamable
|
||||
override public function writeObject (out :ObjectOutputStream) :void
|
||||
{
|
||||
super.writeObject(out);
|
||||
out.writeObject(speaker);
|
||||
out.writeByte(mode);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,64 @@
|
||||
//
|
||||
// $Id$
|
||||
//
|
||||
// Narya library - tools for developing networked games
|
||||
// Copyright (C) 2002-2010 Three Rings Design, Inc., All Rights Reserved
|
||||
// http://code.google.com/p/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.crowd.chat.data {
|
||||
|
||||
import com.threerings.util.Name;
|
||||
|
||||
import com.threerings.io.ObjectInputStream;
|
||||
import com.threerings.io.ObjectOutputStream;
|
||||
|
||||
/**
|
||||
* A system message triggered by the activity of another user.
|
||||
* If the user is muted we can suppress this message, unlike a normal
|
||||
* system message.
|
||||
*/
|
||||
public class UserSystemMessage extends SystemMessage
|
||||
{
|
||||
/** The "speaker" of this message, the user that triggered that this message be sent to us. */
|
||||
public var speaker :Name;
|
||||
|
||||
/**
|
||||
* Construct a UserSystemMessage.
|
||||
*/
|
||||
public function UserSystemMessage (
|
||||
sender :Name = null, message :String = null, bundle :String = null,
|
||||
attLevel :int = 0)
|
||||
{
|
||||
super(message, bundle, attLevel);
|
||||
this.speaker = sender;
|
||||
}
|
||||
|
||||
// from interface Streamable
|
||||
override public function readObject (ins :ObjectInputStream) :void
|
||||
{
|
||||
super.readObject(ins);
|
||||
speaker = Name(ins.readObject());
|
||||
}
|
||||
|
||||
// from interface Streamable
|
||||
override public function writeObject (out :ObjectOutputStream) :void
|
||||
{
|
||||
super.writeObject(out);
|
||||
out.writeObject(speaker);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
//
|
||||
// $Id$
|
||||
//
|
||||
// Narya library - tools for developing networked games
|
||||
// Copyright (C) 2002-2010 Three Rings Design, Inc., All Rights Reserved
|
||||
// http://code.google.com/p/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.crowd.client {
|
||||
|
||||
import com.threerings.presents.client.Client;
|
||||
import com.threerings.presents.client.InvocationService;
|
||||
|
||||
/**
|
||||
* An ActionScript version of the Java BodyService interface.
|
||||
*/
|
||||
public interface BodyService extends InvocationService
|
||||
{
|
||||
// from Java interface BodyService
|
||||
function setIdle (arg1 :Boolean) :void;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
//
|
||||
// $Id$
|
||||
//
|
||||
// Narya library - tools for developing networked games
|
||||
// Copyright (C) 2002-2010 Three Rings Design, Inc., All Rights Reserved
|
||||
// http://code.google.com/p/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.crowd.client {
|
||||
|
||||
import com.threerings.presents.client.Client;
|
||||
import com.threerings.presents.net.Credentials;
|
||||
|
||||
import com.threerings.crowd.data.BodyMarshaller;
|
||||
import com.threerings.crowd.data.CrowdPermissionPolicy;
|
||||
|
||||
/**
|
||||
* Users of the Crowd services should extend this client so that it can ensure that certain
|
||||
* ActionScript classes that will arrive over the wire as a result of using basic Crowd services
|
||||
* will be included in the client.
|
||||
*/
|
||||
public class CrowdClient extends Client
|
||||
{
|
||||
// statically reference classes we require
|
||||
BodyMarshaller;
|
||||
CrowdPermissionPolicy;
|
||||
|
||||
public function CrowdClient (creds :Credentials)
|
||||
{
|
||||
super(creds);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,64 @@
|
||||
//
|
||||
// $Id$
|
||||
//
|
||||
// Narya library - tools for developing networked games
|
||||
// Copyright (C) 2002-2010 Three Rings Design, Inc., All Rights Reserved
|
||||
// http://code.google.com/p/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.crowd.client {
|
||||
|
||||
import com.threerings.crowd.data.PlaceObject;
|
||||
|
||||
public class LocationAdapter
|
||||
implements LocationObserver
|
||||
{
|
||||
public function LocationAdapter (
|
||||
mayChange :Function = null, didChange :Function = null,
|
||||
changeFailed :Function = null)
|
||||
{
|
||||
_mayChange = mayChange;
|
||||
_didChange = didChange;
|
||||
_changeFailed = changeFailed;
|
||||
}
|
||||
|
||||
// documentation inherited from interface LocationObserver
|
||||
public function locationMayChange (placeId :int) :Boolean
|
||||
{
|
||||
return (_mayChange == null) || _mayChange(placeId);
|
||||
}
|
||||
|
||||
// documentation inherited from interface LocationObserver
|
||||
public function locationDidChange (place :PlaceObject) :void
|
||||
{
|
||||
if (_didChange != null) {
|
||||
_didChange(place);
|
||||
}
|
||||
}
|
||||
|
||||
// documentation inherited from interface LocationObserver
|
||||
public function locationChangeFailed (placeId :int, reason :String) :void
|
||||
{
|
||||
if (_changeFailed != null) {
|
||||
_changeFailed(placeId, reason);
|
||||
}
|
||||
}
|
||||
|
||||
protected var _mayChange :Function;
|
||||
protected var _didChange :Function;
|
||||
protected var _changeFailed :Function;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,70 @@
|
||||
//
|
||||
// $Id$
|
||||
//
|
||||
// Narya library - tools for developing networked games
|
||||
// Copyright (C) 2002-2010 Three Rings Design, Inc., All Rights Reserved
|
||||
// http://code.google.com/p/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.crowd.client {
|
||||
|
||||
import com.threerings.crowd.client.LocationReceiver;
|
||||
import com.threerings.presents.client.InvocationDecoder;
|
||||
|
||||
/**
|
||||
* Dispatches calls to a {@link LocationReceiver} instance.
|
||||
*/
|
||||
public class LocationDecoder extends InvocationDecoder
|
||||
{
|
||||
/** The generated hash code used to identify this receiver class. */
|
||||
public static const RECEIVER_CODE :String = "58f2830e027f4f3377e100ef12332497";
|
||||
|
||||
/** The method id used to dispatch {@link LocationReceiver#forcedMove}
|
||||
* notifications. */
|
||||
public static const FORCED_MOVE :int = 1;
|
||||
|
||||
/**
|
||||
* Creates a decoder that may be registered to dispatch invocation
|
||||
* service notifications to the specified receiver.
|
||||
*/
|
||||
public function LocationDecoder (receiver :LocationReceiver)
|
||||
{
|
||||
this.receiver = receiver;
|
||||
}
|
||||
|
||||
// documentation inherited
|
||||
override public function getReceiverCode () :String
|
||||
{
|
||||
return RECEIVER_CODE;
|
||||
}
|
||||
|
||||
// documentation inherited
|
||||
override public function dispatchNotification (
|
||||
methodId :int, args :Array) :void
|
||||
{
|
||||
switch (methodId) {
|
||||
case FORCED_MOVE:
|
||||
(receiver as LocationReceiver).forcedMove(
|
||||
(args[0] as int)
|
||||
);
|
||||
return;
|
||||
|
||||
default:
|
||||
super.dispatchNotification(methodId, args);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,616 @@
|
||||
//
|
||||
// $Id$
|
||||
//
|
||||
// Narya library - tools for developing networked games
|
||||
// Copyright (C) 2002-2010 Three Rings Design, Inc., All Rights Reserved
|
||||
// http://code.google.com/p/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.crowd.client {
|
||||
|
||||
import flash.utils.getTimer; // function import
|
||||
|
||||
import com.threerings.util.ObserverList;
|
||||
import com.threerings.util.Log;
|
||||
import com.threerings.util.ResultListener;
|
||||
|
||||
import com.threerings.presents.client.BasicDirector;
|
||||
import com.threerings.presents.client.Client;
|
||||
import com.threerings.presents.client.ClientEvent;
|
||||
|
||||
import com.threerings.presents.dobj.DObject;
|
||||
import com.threerings.presents.dobj.ObjectAccessError;
|
||||
import com.threerings.presents.dobj.Subscriber;
|
||||
import com.threerings.presents.dobj.SubscriberAdapter;
|
||||
|
||||
import com.threerings.crowd.data.BodyObject;
|
||||
import com.threerings.crowd.data.CrowdCodes;
|
||||
import com.threerings.crowd.data.LocationMarshaller;
|
||||
import com.threerings.crowd.data.PlaceConfig;
|
||||
import com.threerings.crowd.data.PlaceObject;
|
||||
import com.threerings.crowd.util.CrowdContext;
|
||||
|
||||
/**
|
||||
* The location director provides a means by which entities on the client can request to move from
|
||||
* place to place and can be notified if other entities have caused the client to move to a new
|
||||
* place. It also provides a mechanism for ratifying a request to move to a new place before
|
||||
* actually issuing the request.
|
||||
*/
|
||||
public class LocationDirector extends BasicDirector
|
||||
implements Subscriber, LocationReceiver
|
||||
{
|
||||
// statically reference classes we require
|
||||
LocationMarshaller;
|
||||
|
||||
/**
|
||||
* Constructs a location director which will configure itself for operation using the supplied
|
||||
* context.
|
||||
*/
|
||||
public function LocationDirector (ctx :CrowdContext)
|
||||
{
|
||||
super(ctx);
|
||||
|
||||
// keep this around for later
|
||||
_cctx = ctx;
|
||||
|
||||
// register for location notifications
|
||||
_cctx.getClient().getInvocationDirector().registerReceiver(new LocationDecoder(this));
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a location observer to the list. This observer will subsequently be notified of
|
||||
* potential, effected and failed location changes.
|
||||
*/
|
||||
public function addLocationObserver (observer :LocationObserver) :void
|
||||
{
|
||||
_observers.add(observer);
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes a location observer from the list.
|
||||
*/
|
||||
public function removeLocationObserver (observer :LocationObserver) :void
|
||||
{
|
||||
_observers.remove(observer);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the place object for the location we currently occupy or null if we're not currently
|
||||
* occupying any location.
|
||||
*/
|
||||
public function getPlaceObject () :PlaceObject
|
||||
{
|
||||
return _plobj;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the controller for the location we currently occupy or null if we're not currently
|
||||
* occupying any location.
|
||||
*/
|
||||
public function getPlaceController () :PlaceController
|
||||
{
|
||||
return _controller;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if there is a pending move request.
|
||||
*/
|
||||
public function movePending () :Boolean
|
||||
{
|
||||
return (_pendingPlaceId > 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Requests that this client be moved to the specified place. A request will be made and when
|
||||
* the response is received, the location observers will be notified of success or failure.
|
||||
*
|
||||
* @return true if the move to request was issued, false if it was rejected by a location
|
||||
* observer or because we have another request outstanding.
|
||||
*/
|
||||
public function moveTo (placeId :int) :Boolean
|
||||
{
|
||||
// make sure the placeId is valid
|
||||
if (placeId < 0) {
|
||||
log.warning("Refusing moveTo(): invalid placeId", "placeId", placeId);
|
||||
return false;
|
||||
}
|
||||
|
||||
// first check to see if our observers are happy with this move request
|
||||
if (!mayMoveTo(placeId, null)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// we need to call this both to mark that we're issuing a move request and to check to see
|
||||
// if the last issued request should be considered stale
|
||||
var refuse :Boolean = checkRepeatMove();
|
||||
|
||||
// complain if we're over-writing a pending request
|
||||
if (_pendingPlaceId != -1) {
|
||||
// if the pending request has been outstanding more than a minute, go ahead and let
|
||||
// this new one through in an attempt to recover from dropped moveTo requests
|
||||
if (refuse) {
|
||||
log.warning("Refusing moveTo; We have a request outstanding",
|
||||
"ppid", _pendingPlaceId, "npid", placeId);
|
||||
return false;
|
||||
|
||||
} else {
|
||||
log.warning("Overriding stale moveTo request",
|
||||
"ppid", _pendingPlaceId, "npid", placeId);
|
||||
}
|
||||
}
|
||||
|
||||
// make a note of our pending place id
|
||||
_pendingPlaceId = placeId;
|
||||
|
||||
// documentation inherited from interface MoveListener
|
||||
var success :Function = function (config :PlaceConfig) :void {
|
||||
// handle the successful move
|
||||
didMoveTo(_pendingPlaceId, config);
|
||||
|
||||
// and clear out the tracked pending oid
|
||||
_pendingPlaceId = -1;
|
||||
|
||||
handlePendingForcedMove();
|
||||
};
|
||||
|
||||
// documentation inherited from interface MoveListener
|
||||
var failure :Function = function (reason :String) :void {
|
||||
// clear out our pending request oid
|
||||
var placeId :int = _pendingPlaceId;
|
||||
_pendingPlaceId = -1;
|
||||
|
||||
log.info("moveTo failed", "pid", placeId, "reason", reason);
|
||||
|
||||
// let our observers know that something has gone horribly awry
|
||||
notifyFailure(placeId, reason);
|
||||
|
||||
handlePendingForcedMove();
|
||||
};
|
||||
|
||||
// issue a moveTo request
|
||||
log.info("Issuing moveTo", "placeId", placeId);
|
||||
_lservice.moveTo(placeId, new MoveAdapter(success, failure));
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Requests to move to the room that we last occupied, if such a room exists.
|
||||
*
|
||||
* @return true if we had a previous room and we requested to move to it, false if we had no
|
||||
* previous room.
|
||||
*/
|
||||
public function moveBack () :Boolean
|
||||
{
|
||||
if (_previousPlaceId == -1) {
|
||||
return false;
|
||||
|
||||
} else {
|
||||
moveTo(_previousPlaceId);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Issues a request to leave our current location.
|
||||
*
|
||||
* @return true if we were able to leave, false if we are in the middle of moving somewhere and
|
||||
* can't yet leave.
|
||||
*/
|
||||
public function leavePlace () :Boolean
|
||||
{
|
||||
if (_pendingPlaceId != -1) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// if we're not actually in a place, then no need to do anything
|
||||
if (_placeId > 0) {
|
||||
_lservice.leavePlace();
|
||||
didLeavePlace();
|
||||
|
||||
// let our observers know that we're no longer in a location
|
||||
_observers.apply(didChangeOp);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* This can be called by cooperating directors that need to coopt the moving process to extend
|
||||
* it in some way or other. In such situations, they should call this method before moving to a
|
||||
* new location to check to be sure that all of the registered location observers are amenable
|
||||
* to a location change.
|
||||
*
|
||||
* @param placeId the place oid of our tentative new location.
|
||||
*
|
||||
* @return true if everyone is happy with the move, false if it was vetoed by one of the
|
||||
* location observers.
|
||||
*/
|
||||
public function mayMoveTo (placeId :int, rl :ResultListener) :Boolean
|
||||
{
|
||||
var vetoed :Boolean = false;
|
||||
_observers.apply(function (obs :Object) :void {
|
||||
var lobs :LocationObserver = (obs as LocationObserver);
|
||||
vetoed = vetoed || !lobs.locationMayChange(placeId);
|
||||
});
|
||||
|
||||
// if we're actually going somewhere, let the controller know that we might be leaving
|
||||
mayLeavePlace();
|
||||
|
||||
// if we have a result listener, let it know if we failed or keep it for later if we're
|
||||
// still going
|
||||
if (rl != null) {
|
||||
if (vetoed) {
|
||||
rl.requestFailed(new MoveVetoedError());
|
||||
} else {
|
||||
_moveListener = rl;
|
||||
}
|
||||
}
|
||||
// and return the result
|
||||
return !vetoed;
|
||||
}
|
||||
|
||||
/**
|
||||
* Called to inform our controller that we may be leaving the current place.
|
||||
*/
|
||||
protected function mayLeavePlace () :void
|
||||
{
|
||||
if (_controller != null) {
|
||||
try {
|
||||
_controller.mayLeavePlace(_plobj);
|
||||
} catch (e :Error) {
|
||||
log.warning("Place controller choked in mayLeavePlace", "plobj", _plobj, e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This can be called by cooperating directors that need to coopt the moving process to extend
|
||||
* it in some way or other. In such situations, they will be responsible for receiving the
|
||||
* successful move response and they should let the location director know that the move has
|
||||
* been effected.
|
||||
*
|
||||
* @param placeId the place oid of our new location.
|
||||
* @param config the configuration information for the new place.
|
||||
*/
|
||||
public function didMoveTo (placeId :int, config :PlaceConfig) :void
|
||||
{
|
||||
if (_moveListener != null) {
|
||||
_moveListener.requestCompleted(config);
|
||||
_moveListener = null;
|
||||
}
|
||||
|
||||
// keep track of our previous place id
|
||||
_previousPlaceId = _placeId;
|
||||
|
||||
// clear out our last request time
|
||||
_lastRequestTime = 0;
|
||||
|
||||
// do some cleaning up in case we were previously in a place
|
||||
didLeavePlace();
|
||||
|
||||
// make a note that we're now mostly in the new location
|
||||
_placeId = placeId;
|
||||
|
||||
// check whether we should use a custom class loader
|
||||
_controller = config.createController();
|
||||
if (_controller == null) {
|
||||
log.warning("Place config returned null controller", "config", config);
|
||||
return;
|
||||
}
|
||||
_controller.init(_cctx, config);
|
||||
|
||||
// subscribe to our new place object to complete the move
|
||||
_cctx.getDObjectManager().subscribeToObject(_placeId, this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when we're leaving our current location. Informs the location's controller that we're
|
||||
* departing, unsubscribes from the location's place object, and clears out our internal place
|
||||
* information.
|
||||
*/
|
||||
public function didLeavePlace () :void
|
||||
{
|
||||
if (_plobj != null) {
|
||||
// let the old controller know that things are going away
|
||||
if (_controller != null) {
|
||||
try {
|
||||
_controller.didLeavePlace(_plobj);
|
||||
} catch (e :Error) {
|
||||
log.warning("Place controller choked in didLeavePlace", "plobj", _plobj, e);
|
||||
}
|
||||
_controller = null;
|
||||
}
|
||||
|
||||
// let the chat director know that we're leaving this place
|
||||
_cctx.getChatDirector().leftLocation(_plobj);
|
||||
|
||||
// unsubscribe from our old place object
|
||||
_cctx.getDObjectManager().unsubscribeFromObject(_plobj.getOid(), this);
|
||||
_plobj = null;
|
||||
|
||||
// and clear out the associated place id
|
||||
_placeId = -1;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This can be called by cooperating directors that need to coopt the moving process to extend
|
||||
* it in some way or other. If the coopted move request fails, this failure can be propagated
|
||||
* to the location observers if appropriate.
|
||||
*
|
||||
* @param placeId the place oid to which we failed to move.
|
||||
* @param reason the reason code given for failure.
|
||||
*/
|
||||
public function failedToMoveTo (placeId :int, reason :String) :void
|
||||
{
|
||||
if (_moveListener != null) {
|
||||
_moveListener.requestFailed(new MoveFailedError(reason));
|
||||
_moveListener = null;
|
||||
}
|
||||
|
||||
// clear out our last request time
|
||||
_lastRequestTime = 0;
|
||||
|
||||
// let our observers know what's up
|
||||
notifyFailure(placeId, reason);
|
||||
}
|
||||
|
||||
/**
|
||||
* Called to test and set a time stamp that we use to determine if a pending moveTo request is
|
||||
* stale.
|
||||
*/
|
||||
public function checkRepeatMove () :Boolean
|
||||
{
|
||||
var now :Number = getTimer();
|
||||
if (now - _lastRequestTime < STALE_REQUEST_DURATION) {
|
||||
return true;
|
||||
|
||||
} else {
|
||||
_lastRequestTime = now;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// documentation inherited from interface
|
||||
override public function clientDidLogon (event :ClientEvent) :void
|
||||
{
|
||||
super.clientDidLogon(event);
|
||||
|
||||
var success :Function = function (object :DObject) :void {
|
||||
gotBodyObject(object as BodyObject);
|
||||
};
|
||||
var failure :Function = function (oid :int, cause :ObjectAccessError) :void {
|
||||
log.warning("Unable to fetch body object; all has gone horribly wrong", cause);
|
||||
};
|
||||
|
||||
var client :Client = event.getClient();
|
||||
client.getDObjectManager().subscribeToObject(
|
||||
client.getClientOid(), new SubscriberAdapter(success, failure));
|
||||
}
|
||||
|
||||
// documentation inherited
|
||||
override public function clientDidLogoff (event :ClientEvent) :void
|
||||
{
|
||||
super.clientDidLogoff(event);
|
||||
|
||||
// clear ourselves out and inform observers of our departure
|
||||
mayLeavePlace();
|
||||
didLeavePlace();
|
||||
|
||||
// let our observers know that we're no longer in a location
|
||||
_observers.apply(didChangeOp);
|
||||
|
||||
// clear out everything else (it's possible that we were logged off in the middle of a
|
||||
// change location request)
|
||||
_pendingPlaceId = -1;
|
||||
_pendingForcedMoves = [];
|
||||
_previousPlaceId = -1;
|
||||
_lastRequestTime = 0;
|
||||
_lservice = null;
|
||||
}
|
||||
|
||||
// from BasicDirector
|
||||
override protected function registerServices (client :Client) :void
|
||||
{
|
||||
client.addServiceGroup(CrowdCodes.CROWD_GROUP);
|
||||
}
|
||||
|
||||
// from BasicDirector
|
||||
override protected function fetchServices (client :Client) :void
|
||||
{
|
||||
// obtain our service handle
|
||||
_lservice = (client.requireService(LocationService) as LocationService);
|
||||
}
|
||||
|
||||
protected function gotBodyObject (clobj :BodyObject) :void
|
||||
{
|
||||
// check to see if we are already in a location, in which case we'll want to be going there
|
||||
// straight away
|
||||
}
|
||||
|
||||
// documentation inherited from interface
|
||||
public function forcedMove (placeId :int) :void
|
||||
{
|
||||
// if we're in the middle of a move, we can't abort it or we will screw everything up, so
|
||||
// just finish up what we're doing and assume that the repeated move request was the
|
||||
// spurious one as it would be in the case of lag causing rapid-fire repeat requests
|
||||
if (movePending()) {
|
||||
if (_pendingPlaceId == placeId) {
|
||||
log.info("Dropping forced move because we have a move pending",
|
||||
"pendId", _pendingPlaceId, "reqId", placeId);
|
||||
} else {
|
||||
log.info("Delaying forced move because we have a move pending",
|
||||
"pendId", _pendingPlaceId, "reqId", placeId);
|
||||
addPendingForcedMove(new function() :void {
|
||||
forcedMove(placeId);
|
||||
});
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
log.info("Moving at request of server", "placeId", placeId);
|
||||
|
||||
// clear out our old place information
|
||||
mayLeavePlace();
|
||||
didLeavePlace();
|
||||
|
||||
// move to the new place
|
||||
moveTo(placeId);
|
||||
}
|
||||
|
||||
// documentation inherited from interface Subscriber
|
||||
public function objectAvailable (object :DObject) :void
|
||||
{
|
||||
// yay, we have our new place object
|
||||
_plobj = (object as PlaceObject);
|
||||
|
||||
// let the place controller know that we're ready to roll
|
||||
if (_controller != null) {
|
||||
try {
|
||||
_controller.willEnterPlace(_plobj);
|
||||
} catch (e :Error) {
|
||||
log.warning("Controller choked in willEnterPlace", "place", _plobj, e);
|
||||
}
|
||||
}
|
||||
|
||||
// let the chat director know that we're entering this place
|
||||
_cctx.getChatDirector().enteredLocation(_plobj);
|
||||
|
||||
// let our observers know that all is well on the western front
|
||||
_observers.apply(didChangeOp);
|
||||
}
|
||||
|
||||
// documentation inherited from interface Subscriber
|
||||
public function requestFailed (oid :int, cause :ObjectAccessError) :void
|
||||
{
|
||||
// aiya! we were unable to fetch our new place object; something is badly wrong
|
||||
log.warning("Aiya! Unable to fetch place object for new location",
|
||||
"plid", oid, "reason", cause);
|
||||
|
||||
// clear out our half initialized place info
|
||||
var placeId :int = _placeId;
|
||||
_placeId = -1;
|
||||
|
||||
// let the kids know shit be fucked
|
||||
notifyFailure(placeId, "m.unable_to_fetch_place_object");
|
||||
|
||||
// we need to sort out what to do about the half-initialized place controller. presently we
|
||||
// punt and hope that calling didLeavePlace() without ever having called willEnterPlace()
|
||||
// does whatever's necessary
|
||||
|
||||
// try to return to our previous location
|
||||
if (_failureHandler != null) {
|
||||
_failureHandler.recoverFailedMove(placeId);
|
||||
|
||||
} else {
|
||||
// if we were previously somewhere (and that somewhere isn't where we just tried to
|
||||
// go), try going back to that happy place
|
||||
if (_previousPlaceId != -1 && _previousPlaceId != placeId) {
|
||||
moveTo(_previousPlaceId);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the failure handler which will recover from place object fetching failures. In the
|
||||
* event that we are unable to fetch our place object after making a successful moveTo request,
|
||||
* we attempt to rectify the failure by moving back to the last known working location. Because
|
||||
* entites that cooperate with the location director may need to become involved in this
|
||||
* failure recovery, we provide this interface whereby they can interject themseves into the
|
||||
* failure recovery process and do their own failure recovery.
|
||||
*/
|
||||
public function setFailureHandler (handler :LocationDirector_FailureHandler) :void
|
||||
{
|
||||
if (_failureHandler != null) {
|
||||
log.warning("Requested to set failure handler, but we've already got one. The " +
|
||||
"conflicting entities will likely need to perform more sophisticated " +
|
||||
"coordination to deal with failures.",
|
||||
"old", _failureHandler, "new", handler);
|
||||
|
||||
} else {
|
||||
_failureHandler = handler;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* The operation used to inform observers that the location changed.
|
||||
*/
|
||||
protected function didChangeOp (obs :Object) :void
|
||||
{
|
||||
(obs as LocationObserver).locationDidChange(_plobj);
|
||||
};
|
||||
|
||||
protected function notifyFailure (placeId :int, reason :String) :void
|
||||
{
|
||||
_observers.apply(function (obs :Object) :void {
|
||||
(obs as LocationObserver).locationChangeFailed(placeId, reason);
|
||||
});
|
||||
}
|
||||
|
||||
public function addPendingForcedMove (move :Function) :void
|
||||
{
|
||||
_pendingForcedMoves.push(move);
|
||||
}
|
||||
|
||||
protected function handlePendingForcedMove () :void
|
||||
{
|
||||
if (!_pendingForcedMoves.length == 0) {
|
||||
_ctx.getClient().callLater(_pendingForcedMoves.pop());
|
||||
}
|
||||
}
|
||||
|
||||
protected const log :Log = Log.getLog(this);
|
||||
|
||||
/** The context through which we access needed services. */
|
||||
protected var _cctx :CrowdContext;
|
||||
|
||||
/** Provides access to location services. */
|
||||
protected var _lservice :LocationService;
|
||||
|
||||
/** Our location observer list. */
|
||||
protected var _observers :ObserverList = new ObserverList(ObserverList.SAFE_IN_ORDER_NOTIFY);
|
||||
|
||||
/** The oid of the place we currently occupy. */
|
||||
protected var _placeId :int = -1;
|
||||
|
||||
/** The place object that we currently occupy. */
|
||||
protected var _plobj :PlaceObject;
|
||||
|
||||
/** The place controller in effect for our current place. */
|
||||
protected var _controller :PlaceController;
|
||||
|
||||
/** The place oid to whihc we have an outstanding moveTo request, or -1 if we have none. */
|
||||
protected var _pendingPlaceId :int = -1;
|
||||
|
||||
/** The oid of the place we previously occupied. */
|
||||
protected var _previousPlaceId :int = -1;
|
||||
|
||||
/** The last time we requested a move to. */
|
||||
protected var _lastRequestTime :Number;
|
||||
|
||||
/** The entity that deals when we fail to subscribe to a place object. */
|
||||
protected var _failureHandler :LocationDirector_FailureHandler;
|
||||
|
||||
/** A listener that wants to know if we succeeded or how we failed to move. */
|
||||
protected var _moveListener :ResultListener;
|
||||
|
||||
/** Forced move actions we should take once we complete the move we're in the middle of. */
|
||||
protected var _pendingForcedMoves :Array = [];
|
||||
|
||||
/** Allow a moveTo request be outstanding for one minute before it is declared to be stale. */
|
||||
protected static const STALE_REQUEST_DURATION :int = 60 * 1000;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
//
|
||||
// $Id$
|
||||
//
|
||||
// Narya library - tools for developing networked games
|
||||
// Copyright (C) 2002-2010 Three Rings Design, Inc., All Rights Reserved
|
||||
// http://code.google.com/p/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.crowd.client {
|
||||
|
||||
/**
|
||||
* Used to recover from a moveTo request that was accepted but
|
||||
* resulted in a failed attempt to fetch the place object to which we
|
||||
* were moving.
|
||||
*/
|
||||
public interface LocationDirector_FailureHandler
|
||||
{
|
||||
/**
|
||||
* Should instruct the client to move to the last known working
|
||||
* location (as well as clean up after the failed moveTo request).
|
||||
*/
|
||||
function recoverFailedMove (placeId :int) :void;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,68 @@
|
||||
//
|
||||
// $Id$
|
||||
//
|
||||
// Narya library - tools for developing networked games
|
||||
// Copyright (C) 2002-2010 Three Rings Design, Inc., All Rights Reserved
|
||||
// http://code.google.com/p/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.crowd.client {
|
||||
|
||||
import com.threerings.crowd.data.PlaceObject;
|
||||
|
||||
/**
|
||||
* The location observer interface makes it possible for entities to be
|
||||
* notified when the client moves to a new location. It also provides a
|
||||
* means for an entity to participate in the ratification process of a new
|
||||
* location. Observers may opt to reject a request to change to a new
|
||||
* location, probably because something is going on in the previous
|
||||
* location that should not be abandoned.
|
||||
*
|
||||
* <p> Note that these location callbacks occur on the main thread and
|
||||
* should execute quickly and not block under any circumstance.
|
||||
*/
|
||||
public interface LocationObserver
|
||||
{
|
||||
/**
|
||||
* Called when someone has requested that we switch to a new location.
|
||||
* An observer may choose to veto the location change request for some
|
||||
* reason or other.
|
||||
*
|
||||
* @return true if it's OK for the location to change, false if the
|
||||
* change request should be aborted.
|
||||
*/
|
||||
function locationMayChange (placeId :int) :Boolean;
|
||||
|
||||
/**
|
||||
* Called when we have switched to a new location.
|
||||
*
|
||||
* @param place the place object that represents the new location or
|
||||
* null if we have switched to no location.
|
||||
*/
|
||||
function locationDidChange (place :PlaceObject) :void;
|
||||
|
||||
/**
|
||||
* This is called on all location observers when a location change
|
||||
* request is rejected by the server or fails for some other reason.
|
||||
*
|
||||
* @param placeId the place id to which we attempted to relocate, but
|
||||
* failed.
|
||||
* @param reason the reason code that explains why the location change
|
||||
* request was rejected or otherwise failed.
|
||||
*/
|
||||
function locationChangeFailed (placeId :int, reason :String) :void;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
//
|
||||
// $Id$
|
||||
//
|
||||
// Narya library - tools for developing networked games
|
||||
// Copyright (C) 2002-2010 Three Rings Design, Inc., All Rights Reserved
|
||||
// http://code.google.com/p/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.crowd.client {
|
||||
|
||||
import com.threerings.presents.client.InvocationReceiver;
|
||||
|
||||
/**
|
||||
* Defines, for the location services, a set of notifications delivered
|
||||
* asynchronously by the server to the client.
|
||||
*/
|
||||
public interface LocationReceiver extends InvocationReceiver
|
||||
{
|
||||
/**
|
||||
* Used to communicate a required move notification to the client. The
|
||||
* server will have removed the client from their existing location
|
||||
* and the client is then responsible for generating a {@link
|
||||
* LocationService#moveTo} request to move to the new location.
|
||||
*/
|
||||
function forcedMove (placeId :int) :void;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
//
|
||||
// $Id$
|
||||
//
|
||||
// Narya library - tools for developing networked games
|
||||
// Copyright (C) 2002-2010 Three Rings Design, Inc., All Rights Reserved
|
||||
// http://code.google.com/p/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.crowd.client {
|
||||
|
||||
import com.threerings.presents.client.Client;
|
||||
import com.threerings.presents.client.InvocationService;
|
||||
|
||||
/**
|
||||
* An ActionScript version of the Java LocationService interface.
|
||||
*/
|
||||
public interface LocationService extends InvocationService
|
||||
{
|
||||
// from Java interface LocationService
|
||||
function leavePlace () :void;
|
||||
|
||||
// from Java interface LocationService
|
||||
function moveTo (arg1 :int, arg2 :LocationService_MoveListener) :void;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
//
|
||||
// $Id$
|
||||
//
|
||||
// Narya library - tools for developing networked games
|
||||
// Copyright (C) 2002-2010 Three Rings Design, Inc., All Rights Reserved
|
||||
// http://code.google.com/p/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.crowd.client {
|
||||
|
||||
import com.threerings.crowd.data.PlaceConfig;
|
||||
import com.threerings.presents.client.InvocationService_InvocationListener;
|
||||
|
||||
/**
|
||||
* An ActionScript version of the Java LocationService_MoveListener interface.
|
||||
*/
|
||||
public interface LocationService_MoveListener
|
||||
extends InvocationService_InvocationListener
|
||||
{
|
||||
// from Java LocationService_MoveListener
|
||||
function moveSucceeded (arg1 :PlaceConfig) :void
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
//
|
||||
// $Id$
|
||||
//
|
||||
// Narya library - tools for developing networked games
|
||||
// Copyright (C) 2002-2010 Three Rings Design, Inc., All Rights Reserved
|
||||
// http://code.google.com/p/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.crowd.client {
|
||||
|
||||
import com.threerings.presents.client.InvocationAdapter;
|
||||
|
||||
import com.threerings.crowd.data.PlaceConfig;
|
||||
|
||||
public class MoveAdapter extends InvocationAdapter
|
||||
implements LocationService_MoveListener
|
||||
{
|
||||
public function MoveAdapter (success :Function, failure :Function)
|
||||
{
|
||||
super(failure);
|
||||
_success = success;
|
||||
}
|
||||
|
||||
// documentation inherited from interface MoveListener
|
||||
public function moveSucceeded (config :PlaceConfig) :void
|
||||
{
|
||||
_success(config);
|
||||
}
|
||||
|
||||
protected var _success :Function;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
//
|
||||
// $Id$
|
||||
//
|
||||
// Narya library - tools for developing networked games
|
||||
// Copyright (C) 2002-2010 Three Rings Design, Inc., All Rights Reserved
|
||||
// http://code.google.com/p/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.crowd.client {
|
||||
|
||||
/**
|
||||
* An exception that indicates that the server did not allow us to move.
|
||||
*/
|
||||
public class MoveFailedError extends Error
|
||||
{
|
||||
public function MoveFailedError (message :String)
|
||||
{
|
||||
super(message);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
//
|
||||
// $Id$
|
||||
//
|
||||
// Narya library - tools for developing networked games
|
||||
// Copyright (C) 2002-2010 Three Rings Design, Inc., All Rights Reserved
|
||||
// http://code.google.com/p/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.crowd.client {
|
||||
|
||||
/**
|
||||
* An exception that indicates that a LocationObserver vetoed our move request.
|
||||
*/
|
||||
public class MoveVetoedError extends Error
|
||||
{
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,65 @@
|
||||
//
|
||||
// $Id$
|
||||
//
|
||||
// Narya library - tools for developing networked games
|
||||
// Copyright (C) 2002-2010 Three Rings Design, Inc., All Rights Reserved
|
||||
// http://code.google.com/p/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.crowd.client {
|
||||
|
||||
import com.threerings.crowd.data.OccupantInfo;
|
||||
|
||||
public class OccupantAdapter
|
||||
implements OccupantObserver
|
||||
{
|
||||
public function OccupantAdapter (
|
||||
entered :Function = null, left :Function = null, updated :Function = null)
|
||||
{
|
||||
_entered = entered;
|
||||
_left = left;
|
||||
_updated = updated;
|
||||
}
|
||||
|
||||
// from interface OccupantObserver
|
||||
public function occupantEntered (info :OccupantInfo) :void
|
||||
{
|
||||
if (_entered != null) {
|
||||
_entered(info);
|
||||
}
|
||||
}
|
||||
|
||||
// from interface OccupantObserver
|
||||
public function occupantLeft (info :OccupantInfo) :void
|
||||
{
|
||||
if (_left != null) {
|
||||
_left(info);
|
||||
}
|
||||
}
|
||||
|
||||
// from interface OccupantObserver
|
||||
public function occupantUpdated (oldinfo :OccupantInfo, newinfo :OccupantInfo) :void
|
||||
{
|
||||
if (_updated != null) {
|
||||
_updated(oldinfo, newinfo);
|
||||
}
|
||||
}
|
||||
|
||||
protected var _entered :Function;
|
||||
protected var _left :Function;
|
||||
protected var _updated :Function;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,204 @@
|
||||
//
|
||||
// $Id$
|
||||
//
|
||||
// Narya library - tools for developing networked games
|
||||
// Copyright (C) 2002-2010 Three Rings Design, Inc., All Rights Reserved
|
||||
// http://code.google.com/p/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.crowd.client {
|
||||
|
||||
import com.threerings.util.ObserverList;
|
||||
import com.threerings.util.Name;
|
||||
|
||||
import com.threerings.presents.client.BasicDirector;
|
||||
import com.threerings.presents.client.Client;
|
||||
import com.threerings.presents.client.ClientEvent;
|
||||
import com.threerings.presents.dobj.EntryAddedEvent;
|
||||
import com.threerings.presents.dobj.EntryRemovedEvent;
|
||||
import com.threerings.presents.dobj.EntryUpdatedEvent;
|
||||
import com.threerings.presents.dobj.SetListener;
|
||||
|
||||
import com.threerings.crowd.data.OccupantInfo;
|
||||
import com.threerings.crowd.data.PlaceObject;
|
||||
import com.threerings.crowd.util.CrowdContext;
|
||||
|
||||
/**
|
||||
* The occupant director listens for occupants of places to enter and
|
||||
* exit, and dispatches notices to interested parties about these events.
|
||||
*
|
||||
* <p> It will eventually provide a framework for keeping track of
|
||||
* occupant information in a network efficient manner. The idea being that
|
||||
* we want to store as little information about occupants as possible in
|
||||
* the place object (probably just body oid and username), but upon
|
||||
* entering a place, this will be all we know about the occupants. We then
|
||||
* dispatch a request to get information about all of the occupants in the
|
||||
* room (things like avatar information for a graphical display or perhaps
|
||||
* their ratings in the game that is associated with a place for a gaming
|
||||
* site) which we then pass on to the occupant observers when it becomes
|
||||
* available.
|
||||
*
|
||||
* <p> This information would be cached and we could return cached
|
||||
* information for occupants for which we have cached info. We will
|
||||
* probably want to still make a request for the occupant info so that we
|
||||
* can update non-static occupant data rather than permanently using
|
||||
* what's in the cache.
|
||||
*/
|
||||
public class OccupantDirector extends BasicDirector
|
||||
implements LocationObserver, SetListener
|
||||
{
|
||||
/**
|
||||
* Constructs a new occupant director with the supplied context.
|
||||
*/
|
||||
public function OccupantDirector (ctx :CrowdContext)
|
||||
{
|
||||
super(ctx);
|
||||
|
||||
// register ourselves as a location observer
|
||||
ctx.getLocationDirector().addLocationObserver(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds the specified occupant observer to the list.
|
||||
*/
|
||||
public function addOccupantObserver (obs :OccupantObserver) :void
|
||||
{
|
||||
_observers.add(obs);
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes the specified occupant observer from the list.
|
||||
*/
|
||||
public function removeOccupantObserver (obs :OccupantObserver) :void
|
||||
{
|
||||
_observers.remove(obs);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the occupant info for the user in question if it exists in
|
||||
* the currently occupied place. Returns null if no occupant info
|
||||
* exists for the specified body.
|
||||
*/
|
||||
public function getOccupantInfo (bodyOid :int) :OccupantInfo
|
||||
{
|
||||
// make sure we're somewhere
|
||||
return (_place == null) ? null :
|
||||
(_place.occupantInfo.get(bodyOid) as OccupantInfo);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the occupant info for the user in question if it exists in
|
||||
* the currently occupied place. Returns null if no occupant info
|
||||
* exists with the specified username.
|
||||
*/
|
||||
public function getOccupantInfoByName (username :Name) :OccupantInfo
|
||||
{
|
||||
return (_place == null) ? null : _place.getOccupantInfo(username);
|
||||
}
|
||||
|
||||
// documentation inherited
|
||||
override public function clientDidLogoff (event :ClientEvent) :void
|
||||
{
|
||||
super.clientDidLogoff(event);
|
||||
// clear things out
|
||||
if (_place != null) {
|
||||
_place.removeListener(this);
|
||||
_place = null;
|
||||
}
|
||||
}
|
||||
|
||||
// documentation inherited from interface LocationObserver
|
||||
public function locationMayChange (placeId :int) :Boolean
|
||||
{
|
||||
// we've got no opinion
|
||||
return true;
|
||||
}
|
||||
|
||||
// documentation inherited from interface LocationObserver
|
||||
public function locationDidChange (place :PlaceObject) :void
|
||||
{
|
||||
// unlisten to the old place object if there was one
|
||||
if (_place != null) {
|
||||
_place.removeListener(this);
|
||||
}
|
||||
|
||||
// listen to the new one
|
||||
_place = place;
|
||||
if (_place != null) {
|
||||
_place.addListener(this);
|
||||
}
|
||||
}
|
||||
|
||||
// documentation inherited from interface LocationObserver
|
||||
public function locationChangeFailed (placeId :int, reason :String) :void
|
||||
{
|
||||
// nothing to do here either
|
||||
}
|
||||
|
||||
// documentation inherited from interface SetListener
|
||||
public function entryAdded (event :EntryAddedEvent) :void
|
||||
{
|
||||
// bail if this isn't for the OCCUPANT_INFO field
|
||||
if (event.getName() != PlaceObject.OCCUPANT_INFO) {
|
||||
return;
|
||||
}
|
||||
|
||||
// now let the occupant observers know what's up
|
||||
var info :OccupantInfo = (event.getEntry() as OccupantInfo);
|
||||
_observers.apply(function (obj :Object) :void {
|
||||
(obj as OccupantObserver).occupantEntered(info);
|
||||
});
|
||||
}
|
||||
|
||||
// documentation inherited from interface SetListener
|
||||
public function entryUpdated (event :EntryUpdatedEvent) :void
|
||||
{
|
||||
// bail if this isn't for the OCCUPANT_INFO field
|
||||
if (event.getName() != PlaceObject.OCCUPANT_INFO) {
|
||||
return;
|
||||
}
|
||||
|
||||
// now let the occupant observers know what's up
|
||||
var info :OccupantInfo = (event.getEntry() as OccupantInfo);
|
||||
var oinfo :OccupantInfo = (event.getOldEntry() as OccupantInfo);
|
||||
_observers.apply(function (obj :Object) :void {
|
||||
(obj as OccupantObserver).occupantUpdated(oinfo, info);
|
||||
});
|
||||
}
|
||||
|
||||
// documentation inherited from interface SetListener
|
||||
public function entryRemoved (event :EntryRemovedEvent) :void
|
||||
{
|
||||
// bail if this isn't for the OCCUPANT_INFO field
|
||||
if (event.getName() != PlaceObject.OCCUPANT_INFO) {
|
||||
return;
|
||||
}
|
||||
|
||||
// let the occupant observers know what's up
|
||||
var oinfo :OccupantInfo = (event.getOldEntry() as OccupantInfo);
|
||||
_observers.apply(function (obj :Object) :void {
|
||||
(obj as OccupantObserver).occupantLeft(oinfo);
|
||||
});
|
||||
}
|
||||
|
||||
/** The occupant observers to keep abreast of occupant antics. */
|
||||
protected var _observers :ObserverList =
|
||||
new ObserverList(ObserverList.SAFE_IN_ORDER_NOTIFY);
|
||||
|
||||
/** The user's current location. */
|
||||
protected var _place :PlaceObject;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,52 @@
|
||||
//
|
||||
// $Id$
|
||||
//
|
||||
// Narya library - tools for developing networked games
|
||||
// Copyright (C) 2002-2010 Three Rings Design, Inc., All Rights Reserved
|
||||
// http://code.google.com/p/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.crowd.client {
|
||||
|
||||
import com.threerings.crowd.data.OccupantInfo;
|
||||
|
||||
/**
|
||||
* An entity that is interested in hearing about bodies that enter and
|
||||
* leave a location (as well as disconnect and reconnect) can implement
|
||||
* this interface and register itself with the {@link OccupantDirector}.
|
||||
*/
|
||||
public interface OccupantObserver
|
||||
{
|
||||
/**
|
||||
* Called when a body enters the place.
|
||||
*/
|
||||
function occupantEntered (info :OccupantInfo) :void;
|
||||
|
||||
/**
|
||||
* Called when a body leaves the place.
|
||||
*/
|
||||
function occupantLeft (info :OccupantInfo) :void;
|
||||
|
||||
/**
|
||||
* Called when an occupant is updated.
|
||||
*
|
||||
* @param oldinfo the occupant info prior to the update.
|
||||
* @param newinfo the newly update info record.
|
||||
*/
|
||||
function occupantUpdated (
|
||||
oldinfo :OccupantInfo, newinfo :OccupantInfo) :void;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,257 @@
|
||||
//
|
||||
// $Id$
|
||||
//
|
||||
// Narya library - tools for developing networked games
|
||||
// Copyright (C) 2002-2010 Three Rings Design, Inc., All Rights Reserved
|
||||
// http://code.google.com/p/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.crowd.client {
|
||||
|
||||
import com.threerings.util.Controller;
|
||||
|
||||
import com.threerings.crowd.data.PlaceConfig;
|
||||
import com.threerings.crowd.data.PlaceObject;
|
||||
import com.threerings.crowd.util.CrowdContext;
|
||||
|
||||
/**
|
||||
* Controls the user interface that is used to display a place. When the
|
||||
* client moves to a new place, the appropriate place controller is
|
||||
* constructed and requested to create and display the appopriate user
|
||||
* interface for that place.
|
||||
*/
|
||||
public /*abstract*/ class PlaceController extends Controller
|
||||
{
|
||||
/**
|
||||
* Initializes this place controller with a reference to the context
|
||||
* that they can use to access client services and to the
|
||||
* configuration record for this place. The controller should create
|
||||
* as much of its user interface that it can without having access to
|
||||
* the place object because this will be invoked in parallel with the
|
||||
* fetching of the place object. When the place object is obtained,
|
||||
* the controller will be notified and it can then finish the user
|
||||
* interface configuration and put the user interface into operation.
|
||||
*
|
||||
* @param ctx the client context.
|
||||
* @param config the place configuration for this place.
|
||||
*/
|
||||
public function init (ctx :CrowdContext, config :PlaceConfig) :void
|
||||
{
|
||||
// keep these around
|
||||
_ctx = ctx;
|
||||
_config = config;
|
||||
|
||||
// create our user interface
|
||||
_view = createPlaceView(_ctx);
|
||||
|
||||
// initialize our delegates
|
||||
applyToDelegates(function (del :PlaceControllerDelegate) :void {
|
||||
del.init(_ctx, _config);
|
||||
});
|
||||
|
||||
// let the derived classes do any initialization stuff
|
||||
didInit();
|
||||
}
|
||||
|
||||
/**
|
||||
* Derived classes can override this and perform any
|
||||
* post-initialization processing they might need. They should of
|
||||
* course be sure to call <code>super.didInit()</code>.
|
||||
*/
|
||||
protected function didInit () :void
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a reference to the place view associated with this
|
||||
* controller. This is only valid after a call has been made to {@link
|
||||
* #init}.
|
||||
*/
|
||||
public function getPlaceView () :PlaceView
|
||||
{
|
||||
return _view;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the {@link PlaceConfig} associated with this place.
|
||||
*/
|
||||
public function getPlaceConfig () :PlaceConfig
|
||||
{
|
||||
return _config;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates the user interface that will be used to display this place.
|
||||
* The view instance returned will later be configured with the place
|
||||
* object, once it becomes available.
|
||||
*
|
||||
* @param ctx a reference to the {@link CrowdContext} associated with
|
||||
* this controller.
|
||||
*/
|
||||
protected function createPlaceView (ctx :CrowdContext) :PlaceView
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* This is called by the location director once the place object has
|
||||
* been fetched. The place controller will dispatch the place object
|
||||
* to the user interface hierarchy via {@link
|
||||
* PlaceViewUtil#dispatchWillEnterPlace}. Derived classes can override
|
||||
* this and perform any other starting up that they need to do
|
||||
*/
|
||||
public function willEnterPlace (plobj :PlaceObject) :void
|
||||
{
|
||||
// keep a handle on our place object
|
||||
_plobj = plobj;
|
||||
|
||||
if (_view != null ) {
|
||||
// set it as our controlled panel
|
||||
setControlledPanel(_view);
|
||||
|
||||
// let the UI hierarchy know that we've got our place
|
||||
PlaceViewUtil.dispatchWillEnterPlace(_view, plobj);
|
||||
// and display the user interface
|
||||
setPlaceView();
|
||||
}
|
||||
|
||||
// let our delegates know what's up
|
||||
applyToDelegates(function (del :PlaceControllerDelegate) :void {
|
||||
del.willEnterPlace(plobj);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Called before a request is submitted to the server to leave the
|
||||
* current place. As such, this method may be called multiple times
|
||||
* before {@link #didLeavePlace} is finally called. The request to
|
||||
* leave may be rejected, but if a place controller needs to flush any
|
||||
* information to the place manager before it leaves, it should so do
|
||||
* here. This is the only place in which the controller is guaranteed
|
||||
* to be able to communicate to the place manager, as by the time
|
||||
* {@link #didLeavePlace} is called, the place manager may have
|
||||
* already been destroyed.
|
||||
*/
|
||||
public function mayLeavePlace (plobj :PlaceObject) :void
|
||||
{
|
||||
// let our delegates know what's up
|
||||
applyToDelegates(function (del :PlaceControllerDelegate) :void {
|
||||
del.mayLeavePlace(plobj);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* This is called by the location director when we are leaving this
|
||||
* place and need to clean up after ourselves and shutdown. Derived
|
||||
* classes should override this method (being sure to call
|
||||
* <code>super.didLeavePlace</code>) and perform any necessary
|
||||
* cleanup.
|
||||
*/
|
||||
public function didLeavePlace (plobj :PlaceObject) :void
|
||||
{
|
||||
// let our delegates know what's up
|
||||
applyToDelegates(function (del :PlaceControllerDelegate) :void {
|
||||
del.didLeavePlace(plobj);
|
||||
});
|
||||
|
||||
setControlledPanel(null);
|
||||
|
||||
// let the UI hierarchy know that we're outta here
|
||||
if (_view != null ) {
|
||||
PlaceViewUtil.dispatchDidLeavePlace(_view, plobj);
|
||||
clearPlaceView();
|
||||
_view = null;
|
||||
}
|
||||
|
||||
_plobj = null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles basic place controller action events. Derived classes
|
||||
* should be sure to call <code>super.handleAction</code> for events
|
||||
* they don't specifically handle.
|
||||
*/
|
||||
override public function handleAction (cmd :String, arg :Object) :Boolean
|
||||
{
|
||||
var handled :Boolean = false;
|
||||
|
||||
// let our delegates have a crack at the action
|
||||
applyToDelegates(function (del :PlaceControllerDelegate) :void {
|
||||
// we take advantage of short-circuiting here
|
||||
handled = handled || del.handleAction(cmd, arg);
|
||||
});
|
||||
|
||||
// if they didn't handly it, pass it off to the super class
|
||||
return handled || super.handleAction(cmd, arg);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds the supplied delegate to the list for this controller.
|
||||
*/
|
||||
protected function addDelegate (delegate :PlaceControllerDelegate) :void
|
||||
{
|
||||
if (_delegates == null) {
|
||||
_delegates = new Array();
|
||||
}
|
||||
_delegates.push(delegate);
|
||||
}
|
||||
|
||||
/**
|
||||
* Applies the supplied operation to the registered delegates.
|
||||
*/
|
||||
protected function applyToDelegates (visitor :Function) :void
|
||||
{
|
||||
if (_delegates != null) {
|
||||
for (var ii :int = 0; ii < _delegates.length; ii++) {
|
||||
visitor.call(this, _delegates[ii]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the place view. By default, this simply calls {CrowdContext#setPlaceView},
|
||||
* but subclasses can override the method to add the place view in some other way.
|
||||
*/
|
||||
protected function setPlaceView () :void
|
||||
{
|
||||
_ctx.setPlaceView(_view);
|
||||
}
|
||||
|
||||
/**
|
||||
* Clears out the place view. By default, this calls {CrowdContext#clearPlaceView}.
|
||||
*/
|
||||
protected function clearPlaceView () :void
|
||||
{
|
||||
_ctx.clearPlaceView(_view);
|
||||
}
|
||||
|
||||
/** A reference to the active client context. */
|
||||
protected var _ctx :CrowdContext;
|
||||
|
||||
/** A reference to our place configuration. */
|
||||
protected var _config :PlaceConfig;
|
||||
|
||||
/** A reference to the place object for which we're controlling a user
|
||||
* interface. */
|
||||
protected var _plobj :PlaceObject;
|
||||
|
||||
/** A reference to the root user interface component. */
|
||||
protected var _view :PlaceView;
|
||||
|
||||
/** A list of the delegates in use by this controller. */
|
||||
protected var _delegates :Array;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,97 @@
|
||||
//
|
||||
// $Id$
|
||||
//
|
||||
// Narya library - tools for developing networked games
|
||||
// Copyright (C) 2002-2010 Three Rings Design, Inc., All Rights Reserved
|
||||
// http://code.google.com/p/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.crowd.client {
|
||||
|
||||
import com.threerings.crowd.data.PlaceConfig;
|
||||
import com.threerings.crowd.data.PlaceObject;
|
||||
import com.threerings.crowd.util.CrowdContext;
|
||||
|
||||
/**
|
||||
* Provides an extensible mechanism for encapsulating delegated
|
||||
* functionality that works with the place services.
|
||||
*
|
||||
* <p> Thanks to Java's lack of multiple inheritance, it will likely
|
||||
* become necessary to factor certain services that might be used by a
|
||||
* variety of {@link PlaceController} derived classes into delegate
|
||||
* classes because they do not fit into the single inheritance hierarchy
|
||||
* that makes sense for a particular application. To facilitate this
|
||||
* process, this delegate class is provided which the standard place
|
||||
* controller can be made to call out to for all of the standard methods.
|
||||
*/
|
||||
public class PlaceControllerDelegate
|
||||
{
|
||||
/**
|
||||
* Constructs the delegate with the controller for which it is
|
||||
* delegating.
|
||||
*/
|
||||
public function PlaceControllerDelegate (controller :PlaceController)
|
||||
{
|
||||
_controller = controller;
|
||||
}
|
||||
|
||||
/**
|
||||
* Called to initialize the delegate.
|
||||
*/
|
||||
public function init (ctx :CrowdContext, config :PlaceConfig) :void
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* Called to let the delegate know that we're entering a place.
|
||||
*/
|
||||
public function willEnterPlace (plobj :PlaceObject) :void
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* Called before a request is submitted to the server to leave the
|
||||
* current place. The request to leave may be rejected, but if a place
|
||||
* controller needs to make a final communication to the place manager
|
||||
* before it leaves, it should so do here. This is the only place in
|
||||
* which the controller is guaranteed to be able to communicate to the
|
||||
* place manager, as by the time {@link #didLeavePlace} is called, the
|
||||
* place manager may have already been destroyed.
|
||||
*/
|
||||
public function mayLeavePlace (plobj :PlaceObject) :void
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* Called to let the delegate know that we've left the place.
|
||||
*/
|
||||
public function didLeavePlace (plobj :PlaceObject) :void
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* Called to give the delegate a chance to handle controller actions
|
||||
* that weren't handled by the main controller.
|
||||
*/
|
||||
public function handleAction (cmd :String, arg :Object) :Boolean
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/** A reference to the controller for which we are delegating. */
|
||||
protected var _controller :PlaceController;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,79 @@
|
||||
//
|
||||
// $Id$
|
||||
//
|
||||
// Narya library - tools for developing networked games
|
||||
// Copyright (C) 2002-2010 Three Rings Design, Inc., All Rights Reserved
|
||||
// http://code.google.com/p/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.crowd.client {
|
||||
|
||||
import flash.events.IEventDispatcher;
|
||||
|
||||
import com.threerings.crowd.data.PlaceObject;
|
||||
|
||||
/**
|
||||
* This interface provides a convenient means for decoupling user
|
||||
* interface components that interact with a place object and that need to
|
||||
* keep themselves up to date when the client moves from place to place.
|
||||
*
|
||||
* <p> In general, such components need to know when the client is about
|
||||
* to enter a place so that they can subscribe if necessary or at least
|
||||
* extract information about the place. They also need to know when a
|
||||
* client has left a place so that they can unsubscribe and clean up after
|
||||
* themselves. This is the information that the place view interface makes
|
||||
* available to them in a decoupled way.
|
||||
*
|
||||
* <p> The part of the client implementation that is responsible for the
|
||||
* main user interface can act as a location observer, and it can make use
|
||||
* of {@link PlaceViewUtil} to dispatch notification of place changes to
|
||||
* every <code>PlaceView</code> implementing user interface element in the
|
||||
* user interface hierarchy with calls to {@link
|
||||
* PlaceViewUtil#dispatchWillEnterPlace} and {@link
|
||||
* PlaceViewUtil#dispatchDidLeavePlace}. These functions traverse the UI
|
||||
* hierarchy (starting with the element provided which would generally be
|
||||
* the top-level UI element, and dispatch calls to {@link #willEnterPlace}
|
||||
* and {@link #didLeavePlace} respectively on any UI element they find
|
||||
* that implements <code>PlaceView</code>.
|
||||
*
|
||||
* <p> By doing this, the client code can simply create place-sensitive
|
||||
* user interface elements and stick them in the user interface and
|
||||
* essentially forget about them, knowing that they will all be notified
|
||||
* of place entering and exiting by virtue of the single dispatching
|
||||
* calls. It is useful to note that place-sensitive user interface
|
||||
* elements will also generally need a reference to the {@link
|
||||
* com.threerings.crowd.util.CrowdContext} derivative in use by
|
||||
* the client, but those are best supplied at construct time.
|
||||
*/
|
||||
public interface PlaceView extends IEventDispatcher
|
||||
{
|
||||
/**
|
||||
* Called when the client has entered a place and is about to display
|
||||
* the user interface for that place.
|
||||
*
|
||||
* @param plobj the place object that was just entered.
|
||||
*/
|
||||
function willEnterPlace (plobj :PlaceObject) :void;
|
||||
|
||||
/**
|
||||
* Called after the client has left a place and needs to clean up
|
||||
* after the user interface that was displaying that place.
|
||||
*
|
||||
* @param plobj the place object that was just left.
|
||||
*/
|
||||
function didLeavePlace (plobj :PlaceObject) :void;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,109 @@
|
||||
//
|
||||
// $Id$
|
||||
//
|
||||
// Narya library - tools for developing networked games
|
||||
// Copyright (C) 2002-2010 Three Rings Design, Inc., All Rights Reserved
|
||||
// http://code.google.com/p/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.crowd.client {
|
||||
|
||||
import flash.display.DisplayObject;
|
||||
import flash.display.DisplayObjectContainer;
|
||||
|
||||
import mx.core.IRawChildrenContainer; // a simple interface from flex
|
||||
|
||||
import com.threerings.util.Log;
|
||||
|
||||
import com.threerings.crowd.data.PlaceObject;
|
||||
|
||||
/**
|
||||
* Provides a mechanism for dispatching notifications to all user
|
||||
* interface elements in a hierarchy that implement the {@link PlaceView}
|
||||
* interface. Look at the documentation for {@link PlaceView} for more
|
||||
* explanation.
|
||||
*/
|
||||
public class PlaceViewUtil
|
||||
{
|
||||
/**
|
||||
* Dispatches a call to {@link PlaceView#willEnterPlace} to all UI
|
||||
* elements in the hierarchy rooted at the component provided via the
|
||||
* <code>root</code> parameter.
|
||||
*
|
||||
* @param root the component at which to start traversing the UI
|
||||
* hierarchy.
|
||||
* @param plobj the place object that is about to be entered.
|
||||
*/
|
||||
public static function dispatchWillEnterPlace (
|
||||
root :Object, plobj :PlaceObject) :void
|
||||
{
|
||||
dispatch(root, plobj, "willEnterPlace");
|
||||
}
|
||||
|
||||
/**
|
||||
* Dispatches a call to {@link PlaceView#didLeavePlace} to all UI
|
||||
* elements in the hierarchy rooted at the component provided via the
|
||||
* <code>root</code> parameter.
|
||||
*
|
||||
* @param root the component at which to start traversing the UI
|
||||
* hierarchy.
|
||||
* @param plobj the place object that is about to be entered.
|
||||
*/
|
||||
public static function dispatchDidLeavePlace (
|
||||
root :Object, plobj :PlaceObject) :void
|
||||
{
|
||||
dispatch(root, plobj, "didLeavePlace");
|
||||
}
|
||||
|
||||
private static function dispatch (
|
||||
root :Object, plobj :PlaceObject, funct :String) :void
|
||||
{
|
||||
// much of the code in here is adapted from
|
||||
// com.threerings.flash.DisplayUtil, which we cannot access because
|
||||
// it's in the nenya package. So sad, too bad.
|
||||
|
||||
if (root is PlaceView) {
|
||||
try {
|
||||
(root as PlaceView)[funct](plobj);
|
||||
} catch (e :Error) {
|
||||
var log :Log = Log.getLog(PlaceViewUtil);
|
||||
log.warning("Component choked on " + funct + "() ", "component", root,
|
||||
"plobj", plobj, e);
|
||||
}
|
||||
}
|
||||
|
||||
if (!(root is DisplayObject)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (root is DisplayObjectContainer) {
|
||||
// a little type-unsafety so that we don't have to write two blocks
|
||||
var o :Object= (root is IRawChildrenContainer) ?
|
||||
IRawChildrenContainer(root).rawChildren : root;
|
||||
var nn :int = int(o.numChildren);
|
||||
for (var ii :int = 0; ii < nn; ii++) {
|
||||
try {
|
||||
root = o.getChildAt(ii);
|
||||
} catch (err :SecurityError) {
|
||||
// don't try dispatching to children we cannot access!
|
||||
continue;
|
||||
}
|
||||
dispatch(root, plobj, funct);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,50 @@
|
||||
//
|
||||
// $Id$
|
||||
//
|
||||
// Narya library - tools for developing networked games
|
||||
// Copyright (C) 2002-2010 Three Rings Design, Inc., All Rights Reserved
|
||||
// http://code.google.com/p/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.crowd.data {
|
||||
|
||||
import com.threerings.crowd.client.BodyService;
|
||||
import com.threerings.presents.client.Client;
|
||||
import com.threerings.presents.data.InvocationMarshaller;
|
||||
import com.threerings.util.langBoolean;
|
||||
|
||||
/**
|
||||
* Provides the implementation of the <code>BodyService</code> interface
|
||||
* that marshalls the arguments and delivers the request to the provider
|
||||
* on the server. Also provides an implementation of the response listener
|
||||
* interfaces that marshall the response arguments and deliver them back
|
||||
* to the requesting client.
|
||||
*/
|
||||
public class BodyMarshaller extends InvocationMarshaller
|
||||
implements BodyService
|
||||
{
|
||||
/** The method id used to dispatch <code>setIdle</code> requests. */
|
||||
public static const SET_IDLE :int = 1;
|
||||
|
||||
// from interface BodyService
|
||||
public function setIdle (arg1 :Boolean) :void
|
||||
{
|
||||
sendRequest(SET_IDLE, [
|
||||
langBoolean.valueOf(arg1)
|
||||
]);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,197 @@
|
||||
//
|
||||
// $Id$
|
||||
//
|
||||
// Narya library - tools for developing networked games
|
||||
// Copyright (C) 2002-2010 Three Rings Design, Inc., All Rights Reserved
|
||||
// http://code.google.com/p/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.crowd.data {
|
||||
|
||||
import com.threerings.util.Byte;
|
||||
import com.threerings.util.Name;
|
||||
|
||||
import com.threerings.presents.data.ClientObject;
|
||||
import com.threerings.presents.data.InvocationCodes;
|
||||
|
||||
import com.threerings.crowd.chat.data.ChatCodes;
|
||||
|
||||
import com.threerings.io.ObjectInputStream;
|
||||
import com.threerings.io.ObjectOutputStream;
|
||||
|
||||
/**
|
||||
* The basic user object class for Crowd users. Bodies have a location and a status.
|
||||
*/
|
||||
public class BodyObject extends ClientObject
|
||||
{
|
||||
// AUTO-GENERATED: FIELDS START
|
||||
/** The field name of the <code>location</code> field. */
|
||||
public static const LOCATION :String = "location";
|
||||
|
||||
/** The field name of the <code>status</code> field. */
|
||||
public static const STATUS :String = "status";
|
||||
|
||||
/** The field name of the <code>awayMessage</code> field. */
|
||||
public static const AWAY_MESSAGE :String = "awayMessage";
|
||||
// AUTO-GENERATED: FIELDS END
|
||||
|
||||
/**
|
||||
* The oid of the place currently occupied by this body or -1 if they currently occupy no
|
||||
* place.
|
||||
*/
|
||||
public var location :Place;
|
||||
|
||||
/**
|
||||
* The user's current status ({@link OccupantInfo#ACTIVE}, etc.).
|
||||
*/
|
||||
public var status :int;
|
||||
|
||||
/**
|
||||
* If non-null, this contains a message to be auto-replied whenever another user delivers a
|
||||
* tell message to this user.
|
||||
*/
|
||||
public var awayMessage :String;
|
||||
|
||||
/**
|
||||
* Returns this user's access control tokens.
|
||||
*/
|
||||
public function getTokens () :TokenRing
|
||||
{
|
||||
return new TokenRing();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the name that should be displayed to other users. The default is to use
|
||||
* <code>username</code>.
|
||||
* @see com.threerings.presents.data.ClientObject#username
|
||||
*/
|
||||
public function getVisibleName () :Name
|
||||
{
|
||||
return username;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the oid of the place occupied by this body or -1 if we occupy no place.
|
||||
*/
|
||||
public function getPlaceOid () :int
|
||||
{
|
||||
return (location == null) ? -1 : location.placeOid;
|
||||
}
|
||||
|
||||
// // AUTO-GENERATED: METHODS START
|
||||
// /**
|
||||
// * Requests that the <code>username</code> field be set to the
|
||||
// * specified value. The local value will be updated immediately and an
|
||||
// * event will be propagated through the system to notify all listeners
|
||||
// * that the attribute did change. Proxied copies of this object (on
|
||||
// * clients) will apply the value change when they received the
|
||||
// * attribute changed notification.
|
||||
// */
|
||||
// public function setUsername (value :Name) :void
|
||||
// {
|
||||
// var ovalue :Name = this.username;
|
||||
// requestAttributeChange(
|
||||
// USERNAME, value, ovalue);
|
||||
// this.username = value;
|
||||
// }
|
||||
//
|
||||
// /**
|
||||
// * Requests that the <code>location</code> field be set to the
|
||||
// * specified value. The local value will be updated immediately and an
|
||||
// * event will be propagated through the system to notify all listeners
|
||||
// * that the attribute did change. Proxied copies of this object (on
|
||||
// * clients) will apply the value change when they received the
|
||||
// * attribute changed notification.
|
||||
// */
|
||||
// public function setLocation (value :int) :void
|
||||
// {
|
||||
// var ovalue :int = this.location;
|
||||
// requestAttributeChange(
|
||||
// LOCATION, value, ovalue);
|
||||
// this.location = value;
|
||||
// }
|
||||
//
|
||||
// /**
|
||||
// * Requests that the <code>status</code> field be set to the
|
||||
// * specified value. The local value will be updated immediately and an
|
||||
// * event will be propagated through the system to notify all listeners
|
||||
// * that the attribute did change. Proxied copies of this object (on
|
||||
// * clients) will apply the value change when they received the
|
||||
// * attribute changed notification.
|
||||
// */
|
||||
// public function setStatus (value :int) :void
|
||||
// {
|
||||
// var ovalue :int = this.status;
|
||||
// requestAttributeChange(
|
||||
// STATUS, Byte.valueOf(value), Byte.valueOf(ovalue));
|
||||
// this.status = value;
|
||||
// }
|
||||
//
|
||||
// /**
|
||||
// * Requests that the <code>awayMessage</code> field be set to the
|
||||
// * specified value. The local value will be updated immediately and an
|
||||
// * event will be propagated through the system to notify all listeners
|
||||
// * that the attribute did change. Proxied copies of this object (on
|
||||
// * clients) will apply the value change when they received the
|
||||
// * attribute changed notification.
|
||||
// */
|
||||
// public function setAwayMessage (value :String) :void
|
||||
// {
|
||||
// var ovalue :String = this.awayMessage;
|
||||
// requestAttributeChange(
|
||||
// AWAY_MESSAGE, value, ovalue);
|
||||
// this.awayMessage = value;
|
||||
// }
|
||||
// // AUTO-GENERATED: METHODS END
|
||||
//
|
||||
// override public function writeObject (out :ObjectOutputStream) :void
|
||||
// {
|
||||
// super.writeObject(out);
|
||||
//
|
||||
// out.writeObject(username);
|
||||
// out.writeInt(location);
|
||||
// out.writeByte(status);
|
||||
// out.writeField(awayMessage);
|
||||
// }
|
||||
|
||||
override public function who () :String
|
||||
{
|
||||
var who :String = username.toString() + " (" + getOid();
|
||||
if (status != OccupantInfo.ACTIVE) {
|
||||
who += (" " + getStatusTranslation());
|
||||
}
|
||||
who += ")";
|
||||
return who;
|
||||
}
|
||||
|
||||
override public function readObject (ins :ObjectInputStream) :void
|
||||
{
|
||||
super.readObject(ins);
|
||||
location = Place(ins.readObject());
|
||||
status = ins.readByte();
|
||||
awayMessage = (ins.readField(String) as String);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a translation suffix for this occupant's status.
|
||||
* Can be overridden to translate nonstandard statuses.
|
||||
*/
|
||||
protected function getStatusTranslation () :String
|
||||
{
|
||||
return OccupantInfo.X_STATUS[status];
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
//
|
||||
// $Id$
|
||||
//
|
||||
// Narya library - tools for developing networked games
|
||||
// Copyright (C) 2002-2010 Three Rings Design, Inc., All Rights Reserved
|
||||
// http://code.google.com/p/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.crowd.data {
|
||||
|
||||
import com.threerings.presents.data.InvocationCodes;
|
||||
|
||||
/**
|
||||
* Defines codes and constants global to the Crowd services.
|
||||
*/
|
||||
public class CrowdCodes extends InvocationCodes
|
||||
{
|
||||
/** Defines our invocation services group. */
|
||||
public static const CROWD_GROUP :String = "crowd";
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,54 @@
|
||||
//
|
||||
// $Id$
|
||||
//
|
||||
// Narya library - tools for developing networked games
|
||||
// Copyright (C) 2002-2010 Three Rings Design, Inc., All Rights Reserved
|
||||
// http://code.google.com/p/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.crowd.data {
|
||||
|
||||
import com.threerings.presents.data.ClientObject;
|
||||
import com.threerings.presents.data.InvocationCodes;
|
||||
import com.threerings.presents.data.Permission;
|
||||
import com.threerings.presents.data.PermissionPolicy;
|
||||
|
||||
import com.threerings.crowd.chat.data.ChatCodes;
|
||||
|
||||
/**
|
||||
* Implements some Crowd permissions.
|
||||
*/
|
||||
public class CrowdPermissionPolicy extends PermissionPolicy
|
||||
{
|
||||
// from PermissionPolicy
|
||||
override public function checkAccess (
|
||||
clobj :ClientObject, perm :Permission, context :Object) :String
|
||||
{
|
||||
if (!(clobj is BodyObject)) {
|
||||
return super.checkAccess(clobj, perm, context);
|
||||
}
|
||||
|
||||
var body :BodyObject = (clobj as BodyObject);
|
||||
if (perm == ChatCodes.BROADCAST_ACCESS) {
|
||||
return body.getTokens().isAdmin() ? null : InvocationCodes.ACCESS_DENIED;
|
||||
} else if (perm == ChatCodes.CHAT_ACCESS) {
|
||||
return null;
|
||||
} else {
|
||||
return super.checkAccess(clobj, perm, context);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,44 @@
|
||||
//
|
||||
// $Id$
|
||||
//
|
||||
// Narya library - tools for developing networked games
|
||||
// Copyright (C) 2002-2010 Three Rings Design, Inc., All Rights Reserved
|
||||
// http://code.google.com/p/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.crowd.data {
|
||||
|
||||
import com.threerings.presents.data.InvocationCodes;
|
||||
|
||||
/**
|
||||
* Contains codes used by the location invocation services.
|
||||
*/
|
||||
public class LocationCodes extends InvocationCodes
|
||||
{
|
||||
/** An error code indicating that a place identified by a particular
|
||||
* place id does not exist. Usually generated by a failed moveTo
|
||||
* request. */
|
||||
public static const NO_SUCH_PLACE :String = "m.no_such_place";
|
||||
|
||||
/** An error code sent when a user requests to move to a new place but
|
||||
* they are in the middle of moving somewhere already. */
|
||||
public static const MOVE_IN_PROGRESS :String = "m.move_in_progress";
|
||||
|
||||
/** An error code sent when a user requests to move to a place, but
|
||||
* they are already in the requested place. */
|
||||
public static const ALREADY_THERE :String = "m.already_there";
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,64 @@
|
||||
//
|
||||
// $Id$
|
||||
//
|
||||
// Narya library - tools for developing networked games
|
||||
// Copyright (C) 2002-2010 Three Rings Design, Inc., All Rights Reserved
|
||||
// http://code.google.com/p/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.crowd.data {
|
||||
|
||||
import com.threerings.crowd.client.LocationService;
|
||||
import com.threerings.crowd.client.LocationService_MoveListener;
|
||||
import com.threerings.presents.client.Client;
|
||||
import com.threerings.presents.data.InvocationMarshaller;
|
||||
import com.threerings.util.Integer;
|
||||
|
||||
/**
|
||||
* Provides the implementation of the <code>LocationService</code> interface
|
||||
* that marshalls the arguments and delivers the request to the provider
|
||||
* on the server. Also provides an implementation of the response listener
|
||||
* interfaces that marshall the response arguments and deliver them back
|
||||
* to the requesting client.
|
||||
*/
|
||||
public class LocationMarshaller extends InvocationMarshaller
|
||||
implements LocationService
|
||||
{
|
||||
/** The method id used to dispatch <code>leavePlace</code> requests. */
|
||||
public static const LEAVE_PLACE :int = 1;
|
||||
|
||||
// from interface LocationService
|
||||
public function leavePlace () :void
|
||||
{
|
||||
sendRequest(LEAVE_PLACE, [
|
||||
|
||||
]);
|
||||
}
|
||||
|
||||
/** The method id used to dispatch <code>moveTo</code> requests. */
|
||||
public static const MOVE_TO :int = 2;
|
||||
|
||||
// from interface LocationService
|
||||
public function moveTo (arg1 :int, arg2 :LocationService_MoveListener) :void
|
||||
{
|
||||
var listener2 :LocationMarshaller_MoveMarshaller = new LocationMarshaller_MoveMarshaller();
|
||||
listener2.listener = arg2;
|
||||
sendRequest(MOVE_TO, [
|
||||
Integer.valueOf(arg1), listener2
|
||||
]);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,51 @@
|
||||
//
|
||||
// $Id$
|
||||
//
|
||||
// Narya library - tools for developing networked games
|
||||
// Copyright (C) 2002-2010 Three Rings Design, Inc., All Rights Reserved
|
||||
// http://code.google.com/p/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.crowd.data {
|
||||
|
||||
import com.threerings.crowd.client.LocationService_MoveListener;
|
||||
import com.threerings.presents.data.InvocationMarshaller_ListenerMarshaller;
|
||||
|
||||
/**
|
||||
* Marshalls instances of the LocationService_MoveMarshaller interface.
|
||||
*/
|
||||
public class LocationMarshaller_MoveMarshaller
|
||||
extends InvocationMarshaller_ListenerMarshaller
|
||||
{
|
||||
/** The method id used to dispatch <code>moveSucceeded</code> responses. */
|
||||
public static const MOVE_SUCCEEDED :int = 1;
|
||||
|
||||
// from InvocationMarshaller_ListenerMarshaller
|
||||
override public function dispatchResponse (methodId :int, args :Array) :void
|
||||
{
|
||||
switch (methodId) {
|
||||
case MOVE_SUCCEEDED:
|
||||
(listener as LocationService_MoveListener).moveSucceeded(
|
||||
(args[0] as PlaceConfig));
|
||||
return;
|
||||
|
||||
default:
|
||||
super.dispatchResponse(methodId, args);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,44 @@
|
||||
//
|
||||
// $Id$
|
||||
//
|
||||
// Narya library - tools for developing networked games
|
||||
// Copyright (C) 2002-2010 Three Rings Design, Inc., All Rights Reserved
|
||||
// http://code.google.com/p/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.crowd.data {
|
||||
|
||||
import com.threerings.presents.dobj.ServerMessageEvent;
|
||||
|
||||
public class ManagerCaller
|
||||
{
|
||||
public function ManagerCaller (plobj :PlaceObject)
|
||||
{
|
||||
_plobj = plobj;
|
||||
}
|
||||
|
||||
/**
|
||||
* Called to call a method on the manager.
|
||||
*/
|
||||
public function invoke (method :String, ... args) :void
|
||||
{
|
||||
_plobj.postEvent(new ServerMessageEvent(_plobj.getOid(), method, args));
|
||||
}
|
||||
|
||||
/** The place object we're thingy-ing for. */
|
||||
protected var _plobj :PlaceObject;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,134 @@
|
||||
//
|
||||
// $Id$
|
||||
//
|
||||
// Narya library - tools for developing networked games
|
||||
// Copyright (C) 2002-2010 Three Rings Design, Inc., All Rights Reserved
|
||||
// http://code.google.com/p/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.crowd.data {
|
||||
|
||||
import flash.system.ApplicationDomain;
|
||||
|
||||
import com.threerings.util.ClassUtil;
|
||||
import com.threerings.util.Cloneable;
|
||||
import com.threerings.util.Integer;
|
||||
import com.threerings.util.Name;
|
||||
|
||||
import com.threerings.io.ObjectInputStream;
|
||||
import com.threerings.io.ObjectOutputStream;
|
||||
import com.threerings.io.SimpleStreamableObject;
|
||||
|
||||
import com.threerings.presents.dobj.DSet_Entry;
|
||||
|
||||
import com.threerings.crowd.data.BodyObject;
|
||||
|
||||
/**
|
||||
* The occupant info object contains all of the information about an
|
||||
* occupant of a place that should be shared with other occupants of the
|
||||
* place. These objects are stored in the place object itself and are
|
||||
* updated when bodies enter and exit a place.
|
||||
*
|
||||
* <p> A system that builds upon the Crowd framework can extend this class to
|
||||
* include extra information about their occupants. They will need to provide a
|
||||
* derived {@link BodyObject} that creates and configures their occupant info
|
||||
* in {@link BodyObject#createOccupantInfo}.
|
||||
*
|
||||
* <p> Note also that this class implements {@link Cloneable} which means
|
||||
* that if derived classes add non-primitive attributes, they are
|
||||
* responsible for adding the code to clone those attributes when a clone
|
||||
* is requested.
|
||||
*/
|
||||
public class OccupantInfo extends SimpleStreamableObject
|
||||
implements DSet_Entry, Cloneable
|
||||
{
|
||||
/** Constant value for {@link #status}. */
|
||||
public static const ACTIVE :int = 0;
|
||||
|
||||
/** Constant value for {@link #status}. */
|
||||
public static const IDLE :int = 1;
|
||||
|
||||
/** Constant value for {@link #status}. */
|
||||
public static const DISCONNECTED :int = 2;
|
||||
|
||||
/** Maps status codes to human readable strings. */
|
||||
public static const X_STATUS :Array = [ "active", "idle", "discon" ];
|
||||
|
||||
/** The body object id of this occupant (and our entry key). */
|
||||
public var bodyOid :int;
|
||||
|
||||
/** The username of this occupant. */
|
||||
public var username :Name;
|
||||
|
||||
/** The status of this occupant. */
|
||||
public var status :int = ACTIVE;
|
||||
|
||||
/**
|
||||
* Constructs an occupant info record, optionally obtaining data from the
|
||||
* supplied BodyObject.
|
||||
*/
|
||||
public function OccupantInfo (body :BodyObject = null)
|
||||
{
|
||||
if (body != null) {
|
||||
bodyOid = body.getOid();
|
||||
username = body.getVisibleName();
|
||||
status = body.status;
|
||||
}
|
||||
}
|
||||
|
||||
/** Access to the body object id as an int. */
|
||||
public function getBodyOid () :int
|
||||
{
|
||||
return bodyOid;
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates a cloned copy of this instance.
|
||||
*/
|
||||
public function clone () :Object
|
||||
{
|
||||
var that :OccupantInfo = ClassUtil.newInstance(this) as OccupantInfo;
|
||||
that.bodyOid = this.bodyOid;
|
||||
that.username = this.username;
|
||||
that.status = this.status;
|
||||
return that;
|
||||
}
|
||||
|
||||
// documentation inherited from interface DSet_Entry
|
||||
public function getKey () :Object
|
||||
{
|
||||
return bodyOid;
|
||||
}
|
||||
|
||||
// from interface Streamable
|
||||
override public function readObject (ins :ObjectInputStream) :void
|
||||
{
|
||||
super.readObject(ins);
|
||||
bodyOid = (ins.readField(Integer) as Integer).value;
|
||||
username = Name(ins.readObject());
|
||||
status = ins.readByte();
|
||||
}
|
||||
|
||||
// from interface Streamable
|
||||
override public function writeObject (out :ObjectOutputStream) :void
|
||||
{
|
||||
super.writeObject(out);
|
||||
out.writeObject(new Integer(bodyOid));
|
||||
out.writeObject(username);
|
||||
out.writeByte(status);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,72 @@
|
||||
//
|
||||
// $Id$
|
||||
//
|
||||
// Narya library - tools for developing networked games
|
||||
// Copyright (C) 2002-2010 Three Rings Design, Inc., All Rights Reserved
|
||||
// http://code.google.com/p/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.crowd.data {
|
||||
|
||||
import com.threerings.io.ObjectInputStream;
|
||||
import com.threerings.io.ObjectOutputStream;
|
||||
import com.threerings.io.SimpleStreamableObject;
|
||||
import com.threerings.util.Hashable;
|
||||
|
||||
/**
|
||||
* Contains information on the current place occupied by a body.
|
||||
*/
|
||||
public class Place extends SimpleStreamableObject
|
||||
implements Hashable
|
||||
{
|
||||
/** The oid of this place's {@link PlaceObject}. */
|
||||
public var placeOid :int;
|
||||
|
||||
/**
|
||||
* Creates a place with the supplied oid.
|
||||
*/
|
||||
public function Place (placeOid :int = 0)
|
||||
{
|
||||
this.placeOid = placeOid;
|
||||
}
|
||||
|
||||
// from Object
|
||||
public function hashCode () :int
|
||||
{
|
||||
return placeOid;
|
||||
}
|
||||
|
||||
// from Object
|
||||
public function equals (other :Object) :Boolean
|
||||
{
|
||||
return (other is Place) && ((other as Place).placeOid == placeOid);
|
||||
}
|
||||
|
||||
// from interface Streamable
|
||||
override public function readObject (ins :ObjectInputStream) :void
|
||||
{
|
||||
super.readObject(ins);
|
||||
placeOid = ins.readInt();
|
||||
}
|
||||
|
||||
// from interface Streamable
|
||||
override public function writeObject (out :ObjectOutputStream) :void
|
||||
{
|
||||
super.writeObject(out);
|
||||
out.writeInt(placeOid);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,84 @@
|
||||
//
|
||||
// $Id$
|
||||
//
|
||||
// Narya library - tools for developing networked games
|
||||
// Copyright (C) 2002-2010 Three Rings Design, Inc., All Rights Reserved
|
||||
// http://code.google.com/p/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.crowd.data {
|
||||
|
||||
import com.threerings.io.ObjectInputStream;
|
||||
import com.threerings.io.ObjectOutputStream;
|
||||
import com.threerings.io.SimpleStreamableObject;
|
||||
|
||||
import com.threerings.crowd.client.PlaceController;
|
||||
|
||||
/**
|
||||
* The place config class encapsulates the configuration information for a
|
||||
* particular type of place. The hierarchy of place config objects mimics
|
||||
* the hierarchy of place managers and controllers. Both the place manager
|
||||
* and place controller are provided with the place config object when the
|
||||
* place is created.
|
||||
*
|
||||
* <p> The place config object is also the mechanism used to instantiate
|
||||
* the appropriate place manager and controller. Every place must have an
|
||||
* associated place config derived class that overrides {@link
|
||||
* #getControllerClass} and {@link #getManagerClassName}, returning the
|
||||
* appropriate place controller and manager class for that place.
|
||||
*/
|
||||
public /*abstract*/ class PlaceConfig extends SimpleStreamableObject
|
||||
{
|
||||
public function PlaceConfig ()
|
||||
{
|
||||
// nothing needed
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the class that should be used to create a controller for this
|
||||
* place. The controller class must derive from {@link PlaceController}.
|
||||
*
|
||||
* @deprecated Override {@link #createController} directly.
|
||||
*/
|
||||
public function getControllerClass () :Class
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create the controller that should be used for this place.
|
||||
*/
|
||||
public function createController () :PlaceController
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the name of the class that should be used to create a
|
||||
* manager for this place. The manager class must derive from {@link
|
||||
* com.threerings.crowd.server.PlaceManager}. <em>Note:</em> this
|
||||
* method differs from {@link #getControllerClass} because we want to
|
||||
* avoid compile time linkage of the place config object (which is
|
||||
* used on the client) to server code. This allows a code optimizer
|
||||
* (DashO Pro, for example) to remove the server code from the client,
|
||||
* knowing that it is never used.
|
||||
*/
|
||||
public function getManagerClassName () :String
|
||||
{
|
||||
return null; // not used
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,213 @@
|
||||
//
|
||||
// $Id$
|
||||
//
|
||||
// Narya library - tools for developing networked games
|
||||
// Copyright (C) 2002-2010 Three Rings Design, Inc., All Rights Reserved
|
||||
// http://code.google.com/p/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.crowd.data {
|
||||
|
||||
import com.threerings.util.Iterator;
|
||||
import com.threerings.util.Name;
|
||||
|
||||
import com.threerings.io.ObjectInputStream;
|
||||
import com.threerings.io.ObjectOutputStream;
|
||||
|
||||
import com.threerings.presents.dobj.DObject;
|
||||
import com.threerings.presents.dobj.DSet;
|
||||
import com.threerings.presents.dobj.OidList;
|
||||
|
||||
import com.threerings.crowd.chat.data.SpeakMarshaller;
|
||||
//import com.threerings.crowd.chat.data.SpeakObject;
|
||||
|
||||
/**
|
||||
* A distributed object that contains information on a place that is
|
||||
* occupied by bodies. This place might be a chat room, a game room, an
|
||||
* island in a massively multiplayer piratical universe, anything that has
|
||||
* occupants that might want to chat with one another.
|
||||
*/
|
||||
public class PlaceObject extends DObject
|
||||
{
|
||||
// AUTO-GENERATED: FIELDS START
|
||||
/** The field name of the <code>occupants</code> field. */
|
||||
public static const OCCUPANTS :String = "occupants";
|
||||
|
||||
/** The field name of the <code>occupantInfo</code> field. */
|
||||
public static const OCCUPANT_INFO :String = "occupantInfo";
|
||||
|
||||
/** The field name of the <code>speakService</code> field. */
|
||||
public static const SPEAK_SERVICE :String = "speakService";
|
||||
// AUTO-GENERATED: FIELDS END
|
||||
|
||||
/**
|
||||
* Allows the client to call methods on the manager.
|
||||
*/
|
||||
public var manager :ManagerCaller;
|
||||
|
||||
/**
|
||||
* Tracks the oid of the body objects of all of the occupants of this
|
||||
* place.
|
||||
*/
|
||||
public var occupants :OidList = new OidList();
|
||||
|
||||
/**
|
||||
* Contains an info record (of type {@link OccupantInfo}) for each
|
||||
* occupant that contains information about that occupant that needs
|
||||
* to be known by everyone in the place. <em>Note:</em> Don't obtain
|
||||
* occupant info records directly from this set when on the server,
|
||||
* use <code>PlaceManager.getOccupantInfo()</code> instead (along with
|
||||
* <code>PlaceManager.updateOccupantInfo()</code>) because it does
|
||||
* some special processing to ensure that readers and updaters don't
|
||||
* step on one another even if they make rapid fire changes to a
|
||||
* user's occupant info.
|
||||
*/
|
||||
public var occupantInfo :DSet = new DSet();
|
||||
|
||||
/** Used to generate speak requests on this place object. */
|
||||
public var speakService :SpeakMarshaller;
|
||||
|
||||
/**
|
||||
* We need a constructor here in actionscript to set up the
|
||||
* ManagerCaller.
|
||||
*/
|
||||
public function PlaceObject ()
|
||||
{
|
||||
super();
|
||||
manager = new ManagerCaller(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Looks up a user's occupant info by name.
|
||||
*
|
||||
* @return the occupant info record for the named user or null if no
|
||||
* user in the room has that username.
|
||||
*/
|
||||
public function getOccupantInfo (username :Name) :OccupantInfo
|
||||
{
|
||||
var itr :Iterator = occupantInfo.iterator();
|
||||
while (itr.hasNext()) {
|
||||
var info :OccupantInfo = (itr.next() as OccupantInfo);
|
||||
if (info.username.equals(username)) {
|
||||
return info;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
// // AUTO-GENERATED: METHODS START
|
||||
// /**
|
||||
// * Requests that <code>oid</code> be added to the <code>occupants</code>
|
||||
// * oid list. The list will not change until the event is actually
|
||||
// * propagated through the system.
|
||||
// */
|
||||
// public function addToOccupants (oid :int) :void
|
||||
// {
|
||||
// requestOidAdd(OCCUPANTS, oid);
|
||||
// }
|
||||
//
|
||||
// /**
|
||||
// * Requests that <code>oid</code> be removed from the
|
||||
// * <code>occupants</code> oid list. The list will not change until the
|
||||
// * event is actually propagated through the system.
|
||||
// */
|
||||
// public function removeFromOccupants (oid :int) :void
|
||||
// {
|
||||
// requestOidRemove(OCCUPANTS, oid);
|
||||
// }
|
||||
//
|
||||
// /**
|
||||
// * Requests that the specified entry be added to the
|
||||
// * <code>occupantInfo</code> set. The set will not change until the event is
|
||||
// * actually propagated through the system.
|
||||
// */
|
||||
// public function addToOccupantInfo (elem :DSet_Entry) :void
|
||||
// {
|
||||
// requestEntryAdd(OCCUPANT_INFO, elem);
|
||||
// }
|
||||
//
|
||||
// /**
|
||||
// * Requests that the entry matching the supplied key be removed from
|
||||
// * the <code>occupantInfo</code> set. The set will not change until the
|
||||
// * event is actually propagated through the system.
|
||||
// */
|
||||
// public function removeFromOccupantInfo (key :Object) :void
|
||||
// {
|
||||
// requestEntryRemove(OCCUPANT_INFO, key);
|
||||
// }
|
||||
//
|
||||
// /**
|
||||
// * Requests that the specified entry be updated in the
|
||||
// * <code>occupantInfo</code> set. The set will not change until the event is
|
||||
// * actually propagated through the system.
|
||||
// */
|
||||
// public function updateOccupantInfo (elem :DSet_Entry) :void
|
||||
// {
|
||||
// requestEntryUpdate(OCCUPANT_INFO, elem);
|
||||
// }
|
||||
//
|
||||
// /**
|
||||
// * Requests that the <code>occupantInfo</code> field be set to the
|
||||
// * specified value. Generally one only adds, updates and removes
|
||||
// * entries of a distributed set, but certain situations call for a
|
||||
// * complete replacement of the set value. The local value will be
|
||||
// * updated immediately and an event will be propagated through the
|
||||
// * system to notify all listeners that the attribute did
|
||||
// * change. Proxied copies of this object (on clients) will apply the
|
||||
// * value change when they received the attribute changed notification.
|
||||
// */
|
||||
// public function setOccupantInfo (value :DSet) :void
|
||||
// {
|
||||
// requestAttributeChange(OCCUPANT_INFO, value, this.occupantInfo);
|
||||
// this.occupantInfo = (value == null) ? null : value;
|
||||
// }
|
||||
//
|
||||
// /**
|
||||
// * Requests that the <code>speakService</code> field be set to the
|
||||
// * specified value. The local value will be updated immediately and an
|
||||
// * event will be propagated through the system to notify all listeners
|
||||
// * that the attribute did change. Proxied copies of this object (on
|
||||
// * clients) will apply the value change when they received the
|
||||
// * attribute changed notification.
|
||||
// */
|
||||
// public function setSpeakService (value :SpeakMarshaller) :void
|
||||
// {
|
||||
// var ovalue :SpeakMarshaller = this.speakService;
|
||||
// requestAttributeChange(
|
||||
// SPEAK_SERVICE, value, ovalue);
|
||||
// this.speakService = value;
|
||||
// }
|
||||
// // AUTO-GENERATED: METHODS END
|
||||
//
|
||||
// // documentation inherited
|
||||
// override public function writeObject (out :ObjectOutputStream) :void
|
||||
// {
|
||||
// super.writeObject(out);
|
||||
// out.writeObject(occupants);
|
||||
// out.writeObject(occupantInfo);
|
||||
// out.writeObject(speakService);
|
||||
// }
|
||||
|
||||
// documentation inherited
|
||||
override public function readObject (ins :ObjectInputStream) :void
|
||||
{
|
||||
super.readObject(ins);
|
||||
occupants = OidList(ins.readObject());
|
||||
occupantInfo = DSet(ins.readObject());
|
||||
speakService = SpeakMarshaller(ins.readObject());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,120 @@
|
||||
//
|
||||
// $Id$
|
||||
//
|
||||
// Narya library - tools for developing networked games
|
||||
// Copyright (C) 2002-2010 Three Rings Design, Inc., All Rights Reserved
|
||||
// http://code.google.com/p/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.crowd.data {
|
||||
|
||||
import com.threerings.io.ObjectInputStream;
|
||||
import com.threerings.io.ObjectOutputStream;
|
||||
import com.threerings.io.SimpleStreamableObject;
|
||||
|
||||
/**
|
||||
* Defines access control tokens that convey certain privileges to users
|
||||
* (see {@link BodyObject#checkAccess}).
|
||||
*/
|
||||
public class TokenRing extends SimpleStreamableObject
|
||||
{
|
||||
/** Indicates that this user is an administrator and can do things like broadcast, shutdown the
|
||||
* server and whatnot. */
|
||||
public static const ADMIN :int = (1 << 0);
|
||||
|
||||
/**
|
||||
* Constructs a token ring with the supplied set of tokens.
|
||||
*/
|
||||
public function TokenRing (tokens :int = 0)
|
||||
{
|
||||
_tokens = tokens;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds the specified token to this ring.
|
||||
*/
|
||||
public function setToken (token :int, setOn :Boolean = true) :void
|
||||
{
|
||||
if (setOn) {
|
||||
_tokens |= token;
|
||||
|
||||
} else {
|
||||
clearToken(token);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the bitmask that stores the various tokens.
|
||||
*/
|
||||
public function getTokens () :int
|
||||
{
|
||||
return _tokens;
|
||||
}
|
||||
|
||||
/**
|
||||
* Convenience function for checking whether this ring holds the
|
||||
* {@link #ADMIN} token.
|
||||
*/
|
||||
public function isAdmin () :Boolean
|
||||
{
|
||||
return holdsToken(ADMIN);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if this token ring contains the specified token or tokens,
|
||||
* exactly.
|
||||
* For example, if you pass in the OR of two or more tokens,
|
||||
* then the ring must contain all of those tokens.
|
||||
*/
|
||||
public function holdsToken (token :int) :Boolean
|
||||
{
|
||||
return (_tokens & token) == token;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if this token ring contains any one of the specified tokens.
|
||||
*/
|
||||
public function holdsAnyToken (tokens :int) :Boolean
|
||||
{
|
||||
return (_tokens & tokens) != 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Clears the specified token from this ring.
|
||||
*/
|
||||
public function clearToken (token :int) :void
|
||||
{
|
||||
_tokens &= ~token;
|
||||
}
|
||||
|
||||
// from interface Streamable
|
||||
override public function readObject (ins :ObjectInputStream) :void
|
||||
{
|
||||
super.readObject(ins);
|
||||
_tokens = ins.readInt();
|
||||
}
|
||||
|
||||
// from interface Streamable
|
||||
override public function writeObject (out :ObjectOutputStream) :void
|
||||
{
|
||||
super.writeObject(out);
|
||||
out.writeInt(_tokens);
|
||||
}
|
||||
|
||||
/** The tokens contained in this ring (composed together bitwise). */
|
||||
protected var _tokens :int;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,64 @@
|
||||
//
|
||||
// $Id$
|
||||
//
|
||||
// Narya library - tools for developing networked games
|
||||
// Copyright (C) 2002-2010 Three Rings Design, Inc., All Rights Reserved
|
||||
// http://code.google.com/p/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.crowd.peer.data {
|
||||
|
||||
import com.threerings.util.Name;
|
||||
|
||||
import com.threerings.io.ObjectInputStream;
|
||||
import com.threerings.io.ObjectOutputStream;
|
||||
|
||||
import com.threerings.presents.peer.data.ClientInfo;
|
||||
|
||||
/**
|
||||
* Extends the standard {@link ClientInfo} with Crowd bits.
|
||||
*/
|
||||
public class CrowdClientInfo extends ClientInfo
|
||||
{
|
||||
/** The client's visible name, which is used for chatting. */
|
||||
public var visibleName :Name;
|
||||
|
||||
public function CrowdClientInfo ()
|
||||
{
|
||||
// nothing needed
|
||||
}
|
||||
|
||||
// documentation inherited
|
||||
override public function getKey () :Object
|
||||
{
|
||||
return visibleName;
|
||||
}
|
||||
|
||||
// from interface Streamable
|
||||
override public function readObject (ins :ObjectInputStream) :void
|
||||
{
|
||||
super.readObject(ins);
|
||||
visibleName = Name(ins.readObject());
|
||||
}
|
||||
|
||||
// from interface Streamable
|
||||
override public function writeObject (out :ObjectOutputStream) :void
|
||||
{
|
||||
super.writeObject(out);
|
||||
out.writeObject(visibleName);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,76 @@
|
||||
//
|
||||
// $Id$
|
||||
//
|
||||
// Narya library - tools for developing networked games
|
||||
// Copyright (C) 2002-2010 Three Rings Design, Inc., All Rights Reserved
|
||||
// http://code.google.com/p/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.crowd.util {
|
||||
|
||||
import com.threerings.presents.util.PresentsContext;
|
||||
import com.threerings.crowd.client.LocationDirector;
|
||||
import com.threerings.crowd.client.OccupantDirector;
|
||||
import com.threerings.crowd.client.PlaceView;
|
||||
|
||||
import com.threerings.crowd.chat.client.ChatDirector;
|
||||
|
||||
/**
|
||||
* The crowd context provides access to the various managers, etc. that
|
||||
* are needed by the crowd client code.
|
||||
*/
|
||||
public interface CrowdContext extends PresentsContext
|
||||
{
|
||||
/**
|
||||
* Returns a reference to the location director.
|
||||
*/
|
||||
function getLocationDirector () :LocationDirector;
|
||||
|
||||
/**
|
||||
* Returns a reference to the occupant director.
|
||||
*/
|
||||
function getOccupantDirector () :OccupantDirector;
|
||||
|
||||
/**
|
||||
* Provides access to the chat director.
|
||||
*/
|
||||
function getChatDirector () :ChatDirector;
|
||||
|
||||
/**
|
||||
* When the client enters a new place, the location director creates a
|
||||
* place controller which then creates a place view to visualize the
|
||||
* place for the user. The place view created by the place controller
|
||||
* will be passed to this function to actually display it in whatever
|
||||
* user interface is provided for the user. We don't require any
|
||||
* particular user interface toolkit, so it is expected that the place
|
||||
* view implementation will coordinate with the client implementation
|
||||
* so that the client can display the view provided by the place
|
||||
* controller.
|
||||
*
|
||||
* <p> Though the place view is created before we enter the place, it
|
||||
* won't be displayed (via a call to this function) until we have
|
||||
* fully entered the place and are ready for user interaction.
|
||||
*/
|
||||
function setPlaceView (view :PlaceView) :void;
|
||||
|
||||
/**
|
||||
* When the client leaves a place, the place controller will remove
|
||||
* any place view it set previously via {@link #setPlaceView} with a
|
||||
* call to this method.
|
||||
*/
|
||||
function clearPlaceView (view :PlaceView) :void;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,73 @@
|
||||
//
|
||||
// $Id$
|
||||
//
|
||||
// Narya library - tools for developing networked games
|
||||
// Copyright (C) 2002-2010 Three Rings Design, Inc., All Rights Reserved
|
||||
// http://code.google.com/p/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.io {
|
||||
|
||||
import flash.utils.ByteArray;
|
||||
|
||||
public class ArrayMask
|
||||
{
|
||||
public function ArrayMask (length :int = 0)
|
||||
{
|
||||
var mlength :int = int(length / 8);
|
||||
if (length % 8 != 0) {
|
||||
mlength++;
|
||||
}
|
||||
_mask.length = mlength;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the specified index as containing a non-null element in the
|
||||
* array we're representing.
|
||||
*/
|
||||
public function setBit (index :int) :void
|
||||
{
|
||||
_mask[int(index/8)] |= (1 << (index % 8));
|
||||
}
|
||||
|
||||
/**
|
||||
* Is the specified array element non-null?
|
||||
*/
|
||||
public function isSet (index :int) :Boolean
|
||||
{
|
||||
return (_mask[int(index/8)] & (1 << (index % 8))) != 0;
|
||||
}
|
||||
|
||||
public function writeTo (out :ObjectOutputStream) :void
|
||||
{
|
||||
out.writeShort(_mask.length);
|
||||
out.writeBytes(_mask);
|
||||
}
|
||||
|
||||
// documentation inherited from interface Streamable
|
||||
public function readFrom (ins :ObjectInputStream) :void
|
||||
{
|
||||
var len :int = ins.readShort();
|
||||
_mask.length = len;
|
||||
if (len > 0) {
|
||||
ins.readBytes(_mask, 0, len);
|
||||
}
|
||||
}
|
||||
|
||||
/** The array mask. */
|
||||
protected var _mask :ByteArray = new ByteArray();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
//
|
||||
// $Id$
|
||||
//
|
||||
// Narya library - tools for developing networked games
|
||||
// Copyright (C) 2002-2010 Three Rings Design, Inc., All Rights Reserved
|
||||
// http://code.google.com/p/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.io {
|
||||
|
||||
public class ClassMapping
|
||||
{
|
||||
public var code :int;
|
||||
public var streamer :Streamer;
|
||||
|
||||
public function ClassMapping (code :int, streamer :Streamer)
|
||||
{
|
||||
this.code = code;
|
||||
this.streamer = streamer;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
//
|
||||
// $Id$
|
||||
//
|
||||
// Narya library - tools for developing networked games
|
||||
// Copyright (C) 2002-2010 Three Rings Design, Inc., All Rights Reserved
|
||||
// http://code.google.com/p/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.io {
|
||||
|
||||
import flash.events.Event;
|
||||
|
||||
import flash.utils.ByteArray;
|
||||
|
||||
public class FrameAvailableEvent extends Event
|
||||
{
|
||||
/** The event code for a frame available. */
|
||||
public static const FRAME_AVAILABLE :String = "frameAvail";
|
||||
|
||||
public function FrameAvailableEvent (frameData :ByteArray)
|
||||
{
|
||||
super(FRAME_AVAILABLE);
|
||||
_frameData = frameData;
|
||||
}
|
||||
|
||||
public function getFrameData () :ByteArray
|
||||
{
|
||||
return _frameData;
|
||||
}
|
||||
|
||||
protected var _frameData :ByteArray;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,118 @@
|
||||
//
|
||||
// $Id$
|
||||
//
|
||||
// Narya library - tools for developing networked games
|
||||
// Copyright (C) 2002-2010 Three Rings Design, Inc., All Rights Reserved
|
||||
// http://code.google.com/p/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.io {
|
||||
|
||||
import flash.events.EventDispatcher;
|
||||
import flash.events.ProgressEvent;
|
||||
|
||||
import flash.net.Socket;
|
||||
|
||||
import flash.utils.ByteArray;
|
||||
import flash.utils.Endian;
|
||||
|
||||
import com.threerings.util.Log;
|
||||
|
||||
/**
|
||||
* Reads socket data until a complete frame is available.
|
||||
* This dispatches a FrameAvailableEvent.FRAME_AVAILABLE once a frame
|
||||
* has been fully read off the socket and is ready for decoding.
|
||||
*/
|
||||
public class FrameReader extends EventDispatcher
|
||||
{
|
||||
public function FrameReader (socket :Socket)
|
||||
{
|
||||
_socket = socket;
|
||||
_socket.addEventListener(ProgressEvent.SOCKET_DATA, socketHasData);
|
||||
}
|
||||
|
||||
/**
|
||||
* Stop listening on the socket.
|
||||
*/
|
||||
public function shutdown () :void
|
||||
{
|
||||
_socket.removeEventListener(ProgressEvent.SOCKET_DATA, socketHasData);
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when our socket has data that we can read.
|
||||
*/
|
||||
protected function socketHasData (event :ProgressEvent) :void
|
||||
{
|
||||
try {
|
||||
readAvailable();
|
||||
} catch (e :Error) {
|
||||
Log.getLog(this).warning("Error reading socket data", e);
|
||||
}
|
||||
}
|
||||
|
||||
protected function readAvailable () :void
|
||||
{
|
||||
if (ObjectInputStream.DEBUG) {
|
||||
Log.getLog(this).debug("socketHasData(" + _socket.bytesAvailable + ")");
|
||||
}
|
||||
|
||||
while (_socket.connected && _socket.bytesAvailable > 0) {
|
||||
if (_curData == null) {
|
||||
if (_socket.bytesAvailable < HEADER_SIZE) {
|
||||
// if there are less bytes available than a header, let's
|
||||
// just leave them on the socket until we can read the length
|
||||
// all at once
|
||||
return;
|
||||
}
|
||||
// the length specified is the length of the entire frame,
|
||||
// including the length of the bytes used to encode the length.
|
||||
// (I think this is pretty silly).
|
||||
// So for our purposes we subtract 4 bytes so we know how much
|
||||
// more data is in the frame.
|
||||
_length = _socket.readInt() - HEADER_SIZE;
|
||||
_curData = new ByteArray();
|
||||
_curData.endian = Endian.BIG_ENDIAN;
|
||||
}
|
||||
|
||||
// read bytes: either as much as possible or up to the end of the frame
|
||||
var toRead :int = Math.min(_length - _curData.length, _socket.bytesAvailable);
|
||||
// Just in case, if the amount needed is 0, don't do anything!
|
||||
// Passing 0 causes it to read *all available bytes*.
|
||||
if (toRead != 0) {
|
||||
_socket.readBytes(_curData, _curData.length, toRead);
|
||||
}
|
||||
|
||||
if (_length === _curData.length) {
|
||||
// we have now read a complete frame, let us dispatch the data
|
||||
_curData.position = 0; // move the read pointer to the beginning
|
||||
if (ObjectInputStream.DEBUG) {
|
||||
Log.getLog(this).debug("+ FrameAvailable");
|
||||
}
|
||||
dispatchEvent(new FrameAvailableEvent(_curData));
|
||||
_curData = null; // clear, so we know we need to first read length
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected var _socket :Socket;
|
||||
protected var _curData :ByteArray;
|
||||
protected var _length :int;
|
||||
|
||||
/** The number of bytes in the frame header (a 32-bit integer). */
|
||||
protected const HEADER_SIZE :int = 4;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,297 @@
|
||||
//
|
||||
// $Id$
|
||||
//
|
||||
// Narya library - tools for developing networked games
|
||||
// Copyright (C) 2002-2010 Three Rings Design, Inc., All Rights Reserved
|
||||
// http://code.google.com/p/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.io {
|
||||
|
||||
import flash.errors.IOError;
|
||||
import flash.errors.MemoryError;
|
||||
|
||||
import flash.utils.ByteArray;
|
||||
import flash.utils.IDataInput;
|
||||
|
||||
import com.threerings.util.ClassUtil;
|
||||
import com.threerings.util.Log;
|
||||
import com.threerings.util.Long;
|
||||
|
||||
public class ObjectInputStream
|
||||
{
|
||||
/** Enables verbose object I/O debugging. */
|
||||
public static const DEBUG :Boolean = false;
|
||||
|
||||
public function ObjectInputStream (source :IDataInput = null, clientProps :Object = null)
|
||||
{
|
||||
_source = source || new ByteArray();
|
||||
_cliProps = clientProps || {};
|
||||
}
|
||||
|
||||
/**
|
||||
* Set a new source from which to read our data.
|
||||
*/
|
||||
public function setSource (source :IDataInput) :void
|
||||
{
|
||||
_source = source;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a "client property" with the specified name.
|
||||
* Actionscript only.
|
||||
*/
|
||||
public function getClientProperty (name :String) :*
|
||||
{
|
||||
return _cliProps[name];
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads the next Object (or null) from the stream and returns it as * so that you may assign
|
||||
* to any variable without casting. It is strongly recommended that you pass a 'checkType'
|
||||
* parameter so that the type of the Object is verified to be what you believe it to be,
|
||||
* thus helping you detect streaming errors as quickly as possible.
|
||||
*
|
||||
* @param checkType optional type to check the read object against
|
||||
* @return the Object read, or null.
|
||||
* @throws TypeError if the object is read successfully but is the wrong type
|
||||
*
|
||||
* @example This demonstrates how to type-check the objects read off the stream without
|
||||
* having to cast them.
|
||||
* <listing version="3.0">
|
||||
*
|
||||
* public function readObject (ins :ObjectInputStream) :void
|
||||
* {
|
||||
* _scoops = ins.readObject(Array);
|
||||
* _coneType = ins.readObject(Cone);
|
||||
* }
|
||||
*
|
||||
* protected var _scoops :Array;
|
||||
* protected var _coneType :Cone;
|
||||
* </listing>
|
||||
*/
|
||||
public function readObject (checkType :Class = null) :*
|
||||
//throws IOError
|
||||
{
|
||||
var DEBUG_ID :String = "[" + (++_debugObjectCounter) + "] ";
|
||||
try {
|
||||
// read in the class code for this instance
|
||||
var code :int = readShort();
|
||||
|
||||
// a zero code indicates a null value
|
||||
if (code == 0) {
|
||||
if (DEBUG) log.debug(DEBUG_ID + "Read null");
|
||||
return null;
|
||||
}
|
||||
|
||||
var cmap :ClassMapping;
|
||||
|
||||
// if the code is negative, that means we've never seen it
|
||||
// before and class metadata follows
|
||||
if (code < 0) {
|
||||
// first swap the code into positive land
|
||||
code *= -1;
|
||||
|
||||
// read in the class metadata
|
||||
var jname :String = readUTF();
|
||||
// log.debug("read jname: " + jname);
|
||||
var streamer :Streamer = Streamer.getStreamerByJavaName(jname);
|
||||
if (streamer == null) {
|
||||
log.warning("OMG, cannot stream " + jname);
|
||||
return null;
|
||||
}
|
||||
if (DEBUG) log.debug(DEBUG_ID + "Got streamer (" + streamer + ")");
|
||||
|
||||
cmap = new ClassMapping(code, streamer);
|
||||
_classMap[code] = cmap;
|
||||
if (DEBUG) log.debug(DEBUG_ID + "Created mapping: (" + code + "): " + jname);
|
||||
|
||||
} else {
|
||||
cmap = (_classMap[code] as ClassMapping);
|
||||
if (null == cmap) {
|
||||
throw new IOError("Read object for which we have no " +
|
||||
"registered class metadata [code=" + code + "].");
|
||||
}
|
||||
if (DEBUG) {
|
||||
log.debug(DEBUG_ID + "Read known code: (" + code + ": " +
|
||||
cmap.streamer.getJavaClassName() + ")");
|
||||
}
|
||||
}
|
||||
|
||||
// log.debug("Creating object sleeve...");
|
||||
var target :Object = cmap.streamer.createObject(this);
|
||||
//log.debug("Reading object...");
|
||||
readBareObjectImpl(target, cmap.streamer);
|
||||
if (DEBUG) log.debug(DEBUG_ID + "Read object: " + target);
|
||||
if (checkType != null && !(target is checkType)) {
|
||||
throw new TypeError(
|
||||
"Cannot convert " + ClassUtil.getClass(target) + " to " + checkType);
|
||||
}
|
||||
return target;
|
||||
|
||||
} catch (me :MemoryError) {
|
||||
throw new IOError("out of memory" + me.message);
|
||||
}
|
||||
return null; // not reached: compiler dumb
|
||||
}
|
||||
|
||||
public function readBareObject (obj :Object) :void
|
||||
//throws IOError
|
||||
{
|
||||
readBareObjectImpl(obj, Streamer.getStreamer(obj));
|
||||
}
|
||||
|
||||
public function readBareObjectImpl (obj :Object, streamer :Streamer) :void
|
||||
{
|
||||
_current = obj;
|
||||
_streamer = streamer;
|
||||
try {
|
||||
_streamer.readObject(obj, this);
|
||||
|
||||
} finally {
|
||||
// clear out our current object references
|
||||
_current = null;
|
||||
_streamer = null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Called to read an Object of a known final type into a Streamable object.
|
||||
*
|
||||
* @param type either a String representing the java type,
|
||||
* a Class representing the actionscript type,
|
||||
* or the Streamer to be used to read the field.
|
||||
*/
|
||||
public function readField (type :Object) :*
|
||||
//throws IOError
|
||||
{
|
||||
if (!readBoolean()) {
|
||||
return null;
|
||||
}
|
||||
|
||||
var streamer :Streamer;
|
||||
if (type is Streamer) {
|
||||
streamer = Streamer(type);
|
||||
} else {
|
||||
var jname :String = type as String;
|
||||
if (type is Class) {
|
||||
jname = Translations.getToServer(ClassUtil.getClassName(type));
|
||||
}
|
||||
streamer= Streamer.getStreamerByJavaName(jname);
|
||||
if (streamer == null) {
|
||||
throw new Error("Cannot field stream " + type);
|
||||
}
|
||||
}
|
||||
|
||||
var obj :Object = streamer.createObject(this);
|
||||
readBareObjectImpl(obj, streamer);
|
||||
return obj;
|
||||
}
|
||||
|
||||
public function defaultReadObject () :void
|
||||
//throws IOError
|
||||
{
|
||||
_streamer.readObject(_current, this);
|
||||
}
|
||||
|
||||
public function readBoolean () :Boolean
|
||||
//throws IOError
|
||||
{
|
||||
return _source.readBoolean();
|
||||
}
|
||||
|
||||
public function readByte () :int
|
||||
//throws IOError
|
||||
{
|
||||
return _source.readByte();
|
||||
}
|
||||
|
||||
/**
|
||||
* Read bytes into the byte array. If length is not specified, then
|
||||
* enough bytes to fill the array (from the offset) are read.
|
||||
*/
|
||||
public function readBytes (
|
||||
bytes :ByteArray, offset :uint = 0, length :uint = uint.MAX_VALUE) :void
|
||||
//throws IOError
|
||||
{
|
||||
// if no length specified then fill the ByteArray
|
||||
if (length == uint.MAX_VALUE) {
|
||||
length = bytes.length - offset;
|
||||
}
|
||||
// And, if we really want to read 0 bytes then just don't do anything, because an
|
||||
// IDataInput will read *all available bytes* when the specified length is 0.
|
||||
if (length > 0) {
|
||||
_source.readBytes(bytes, offset, length);
|
||||
}
|
||||
}
|
||||
|
||||
public function readDouble () :Number
|
||||
//throws IOError
|
||||
{
|
||||
return _source.readDouble();
|
||||
}
|
||||
|
||||
public function readFloat () :Number
|
||||
//throws IOError
|
||||
{
|
||||
return _source.readFloat();
|
||||
}
|
||||
|
||||
public function readLong () :Long
|
||||
{
|
||||
const result :Long = new Long();
|
||||
readBareObject(result);
|
||||
return result;
|
||||
}
|
||||
|
||||
public function readInt () :int
|
||||
//throws IOError
|
||||
{
|
||||
return _source.readInt();
|
||||
}
|
||||
|
||||
public function readShort () :int
|
||||
//throws IOError
|
||||
{
|
||||
return _source.readShort();
|
||||
}
|
||||
|
||||
public function readUTF () :String
|
||||
//throws IOError
|
||||
{
|
||||
return _source.readUTF();
|
||||
}
|
||||
|
||||
/** Named "client properties" that we can provide to deserialized objects. */
|
||||
protected var _cliProps :Object;
|
||||
|
||||
/** The target DataInput that we route input from. */
|
||||
protected var _source :IDataInput;
|
||||
|
||||
/** The object currently being read from the stream. */
|
||||
protected var _current :Object;
|
||||
|
||||
/** The streamer being used currently. */
|
||||
protected var _streamer :Streamer;
|
||||
|
||||
/** A map of short class code to ClassMapping info. */
|
||||
protected var _classMap :Array = new Array();
|
||||
|
||||
private static var _debugObjectCounter :int = 0;
|
||||
|
||||
private static const log :Log = Log.getLog(ObjectInputStream);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,236 @@
|
||||
//
|
||||
// $Id$
|
||||
//
|
||||
// Narya library - tools for developing networked games
|
||||
// Copyright (C) 2002-2010 Three Rings Design, Inc., All Rights Reserved
|
||||
// http://code.google.com/p/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.io {
|
||||
|
||||
import flash.utils.ByteArray;
|
||||
import flash.utils.IDataOutput;
|
||||
|
||||
import com.threerings.util.ClassUtil;
|
||||
import com.threerings.util.Map;
|
||||
import com.threerings.util.Maps;
|
||||
import com.threerings.util.Log;
|
||||
import com.threerings.util.Long;
|
||||
import com.threerings.util.Short;
|
||||
|
||||
public class ObjectOutputStream
|
||||
{
|
||||
private static const log :Log = Log.getLog(ObjectOutputStream);
|
||||
|
||||
public function ObjectOutputStream (targ :IDataOutput)
|
||||
{
|
||||
_targ = targ;
|
||||
}
|
||||
|
||||
public function writeObject (obj :Object) :void
|
||||
//throws IOError
|
||||
{
|
||||
// if the object to be written is null (or undefined) write a zero
|
||||
if (obj == null) {
|
||||
writeShort(0);
|
||||
return;
|
||||
}
|
||||
|
||||
var cname :String;
|
||||
if (obj is TypedArray) {
|
||||
cname = (obj as TypedArray).getJavaType();
|
||||
} else {
|
||||
cname = ClassUtil.getClassName(obj);
|
||||
}
|
||||
// look up the class mapping record
|
||||
var cmap :ClassMapping = (_classMap.get(cname) as ClassMapping);
|
||||
|
||||
// create a class mapping if we've not got one
|
||||
if (cmap == null) {
|
||||
var streamer :Streamer = Streamer.getStreamer(obj);
|
||||
if (streamer == null) {
|
||||
throw new Error("Unable to stream " + cname);
|
||||
}
|
||||
|
||||
cmap = new ClassMapping(_nextCode++, streamer);
|
||||
_classMap.put(cname, cmap);
|
||||
|
||||
if (_nextCode > Short.MAX_VALUE) {
|
||||
throw new Error("Too many unique classes written to ObjectOutputStream");
|
||||
}
|
||||
|
||||
if (ObjectInputStream.DEBUG) {
|
||||
log.debug("Assigning class code", "code", cmap.code, "class", cname);
|
||||
}
|
||||
|
||||
writeShort(-cmap.code);
|
||||
writeUTF(streamer.getJavaClassName());
|
||||
|
||||
} else {
|
||||
writeShort(cmap.code);
|
||||
}
|
||||
|
||||
writeBareObjectImpl(obj, cmap.streamer);
|
||||
}
|
||||
|
||||
public function writeBareObject (obj :Object, streamer :Streamer = null) :void
|
||||
//throws IOError
|
||||
{
|
||||
if (streamer == null) {
|
||||
streamer = Streamer.getStreamer(obj);
|
||||
}
|
||||
writeBareObjectImpl(obj, streamer);
|
||||
}
|
||||
|
||||
public function writeBareObjectImpl (obj :Object, streamer :Streamer) :void
|
||||
{
|
||||
// otherwise, stream it!
|
||||
_current = obj;
|
||||
_streamer = streamer;
|
||||
try {
|
||||
_streamer.writeObject(obj, this);
|
||||
} finally {
|
||||
_current = null;
|
||||
_streamer = null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Called to write an object reference within a Streamable object when the type of the
|
||||
* field is a final type.
|
||||
*
|
||||
* @example This is how you would do it, even if s and o referred to the same String object!
|
||||
* <listing version="3.0">
|
||||
* public class Foo
|
||||
* implements Streamable
|
||||
* {
|
||||
* public var o :Object;
|
||||
* public var s :String;
|
||||
* ...
|
||||
* public function writeObject (out :ObjectOutputStream) :void
|
||||
* {
|
||||
* out.writeObject(o);
|
||||
* out.writeField(s);
|
||||
* }
|
||||
* }
|
||||
* </listing>
|
||||
*/
|
||||
public function writeField (val :Object, streamer :Streamer = null) :void
|
||||
//throws IOError
|
||||
{
|
||||
var b :Boolean = (val != null);
|
||||
writeBoolean(b);
|
||||
if (b) {
|
||||
writeBareObject(val, streamer);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Uses the default streamable mechanism to write the contents of the object currently being
|
||||
* streamed. This can only be called from within a <code>writeObject</code> implementation in a
|
||||
* {@link Streamable} object.
|
||||
*/
|
||||
public function defaultWriteObject () :void
|
||||
//throws IOError
|
||||
{
|
||||
// sanity check
|
||||
if (_current == null) {
|
||||
throw new Error("defaultWriteObject() called illegally.");
|
||||
}
|
||||
|
||||
// write the instance data
|
||||
_streamer.writeObject(_current, this);
|
||||
}
|
||||
|
||||
public function writeBoolean (value :Boolean) :void
|
||||
//throws IOError
|
||||
{
|
||||
_targ.writeBoolean(value);
|
||||
}
|
||||
|
||||
public function writeByte (value :int) :void
|
||||
//throws IOError
|
||||
{
|
||||
_targ.writeByte(value);
|
||||
}
|
||||
|
||||
public function writeBytes (
|
||||
bytes :ByteArray, offset :uint = 0, length :uint = uint.MAX_VALUE) :void
|
||||
//throws IOError
|
||||
{
|
||||
if (length == uint.MAX_VALUE) {
|
||||
length = bytes.length - offset;
|
||||
}
|
||||
if (length > 0) {
|
||||
_targ.writeBytes(bytes, offset, length);
|
||||
}
|
||||
}
|
||||
|
||||
public function writeDouble (value :Number) :void
|
||||
//throws IOError
|
||||
{
|
||||
_targ.writeDouble(value);
|
||||
}
|
||||
|
||||
public function writeFloat (value :Number) :void
|
||||
//throws IOError
|
||||
{
|
||||
_targ.writeFloat(value);
|
||||
}
|
||||
|
||||
public function writeLong (value :Long) :void
|
||||
{
|
||||
writeBareObject(value);
|
||||
}
|
||||
|
||||
public function writeInt (value :int) :void
|
||||
//throws IOError
|
||||
{
|
||||
_targ.writeInt(value);
|
||||
}
|
||||
|
||||
public function writeShort (value :int) :void
|
||||
//throws IOError
|
||||
{
|
||||
_targ.writeShort(value);
|
||||
}
|
||||
|
||||
public function writeUTF (value :String) :void
|
||||
//throws IOError
|
||||
{
|
||||
_targ.writeUTF(value);
|
||||
}
|
||||
|
||||
// these two are defined in IDataOutput, but have no java equivalent so we skip them.
|
||||
//public function writeUnsignedInt (value :int) :void
|
||||
//public function writeUTFBytes (value :int) :void
|
||||
|
||||
/** The target DataOutput that we route things to. */
|
||||
protected var _targ :IDataOutput;
|
||||
|
||||
/** A counter used to assign codes to streamed classes. */
|
||||
protected var _nextCode :int = 1;
|
||||
|
||||
/** The object currently being written out. */
|
||||
protected var _current :Object;
|
||||
|
||||
/** The streamer being used currently. */
|
||||
protected var _streamer :Streamer;
|
||||
|
||||
/** A map of classname to ClassMapping info. */
|
||||
protected var _classMap :Map = Maps.newMapOf(String);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,64 @@
|
||||
//
|
||||
// $Id$
|
||||
//
|
||||
// Narya library - tools for developing networked games
|
||||
// Copyright (C) 2002-2010 Three Rings Design, Inc., All Rights Reserved
|
||||
// http://code.google.com/p/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.io {
|
||||
|
||||
import com.threerings.util.Joiner;
|
||||
|
||||
/**
|
||||
* A simple serializable object implements the {@link Streamable}
|
||||
* interface and provides a default {@link #toString} implementation which
|
||||
* outputs all public members.
|
||||
*/
|
||||
public class SimpleStreamableObject implements Streamable
|
||||
{
|
||||
// from interface Streamable
|
||||
public function readObject (ins :ObjectInputStream) :void
|
||||
{
|
||||
// nothing by default
|
||||
}
|
||||
|
||||
// from interface Streamable
|
||||
public function writeObject (out :ObjectOutputStream) :void
|
||||
{
|
||||
// nothing by default
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates a string representation of this instance.
|
||||
*/
|
||||
public function toString () :String
|
||||
{
|
||||
var j :Joiner = Joiner.createFor(this);
|
||||
toStringJoiner(j);
|
||||
return j.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles the toString-ification of all public members. Derived
|
||||
* classes can override and include non-public members if desired.
|
||||
*/
|
||||
protected function toStringJoiner (j :Joiner): void
|
||||
{
|
||||
j.addFields(this);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
//
|
||||
// $Id$
|
||||
//
|
||||
// Narya library - tools for developing networked games
|
||||
// Copyright (C) 2002-2010 Three Rings Design, Inc., All Rights Reserved
|
||||
// http://code.google.com/p/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.io {
|
||||
|
||||
/**
|
||||
* Note: all Streamable instances should have a constructor that copes
|
||||
* with no arguments.
|
||||
*/
|
||||
public interface Streamable
|
||||
{
|
||||
function writeObject (out :ObjectOutputStream) :void;
|
||||
//throws IOError;
|
||||
|
||||
function readObject (ins :ObjectInputStream) :void;
|
||||
//throws IOError; /** ClassCastException equivalent. */
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,165 @@
|
||||
//
|
||||
// $Id$
|
||||
//
|
||||
// Narya library - tools for developing networked games
|
||||
// Copyright (C) 2002-2010 Three Rings Design, Inc., All Rights Reserved
|
||||
// http://code.google.com/p/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.io {
|
||||
|
||||
import flash.utils.ByteArray;
|
||||
import flash.utils.Dictionary;
|
||||
|
||||
import com.threerings.util.ByteEnum;
|
||||
import com.threerings.util.ClassUtil;
|
||||
import com.threerings.util.Enum;
|
||||
|
||||
import com.threerings.io.streamers.ArrayStreamer;
|
||||
import com.threerings.io.streamers.ByteArrayStreamer;
|
||||
import com.threerings.io.streamers.ByteEnumStreamer;
|
||||
import com.threerings.io.streamers.EnumStreamer;
|
||||
import com.threerings.io.streamers.MapStreamer;
|
||||
import com.threerings.io.streamers.NumberStreamer;
|
||||
import com.threerings.io.streamers.SetStreamer;
|
||||
import com.threerings.io.streamers.StringStreamer;
|
||||
|
||||
public class Streamer
|
||||
{
|
||||
public static function getStreamer (obj :Object) :Streamer
|
||||
{
|
||||
var jname :String;
|
||||
if (obj is TypedArray) {
|
||||
jname = TypedArray(obj).getJavaType();
|
||||
} else {
|
||||
jname = Translations.getToServer(ClassUtil.getClassName(obj));
|
||||
}
|
||||
return getStreamerByJavaName(jname);
|
||||
}
|
||||
|
||||
public static function getStreamerByJavaName (jname :String) :Streamer
|
||||
{
|
||||
initStreamers();
|
||||
|
||||
// see if we have a streamer for it
|
||||
var streamer :Streamer = _byJName[jname] as Streamer;
|
||||
if (streamer != null) {
|
||||
return streamer;
|
||||
}
|
||||
|
||||
// see if it's an array that we unstream using an ArrayStreamer
|
||||
if (jname.charAt(0) === "[") {
|
||||
streamer = new ArrayStreamer(jname);
|
||||
|
||||
} else {
|
||||
// otherwise see if it represents a Streamable
|
||||
// usually this is called from ObjectInputStream, but when it's called from
|
||||
// ObjectOutputStream it's a bit annoying, because we started with a class/object.
|
||||
// But: the code is smaller, so that wins
|
||||
var clazz :Class = ClassUtil.getClassByName(Translations.getFromServer(jname));
|
||||
|
||||
if (ClassUtil.isAssignableAs(Enum, clazz)) {
|
||||
streamer = ClassUtil.isAssignableAs(ByteEnum, clazz) ?
|
||||
new ByteEnumStreamer(clazz, jname) : new EnumStreamer(clazz, jname);
|
||||
|
||||
} else if (ClassUtil.isAssignableAs(Streamable, clazz)) {
|
||||
streamer = new Streamer(clazz, jname);
|
||||
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
// add the good new streamer
|
||||
registerStreamer(streamer);
|
||||
return streamer;
|
||||
}
|
||||
|
||||
/** This should be a protected constructor. */
|
||||
public function Streamer (targ :Class, jname :String = null)
|
||||
//throws IOError
|
||||
{
|
||||
_target = targ;
|
||||
_jname = (jname != null) ? jname : Translations.getToServer(ClassUtil.getClassName(targ));
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the String to use to identify the class that we're streaming.
|
||||
*/
|
||||
public function getJavaClassName () :String
|
||||
{
|
||||
return _jname;
|
||||
}
|
||||
|
||||
public function writeObject (obj :Object, out :ObjectOutputStream) :void
|
||||
//throws IOError
|
||||
{
|
||||
(obj as Streamable).writeObject(out);
|
||||
}
|
||||
|
||||
public function createObject (ins :ObjectInputStream) :Object
|
||||
//throws IOError
|
||||
{
|
||||
// actionscript is so fucked up
|
||||
return new _target();
|
||||
}
|
||||
|
||||
public function readObject (obj :Object, ins :ObjectInputStream) :void
|
||||
//throws IOError
|
||||
{
|
||||
(obj as Streamable).readObject(ins);
|
||||
}
|
||||
|
||||
public function toString () :String
|
||||
{
|
||||
return "[Streamer(" + _jname + ")]";
|
||||
}
|
||||
|
||||
protected static function registerStreamer (st :Streamer, ... extraJavaNames) :void
|
||||
{
|
||||
_byJName[st.getJavaClassName()] = st;
|
||||
for each (var name :String in extraJavaNames) {
|
||||
_byJName[name] = st;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize our streamers. This cannot simply be done statically
|
||||
* because we cannot instantiate a subclass when this class is still
|
||||
* being created. Fucking actionscript.
|
||||
*/
|
||||
private static function initStreamers () :void
|
||||
{
|
||||
if (_byJName != null) {
|
||||
return;
|
||||
}
|
||||
_byJName = new Dictionary();
|
||||
for each (var c :Class in [ StringStreamer, NumberStreamer, ByteArrayStreamer ]) {
|
||||
registerStreamer(Streamer(new c()));
|
||||
}
|
||||
registerStreamer(ArrayStreamer.INSTANCE,
|
||||
"java.util.List", "java.util.ArrayList", "java.util.Collection");
|
||||
registerStreamer(SetStreamer.INSTANCE, "java.util.Set");
|
||||
registerStreamer(MapStreamer.INSTANCE, "java.util.Map");
|
||||
}
|
||||
|
||||
protected var _target :Class;
|
||||
|
||||
protected var _jname :String;
|
||||
|
||||
protected static var _byJName :Dictionary;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,68 @@
|
||||
//
|
||||
// $Id$
|
||||
//
|
||||
// Narya library - tools for developing networked games
|
||||
// Copyright (C) 2002-2010 Three Rings Design, Inc., All Rights Reserved
|
||||
// http://code.google.com/p/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.io {
|
||||
|
||||
import flash.utils.Dictionary;
|
||||
|
||||
/**
|
||||
* Maintains a set of translations between actionscript class names
|
||||
* and server (Java) class names.
|
||||
*/
|
||||
public class Translations
|
||||
{
|
||||
public static function getToServer (asName :String) :String
|
||||
{
|
||||
var javaName :String = (_toServer[asName] as String);
|
||||
return (javaName == null) ? asName.replace("_", "$") : javaName;
|
||||
}
|
||||
|
||||
public static function getFromServer (javaName :String) :String
|
||||
{
|
||||
var asName :String = (_fromServer[javaName] as String);
|
||||
return (asName == null) ? javaName.replace("$", "_") : asName;
|
||||
}
|
||||
|
||||
public static function addTranslation (asName :String, javaName :String) :void
|
||||
{
|
||||
_toServer[asName] = javaName;
|
||||
_fromServer[javaName] = asName;
|
||||
}
|
||||
|
||||
/** A mapping of actionscript names to java names. */
|
||||
protected static var _toServer :Dictionary = new Dictionary();
|
||||
|
||||
/** A mapping of java names to actionscript names. */
|
||||
protected static var _fromServer :Dictionary = new Dictionary();
|
||||
|
||||
// initialize some standard classes
|
||||
addTranslation("Object", "java.lang.Object");
|
||||
addTranslation("String", "java.lang.String");
|
||||
addTranslation("Array", "[Ljava.lang.Object;");
|
||||
addTranslation("flash.utils.ByteArray", "[B");
|
||||
addTranslation("com.threerings.util.langBoolean", "java.lang.Boolean");
|
||||
addTranslation("com.threerings.util.Byte", "java.lang.Byte");
|
||||
addTranslation("com.threerings.util.Short", "java.lang.Short");
|
||||
addTranslation("com.threerings.util.Integer", "java.lang.Integer");
|
||||
addTranslation("com.threerings.util.Long", "java.lang.Long");
|
||||
addTranslation("com.threerings.util.Float", "java.lang.Float");
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,127 @@
|
||||
//
|
||||
// $Id$
|
||||
//
|
||||
// Narya library - tools for developing networked games
|
||||
// Copyright (C) 2002-2010 Three Rings Design, Inc., All Rights Reserved
|
||||
// http://code.google.com/p/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.io {
|
||||
|
||||
import flash.utils.ByteArray;
|
||||
|
||||
import com.threerings.util.ClassUtil;
|
||||
import com.threerings.util.Cloneable;
|
||||
|
||||
public dynamic class TypedArray extends Array
|
||||
implements Cloneable
|
||||
{
|
||||
/**
|
||||
* Convenience method to get the java type of an array containing objects of the specified
|
||||
* class.
|
||||
*/
|
||||
public static function getJavaType (of :Class) :String
|
||||
{
|
||||
if (of === Boolean) {
|
||||
return "[Z";
|
||||
|
||||
} else if (of === int) { // Number will be int if something like 3.0
|
||||
return "[I";
|
||||
|
||||
} else if (of === Number) {
|
||||
return "[D";
|
||||
|
||||
} else if (of === ByteArray) {
|
||||
return "[[B";
|
||||
}
|
||||
|
||||
var cname :String = Translations.getToServer(ClassUtil.getClassName(of));
|
||||
return "[L" + cname + ";";
|
||||
}
|
||||
|
||||
/** Because we have no actionscript type to check, we'll just handle this one manually. */
|
||||
public static function getJavaShortType () :String
|
||||
{
|
||||
return "[S";
|
||||
}
|
||||
|
||||
/**
|
||||
* A factory method to create a TypedArray for holding objects of the specified type.
|
||||
*/
|
||||
public static function create (of :Class, initialValues :Array = null) :TypedArray
|
||||
{
|
||||
var ta :TypedArray = new TypedArray(getJavaType(of));
|
||||
if (initialValues != null) {
|
||||
ta.addAll(initialValues);
|
||||
}
|
||||
return ta;
|
||||
}
|
||||
|
||||
/**
|
||||
* A factory method to create a TypedArray for holding data meant as java shorts.
|
||||
*/
|
||||
public static function createShort (initialValues :Array = null) :TypedArray
|
||||
{
|
||||
var ta :TypedArray = new TypedArray(getJavaShortType());
|
||||
if (initialValues != null) {
|
||||
ta.addAll(initialValues);
|
||||
}
|
||||
return ta;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a TypedArray
|
||||
*
|
||||
* @param jtype The java classname of this array, for example "[I" to represent an int[], or
|
||||
* "[Ljava.lang.Object;" for Object[].
|
||||
*/
|
||||
public function TypedArray (jtype :String)
|
||||
{
|
||||
_jtype = jtype;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds all of the elements of the supplied array to this typed array. The types of the
|
||||
* elements of the target array must, of course, be of the type specified for this array
|
||||
* otherwise badness will ensue.
|
||||
*
|
||||
* @return this array instance for handy call chainability.
|
||||
*/
|
||||
public function addAll (other :Array) :TypedArray
|
||||
{
|
||||
push.apply(this, other);
|
||||
return this;
|
||||
}
|
||||
|
||||
public function getJavaType () :String
|
||||
{
|
||||
return _jtype;
|
||||
}
|
||||
|
||||
// from Cloneable
|
||||
public function clone () :Object
|
||||
{
|
||||
var clazz :Class = ClassUtil.getClass(this);
|
||||
var copy :TypedArray = new clazz(_jtype);
|
||||
copy.addAll(this);
|
||||
return copy;
|
||||
}
|
||||
|
||||
/** The 'type' of this array, which doesn't really mean anything except gives it a clue as to
|
||||
* how to stream to our server. */
|
||||
protected var _jtype :String;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,203 @@
|
||||
//
|
||||
// $Id$
|
||||
//
|
||||
// Narya library - tools for developing networked games
|
||||
// Copyright (C) 2002-2010 Three Rings Design, Inc., All Rights Reserved
|
||||
// http://code.google.com/p/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.io.streamers {
|
||||
|
||||
import com.threerings.io.ArrayMask;
|
||||
import com.threerings.io.ObjectInputStream;
|
||||
import com.threerings.io.ObjectOutputStream;
|
||||
import com.threerings.io.Streamer;
|
||||
import com.threerings.io.Translations;
|
||||
import com.threerings.io.TypedArray;
|
||||
import com.threerings.util.ClassUtil;
|
||||
import com.threerings.util.Enum;
|
||||
import com.threerings.util.Byte;
|
||||
import com.threerings.util.Float;
|
||||
import com.threerings.util.Integer;
|
||||
import com.threerings.util.Log;
|
||||
import com.threerings.util.Long;
|
||||
import com.threerings.util.Short;
|
||||
import com.threerings.util.langBoolean;
|
||||
|
||||
/**
|
||||
* A Streamer for Array objects.
|
||||
*/
|
||||
public class ArrayStreamer extends Streamer
|
||||
{
|
||||
public static const INSTANCE :ArrayStreamer = new ArrayStreamer();
|
||||
|
||||
public function ArrayStreamer (jname :String = "[Ljava.lang.Object;")
|
||||
{
|
||||
super(TypedArray, jname);
|
||||
|
||||
var secondChar :String = jname.charAt(1);
|
||||
if (secondChar === "[") {
|
||||
// if we're a multi-dimensional array then we need a delegate
|
||||
_delegate = Streamer.getStreamerByJavaName(jname.substring(1));
|
||||
_isFinal = true; // it just is
|
||||
|
||||
} else if (secondChar === "L") {
|
||||
// form is "[L<class>;"
|
||||
var baseJClass :String = jname.substring(2, jname.length - 1);
|
||||
_delegate = Streamer.getStreamerByJavaName(baseJClass);
|
||||
_elementType = ClassUtil.getClassByName(Translations.getFromServer(baseJClass));
|
||||
_isFinal = isFinal(_elementType);
|
||||
|
||||
} else if (secondChar === "I") {
|
||||
_elementType = int;
|
||||
|
||||
} else if (secondChar === "Z") {
|
||||
_elementType = Boolean;
|
||||
|
||||
} else if (secondChar === "S") {
|
||||
_elementType = PrimitiveShort;
|
||||
|
||||
} else {
|
||||
Log.getLog(this).warning("Other array types are not yet handled", "jname", jname);
|
||||
throw new Error("Don't know how to stream '" + jname + "' instances.");
|
||||
}
|
||||
}
|
||||
|
||||
override public function createObject (ins :ObjectInputStream) :Object
|
||||
{
|
||||
var ta :TypedArray = new TypedArray(_jname);
|
||||
ta.length = ins.readInt();
|
||||
return ta;
|
||||
}
|
||||
|
||||
override public function writeObject (obj :Object, out :ObjectOutputStream) :void
|
||||
{
|
||||
var arr :Array = (obj as Array);
|
||||
var ii :int;
|
||||
out.writeInt(arr.length);
|
||||
if (_elementType == int) {
|
||||
for (ii = 0; ii < arr.length; ii++) {
|
||||
out.writeInt(int(arr[ii]));
|
||||
}
|
||||
} else if (_elementType == PrimitiveShort) {
|
||||
for (ii = 0; ii < arr.length; ii++) {
|
||||
out.writeShort(int(arr[ii]));
|
||||
}
|
||||
|
||||
} else if (_elementType == Boolean) {
|
||||
for (ii = 0; ii < arr.length; ii++) {
|
||||
out.writeBoolean(Boolean(arr[ii]));
|
||||
}
|
||||
|
||||
} else if (_isFinal) {
|
||||
var mask :ArrayMask = new ArrayMask(arr.length);
|
||||
for (ii = 0; ii < arr.length; ii++) {
|
||||
if (arr[ii] != null) {
|
||||
mask.setBit(ii);
|
||||
}
|
||||
}
|
||||
mask.writeTo(out);
|
||||
// now write the populated elements
|
||||
for (ii = 0; ii < arr.length; ii++) {
|
||||
var element :Object = arr[ii];
|
||||
if (element != null) {
|
||||
out.writeBareObjectImpl(element, _delegate);
|
||||
}
|
||||
}
|
||||
|
||||
} else {
|
||||
for (ii = 0; ii < arr.length; ii++) {
|
||||
out.writeObject(arr[ii]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override public function readObject (obj :Object, ins :ObjectInputStream) :void
|
||||
{
|
||||
var arr :Array = (obj as Array);
|
||||
var ii :int;
|
||||
if (_elementType == int) {
|
||||
for (ii = 0; ii < arr.length; ii++) {
|
||||
arr[ii] = ins.readInt();
|
||||
}
|
||||
|
||||
} else if (_elementType == PrimitiveShort) {
|
||||
for (ii = 0; ii < arr.length; ii++) {
|
||||
arr[ii] = ins.readShort();
|
||||
}
|
||||
|
||||
} else if (_elementType == Boolean) {
|
||||
for (ii = 0; ii < arr.length; ii++) {
|
||||
arr[ii] = ins.readBoolean();
|
||||
}
|
||||
|
||||
} else if (_isFinal) {
|
||||
var mask :ArrayMask = new ArrayMask();
|
||||
mask.readFrom(ins);
|
||||
for (ii = 0; ii < arr.length; ii++) {
|
||||
if (mask.isSet(ii)) {
|
||||
var target :Object;
|
||||
if (_delegate == null) {
|
||||
target = new _elementType();
|
||||
} else {
|
||||
target = _delegate.createObject(ins);
|
||||
}
|
||||
ins.readBareObjectImpl(target, _delegate);
|
||||
arr[ii] = target;
|
||||
}
|
||||
}
|
||||
|
||||
} else {
|
||||
for (ii = 0; ii < arr.length; ii++) {
|
||||
arr[ii] = ins.readObject();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected static function isFinal (type :Class) :Boolean
|
||||
{
|
||||
if (type === String || type == Byte || type == Short || type === Integer ||
|
||||
type == Float || type == Long || type === langBoolean) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// all enums are final, even if you forget to make your enum class final, you punk
|
||||
if (ClassUtil.isAssignableAs(Enum, type)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// TODO: there's currently no way to determine final from the class
|
||||
// I thought examining the prototype might do it, but no dice.
|
||||
// Fuckers!
|
||||
return false;
|
||||
}
|
||||
|
||||
/** A streamer for our elements. */
|
||||
protected var _delegate :Streamer;
|
||||
|
||||
/** If this is the final dimension of the array, the element type. */
|
||||
protected var _elementType :Class;
|
||||
|
||||
/** Whether we're final or not: true if we're not the final dimension
|
||||
* or if the element type is final. */
|
||||
protected var _isFinal :Boolean;
|
||||
}
|
||||
}
|
||||
|
||||
/** A class to represent that the data in question should be handled as a java primitive short. */
|
||||
class PrimitiveShort
|
||||
{
|
||||
}
|
||||
@@ -0,0 +1,62 @@
|
||||
//
|
||||
// $Id$
|
||||
//
|
||||
// Narya library - tools for developing networked games
|
||||
// Copyright (C) 2002-2010 Three Rings Design, Inc., All Rights Reserved
|
||||
// http://code.google.com/p/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.io.streamers {
|
||||
|
||||
import flash.utils.ByteArray;
|
||||
|
||||
import com.threerings.io.ObjectInputStream;
|
||||
import com.threerings.io.ObjectOutputStream;
|
||||
import com.threerings.io.Streamer;
|
||||
|
||||
/**
|
||||
* A Streamer for ByteArray objects.
|
||||
*/
|
||||
public class ByteArrayStreamer extends Streamer
|
||||
{
|
||||
public function ByteArrayStreamer ()
|
||||
{
|
||||
super(ByteArray, "[B"); // yes, that's the Java class for a byte[].
|
||||
}
|
||||
|
||||
override public function createObject (ins :ObjectInputStream) :Object
|
||||
{
|
||||
var bytes :ByteArray = new ByteArray();
|
||||
bytes.length = ins.readInt();
|
||||
return bytes;
|
||||
}
|
||||
|
||||
override public function writeObject (obj :Object, out :ObjectOutputStream) :void
|
||||
{
|
||||
var bytes :ByteArray = (obj as ByteArray);
|
||||
out.writeInt(bytes.length);
|
||||
out.writeBytes(bytes);
|
||||
}
|
||||
|
||||
override public function readObject (obj :Object, ins :ObjectInputStream) :void
|
||||
{
|
||||
var bytes :ByteArray = (obj as ByteArray);
|
||||
if (bytes.length > 0) {
|
||||
ins.readBytes(bytes, 0, bytes.length);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,52 @@
|
||||
//
|
||||
// $Id$
|
||||
//
|
||||
// Narya library - tools for developing networked games
|
||||
// Copyright (C) 2002-2010 Three Rings Design, Inc., All Rights Reserved
|
||||
// http://code.google.com/p/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.io.streamers {
|
||||
|
||||
import com.threerings.util.ByteEnum;
|
||||
|
||||
import com.threerings.io.ObjectInputStream;
|
||||
import com.threerings.io.ObjectOutputStream;
|
||||
import com.threerings.io.Streamer;
|
||||
|
||||
public class ByteEnumStreamer extends Streamer
|
||||
{
|
||||
public function ByteEnumStreamer (enumClass :Class, jname :String = null)
|
||||
{
|
||||
super(enumClass, jname);
|
||||
}
|
||||
|
||||
override public function createObject (ins :ObjectInputStream) :Object
|
||||
{
|
||||
return ByteEnum.fromByte(_target, ins.readByte());
|
||||
}
|
||||
|
||||
override public function writeObject (obj :Object, out :ObjectOutputStream) :void
|
||||
{
|
||||
out.writeByte(ByteEnum(obj).toByte());
|
||||
}
|
||||
|
||||
override public function readObject (obj :Object, ins :ObjectInputStream) :void
|
||||
{
|
||||
// unneeded, done in createObject
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,52 @@
|
||||
//
|
||||
// $Id$
|
||||
//
|
||||
// Narya library - tools for developing networked games
|
||||
// Copyright (C) 2002-2010 Three Rings Design, Inc., All Rights Reserved
|
||||
// http://code.google.com/p/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.io.streamers {
|
||||
|
||||
import com.threerings.util.Enum;
|
||||
|
||||
import com.threerings.io.ObjectInputStream;
|
||||
import com.threerings.io.ObjectOutputStream;
|
||||
import com.threerings.io.Streamer;
|
||||
|
||||
public class EnumStreamer extends Streamer
|
||||
{
|
||||
public function EnumStreamer (enumClass :Class, jname :String = null)
|
||||
{
|
||||
super(enumClass, jname);
|
||||
}
|
||||
|
||||
override public function createObject (ins :ObjectInputStream) :Object
|
||||
{
|
||||
return Enum.valueOf(_target, ins.readUTF());
|
||||
}
|
||||
|
||||
override public function writeObject (obj :Object, out :ObjectOutputStream) :void
|
||||
{
|
||||
out.writeUTF((obj as Enum).name());
|
||||
}
|
||||
|
||||
override public function readObject (obj :Object, ins :ObjectInputStream) :void
|
||||
{
|
||||
// unneeded, done in createObject
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,81 @@
|
||||
//
|
||||
// $Id$
|
||||
//
|
||||
// Narya library - tools for developing networked games
|
||||
// Copyright (C) 2002-2010 Three Rings Design, Inc., All Rights Reserved
|
||||
// http://code.google.com/p/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.io.streamers {
|
||||
|
||||
import com.threerings.io.ObjectInputStream;
|
||||
import com.threerings.io.ObjectOutputStream;
|
||||
import com.threerings.io.Streamer;
|
||||
|
||||
import com.threerings.util.ClassUtil;
|
||||
|
||||
import com.threerings.util.Map;
|
||||
import com.threerings.util.Maps;
|
||||
|
||||
/**
|
||||
* Streamer for Maps.
|
||||
*/
|
||||
public class MapStreamer extends Streamer
|
||||
{
|
||||
public static const INSTANCE :MapStreamer = new MapStreamer();
|
||||
|
||||
public static const DEFAULT_MAP :Map = Maps.newBuilder(Object).makeImmutable().build();
|
||||
|
||||
public function MapStreamer ()
|
||||
{
|
||||
super(Map, "java.util.HashMap");
|
||||
}
|
||||
|
||||
override public function createObject (ins :ObjectInputStream) :Object
|
||||
{
|
||||
var size :int = ins.readInt();
|
||||
var map :Map;
|
||||
if (size > 0) {
|
||||
// guess the type of map based on the first key
|
||||
var key :Object = ins.readObject();
|
||||
map = Maps.newMapOf(ClassUtil.getClass(key));
|
||||
map.put(key, ins.readObject());
|
||||
for (var ii :int = 1; ii < size; ii++) {
|
||||
map.put(ins.readObject(), ins.readObject());
|
||||
}
|
||||
} else {
|
||||
// oh crap
|
||||
map = DEFAULT_MAP;
|
||||
}
|
||||
return map;
|
||||
}
|
||||
|
||||
override public function readObject (obj :Object, ins :ObjectInputStream) :void
|
||||
{
|
||||
// nada
|
||||
}
|
||||
|
||||
override public function writeObject (obj :Object, out :ObjectOutputStream) :void
|
||||
{
|
||||
var map :Map = Map(obj);
|
||||
out.writeInt(map.size());
|
||||
map.forEach(function (key :Object, value :Object) :void {
|
||||
out.writeObject(key);
|
||||
out.writeObject(value);
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,54 @@
|
||||
//
|
||||
// $Id$
|
||||
//
|
||||
// Narya library - tools for developing networked games
|
||||
// Copyright (C) 2002-2010 Three Rings Design, Inc., All Rights Reserved
|
||||
// http://code.google.com/p/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.io.streamers {
|
||||
|
||||
import com.threerings.io.ObjectInputStream;
|
||||
import com.threerings.io.ObjectOutputStream;
|
||||
import com.threerings.io.Streamer;
|
||||
|
||||
/**
|
||||
* A Streamer for Number objects.
|
||||
*/
|
||||
public class NumberStreamer extends Streamer
|
||||
{
|
||||
public function NumberStreamer ()
|
||||
{
|
||||
super(Number, "java.lang.Double");
|
||||
}
|
||||
|
||||
override public function createObject (ins :ObjectInputStream) :Object
|
||||
{
|
||||
return ins.readDouble();
|
||||
}
|
||||
|
||||
override public function writeObject (obj :Object, out :ObjectOutputStream) :void
|
||||
{
|
||||
var n :Number = (obj as Number);
|
||||
out.writeDouble(n);
|
||||
}
|
||||
|
||||
override public function readObject (obj :Object, ins :ObjectInputStream) :void
|
||||
{
|
||||
// nothing here, the Number is fully read in createObject()
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,80 @@
|
||||
//
|
||||
// $Id$
|
||||
//
|
||||
// Narya library - tools for developing networked games
|
||||
// Copyright (C) 2002-2010 Three Rings Design, Inc., All Rights Reserved
|
||||
// http://code.google.com/p/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.io.streamers {
|
||||
|
||||
import com.threerings.io.ObjectInputStream;
|
||||
import com.threerings.io.ObjectOutputStream;
|
||||
import com.threerings.io.Streamer;
|
||||
|
||||
import com.threerings.util.ClassUtil;
|
||||
|
||||
import com.threerings.util.Set;
|
||||
import com.threerings.util.Sets;
|
||||
|
||||
/**
|
||||
* Streamer for Sets.
|
||||
*/
|
||||
public class SetStreamer extends Streamer
|
||||
{
|
||||
public static const INSTANCE :SetStreamer = new SetStreamer();
|
||||
|
||||
public static const DEFAULT_SET :Set = Sets.newBuilder(Object).makeImmutable().build();
|
||||
|
||||
public function SetStreamer ()
|
||||
{
|
||||
super(Set, "java.util.HashSet");
|
||||
}
|
||||
|
||||
override public function createObject (ins :ObjectInputStream) :Object
|
||||
{
|
||||
var size :int = ins.readInt();
|
||||
var set :Set;
|
||||
if (size > 0) {
|
||||
// guess the type of set based on the first value
|
||||
var first :Object = ins.readObject();
|
||||
set = Sets.newSetOf(ClassUtil.getClass(first));
|
||||
set.add(first);
|
||||
for (var ii :int = 1; ii < size; ii++) {
|
||||
set.add(ins.readObject());
|
||||
}
|
||||
} else {
|
||||
// oh crap
|
||||
set = DEFAULT_SET;
|
||||
}
|
||||
return set;
|
||||
}
|
||||
|
||||
override public function readObject (obj :Object, ins :ObjectInputStream) :void
|
||||
{
|
||||
// nada
|
||||
}
|
||||
|
||||
override public function writeObject (obj :Object, out :ObjectOutputStream) :void
|
||||
{
|
||||
var set :Set = Set(obj);
|
||||
out.writeInt(set.size());
|
||||
set.forEach(function (value :Object) :void {
|
||||
out.writeObject(value);
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user