Checkpoint: converting parlor stuff to actionscript.
git-svn-id: svn+ssh://src.earth.threerings.net/vilya/trunk@30 c613c5cb-e716-0410-b11b-feb51c14d237
This commit is contained in:
@@ -0,0 +1,123 @@
|
||||
//
|
||||
// $Id$
|
||||
//
|
||||
// Narya library - tools for developing networked games
|
||||
// Copyright (C) 2002-2005 Three Rings Design, Inc., All Rights Reserved
|
||||
// http://www.threerings.net/code/narya/
|
||||
//
|
||||
// This library is free software; you can redistribute it and/or modify it
|
||||
// under the terms of the GNU Lesser General Public License as published
|
||||
// by the Free Software Foundation; either version 2.1 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This library is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
// Lesser General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public
|
||||
// License along with this library; if not, write to the Free Software
|
||||
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
package com.threerings.parlor.client {
|
||||
|
||||
import mx.controls.CheckBox;
|
||||
import mx.controls.HSlider;
|
||||
import mx.controls.Label;
|
||||
|
||||
import com.threerings.parlor.data.TableConfig;
|
||||
import com.threerings.parlor.util.ParlorContext;
|
||||
|
||||
import com.threerings.parlor.game.client.FlexGameConfigurator;
|
||||
import com.threerings.parlor.game.data.GameConfig;
|
||||
|
||||
/**
|
||||
* Provides a default implementation of a TableConfigurator for
|
||||
* a Swing interface.
|
||||
*/
|
||||
public class DefaultFlexTableConfigurator extends TableConfigurator
|
||||
{
|
||||
/**
|
||||
* Create a TableConfigurator that allows for the specified configuration
|
||||
* parameters.
|
||||
*/
|
||||
public function DefaultSwingTableConfigurator (
|
||||
desiredPlayers :int, minPlayers :int = -1, maxPlayers :int = -1,
|
||||
allowPrivate :Boolean = false)
|
||||
{
|
||||
if (minPlayers < 0) {
|
||||
minPlayers = desiredPlayers;
|
||||
}
|
||||
if (maxPlayers < 0) {
|
||||
maxPlayers = desiredPlayers;
|
||||
}
|
||||
|
||||
_config.minimumPlayerCount = minPlayers;
|
||||
|
||||
// create a slider for players, if applicable
|
||||
if (minPlayers != maxPlayers) {
|
||||
_playerSlider = new HSlider();
|
||||
_playerSlider.value = desiredPlayers;
|
||||
_playerSlider.minimum = minPlayers;
|
||||
_playerSlider.maximum = maxPlayers;
|
||||
|
||||
} else {
|
||||
_config.desiredPlayerCount = desiredPlayers;
|
||||
}
|
||||
|
||||
// create up the checkbox for private games, if applicable
|
||||
if (allowPrivate) {
|
||||
_privateCheck = new CheckBox();
|
||||
}
|
||||
}
|
||||
|
||||
// documentation inherited
|
||||
protected function createConfigInterface () :void
|
||||
{
|
||||
super.createConfigInterface();
|
||||
|
||||
var gconf :FlexGameConfigurator =
|
||||
(_gameConfigurator as FlexGameConfigurator);
|
||||
|
||||
if (_playerSlider != null) {
|
||||
// TODO: proper translation
|
||||
var playerLabel :Label = new Label();
|
||||
playerLabel.text = "Players:";
|
||||
gconf.addControl(playerLabel, _playerSlider);
|
||||
}
|
||||
|
||||
if (_privateCheck != null) {
|
||||
// TODO: proper translation
|
||||
var privateLabel :Label = new Label();
|
||||
privateLabel.text = "Private:";
|
||||
gconf.addControl(privateLabel, _privateCheck);
|
||||
}
|
||||
}
|
||||
|
||||
// documentation inherited
|
||||
override public function isEmpty () :Boolean
|
||||
{
|
||||
return (_playerSlider == null) && (_privateCheck == null);
|
||||
}
|
||||
|
||||
// documentation inherited
|
||||
override protected function flushTableConfig() :void
|
||||
{
|
||||
super.flushTableConfig();
|
||||
|
||||
if (_playerSlider != null) {
|
||||
_config.desiredPlayerCount = _playerSlider.value;
|
||||
}
|
||||
if (_privateCheck != null) {
|
||||
_config.privateTable = _privateCheck.selected;
|
||||
}
|
||||
}
|
||||
|
||||
/** A slider for configuring the number of players at the table. */
|
||||
protected var _playerSlider :HSlider;
|
||||
|
||||
/** A checkbox to allow the table creator to specify if the table is
|
||||
* private. */
|
||||
protected var _privateCheck :CheckBox;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,44 @@
|
||||
//
|
||||
// $Id: GameReadyObserver.java 4191 2006-06-13 22:42:20Z ray $
|
||||
//
|
||||
// Narya library - tools for developing networked games
|
||||
// Copyright (C) 2002-2004 Three Rings Design, Inc., All Rights Reserved
|
||||
// http://www.threerings.net/code/narya/
|
||||
//
|
||||
// This library is free software; you can redistribute it and/or modify it
|
||||
// under the terms of the GNU Lesser General Public License as published
|
||||
// by the Free Software Foundation; either version 2.1 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This library is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
// Lesser General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public
|
||||
// License along with this library; if not, write to the Free Software
|
||||
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
package com.threerings.parlor.client {
|
||||
|
||||
/**
|
||||
* Used to inform interested parties when the {@link ParlorDirector}
|
||||
* receives a game ready notification. The observers can ratify the
|
||||
* decision to head directly into the game or can take responsibility
|
||||
* themselves for doing so.
|
||||
*/
|
||||
public interface GameReadyObserver
|
||||
{
|
||||
/**
|
||||
* Called when a game ready notification is received.
|
||||
*
|
||||
* @param gameOid the place oid of the ready game.
|
||||
*
|
||||
* @return if the observer returns true from this method, the parlor
|
||||
* director assumes they will take care of entering the game room
|
||||
* after performing processing of their own. If all observers return
|
||||
* false, the director will enter the game room automatically.
|
||||
*/
|
||||
function receivedGameReady (gameOid :int) :Boolean;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,214 @@
|
||||
//
|
||||
// $Id: Invitation.java 3381 2005-03-03 19:36:34Z mdb $
|
||||
//
|
||||
// Narya library - tools for developing networked games
|
||||
// Copyright (C) 2002-2004 Three Rings Design, Inc., All Rights Reserved
|
||||
// http://www.threerings.net/code/narya/
|
||||
//
|
||||
// This library is free software; you can redistribute it and/or modify it
|
||||
// under the terms of the GNU Lesser General Public License as published
|
||||
// by the Free Software Foundation; either version 2.1 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This library is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
// Lesser General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public
|
||||
// License along with this library; if not, write to the Free Software
|
||||
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
package com.threerings.parlor.client {
|
||||
|
||||
import com.threerings.util.Name;
|
||||
|
||||
import com.threerings.parlor.data.ParlorCodes;
|
||||
import com.threerings.parlor.game.data.GameConfig;
|
||||
import com.threerings.parlor.util.ParlorContext;
|
||||
|
||||
/**
|
||||
* The invitation class is used to track information related to
|
||||
* outstanding invitations generated by or targeted to this client.
|
||||
*/
|
||||
public class Invitation
|
||||
implements ParlorCodes, ParlorService_InviteListener
|
||||
{
|
||||
/** The unique id for this invitation (as assigned by the
|
||||
* server). This is -1 until we receive an acknowledgement from
|
||||
* the server that our invitation was delivered. */
|
||||
public var inviteId :int = -1;
|
||||
|
||||
/** The name of the other user involved in this invitation. */
|
||||
public var opponent :Name;
|
||||
|
||||
/** The configuration of the game to be created. */
|
||||
public var config :GameConfig;
|
||||
|
||||
/** Constructs a new invitation record. */
|
||||
public function Invitation (
|
||||
ctx :ParlorContext, pservice :ParlorService,
|
||||
opponent :Name, config :GameConfig,
|
||||
observer :InvitationResponseObserver)
|
||||
{
|
||||
_ctx = ctx;
|
||||
_pservice = pservice;
|
||||
_observer = observer;
|
||||
this.opponent = opponent;
|
||||
this.config = config;
|
||||
}
|
||||
|
||||
/**
|
||||
* Accepts this invitation.
|
||||
*/
|
||||
public function accept () :void
|
||||
{
|
||||
// generate the invocation service request
|
||||
_pservice.respond(_ctx.getClient(), inviteId,
|
||||
INVITATION_ACCEPTED, null, this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Refuses this invitation.
|
||||
*
|
||||
* @param message the message to deliver to the inviting user
|
||||
* explaining the reason for the refusal or null if no message is to
|
||||
* be provided.
|
||||
*/
|
||||
public function refuse (message :String) :void
|
||||
{
|
||||
// generate the invocation service request
|
||||
_pservice.respond(_ctx.getClient(), inviteId,
|
||||
INVITATION_REFUSED, message, this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Cancels this invitation.
|
||||
*/
|
||||
public function cancel () :void
|
||||
{
|
||||
// if the invitation has not yet been acknowleged by the
|
||||
// server, we make a note that it should be cancelled when we
|
||||
// do receive the acknowlegement
|
||||
if (inviteId == -1) {
|
||||
_cancelled = true;
|
||||
|
||||
} else {
|
||||
// otherwise, generate the invocation service request
|
||||
_pservice.cancel(_ctx.getClient(), inviteId, this);
|
||||
// and remove it from the pending table
|
||||
_ctx.getParlorDirector().clearInvitation(this);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Counters this invitation with an invitation with different game
|
||||
* configuration parameters.
|
||||
*
|
||||
* @param config the updated game configuration.
|
||||
* @param observer the entity that will be notified if this
|
||||
* counter-invitation is accepted, refused or countered.
|
||||
*/
|
||||
public function counter (
|
||||
config :GameConfig, observer :InvitationResponseObserver) :void
|
||||
{
|
||||
// update our observer (who will eventually be hearing back from
|
||||
// the other client about their counter-invitation)
|
||||
_observer = observer;
|
||||
|
||||
// generate the invocation service request
|
||||
_pservice.respond(_ctx.getClient(), inviteId,
|
||||
INVITATION_COUNTERED, config, this);
|
||||
}
|
||||
|
||||
// documentation inherited from interface
|
||||
public function inviteReceived (inviteId :int) :void
|
||||
{
|
||||
// fill in our invitation id
|
||||
this.inviteId = inviteId;
|
||||
|
||||
// if the invitation was cancelled before we heard back about
|
||||
// it, we need to send off a cancellation request now
|
||||
if (_cancelled) {
|
||||
_pservice.cancel(_ctx.getClient(), inviteId, this);
|
||||
} else {
|
||||
// otherwise, put it in the pending invites table
|
||||
_ctx.getParlorDirector().registerInvitation(this);
|
||||
}
|
||||
}
|
||||
|
||||
// documentation inherited from interface
|
||||
public function requestFailed (reason :String) :void
|
||||
{
|
||||
// let the observer know what's up
|
||||
_observer.invitationRefused(this, reason);
|
||||
}
|
||||
|
||||
/**
|
||||
* Called by the parlor director when we receive a response to an
|
||||
* invitation initiated by this client.
|
||||
*/
|
||||
protected function receivedResponse (code :int, arg :Object) :void
|
||||
{
|
||||
// make sure we have an observer to notify
|
||||
if (_observer == null) {
|
||||
Log.getLog(this).warning("No observer registered for invitation " +
|
||||
this + ".");
|
||||
return;
|
||||
}
|
||||
|
||||
// notify the observer
|
||||
try {
|
||||
switch (code) {
|
||||
case INVITATION_ACCEPTED:
|
||||
_observer.invitationAccepted(this);
|
||||
break;
|
||||
|
||||
case INVITATION_REFUSED:
|
||||
_observer.invitationRefused(this, (arg as String));
|
||||
break;
|
||||
|
||||
case INVITATION_COUNTERED:
|
||||
_observer.invitationCountered(this, (arg as GameConfig));
|
||||
break;
|
||||
}
|
||||
|
||||
} catch (err :Error) {
|
||||
var log :Log = Log.getLog(this);
|
||||
log.warning("Invitation response observer choked on response " +
|
||||
"[code=" + code + ", arg=" + arg +
|
||||
", invite=" + this + "].");
|
||||
log.logStackTrace(e);
|
||||
}
|
||||
|
||||
// unless the invitation was countered, we can remove it from the
|
||||
// pending table because it's resolved
|
||||
if (code != INVITATION_COUNTERED) {
|
||||
_ctx.getParlorDirector().clearInvitation(this);
|
||||
}
|
||||
}
|
||||
|
||||
/** Returns a string representation of this invitation record. */
|
||||
public function toString () :String
|
||||
{
|
||||
return "[inviteId=" + inviteId + ", opponent=" + opponent +
|
||||
", config=" + config + ", observer=" + _observer +
|
||||
", cancelled=" + _cancelled + "]";
|
||||
}
|
||||
|
||||
/** Provides access to client services. */
|
||||
protected var _ctx :ParlorContext;
|
||||
|
||||
/** Provides access to parlor services. */
|
||||
protected var _pservice :ParlorService;
|
||||
|
||||
/** The entity to notify when we receive a response for this
|
||||
* invitation. */
|
||||
protected var _observer :InvitationResponseObserver;
|
||||
|
||||
/** A flag indicating that we were requested to cancel this
|
||||
* invitation before we even heard back with an acknowledgement
|
||||
* that it was received by the server. */
|
||||
protected var _cancelled :Boolean = false;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
//
|
||||
// $Id: InvitationHandler.java 4191 2006-06-13 22:42:20Z ray $
|
||||
//
|
||||
// Narya library - tools for developing networked games
|
||||
// Copyright (C) 2002-2004 Three Rings Design, Inc., All Rights Reserved
|
||||
// http://www.threerings.net/code/narya/
|
||||
//
|
||||
// This library is free software; you can redistribute it and/or modify it
|
||||
// under the terms of the GNU Lesser General Public License as published
|
||||
// by the Free Software Foundation; either version 2.1 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This library is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
// Lesser General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public
|
||||
// License along with this library; if not, write to the Free Software
|
||||
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
package com.threerings.parlor.client {
|
||||
|
||||
/**
|
||||
* A client entity that wishes to handle invitations received by other
|
||||
* clients should implement this interface and register itself with the
|
||||
* parlor director. It will subsequently be notified of any incoming
|
||||
* invitations. It is also responsible for handling cancelled invitations.
|
||||
*/
|
||||
public interface InvitationHandler
|
||||
{
|
||||
/**
|
||||
* Called when an invitation is received from another player.
|
||||
*
|
||||
* @param invite the received invitation.
|
||||
*/
|
||||
function invitationReceived (invite :Invitation) :void;
|
||||
|
||||
/**
|
||||
* Called when an invitation is cancelled by the inviting player.
|
||||
*
|
||||
* @param invite the cancelled invitation.
|
||||
*/
|
||||
function invitationCancelled (invite :Invitation) :void;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,62 @@
|
||||
//
|
||||
// $Id: InvitationResponseObserver.java 3381 2005-03-03 19:36:34Z mdb $
|
||||
//
|
||||
// Narya library - tools for developing networked games
|
||||
// Copyright (C) 2002-2004 Three Rings Design, Inc., All Rights Reserved
|
||||
// http://www.threerings.net/code/narya/
|
||||
//
|
||||
// This library is free software; you can redistribute it and/or modify it
|
||||
// under the terms of the GNU Lesser General Public License as published
|
||||
// by the Free Software Foundation; either version 2.1 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This library is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
// Lesser General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public
|
||||
// License along with this library; if not, write to the Free Software
|
||||
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
package com.threerings.parlor.client {
|
||||
|
||||
import com.threerings.parlor.game.data.GameConfig;
|
||||
|
||||
/**
|
||||
* A client entity that wishes to generate invitations for games must
|
||||
* implement this interface. An invitation can be accepted, refused or
|
||||
* countered. A countered invitation is one where the game configuration
|
||||
* is adjusted by the invited player and proposed back to the inviting
|
||||
* player.
|
||||
*/
|
||||
public interface InvitationResponseObserver
|
||||
{
|
||||
/**
|
||||
* Called if the invitation was accepted.
|
||||
*
|
||||
* @param invite the invitation for which we received a response.
|
||||
*/
|
||||
function invitationAccepted (invite :Invitation) :void;
|
||||
|
||||
/**
|
||||
* Called if the invitation was refused.
|
||||
*
|
||||
* @param invite the invitation for which we received a response.
|
||||
* @param message a message provided by the invited user explaining
|
||||
* the reason for their refusal, or the empty string if no message was
|
||||
* provided.
|
||||
*/
|
||||
function invitationRefused (invite :Invitation, message :String) :void;
|
||||
|
||||
/**
|
||||
* Called if the invitation was countered with an alternate game
|
||||
* configuration.
|
||||
*
|
||||
* @param invite the invitation for which we received a response.
|
||||
* @param config the game configuration proposed by the invited
|
||||
* player.
|
||||
*/
|
||||
function invitationCountered (invite :Invitation, config :GameConfig) :void;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,103 @@
|
||||
//
|
||||
// $Id: ParlorDecoder.java 4145 2006-05-24 01:24:24Z ray $
|
||||
//
|
||||
// Narya library - tools for developing networked games
|
||||
// Copyright (C) 2002-2006 Three Rings Design, Inc., All Rights Reserved
|
||||
// http://www.threerings.net/code/narya/
|
||||
//
|
||||
// This library is free software; you can redistribute it and/or modify it
|
||||
// under the terms of the GNU Lesser General Public License as published
|
||||
// by the Free Software Foundation; either version 2.1 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This library is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
// Lesser General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public
|
||||
// License along with this library; if not, write to the Free Software
|
||||
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
package com.threerings.parlor.client {
|
||||
|
||||
import com.threerings.parlor.client.ParlorReceiver;
|
||||
import com.threerings.parlor.game.data.GameConfig;
|
||||
import com.threerings.presents.client.InvocationDecoder;
|
||||
import com.threerings.util.Name;
|
||||
|
||||
/**
|
||||
* Dispatches calls to a {@link ParlorReceiver} instance.
|
||||
*/
|
||||
public class ParlorDecoder extends InvocationDecoder
|
||||
{
|
||||
/** The generated hash code used to identify this receiver class. */
|
||||
public static const RECEIVER_CODE :String = "5ef9ee0d359c42a9024498ee9aad119a";
|
||||
|
||||
/** The method id used to dispatch {@link ParlorReceiver#gameIsReady}
|
||||
* notifications. */
|
||||
public static const GAME_IS_READY :int = 1;
|
||||
|
||||
/** The method id used to dispatch {@link ParlorReceiver#receivedInvite}
|
||||
* notifications. */
|
||||
public static const RECEIVED_INVITE :int = 2;
|
||||
|
||||
/** The method id used to dispatch {@link ParlorReceiver#receivedInviteCancellation}
|
||||
* notifications. */
|
||||
public static const RECEIVED_INVITE_CANCELLATION :int = 3;
|
||||
|
||||
/** The method id used to dispatch {@link ParlorReceiver#receivedInviteResponse}
|
||||
* notifications. */
|
||||
public static const RECEIVED_INVITE_RESPONSE :int = 4;
|
||||
|
||||
/**
|
||||
* Creates a decoder that may be registered to dispatch invocation
|
||||
* service notifications to the specified receiver.
|
||||
*/
|
||||
public function ParlorDecoder (receiver :ParlorReceiver)
|
||||
{
|
||||
this.receiver = receiver;
|
||||
}
|
||||
|
||||
// documentation inherited
|
||||
override public function getReceiverCode () :String
|
||||
{
|
||||
return RECEIVER_CODE;
|
||||
}
|
||||
|
||||
// documentation inherited
|
||||
override public function dispatchNotification (
|
||||
methodId :int, args :Array) :void
|
||||
{
|
||||
var prec :ParlorReceiver = (receiver as ParlorReceiver);
|
||||
switch (methodId) {
|
||||
case GAME_IS_READY:
|
||||
prec.gameIsReady((args[0] as Integer).value);
|
||||
return;
|
||||
|
||||
case RECEIVED_INVITE:
|
||||
prec.receivedInvite(
|
||||
(args[0] as Integer).value, (args[1] as Name),
|
||||
(args[2] as GameConfig)
|
||||
);
|
||||
return;
|
||||
|
||||
case RECEIVED_INVITE_CANCELLATION:
|
||||
prec.receivedInviteCancellation(
|
||||
(args[0] as Integer).value
|
||||
);
|
||||
return;
|
||||
|
||||
case RECEIVED_INVITE_RESPONSE:
|
||||
prec.receivedInviteResponse(
|
||||
(args[0] as Integer).value, (args[1] as Integer).value, args[2]
|
||||
);
|
||||
return;
|
||||
|
||||
default:
|
||||
super.dispatchNotification(methodId, args);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,252 @@
|
||||
//
|
||||
// $Id: ParlorDirector.java 3381 2005-03-03 19:36:34Z mdb $
|
||||
//
|
||||
// Narya library - tools for developing networked games
|
||||
// Copyright (C) 2002-2004 Three Rings Design, Inc., All Rights Reserved
|
||||
// http://www.threerings.net/code/narya/
|
||||
//
|
||||
// This library is free software; you can redistribute it and/or modify it
|
||||
// under the terms of the GNU Lesser General Public License as published
|
||||
// by the Free Software Foundation; either version 2.1 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This library is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
// Lesser General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public
|
||||
// License along with this library; if not, write to the Free Software
|
||||
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
package com.threerings.parlor.client {
|
||||
|
||||
import com.threerings.util.ArrayUtil;
|
||||
import com.threerings.util.HashMap;
|
||||
import com.threerings.util.Name;
|
||||
|
||||
import com.threerings.presents.client.BasicDirector;
|
||||
import com.threerings.presents.client.Client;
|
||||
import com.threerings.presents.client.InvocationService;
|
||||
|
||||
import com.threerings.parlor.Log;
|
||||
import com.threerings.parlor.data.ParlorCodes;
|
||||
import com.threerings.parlor.game.data.GameConfig;
|
||||
import com.threerings.parlor.util.ParlorContext;
|
||||
|
||||
/**
|
||||
* The parlor director manages the client side of the game configuration
|
||||
* and matchmaking processes. It is also the entity that is listening for
|
||||
* game start notifications which it then dispatches the client entity
|
||||
* that will actually create and display the user interface for the game
|
||||
* that started.
|
||||
*/
|
||||
public class ParlorDirector extends BasicDirector
|
||||
implements ParlorCodes, ParlorReceiver
|
||||
{
|
||||
/**
|
||||
* Constructs a parlor director and provides it with the parlor
|
||||
* context that it can use to access the client services that it needs
|
||||
* to provide its own services. Only one parlor director should be
|
||||
* active in the client at one time and it should be made available
|
||||
* via the parlor context.
|
||||
*
|
||||
* @param ctx the parlor context in use by the client.
|
||||
*/
|
||||
public function ParlorDirector (ctx :ParlorContext)
|
||||
{
|
||||
super(ctx);
|
||||
_pctx = ctx;
|
||||
|
||||
// register ourselves with the invocation director as a parlor
|
||||
// notification receiver
|
||||
_pctx.getClient().getInvocationDirector().registerReceiver(
|
||||
new ParlorDecoder(this));
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the invitation handler, which is the entity that will be
|
||||
* notified when we receive incoming invitation notifications and when
|
||||
* invitations have been cancelled.
|
||||
*
|
||||
* @param handler our new invitation handler.
|
||||
*/
|
||||
public function setInvitationHandler (handler :InvitationHandler) :void
|
||||
{
|
||||
_handler = handler;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds the specified observer to the list of entities that are
|
||||
* notified when we receive a game ready notification.
|
||||
*/
|
||||
public function addGameReadyObserver (observer :GameReadyObserver) :void
|
||||
{
|
||||
_grobs.add(observer);
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes the specified observer from the list of entities that are
|
||||
* notified when we receive a game ready notification.
|
||||
*/
|
||||
public function removeGameReadyObserver (observer :GameReadyObserver) :void
|
||||
{
|
||||
ArrayUtil.removeFirst(_grobs, observer);
|
||||
}
|
||||
|
||||
/**
|
||||
* Requests that the named user be invited to a game described by the
|
||||
* supplied game config.
|
||||
*
|
||||
* @param invitee the user to invite.
|
||||
* @param config the configuration of the game to which the user is
|
||||
* being invited.
|
||||
* @param observer the entity that will be notified if this invitation
|
||||
* is accepted, refused or countered.
|
||||
*
|
||||
* @return an invitation object that can be used to manage the
|
||||
* outstanding invitation.
|
||||
*/
|
||||
public function invite (
|
||||
invitee :Name, config :GameConfig,
|
||||
observer :InvitationResponseObserver) :Invitation
|
||||
{
|
||||
// create the invitation record
|
||||
var invite :Invitation = new Invitation(
|
||||
_ctx, _pservice, invitee, config, observer);
|
||||
// submit the invitation request to the server
|
||||
_pservice.invite(_ctx.getClient(), invitee, config, invite);
|
||||
// and return the invitation to the caller
|
||||
return invite;
|
||||
}
|
||||
|
||||
/**
|
||||
* Requests that the specified single player game be started.
|
||||
*
|
||||
* @param config the configuration of the single player game to be
|
||||
* started.
|
||||
* @param listener a listener to be informed of failure if the game
|
||||
* cannot be started.
|
||||
*/
|
||||
public function startSolitaire (
|
||||
config :GameConfig, listener :InvocationService.ConfirmListener) :void
|
||||
{
|
||||
_pservice.startSolitaire(_ctx.getClient(), config, listener);
|
||||
}
|
||||
|
||||
// documentation inherited
|
||||
public function clientDidLogoff (event :ClientEvent) :void
|
||||
{
|
||||
super.clientDidLogoff(event);
|
||||
_pservice = null;
|
||||
_pendingInvites.clear();
|
||||
}
|
||||
|
||||
// documentation inherited
|
||||
protected function fetchServices (client :Client) :void
|
||||
{
|
||||
// get a handle on our parlor services
|
||||
_pservice = (client.requireService(ParlorService) as ParlorService);
|
||||
}
|
||||
|
||||
// documentation inherited from interface
|
||||
public function gameIsReady (gameOid :int) :void
|
||||
{
|
||||
Log.getLog(this).info("Handling game ready [goid=" + gameOid + "].");
|
||||
|
||||
// see what our observers have to say about it
|
||||
var handled :Boolean = false;
|
||||
for (var ii :int = 0; ii < _grobs.length; ii++) {
|
||||
var grob :GameReadyObserver = (_grobs[ii] as GameReadyObserver);
|
||||
handled = grob.receivedGameReady(gameOid) || handled;
|
||||
}
|
||||
|
||||
// if none of the observers took matters into their own hands,
|
||||
// then we'll head on over to the game room ourselves
|
||||
if (!handled) {
|
||||
_ctx.getLocationDirector().moveTo(gameOid);
|
||||
}
|
||||
}
|
||||
|
||||
// documentation inherited from interface
|
||||
public function receivedInvite (
|
||||
remoteId :int, inviter :Name, config :GameConfig) :void
|
||||
{
|
||||
// create an invitation record for this invitation
|
||||
invite :Invitation = new Invitation(
|
||||
_ctx, _pservice, inviter, config, null);
|
||||
invite.inviteId = remoteId;
|
||||
|
||||
// put it in the pending invitations table
|
||||
_pendingInvites.put(remoteId, invite);
|
||||
|
||||
try {
|
||||
// notify the invitation handler of the incoming invitation
|
||||
_handler.invitationReceived(invite);
|
||||
|
||||
} catch (err :Error) {
|
||||
var log :Log = Log.getLog(this);
|
||||
log.warning("Invitation handler choked on invite " +
|
||||
"notification " + invite + ".");
|
||||
log.logStackTrace(err);
|
||||
}
|
||||
}
|
||||
|
||||
// documentation inherited from interface
|
||||
public function receivedInviteResponse (
|
||||
remoteId :int, code :int, arg :Object) :void
|
||||
{
|
||||
// look up the invitation record for this invitation
|
||||
var invite :Invitation = (_pendingInvites.get(remoteId) as Invitation);
|
||||
if (invite == null) {
|
||||
Log.getLog(this).warning("Have no record of invitation for " +
|
||||
"which we received a response?! [remoteId=" + remoteId +
|
||||
", code=" + code + ", arg=" + arg + "].");
|
||||
|
||||
} else {
|
||||
invite.receivedResponse(code, arg);
|
||||
}
|
||||
}
|
||||
|
||||
// documentation inherited from interface
|
||||
public function receivedInviteCancellation (remoteId :int) :void
|
||||
{
|
||||
// TBD
|
||||
}
|
||||
|
||||
/**
|
||||
* Register a new invitation in our pending invitations table. The
|
||||
* invitation will call this when it knows its invitation id.
|
||||
*/
|
||||
protected function registerInvitation (invite :Invitation) :void
|
||||
{
|
||||
_pendingInvites.put(invite.inviteId, invite);
|
||||
}
|
||||
|
||||
/**
|
||||
* Called by an invitation when it knows it is no longer and can be
|
||||
* cleared from the pending invitations table.
|
||||
*/
|
||||
protected function clearInvitation (invite :Invitation) :void
|
||||
{
|
||||
_pendingInvites.remove(invite.inviteId);
|
||||
}
|
||||
|
||||
/** An active parlor context. */
|
||||
protected var _pctx :ParlorContext;
|
||||
|
||||
/** Provides access to parlor server side services. */
|
||||
protected var _pservice :ParlorService;
|
||||
|
||||
/** The entity that has registered itself to handle incoming
|
||||
* invitation notifications. */
|
||||
protected var _handler :InvitationHandler;
|
||||
|
||||
/** A table of acknowledged (but not yet accepted or refused)
|
||||
* invitation requests, keyed on invitation id. */
|
||||
protected var _pendingInvites :HashMap = new HashMap();
|
||||
|
||||
/** We notify the entities on this list when we get a game ready
|
||||
* notification. */
|
||||
protected var _grobs :Array = new Array();
|
||||
}
|
||||
@@ -0,0 +1,85 @@
|
||||
//
|
||||
// $Id: ParlorReceiver.java 3381 2005-03-03 19:36:34Z mdb $
|
||||
//
|
||||
// Narya library - tools for developing networked games
|
||||
// Copyright (C) 2002-2004 Three Rings Design, Inc., All Rights Reserved
|
||||
// http://www.threerings.net/code/narya/
|
||||
//
|
||||
// This library is free software; you can redistribute it and/or modify it
|
||||
// under the terms of the GNU Lesser General Public License as published
|
||||
// by the Free Software Foundation; either version 2.1 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This library is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
// Lesser General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public
|
||||
// License along with this library; if not, write to the Free Software
|
||||
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
package com.threerings.parlor.client {
|
||||
|
||||
import com.threerings.util.Name;
|
||||
|
||||
import com.threerings.presents.client.InvocationReceiver;
|
||||
|
||||
import com.threerings.parlor.data.ParlorCodes;
|
||||
import com.threerings.parlor.game.data.GameConfig;
|
||||
|
||||
/**
|
||||
* Defines, for the parlor services, a set of notifications delivered
|
||||
* asynchronously by the server to the client. These are handled by the
|
||||
* {@link ParlorDirector}.
|
||||
*/
|
||||
public interface ParlorReceiver extends InvocationReceiver
|
||||
{
|
||||
/**
|
||||
* Dispatched to the client when a game in which they are a
|
||||
* participant is ready for play. The client will then enter the game
|
||||
* room which will trigger the loading of the appropriate game UI code
|
||||
* and generally get things started.
|
||||
*
|
||||
* @param gameOid the object id of the game object.
|
||||
*/
|
||||
function gameIsReady (gameOid :int) :void;
|
||||
|
||||
/**
|
||||
* Called by the invocation services when another user has invited us
|
||||
* to play a game.
|
||||
*
|
||||
* @param remoteId the unique indentifier for this invitation (used
|
||||
* when countering or responding).
|
||||
* @param inviter the username of the inviting user.
|
||||
* @param config the configuration information for the game to which
|
||||
* we've been invited.
|
||||
*/
|
||||
function receivedInvite (remoteId :int, inviter :Name, config :GameConfig);
|
||||
|
||||
/**
|
||||
* Called by the invocation services when another user has responded
|
||||
* to our invitation by either accepting, refusing or countering it.
|
||||
*
|
||||
* @param remoteId the indentifier for the invitation on question.
|
||||
* @param code the response code, either {@link
|
||||
* ParlorCodes#INVITATION_ACCEPTED} or {@link
|
||||
* ParlorCodes#INVITATION_REFUSED} or {@link
|
||||
* ParlorCodes#INVITATION_COUNTERED}.
|
||||
* @param arg in the case of a refused invitation, a string
|
||||
* containing a message provided by the invited user explaining the
|
||||
* reason for refusal (the empty string if no explanation was
|
||||
* provided). In the case of a countered invitation, a new game config
|
||||
* object with the modified game configuration.
|
||||
*/
|
||||
function receivedInviteResponse (remoteId :int, code :int, arg :Object);
|
||||
|
||||
/**
|
||||
* Called by the invocation services when an outstanding invitation
|
||||
* has been cancelled by the inviting user.
|
||||
*
|
||||
* @param remoteId the indentifier of the cancelled invitation.
|
||||
*/
|
||||
function receivedInviteCancellation (remoteId :int);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,151 @@
|
||||
//
|
||||
// $Id: ParlorService.java 3525 2005-04-26 02:38:42Z ray $
|
||||
//
|
||||
// Narya library - tools for developing networked games
|
||||
// Copyright (C) 2002-2004 Three Rings Design, Inc., All Rights Reserved
|
||||
// http://www.threerings.net/code/narya/
|
||||
//
|
||||
// This library is free software; you can redistribute it and/or modify it
|
||||
// under the terms of the GNU Lesser General Public License as published
|
||||
// by the Free Software Foundation; either version 2.1 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This library is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
// Lesser General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public
|
||||
// License along with this library; if not, write to the Free Software
|
||||
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
package com.threerings.parlor.client {
|
||||
|
||||
import com.threerings.util.Name;
|
||||
|
||||
import com.threerings.presents.client.Client;
|
||||
import com.threerings.presents.client.InvocationService;
|
||||
|
||||
import com.threerings.parlor.data.TableConfig;
|
||||
|
||||
import com.threerings.parlor.game.data.GameConfig;
|
||||
|
||||
/**
|
||||
* Provides an interface to the various parlor invocation services.
|
||||
* Presently these services are limited to the various matchmaking
|
||||
* mechanisms. It is unlikely that client code will want to make direct
|
||||
* use of this class, instead they would make use of the programmatic
|
||||
* interface provided by the {@link ParlorDirector}.
|
||||
*/
|
||||
public interface ParlorService extends InvocationService
|
||||
{
|
||||
/**
|
||||
* You probably don't want to call this directly, but want to generate
|
||||
* your invitation request via {@link ParlorDirector#invite}. Requests
|
||||
* that an invitation be delivered to the named user, requesting that
|
||||
* they join the inviting user in a game, the details of which are
|
||||
* specified in the supplied game config object.
|
||||
*
|
||||
* @param client a connected, operational client instance.
|
||||
* @param invitee the username of the user to be invited.
|
||||
* @param config a game config object detailing the type and
|
||||
* configuration of the game to be created.
|
||||
* @param listener will receive and process the response.
|
||||
*/
|
||||
function invite (
|
||||
client :Client, invitee :Name, config :GameConfig,
|
||||
listener :InviteListener) :void;
|
||||
|
||||
/**
|
||||
* You probably don't want to call this directly, but want to call one
|
||||
* of {@link Invitation#accept}, {@link Invitation#refuse}, or {@link
|
||||
* Invitation#counter}. Requests that an invitation response be
|
||||
* delivered with the specified parameters.
|
||||
*
|
||||
* @param client a connected, operational client instance.
|
||||
* @param inviteId the unique id previously assigned by the server to
|
||||
* this invitation.
|
||||
* @param code the response code to use in responding to the
|
||||
* invitation.
|
||||
* @param arg the argument associated with the response (a string
|
||||
* message from the player explaining why the response was refused in
|
||||
* the case of an invitation refusal or an updated game configuration
|
||||
* object in the case of a counter-invitation, or null in the case of
|
||||
* an accepted invitation).
|
||||
* @param listener will receive and process the response.
|
||||
*/
|
||||
function respond (
|
||||
client :Client, inviteId :int, code :int, arg :Object,
|
||||
listener :InvocationListener) :void;
|
||||
|
||||
/**
|
||||
* You probably don't want to call this directly, but want to call
|
||||
* {@link Invitation#cancel}. Requests that an outstanding
|
||||
* invitation be cancelled.
|
||||
*
|
||||
* @param client a connected, operational client instance.
|
||||
* @param inviteId the unique id previously assigned by the server to
|
||||
* this invitation.
|
||||
* @param listener will receive and process the response.
|
||||
*/
|
||||
function cancel (
|
||||
client :Client, inviteId :int, listener :InvocationListener) :void;
|
||||
|
||||
/**
|
||||
* You probably don't want to call this directly, but want to call
|
||||
* {@link TableDirector#createTable}. Requests that a new table be
|
||||
* created.
|
||||
*
|
||||
* @param client a connected, operational client instance.
|
||||
* @param lobbyOid the oid of the lobby that will contain the newly
|
||||
* created table.
|
||||
* @param tableConfig the table configuration parameters.
|
||||
* @param config the game config for the game to be matchmade by the
|
||||
* table.
|
||||
* @param listener will receive and process the response.
|
||||
*/
|
||||
function createTable (
|
||||
client :Client, lobbyOid :int, tableConfig :TableConfig,
|
||||
config :GameConfig, listener :TableListener) :void;
|
||||
|
||||
/**
|
||||
* You probably don't want to call this directly, but want to call
|
||||
* {@link TableDirector#joinTable}. Requests that the current user
|
||||
* be added to the specified table at the specified position.
|
||||
*
|
||||
* @param client a connected, operational client instance.
|
||||
* @param lobbyOid the oid of the lobby that contains the table.
|
||||
* @param tableId the unique id of the table to which this user wishes
|
||||
* to be added.
|
||||
* @param position the position at the table to which this user desires
|
||||
* to be added.
|
||||
* @param listener will receive and process the response.
|
||||
*/
|
||||
function joinTable (
|
||||
client :Client, lobbyOid :int, tableId :int,
|
||||
position :int, listener :InvocationListener) :void;
|
||||
|
||||
/**
|
||||
* You probably don't want to call this directly, but want to call
|
||||
* {@link TableDirector#leaveTable}. Requests that the current user be
|
||||
* removed from the specified table.
|
||||
*
|
||||
* @param client a connected, operational client instance.
|
||||
* @param lobbyOid the oid of the lobby that contains the table.
|
||||
* @param tableId the unique id of the table from which this user
|
||||
* wishes to be removed.
|
||||
* @param listener will receive and process the response.
|
||||
*/
|
||||
function leaveTable (
|
||||
client :Client, lobbyOid :int, tableId :int,
|
||||
listener :InvocationListener) :void;
|
||||
|
||||
/**
|
||||
* Requests to start a single player game with the specified game
|
||||
* configuration.
|
||||
*/
|
||||
function startSolitaire (
|
||||
client :Client, config :GameConfig,
|
||||
listener :ConfirmListener) :void;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
package com.threerings.parlor.client {
|
||||
|
||||
import com.threerings.presents.client.InvocationListener;
|
||||
|
||||
/**
|
||||
* Used to communicate responses to {@link #invite} requests.
|
||||
*/
|
||||
public interface ParlorService_InviteListener extends InvocationListener
|
||||
{
|
||||
/**
|
||||
* Called in response to a successful {@link #invite} request.
|
||||
*/
|
||||
function inviteReceived (inviteId :int) :void;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
package com.threerings.parlor.client {
|
||||
|
||||
import com.threerings.presents.client.InvocationListener;
|
||||
|
||||
/**
|
||||
* Used to communicate responses to {@link #createTable}, {@link
|
||||
* #joinTable}, and {@link #leaveTable} requests.
|
||||
*/
|
||||
public interface ParlorService_TableListener extends InvocationListener
|
||||
{
|
||||
function tableCreated (tableId :int) :void;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
//
|
||||
// $Id: SeatednessObserver.java 4191 2006-06-13 22:42:20Z ray $
|
||||
//
|
||||
// Narya library - tools for developing networked games
|
||||
// Copyright (C) 2002-2004 Three Rings Design, Inc., All Rights Reserved
|
||||
// http://www.threerings.net/code/narya/
|
||||
//
|
||||
// This library is free software; you can redistribute it and/or modify it
|
||||
// under the terms of the GNU Lesser General Public License as published
|
||||
// by the Free Software Foundation; either version 2.1 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This library is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
// Lesser General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public
|
||||
// License along with this library; if not, write to the Free Software
|
||||
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
package com.threerings.parlor.client {
|
||||
|
||||
/**
|
||||
* Entites that wish to hear about when we sit down at a table or stand up
|
||||
* from a table can implement this interface and register themselves with
|
||||
* the {@link TableDirector}.
|
||||
*/
|
||||
public interface SeatednessObserver
|
||||
{
|
||||
/**
|
||||
* Called when this client sits down at or stands up from a table.
|
||||
*
|
||||
* @param isSeated true if the client is now seated at a table, false
|
||||
* if they are now no longer seated at a table.
|
||||
*/
|
||||
function seatednessDidChange (isSeated :Boolean) :void;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,125 @@
|
||||
//
|
||||
// $Id$
|
||||
//
|
||||
// Narya library - tools for developing networked games
|
||||
// Copyright (C) 2002-2005 Three Rings Design, Inc., All Rights Reserved
|
||||
// http://www.threerings.net/code/narya/
|
||||
//
|
||||
// This library is free software; you can redistribute it and/or modify it
|
||||
// under the terms of the GNU Lesser General Public License as published
|
||||
// by the Free Software Foundation; either version 2.1 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This library is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
// Lesser General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public
|
||||
// License along with this library; if not, write to the Free Software
|
||||
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
package com.threerings.parlor.client {
|
||||
|
||||
import com.threerings.parlor.util.ParlorContext;
|
||||
|
||||
import com.threerings.parlor.data.TableConfig;
|
||||
|
||||
import com.threerings.parlor.game.client.GameConfigurator;
|
||||
|
||||
/**
|
||||
* This should be implemented some user-interface element that allows
|
||||
* the user to configure whichever TableConfig options are relevant.
|
||||
*/
|
||||
public /*abstract*/ class TableConfigurator
|
||||
{
|
||||
/**
|
||||
* Create a TableConfigurator.
|
||||
*/
|
||||
public function TableConfigurator ()
|
||||
{
|
||||
_config = createTableConfig();
|
||||
}
|
||||
|
||||
/**
|
||||
* Optionally, you can set a pre-configured TableConfig
|
||||
* that will be used to initialize the display parameters (if possible).
|
||||
* This should be called prior to init().
|
||||
*/
|
||||
public function setTableConfig (config :TableConfig) :void
|
||||
{
|
||||
if (config != null) {
|
||||
_config = config;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize the TableConfigurator.
|
||||
*
|
||||
* At the time this is called, the GameConfigurator should have
|
||||
* already been initialized.
|
||||
*/
|
||||
public function init (
|
||||
ctx :ParlorContext, gameConfigurator :GameConfigurator) :void
|
||||
{
|
||||
_ctx = ctx;
|
||||
_gameConfigurator = gameConfigurator;
|
||||
createConfigInterface();
|
||||
}
|
||||
|
||||
/**
|
||||
* Create the table config object that will be used.
|
||||
*/
|
||||
protected function createTableConfig () :TableConfig
|
||||
{
|
||||
return new TableConfig();
|
||||
}
|
||||
|
||||
/**
|
||||
* Create the config interface.
|
||||
*/
|
||||
protected function createConfigInterface () :void
|
||||
{
|
||||
// nothing by default
|
||||
}
|
||||
|
||||
/**
|
||||
* If true, the TableConfigurator is empty, which doesn't mean that
|
||||
* it will not return a TableConfig object (for it must), but rather
|
||||
* that there are no user-editable options being presented in the
|
||||
* config interface.
|
||||
*/
|
||||
public /*abstract*/ function isEmpty () :Boolean
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the fully configured table config according to the currently
|
||||
* configured user interface elements.
|
||||
*/
|
||||
public function getTableConfig () :TableConfig
|
||||
{
|
||||
flushTableConfig();
|
||||
return _config;
|
||||
}
|
||||
|
||||
/**
|
||||
* Derived classes will want to override this method, flushing
|
||||
* values from the user interface to the table config object.
|
||||
*/
|
||||
protected function flushTableConfig () :void
|
||||
{
|
||||
// nothing by default
|
||||
}
|
||||
|
||||
/** Provides access to client services. */
|
||||
protected var _ctx :ParlorContext;
|
||||
|
||||
/** The config we're configurating. */
|
||||
protected var _config :TableConfig;
|
||||
|
||||
/** The game configurator, which we may wish to reference. */
|
||||
protected var _gameConfigurator :GameConfigurator;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,367 @@
|
||||
//
|
||||
// $Id: TableDirector.java 3758 2005-11-10 23:18:58Z mdb $
|
||||
//
|
||||
// Narya library - tools for developing networked games
|
||||
// Copyright (C) 2002-2004 Three Rings Design, Inc., All Rights Reserved
|
||||
// http://www.threerings.net/code/narya/
|
||||
//
|
||||
// This library is free software; you can redistribute it and/or modify it
|
||||
// under the terms of the GNU Lesser General Public License as published
|
||||
// by the Free Software Foundation; either version 2.1 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This library is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
// Lesser General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public
|
||||
// License along with this library; if not, write to the Free Software
|
||||
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
package com.threerings.parlor.client {
|
||||
|
||||
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.BodyObject;
|
||||
import com.threerings.crowd.data.PlaceObject;
|
||||
|
||||
import com.threerings.parlor.data.Table;
|
||||
import com.threerings.parlor.data.TableConfig;
|
||||
import com.threerings.parlor.data.TableLobbyObject;
|
||||
import com.threerings.parlor.game.data.GameConfig;
|
||||
import com.threerings.parlor.util.ParlorContext;
|
||||
|
||||
/**
|
||||
* As tables are created and managed within the scope of a place (a
|
||||
* lobby), we want to fold the table management functionality into the
|
||||
* standard hierarchy of place controllers that deal with place-related
|
||||
* functionality on the client. Thus, instead of forcing places that
|
||||
* expect to have tables to extend a <code>TableLobbyController</code> or
|
||||
* something similar, we instead provide the table director which can be
|
||||
* instantiated by the place controller (or specific table related views)
|
||||
* to handle the table matchmaking services.
|
||||
*
|
||||
* <p> Entites that do so, will need to implement the {@link
|
||||
* TableObserver} interface so that the table director can notify them
|
||||
* when table related things happen.
|
||||
*
|
||||
* <p> The table services expect that the place object being used as a
|
||||
* lobby in which the table matchmaking takes place implements the {@link
|
||||
* TableLobbyObject} interface.
|
||||
*/
|
||||
public class TableDirector extends BasicDirector
|
||||
implements SetListener, ParlorService_TableListener
|
||||
{
|
||||
private static const log :Log = Log.getLog(TableDirector);
|
||||
|
||||
/**
|
||||
* Creates a new table director to manage tables with the specified
|
||||
* observer which will receive callbacks when interesting table
|
||||
* related things happen.
|
||||
*
|
||||
* @param ctx the parlor context in use by the client.
|
||||
* @param tableField the field name of the distributed set that
|
||||
* contains the tables we will be managing.
|
||||
* @param observer the entity that will receive callbacks when things
|
||||
* happen to the tables.
|
||||
*/
|
||||
public function TableDirector (
|
||||
ctx :ParlorContext, tableField :String, observer :TableObserver)
|
||||
{
|
||||
super(ctx);
|
||||
|
||||
// keep track of this stuff
|
||||
_pctx = ctx;
|
||||
_tableField = tableField;
|
||||
_observer = observer;
|
||||
}
|
||||
|
||||
/**
|
||||
* This must be called by the entity that uses the table director when
|
||||
* the using entity prepares to enter and display a place. It is
|
||||
* assumed that the client is already subscribed to the provided place
|
||||
* object.
|
||||
*/
|
||||
public function willEnterPlace (place :PlaceObject) :void
|
||||
{
|
||||
// add ourselves as a listener to the place object
|
||||
place.addListener(this);
|
||||
|
||||
// and remember this for later
|
||||
_lobby = place;
|
||||
}
|
||||
|
||||
/**
|
||||
* This must be called by the entity that uses the table director when
|
||||
* the using entity has left and is done displaying a place.
|
||||
*/
|
||||
public function didLeavePlace (place :PlaceObject) :void
|
||||
{
|
||||
// remove our listenership
|
||||
place.removeListener(this);
|
||||
|
||||
// clear out our lobby reference
|
||||
_lobby = null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Requests that the specified observer be added to the list of
|
||||
* observers that are notified when this client sits down at or stands
|
||||
* up from a table.
|
||||
*/
|
||||
public function addSeatednessObserver (observer :SeatednessObserver) :void
|
||||
{
|
||||
_seatedObservers.push(observer);
|
||||
}
|
||||
|
||||
/**
|
||||
* Requests that the specified observer be removed from to the list of
|
||||
* observers that are notified when this client sits down at or stands
|
||||
* up from a table.
|
||||
*/
|
||||
public function removeSeatednessObserver (
|
||||
observer :SeatednessObserver) :void
|
||||
{
|
||||
ArrayUtil.removeFirst(_seatedObservers, observer);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if this client is currently seated at a table, false
|
||||
* if they are not.
|
||||
*/
|
||||
public function isSeated () :Boolean
|
||||
{
|
||||
return (_ourTable != null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sends a request to create a table with the specified game
|
||||
* configuration. This user will become the owner of this table and
|
||||
* will be added to the first position in the table. The response will
|
||||
* be communicated via the {@link TableObserver} interface.
|
||||
*/
|
||||
public function createTable (
|
||||
tableConfig :TableConfig, config :GameConfig) :void
|
||||
{
|
||||
// if we're already in a table, refuse the request
|
||||
if (_ourTable != null) {
|
||||
log.warning("Ignoring request to create table as we're " +
|
||||
"already in a table [table=" + _ourTable + "].");
|
||||
return;
|
||||
}
|
||||
|
||||
// make sure we're currently in a place
|
||||
if (_lobby == null) {
|
||||
log.warning("Requested to create a table but we're not " +
|
||||
"currently in a place [config=" + config + "].");
|
||||
return;
|
||||
}
|
||||
|
||||
// go ahead and issue the create request
|
||||
_pservice.createTable(_pctx.getClient(), _lobby.getOid(), tableConfig,
|
||||
config, this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sends a request to join the specified table at the specified
|
||||
* position. The response will be communicated via the {@link
|
||||
* TableObserver} interface.
|
||||
*/
|
||||
public function joinTable (tableId :int, position :int) :void
|
||||
{
|
||||
// if we're already in a table, refuse the request
|
||||
if (_ourTable != null) {
|
||||
log.warning("Ignoring request to join table as we're " +
|
||||
"already in a table [table=" + _ourTable + "].");
|
||||
return;
|
||||
}
|
||||
|
||||
// make sure we're currently in a place
|
||||
if (_lobby == null) {
|
||||
log.warning("Requested to join a table but we're not " +
|
||||
"currently in a place [tableId=" + tableId + "].");
|
||||
return;
|
||||
}
|
||||
|
||||
// issue the join request
|
||||
_pservice.joinTable(_pctx.getClient(), _lobby.getOid(), tableId,
|
||||
position, this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sends a request to leave the specified table at which we are
|
||||
* presumably seated. The response will be communicated via the {@link
|
||||
* TableObserver} interface.
|
||||
*/
|
||||
public function leaveTable (tableId :int) :void
|
||||
{
|
||||
// make sure we're currently in a place
|
||||
if (_lobby == null) {
|
||||
log.warning("Requested to leave a table but we're not " +
|
||||
"currently in a place [tableId=" + tableId + "].");
|
||||
return;
|
||||
}
|
||||
|
||||
// issue the leave request
|
||||
_pservice.leaveTable(_pctx.getClient(), _lobby.getOid(), tableId, this);
|
||||
}
|
||||
|
||||
// documentation inherited
|
||||
override public function clientDidLogoff (event :ClientEvent) :void
|
||||
{
|
||||
super.clientDidLogoff(event);
|
||||
_pservice = null;
|
||||
_lobby = null;
|
||||
_ourTable = null;
|
||||
}
|
||||
|
||||
// documentation inherited
|
||||
protected function fetchServices (Client client) :void
|
||||
{
|
||||
// get a handle on our parlor services
|
||||
_pservice = (client.requireService(ParlorService) as ParlorService);
|
||||
}
|
||||
|
||||
// documentation inherited
|
||||
public function entryAdded (event :EntryAddedEvent) :void
|
||||
{
|
||||
if (event.getName() == _tableField) {
|
||||
var table :Table = (event.getEntry() as Table);
|
||||
|
||||
// check to see if we just joined a table
|
||||
checkSeatedness(table);
|
||||
|
||||
// now let the observer know what's up
|
||||
_observer.tableAdded(table);
|
||||
}
|
||||
}
|
||||
|
||||
// documentation inherited
|
||||
public function entryUpdated (event :EntryUpdatedEvent) :void
|
||||
{
|
||||
if (event.getName() == _tableField) {
|
||||
var table :Table = (event.getEntry() as Table);
|
||||
|
||||
// check to see if we just joined or left a table
|
||||
checkSeatedness(table);
|
||||
|
||||
// now let the observer know what's up
|
||||
_observer.tableUpdated(table);
|
||||
}
|
||||
}
|
||||
|
||||
// documentation inherited
|
||||
public function entryRemoved (event :EntryRemovedEvent) :void
|
||||
{
|
||||
if (event.getName() == _tableField) {
|
||||
var tableId :int = (event.getKey() as int);
|
||||
|
||||
// check to see if our table just disappeared
|
||||
if (_ourTable != null && tableId == _ourTable.tableId) {
|
||||
_ourTable = null;
|
||||
notifySeatedness(false);
|
||||
}
|
||||
|
||||
// now let the observer know what's up
|
||||
_observer.tableRemoved(tableId);
|
||||
}
|
||||
}
|
||||
|
||||
// documentation inherited from interface
|
||||
public function tableCreated (tableId :int) :void
|
||||
{
|
||||
// nothing much to do here
|
||||
log.info("Table creation succeeded [tableId=" + tableId + "].");
|
||||
}
|
||||
|
||||
// documentation inherited from interface
|
||||
public function requestFailed (reason :String) :void
|
||||
{
|
||||
log.warning("Table creation failed [reason=" + reason + "].");
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks to see if we're a member of this table and notes it as our
|
||||
* table, if so.
|
||||
*/
|
||||
protected function checkSeatedness (table :Table) :void
|
||||
{
|
||||
var oldTable :Table = _ourTable;
|
||||
|
||||
// if this is the same table as our table, clear out our table
|
||||
// reference and allow it to be added back if we are still in the
|
||||
// table
|
||||
if (table.equals(_ourTable)) {
|
||||
_ourTable = null;
|
||||
}
|
||||
|
||||
// look for our username in the occupants array
|
||||
var self :BodyObject =
|
||||
(_pctx.getClient().getClientObject() as BodyObject);
|
||||
for (var ii :int = 0; ii < table.occupants.length; ii++) {
|
||||
if (self.getVisibleName().equals(table.occupants[i])) {
|
||||
_ourTable = table;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// if nothing changed, bail now
|
||||
if (oldTable == _ourTable ||
|
||||
(oldTable != null && oldTable.equals(_ourTable))) {
|
||||
return;
|
||||
}
|
||||
|
||||
// otherwise notify the observers
|
||||
notifySeatedness(_ourTable != null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Notifies the seatedness observers of a seatedness change.
|
||||
*/
|
||||
protected function notifySeatedness (isSeated :Boolean) :void
|
||||
{
|
||||
var slength :int = _seatedObservers.length;
|
||||
for (var ii :int = 0; ii < slength; ii++) {
|
||||
var observer :SeatednessObserver =
|
||||
(_seatedObservers[ii] as SeatednessObserver);
|
||||
try {
|
||||
observer.seatednessDidChange(isSeated);
|
||||
} catch (err :Error) {
|
||||
log.warning("Observer choked in seatednessDidChange() " +
|
||||
"[observer=" + observer + "].");
|
||||
log.logStackTrace(err);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/** A context by which we can access necessary client services. */
|
||||
protected var _pctx :ParlorContext;
|
||||
|
||||
/** Parlor server-side services. */
|
||||
protected var _pservice :ParlorService;
|
||||
|
||||
/** The place object in which we're currently managing tables. */
|
||||
protected var _lobby :PlaceObject;
|
||||
|
||||
/** The field name of the distributed set that contains our tables. */
|
||||
protected var _tableField :String;
|
||||
|
||||
/** The entity that we talk to when table stuff happens. */
|
||||
protected var _observer :TableObserver;
|
||||
|
||||
/** The table of which we are a member if any. */
|
||||
protected var _ourTable :Table;
|
||||
|
||||
/** An array of entities that want to hear about when we stand up or
|
||||
* sit down. */
|
||||
protected var _seatedObservers :Array = new Array();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,49 @@
|
||||
//
|
||||
// $Id: TableObserver.java 4191 2006-06-13 22:42:20Z ray $
|
||||
//
|
||||
// Narya library - tools for developing networked games
|
||||
// Copyright (C) 2002-2004 Three Rings Design, Inc., All Rights Reserved
|
||||
// http://www.threerings.net/code/narya/
|
||||
//
|
||||
// This library is free software; you can redistribute it and/or modify it
|
||||
// under the terms of the GNU Lesser General Public License as published
|
||||
// by the Free Software Foundation; either version 2.1 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This library is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
// Lesser General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public
|
||||
// License along with this library; if not, write to the Free Software
|
||||
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
package com.threerings.parlor.client {
|
||||
|
||||
import com.threerings.parlor.data.Table;
|
||||
|
||||
/**
|
||||
* The {@link TableDirector} converts distributed object events into
|
||||
* higher level callbacks to implementers of this interface, which are
|
||||
* expected to render these events sensically in a user interface.
|
||||
*/
|
||||
public interface TableObserver
|
||||
{
|
||||
/**
|
||||
* Called when a new table is created.
|
||||
*/
|
||||
function tableAdded (table :Table) :void;
|
||||
|
||||
/**
|
||||
* Called when something has changed about a table (occupant list
|
||||
* updated, state changed from matchmaking to in-play, etc.).
|
||||
*/
|
||||
function tableUpdated (table :Table) :void;
|
||||
|
||||
/**
|
||||
* Called when a table goes away.
|
||||
*/
|
||||
function tableRemoved (tableId :int) :void;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,63 @@
|
||||
//
|
||||
// $Id: ParlorCodes.java 3359 2005-02-19 22:38:06Z mdb $
|
||||
//
|
||||
// Narya library - tools for developing networked games
|
||||
// Copyright (C) 2002-2004 Three Rings Design, Inc., All Rights Reserved
|
||||
// http://www.threerings.net/code/narya/
|
||||
//
|
||||
// This library is free software; you can redistribute it and/or modify it
|
||||
// under the terms of the GNU Lesser General Public License as published
|
||||
// by the Free Software Foundation; either version 2.1 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This library is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
// Lesser General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public
|
||||
// License along with this library; if not, write to the Free Software
|
||||
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
package com.threerings.parlor.data {
|
||||
|
||||
import com.threerings.presents.data.InvocationCodes;
|
||||
|
||||
/**
|
||||
* Contains codes used by the parlor invocation services.
|
||||
*/
|
||||
public class ParlorCodes extends InvocationCodes
|
||||
{
|
||||
/** The response code for an accepted invitation. */
|
||||
public static const INVITATION_ACCEPTED :int = 0;
|
||||
|
||||
/** The response code for a refused invitation. */
|
||||
public static const INVITATION_REFUSED :int = 1;
|
||||
|
||||
/** The response code for a countered invitation. */
|
||||
public static const INVITATION_COUNTERED :int = 2;
|
||||
|
||||
/** An error code explaining that an invitation was rejected because
|
||||
* the invited user was not online at the time the invitation was
|
||||
* received. */
|
||||
public static const INVITEE_NOT_ONLINE :String = "m.invitee_not_online";
|
||||
|
||||
/** An error code returned when a user requests to join a table that
|
||||
* doesn't exist. */
|
||||
public static const NO_SUCH_TABLE :String = "m.no_such_table";
|
||||
|
||||
/** An error code returned when a user requests to join a table at a
|
||||
* position that is not valid. */
|
||||
public static const INVALID_TABLE_POSITION :String =
|
||||
"m.invalid_table_position";
|
||||
|
||||
/** An error code returned when a user requests to join a table in a
|
||||
* position that is already occupied. */
|
||||
public static const TABLE_POSITION_OCCUPIED :String =
|
||||
"m.table_position_occupied";
|
||||
|
||||
/** An error code returned when a user requests to leave a table that
|
||||
* they were not sitting at in the first place. */
|
||||
public static const NOT_AT_TABLE :String = "m.not_at_table";
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,143 @@
|
||||
//
|
||||
// $Id: ParlorMarshaller.java 4145 2006-05-24 01:24:24Z ray $
|
||||
//
|
||||
// Narya library - tools for developing networked games
|
||||
// Copyright (C) 2002-2006 Three Rings Design, Inc., All Rights Reserved
|
||||
// http://www.threerings.net/code/narya/
|
||||
//
|
||||
// This library is free software; you can redistribute it and/or modify it
|
||||
// under the terms of the GNU Lesser General Public License as published
|
||||
// by the Free Software Foundation; either version 2.1 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This library is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
// Lesser General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public
|
||||
// License along with this library; if not, write to the Free Software
|
||||
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
package com.threerings.parlor.data {
|
||||
|
||||
import com.threerings.parlor.client.ParlorService;
|
||||
import com.threerings.parlor.data.TableConfig;
|
||||
import com.threerings.parlor.game.data.GameConfig;
|
||||
import com.threerings.presents.client.Client;
|
||||
import com.threerings.presents.client.InvocationService;
|
||||
import com.threerings.presents.client.InvocationService_InvocationListener;
|
||||
import com.threerings.presents.data.InvocationMarshaller;
|
||||
import com.threerings.presents.dobj.InvocationResponseEvent;
|
||||
import com.threerings.util.Name;
|
||||
|
||||
/**
|
||||
* Provides the implementation of the {@link ParlorService} 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 ParlorMarshaller extends InvocationMarshaller
|
||||
implements ParlorService
|
||||
{
|
||||
/** The method id used to dispatch {@link #cancel} requests. */
|
||||
public static const CANCEL :int = 1;
|
||||
|
||||
// documentation inherited from interface
|
||||
public function cancel (arg1 :Client, arg2 :int, arg3 :InvocationService_InvocationListener) :void
|
||||
{
|
||||
var listener3 :InvocationMarshaller_ListenerMarshaller =
|
||||
new InvocationMarshaller_ListenerMarshaller();
|
||||
listener3.listener = arg3;
|
||||
sendRequest(arg1, CANCEL, [
|
||||
Integer.valueOf(arg2), listener3
|
||||
]);
|
||||
}
|
||||
|
||||
/** The method id used to dispatch {@link #createTable} requests. */
|
||||
public static const CREATE_TABLE :int = 2;
|
||||
|
||||
// documentation inherited from interface
|
||||
public function createTable (arg1 :Client, arg2 :int, arg3 :TableConfig, arg4 :GameConfig, arg5 :ParlorService_TableListener) :void
|
||||
{
|
||||
var listener5 :ParlorMarshaller_TableMarshaller =
|
||||
new ParlorMarshaller_TableMarshaller();
|
||||
listener5.listener = arg5;
|
||||
sendRequest(arg1, CREATE_TABLE, [
|
||||
Integer.valueOf(arg2), arg3, arg4, listener5
|
||||
]);
|
||||
}
|
||||
|
||||
/** The method id used to dispatch {@link #invite} requests. */
|
||||
public static const INVITE :int = 3;
|
||||
|
||||
// documentation inherited from interface
|
||||
public function invite (arg1 :Client, arg2 :Name, arg3 :GameConfig, arg4 :ParlorService_InviteListener) :void
|
||||
{
|
||||
var listener4 :ParlorMarshaller_InviteMarshaller =
|
||||
new ParlorMarshaller_InviteMarshaller();
|
||||
listener4.listener = arg4;
|
||||
sendRequest(arg1, INVITE, [
|
||||
arg2, arg3, listener4
|
||||
]);
|
||||
}
|
||||
|
||||
/** The method id used to dispatch {@link #joinTable} requests. */
|
||||
public static const JOIN_TABLE :int = 4;
|
||||
|
||||
// documentation inherited from interface
|
||||
public function joinTable (arg1 :Client, arg2 :int, arg3 :int, arg4 :int, arg5 :InvocationService_InvocationListener) :void
|
||||
{
|
||||
var listener5 :InvocationMarshaller_ListenerMarshaller listener5 =
|
||||
new InvocationMarshaller_ListenerMarshaller();
|
||||
listener5.listener = arg5;
|
||||
sendRequest(arg1, JOIN_TABLE, [
|
||||
Integer.valueOf(arg2), Integer.valueOf(arg3), Integer.valueOf(arg4), listener5
|
||||
]);
|
||||
}
|
||||
|
||||
/** The method id used to dispatch {@link #leaveTable} requests. */
|
||||
public static const LEAVE_TABLE :int = 5;
|
||||
|
||||
// documentation inherited from interface
|
||||
public function leaveTable (arg1 :Client, arg2 :int, arg3 :int, arg4 :InvocationService_InvocationListener) :void
|
||||
{
|
||||
var listener4 :InvocationMarshaller_ListenerMarshaller =
|
||||
new InvocationMarshaller_ListenerMarshaller();
|
||||
listener4.listener = arg4;
|
||||
sendRequest(arg1, LEAVE_TABLE, [
|
||||
Integer.valueOf(arg2), Integer.valueOf(arg3), listener4
|
||||
]);
|
||||
}
|
||||
|
||||
/** The method id used to dispatch {@link #respond} requests. */
|
||||
public static const RESPOND :int = 6;
|
||||
|
||||
// documentation inherited from interface
|
||||
public function respond (arg1 :Client, arg2 :int, arg3 :int, arg4 :Object, arg5 :InvocationService_InvocationListener) :void
|
||||
{
|
||||
var listener5 :InvocationMarshaller_ListenerMarshaller =
|
||||
new InvocationMarshallerListenerMarshaller();
|
||||
listener5.listener = arg5;
|
||||
sendRequest(arg1, RESPOND, [
|
||||
Integer.valueOf(arg2), Integer.valueOf(arg3), arg4, listener5
|
||||
]);
|
||||
}
|
||||
|
||||
/** The method id used to dispatch {@link #startSolitaire} requests. */
|
||||
public static const START_SOLITAIRE :int = 7;
|
||||
|
||||
// documentation inherited from interface
|
||||
public function startSolitaire (arg1 :Client, arg2 :GameConfig, arg3 :InvocationService_ConfirmListener) :void
|
||||
{
|
||||
var listener3 :InvocationMarshaller_ConfirmMarshaller =
|
||||
new InvocationMarshaller_ConfirmMarshaller();
|
||||
listener3.listener = arg3;
|
||||
sendRequest(arg1, START_SOLITAIRE, [
|
||||
arg2, listener3
|
||||
]);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
package com.threerings.parlor.data {
|
||||
|
||||
import com.threerings.util.Integer;
|
||||
|
||||
import com.threerings.presents.data.InvocationMarshaller_ListenerMarshaller;
|
||||
|
||||
public class ParlorMarshaller_InviteMarshaller
|
||||
extends InvocationMarshaller_ListenerMarshaller
|
||||
implements InviteListener
|
||||
{
|
||||
/** The method id used to dispatch {@link #inviteReceived}
|
||||
* responses. */
|
||||
public static const INVITE_RECEIVED :int = 1;
|
||||
|
||||
// documentation inherited from interface
|
||||
public function inviteReceived (arg1 :int) :void
|
||||
{
|
||||
_invId = null;
|
||||
omgr.postEvent(new InvocationResponseEvent(
|
||||
callerOid, requestId, INVITE_RECEIVED,
|
||||
[ Integer.valueOf(arg1) ]));
|
||||
}
|
||||
|
||||
// documentation inherited
|
||||
override public function dispatchResponse (methodId :int, args :Array) :void
|
||||
{
|
||||
switch (methodId) {
|
||||
case INVITE_RECEIVED:
|
||||
(listener as InviteListener).inviteReceived(
|
||||
(args[0] as Integer).value);
|
||||
return;
|
||||
|
||||
default:
|
||||
super.dispatchResponse(methodId, args);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
package com.threerings.parlor.data {
|
||||
|
||||
import com.threerings.util.Integer;
|
||||
|
||||
import com.threerings.presents.data.InvocationMarshaller_ListenerMarshaller;
|
||||
|
||||
public class ParlorMarshaller_TableMarshaller
|
||||
extends InvocationMarshaller_ListenerMarshaller
|
||||
implements TableListener
|
||||
{
|
||||
/** The method id used to dispatch {@link #tableCreated}
|
||||
* responses. */
|
||||
public static const TABLE_CREATED :int = 1;
|
||||
|
||||
// documentation inherited from interface
|
||||
public function tableCreated (arg1 :int) :void
|
||||
{
|
||||
_invId = null;
|
||||
omgr.postEvent(new InvocationResponseEvent(
|
||||
callerOid, requestId, TABLE_CREATED,
|
||||
[ Integer.valueOf(arg1) ]));
|
||||
}
|
||||
|
||||
// documentation inherited
|
||||
override public function dispatchResponse (methodId :int, args :Array) :void
|
||||
{
|
||||
switch (methodId) {
|
||||
case TABLE_CREATED:
|
||||
(listener as TableListener).tableCreated(
|
||||
(args[0] as Integer).value);
|
||||
return;
|
||||
|
||||
default:
|
||||
super.dispatchResponse(methodId, args);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,378 @@
|
||||
//
|
||||
// $Id: Table.java 4191 2006-06-13 22:42:20Z ray $
|
||||
//
|
||||
// Narya library - tools for developing networked games
|
||||
// Copyright (C) 2002-2004 Three Rings Design, Inc., All Rights Reserved
|
||||
// http://www.threerings.net/code/narya/
|
||||
//
|
||||
// This library is free software; you can redistribute it and/or modify it
|
||||
// under the terms of the GNU Lesser General Public License as published
|
||||
// by the Free Software Foundation; either version 2.1 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This library is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
// Lesser General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public
|
||||
// License along with this library; if not, write to the Free Software
|
||||
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
package com.threerings.parlor.data {
|
||||
|
||||
import com.threerings.util.Hashable;
|
||||
import com.threerings.util.Name;
|
||||
import com.threerings.util.StringBuilder;
|
||||
|
||||
import com.threerings.io.ObjectInputStream;
|
||||
import com.threerings.io.ObjectOutputStream;
|
||||
|
||||
import com.threerings.presents.dobj.DSet;
|
||||
import com.threerings.presents.dobj.DSet_Entry;
|
||||
|
||||
import com.threerings.crowd.data.BodyObject;
|
||||
|
||||
import com.threerings.parlor.data.ParlorCodes;
|
||||
import com.threerings.parlor.game.data.GameConfig;
|
||||
import com.threerings.parlor.game.data.PartyGameConfig;
|
||||
|
||||
/**
|
||||
* This class represents a table that is being used to matchmake a game by
|
||||
* the Parlor services.
|
||||
*/
|
||||
public class Table
|
||||
implements Hashable, DSet_Entry, ParlorCodes
|
||||
{
|
||||
/** The unique identifier for this table. */
|
||||
public var tableId :int;
|
||||
|
||||
/** The object id of the lobby object with which this table is
|
||||
* associated. */
|
||||
public var lobbyOid :int;
|
||||
|
||||
/** The oid of the game that was created from this table or -1 if the
|
||||
* table is still in matchmaking mode. */
|
||||
public var gameOid :int = -1;
|
||||
|
||||
/** An array of the usernames of the occupants of this table (some
|
||||
* slots may not be filled), or null if a party game. */
|
||||
public var occupants :TypedArray /* of Name */;
|
||||
|
||||
/** The body oids of the occupants of this table, or null if a party game.
|
||||
* (This is not propagated to remote instances.) */
|
||||
public var bodyOids :TypedArray /* of int */;
|
||||
|
||||
/** The game config for the game that is being matchmade. */
|
||||
public var config :GameConfig;
|
||||
|
||||
/** The table configuration object. */
|
||||
public var tconfig :TableConfig;
|
||||
|
||||
/** Suitable for unserialization. */
|
||||
public function Table ()
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if there is no one sitting at this table.
|
||||
*/
|
||||
public function isEmpty () :Boolean
|
||||
{
|
||||
for (var ii :int = 0; ii < bodyOids.length; ii++) {
|
||||
if ((bodyOids[ii] as int) !== 0) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Count the number of players currently occupying this table.
|
||||
*/
|
||||
public function getOccupiedCount () :int
|
||||
{
|
||||
var count :int = 0;
|
||||
for (var ii :int = 0; ii < occupants.length; ii++) {
|
||||
if (occupants[ii] != null) {
|
||||
count++;
|
||||
}
|
||||
}
|
||||
return count;
|
||||
}
|
||||
|
||||
/**
|
||||
* Once a table is ready to play (see {@link #mayBeStarted} and {@link
|
||||
* #shouldBeStarted}), the players array can be fetched using this
|
||||
* method. It will return an array containing the usernames of all of
|
||||
* the players in the game, sized properly and with each player in the
|
||||
* appropriate position.
|
||||
*/
|
||||
public function getPlayers () :Array
|
||||
{
|
||||
if (isPartyGame()) {
|
||||
return occupants;
|
||||
}
|
||||
|
||||
// create and populate the players array
|
||||
var players :Array = new Array();
|
||||
for (var ii :int = 0; ii < occupants.length; ii++) {
|
||||
if (occupants[ii] != null) {
|
||||
players.push(occupants[ii]);
|
||||
}
|
||||
}
|
||||
|
||||
return players;
|
||||
}
|
||||
|
||||
/**
|
||||
* For a team game, get the team member indices of the compressed
|
||||
* players array returned by getPlayers().
|
||||
*/
|
||||
public function getTeamMemberIndices () :Array /* of Array of int */
|
||||
{
|
||||
var teams :Array = tconfig.teamMemberIndices;
|
||||
if (teams == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// TODO
|
||||
// compress the team indexes down
|
||||
ArrayIntSet set = new ArrayIntSet();
|
||||
int[][] newTeams = new int[teams.length][];
|
||||
Name[] players = getPlayers();
|
||||
for (int ii=0; ii < teams.length; ii++) {
|
||||
set.clear();
|
||||
for (int jj=0; jj < teams[ii].length; jj++) {
|
||||
Name occ = occupants[teams[ii][jj]];
|
||||
if (occ != null) {
|
||||
set.add(ListUtil.indexOf(players, occ));
|
||||
}
|
||||
}
|
||||
newTeams[ii] = set.toIntArray();
|
||||
}
|
||||
|
||||
return newTeams;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return true if the game is a party game.
|
||||
*/
|
||||
public function isPartyGame () :Boolean
|
||||
{
|
||||
return (PartyGameConfig.NOT_PARTY_GAME != getPartyGameType());
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the type of party game being played at this table, or
|
||||
* PartyGameConfig.NOT_PARTY_GAME.
|
||||
*/
|
||||
public function getPartyGameType () :int
|
||||
{
|
||||
if (config is PartyGameConfig) {
|
||||
return (config as PartyGameConfig).getPartyGameType();
|
||||
|
||||
} else {
|
||||
return PartyGameConfig.NOT_PARTY_GAME;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Requests to seat the specified user at the specified position in
|
||||
* this table.
|
||||
*
|
||||
* @param position the position in which to seat the user.
|
||||
* @param occupant the occupant to set.
|
||||
*
|
||||
* @return null if the user was successfully seated, a string error
|
||||
* code explaining the failure if the user was not able to be seated
|
||||
* at that position.
|
||||
*/
|
||||
public function setOccupant (position :int, occupant :BodyObject) :String
|
||||
{
|
||||
// make sure the requested position is a valid one
|
||||
if (position >= tconfig.desiredPlayerCount || position < 0) {
|
||||
return INVALID_TABLE_POSITION;
|
||||
}
|
||||
|
||||
// make sure the requested position is not already occupied
|
||||
if (occupants[position] != null) {
|
||||
return TABLE_POSITION_OCCUPIED;
|
||||
}
|
||||
|
||||
// otherwise all is well, stick 'em in
|
||||
setOccupantPos(position, occupant);
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method is used for party games, it does no bounds checking
|
||||
* or verification of the player's ability to join, if you are unsure
|
||||
* you should call 'setOccupant'.
|
||||
*/
|
||||
public function setOccupantPos (position :int, occupant :BodyObject) :void
|
||||
{
|
||||
occupants[position] = occupant.getVisibleName();
|
||||
bodyOids[position] = occupant.getOid();
|
||||
}
|
||||
|
||||
/**
|
||||
* Requests that the specified user be removed from their seat at this
|
||||
* table.
|
||||
*
|
||||
* @return true if the user was seated at the table and has now been
|
||||
* removed, false if the user was never seated at the table in the
|
||||
* first place.
|
||||
*/
|
||||
public function clearOccupant (username :Name) :void
|
||||
{
|
||||
var dex :int = ArrayUtil.indexOf(occupants, username);
|
||||
if (dex != -1) {
|
||||
clearOccupantPos(dex);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Requests that the user identified by the specified body object id
|
||||
* be removed from their seat at this table.
|
||||
*
|
||||
* @return true if the user was seated at the table and has now been
|
||||
* removed, false if the user was never seated at the table in the
|
||||
* first place.
|
||||
*/
|
||||
public function clearOccupant (bodyOid :int) :Boolean
|
||||
{
|
||||
var dex :int = ArrayUtil.indexOf(bodyOids, bodyOid);
|
||||
if (dex != -1) {
|
||||
clearOccupantPos(dex);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Called to clear an occupant at the specified position.
|
||||
* Only call this method if you know what you're doing.
|
||||
*/
|
||||
public function clearOccupantPos (position :int) :void
|
||||
{
|
||||
occupants[position] = null;
|
||||
bodyOids[position] = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if this table has a sufficient number of occupants
|
||||
* that the game can be started.
|
||||
*/
|
||||
public function mayBeStarted () :Boolean
|
||||
{
|
||||
if (tconfig.teamMemberIndices == null) {
|
||||
// for a normal game, just check to see if we're past the minimum
|
||||
return tconfig.minimumPlayerCount <= getOccupiedCount();
|
||||
|
||||
} else {
|
||||
// for a team game, make sure each team has the minimum players
|
||||
var teams :Array = tconfig.teamMemberIndices;
|
||||
for (var ii :int = 0; ii < teams.length; ii++) {
|
||||
var teamCount :int = 0;
|
||||
var members :Array = (teams[ii] as Array);
|
||||
for (var jj :int = 0; jj < members.length; jj++) {
|
||||
if (occupants[members[jj]] != null) {
|
||||
teamCount++;
|
||||
}
|
||||
}
|
||||
if (teamCount < tconfig.minimumPlayerCount) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if sufficient seats are occupied that the game should
|
||||
* be automatically started.
|
||||
*/
|
||||
public function shouldBeStarted () :Boolean
|
||||
{
|
||||
return tconfig.desiredPlayerCount <= getOccupiedCount();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if this table is in play, false if it is still being
|
||||
* matchmade.
|
||||
*/
|
||||
public function inPlay () :Boolean
|
||||
{
|
||||
return gameOid != -1;
|
||||
}
|
||||
|
||||
// documentation inherited
|
||||
public function getKey () :Object
|
||||
{
|
||||
return tableId;
|
||||
}
|
||||
|
||||
// from Hashable
|
||||
public function equals (other :Object) :Boolean
|
||||
{
|
||||
return (other is Table) &&
|
||||
(tableId == ((Table) other).tableId);
|
||||
}
|
||||
|
||||
// from Hashable
|
||||
public function hashCode () :int
|
||||
{
|
||||
return tableId;
|
||||
}
|
||||
|
||||
// from Streamable
|
||||
public function writeObject (out :ObjectOutputStream) :void
|
||||
{
|
||||
out.writeInt(tableId);
|
||||
out.writeInt(lobbyOid);
|
||||
out.writeInt(gameOid);
|
||||
out.writeObject(occupants);
|
||||
out.writeObject(config);
|
||||
out.writeObject(tconfig);
|
||||
}
|
||||
|
||||
// from Streamable
|
||||
public function readObject (ins :ObjectInputStream) :void
|
||||
{
|
||||
tableId = ins.readInt();
|
||||
lobbyOid = ins.readInt();
|
||||
gameOid = ins.readInt();
|
||||
occupants = (ins.readObject() as TypedArray);
|
||||
config = (ins.readObject() as GameConfig);
|
||||
tconfig = (ins.readObject() as TableConfig);
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates a string representation of this table instance.
|
||||
*/
|
||||
public function toString () :String
|
||||
{
|
||||
var buf :StringBuilder = new StringBuilder();
|
||||
buf.append(ClassUtil.shortClassName(this));
|
||||
buf.append(" [");
|
||||
toStringBuf(buf);
|
||||
buf.append("]");
|
||||
return buf.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper method for toString, ripe for overrideability.
|
||||
*/
|
||||
protected function toStringBuf (buf :StringBuilder) :void
|
||||
{
|
||||
buf.append("tableId=").append(tableId);
|
||||
buf.append(", lobbyOid=").append(lobbyOid);
|
||||
buf.append(", gameOid=").append(gameOid);
|
||||
buf.append(", occupants=").append(occupants.join());
|
||||
buf.append(", config=").append(config);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,72 @@
|
||||
//
|
||||
// $Id: TableConfig.java 3604 2005-06-17 20:25:28Z ray $
|
||||
//
|
||||
// Narya library - tools for developing networked games
|
||||
// Copyright (C) 2002-2004 Three Rings Design, Inc., All Rights Reserved
|
||||
// http://www.threerings.net/code/narya/
|
||||
//
|
||||
// This library is free software; you can redistribute it and/or modify it
|
||||
// under the terms of the GNU Lesser General Public License as published
|
||||
// by the Free Software Foundation; either version 2.1 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This library is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
// Lesser General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public
|
||||
// License along with this library; if not, write to the Free Software
|
||||
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
package com.threerings.parlor.data {
|
||||
|
||||
import com.threerings.io.ObjectInputStream;
|
||||
import com.threerings.io.ObjectOutputStream;
|
||||
import com.threerings.io.Streamable;
|
||||
import com.threerings.io.TypedArray;
|
||||
|
||||
/**
|
||||
* Table configuration parameters for a game that is to be matchmade
|
||||
* using the table services.
|
||||
*/
|
||||
public class TableConfig
|
||||
implements Streamable
|
||||
{
|
||||
/** The total number of players that are desired for the table,
|
||||
* or -1 for a party game. For team games, this should be set to the
|
||||
* total number of players overall, as teams may be unequal. */
|
||||
public var desiredPlayerCount :int;
|
||||
|
||||
/** The minimum number of players needed overall (or per-team if a
|
||||
* team-based game) for the game to start at the creator's discretion. */
|
||||
public var minimumPlayerCount :int;
|
||||
|
||||
/** If non-null, indicates that this is a team-based game and contains
|
||||
* the team assignments for each player. For example, a game with
|
||||
* three players in two teams- players 0 and 2 versus player 1- would
|
||||
* have { {0, 2}, {1} }; */
|
||||
public var teamMemberIndices :TypedArray;
|
||||
|
||||
/** Whether the table is "private". */
|
||||
public var privateTable :Boolean;
|
||||
|
||||
// from Streamable
|
||||
public function writeObject (out :ObjectOutputStream) :void
|
||||
{
|
||||
out.writeInt(desiredPlayerCount);
|
||||
out.writeInt(minimumPlayerCount);
|
||||
out.writeField(teamMemberIndices);
|
||||
out.writeBoolean(privateTable);
|
||||
}
|
||||
|
||||
// from Streamable
|
||||
public function readObject (ins :ObjectInputStream) :void
|
||||
{
|
||||
desiredPlayerCount = ins.readInt();
|
||||
minimumPlayerCount = ins.readInt();
|
||||
teamMemberIndices = (ins.readField("[[I") as TypedArray);
|
||||
privateTable = ins.readBoolean();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,57 @@
|
||||
//
|
||||
// $Id: TableLobbyObject.java 4145 2006-05-24 01:24:24Z ray $
|
||||
//
|
||||
// Narya library - tools for developing networked games
|
||||
// Copyright (C) 2002-2004 Three Rings Design, Inc., All Rights Reserved
|
||||
// http://www.threerings.net/code/narya/
|
||||
//
|
||||
// This library is free software; you can redistribute it and/or modify it
|
||||
// under the terms of the GNU Lesser General Public License as published
|
||||
// by the Free Software Foundation; either version 2.1 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This library is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
// Lesser General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public
|
||||
// License along with this library; if not, write to the Free Software
|
||||
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
package com.threerings.parlor.data {
|
||||
|
||||
import com.threerings.presents.dobj.DSet;
|
||||
|
||||
/**
|
||||
* This interface must be implemented by the place object used by a lobby
|
||||
* that wishes to make use of the table services.
|
||||
*/
|
||||
public interface TableLobbyObject
|
||||
{
|
||||
/**
|
||||
* Returns a reference to the distributed set instance that will be
|
||||
* holding the tables.
|
||||
*/
|
||||
function getTables () :DSet;
|
||||
|
||||
/**
|
||||
* Adds the supplied table instance to the tables set (using the
|
||||
* appropriate distributed object mechanisms).
|
||||
*/
|
||||
function addToTables (table :Table) :void;
|
||||
|
||||
/**
|
||||
* Updates the value of the specified table instance in the tables
|
||||
* distributed set (using the appropriate distributed object
|
||||
* mechanisms).
|
||||
*/
|
||||
function updateTables (table :Table) :void;
|
||||
|
||||
/**
|
||||
* Removes the table instance that matches the specified key from the
|
||||
* tables set (using the appropriate distributed object mechanisms).
|
||||
*/
|
||||
function removeFromTables (key :Object) :void;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,77 @@
|
||||
//
|
||||
// $Id: GameConfigurator.java 3590 2005-06-08 23:20:18Z ray $
|
||||
//
|
||||
// Narya library - tools for developing networked games
|
||||
// Copyright (C) 2002-2004 Three Rings Design, Inc., All Rights Reserved
|
||||
// http://www.threerings.net/code/narya/
|
||||
//
|
||||
// This library is free software; you can redistribute it and/or modify it
|
||||
// under the terms of the GNU Lesser General Public License as published
|
||||
// by the Free Software Foundation; either version 2.1 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This library is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
// Lesser General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public
|
||||
// License along with this library; if not, write to the Free Software
|
||||
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
package com.threerings.parlor.game.client;
|
||||
|
||||
import mx.core.Container;
|
||||
import mx.core.UIComponent;
|
||||
|
||||
import mx.containers.Grid;
|
||||
import mx.containers.GridItem;
|
||||
import mx.containers.GridRow;
|
||||
|
||||
import com.threerings.parlor.game.data.GameConfig;
|
||||
import com.threerings.parlor.util.ParlorContext;
|
||||
|
||||
/**
|
||||
* Provides the base from which interfaces can be built to configure games
|
||||
* prior to starting them. Derived classes would extend the base
|
||||
* configurator adding interface elements and wiring them up properly to
|
||||
* allow the user to configure an instance of their game.
|
||||
*
|
||||
* <p> Clients that use the game configurator will want to instantiate one
|
||||
* based on the class returned from the {@link GameConfig} and then
|
||||
* initialize it with a call to {@link #init}.
|
||||
*/
|
||||
public /*abstract*/ class FlexGameConfigurator extends GameConfigurator
|
||||
{
|
||||
/**
|
||||
* Get the Container that contains the UI elements for this configurator.
|
||||
*/
|
||||
public function getContainer () :Container
|
||||
{
|
||||
return _grid;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a control to the interface. This should be the standard way
|
||||
* that configurator controls are added, but note also that external
|
||||
* entities may add their own controls that are related to the game,
|
||||
* but do not directly alter the game config, so that all the controls
|
||||
* are added in a uniform manner and are well aligned.
|
||||
*/
|
||||
public function addControl (
|
||||
label :UIComponent, control :UIComponent) :void
|
||||
{
|
||||
var row :GridRow = new GridRow();
|
||||
var labelItem :GridItem = new GridItem();
|
||||
var controlItem :GridItem = new GridItem();
|
||||
|
||||
labelItem.addChild(label);
|
||||
controlItem.addChild(control);
|
||||
row.addChild(labelItem);
|
||||
row.addChild(controlItem);
|
||||
_grid.addChild(row);
|
||||
}
|
||||
|
||||
/** The grid on which the config options are placed. */
|
||||
protected var _grid :Grid = new Grid();
|
||||
}
|
||||
@@ -0,0 +1,104 @@
|
||||
//
|
||||
// $Id: GameConfigurator.java 3590 2005-06-08 23:20:18Z ray $
|
||||
//
|
||||
// Narya library - tools for developing networked games
|
||||
// Copyright (C) 2002-2004 Three Rings Design, Inc., All Rights Reserved
|
||||
// http://www.threerings.net/code/narya/
|
||||
//
|
||||
// This library is free software; you can redistribute it and/or modify it
|
||||
// under the terms of the GNU Lesser General Public License as published
|
||||
// by the Free Software Foundation; either version 2.1 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This library is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
// Lesser General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public
|
||||
// License along with this library; if not, write to the Free Software
|
||||
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
package com.threerings.parlor.game.client {
|
||||
|
||||
import com.threerings.parlor.game.data.GameConfig;
|
||||
import com.threerings.parlor.util.ParlorContext;
|
||||
|
||||
/**
|
||||
* Provides the base from which interfaces can be built to configure games
|
||||
* prior to starting them. Derived classes would extend the base
|
||||
* configurator adding interface elements and wiring them up properly to
|
||||
* allow the user to configure an instance of their game.
|
||||
*
|
||||
* <p> Clients that use the game configurator will want to instantiate one
|
||||
* based on the class returned from the {@link GameConfig} and then
|
||||
* initialize it with a call to {@link #init}.
|
||||
*/
|
||||
public /*abstract*/ class GameConfigurator
|
||||
{
|
||||
/**
|
||||
* Initializes this game configurator, creates its user interface
|
||||
* elements and prepares it for display.
|
||||
*/
|
||||
public function init (ctx :ParlorContext) :void
|
||||
{
|
||||
// save this for later
|
||||
_ctx = ctx;
|
||||
|
||||
// create our interface elements
|
||||
createConfigInterface();
|
||||
}
|
||||
|
||||
/**
|
||||
* The default implementation creates nothing.
|
||||
*/
|
||||
protected function createConfigInterface () :void
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* Provides this configurator with its configuration. It should set up
|
||||
* all of its user interface elements to reflect the configuration.
|
||||
*/
|
||||
public function setGameConfig (config :GameConfig) :void
|
||||
{
|
||||
_config = config;
|
||||
// set up the user interface
|
||||
gotGameConfig();
|
||||
}
|
||||
|
||||
/**
|
||||
* Derived classes will likely want to override this method and
|
||||
* configure their user interface elements accordingly.
|
||||
*/
|
||||
protected function gotGameConfig () :void
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* Obtains a configured game configuration.
|
||||
*/
|
||||
public function getGameConfig () :GameConfig
|
||||
{
|
||||
// flush our changes to the config object
|
||||
flushGameConfig();
|
||||
return _config;
|
||||
}
|
||||
|
||||
/**
|
||||
* Derived classes will want to override this method, flushing values
|
||||
* from the user interface to the game config object so that it is
|
||||
* properly configured prior to being returned to the {@link
|
||||
* #getGameConfig} caller.
|
||||
*/
|
||||
protected function flushGameConfig () :void
|
||||
{
|
||||
}
|
||||
|
||||
/** Provides access to client services. */
|
||||
protected var _ctx :ParlorContext;
|
||||
|
||||
/** Our game configuration. */
|
||||
protected var _config :GameConfig;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,337 @@
|
||||
//
|
||||
// $Id: GameController.java 3804 2006-01-13 01:52:36Z ray $
|
||||
//
|
||||
// Narya library - tools for developing networked games
|
||||
// Copyright (C) 2002-2004 Three Rings Design, Inc., All Rights Reserved
|
||||
// http://www.threerings.net/code/narya/
|
||||
//
|
||||
// This library is free software; you can redistribute it and/or modify it
|
||||
// under the terms of the GNU Lesser General Public License as published
|
||||
// by the Free Software Foundation; either version 2.1 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This library is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
// Lesser General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public
|
||||
// License along with this library; if not, write to the Free Software
|
||||
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
package com.threerings.parlor.game.client {
|
||||
|
||||
import com.threerings.presents.dobj.AttributeChangeListener;
|
||||
import com.threerings.presents.dobj.AttributeChangedEvent;
|
||||
|
||||
import com.threerings.crowd.client.PlaceController;
|
||||
import com.threerings.crowd.data.BodyObject;
|
||||
import com.threerings.crowd.data.PlaceConfig;
|
||||
import com.threerings.crowd.data.PlaceObject;
|
||||
import com.threerings.crowd.util.CrowdContext;
|
||||
|
||||
import com.threerings.parlor.Log;
|
||||
import com.threerings.parlor.game.data.GameCodes;
|
||||
import com.threerings.parlor.game.data.GameConfig;
|
||||
import com.threerings.parlor.game.data.GameObject;
|
||||
import com.threerings.parlor.game.data.PartyGameConfig;
|
||||
import com.threerings.parlor.util.ParlorContext;
|
||||
|
||||
/**
|
||||
* The game controller manages the flow and control of a game on the
|
||||
* client side. This class serves as the root of a hierarchy of controller
|
||||
* classes that aim to provide functionality shared between various
|
||||
* similar games. The base controller provides functionality for starting
|
||||
* and ending the game and for calculating ratings adjustements when a
|
||||
* game ends normally. It also handles the basic house keeping like
|
||||
* subscription to the game object and dispatch of commands and
|
||||
* distributed object events.
|
||||
*/
|
||||
public /*abstract*/ class GameController extends PlaceController
|
||||
implements AttributeChangeListener
|
||||
{
|
||||
protected static const log :Log = Log.getLog(GameController);
|
||||
|
||||
/**
|
||||
* Initializes this game controller with the game configuration that
|
||||
* was established during the match making process. Derived classes
|
||||
* may want to override this method to initialize themselves with
|
||||
* game-specific configuration parameters but they should be sure to
|
||||
* call <code>super.init</code> in such cases.
|
||||
*
|
||||
* @param ctx the client context.
|
||||
* @param config the configuration of the game we are intended to
|
||||
* control.
|
||||
*/
|
||||
override public function init (ctx :CrowdContext, config :PlaceConfig) :void
|
||||
{
|
||||
// cast our references before we call super.init() so that when
|
||||
// super.init() calls createPlaceView(), we have our casted
|
||||
// references already in place
|
||||
_ctx = (ctx as ParlorContext);
|
||||
_config = (config as GameConfig);
|
||||
|
||||
super.init(ctx, config);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds this controller as a listener to the game object (thus derived
|
||||
* classes need not do so) and lets the game manager know that we are
|
||||
* now ready to go.
|
||||
*/
|
||||
override public function willEnterPlace (plobj :PlaceObject) :void
|
||||
{
|
||||
super.willEnterPlace(plobj);
|
||||
|
||||
// obtain a casted reference
|
||||
_gobj = (plobj as GameObject);
|
||||
|
||||
// if this place object is not our current location we'll need to
|
||||
// add it as an auxiliary chat source
|
||||
var bobj :BodyObject =
|
||||
(_ctx.getClient().getClientObject() as BodyObject);
|
||||
if (bobj.location != plobj.getOid()) {
|
||||
_ctx.getChatDirector().addAuxiliarySource(
|
||||
_gobj, GameCodes.GAME_CHAT_TYPE);
|
||||
}
|
||||
|
||||
// and add ourselves as a listener
|
||||
_gobj.addListener(this);
|
||||
|
||||
// we don't want to claim to be finished until any derived classes
|
||||
// that overrode this method have executed, so we'll queue up a
|
||||
// runnable here that will let the game manager know that we're
|
||||
// ready on the next pass through the distributed event loop
|
||||
log.info("Entering game " + _gobj.which() + ".");
|
||||
if (_gobj.getPlayerIndex(bobj.getVisibleName()) != -1) {
|
||||
// finally let the game manager know that we're ready
|
||||
// to roll
|
||||
_ctx.getClient().callLater(playerReady);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes our listener registration from the game object and cleans
|
||||
* house.
|
||||
*/
|
||||
override public function didLeavePlace (plobj :PlaceObject) :void
|
||||
{
|
||||
super.didLeavePlace(plobj);
|
||||
|
||||
_ctx.getChatDirector().removeAuxiliarySource(_gobj);
|
||||
|
||||
// unlisten to the game object
|
||||
_gobj.removeListener(this);
|
||||
_gobj = null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether the game is over.
|
||||
*/
|
||||
public function isGameOver () :Boolean
|
||||
{
|
||||
var gameOver :Boolean = (_gobj == null) ||
|
||||
(_gobj.state != GameObject.IN_PLAY);
|
||||
return (_gameOver || gameOver);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the client game over override. This is used in situations
|
||||
* where we determine that the game is over before the server has
|
||||
* informed us of such.
|
||||
*/
|
||||
public function setGameOver (gameOver :Boolean) :void
|
||||
{
|
||||
_gameOver = gameOver;
|
||||
}
|
||||
|
||||
/**
|
||||
* Calls {@link #gameWillReset}, ends the current game (locally, it
|
||||
* does not tell the server to end the game), and waits to receive a
|
||||
* reset notification (which is simply an event setting the game state
|
||||
* to <code>IN_PLAY</code> even though it's already set to
|
||||
* <code>IN_PLAY</code>) from the server which will start up a new
|
||||
* game. Derived classes should override {@link #gameWillReset} to
|
||||
* perform any game-specific animations.
|
||||
*/
|
||||
public function resetGame () :void
|
||||
{
|
||||
// let derived classes do their thing
|
||||
gameWillReset();
|
||||
|
||||
// end the game until we receive a new board
|
||||
setGameOver(true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the unique round identifier for the current round.
|
||||
*/
|
||||
public function getRoundId () :int
|
||||
{
|
||||
return (_gobj == null) ? -1 : _gobj.roundId;
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles basic game 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
|
||||
{
|
||||
return super.handleAction(cmd, arg);
|
||||
}
|
||||
|
||||
/**
|
||||
* A way for controllers to display a game-related system message.
|
||||
*/
|
||||
public function systemMessage (bundle :String, msg :String) :void
|
||||
{
|
||||
_ctx.getChatDirector().displayInfo(
|
||||
bundle, msg, GameCodes.GAME_CHAT_TYPE);
|
||||
}
|
||||
|
||||
// from interface AttributeChangeListener
|
||||
public function attributeChanged (event :AttributeChangedEvent) :void
|
||||
{
|
||||
// deal with game state changes
|
||||
var name :String = event.getName();
|
||||
if (GameObject.STATE.equals(name)) {
|
||||
var newState :int = int(event.getValue());
|
||||
if (!stateDidChange(newState)) {
|
||||
log.warning("Game transitioned to unknown state " +
|
||||
"[gobj=" + _gobj + ", state=" + newState + "].");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Derived classes can override this method if they add additional game
|
||||
* states and should handle transitions to those states, returning true to
|
||||
* indicate they were handled and calling super for the normal game states.
|
||||
*/
|
||||
protected function stateDidChange (state :int) :Boolean
|
||||
{
|
||||
switch (state) {
|
||||
case GameObject.IN_PLAY:
|
||||
gameDidStart();
|
||||
return true;
|
||||
case GameObject.GAME_OVER:
|
||||
gameDidEnd();
|
||||
return true;
|
||||
case GameObject.CANCELLED:
|
||||
gameWasCancelled();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Called after we've entered the game and everything has initialized
|
||||
* to notify the server that we, as a player, are ready to play.
|
||||
*/
|
||||
protected function playerReady () :void
|
||||
{
|
||||
log.info("Reporting ready " + _gobj.which() + ".");
|
||||
_gobj.gameService.playerReady(_ctx.getClient());
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when the game transitions to the <code>IN_PLAY</code>
|
||||
* state. This happens when all of the players have arrived and the
|
||||
* server starts the game.
|
||||
*/
|
||||
protected function gameDidStart () :void
|
||||
{
|
||||
if (_gobj == null) {
|
||||
log.info("Received gameDidStart() after leaving game room.");
|
||||
return;
|
||||
}
|
||||
|
||||
// clear out our game over flag
|
||||
setGameOver(false);
|
||||
|
||||
/* TODO
|
||||
// let our delegates do their business
|
||||
applyToDelegates(new DelegateOp() {
|
||||
public void apply (PlaceControllerDelegate delegate) {
|
||||
((GameControllerDelegate)delegate).gameDidStart();
|
||||
}
|
||||
});
|
||||
*/
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when the game transitions to the <code>GAME_OVER</code>
|
||||
* state. This happens when the game reaches some end condition by
|
||||
* normal means (is not cancelled or aborted).
|
||||
*/
|
||||
protected function gameDidEnd () :void
|
||||
{
|
||||
/* TODO
|
||||
// let our delegates do their business
|
||||
applyToDelegates(new DelegateOp() {
|
||||
public void apply (PlaceControllerDelegate delegate) {
|
||||
((GameControllerDelegate)delegate).gameDidEnd();
|
||||
}
|
||||
});
|
||||
*/
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when the game was cancelled for some reason.
|
||||
*/
|
||||
protected function gameWasCancelled () :void
|
||||
{
|
||||
/*
|
||||
// let our delegates do their business
|
||||
applyToDelegates(new DelegateOp() {
|
||||
public void apply (PlaceControllerDelegate delegate) {
|
||||
((GameControllerDelegate)delegate).gameWasCancelled();
|
||||
}
|
||||
});
|
||||
*/
|
||||
}
|
||||
|
||||
/**
|
||||
* Called to give derived classes a chance to display animations, send
|
||||
* a final packet, or do any other business they care to do when the
|
||||
* game is about to reset.
|
||||
*/
|
||||
protected function gameWillReset () :void
|
||||
{
|
||||
/* TODO
|
||||
// let our delegates do their business
|
||||
applyToDelegates(new DelegateOp() {
|
||||
public void apply (PlaceControllerDelegate delegate) {
|
||||
((GameControllerDelegate)delegate).gameWillReset();
|
||||
}
|
||||
});
|
||||
*/
|
||||
}
|
||||
|
||||
/**
|
||||
* Used to determine if this game is a party game.
|
||||
*/
|
||||
protected function isPartyGame () :Boolean
|
||||
{
|
||||
return (_config is PartyGameConfig) &&
|
||||
(PartyGameConfig(_config).getPartyGameType() !=
|
||||
PartyGameConfig.NOT_PARTY_GAME);
|
||||
}
|
||||
|
||||
/** A reference to the active parlor context. */
|
||||
protected var _pctx :ParlorContext;
|
||||
|
||||
/** Our game configuration information. */
|
||||
protected var _config :GameConfig;
|
||||
|
||||
/** A reference to the game object for the game that we're
|
||||
* controlling. */
|
||||
protected var _gobj :GameObject;
|
||||
|
||||
/** A local flag overriding the game over state for situations where
|
||||
* the client knows the game is over before the server has
|
||||
* transitioned the game object accordingly. */
|
||||
protected var _gameOver :Boolean;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
//
|
||||
// $Id: GameService.java 3600 2005-06-15 23:46:31Z ray $
|
||||
//
|
||||
// Narya library - tools for developing networked games
|
||||
// Copyright (C) 2002-2004 Three Rings Design, Inc., All Rights Reserved
|
||||
// http://www.threerings.net/code/narya/
|
||||
//
|
||||
// This library is free software; you can redistribute it and/or modify it
|
||||
// under the terms of the GNU Lesser General Public License as published
|
||||
// by the Free Software Foundation; either version 2.1 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This library is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
// Lesser General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public
|
||||
// License along with this library; if not, write to the Free Software
|
||||
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
package com.threerings.parlor.game.client {
|
||||
|
||||
import com.threerings.presents.client.Client;
|
||||
import com.threerings.presents.client.InvocationService;
|
||||
|
||||
/**
|
||||
* Provides services used by game clients to request that actions be taken
|
||||
* by the game manager.
|
||||
*/
|
||||
public interface GameService extends InvocationService
|
||||
{
|
||||
/**
|
||||
* Lets the game manager know that the calling player is in the game
|
||||
* room and ready to play.
|
||||
*/
|
||||
function playerReady (client :Client) :void;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
//
|
||||
// $Id: GameAI.java 3399 2005-03-12 07:37:34Z mdb $
|
||||
|
||||
package com.threerings.parlor.game.data {
|
||||
|
||||
import com.threerings.io.ObjectInputStream;
|
||||
import com.threerings.io.ObjectOutputStream;
|
||||
import com.threerings.io.Streamable;
|
||||
|
||||
/**
|
||||
* Represents attributes of an AI player.
|
||||
*/
|
||||
public class GameAI
|
||||
implements Streamable
|
||||
{
|
||||
/** The "personality" of the AI, which can be interpreted by
|
||||
* each puzzle. */
|
||||
public var personality :int;
|
||||
|
||||
/** The skill level of the AI. */
|
||||
public var skill :int;
|
||||
|
||||
/**
|
||||
* Constructs an AI with the specified (game-interpreted) skill and
|
||||
* personality.
|
||||
*/
|
||||
public function GameAI (personality :int = 0, skill :int = 0)
|
||||
{
|
||||
this.personality = personality;
|
||||
this.skill = skill;
|
||||
}
|
||||
|
||||
// from Streamable
|
||||
public function writeObject (out :ObjectOutputStream) :void
|
||||
{
|
||||
out.writeInt(personality);
|
||||
out.writeInt(skill);
|
||||
}
|
||||
|
||||
// from Streamable
|
||||
public function readObject (ins :ObjectInputStream) :void
|
||||
{
|
||||
personality = ins.readInt();
|
||||
skill = ins.readInt();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
//
|
||||
// $Id: PuzzleCodes.java 3184 2004-10-28 19:20:27Z mdb $
|
||||
//
|
||||
// Narya library - tools for developing networked games
|
||||
// Copyright (C) 2002-2004 Three Rings Design, Inc., All Rights Reserved
|
||||
// http://www.threerings.net/code/narya/
|
||||
//
|
||||
// This library is free software; you can redistribute it and/or modify it
|
||||
// under the terms of the GNU Lesser General Public License as published
|
||||
// by the Free Software Foundation; either version 2.1 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This library is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
// Lesser General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public
|
||||
// License along with this library; if not, write to the Free Software
|
||||
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
package com.threerings.parlor.game.data {
|
||||
|
||||
import com.threerings.presents.data.InvocationCodes;
|
||||
|
||||
/**
|
||||
* Constants relating to the game services.
|
||||
*/
|
||||
public class GameCodes extends InvocationCodes
|
||||
{
|
||||
/** The message bundle identifier for general game messages. */
|
||||
public static const GAME_MESSAGE_BUNDLE :String = "game.general";
|
||||
|
||||
/** The name of the message event to a placeObject that a player
|
||||
* was knocked out of a puzzle. */
|
||||
public static const PLAYER_KNOCKED_OUT :String = "playerKnocked";
|
||||
|
||||
/** The name of the message event to a placeObject that reports
|
||||
* the winners and losers of a game. */
|
||||
public static const WINNERS_AND_LOSERS :String = "winnersAndLosers";
|
||||
|
||||
/** A chat type for chatting on the game object. */
|
||||
public static const GAME_CHAT_TYPE :String = "gameChat";
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,162 @@
|
||||
//
|
||||
// $Id: GameConfig.java 4026 2006-04-18 01:32:41Z mdb $
|
||||
//
|
||||
// Narya library - tools for developing networked games
|
||||
// Copyright (C) 2002-2004 Three Rings Design, Inc., All Rights Reserved
|
||||
// http://www.threerings.net/code/narya/
|
||||
//
|
||||
// This library is free software; you can redistribute it and/or modify it
|
||||
// under the terms of the GNU Lesser General Public License as published
|
||||
// by the Free Software Foundation; either version 2.1 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This library is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
// Lesser General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public
|
||||
// License along with this library; if not, write to the Free Software
|
||||
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
package com.threerings.parlor.game.data {
|
||||
|
||||
import com.threerings.util.ClassUtil;
|
||||
import com.threerings.util.Cloneable;
|
||||
import com.threerings.util.Hashable;
|
||||
import com.threerings.util.Name;
|
||||
|
||||
import com.threerings.io.TypedArray;
|
||||
|
||||
import com.threerings.crowd.data.PlaceConfig;
|
||||
|
||||
import com.threerings.parlor.client.TableConfigurator;
|
||||
import com.threerings.parlor.game.client.GameConfigurator;
|
||||
|
||||
/**
|
||||
* The game config class encapsulates the configuration information for a
|
||||
* particular type of game. The hierarchy of game config objects mimics the
|
||||
* hierarchy of game managers and controllers. Both the game manager and game
|
||||
* controller are provided with the game config object when the game is
|
||||
* created.
|
||||
*
|
||||
* <p> The game config object is also the mechanism used to instantiate the
|
||||
* appropriate game manager and controller. Every game must have an associated
|
||||
* game config derived class that overrides {@link #createController} and
|
||||
* {@link #getManagerClassName}, returning the appropriate game controller and
|
||||
* manager class for that game. Thus the entire chain of events that causes a
|
||||
* particular game to be created is the construction of the appropriate game
|
||||
* config instance which is provided to the server as part of an invitation or
|
||||
* via some other matchmaking mechanism.
|
||||
*/
|
||||
public /*abstract*/ class GameConfig extends PlaceConfig
|
||||
implements Cloneable, Hashable
|
||||
{
|
||||
/** The usernames of the players involved in this game, or an empty
|
||||
* array if such information is not needed by this particular game. */
|
||||
public var players :TypedArray = TypedArray.create(Name);
|
||||
|
||||
/** Indicates whether or not this game is rated. */
|
||||
public var rated :Boolean = true;
|
||||
|
||||
/** Configurations for AIs to be used in this game. Slots with real
|
||||
* players should be null and slots with AIs should contain
|
||||
* configuration for those AIs. A null array indicates no use of AIs
|
||||
* at all. */
|
||||
public var ais :TypedArray = TypedArray.create(GameAI);
|
||||
|
||||
/**
|
||||
* Returns the message bundle identifier for the bundle that should be
|
||||
* used to translate the translatable strings used to describe the
|
||||
* game config parameters.
|
||||
*/
|
||||
public function getBundleName () :String
|
||||
{
|
||||
Log.getLog(this).warning("this method is actually abstract.");
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a configurator that can be used to create a user interface
|
||||
* for configuring this instance prior to starting the game. If no
|
||||
* configuration is necessary, this method should return null.
|
||||
*/
|
||||
public function createConfigurator () :GameConfigurator
|
||||
|
||||
/**
|
||||
* Creates a table configurator for initializing 'table' properties
|
||||
* of the game. The default implementation returns null.
|
||||
*/
|
||||
public function createTableConfigurator () :TableConfigurator
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a translatable label describing this game.
|
||||
*/
|
||||
public function getGameName () :String
|
||||
{
|
||||
// the whole getRatingTypeId(), getGameName(), getBundleName()
|
||||
// business should be cleaned up. we should have getGameIdent()
|
||||
// and everything should have a default implementation using that
|
||||
return "m." + getBundleName();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the game rating type, if the system uses such things.
|
||||
*/
|
||||
public function getRatingTypeId () :int
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an Array of strings that describe the configuration of this
|
||||
* game. Default implementation returns an empty array.
|
||||
*/
|
||||
public function getDescription () :Array
|
||||
{
|
||||
return new Array(); // nothing by default
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if this game config object is equal to the supplied
|
||||
* object (meaning it is also a game config object and its
|
||||
* configuration settings are the same as ours).
|
||||
*/
|
||||
public function equals (other :Object) :Boolean
|
||||
{
|
||||
// make sure they're of the same class
|
||||
if (ClassUtil.getClassName(other) == ClassUtil.getClassName(this)) {
|
||||
var that :GameConfig = GameConfig(other);
|
||||
return this.rated == that.rated;
|
||||
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Computes a hashcode for this game config object that supports our
|
||||
* {@link #equals} implementation. Objects that are equal should have
|
||||
* the same hashcode.
|
||||
*/
|
||||
public function hashCode () :int
|
||||
{
|
||||
// look ma, it's so sophisticated!
|
||||
return StringUtil.hashCode(ClassUtil.getClassName(this)) +
|
||||
(rated ? 1 : 0);
|
||||
}
|
||||
|
||||
// from Cloneable
|
||||
public function clone () :Object
|
||||
{
|
||||
var copy :GameConfig = ClassUtil.newInstance(this);
|
||||
copy.players = this.players;
|
||||
copy.rated = this.rated;
|
||||
copy.ais = this.ais;
|
||||
|
||||
return copy;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,49 @@
|
||||
//
|
||||
// $Id: GameMarshaller.java 4145 2006-05-24 01:24:24Z ray $
|
||||
//
|
||||
// Narya library - tools for developing networked games
|
||||
// Copyright (C) 2002-2006 Three Rings Design, Inc., All Rights Reserved
|
||||
// http://www.threerings.net/code/narya/
|
||||
//
|
||||
// This library is free software; you can redistribute it and/or modify it
|
||||
// under the terms of the GNU Lesser General Public License as published
|
||||
// by the Free Software Foundation; either version 2.1 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This library is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
// Lesser General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public
|
||||
// License along with this library; if not, write to the Free Software
|
||||
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
package com.threerings.parlor.game.data {
|
||||
|
||||
import com.threerings.parlor.game.client.GameService;
|
||||
import com.threerings.presents.client.Client;
|
||||
import com.threerings.presents.data.InvocationMarshaller;
|
||||
import com.threerings.presents.dobj.InvocationResponseEvent;
|
||||
|
||||
/**
|
||||
* Provides the implementation of the {@link GameService} 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 GameMarshaller extends InvocationMarshaller
|
||||
implements GameService
|
||||
{
|
||||
/** The method id used to dispatch {@link #playerReady} requests. */
|
||||
public static const PLAYER_READY :int = 1;
|
||||
|
||||
// documentation inherited from interface
|
||||
public function playerReady (arg1 :Client) :void
|
||||
{
|
||||
sendRequest(arg1, PLAYER_READY, [ ]);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,442 @@
|
||||
//
|
||||
// $Id: GameObject.java 4191 2006-06-13 22:42:20Z ray $
|
||||
//
|
||||
// Narya library - tools for developing networked games
|
||||
// Copyright (C) 2002-2004 Three Rings Design, Inc., All Rights Reserved
|
||||
// http://www.threerings.net/code/narya/
|
||||
//
|
||||
// This library is free software; you can redistribute it and/or modify it
|
||||
// under the terms of the GNU Lesser General Public License as published
|
||||
// by the Free Software Foundation; either version 2.1 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This library is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
// Lesser General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public
|
||||
// License along with this library; if not, write to the Free Software
|
||||
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
package com.threerings.parlor.game.data {
|
||||
|
||||
import com.threerings.util.Integer;
|
||||
import com.threerings.util.langBoolean;
|
||||
import com.threerings.util.Name;
|
||||
|
||||
import com.threerings.io.TypedArray;
|
||||
|
||||
import com.threerings.crowd.data.PlaceObject;
|
||||
|
||||
/**
|
||||
* A game object hosts the shared data associated with a game played by
|
||||
* one or more players. The game object extends the place object so that
|
||||
* the game can act as a place where players actually go when playing the
|
||||
* game. Only very basic information is maintained in the base game
|
||||
* object. It serves as the base for a hierarchy of game object
|
||||
* derivatives that handle basic gameplay for a suite of different game
|
||||
* types (ie. turn based games, party games, board games, card games,
|
||||
* etc.).
|
||||
*/
|
||||
public class GameObject extends PlaceObject
|
||||
{
|
||||
// AUTO-GENERATED: FIELDS START
|
||||
/** The field name of the <code>gameService</code> field. */
|
||||
public static const GAME_SERVICE :String = "gameService";
|
||||
|
||||
/** The field name of the <code>state</code> field. */
|
||||
public static const STATE :String = "state";
|
||||
|
||||
/** The field name of the <code>isRated</code> field. */
|
||||
public static const IS_RATED :String = "isRated";
|
||||
|
||||
/** The field name of the <code>isPrivate</code> field. */
|
||||
public static const IS_PRIVATE :String = "isPrivate";
|
||||
|
||||
/** The field name of the <code>players</code> field. */
|
||||
public static const PLAYERS :String = "players";
|
||||
|
||||
/** The field name of the <code>winners</code> field. */
|
||||
public static const WINNERS :String = "winners";
|
||||
|
||||
/** The field name of the <code>roundId</code> field. */
|
||||
public static const ROUND_ID :String = "roundId";
|
||||
|
||||
/** The field name of the <code>playerStatus</code> field. */
|
||||
public static const PLAYER_STATUS :String = "playerStatus";
|
||||
// AUTO-GENERATED: FIELDS END
|
||||
|
||||
/** A game state constant indicating that the game has not yet started
|
||||
* and is still awaiting the arrival of all of the players. */
|
||||
public static const PRE_GAME :int = 0;
|
||||
|
||||
/** A game state constant indicating that the game is in play. */
|
||||
public static const IN_PLAY :int = 1;
|
||||
|
||||
/** A game state constant indicating that the game ended normally. */
|
||||
public static const GAME_OVER :int = 2;
|
||||
|
||||
/** A game state constant indicating that the game was cancelled. */
|
||||
public static const CANCELLED :int = 3;
|
||||
|
||||
/** The player status constant for a player whose game is in play. */
|
||||
public static const PLAYER_IN_PLAY :int = 0;
|
||||
|
||||
/** The player status constant for a player whose has been knocked out
|
||||
* of the game. NOTE: This can include a player choosing to leave a
|
||||
* game prematurely. */
|
||||
public static const PLAYER_LEFT_GAME :int = 1;
|
||||
|
||||
/** Provides general game invocation services. */
|
||||
public var gameService :GameMarshaller;
|
||||
|
||||
/** The game state, one of {@link #PRE_GAME}, {@link #IN_PLAY},
|
||||
* {@link #GAME_OVER}, or {@link #CANCELLED}. */
|
||||
public var state :int = PRE_GAME;
|
||||
|
||||
/** Indicates whether or not this game is rated. */
|
||||
public var isRated :Boolean;
|
||||
|
||||
/** Indicates whether the game is "private". */
|
||||
public var isPrivate :Boolean;
|
||||
|
||||
/** The usernames of the players involved in this game. */
|
||||
public var players :TypedArray; /* of Name */
|
||||
|
||||
/** Whether each player in the game is a winner, or <code>null</code>
|
||||
* if the game is not yet over. */
|
||||
public var winners :TypedArray; /* of Boolean */
|
||||
|
||||
/** The unique round identifier for the current round. */
|
||||
public var roundId :int;
|
||||
|
||||
/** If null, indicates that all present players are active, or for
|
||||
* more complex games can be non-null to indicate the current status
|
||||
* of each player in the game. The status value is one of
|
||||
* {@link #PLAYER_LEFT_GAME} or {@link #PLAYER_IN_PLAY}. */
|
||||
public var playerStatus :TypedArray; /* of int */
|
||||
|
||||
/**
|
||||
* Returns the number of players in the game.
|
||||
*/
|
||||
public function getPlayerCount () :int
|
||||
{
|
||||
var count :int = 0;
|
||||
var size :int = players.length;
|
||||
for (var ii :int = 0; ii < size; ii++) {
|
||||
if (players[ii] != null) {
|
||||
count++;
|
||||
}
|
||||
}
|
||||
return count;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the number of active players in the game.
|
||||
*/
|
||||
public function getActivePlayerCount () :int
|
||||
{
|
||||
var count :int = 0;
|
||||
var size :int = players.length;
|
||||
for (var ii :int = 0; ii < size; ii++) {
|
||||
if (isActivePlayer(ii)) {
|
||||
count++;
|
||||
}
|
||||
}
|
||||
return count;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether the given player is still an active player in
|
||||
* the game. (Ie. whether or not they are still participating.)
|
||||
*/
|
||||
public function isActivePlayer (pidx :int) :Boolean
|
||||
{
|
||||
return isOccupiedPlayer(pidx) &&
|
||||
(playerStatus == null || isActivePlayerStatus(playerStatus[pidx]));
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the player index of the given user in the game, or
|
||||
* <code>-1</code> if the player is not involved in the game.
|
||||
*/
|
||||
public function getPlayerIndex (username :Name) :int
|
||||
{
|
||||
return ArrayUtil.indexOf(players, username);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether the game is in play. A game that is not in play
|
||||
* could either be awaiting players, ended, or cancelled.
|
||||
*/
|
||||
public function isInPlay () :Boolean
|
||||
{
|
||||
return (state == IN_PLAY);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether the given player index in the game is occupied.
|
||||
*/
|
||||
public function isOccupiedPlayer (pidx :int) :Boolean
|
||||
{
|
||||
return (pidx >= 0 && pidx < players.length) && (players[pidx] != null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether the given player index is a winner, or false if the
|
||||
* winners are not yet assigned.
|
||||
*/
|
||||
public function isWinner (pidx :int) :Boolean
|
||||
{
|
||||
return (winners != null) && winners[pidx];
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the number of winners for this game, or <code>0</code> if
|
||||
* the winners array is not populated, e.g., the game is not yet over.
|
||||
*/
|
||||
public function getWinnerCount () :int
|
||||
{
|
||||
int count = 0;
|
||||
if (winners != null) {
|
||||
for (var ii :int = 0; ii < winners.length; ii++) {
|
||||
if (winners[ii]) {
|
||||
count++;
|
||||
}
|
||||
}
|
||||
}
|
||||
return count;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if the game is ended in a draw.
|
||||
*/
|
||||
public function isDraw () :Boolean
|
||||
{
|
||||
return getWinnerCount() == getPlayerCount();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the winner index of the first winning player for this game,
|
||||
* or <code>-1</code> if there are no winners or the winners array is
|
||||
* not yet assigned. This is only likely to be useful for games that
|
||||
* are known to have a single winner.
|
||||
*/
|
||||
public function getWinnerIndex () :int
|
||||
{
|
||||
return ArrayUtil.indexOf(winners, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the type of party game being played or NOT_PARTY_GAME.
|
||||
* {@link PartyGameConfig}.
|
||||
*/
|
||||
public function getPartyGameType () :int
|
||||
{
|
||||
return PartyGameConfig.NOT_PARTY_GAME;
|
||||
}
|
||||
|
||||
/**
|
||||
* Used by {@link #isActivePlayer} to determine if the supplied status is
|
||||
* associated with an active player (one that has not resigned from the
|
||||
* game and/or left the game room).
|
||||
*/
|
||||
protected function isActivePlayerStatus (playerStatus :int) :Boolean
|
||||
{
|
||||
return playerStatus == PLAYER_IN_PLAY;
|
||||
}
|
||||
|
||||
override protected function whichBuf (buf :StringBuilder) :void
|
||||
{
|
||||
super.whichBuf(buf);
|
||||
buf.append(players.join());
|
||||
buf.append(":").append(state);
|
||||
}
|
||||
|
||||
// AUTO-GENERATED: METHODS START
|
||||
/**
|
||||
* Requests that the <code>gameService</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 setGameService (value :GameMarshaller) :void
|
||||
{
|
||||
var ovalue :GameMarshaller = this.gameService;
|
||||
requestAttributeChange(
|
||||
GAME_SERVICE, value, ovalue);
|
||||
this.gameService = value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Requests that the <code>state</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 setState (value :int) :void
|
||||
{
|
||||
var ovalue :int = this.state;
|
||||
requestAttributeChange(
|
||||
STATE, Integer.valueOf(value), Integer.valueOf(ovalue));
|
||||
this.state = value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Requests that the <code>isRated</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 setIsRated (value :Boolean) :void
|
||||
{
|
||||
var ovalue :Boolean = this.isRated;
|
||||
requestAttributeChange(
|
||||
IS_RATED, langBoolean.valueOf(value), langBoolean.valueOf(ovalue));
|
||||
this.isRated = value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Requests that the <code>isPrivate</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 setIsPrivate (value :Boolean) :void
|
||||
{
|
||||
var ovalue :Boolean = this.isPrivate;
|
||||
requestAttributeChange(
|
||||
IS_PRIVATE, langBoolean.valueOf(value),
|
||||
langBoolean.valueOf(ovalue));
|
||||
this.isPrivate = value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Requests that the <code>players</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 setPlayers (value :TypedArray) :void
|
||||
{
|
||||
var ovalue :TypedArray = this.players;
|
||||
requestAttributeChange(
|
||||
PLAYERS, value, ovalue);
|
||||
this.players = (value == null) ? null : (value.clone() as TypedArray);
|
||||
}
|
||||
|
||||
/**
|
||||
* Requests that the <code>index</code>th element of
|
||||
* <code>players</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 setPlayersAt (value :Name, index :int) :void
|
||||
{
|
||||
var ovalue :Name = (this.players[index] as Name);
|
||||
requestElementUpdate(
|
||||
PLAYERS, index, value, ovalue);
|
||||
this.players[index] = value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Requests that the <code>winners</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 setWinners (value :TypedArray) :void
|
||||
{
|
||||
var ovalue :TypedArray = this.winners;
|
||||
requestAttributeChange(
|
||||
WINNERS, value, ovalue);
|
||||
this.winners = (value == null) ? null : (value.clone() as TypedArray);
|
||||
}
|
||||
|
||||
/**
|
||||
* Requests that the <code>index</code>th element of
|
||||
* <code>winners</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 setWinnersAt (value :Boolean, index :int) :void
|
||||
{
|
||||
var ovalue :Boolean = (this.winners[index] as Boolean);
|
||||
requestElementUpdate(
|
||||
WINNERS, index, langBoolean.valueOf(value),
|
||||
langBoolean.valueOf(ovalue));
|
||||
this.winners[index] = value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Requests that the <code>roundId</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 setRoundId (value :int) :void
|
||||
{
|
||||
var ovalue :int = this.roundId;
|
||||
requestAttributeChange(
|
||||
ROUND_ID, Integer.valueOf(value), Integer.valueOf(ovalue));
|
||||
this.roundId = value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Requests that the <code>playerStatus</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 setPlayerStatus (value :TypedArray) :void
|
||||
{
|
||||
var ovalue :TypedArray = this.playerStatus;
|
||||
requestAttributeChange(
|
||||
PLAYER_STATUS, value, ovalue);
|
||||
this.playerStatus = (value == null) ? null
|
||||
: (value.clone() as TypedArray);
|
||||
}
|
||||
|
||||
/**
|
||||
* Requests that the <code>index</code>th element of
|
||||
* <code>playerStatus</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 setPlayerStatusAt (value :int, index :int) :void
|
||||
{
|
||||
var ovalue :int = (this.playerStatus[index] as int);
|
||||
requestElementUpdate(
|
||||
PLAYER_STATUS, index, Integer.valueOf(value),
|
||||
Integer.valueOf(ovalue));
|
||||
this.playerStatus[index] = value;
|
||||
}
|
||||
// AUTO-GENERATED: METHODS END
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,51 @@
|
||||
//
|
||||
// $Id: PartyGameConfig.java 3804 2006-01-13 01:52:36Z ray $
|
||||
//
|
||||
// Narya library - tools for developing networked games
|
||||
// Copyright (C) 2002-2004 Three Rings Design, Inc., All Rights Reserved
|
||||
// http://www.threerings.net/code/narya/
|
||||
//
|
||||
// This library is free software; you can redistribute it and/or modify it
|
||||
// under the terms of the GNU Lesser General Public License as published
|
||||
// by the Free Software Foundation; either version 2.1 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This library is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
// Lesser General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public
|
||||
// License along with this library; if not, write to the Free Software
|
||||
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
package com.threerings.parlor.game.data {
|
||||
|
||||
/**
|
||||
* Provides additional information for party games.
|
||||
* A party game is a game in which the players are not set prior to starting,
|
||||
* but players can come and go at will during the normal progression of
|
||||
* the game.
|
||||
*/
|
||||
public interface PartyGameConfig
|
||||
{
|
||||
/** Party game constant indicating that this game, while it does
|
||||
* implement PartyGameConfig, is not currently being played in party
|
||||
* mode. */
|
||||
public static const NOT_PARTY_GAME :int = 0;
|
||||
|
||||
/** Party game constant indicating that we're in a party game in which
|
||||
* players must sit at an available seat to play, otherwise they're
|
||||
* an observer. */
|
||||
public static const SEATED_PARTY_GAME :int = 1;
|
||||
|
||||
/** Party game constant indicating that everyone in the game place is
|
||||
* a "player", meaning that they do not need to claim a seat to play. */
|
||||
public static const FREE_FOR_ALL_PARTY_GAME :int = 2;
|
||||
|
||||
/**
|
||||
* Get the type of party game being played.
|
||||
*/
|
||||
function getPartyGameType () :int;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
//
|
||||
// $Id: ParlorContext.java 4191 2006-06-13 22:42:20Z ray $
|
||||
//
|
||||
// Narya library - tools for developing networked games
|
||||
// Copyright (C) 2002-2004 Three Rings Design, Inc., All Rights Reserved
|
||||
// http://www.threerings.net/code/narya/
|
||||
//
|
||||
// This library is free software; you can redistribute it and/or modify it
|
||||
// under the terms of the GNU Lesser General Public License as published
|
||||
// by the Free Software Foundation; either version 2.1 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This library is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
// Lesser General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public
|
||||
// License along with this library; if not, write to the Free Software
|
||||
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
package com.threerings.parlor.util {
|
||||
|
||||
import com.threerings.crowd.util.CrowdContext;
|
||||
import com.threerings.parlor.client.ParlorDirector;
|
||||
|
||||
/**
|
||||
* The parlor context provides access to the various managers, etc. that
|
||||
* are needed by the parlor client code.
|
||||
*/
|
||||
public interface ParlorContext extends CrowdContext
|
||||
{
|
||||
/**
|
||||
* Returns a reference to the parlor director.
|
||||
*/
|
||||
function getParlorDirector () :ParlorDirector;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user