More progress on MiCasa services. Have lobby selection working now.

git-svn-id: svn+ssh://src.earth.threerings.net/narya/trunk@397 542714f4-19e9-0310-aa3c-eee0fc999fb1
This commit is contained in:
Michael Bayne
2001-10-04 23:41:44 +00:00
parent b48e5b90a6
commit e8071b5ad6
13 changed files with 706 additions and 88 deletions
+13 -1
View File
@@ -1,4 +1,16 @@
#
# $Id: server.properties,v 1.1 2001/10/03 23:24:09 mdb Exp $
# $Id: server.properties,v 1.2 2001/10/04 23:41:44 mdb Exp $
#
# Configuration for the MiCasa server
#
# The list of lobby identifiers to be loaded into this server.
#
lobby_ids = test
#
# The cofiguration for the test lobby.
#
test.mgrclass = com.threerings.micasa.lobby.LobbyManager
test.ugi = test,board,partner
test.name = Test Lobby
@@ -1,10 +1,11 @@
//
// $Id: ClientController.java,v 1.1 2001/10/03 23:24:09 mdb Exp $
// $Id: ClientController.java,v 1.2 2001/10/04 23:41:44 mdb Exp $
package com.threerings.micasa.client;
import java.awt.event.ActionEvent;
import com.samskivert.swing.Controller;
import com.samskivert.util.StringUtil;
import com.threerings.cocktail.cher.dobj.*;
import com.threerings.cocktail.cher.client.*;
@@ -13,10 +14,12 @@ import com.threerings.cocktail.cher.net.UsernamePasswordCreds;
import com.threerings.cocktail.party.client.*;
import com.threerings.cocktail.party.data.*;
import com.threerings.cocktail.party.util.PlaceViewUtil;
import com.threerings.media.sprite.SpriteManager;
import com.threerings.micasa.Log;
import com.threerings.micasa.lobby.LobbyService;
import com.threerings.micasa.util.MiCasaContext;
/**
@@ -49,12 +52,8 @@ public class ClientController
// we also want to know about occupant changes
_ctx.getOccupantManager().addOccupantObserver(this);
// create our main panel which we'll use once we're logged on
_mainPanel = new MainPanel();
// create the chat ui
ChatPanel panel = new ChatPanel(_ctx);
_mainPanel.setNavigation(panel);
// create our lobby panel which we'll use once we're logged on
_lobbyPanel = new LobbyPanel(ctx);
// create the logon panel and display it
_logonPanel = new LogonPanel(_ctx);
@@ -89,7 +88,7 @@ public class ClientController
// we're logged on, so we lose the login panel and move to our
// primary display
_frame.setPanel(_mainPanel);
_frame.setPanel(_lobbyPanel);
}
// documentation inherited
@@ -132,12 +131,19 @@ public class ClientController
{
Log.info("Moved to new location [place=" + place + "].");
// we wants to subscribe to the location
// clean up after the old place
if (_place != null) {
_place.removeSubscriber(this);
PlaceViewUtil.dispatchDidLeavePlace(_frame, _place);
}
place.addSubscriber(this);
_place = place;
// and enter the new place with bells on
if (_place != null) {
_place.addSubscriber(this);
PlaceViewUtil.dispatchWillEnterPlace(_frame, _place);
}
}
// documentation inherited
@@ -185,5 +191,5 @@ public class ClientController
// our panels
protected LogonPanel _logonPanel;
protected MainPanel _mainPanel;
protected LobbyPanel _lobbyPanel;
}
@@ -0,0 +1,83 @@
//
// $Id: OccupantList.java,v 1.1 2001/10/04 23:41:44 mdb Exp $
package com.threerings.micasa.client;
import java.util.Iterator;
import javax.swing.*;
import com.threerings.cocktail.party.client.OccupantObserver;
import com.threerings.cocktail.party.data.OccupantInfo;
import com.threerings.cocktail.party.data.PlaceObject;
import com.threerings.cocktail.party.util.PlaceView;
import com.threerings.micasa.util.MiCasaContext;
/**
* The occupant list displays the list of users that are in a particular
* place.
*/
public class OccupantList
extends JList implements PlaceView, OccupantObserver
{
/**
* Constructs an occupant list with the supplied context which it will
* use to register itself with the necessary managers.
*/
public OccupantList (MiCasaContext ctx)
{
// set up our list model
_model = new DefaultListModel();
setModel(_model);
// keep our context around for later
_ctx = ctx;
// register ourselves as an occupant observer
_ctx.getOccupantManager().addOccupantObserver(this);
}
// documentation inherited
public void willEnterPlace (PlaceObject plobj)
{
// add all of the occupants of the place to our list
Iterator users = plobj.occupantInfo.elements();
while (users.hasNext()) {
OccupantInfo info = (OccupantInfo)users.next();
_model.addElement(info.username);
}
}
// documentation inherited
public void didLeavePlace (PlaceObject plobj)
{
// clear out our occupant entries
_model.clear();
}
// documentation inherited
public void occupantEntered (OccupantInfo info)
{
// simply add this user to our list
_model.addElement(info.username);
}
// documentation inherited
public void occupantLeft (OccupantInfo info)
{
// remove this occupant from our list
_model.removeElement(info.username);
}
// documentation inherited
public void occupantUpdated (OccupantInfo info)
{
// nothing doing
}
/** Our client context. */
protected MiCasaContext _ctx;
/** A list model that provides a vector interface. */
protected DefaultListModel _model;
}
@@ -0,0 +1,69 @@
//
// $Id: Lobby.java,v 1.1 2001/10/04 23:41:44 mdb Exp $
package com.threerings.micasa.lobby;
import java.io.IOException;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import com.threerings.cocktail.cher.io.Streamable;
/**
* A simple class for keeping track of information for each lobby in
* operation on the server.
*/
public class Lobby implements Streamable
{
/** The object id of the lobby place object. */
public int placeOid;
/** The universal game identifier string for the game matchmade by
* this lobby. */
public String gameIdent;
/** The human readable name of the lobby. */
public String name;
/**
* Constructs a lobby record and initializes it with the specified
* values.
*/
public Lobby (int placeOid, String gameIdent, String name)
{
this.placeOid = placeOid;
this.gameIdent = gameIdent;
this.name = name;
}
/**
* Constructs a blank lobby record suitable for unserialization.
*/
public Lobby ()
{
}
// documentation inherited
public void writeTo (DataOutputStream out)
throws IOException
{
out.writeInt(placeOid);
out.writeUTF(gameIdent);
out.writeUTF(name);
}
// documentation inherited
public void readFrom (DataInputStream in)
throws IOException
{
placeOid = in.readInt();
gameIdent = in.readUTF();
name = in.readUTF();
}
public String toString ()
{
return "[oid=" + placeOid + ", ident=" + gameIdent +
", name=" + name + "]";
}
}
@@ -1,7 +1,7 @@
//
// $Id: LobbyCodes.java,v 1.1 2001/10/04 00:29:07 mdb Exp $
// $Id: LobbyCodes.java,v 1.2 2001/10/04 23:41:44 mdb Exp $
package com.threerings.micasa.lobdy;
package com.threerings.micasa.lobby;
import com.threerings.cocktail.cher.client.InvocationCodes;
@@ -13,6 +13,24 @@ public interface LobbyCodes extends InvocationCodes
/** The module name for the lobby services. */
public static final String MODULE_NAME = "lobby";
/** The message identifier for a get categories request. */
public static final String GET_CATEGORIES_REQUEST = "GetCategories";
/** The message identifier for a got categories response. This is
* mapped by the invocation services to a call to
* <code>handleGotCategories</code>. */
public static final String GOT_CATEGORIES_RESPONSE = "GotCategories";
/** The message identifier for a get lobbies request. */
public static final String GET_LOBBIES_REQUEST = "GetLobbies";
/** The message identifier for a got lobbies response. This is mapped
* by the invocation services to a call to
* <code>handleGotLobbies</code>. */
public static final String GOT_LOBBIES_RESPONSE = "GotLobbies";
/** The message identifier for a failed request. This is
* mapped by the invocation services to a call to
* <code>handleRequestFailed</code>. */
public static final String REQUEST_FAILED_RESPONSE = "RequestFailed";
}
@@ -1,9 +1,10 @@
//
// $Id: LobbyManager.java,v 1.1 2001/10/04 00:29:07 mdb Exp $
// $Id: LobbyManager.java,v 1.2 2001/10/04 23:41:44 mdb Exp $
package com.threerings.micasa.lobdy;
package com.threerings.micasa.lobby;
import java.util.Properties;
import com.samskivert.util.StringUtil;
import com.threerings.cocktail.party.server.PlaceManager;
import com.threerings.micasa.Log;
@@ -18,14 +19,55 @@ public class LobbyManager extends PlaceManager
*
* @exception Exception thrown if a configuration error is detected.
*/
public void init (Properties config)
public void init (LobbyRegistry lobreg, Properties config)
throws Exception
{
Log.info("Lobby manager initialized.");
// look up some configuration parameters
_gameIdent = getConfigValue(config, "ugi");
_name = getConfigValue(config, "name");
// keep this for later
_lobreg = lobreg;
Log.info("Lobby manager initialized [ident=" + _gameIdent +
", name=" + _name + "].");
}
/** Looks up a configuration property in the supplied properties
* object and throws an exception if it's not found. */
protected String getConfigValue (Properties config, String key)
throws Exception
{
String value = config.getProperty(key);
if (StringUtil.blank(value)) {
throw new Exception("Missing '" + key + "' definition in " +
"lobby configuration.");
}
return value;
}
// documentation inherited
protected Class getPlaceObjectClass ()
{
return LobbyObject.class;
}
// documentation inherited
protected void didStartup ()
{
super.didStartup();
// let the lobby registry know that we're up and running
_lobreg.lobbyReady(_plobj.getOid(), _gameIdent, _name);
}
/** The universal game identifier for the game matchmade by this
* lobby. */
protected String _gameIdent;
/** The human readable name of this lobby. */
protected String _name;
/** A reference to the lobby registry. */
protected LobbyRegistry _lobreg;
}
@@ -1,7 +1,7 @@
//
// $Id: LobbyObject.dobj,v 1.1 2001/10/04 00:29:07 mdb Exp $
// $Id: LobbyObject.dobj,v 1.2 2001/10/04 23:41:44 mdb Exp $
package com.threerings.micasa.lobdy;
package com.threerings.micasa.lobby;
import com.threerings.cocktail.party.data.PlaceObject;
@@ -1,36 +1,56 @@
//
// $Id: LobbyPanel.java,v 1.1 2001/10/03 23:24:09 mdb Exp $
// $Id: LobbyPanel.java,v 1.2 2001/10/04 23:41:44 mdb Exp $
package com.threerings.micasa.client;
import javax.swing.*;
import com.samskivert.swing.*;
import com.threerings.micasa.util.MiCasaContext;
/**
* The main panel is the top level component in the UI. It encloses the
* primary user interface display and the sidebar displays. The sidebar
* contains a navigation display, a management display (where various
* management panels can be added), and the chat interface.
* The lobby panel is used to display the interface for the lobbies. It
* contains a lobby selection mechanism, a chat interface and a user
* interface for whatever matchmaking mechanism is appropriate for a
* particular lobby.
*/
public class MainPanel extends JPanel
public class LobbyPanel extends JPanel
{
public MainPanel ()
/**
* Constructs a new lobby panel and the associated user interface
* elements.
*/
public LobbyPanel (MiCasaContext ctx)
{
// we want a five pixel border around everything
setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));
// create our primary layout which divides the display in two
// horizontally
GroupLayout gl = new HGroupLayout(GroupLayout.STRETCH);
gl.setOffAxisPolicy(GroupLayout.STRETCH);
gl.setJustification(GroupLayout.RIGHT);
gl.setGap(0);
setLayout(gl);
// create our sidebar panel
gl = new VGroupLayout(GroupLayout.STRETCH);
gl.setOffAxisPolicy(GroupLayout.STRETCH);
_sidePanel = new JPanel(gl);
_sidePanel.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));
// stick some stuff in our sidebar for now
JLabel label = new JLabel("Sidebar views");
// the sidebar contains a lobby selector...
JLabel label = new JLabel("Select a lobby...");
_sidePanel.add(label, GroupLayout.FIXED);
LobbySelector selector = new LobbySelector(ctx);
_sidePanel.add(selector);
// ...a lobby info display...
// and an occupants list
label = new JLabel("Occupants");
_sidePanel.add(label, GroupLayout.FIXED);
OccupantList occupants = new OccupantList(ctx);
_sidePanel.add(occupants);
// add our sidebar panel into the mix
add(_sidePanel, GroupLayout.FIXED);
}
@@ -58,29 +78,9 @@ public class MainPanel extends JPanel
validate();
}
/**
* Sets the navigation view. This is the small map-like view in the
* upper right corner of the display.
*/
public void setNavigation (JPanel view)
{
// remove the old view
if (_navView != null) {
_sidePanel.remove(_navView);
}
// add the new one
_navView = view;
_sidePanel.add(_navView);
_sidePanel.validate();
}
/** The sidebar panel. */
protected JPanel _sidePanel;
/** The primary view. */
protected JPanel _primView;
/** The navigation view. */
protected JPanel _navView;
}
@@ -1,9 +1,10 @@
//
// $Id: LobbyProvider.java,v 1.1 2001/10/04 00:29:07 mdb Exp $
// $Id: LobbyProvider.java,v 1.2 2001/10/04 23:41:44 mdb Exp $
package com.threerings.micasa.lobdy;
package com.threerings.micasa.lobby;
import com.threerings.cocktail.cher.server.InvocationProvider;
import com.threerings.cocktail.cher.util.StreamableArrayList;
import com.threerings.cocktail.party.data.BodyObject;
/**
@@ -26,13 +27,29 @@ public class LobbyProvider
_lobreg = lobreg;
}
/**
* Processes a request by the client to obtain a list of the lobby
* categories available on this server.
*/
public void handleGetCategoriesRequest (
BodyObject source, int invid)
{
String[] cats = _lobreg.getCategories(source);
// we have to cast the array to an object to avoid having the
// compiler pick the version of sendResponse that takes Object[]
sendResponse(source, invid, GOT_CATEGORIES_RESPONSE, (Object)cats);
}
/**
* Processes a request by the client to obtain a list of lobbies
* matching the supplied pattern string.
* matching the supplied category string.
*/
public void handleGetLobbiesRequest (
BodyObject source, int invid, String pattern)
BodyObject source, int invid, String category)
{
StreamableArrayList list = new StreamableArrayList();
_lobreg.getLobbies(source, category, list);
sendResponse(source, invid, GOT_LOBBIES_RESPONSE, list);
}
/** A reference to the lobby registry. */
@@ -1,12 +1,13 @@
//
// $Id: LobbyRegistry.java,v 1.1 2001/10/04 00:29:07 mdb Exp $
// $Id: LobbyRegistry.java,v 1.2 2001/10/04 23:41:44 mdb Exp $
package com.threerings.micasa.lobdy;
package com.threerings.micasa.lobby;
import java.util.Properties;
import java.util.*;
import com.samskivert.util.*;
import com.samskivert.util.Config;
import com.samskivert.util.PropertiesUtil;
import com.threerings.cocktail.cher.server.InvocationManager;
import com.threerings.cocktail.party.data.BodyObject;
import com.threerings.micasa.Log;
import com.threerings.micasa.server.MiCasaServer;
@@ -24,10 +25,14 @@ import com.threerings.micasa.server.MiCasaServer;
* lobby_ids = foolobby, barlobby, bazlobby
*
* foolobby.mgrclass = com.threerings.micasa.lobby.LobbyManager
* foolobby.ugi = <universal game identifier>
* foolobby.name = <human readable lobby name>
* foolobby.config1 = some config value
* foolobby.config2 = some other config value
*
* barlobby.mgrclass = com.threerings.micasa.lobby.LobbyManager
* barlobby.ugi = <universal game identifier>
* barlobby.name = <human readable lobby name>
* ...
* </pre>
*
@@ -36,35 +41,50 @@ import com.threerings.micasa.server.MiCasaServer;
* <code>rsrc/config/micasa/server.properties</code> somwhere in the
* classpath where it will override the default MiCasa server properties
* file.
*
* <p> The <code>UGI</code> or universal game identifier is a string that
* is used to uniquely identify every type of game and also to classify it
* according to meaningful keywords. It is best described with a few
* examples:
*
* <pre>
* backgammon,board,strategy
* spades,card,partner
* yahtzee,dice
* </pre>
*
* As you can see, a UGI should start with an identifier uniquely
* identifying the type of game and can be followed by a list of keywords
* that classify it as a member of a particular category of games
* (eg. board, card, dice, partner game, strategy game). A game can belong
* to multiple categories.
*
* <p> As long as the UGIs in use by a particular server make some kind of
* sense, the client will be able to use them to search for lobbies
* containing games of similar types using the provided facilities.
*/
public class LobbyRegistry
public class LobbyRegistry implements LobbyCodes
{
/**
* A simple class for keeping track of information for each lobby in
* operation on the server.
*/
public static class Lobby
{
/** The object id of the lobby place object. */
public int placeOid;
/** The human readable name of the lobby. */
public String name;
}
/**
* Initializes the registry. It will use the supplied configuration
* instance to determine which lobbies to load, etc.
*
* @param config the server configuration.
* @param invmgr a reference to the server's invocation manager.
*/
public void init (Config config)
public void init (Config config, InvocationManager invmgr)
{
_config = config;
// register our invocation service handler
LobbyProvider provider = new LobbyProvider(this);
invmgr.registerProvider(MODULE_NAME, provider);
// create our lobby managers
String[] lmgrs = config.getValue(LOBIDS_KEY, (String[])null);
if (lmgrs == null || lmgrs.length == 0) {
Log.warning("No lobbies specified in config file (via '" +
LOBIDS_KEY + "' parameter.");
LOBIDS_KEY + "' parameter).");
} else {
for (int i = 0; i < lmgrs.length; i++) {
@@ -85,9 +105,9 @@ public class LobbyRegistry
_config.getProperties(MiCasaServer.CONFIG_KEY);
props = PropertiesUtil.getSubProperties(props, lobbyId);
// get the lobby manager class
// get the lobby manager class and UGI
String lmgrClass = props.getProperty("mgrclass");
if (lmgrClass == null) {
if (StringUtil.blank(lmgrClass)) {
throw new Exception("Missing 'mgrclass' definition in " +
"lobby configuration.");
}
@@ -96,8 +116,10 @@ public class LobbyRegistry
LobbyManager lobmgr = (LobbyManager)
MiCasaServer.plreg.createPlace(Class.forName(lmgrClass));
// initialize the manager
lobmgr.init(props);
// initialize the lobby manager. it will call lobbyReady()
// when it has obtained a reference to its lobby object and is
// ready to roll
lobmgr.init(this, props);
} catch (Exception e) {
Log.warning("Unable to create lobby manager " +
@@ -106,20 +128,85 @@ public class LobbyRegistry
}
/**
* Returns information about all lobbies matching the supplied pattern
* string. Presently the pattern is interpreted as a simple prefix and
* all lobbies matching that prefix will be returned.
* Returns information about all lobbies hosting games in the
* specified category.
*
* @param pattern the pattern to match or null if all lobbies should
* be returned.
* @param requester the body object of the client requesting the lobby
* list (which can be used to filter the list based on their
* capabilities).
* @param category the category of game for which the lobbies are
* desired.
* @param target the list into which the matching lobbies will be
* deposited.
*/
public Lobby[] getLobbies (String pattern)
public void getLobbies (BodyObject requester, String category,
List target)
{
return null;
ArrayList list = (ArrayList)_lobbies.get(category);
if (list != null) {
target.addAll(list);
}
}
/**
* Returns an array containing the category identifiers of all the
* categories in which lobbies have been registered with the registry.
*
* @param requester the body object of the client requesting the
* cateogory list (which can be used to filter the list based on their
* capabilities).
*/
public String[] getCategories (BodyObject requester)
{
// might want to cache this some day so that we don't recreate it
// every time someone wants it. we can cache the array until the
// category count changes
String[] cats = new String[_lobbies.size()];
Iterator iter = _lobbies.keySet().iterator();
for (int i = 0; iter.hasNext(); i++) {
cats[i] = (String)iter.next();
}
return cats;
}
/**
* Called by our lobby managers once they have started up and are
* ready to do their lobby duties.
*/
protected void lobbyReady (int placeOid, String gameIdent, String name)
{
// create a lobby record
Lobby record = new Lobby(placeOid, gameIdent, name);
// and register it in all the right lobby tables
StringTokenizer tok = new StringTokenizer(gameIdent, ",");
while (tok.hasMoreTokens()) {
String category = tok.nextToken();
registerLobby(category, record);
}
}
/** Registers the supplied lobby in the specified category table. */
protected void registerLobby (String category, Lobby record)
{
ArrayList catlist = (ArrayList)_lobbies.get(category);
if (catlist == null) {
catlist = new ArrayList();
_lobbies.put(category, catlist);
}
catlist.add(record);
Log.info("Registered lobby [cat=" + category +
", record=" + record + "].");
}
/** A reference to the server config object from which we loaded all
* of our configuration information. */
protected Config _config;
/** A table containing references to all of our lobby records (in the
* form of category lists. */
protected HashMap _lobbies = new HashMap();
/** The configuration key for the lobby managers list. */
protected static final String LOBIDS_KEY =
MiCasaServer.CONFIG_KEY + ".lobby_ids";
@@ -0,0 +1,215 @@
//
// $Id: LobbySelector.java,v 1.1 2001/10/04 23:41:44 mdb Exp $
package com.threerings.micasa.client;
import java.awt.BorderLayout;
import java.awt.Component;
import java.awt.event.*;
import java.util.*;
import javax.swing.*;
import javax.swing.event.AncestorEvent;
import javax.swing.event.AncestorListener;
import com.samskivert.util.StringUtil;
import com.threerings.cocktail.party.data.PlaceObject;
import com.threerings.micasa.Log;
import com.threerings.micasa.lobby.Lobby;
import com.threerings.micasa.lobby.LobbyService;
import com.threerings.micasa.util.MiCasaContext;
/**
* The lobby selector displays a drop-down box listing the categories of
* lobbies available on this server and when a category is selected, it
* displays a list of the lobbies that are available in that category. If
* a lobby is double-clicked, it moves the client into that lobby room.
*/
public class LobbySelector
extends JPanel implements ActionListener
{
/**
* Constructs a new lobby selector component. It will wait until it is
* visible before issuing a get categories request to download a list
* of categories.
*/
public LobbySelector (MiCasaContext ctx)
{
setLayout(new BorderLayout());
// keep this around for later
_ctx = ctx;
// create our drop-down box with a bogus entry at the moment
String[] options = new String[] { CAT_FIRST_ITEM };
_combo = new JComboBox(options);
_combo.addActionListener(this);
add(_combo, BorderLayout.NORTH);
// and create our empty lobby list
_loblist = new JList();
_loblist.setCellRenderer(new LobbyCellRenderer());
// add a mouse listener that tells us about double clicks
MouseListener ml = new MouseAdapter() {
public void mouseClicked (MouseEvent e) {
if (e.getClickCount() == 2) {
int index = _loblist.locationToIndex(e.getPoint());
Object item = _loblist.getSelectedValue();
enterLobby((Lobby)item);
}
}
};
_loblist.addMouseListener(ml);
add(_loblist, BorderLayout.CENTER);
// we'll need to know when we are made visible because we'll want
// to issue a request for our categories when that happens
addAncestorListener(new AncestorListener () {
public void ancestorAdded (AncestorEvent evt) {
// issue a get categories request to get the category list
LobbyService.getCategories(
_ctx.getClient(), LobbySelector.this);
}
public void ancestorRemoved (AncestorEvent evt) {
}
public void ancestorMoved (AncestorEvent evt) {
}
});
}
/**
* Called when the user selects a category or double-clicks on a
* lobby.
*/
public void actionPerformed (ActionEvent evt)
{
if (evt.getSource() == _combo) {
String selcat = (String)_combo.getSelectedItem();
if (!selcat.equals(CAT_FIRST_ITEM)) {
selectCategory(selcat);
}
}
}
/**
* Called in response to a {@link LobbyService#getCategories}
* invocation service request.
*/
public void handleGotCategories (int invid, String[] categories)
{
// append these to our "unselected" item
for (int i = 0; i < categories.length; i++) {
_combo.addItem(categories[i]);
}
}
/**
* Called in response to a {@link LobbyService#getLobbies} invocation
* service request.
*/
public void handleGotLobbies (int invid, List lobbies)
{
// create a list model for this category
DefaultListModel model = new DefaultListModel();
// populate it with the lobby info
Iterator iter = lobbies.iterator();
while (iter.hasNext()) {
model.addElement(iter.next());
}
// stick it in the table
_catlists.put(_pendingCategory, model);
// finally tell the lobby list to update the display (which we do
// by setting the combo box to this category in case the luser
// decided to try to select some new category while we weren't
// looking)
_combo.setSelectedItem(_pendingCategory);
// clear out our pending category indicator
_pendingCategory = null;
}
/**
* Called in response to a lobby invocation request when the request
* failed.
*/
public void handleRequestFailed (int invid, String reason)
{
Log.info("Request failed [invid=" + invid +
", reason=" + reason + "].");
// clear out our pending category indicator
_pendingCategory = null;
}
/**
* Fetches the list of lobbies available in a particular category (if
* they haven't already been fetched) and displays them in the lobby
* list.
*/
protected void selectCategory (String category)
{
DefaultListModel model = (DefaultListModel)_catlists.get(category);
if (model != null) {
_loblist.setModel(model);
} else if (_pendingCategory == null) {
// make a note that we're loading up this category
_pendingCategory = category;
// issue a request to load up the lobbies in this category
LobbyService.getLobbies(_ctx.getClient(), category, this);
} else {
Log.info("Ignoring category select request because " +
"one is outstanding [pcat=" + _pendingCategory +
", newcat=" + category + "].");
}
}
/** Called when the user selects a lobby from the lobby list. */
protected void enterLobby (Lobby lobby)
{
// make sure we're not already in this lobby
PlaceObject plobj = _ctx.getLocationDirector().getPlaceObject();
if (plobj != null && plobj.getOid() == lobby.placeOid) {
return;
}
// otherwise request that we go there
_ctx.getLocationDirector().moveTo(lobby.placeOid);
Log.info("Entering lobby " + lobby + ".");
}
/** Used to render Lobby instances in our lobby list. */
protected static class LobbyCellRenderer
extends DefaultListCellRenderer
{
public Component getListCellRendererComponent(
JList list,
Object value,
int index,
boolean isSelected,
boolean cellHasFocus) {
// use the lobby's name rather than the value of toString()
value = ((Lobby)value).name;
return super.getListCellRendererComponent(
list, value, index, isSelected, cellHasFocus);
}
}
protected MiCasaContext _ctx;
protected JComboBox _combo;
protected JList _loblist;
protected HashMap _catlists = new HashMap();
protected String _pendingCategory;
protected static final String CAT_FIRST_ITEM = "<categories...>";
}
@@ -0,0 +1,62 @@
//
// $Id: LobbyService.java,v 1.1 2001/10/04 23:41:44 mdb Exp $
package com.threerings.micasa.lobby;
import com.threerings.cocktail.cher.client.Client;
import com.threerings.cocktail.cher.client.InvocationDirector;
import com.threerings.micasa.Log;
/**
* This class provides an interface to the various parlor services that
* are directly invokable by the client (by means of the invocation
* services).
*/
public class LobbyService
implements LobbyCodes
{
/**
* Requests the list of lobby cateogories that are available on this
* server.
*
* @param client a connected, operational client instance.
* @param rsptarget the object reference that will receive and process
* the response. The response will come in the form of a method call
* to <code>handleGotCategories</code> or
* <code>handleRequestFailed</code>.
*
* @return the invocation request id of the generated request.
*/
public static int getCategories (Client client, Object rsptarget)
{
InvocationDirector invdir = client.getInvocationDirector();
Log.info("Sending get categories.");
return invdir.invoke(
MODULE_NAME, GET_CATEGORIES_REQUEST, null, rsptarget);
}
/**
* Requests information on all active lobbies that match the specified
* category.
*
* @param client a connected, operational client instance.
* @param category the category of game for which a list of lobbies is
* desired.
* @param rsptarget the object reference that will receive and process
* the response. The response will come in the form of a method call
* to <code>handleLobbyList</code> or
* <code>handleRequestFailed</code>.
*
* @return the invocation request id of the generated request.
*/
public static int getLobbies (
Client client, String category, Object rsptarget)
{
InvocationDirector invdir = client.getInvocationDirector();
Object[] args = new Object[] { category };
Log.info("Sending get lobbies [category=" + category + "].");
return invdir.invoke(
MODULE_NAME, GET_LOBBIES_REQUEST, args, rsptarget);
}
}
@@ -1,5 +1,5 @@
//
// $Id: MiCasaServer.java,v 1.1 2001/10/03 23:24:09 mdb Exp $
// $Id: MiCasaServer.java,v 1.2 2001/10/04 23:41:44 mdb Exp $
package com.threerings.micasa.server;
@@ -11,6 +11,7 @@ import com.threerings.cocktail.party.server.PartyServer;
import com.threerings.parlor.server.ParlorManager;
import com.threerings.micasa.Log;
import com.threerings.micasa.lobby.LobbyRegistry;
/**
* This class is the main entry point and general organizer of everything
@@ -27,6 +28,9 @@ public class MiCasaServer extends PartyServer
/** The parlor manager in operation on this server. */
public static ParlorManager parmgr = new ParlorManager();
/** The lobby registry operating on this server. */
public static LobbyRegistry lobreg = new LobbyRegistry();
/**
* Initializes all of the server services and prepares for operation.
*/
@@ -42,6 +46,9 @@ public class MiCasaServer extends PartyServer
// initialize our parlor manager
parmgr.init(config, invmgr);
// initialize the lobby registry
lobreg.init(config, invmgr);
// create our connection provider
String dbmap = config.getValue(DBMAP_KEY, DEF_DBMAP);
conprov = new StaticConnectionProvider(dbmap);