diff --git a/src/as/com/threerings/parlor/client/ParlorService.as b/src/as/com/threerings/parlor/client/ParlorService.as index c1d779c7..3ddab760 100644 --- a/src/as/com/threerings/parlor/client/ParlorService.as +++ b/src/as/com/threerings/parlor/client/ParlorService.as @@ -60,5 +60,8 @@ public interface ParlorService extends InvocationService // from Java interface ParlorService function startSolitaire (arg1 :Client, arg2 :GameConfig, arg3 :InvocationService_ConfirmListener) :void; + + // from Java interface ParlorService + function startTableNow (arg1 :Client, arg2 :int, arg3 :int, arg4 :InvocationService_InvocationListener) :void; } } diff --git a/src/as/com/threerings/parlor/client/TableDirector.as b/src/as/com/threerings/parlor/client/TableDirector.as index e6640278..b82dde3c 100644 --- a/src/as/com/threerings/parlor/client/TableDirector.as +++ b/src/as/com/threerings/parlor/client/TableDirector.as @@ -218,6 +218,22 @@ public class TableDirector extends BasicDirector _pservice.leaveTable(_pctx.getClient(), _lobby.getOid(), tableId, this); } + /** + * Sends a request to have the specified table start now, even if + * all the seats have not yet been filled. + */ + public function startTableNow (tableId :int) :void + { + if (_lobby == null) { + log.warning("Requested to start a table but we're not " + + "currently in a place [tableId=" + tableId + "]."); + return; + } + + _pservice.startTableNow(_ctx.getClient(), _lobby.getOid(), + tableId, this); + } + // documentation inherited override public function clientDidLogoff (event :ClientEvent) :void { diff --git a/src/as/com/threerings/parlor/data/ParlorMarshaller.as b/src/as/com/threerings/parlor/data/ParlorMarshaller.as index 7b809e16..a7c9f5c6 100644 --- a/src/as/com/threerings/parlor/data/ParlorMarshaller.as +++ b/src/as/com/threerings/parlor/data/ParlorMarshaller.as @@ -138,5 +138,18 @@ public class ParlorMarshaller extends InvocationMarshaller arg2, listener3 ]); } + + /** The method id used to dispatch {@link #startTableNow} requests. */ + public static const START_TABLE_NOW :int = 8; + + // from interface ParlorService + public function startTableNow (arg1 :Client, arg2 :int, arg3 :int, arg4 :InvocationService_InvocationListener) :void + { + var listener4 :InvocationMarshaller_ListenerMarshaller = new InvocationMarshaller_ListenerMarshaller(); + listener4.listener = arg4; + sendRequest(arg1, START_TABLE_NOW, [ + Integer.valueOf(arg2), Integer.valueOf(arg3), listener4 + ]); + } } } diff --git a/src/java/com/threerings/parlor/client/ParlorService.java b/src/java/com/threerings/parlor/client/ParlorService.java index 4cab0964..a5e492b5 100644 --- a/src/java/com/threerings/parlor/client/ParlorService.java +++ b/src/java/com/threerings/parlor/client/ParlorService.java @@ -155,6 +155,16 @@ public interface ParlorService extends InvocationService public void leaveTable (Client client, int lobbyOid, int tableId, InvocationListener listener); + /** + * You probably don't want to call this directly, but want to call + * {@link TableDirector#startTableNow}. Requests that the specified + * table be started now, even if all seats are not occupied. This + * will always fail if called by any other player than that seated + * in position 0 (usually the creator). + */ + public void startTableNow (Client client, int lobbyOid, int tableId, + InvocationListener listener); + /** * Requests to start a single player game with the specified game * configuration. diff --git a/src/java/com/threerings/parlor/client/TableDirector.java b/src/java/com/threerings/parlor/client/TableDirector.java index 6f423e24..8c1adad4 100644 --- a/src/java/com/threerings/parlor/client/TableDirector.java +++ b/src/java/com/threerings/parlor/client/TableDirector.java @@ -214,6 +214,22 @@ public class TableDirector extends BasicDirector _pservice.leaveTable(_ctx.getClient(), _lobby.getOid(), tableId, this); } + /** + * Sends a request to have the specified table start now, even if + * all the seats have not yet been filled. + */ + public void startTableNow (int tableId) + { + if (_lobby == null) { + Log.warning("Requested to start a table but we're not " + + "currently in a place [tableId=" + tableId + "]."); + return; + } + + _pservice.startTableNow(_ctx.getClient(), _lobby.getOid(), + tableId, this); + } + // documentation inherited public void clientDidLogoff (Client client) { diff --git a/src/java/com/threerings/parlor/data/ParlorMarshaller.java b/src/java/com/threerings/parlor/data/ParlorMarshaller.java index e96707b4..1e99e4f7 100644 --- a/src/java/com/threerings/parlor/data/ParlorMarshaller.java +++ b/src/java/com/threerings/parlor/data/ParlorMarshaller.java @@ -200,4 +200,17 @@ public class ParlorMarshaller extends InvocationMarshaller arg2, listener3 }); } + + /** The method id used to dispatch {@link #startTableNow} requests. */ + public static final int START_TABLE_NOW = 8; + + // from interface ParlorService + public void startTableNow (Client arg1, int arg2, int arg3, InvocationService.InvocationListener arg4) + { + ListenerMarshaller listener4 = new ListenerMarshaller(); + listener4.listener = arg4; + sendRequest(arg1, START_TABLE_NOW, new Object[] { + Integer.valueOf(arg2), Integer.valueOf(arg3), listener4 + }); + } } diff --git a/src/java/com/threerings/parlor/server/ParlorDispatcher.java b/src/java/com/threerings/parlor/server/ParlorDispatcher.java index 0008914d..b8965adb 100644 --- a/src/java/com/threerings/parlor/server/ParlorDispatcher.java +++ b/src/java/com/threerings/parlor/server/ParlorDispatcher.java @@ -108,6 +108,13 @@ public class ParlorDispatcher extends InvocationDispatcher ); return; + case ParlorMarshaller.START_TABLE_NOW: + ((ParlorProvider)provider).startTableNow( + source, + ((Integer)args[0]).intValue(), ((Integer)args[1]).intValue(), (InvocationService.InvocationListener)args[2] + ); + return; + default: super.dispatchRequest(source, methodId, args); return; diff --git a/src/java/com/threerings/parlor/server/ParlorProvider.java b/src/java/com/threerings/parlor/server/ParlorProvider.java index 61314317..5881ed64 100644 --- a/src/java/com/threerings/parlor/server/ParlorProvider.java +++ b/src/java/com/threerings/parlor/server/ParlorProvider.java @@ -163,6 +163,17 @@ public class ParlorProvider // themselves removed from the table they just left } + /** + * Handles a {@link ParlorService#startSolitaire} request. + */ + public void startTableNow (ClientObject caller, int lobbyOid, int tableId, + InvocationService.InvocationListener listener) + throws InvocationException + { + TableManager tmgr = getTableManager(lobbyOid); + tmgr.startTableNow((BodyObject) caller, tableId); + } + /** * Handles a {@link ParlorService#startSolitaire} request. */ diff --git a/src/java/com/threerings/parlor/server/TableManager.java b/src/java/com/threerings/parlor/server/TableManager.java index 0512282f..2c08a589 100644 --- a/src/java/com/threerings/parlor/server/TableManager.java +++ b/src/java/com/threerings/parlor/server/TableManager.java @@ -231,6 +231,40 @@ public class TableManager } } + /** + * Requests that the specified table be started now, even if there are + * some vacant seats. This may only be done if the minimum number of + * players are already present at the table. By convention, only the + * player at seat 0 may request to have the game start early, as they + * are usually the creator. + * + * @param requester the body object of the user that wishes to start + * the table. + * @param tableId the id of the table to be started. + * + * @exception InvocationException thrown if the starting was not able + * processed for some reason. The explanation will be provided in the + * message data of the exception. + */ + public void startTableNow (BodyObject requester, int tableId) + throws InvocationException + { + // look the table up + Table table = _tables.get(tableId); + if (table == null) { + throw new InvocationException(NO_SUCH_TABLE); + + } else if (requester.getOid() != table.bodyOids[0]) { + throw new InvocationException(INVALID_TABLE_POSITION); + + } else if (!table.mayBeStarted()) { + throw new InvocationException(INTERNAL_ERROR); + } + + // I guess we're ready to go! + createGame(table); + } + /** * Removes the table from all of our internal tables and from its * lobby's distributed object.