The table system now supports the party game types better.
The creator of a party game isn't joining, but I think that's a problem with the msoy client... git-svn-id: svn+ssh://src.earth.threerings.net/vilya/trunk@168 c613c5cb-e716-0410-b11b-feb51c14d237
This commit is contained in:
@@ -29,6 +29,10 @@ public class EZGameConfig extends GameConfig
|
||||
// For now, the configData is either a classname or url.
|
||||
public var configData :String;
|
||||
|
||||
// TODO: this is separate right now, but may eventually be extracted
|
||||
// from configData? Do not read this value, use getPartyGameType()
|
||||
public var partyGameType :int = PartyGameCodes.NOT_PARTY_GAME;
|
||||
|
||||
/** If non-zero, a game id used to persistently identify the game.
|
||||
* This could be thought of as a new-style rating id. */
|
||||
public var persistentGameId:int;
|
||||
@@ -68,8 +72,7 @@ public class EZGameConfig extends GameConfig
|
||||
// from PartyGameConfig
|
||||
public function getPartyGameType () :int
|
||||
{
|
||||
// TODO
|
||||
return PartyGameCodes.NOT_PARTY_GAME;
|
||||
return partyGameType;
|
||||
}
|
||||
|
||||
override public function hashCode () :int
|
||||
@@ -93,6 +96,7 @@ public class EZGameConfig extends GameConfig
|
||||
super.readObject(ins);
|
||||
|
||||
configData = (ins.readField(String) as String);
|
||||
partyGameType = ins.readByte();
|
||||
persistentGameId = ins.readInt();
|
||||
}
|
||||
|
||||
@@ -102,6 +106,7 @@ public class EZGameConfig extends GameConfig
|
||||
super.writeObject(out);
|
||||
|
||||
out.writeField(configData);
|
||||
out.writeByte(partyGameType);
|
||||
out.writeInt(persistentGameId);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -65,7 +65,15 @@ public class Table
|
||||
|
||||
/** 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;
|
||||
public /*transient*/ 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;
|
||||
@@ -84,9 +92,11 @@ public class Table
|
||||
public function getOccupiedCount () :int
|
||||
{
|
||||
var count :int = 0;
|
||||
for (var ii :int = 0; ii < occupants.length; ii++) {
|
||||
if (occupants[ii] != null) {
|
||||
count++;
|
||||
if (occupants != null) {
|
||||
for (var ii :int = 0; ii < occupants.length; ii++) {
|
||||
if (occupants[ii] != null) {
|
||||
count++;
|
||||
}
|
||||
}
|
||||
}
|
||||
return count;
|
||||
@@ -101,10 +111,6 @@ public class Table
|
||||
*/
|
||||
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++) {
|
||||
@@ -288,7 +294,8 @@ public class Table
|
||||
*/
|
||||
public function shouldBeStarted () :Boolean
|
||||
{
|
||||
return tconfig.desiredPlayerCount <= getOccupiedCount();
|
||||
return isPartyGame() ||
|
||||
(tconfig.desiredPlayerCount <= getOccupiedCount());
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -332,18 +339,18 @@ public class Table
|
||||
return tableId;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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;
|
||||
}
|
||||
// /**
|
||||
// * 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;
|
||||
// }
|
||||
|
||||
// from Streamable
|
||||
public function readObject (ins :ObjectInputStream) :void
|
||||
@@ -352,6 +359,8 @@ public class Table
|
||||
lobbyOid = ins.readInt();
|
||||
gameOid = ins.readInt();
|
||||
occupants = (ins.readObject() as TypedArray);
|
||||
playerCount = ins.readShort();
|
||||
watcherCount = ins.readShort();
|
||||
config = (ins.readObject() as GameConfig);
|
||||
tconfig = (ins.readObject() as TableConfig);
|
||||
}
|
||||
|
||||
@@ -32,9 +32,9 @@ import com.threerings.io.TypedArray;
|
||||
*/
|
||||
public class TableConfig extends SimpleStreamableObject
|
||||
{
|
||||
/** 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. */
|
||||
/** The total number of players that are desired for the table.
|
||||
* 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
|
||||
|
||||
@@ -24,6 +24,10 @@ public class EZGameConfig extends GameConfig
|
||||
// For now, the configData is either a classname or url.
|
||||
public String configData;
|
||||
|
||||
// TODO: this is separate right now, but may eventually be extracted
|
||||
// from configData? Do not read this value, use getPartyGameType()
|
||||
public byte partyGameType = NOT_PARTY_GAME;
|
||||
|
||||
/** If non-zero, a game id used to persistently identify the game.
|
||||
* This could be thought of as a new-style rating id. */
|
||||
public int persistentGameId;
|
||||
@@ -62,8 +66,7 @@ public class EZGameConfig extends GameConfig
|
||||
// from PartyGameConfig
|
||||
public byte getPartyGameType ()
|
||||
{
|
||||
// TODO
|
||||
return NOT_PARTY_GAME;
|
||||
return partyGameType;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -424,6 +424,7 @@ public class EZGameManager extends GameManager
|
||||
@Override
|
||||
protected void didShutdown ()
|
||||
{
|
||||
System.err.println("didShutdown!");
|
||||
CrowdServer.invmgr.clearDispatcher(_gameObj.ezGameService);
|
||||
stopTickers();
|
||||
|
||||
|
||||
@@ -62,6 +62,14 @@ public class Table
|
||||
* (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;
|
||||
|
||||
@@ -98,7 +106,7 @@ public class Table
|
||||
this.config = config;
|
||||
|
||||
// make room for the maximum number of players
|
||||
if (tconfig.desiredPlayerCount != -1) {
|
||||
if (!isPartyGame()) {
|
||||
occupants = new Name[tconfig.desiredPlayerCount];
|
||||
bodyOids = new int[occupants.length];
|
||||
|
||||
@@ -130,9 +138,11 @@ public class Table
|
||||
public int getOccupiedCount ()
|
||||
{
|
||||
int count = 0;
|
||||
for (int ii = 0; ii < occupants.length; ii++) {
|
||||
if (occupants[ii] != null) {
|
||||
count++;
|
||||
if (occupants != null) {
|
||||
for (int ii = 0; ii < occupants.length; ii++) {
|
||||
if (occupants[ii] != null) {
|
||||
count++;
|
||||
}
|
||||
}
|
||||
}
|
||||
return count;
|
||||
@@ -147,15 +157,19 @@ public class Table
|
||||
*/
|
||||
public Name[] getPlayers ()
|
||||
{
|
||||
if (isPartyGame()) {
|
||||
return occupants;
|
||||
// seated party games need a spot for every seat
|
||||
if (PartyGameConfig.SEATED_PARTY_GAME == getPartyGameType()) {
|
||||
return new Name[tconfig.desiredPlayerCount];
|
||||
}
|
||||
|
||||
// create and populate the players array
|
||||
// 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()];
|
||||
for (int ii = 0, dex = 0; ii < occupants.length; ii++) {
|
||||
if (occupants[ii] != null) {
|
||||
players[dex++] = occupants[ii];
|
||||
if (occupants != null) {
|
||||
for (int ii = 0, dex = 0; ii < occupants.length; ii++) {
|
||||
if (occupants[ii] != null) {
|
||||
players[dex++] = occupants[ii];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -262,10 +276,12 @@ public class Table
|
||||
*/
|
||||
public boolean clearOccupant (Name username)
|
||||
{
|
||||
for (int i = 0; i < occupants.length; i++) {
|
||||
if (username.equals(occupants[i])) {
|
||||
clearOccupantPos(i);
|
||||
return true;
|
||||
if (occupants != null) {
|
||||
for (int i = 0; i < occupants.length; i++) {
|
||||
if (username.equals(occupants[i])) {
|
||||
clearOccupantPos(i);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
@@ -281,10 +297,12 @@ public class Table
|
||||
*/
|
||||
public boolean clearOccupantByOid (int bodyOid)
|
||||
{
|
||||
for (int i = 0; i < bodyOids.length; i++) {
|
||||
if (bodyOid == bodyOids[i]) {
|
||||
clearOccupantPos(i);
|
||||
return true;
|
||||
if (bodyOids != null) {
|
||||
for (int i = 0; i < bodyOids.length; i++) {
|
||||
if (bodyOid == bodyOids[i]) {
|
||||
clearOccupantPos(i);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
@@ -334,7 +352,8 @@ public class Table
|
||||
*/
|
||||
public boolean shouldBeStarted ()
|
||||
{
|
||||
return tconfig.desiredPlayerCount <= getOccupiedCount();
|
||||
return isPartyGame() ||
|
||||
(tconfig.desiredPlayerCount <= getOccupiedCount());
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -29,9 +29,9 @@ import com.threerings.io.SimpleStreamableObject;
|
||||
*/
|
||||
public class TableConfig extends SimpleStreamableObject
|
||||
{
|
||||
/** 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. */
|
||||
/** The total number of players that are desired for the table.
|
||||
* For team games, this should be set to the total number of players
|
||||
* overall, as teams may be unequal. */
|
||||
public int desiredPlayerCount;
|
||||
|
||||
/** The minimum number of players needed overall (or per-team if a
|
||||
|
||||
@@ -29,12 +29,14 @@ import com.samskivert.util.StringUtil;
|
||||
import com.threerings.util.Name;
|
||||
|
||||
import com.threerings.presents.dobj.ChangeListener;
|
||||
import com.threerings.presents.dobj.NamedEvent;
|
||||
import com.threerings.presents.dobj.ObjectAddedEvent;
|
||||
import com.threerings.presents.dobj.ObjectDeathListener;
|
||||
import com.threerings.presents.dobj.ObjectDestroyedEvent;
|
||||
import com.threerings.presents.dobj.ObjectRemovedEvent;
|
||||
import com.threerings.presents.dobj.OidListListener;
|
||||
import com.threerings.presents.server.InvocationException;
|
||||
import com.threerings.presents.server.PresentsServer;
|
||||
|
||||
import com.threerings.crowd.data.BodyObject;
|
||||
import com.threerings.crowd.data.PlaceObject;
|
||||
@@ -126,29 +128,38 @@ public class TableManager
|
||||
}
|
||||
table.init(_plobj.getOid(), tableConfig, config);
|
||||
|
||||
// stick the creator into the first non-AI position
|
||||
int cpos = (config.ais == null) ? 0 : config.ais.length;
|
||||
String error = table.setOccupant(cpos, creator);
|
||||
if (error != null) {
|
||||
Log.warning("Unable to add creator to position zero of " +
|
||||
"table!? [table=" + table + ", creator=" + creator +
|
||||
", error=" + error + "].");
|
||||
// bail out now and abort the table creation process
|
||||
throw new InvocationException(error);
|
||||
boolean isParty = table.isPartyGame();
|
||||
if (!isParty) {
|
||||
// stick the creator into the first non-AI position
|
||||
int cpos = (config.ais == null) ? 0 : config.ais.length;
|
||||
String error = table.setOccupant(cpos, creator);
|
||||
if (error != null) {
|
||||
Log.warning("Unable to add creator to position zero of " +
|
||||
"table!? [table=" + table + ", creator=" + creator +
|
||||
", error=" + error + "].");
|
||||
// bail out now and abort the table creation process
|
||||
throw new InvocationException(error);
|
||||
}
|
||||
|
||||
// make a mapping from the creator to this table
|
||||
_boidMap.put(creator.getOid(), table);
|
||||
}
|
||||
|
||||
// stick the table into the table lobby object
|
||||
_tlobj.addToTables(table);
|
||||
|
||||
// make a mapping from the creator to this table
|
||||
_boidMap.put(creator.getOid(), table);
|
||||
|
||||
// also stick it into our tables tables
|
||||
_tables.put(table.tableId, table);
|
||||
|
||||
// if the table has only one seat, start the game immediately
|
||||
if (table.shouldBeStarted()) {
|
||||
createGame(table);
|
||||
int oid = createGame(table);
|
||||
|
||||
// the creator will not be moved automatically, so we do it for them
|
||||
if (isParty) {
|
||||
System.err.println("Trying to move creator");
|
||||
CrowdServer.plreg.locprov.moveBody(creator, oid);
|
||||
}
|
||||
}
|
||||
|
||||
// finally let the caller know what the new table id is
|
||||
@@ -295,6 +306,9 @@ public class TableManager
|
||||
_boidMap.remove(table.bodyOids[i]);
|
||||
}
|
||||
|
||||
// remove the mapping by gameOid
|
||||
_goidMap.remove(table.gameOid); // no-op if gameOid == 0
|
||||
|
||||
// remove the table from the lobby object
|
||||
_tlobj.removeFromTables(table.tableId);
|
||||
}
|
||||
@@ -303,8 +317,10 @@ public class TableManager
|
||||
* Called when we're ready to create a game (either an invitation has
|
||||
* been accepted or a table is ready to start. If there is a problem
|
||||
* creating the game manager, it should be reported in the logs.
|
||||
*
|
||||
* @return the oid of the newly-created game.
|
||||
*/
|
||||
protected void createGame (final Table table)
|
||||
protected int createGame (final Table table)
|
||||
throws InvocationException
|
||||
{
|
||||
// fill the players array into the game config
|
||||
@@ -312,7 +328,10 @@ public class TableManager
|
||||
|
||||
try {
|
||||
PlaceManager pmgr = CrowdServer.plreg.createPlace(table.config);
|
||||
gameCreated(table, (GameObject)pmgr.getPlaceObject());
|
||||
GameObject gobj = (GameObject) pmgr.getPlaceObject();
|
||||
gameCreated(table, gobj);
|
||||
return gobj.getOid();
|
||||
|
||||
} catch (Throwable t) {
|
||||
Log.warning("Failed to create manager for game " +
|
||||
"[config=" + table.config + "]: " + t);
|
||||
@@ -329,17 +348,22 @@ public class TableManager
|
||||
// update the table with the newly created game object
|
||||
table.gameOid = gameobj.getOid();
|
||||
|
||||
// add it to the gameOid map
|
||||
_goidMap.put(table.gameOid, table);
|
||||
|
||||
// configure the privacy of the game
|
||||
gameobj.setIsPrivate(table.tconfig.privateTable);
|
||||
|
||||
// clear the occupant to table mappings as this game is underway
|
||||
for (int i = 0; i < table.bodyOids.length; i++) {
|
||||
_boidMap.remove(table.bodyOids[i]);
|
||||
if (!table.isPartyGame()) {
|
||||
// clear the occupant to table mappings as this game is underway
|
||||
for (int i = 0; i < table.bodyOids.length; i++) {
|
||||
_boidMap.remove(table.bodyOids[i]);
|
||||
}
|
||||
}
|
||||
|
||||
// add an object death listener to unmap the table when the game
|
||||
// finally goes away
|
||||
gameobj.addListener(_gameDeathListener);
|
||||
gameobj.addListener(_gameListener);
|
||||
|
||||
// and then update the lobby object that contains the table
|
||||
_tlobj.updateTables(table);
|
||||
@@ -351,16 +375,36 @@ public class TableManager
|
||||
*/
|
||||
protected void unmapTable (int gameOid)
|
||||
{
|
||||
// look through our tables table for a table with a matching game
|
||||
for (Table table : _tables.values()) {
|
||||
if (table.gameOid == gameOid) {
|
||||
purgeTable(table);
|
||||
return; // all done
|
||||
}
|
||||
Table table = _goidMap.get(gameOid);
|
||||
if (table != null) {
|
||||
purgeTable(table);
|
||||
|
||||
} else {
|
||||
Log.warning("Requested to unmap table that wasn't mapped " +
|
||||
"[gameOid=" + gameOid + "].");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when the occupants in a game change: publish new info.
|
||||
*/
|
||||
protected void updateOccupants (int gameOid)
|
||||
{
|
||||
Table table = _goidMap.get(gameOid);
|
||||
if (table == null) {
|
||||
Log.warning("Unable to find table for running game " +
|
||||
"[gameOid=" + gameOid + "].");
|
||||
return;
|
||||
}
|
||||
|
||||
Log.warning("Requested to unmap table that wasn't mapped " +
|
||||
"[gameOid=" + gameOid + "].");
|
||||
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
|
||||
|
||||
// finally, update the table
|
||||
_tlobj.updateTables(table);
|
||||
}
|
||||
|
||||
// documentation inherited
|
||||
@@ -415,10 +459,38 @@ public class TableManager
|
||||
/** A mapping from body oid to table. */
|
||||
protected HashIntMap<Table> _boidMap = new HashIntMap<Table>();
|
||||
|
||||
/** A listener that prunes tables after the game dies. */
|
||||
protected ChangeListener _gameDeathListener = new ObjectDeathListener() {
|
||||
/** Once a game starts, a mapping from gameOid to table. */
|
||||
protected HashIntMap<Table> _goidMap = new HashIntMap<Table>();
|
||||
|
||||
/** Listens to all games and updates the table objects as necessary. */
|
||||
protected class GameListener
|
||||
implements ObjectDeathListener, OidListListener
|
||||
{
|
||||
// from ObjectDeathListener
|
||||
public void objectDestroyed (ObjectDestroyedEvent event) {
|
||||
unmapTable(event.getTargetOid());
|
||||
}
|
||||
};
|
||||
|
||||
// from OidListListener
|
||||
public void objectAdded (ObjectAddedEvent event) {
|
||||
maybeCheckOccupants(event);
|
||||
}
|
||||
|
||||
// from OidListListener
|
||||
public void objectRemoved (ObjectRemovedEvent event) {
|
||||
maybeCheckOccupants(event);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check to see if the set event causes us to update the table.
|
||||
*/
|
||||
protected void maybeCheckOccupants (NamedEvent event) {
|
||||
if (GameObject.OCCUPANTS.equals(event.getName())) {
|
||||
updateOccupants(event.getTargetOid());
|
||||
}
|
||||
}
|
||||
} // END: class GameDeathListener
|
||||
|
||||
/** A listener that prunes tables after the game dies. */
|
||||
protected ChangeListener _gameListener = new GameListener();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user