From 32c4464a854878eca72e3a40984f492a98ac627e Mon Sep 17 00:00:00 2001 From: Michael Bayne Date: Thu, 6 Dec 2007 00:37:32 +0000 Subject: [PATCH] Revamped some table stuff. First I don't know why I called players occupants, that was stupid. Now they're called players. Next I added a list of watchers rather than simply a count. If we're going to go to all the trouble to update the table when the watchers change, let's have the goods. This will probably break Bang and/or Yohoho. I'll fix them toot sweet. git-svn-id: svn+ssh://src.earth.threerings.net/vilya/trunk@515 c613c5cb-e716-0410-b11b-feb51c14d237 --- .../threerings/parlor/client/TableDirector.as | 6 +- src/as/com/threerings/parlor/data/Table.as | 47 ++++--- .../micasa/lobby/table/TableItem.java | 8 +- .../parlor/client/TableDirector.java | 5 +- .../com/threerings/parlor/data/Table.java | 118 +++++++++++------- .../parlor/server/TableManager.java | 33 ++--- 6 files changed, 118 insertions(+), 99 deletions(-) diff --git a/src/as/com/threerings/parlor/client/TableDirector.as b/src/as/com/threerings/parlor/client/TableDirector.as index afa0bee8..633ad898 100644 --- a/src/as/com/threerings/parlor/client/TableDirector.as +++ b/src/as/com/threerings/parlor/client/TableDirector.as @@ -318,7 +318,7 @@ public class TableDirector extends BasicDirector } // All this to check to see if we created a party game (and should now enter). - if (table.gameOid != -1 && (table.occupants.length == 0)) { + if (table.gameOid != -1 && (table.players.length == 0)) { // let's boogie! _pctx.getParlorDirector().gameIsReady(table.gameOid); } @@ -343,9 +343,9 @@ public class TableDirector extends BasicDirector _ourTable = null; } - // look for our username in the occupants array + // look for our username in the players array var self :BodyObject = (_pctx.getClient().getClientObject() as BodyObject); - if (ArrayUtil.contains(table.occupants, self.getVisibleName())) { + if (ArrayUtil.contains(table.players, self.getVisibleName())) { _ourTable = table; } diff --git a/src/as/com/threerings/parlor/data/Table.as b/src/as/com/threerings/parlor/data/Table.as index eb62a51c..be733810 100644 --- a/src/as/com/threerings/parlor/data/Table.as +++ b/src/as/com/threerings/parlor/data/Table.as @@ -55,20 +55,18 @@ public class Table * 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 + /** An array of the usernames of the players of this table (some slots may not be filled), or * null if a party game. */ - public var occupants :TypedArray; + public var players :TypedArray; - /** The body oids of the occupants of this table, or null if a party game. (This is not + /** An array of the usernames of the non-player occupants of this game. For FFA party games + * this is all of a room's occupants and they are in fact players. */ + public var watchers :TypedArray; + + /** The body oids of the players of this table, or null if a party game. (This is not * propagated to remote instances.) */ public var bodyOids :TypedArray; - /** For a running game, the total number of players. For FFA party games, this is everyone. */ - public var playerCount :int; - - /** For a running game, the total number of watchers. For FFA party games, this is always 0. */ - public var watcherCount :int; - /** The game config for the game that is being matchmade. */ public var config :GameConfig; @@ -90,9 +88,9 @@ public class Table { // 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]); + for (var ii :int = 0; ii < players.length; ii++) { + if (players[ii] != null) { + players.push(players[ii]); } } @@ -105,9 +103,9 @@ public class Table public function getOccupiedCount () :int { var count :int = 0; - if (occupants != null) { - for (var ii :int = 0; ii < occupants.length; ii++) { - if (occupants[ii] != null) { + if (players != null) { + for (var ii :int = 0; ii < players.length; ii++) { + if (players[ii] != null) { count++; } } @@ -133,7 +131,7 @@ public class Table var subTeams :Array = (teams[ii] as Array); var newSubTeams :TypedArray = TypedArray.create(int); for (var jj :int = 0; jj < subTeams.length; jj++) { - var occ :Name = (occupants[(subTeams[jj] as int)] as Name); + var occ :Name = (players[(subTeams[jj] as int)] as Name); if (occ != null) { newSubTeams.push(ArrayUtil.indexOf(players, occ)); } @@ -146,7 +144,7 @@ public class Table } /** - * Returns true if this table has a sufficient number of occupants that the game can be + * Returns true if this table has a sufficient number of players that the game can be * started. */ public function mayBeStarted () :Boolean @@ -168,7 +166,7 @@ public class Table 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) { + if (players[members[jj]] != null) { teamCount++; } } @@ -240,9 +238,8 @@ public class Table tableId = ins.readInt(); lobbyOid = ins.readInt(); gameOid = ins.readInt(); - occupants = (ins.readObject() as TypedArray); - playerCount = ins.readShort(); - watcherCount = ins.readShort(); + players = (ins.readObject() as TypedArray); + watchers = (ins.readObject() as TypedArray); config = (ins.readObject() as GameConfig); tconfig = (ins.readObject() as TableConfig); } @@ -253,9 +250,8 @@ public class Table out.writeInt(tableId); out.writeInt(lobbyOid); out.writeInt(gameOid); - out.writeObject(occupants); - out.writeShort(playerCount); - out.writeShort(watcherCount); + out.writeObject(players); + out.writeObject(watchers); out.writeObject(config); out.writeObject(tconfig); } @@ -268,7 +264,8 @@ public class Table buf.append("tableId=").append(tableId); buf.append(", lobbyOid=").append(lobbyOid); buf.append(", gameOid=").append(gameOid); - buf.append(", occupants=").append(occupants == null ? "" : occupants.join()); + buf.append(", players=").append(players == null ? "" : players.join()); + buf.append(", watchers=").append(watchers == null ? "" : watchers.join()); buf.append(", config=").append(config); } diff --git a/src/java/com/threerings/micasa/lobby/table/TableItem.java b/src/java/com/threerings/micasa/lobby/table/TableItem.java index f7155cc3..b47580b0 100644 --- a/src/java/com/threerings/micasa/lobby/table/TableItem.java +++ b/src/java/com/threerings/micasa/lobby/table/TableItem.java @@ -84,7 +84,7 @@ public class TableItem add(tlabel, gbc); // we have one button for every "seat" at the table - int bcount = table.occupants.length; + int bcount = table.players.length; // create blank buttons for now and then we'll update everything // with the current state when we're done @@ -148,19 +148,19 @@ public class TableItem // now enable and label the buttons accordingly int slength = _seats.length; for (int i = 0; i < slength; i++) { - if (table.occupants[i] == null) { + if (table.players[i] == null) { _seats[i].setText(JOIN_LABEL); _seats[i].setEnabled(!isSeated); _seats[i].setActionCommand("join"); - } else if (table.occupants[i].equals(_self) && + } else if (table.players[i].equals(_self) && !table.inPlay()) { _seats[i].setText(LEAVE_LABEL); _seats[i].setEnabled(true); _seats[i].setActionCommand("leave"); } else { - _seats[i].setText(table.occupants[i].toString()); + _seats[i].setText(table.players[i].toString()); _seats[i].setEnabled(false); } } diff --git a/src/java/com/threerings/parlor/client/TableDirector.java b/src/java/com/threerings/parlor/client/TableDirector.java index b4a8b104..5a1fa687 100644 --- a/src/java/com/threerings/parlor/client/TableDirector.java +++ b/src/java/com/threerings/parlor/client/TableDirector.java @@ -21,7 +21,6 @@ package com.threerings.parlor.client; -import com.samskivert.util.ListUtil; import com.samskivert.util.ObjectUtil; import com.samskivert.util.ObserverList; @@ -282,7 +281,7 @@ public class TableDirector extends BasicDirector } // All this to check to see if we created a party game (and should now enter). - if (table.gameOid != -1 && table.occupants.length == 0) { + if (table.gameOid != -1 && table.players.length == 0) { _ctx.getParlorDirector().gameIsReady(table.gameOid); // let's boogie! } } @@ -309,7 +308,7 @@ public class TableDirector extends BasicDirector // look for our username in the occupants array BodyObject self = (BodyObject)_ctx.getClient().getClientObject(); - if (ListUtil.contains(table.occupants, self.getVisibleName())) { + if (table.containsPlayer(self.getVisibleName())) { _ourTable = table; } diff --git a/src/java/com/threerings/parlor/data/Table.java b/src/java/com/threerings/parlor/data/Table.java index 8d8344de..132d607e 100644 --- a/src/java/com/threerings/parlor/data/Table.java +++ b/src/java/com/threerings/parlor/data/Table.java @@ -21,6 +21,10 @@ package com.threerings.parlor.data; +import java.util.List; + +import com.google.common.collect.Lists; + import com.samskivert.util.ArrayIntSet; import com.samskivert.util.ListUtil; import com.samskivert.util.StringUtil; @@ -31,9 +35,11 @@ import com.threerings.util.Name; import com.threerings.presents.dobj.DSet; import com.threerings.crowd.data.BodyObject; +import com.threerings.crowd.data.OccupantInfo; import com.threerings.parlor.data.ParlorCodes; import com.threerings.parlor.game.data.GameConfig; +import com.threerings.parlor.game.data.GameObject; /** * This class represents a table that is being used to matchmake a game by the Parlor services. @@ -51,20 +57,18 @@ public class Table * matchmaking mode. */ public int gameOid = -1; - /** An array of the usernames of the occupants of this table (some slots may not be filled), or + /** An array of the usernames of the players of this table (some slots may not be filled), or * null if a party game. */ - public Name[] occupants; + public Name[] players; - /** The body oids of the occupants of this table, or null if a party game. (This is not + /** An array of the usernames of the non-player occupants of this game. For FFA party games + * this is all of a room's occupants and they are in fact players. */ + public Name[] watchers = new Name[0]; + + /** The body oids of the players of this table, or null if a party game. (This is not * propagated to remote instances.) */ public transient int[] bodyOids; - /** For a running game, the total number of players. For FFA party games, this is everyone. */ - public short playerCount; - - /** For a running game, the total number of watchers. For FFA party games, this is always 0. */ - public short watcherCount; - /** The game config for the game that is being matchmade. */ public GameConfig config; @@ -100,18 +104,18 @@ public class Table // make room for the maximum number of players if (config.getMatchType() != GameConfig.PARTY) { - occupants = new Name[tconfig.desiredPlayerCount]; - bodyOids = new int[occupants.length]; + players = new Name[tconfig.desiredPlayerCount]; + bodyOids = new int[players.length]; // fill in information on the AIs int acount = (config.ais == null) ? 0 : config.ais.length; for (int ii = 0; ii < acount; ii++) { // TODO: handle this naming business better - occupants[ii] = new Name("AI " + (ii+1)); + players[ii] = new Name("AI " + (ii+1)); } } else { - occupants = new Name[0]; + players = new Name[0]; bodyOids = new int[0]; } } @@ -136,9 +140,9 @@ public class Table public int getOccupiedCount () { int count = 0; - if (occupants != null) { - for (int ii = 0; ii < occupants.length; ii++) { - if (occupants[ii] != null) { + if (players != null) { + for (int ii = 0; ii < players.length; ii++) { + if (players[ii] != null) { count++; } } @@ -162,10 +166,10 @@ public class Table // FFA party games have 0-length players array, and non-party games will have the players // who are ready-to-go for the game start. Name[] players = new Name[getOccupiedCount()]; - if (occupants != null) { - for (int ii = 0, dex = 0; ii < occupants.length; ii++) { - if (occupants[ii] != null) { - players[dex++] = occupants[ii]; + if (players != null) { + for (int ii = 0, dex = 0; ii < players.length; ii++) { + if (players[ii] != null) { + players[dex++] = players[ii]; } } } @@ -175,7 +179,7 @@ public class Table /** * For a team game, get the team member indices of the compressed players array returned by - * getPlayers(). + * {@link #getPlayers}. */ public int[][] getTeamMemberIndices () { @@ -191,7 +195,7 @@ public class Table 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]]; + Name occ = players[teams[ii][jj]]; if (occ != null) { set.add(ListUtil.indexOf(players, occ)); } @@ -206,13 +210,13 @@ public class Table * 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. + * @param player the player 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. */ @ActionScript(omit=true) - public String setOccupant (int position, BodyObject occupant) + public String setPlayer (int position, BodyObject player) { // make sure the requested position is a valid one if (position >= tconfig.desiredPlayerCount || position < 0) { @@ -220,24 +224,24 @@ public class Table } // make sure the requested position is not already occupied - if (occupants[position] != null) { + if (players[position] != null) { return TABLE_POSITION_OCCUPIED; } // otherwise all is well, stick 'em in - setOccupantPos(position, occupant); + setPlayerPos(position, player); 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'. + * player's ability to join, if you are unsure you should call 'setPlayer'. */ @ActionScript(omit=true) - public void setOccupantPos (int position, BodyObject occupant) + public void setPlayerPos (int position, BodyObject player) { - occupants[position] = occupant.getVisibleName(); - bodyOids[position] = occupant.getOid(); + players[position] = player.getVisibleName(); + bodyOids[position] = player.getOid(); } /** @@ -247,12 +251,12 @@ public class Table * was never seated at the table in the first place. */ @ActionScript(omit=true) - public boolean clearOccupant (Name username) + public boolean clearPlayer (Name username) { - if (occupants != null) { - for (int i = 0; i < occupants.length; i++) { - if (username.equals(occupants[i])) { - clearOccupantPos(i); + if (players != null) { + for (int i = 0; i < players.length; i++) { + if (username.equals(players[i])) { + clearPlayerPos(i); return true; } } @@ -268,12 +272,12 @@ public class Table * was never seated at the table in the first place. */ @ActionScript(omit=true) - public boolean clearOccupantByOid (int bodyOid) + public boolean clearPlayerByOid (int bodyOid) { if (bodyOids != null) { for (int i = 0; i < bodyOids.length; i++) { if (bodyOid == bodyOids[i]) { - clearOccupantPos(i); + clearPlayerPos(i); return true; } } @@ -282,18 +286,44 @@ public class Table } /** - * Called to clear an occupant at the specified position. Only call this method if you know - * what you're doing. + * Called to clear a player at the specified position. Only call this method if you know what + * you're doing. */ @ActionScript(omit=true) - public void clearOccupantPos (int position) + public void clearPlayerPos (int position) { - occupants[position] = null; + players[position] = null; bodyOids[position] = 0; } /** - * Returns true if this table has a sufficient number of occupants that the game can be + * Returns true if this table contains the specified player. + */ + @ActionScript(omit=true) + public boolean containsPlayer (Name player) + { + return (players != null && ListUtil.indexOf(players, player) != -1); + } + + /** + * Called by the table manager when the game object's players have changed. Regenerates the + * {@link #watchers} array. + */ + @ActionScript(omit=true) + public void updateOccupants (GameObject gameobj) + { + List wlist = Lists.newArrayList(); + for (OccupantInfo info : gameobj.occupantInfo) { + if (containsPlayer(info.username)) { // skip players + continue; + } + wlist.add(info.username); + } + watchers = wlist.toArray(new Name[wlist.size()]); + } + + /** + * Returns true if this table has a sufficient number of players that the game can be * started. */ public boolean mayBeStarted () @@ -314,7 +344,7 @@ public class Table for (int ii=0; ii < teams.length; ii++) { int teamCount = 0; for (int jj=0; jj < teams[ii].length; jj++) { - if (occupants[teams[ii][jj]] != null) { + if (players[teams[ii][jj]] != null) { teamCount++; } } @@ -389,7 +419,7 @@ public class Table buf.append("tableId=").append(tableId); buf.append(", lobbyOid=").append(lobbyOid); buf.append(", gameOid=").append(gameOid); - buf.append(", occupants=").append(StringUtil.toString(occupants)); + buf.append(", players=").append(StringUtil.toString(players)); buf.append(", config=").append(config); } diff --git a/src/java/com/threerings/parlor/server/TableManager.java b/src/java/com/threerings/parlor/server/TableManager.java index efdd764a..1b4d887b 100644 --- a/src/java/com/threerings/parlor/server/TableManager.java +++ b/src/java/com/threerings/parlor/server/TableManager.java @@ -129,7 +129,7 @@ public class TableManager if (table.bodyOids != null && table.bodyOids.length > 0) { // stick the creator into the first non-AI position int cpos = (config.ais == null) ? 0 : config.ais.length; - String error = table.setOccupant(cpos, creator); + String error = table.setPlayer(cpos, creator); if (error != null) { Log.warning("Unable to add creator to position zero of table!? [table=" + table + ", creator=" + creator + ", error=" + error + "]."); @@ -189,7 +189,7 @@ public class TableManager } // request that the user be added to the table at that position - String error = table.setOccupant(position, joiner); + String error = table.setPlayer(position, joiner); // if that failed, report the error if (error != null) { throw new InvocationException(error); @@ -199,7 +199,7 @@ public class TableManager if (table.shouldBeStarted()) { createGame(table); } else { - // make a mapping from this occupant to this table + // make a mapping from this player to this table notePlayerAdded(table, joiner); } @@ -224,7 +224,7 @@ public class TableManager } // request that the user be removed from the table - if (!table.clearOccupant(leaver.getVisibleName())) { + if (!table.clearPlayer(leaver.getVisibleName())) { throw new InvocationException(NOT_AT_TABLE); } @@ -235,7 +235,7 @@ public class TableManager } // either update or delete the table depending on whether or not we just removed the last - // occupant + // player if (table.isEmpty()) { purgeTable(table); } else { @@ -376,7 +376,7 @@ public class TableManager gameobj.setIsPrivate(table.tconfig.privateTable); if (table.bodyOids != null) { - // clear the occupant to table mappings as this game is underway + // clear the player to table mappings as this game is underway for (int ii = 0; ii < table.bodyOids.length; ii++) { if (table.bodyOids[ii] != 0) { notePlayerRemoved(table.bodyOids[ii]); @@ -411,7 +411,7 @@ public class TableManager } /** - * Called when the occupants in a game change: publish new info. + * Called when the occupants in a game change: publishes new info. */ protected void updateOccupants (int gameOid) { @@ -426,16 +426,9 @@ public class TableManager return; } + // update this table's occupants information and update the table GameObject gameObj = (GameObject) PresentsServer.omgr.getObject(gameOid); - table.watcherCount = (short) gameObj.occupants.size(); - - // TODO: this will become more complicated - // As we separate watchers and players - - // TODO: for SEATED_CONTINUOUS, we will probably be showing the - // folks in the game... - - // finally, update the table + table.updateOccupants(gameObj); _tlobj.updateTables(table); } @@ -445,21 +438,21 @@ public class TableManager */ protected void bodyLeft (int bodyOid) { - // look up the table to which this occupant is mapped + // look up the table to which this player is mapped Table pender = notePlayerRemoved(bodyOid); if (pender == null) { return; } - // remove this occupant from the table - if (!pender.clearOccupantByOid(bodyOid)) { + // remove this player from the table + if (!pender.clearPlayerByOid(bodyOid)) { Log.warning("Attempt to remove body from mapped table failed [table=" + pender + ", bodyOid=" + bodyOid + "]."); return; } // either update or delete the table depending on whether or not we just removed the last - // occupant + // player if (pender.isEmpty()) { purgeTable(pender); } else {