More progress on parlor services (mostly invitation handling).
git-svn-id: svn+ssh://src.earth.threerings.net/narya/trunk@365 542714f4-19e9-0310-aa3c-eee0fc999fb1
This commit is contained in:
@@ -0,0 +1,33 @@
|
||||
//
|
||||
// $Id: InvitationHandler.java,v 1.1 2001/10/01 05:07:13 mdb Exp $
|
||||
|
||||
package com.threerings.parlor.client;
|
||||
|
||||
import com.threerings.parlor.data.GameConfig;
|
||||
|
||||
/**
|
||||
* 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 inviteId this invitation's unique id.
|
||||
* @param inviter the username of the user that sent the invitation.
|
||||
* @param config the configuration of the game to which we are being
|
||||
* invited.
|
||||
*/
|
||||
public void invitationReceived (int inviteId, String inviter,
|
||||
GameConfig config);
|
||||
|
||||
/**
|
||||
* Called when an invitation is cancelled by the inviting player.
|
||||
*
|
||||
* @param inviteId this invitation's unique id.
|
||||
*/
|
||||
public void invitationCancelled (int inviteId);
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
//
|
||||
// $Id: InvitationResponseObserver.java,v 1.2 2001/10/01 02:57:37 mdb Exp $
|
||||
// $Id: InvitationResponseObserver.java,v 1.3 2001/10/01 05:07:13 mdb Exp $
|
||||
|
||||
package com.threerings.parlor.client;
|
||||
|
||||
@@ -12,16 +12,21 @@ import com.threerings.parlor.data.GameConfig;
|
||||
* is adjusted by the invited player and proposed back to the inviting
|
||||
* player.
|
||||
*/
|
||||
public interface InvitationObserver
|
||||
public interface InvitationResponseObserver
|
||||
{
|
||||
/**
|
||||
* Called if the invitation was accepted.
|
||||
*
|
||||
* @param inviteId the unique id of the invitation for which we
|
||||
* received a response.
|
||||
*/
|
||||
public void invitationAccepted (int inviteId);
|
||||
|
||||
/**
|
||||
* Called if the invitation was rejected.
|
||||
*
|
||||
* @param inviteId the unique id of the invitation for which we
|
||||
* received a response.
|
||||
* @param message a message provided by the rejecting user explaining
|
||||
* the reason for their rejection, or the empty string if no message
|
||||
* was provided.
|
||||
@@ -32,6 +37,8 @@ public interface InvitationObserver
|
||||
* Called if the invitation was countered with an alternate game
|
||||
* configuration.
|
||||
*
|
||||
* @param inviteId the unique id of the invitation for which we
|
||||
* received a response.
|
||||
* @param config the game configuration proposed by the invited
|
||||
* player.
|
||||
*/
|
||||
|
||||
@@ -1,8 +1,10 @@
|
||||
//
|
||||
// $Id: ParlorDirector.java,v 1.1 2001/10/01 02:56:35 mdb Exp $
|
||||
// $Id: ParlorDirector.java,v 1.2 2001/10/01 05:07:13 mdb Exp $
|
||||
|
||||
package com.threerings.parlor.client;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Iterator;
|
||||
import com.samskivert.util.HashIntMap;
|
||||
|
||||
import com.threerings.parlor.Log;
|
||||
@@ -18,6 +20,32 @@ import com.threerings.parlor.util.ParlorContext;
|
||||
*/
|
||||
public class ParlorDirector
|
||||
{
|
||||
/**
|
||||
* 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 ParlorDirector (ParlorContext ctx)
|
||||
{
|
||||
_ctx = ctx;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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 void setInvitationHandler (InvitationHandler handler)
|
||||
{
|
||||
_handler = handler;
|
||||
}
|
||||
|
||||
/**
|
||||
* Requests that the named user be invited to a game described by the
|
||||
* supplied game config.
|
||||
@@ -25,29 +53,89 @@ public class ParlorDirector
|
||||
* @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 wants to know about accepted,
|
||||
* rejected or countered invitations.
|
||||
* @param observer the entity that will be notified if this invitation
|
||||
* is accepted, rejected or countered.
|
||||
*
|
||||
* @return a unique id associated with this invitation that can be
|
||||
* used to discern between various outstanding invitations by the
|
||||
* invitation observer.
|
||||
*/
|
||||
public int invite (ParlorContext ctx, String invitee,
|
||||
GameConfig config, InvitationObserver observer)
|
||||
public int invite (String invitee, GameConfig config,
|
||||
InvitationResponseObserver observer)
|
||||
{
|
||||
// generate the invocation service request
|
||||
int invid = ParlorService.invite(
|
||||
ctx.getClient(), invitee, config, this);
|
||||
_ctx.getClient(), invitee, config, this);
|
||||
|
||||
// create an invitation record and put it in the submitted table
|
||||
Invitation invite = new Invitation(invitee, config, observer);
|
||||
_submittedInvites.put(invid, invite);
|
||||
return invite.localId;
|
||||
return invite.inviteId;
|
||||
}
|
||||
|
||||
public void counter (ParlorContext ctx, int inviteId,
|
||||
GameConfig config, InvitationObserver observer)
|
||||
/**
|
||||
* Counters a received invitation with an invitation with different
|
||||
* game configuration parameters.
|
||||
*
|
||||
* @param inviteId the id of the received invitation.
|
||||
* @param config the updated game configuration.
|
||||
* @param observer the entity that will be notified if this
|
||||
* counter-invitation is accepted, rejected or countered.
|
||||
*/
|
||||
public void counter (int inviteId, GameConfig config,
|
||||
InvitationResponseObserver observer)
|
||||
{
|
||||
// look up the invitation record (oh the two separate key spaces
|
||||
// humanity)
|
||||
Invitation invite = getInviteByLocalId(inviteId);
|
||||
if (invite == null) {
|
||||
// complain if we didn't find a matching invitation
|
||||
Log.warning("Received request to counter non-existent " +
|
||||
"invitation [inviteId=" + inviteId +
|
||||
", config=" + config + "].");
|
||||
return;
|
||||
}
|
||||
|
||||
// update the invitation record with the observer (who will
|
||||
// eventually be hearing back from the other client about their
|
||||
// counter-invitation)
|
||||
invite.observer = observer;
|
||||
|
||||
// generate the invocation service request
|
||||
ParlorService.respond(_ctx.getClient(), invite.remoteId,
|
||||
ParlorService.INVITATION_COUNTERED,
|
||||
config, this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Issues a request to cancel an outstanding invitation.
|
||||
*
|
||||
* @param inviteId the id of the invitation to cancel.
|
||||
*/
|
||||
public void cancel (int inviteId)
|
||||
{
|
||||
// look up the invitation record (oh the two separate key spaces
|
||||
// humanity)
|
||||
Invitation invite = getInviteByLocalId(inviteId);
|
||||
if (invite == null) {
|
||||
// complain if we didn't find a matching invitation
|
||||
Log.warning("Received request to cancel non-existent " +
|
||||
"invitation [inviteId=" + inviteId + "].");
|
||||
return;
|
||||
}
|
||||
|
||||
// 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 (invite.remoteId == -1) {
|
||||
invite.cancelled = true;
|
||||
|
||||
} else {
|
||||
// otherwise, generate the invocation service request
|
||||
ParlorService.cancel(_ctx.getClient(), invite.remoteId, this);
|
||||
// and remove it from the pending table
|
||||
_pendingInvites.remove(invite.remoteId);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -63,23 +151,59 @@ public class ParlorDirector
|
||||
public void handleInviteNotification (
|
||||
int remoteId, String inviter, GameConfig config)
|
||||
{
|
||||
// create an invitation record for this invitation
|
||||
Invitation invite = new Invitation(inviter, config, null);
|
||||
invite.remoteId = remoteId;
|
||||
|
||||
// put it in the pending invitations table
|
||||
_pendingInvites.put(remoteId, invite);
|
||||
|
||||
try {
|
||||
// notify the invitation handler of the incoming invitation
|
||||
_handler.invitationReceived(invite.inviteId, inviter, config);
|
||||
|
||||
} catch (Exception e) {
|
||||
Log.warning("Invitation handler choked on invite " +
|
||||
"notification [inviteId=" + invite.inviteId +
|
||||
", inviter=" + inviter +
|
||||
", config=" + config + "].");
|
||||
Log.logStackTrace(e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Called by the invocation services when another user has responded
|
||||
* to our invitation.
|
||||
* to our invitation by either accepting, rejecting or countering it.
|
||||
*
|
||||
* @param remoteId the unique indentifier for the invitation.
|
||||
* @param code the response code {@link
|
||||
* @param code the response code, either {@link
|
||||
* ParlorService#INVITATION_ACCEPTED} or {@link
|
||||
* ParlorService#INVITATION_REJECTED}.
|
||||
* @param message in the case of a rejected invitation, a message
|
||||
* provided by the invited user explaining the rejection. The empty
|
||||
* string if no explanation was provided.
|
||||
* ParlorService#INVITATION_REJECTED} or {@link
|
||||
* ParlorService#INVITATION_COUNTERED}.
|
||||
* @param arg in the case of a rejected invitation, a string
|
||||
* containing a message provided by the invited user explaining the
|
||||
* reason for rejection (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.
|
||||
*/
|
||||
public void handleResponseNotification (
|
||||
int remoteId, int code, String message)
|
||||
public void handleRespondInviteNotification (
|
||||
int remoteId, int code, Object arg)
|
||||
{
|
||||
// look up the invitation record for this invitation
|
||||
Invitation invite = (Invitation)_pendingInvites.get(remoteId);
|
||||
if (invite == null) {
|
||||
Log.warning("Have no record of invitation for which we " +
|
||||
"received a response?! [remoteId=" + remoteId +
|
||||
", code=" + code + ", arg=" + arg + "].");
|
||||
return;
|
||||
}
|
||||
|
||||
// make sure we have an observer to notify
|
||||
if (invite.observer == null) {
|
||||
Log.warning("No observer registered for invitation " +
|
||||
invite + ".");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -90,7 +214,7 @@ public class ParlorDirector
|
||||
* @param config the configuration information for the game to which
|
||||
* we've been invited.
|
||||
*/
|
||||
public void handleInviteNotification (String inviter, GameConfig config)
|
||||
public void handleCancelInviteNotification (String inviter, GameConfig config)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -104,7 +228,7 @@ public class ParlorDirector
|
||||
{
|
||||
// remove the invitation record from the submitted table and put
|
||||
// it in the pending table
|
||||
Invitation invite = (Invitation)_submittedInvites.get(invid);
|
||||
Invitation invite = (Invitation)_submittedInvites.remove(invid);
|
||||
if (invite == null) {
|
||||
Log.warning("Received accepted notification for non-existent " +
|
||||
"invitation request!? [invid=" + invid +
|
||||
@@ -115,8 +239,16 @@ public class ParlorDirector
|
||||
// now that we know the invitation's unique id, keep track of it
|
||||
invite.remoteId = remoteId;
|
||||
|
||||
// and put it in the new table
|
||||
_pendingInvites.put(remoteId, invite);
|
||||
// if the invitation was cancelled before we heard back about it,
|
||||
// we need to send off a cancellation request now
|
||||
if (invite.cancelled) {
|
||||
// generate the invocation service request to cancel it
|
||||
ParlorService.cancel(_ctx.getClient(), invite.remoteId, this);
|
||||
|
||||
} else {
|
||||
// otherwise, put it in the new table
|
||||
_pendingInvites.put(remoteId, invite);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -130,6 +262,10 @@ public class ParlorDirector
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* The invitation class is used to track information related to
|
||||
* outstanding invitations generated by or targeted to this client.
|
||||
*/
|
||||
protected static class Invitation
|
||||
{
|
||||
/** A unique id for this invitation assigned on the client which
|
||||
@@ -139,37 +275,82 @@ public class ParlorDirector
|
||||
* acknowlegedment from the server and we need to provide the
|
||||
* caller with some sort of unique id at the time the request is
|
||||
* generated. */
|
||||
public int localId = _localInvitationId++;
|
||||
public int inviteId = _localInvitationId++;
|
||||
|
||||
/** 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 int remoteId = -1;
|
||||
|
||||
/** The name of the user that was invited. */
|
||||
public String invitee;
|
||||
/** The name of the other user involved in this invitation. */
|
||||
public String opponent;
|
||||
|
||||
/** The configuration of the game to be created. */
|
||||
public GameConfig config;
|
||||
|
||||
/** The invitation observer that created this invitation. */
|
||||
public InvitationObserver observer;
|
||||
/** The entity to notify when we receive a response for this
|
||||
* invitation. */
|
||||
public InvitationResponseObserver observer;
|
||||
|
||||
/** A flag indicating that we were requested to abort this
|
||||
/** 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. */
|
||||
public boolean aborted = false;
|
||||
public boolean cancelled = false;
|
||||
|
||||
/** Constructs a new invitation request. */
|
||||
public Invitation (String invitee, GameConfig config,
|
||||
InvitationObserver observer)
|
||||
/** Constructs a new invitation record. */
|
||||
public Invitation (String opponent, GameConfig config,
|
||||
InvitationResponseObserver observer)
|
||||
{
|
||||
this.invitee = invitee;
|
||||
this.opponent = opponent;
|
||||
this.config = config;
|
||||
this.observer = observer;
|
||||
}
|
||||
|
||||
/** Returns a string representation of this invitation record. */
|
||||
public String toString ()
|
||||
{
|
||||
return "[inviteId=" + inviteId + ", remoteId=" + remoteId +
|
||||
", opponent=" + opponent + ", config=" + config +
|
||||
", observer=" + observer + ", cancelled=" + cancelled + "]";
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Looks up an invitation by its local unique identifier. Oh the dual
|
||||
* uid space humanity!
|
||||
*/
|
||||
protected Invitation getInviteByLocalId (int inviteId)
|
||||
{
|
||||
// first search the pending invites which is where we're most
|
||||
// likely to find it
|
||||
Iterator iter = _pendingInvites.values().iterator();
|
||||
while (iter.hasNext()) {
|
||||
Invitation match = (Invitation)iter.next();
|
||||
if (match.inviteId == inviteId) {
|
||||
return match;
|
||||
}
|
||||
}
|
||||
|
||||
// if that didn't work, look in the submitted invites
|
||||
iter = _submittedInvites.values().iterator();
|
||||
while (iter.hasNext()) {
|
||||
Invitation match = (Invitation)iter.next();
|
||||
if (match.inviteId == inviteId) {
|
||||
return match;
|
||||
}
|
||||
}
|
||||
|
||||
// il n'existe pas
|
||||
return null;
|
||||
}
|
||||
|
||||
/** An active parlor context. */
|
||||
protected ParlorContext _ctx;
|
||||
|
||||
/** The entity that has registered itself to handle incoming
|
||||
* invitation notifications. */
|
||||
protected InvitationHandler _handler;
|
||||
|
||||
/** A table of submitted (but not acknowledged) invitation requests,
|
||||
* keyed on invocation request id. */
|
||||
protected HashIntMap _submittedInvites = new HashIntMap();
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
//
|
||||
// $Id: ParlorService.java,v 1.1 2001/10/01 02:56:35 mdb Exp $
|
||||
// $Id: ParlorService.java,v 1.2 2001/10/01 05:07:13 mdb Exp $
|
||||
|
||||
package com.threerings.parlor.client;
|
||||
|
||||
@@ -24,17 +24,17 @@ public class ParlorService
|
||||
/** The module name for the parlor services. */
|
||||
public static final String MODULE = "parlor";
|
||||
|
||||
/** The message identifier for an invitation creation request. */
|
||||
public static final String INVITE_REQUEST = "Invite";
|
||||
/** The message identifier for an invitation creation request or
|
||||
* notification. */
|
||||
public static final String INVITE_ID = "Invite";
|
||||
|
||||
/** The message identifier for an invitation notification. */
|
||||
public static final String INVITE_NOTIFICATION = "Invite";
|
||||
/** The message identifier for an invitation cancellation request or
|
||||
* notification. */
|
||||
public static final String CANCEL_INVITE_ID = "CancelInvite";
|
||||
|
||||
/** The message identifier for an invitation response request. */
|
||||
public static final String RESPONSE_REQUEST = "Response";
|
||||
|
||||
/** The message identifier for an invitation response notification. */
|
||||
public static final String RESPONSE_NOTIFICATION = "Response";
|
||||
/** The message identifier for an invitation response request or
|
||||
* notification. */
|
||||
public static final String RESPOND_INVITE_ID = "RespondInvite";
|
||||
|
||||
/** The response code for an accepted invitation. */
|
||||
public static final int INVITATION_ACCEPTED = 0;
|
||||
@@ -42,17 +42,8 @@ public class ParlorService
|
||||
/** The response code for a rejected invitation. */
|
||||
public static final int INVITATION_REJECTED = 1;
|
||||
|
||||
/** The message identifier for an counter invitation request. */
|
||||
public static final String COUNTER_REQUEST = "Counter";
|
||||
|
||||
/** The message identifier for an countered invitation notification. */
|
||||
public static final String COUNTER_NOTIFICATION = "Counter";
|
||||
|
||||
/** The message identifier for an rescind invitation request. */
|
||||
public static final String RESCIND_REQUEST = "Rescind";
|
||||
|
||||
/** The message identifier for an rescinded invitation notification. */
|
||||
public static final String RESCIND_NOTIFICATION = "Rescind";
|
||||
/** The response code for a countered invitation. */
|
||||
public static final int INVITATION_COUNTERED = 2;
|
||||
|
||||
/**
|
||||
* You probably don't want to call this directly, but want to generate
|
||||
@@ -65,8 +56,8 @@ public class ParlorService
|
||||
* @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 rsptarget the parlor director reference that will receive and
|
||||
* process the response.
|
||||
* @param rsptarget the object reference that will receive and process
|
||||
* the response.
|
||||
*
|
||||
* @return the invocation request id of the generated request.
|
||||
*/
|
||||
@@ -77,6 +68,61 @@ public class ParlorService
|
||||
Object[] args = new Object[] { invitee, config };
|
||||
Log.info("Sending invite request [to=" + invitee +
|
||||
", cfg=" + config + "].");
|
||||
return invmgr.invoke(MODULE, INVITE_REQUEST, args, rsptarget);
|
||||
return invmgr.invoke(MODULE, INVITE_ID, args, rsptarget);
|
||||
}
|
||||
|
||||
/**
|
||||
* You probably don't want to call this directly, but want to call
|
||||
* {@link ParlorDirector#counter}. Requests that a counter-invitation 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 rsptarget the object reference that will receive and process
|
||||
* the response.
|
||||
*
|
||||
* @return the invocation request id of the generated request.
|
||||
*/
|
||||
public static int respond (Client client, int inviteId, int code,
|
||||
Object arg, Object rsptarget)
|
||||
{
|
||||
InvocationManager invmgr = client.getInvocationManager();
|
||||
Object[] args = new Object[] {
|
||||
new Integer(inviteId), new Integer(code), null };
|
||||
// we can't have a null argument so we use the empty string
|
||||
args[2] = (arg == null) ? "" : arg;
|
||||
Log.info("Sending invitation response [inviteId=" + inviteId +
|
||||
", code=" + code + ", arg=" + arg + "].");
|
||||
return invmgr.invoke(MODULE, RESPOND_INVITE_ID, args, rsptarget);
|
||||
}
|
||||
|
||||
/**
|
||||
* You probably don't want to call this directly, but want to call
|
||||
* {@link ParlorDirector#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 rsptarget the object reference that will receive and process
|
||||
* the response.
|
||||
*
|
||||
* @return the invocation request id of the generated request.
|
||||
*/
|
||||
public static int cancel (Client client, int inviteId, Object rsptarget)
|
||||
{
|
||||
InvocationManager invmgr = client.getInvocationManager();
|
||||
Object[] args = new Object[] { new Integer(inviteId) };
|
||||
Log.info("Sending invitation cancellation " +
|
||||
"[inviteId=" + inviteId + "].");
|
||||
return invmgr.invoke(MODULE, CANCEL_INVITE_ID, args, rsptarget);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
//
|
||||
// $Id: ParlorProvider.java,v 1.1 2001/10/01 02:56:35 mdb Exp $
|
||||
// $Id: ParlorProvider.java,v 1.2 2001/10/01 05:07:13 mdb Exp $
|
||||
|
||||
package com.threerings.parlor.server;
|
||||
|
||||
@@ -38,6 +38,24 @@ public class ParlorProvider extends InvocationProvider
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* Processes a request from the client to respond to an outstanding
|
||||
* invitation by accepting, refusing, or countering it.
|
||||
*/
|
||||
public void handleRepsondInviteRequest (
|
||||
BodyObject source, int invid, int inviteId, int code, Object arg)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* Processes a request from the client to cancel an outstanding
|
||||
* invitation.
|
||||
*/
|
||||
public void handleCancelInviteRequest (
|
||||
BodyObject source, int invid, int inviteId)
|
||||
{
|
||||
}
|
||||
|
||||
/** A reference to the parlor manager we're working with. */
|
||||
protected ParlorManager _pmgr;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user