Behold Vilya, Ring of Air and repository for our game and virtual worldly
extensions to the distributed environment provided by Narya. git-svn-id: svn+ssh://src.earth.threerings.net/vilya/trunk@1 c613c5cb-e716-0410-b11b-feb51c14d237
This commit is contained in:
@@ -0,0 +1,72 @@
|
||||
//
|
||||
// $Id: Log.java 4191 2006-06-13 22:42:20Z ray $
|
||||
//
|
||||
// Narya library - tools for developing networked games
|
||||
// Copyright (C) 2002-2004 Three Rings Design, Inc., All Rights Reserved
|
||||
// http://www.threerings.net/code/narya/
|
||||
//
|
||||
// This library is free software; you can redistribute it and/or modify it
|
||||
// under the terms of the GNU Lesser General Public License as published
|
||||
// by the Free Software Foundation; either version 2.1 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This library is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
// Lesser General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public
|
||||
// License along with this library; if not, write to the Free Software
|
||||
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
package com.threerings.micasa;
|
||||
|
||||
/**
|
||||
* A placeholder class that contains a reference to the log object used by
|
||||
* the MiCasa package. This is a useful pattern to use when using the
|
||||
* samskivert logging facilities. One creates a top-level class like this
|
||||
* one that instantiates a log object with an name that identifies log
|
||||
* messages from that package and then provides static methods that
|
||||
* generate log messages using that instance. Then, classes in that
|
||||
* package need only import the log wrapper class and can easily use it to
|
||||
* generate log messages. For example:
|
||||
*
|
||||
* <pre>
|
||||
* import com.threerings.micasa.Log;
|
||||
* // ...
|
||||
* Log.warning("All hell is breaking loose!");
|
||||
* // ...
|
||||
* </pre>
|
||||
*
|
||||
* @see com.samskivert.util.Log
|
||||
*/
|
||||
public class Log
|
||||
{
|
||||
/** The static log instance configured for use by this package. */
|
||||
public static com.samskivert.util.Log log =
|
||||
new com.samskivert.util.Log("micasa");
|
||||
|
||||
/** Convenience function. */
|
||||
public static void debug (String message)
|
||||
{
|
||||
log.debug(message);
|
||||
}
|
||||
|
||||
/** Convenience function. */
|
||||
public static void info (String message)
|
||||
{
|
||||
log.info(message);
|
||||
}
|
||||
|
||||
/** Convenience function. */
|
||||
public static void warning (String message)
|
||||
{
|
||||
log.warning(message);
|
||||
}
|
||||
|
||||
/** Convenience function. */
|
||||
public static void logStackTrace (Throwable t)
|
||||
{
|
||||
log.logStackTrace(com.samskivert.util.Log.WARNING, t);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,336 @@
|
||||
//
|
||||
// $Id: ChatPanel.java 3741 2005-10-25 11:13:51Z elizabeth $
|
||||
//
|
||||
// Narya library - tools for developing networked games
|
||||
// Copyright (C) 2002-2004 Three Rings Design, Inc., All Rights Reserved
|
||||
// http://www.threerings.net/code/narya/
|
||||
//
|
||||
// This library is free software; you can redistribute it and/or modify it
|
||||
// under the terms of the GNU Lesser General Public License as published
|
||||
// by the Free Software Foundation; either version 2.1 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This library is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
// Lesser General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public
|
||||
// License along with this library; if not, write to the Free Software
|
||||
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
package com.threerings.micasa.client;
|
||||
|
||||
import java.awt.Color;
|
||||
import java.awt.Dimension;
|
||||
import java.awt.event.ActionEvent;
|
||||
import java.awt.event.ActionListener;
|
||||
|
||||
import java.util.StringTokenizer;
|
||||
|
||||
import javax.swing.JButton;
|
||||
import javax.swing.JComboBox;
|
||||
import javax.swing.JLabel;
|
||||
import javax.swing.JPanel;
|
||||
import javax.swing.JScrollPane;
|
||||
import javax.swing.JTextField;
|
||||
import javax.swing.JTextPane;
|
||||
|
||||
import javax.swing.event.AncestorEvent;
|
||||
import javax.swing.event.AncestorListener;
|
||||
|
||||
import javax.swing.text.BadLocationException;
|
||||
import javax.swing.text.Document;
|
||||
import javax.swing.text.Style;
|
||||
import javax.swing.text.StyleConstants;
|
||||
import javax.swing.text.StyleContext;
|
||||
|
||||
import com.samskivert.swing.GroupLayout;
|
||||
import com.samskivert.swing.HGroupLayout;
|
||||
import com.samskivert.swing.VGroupLayout;
|
||||
import com.samskivert.swing.event.AncestorAdapter;
|
||||
|
||||
import com.threerings.util.Name;
|
||||
|
||||
import com.threerings.crowd.chat.client.ChatDirector;
|
||||
import com.threerings.crowd.chat.client.ChatDisplay;
|
||||
import com.threerings.crowd.chat.data.ChatCodes;
|
||||
import com.threerings.crowd.chat.data.ChatMessage;
|
||||
import com.threerings.crowd.chat.data.SystemMessage;
|
||||
import com.threerings.crowd.chat.data.UserMessage;
|
||||
|
||||
import com.threerings.crowd.client.OccupantObserver;
|
||||
import com.threerings.crowd.client.PlaceView;
|
||||
import com.threerings.crowd.data.OccupantInfo;
|
||||
import com.threerings.crowd.data.PlaceObject;
|
||||
import com.threerings.crowd.util.CrowdContext;
|
||||
|
||||
import com.threerings.micasa.Log;
|
||||
|
||||
public class ChatPanel
|
||||
extends JPanel
|
||||
implements ActionListener, ChatDisplay, OccupantObserver, PlaceView
|
||||
{
|
||||
public ChatPanel (CrowdContext ctx)
|
||||
{
|
||||
// keep this around for later
|
||||
_ctx = ctx;
|
||||
|
||||
// create our chat director and register ourselves with it
|
||||
_chatdtr = new ChatDirector(_ctx, null, null);
|
||||
// XXX - the line above royally borks things because it sends
|
||||
// null, null downstream.
|
||||
_chatdtr.addChatDisplay(this);
|
||||
|
||||
// register as an occupant observer
|
||||
_ctx.getOccupantDirector().addOccupantObserver(this);
|
||||
|
||||
GroupLayout gl = new VGroupLayout(GroupLayout.STRETCH);
|
||||
gl.setOffAxisPolicy(GroupLayout.STRETCH);
|
||||
setLayout(gl);
|
||||
|
||||
// create our scrolling chat text display
|
||||
_text = new JTextPane();
|
||||
_text.setEditable(false);
|
||||
add(new JScrollPane(_text));
|
||||
|
||||
// create our styles and add those to the text pane
|
||||
createStyles(_text);
|
||||
|
||||
// add a label for the text entry stuff
|
||||
add(new JLabel("Type here to chat:"), GroupLayout.FIXED);
|
||||
|
||||
// create a horizontal group for the text entry bar
|
||||
gl = new HGroupLayout(GroupLayout.STRETCH);
|
||||
JPanel epanel = new JPanel(gl);
|
||||
epanel.add(_entry = new JTextField());
|
||||
_entry.setActionCommand("send");
|
||||
_entry.addActionListener(this);
|
||||
_entry.setEnabled(false);
|
||||
|
||||
_send = new JButton("Send");
|
||||
_send.setEnabled(false);
|
||||
_send.addActionListener(this);
|
||||
_send.setActionCommand("send");
|
||||
epanel.add(_send, GroupLayout.FIXED);
|
||||
add(epanel, GroupLayout.FIXED);
|
||||
|
||||
// listen to ancestor events to request focus when added
|
||||
addAncestorListener(new AncestorAdapter() {
|
||||
public void ancestorAdded (AncestorEvent e) {
|
||||
if (_focus) {
|
||||
_entry.requestFocusInWindow();
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* For applications where the chat box has extremely limited space,
|
||||
* the send button can be removed to leave more space for the text
|
||||
* input box.
|
||||
*/
|
||||
public void removeSendButton ()
|
||||
{
|
||||
if (_send.isVisible()) {
|
||||
// _send.getParent().remove(_send);
|
||||
_send.setVisible(false);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets whether the chat box text entry field requests the keyboard
|
||||
* focus when the panel receives {@link
|
||||
* AncestorListener#ancestorAdded} or {@link PlaceView#willEnterPlace}
|
||||
* events.
|
||||
*/
|
||||
public void setRequestFocus (boolean focus)
|
||||
{
|
||||
_focus = focus;
|
||||
}
|
||||
|
||||
protected void createStyles (JTextPane text)
|
||||
{
|
||||
StyleContext sctx = StyleContext.getDefaultStyleContext();
|
||||
Style defstyle = sctx.getStyle(StyleContext.DEFAULT_STYLE);
|
||||
|
||||
_nameStyle = text.addStyle("name", defstyle);
|
||||
StyleConstants.setForeground(_nameStyle, Color.blue);
|
||||
|
||||
_msgStyle = text.addStyle("msg", defstyle);
|
||||
StyleConstants.setForeground(_msgStyle, Color.black);
|
||||
|
||||
_errStyle = text.addStyle("err", defstyle);
|
||||
StyleConstants.setForeground(_errStyle, Color.red);
|
||||
|
||||
_noticeStyle = text.addStyle("notice", defstyle);
|
||||
StyleConstants.setForeground(_noticeStyle, Color.magenta);
|
||||
}
|
||||
|
||||
// documentation inherited
|
||||
public void actionPerformed (ActionEvent e)
|
||||
{
|
||||
String cmd = e.getActionCommand();
|
||||
if (cmd.equals("send")) {
|
||||
sendText();
|
||||
|
||||
} else {
|
||||
System.out.println("Unknown action event: " + cmd);
|
||||
}
|
||||
}
|
||||
|
||||
// documentation inherited
|
||||
public void occupantEntered (OccupantInfo info)
|
||||
{
|
||||
displayOccupantMessage("*** " + info.username + " entered.");
|
||||
}
|
||||
|
||||
// documentation inherited
|
||||
public void occupantLeft (OccupantInfo info)
|
||||
{
|
||||
displayOccupantMessage("*** " + info.username + " left.");
|
||||
}
|
||||
|
||||
// documentation inherited
|
||||
public void occupantUpdated (OccupantInfo oinfo, OccupantInfo info)
|
||||
{
|
||||
}
|
||||
|
||||
protected void displayOccupantMessage (String message)
|
||||
{
|
||||
append(message + "\n", _noticeStyle);
|
||||
}
|
||||
|
||||
protected void sendText ()
|
||||
{
|
||||
String text = _entry.getText();
|
||||
|
||||
// if the message to send begins with /tell then parse it and
|
||||
// generate a tell request rather than a speak request
|
||||
if (text.startsWith("/tell")) {
|
||||
StringTokenizer tok = new StringTokenizer(text);
|
||||
// there should be at least three tokens: '/tell target word'
|
||||
if (tok.countTokens() < 3) {
|
||||
displayError("Usage: /tell username message");
|
||||
return;
|
||||
}
|
||||
|
||||
// skip the /tell and grab the username
|
||||
tok.nextToken();
|
||||
String username = tok.nextToken();
|
||||
|
||||
// now strip off everything up to the username to get the
|
||||
// message
|
||||
int uidx = text.indexOf(username);
|
||||
String message = text.substring(uidx + username.length()).trim();
|
||||
|
||||
// request to send this text as a tell message
|
||||
_chatdtr.requestTell(new Name(username), message, null);
|
||||
|
||||
} else if (text.startsWith("/clear")) {
|
||||
// clear the chat box
|
||||
_chatdtr.clearDisplays();
|
||||
|
||||
} else {
|
||||
// request to send this text as a chat message
|
||||
_chatdtr.requestSpeak(null, text, ChatCodes.DEFAULT_MODE);
|
||||
}
|
||||
|
||||
// clear out the input because we sent a request
|
||||
_entry.setText("");
|
||||
}
|
||||
|
||||
// documentation inherited from interface ChatDisplay
|
||||
public void clear ()
|
||||
{
|
||||
_text.setText("");
|
||||
}
|
||||
|
||||
// documentation inherited from interface ChatDisplay
|
||||
public void displayMessage (ChatMessage message)
|
||||
{
|
||||
if (message instanceof UserMessage) {
|
||||
UserMessage msg = (UserMessage) message;
|
||||
if (msg.localtype == ChatCodes.USER_CHAT_TYPE) {
|
||||
append("[" + msg.speaker + " whispers] ", _nameStyle);
|
||||
append(msg.message + "\n", _msgStyle);
|
||||
} else {
|
||||
append("<" + msg.speaker + "> ", _nameStyle);
|
||||
append(msg.message + "\n", _msgStyle);
|
||||
}
|
||||
|
||||
} else if (message instanceof SystemMessage) {
|
||||
append(message.message + "\n", _noticeStyle);
|
||||
|
||||
} else {
|
||||
Log.warning("Received unknown message type [message=" +
|
||||
message + "].");
|
||||
}
|
||||
}
|
||||
|
||||
protected void displayError (String message)
|
||||
{
|
||||
append(message + "\n", _errStyle);
|
||||
}
|
||||
|
||||
/**
|
||||
* Append the specified text in the specified style.
|
||||
*/
|
||||
protected void append (String text, Style style)
|
||||
{
|
||||
Document doc = _text.getDocument();
|
||||
try {
|
||||
doc.insertString(doc.getLength(), text, style);
|
||||
} catch (BadLocationException ble) {
|
||||
Log.warning("Unable to insert text!? [error=" + ble + "].");
|
||||
}
|
||||
}
|
||||
|
||||
public void willEnterPlace (PlaceObject place)
|
||||
{
|
||||
// enable our chat input elements since we're now somewhere that
|
||||
// we can chat
|
||||
_entry.setEnabled(true);
|
||||
_send.setEnabled(true);
|
||||
if (_focus) {
|
||||
_entry.requestFocusInWindow();
|
||||
}
|
||||
}
|
||||
|
||||
// documentation inherited
|
||||
public void didLeavePlace (PlaceObject place)
|
||||
{
|
||||
// nothing doing
|
||||
}
|
||||
|
||||
// documentation inherited
|
||||
public Dimension getPreferredSize ()
|
||||
{
|
||||
Dimension size = super.getPreferredSize();
|
||||
// always prefer a sensible but not overly large width. this also
|
||||
// prevents us from inheriting a foolishly large preferred width
|
||||
// from the JTextPane which sometimes decides it wants to be as
|
||||
// wide as its widest line of text rather than wrap that line of
|
||||
// text.
|
||||
size.width = PREFERRED_WIDTH;
|
||||
return size;
|
||||
}
|
||||
|
||||
protected CrowdContext _ctx;
|
||||
protected ChatDirector _chatdtr;
|
||||
|
||||
protected boolean _focus = true;
|
||||
|
||||
protected JComboBox _roombox;
|
||||
protected JTextPane _text;
|
||||
protected JButton _send;
|
||||
protected JTextField _entry;
|
||||
|
||||
protected Style _nameStyle;
|
||||
protected Style _msgStyle;
|
||||
protected Style _errStyle;
|
||||
protected Style _noticeStyle;
|
||||
|
||||
/** A width that isn't so skinny that the text is teeny. */
|
||||
protected static final int PREFERRED_WIDTH = 200;
|
||||
}
|
||||
@@ -0,0 +1,140 @@
|
||||
//
|
||||
// $Id: ClientController.java 4191 2006-06-13 22:42:20Z ray $
|
||||
//
|
||||
// Narya library - tools for developing networked games
|
||||
// Copyright (C) 2002-2004 Three Rings Design, Inc., All Rights Reserved
|
||||
// http://www.threerings.net/code/narya/
|
||||
//
|
||||
// This library is free software; you can redistribute it and/or modify it
|
||||
// under the terms of the GNU Lesser General Public License as published
|
||||
// by the Free Software Foundation; either version 2.1 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This library is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
// Lesser General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public
|
||||
// License along with this library; if not, write to the Free Software
|
||||
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
package com.threerings.micasa.client;
|
||||
|
||||
import java.awt.event.ActionEvent;
|
||||
import com.samskivert.swing.Controller;
|
||||
|
||||
import com.threerings.presents.client.Client;
|
||||
import com.threerings.presents.client.SessionObserver;
|
||||
|
||||
import com.threerings.crowd.data.BodyObject;
|
||||
|
||||
import com.threerings.micasa.Log;
|
||||
import com.threerings.micasa.data.MiCasaBootstrapData;
|
||||
import com.threerings.micasa.util.MiCasaContext;
|
||||
|
||||
/**
|
||||
* Responsible for top-level control of the client user interface.
|
||||
*/
|
||||
public class ClientController extends Controller
|
||||
implements SessionObserver
|
||||
{
|
||||
/**
|
||||
* Creates a new client controller. The controller will set everything
|
||||
* up in preparation for logging on.
|
||||
*/
|
||||
public ClientController (MiCasaContext ctx, MiCasaFrame frame)
|
||||
{
|
||||
// we'll want to keep these around
|
||||
_ctx = ctx;
|
||||
_frame = frame;
|
||||
|
||||
// we want to know about logon/logoff
|
||||
_ctx.getClient().addClientObserver(this);
|
||||
|
||||
// create the logon panel and display it
|
||||
_logonPanel = new LogonPanel(_ctx);
|
||||
_frame.setPanel(_logonPanel);
|
||||
}
|
||||
|
||||
// documentation inherited
|
||||
public boolean handleAction (ActionEvent action)
|
||||
{
|
||||
String cmd = action.getActionCommand();
|
||||
|
||||
if (cmd.equals("logoff")) {
|
||||
// request that we logoff
|
||||
_ctx.getClient().logoff(true);
|
||||
return true;
|
||||
}
|
||||
|
||||
Log.info("Unhandled action: " + action);
|
||||
return false;
|
||||
}
|
||||
|
||||
// documentation inherited
|
||||
public void clientDidLogon (Client client)
|
||||
{
|
||||
Log.info("Client did logon [client=" + client + "].");
|
||||
|
||||
// keep the body object around for stuff
|
||||
_body = (BodyObject)client.getClientObject();
|
||||
|
||||
// figure out where to go
|
||||
int moveOid = -1;
|
||||
|
||||
// hacky hack
|
||||
String jumpOidStr = null;
|
||||
try {
|
||||
jumpOidStr = System.getProperty("jumpoid");
|
||||
} catch (SecurityException se) {
|
||||
Log.info("Not checking for jumpOid as we're in an applet.");
|
||||
}
|
||||
|
||||
if (jumpOidStr != null) {
|
||||
try {
|
||||
moveOid = Integer.parseInt(jumpOidStr);
|
||||
} catch (NumberFormatException nfe) {
|
||||
Log.warning("Invalid jump oid [oid=" + jumpOidStr +
|
||||
", err=" + nfe + "].");
|
||||
}
|
||||
|
||||
} else if (_body.location != -1) {
|
||||
// if we were already in a location, go there
|
||||
moveOid = _body.location;
|
||||
|
||||
} else {
|
||||
// otherwise head to the default lobby to start things off
|
||||
MiCasaBootstrapData data = (MiCasaBootstrapData)
|
||||
client.getBootstrapData();
|
||||
moveOid = data.defLobbyOid;
|
||||
}
|
||||
|
||||
if (moveOid > 0) {
|
||||
_ctx.getLocationDirector().moveTo(moveOid);
|
||||
}
|
||||
}
|
||||
|
||||
// documentation inherited
|
||||
public void clientObjectDidChange (Client client)
|
||||
{
|
||||
// regrab our body object
|
||||
_body = (BodyObject)client.getClientObject();
|
||||
}
|
||||
|
||||
// documentation inherited
|
||||
public void clientDidLogoff (Client client)
|
||||
{
|
||||
Log.info("Client did logoff [client=" + client + "].");
|
||||
|
||||
// reinstate the logon panel
|
||||
_frame.setPanel(_logonPanel);
|
||||
}
|
||||
|
||||
protected MiCasaContext _ctx;
|
||||
protected MiCasaFrame _frame;
|
||||
protected BodyObject _body;
|
||||
|
||||
// our panels
|
||||
protected LogonPanel _logonPanel;
|
||||
}
|
||||
@@ -0,0 +1,234 @@
|
||||
//
|
||||
// $Id: LogonPanel.java 4158 2006-05-30 22:12:15Z mdb $
|
||||
//
|
||||
// Narya library - tools for developing networked games
|
||||
// Copyright (C) 2002-2004 Three Rings Design, Inc., All Rights Reserved
|
||||
// http://www.threerings.net/code/narya/
|
||||
//
|
||||
// This library is free software; you can redistribute it and/or modify it
|
||||
// under the terms of the GNU Lesser General Public License as published
|
||||
// by the Free Software Foundation; either version 2.1 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This library is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
// Lesser General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public
|
||||
// License along with this library; if not, write to the Free Software
|
||||
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
package com.threerings.micasa.client;
|
||||
|
||||
import java.awt.Dimension;
|
||||
import java.awt.Font;
|
||||
import java.awt.event.ActionEvent;
|
||||
import java.awt.event.ActionListener;
|
||||
|
||||
import javax.swing.JButton;
|
||||
import javax.swing.JLabel;
|
||||
import javax.swing.JPanel;
|
||||
import javax.swing.JPasswordField;
|
||||
import javax.swing.JScrollPane;
|
||||
import javax.swing.JTextArea;
|
||||
import javax.swing.JTextField;
|
||||
|
||||
import com.samskivert.swing.GroupLayout;
|
||||
import com.samskivert.swing.HGroupLayout;
|
||||
import com.samskivert.swing.VGroupLayout;
|
||||
|
||||
import com.threerings.util.MessageBundle;
|
||||
import com.threerings.util.Name;
|
||||
|
||||
import com.threerings.presents.client.Client;
|
||||
import com.threerings.presents.client.ClientObserver;
|
||||
import com.threerings.presents.client.LogonException;
|
||||
import com.threerings.presents.net.Credentials;
|
||||
import com.threerings.presents.net.UsernamePasswordCreds;
|
||||
|
||||
import com.threerings.micasa.util.MiCasaContext;
|
||||
|
||||
public class LogonPanel extends JPanel
|
||||
implements ActionListener, ClientObserver
|
||||
{
|
||||
public LogonPanel (MiCasaContext ctx)
|
||||
{
|
||||
// keep these around for later
|
||||
_ctx = ctx;
|
||||
_msgs = _ctx.getMessageManager().getBundle("micasa");
|
||||
|
||||
setLayout(new VGroupLayout());
|
||||
|
||||
// stick the logon components into a panel that will stretch them
|
||||
// to a sensible width
|
||||
JPanel box = new JPanel(
|
||||
new VGroupLayout(VGroupLayout.NONE, VGroupLayout.STRETCH,
|
||||
5, VGroupLayout.CENTER)) {
|
||||
public Dimension getPreferredSize () {
|
||||
Dimension psize = super.getPreferredSize();
|
||||
psize.width = Math.max(psize.width, 300);
|
||||
return psize;
|
||||
}
|
||||
};
|
||||
add(box);
|
||||
|
||||
// try obtaining our title text from a system property
|
||||
String tstr = null;
|
||||
try {
|
||||
tstr = System.getProperty("logon.title");
|
||||
} catch (Throwable t) {
|
||||
}
|
||||
if (tstr == null) {
|
||||
tstr = "Mi Casa!";
|
||||
}
|
||||
|
||||
// create a big fat label
|
||||
JLabel title = new JLabel(tstr, JLabel.CENTER);
|
||||
title.setFont(new Font("Helvetica", Font.BOLD, 24));
|
||||
box.add(title);
|
||||
|
||||
// create the username bar
|
||||
JPanel bar = new JPanel(new HGroupLayout(GroupLayout.STRETCH));
|
||||
bar.add(new JLabel(_msgs.get("m.username")), GroupLayout.FIXED);
|
||||
_username = new JTextField();
|
||||
_username.setActionCommand("skipToPassword");
|
||||
_username.addActionListener(this);
|
||||
bar.add(_username);
|
||||
box.add(bar);
|
||||
|
||||
// create the password bar
|
||||
bar = new JPanel(new HGroupLayout(GroupLayout.STRETCH));
|
||||
bar.add(new JLabel(_msgs.get("m.password")), GroupLayout.FIXED);
|
||||
_password = new JPasswordField();
|
||||
_password.setActionCommand("logon");
|
||||
_password.addActionListener(this);
|
||||
bar.add(_password);
|
||||
box.add(bar);
|
||||
|
||||
// create the logon button bar
|
||||
HGroupLayout gl = new HGroupLayout(GroupLayout.NONE);
|
||||
gl.setJustification(GroupLayout.RIGHT);
|
||||
bar = new JPanel(gl);
|
||||
_logon = new JButton(_msgs.get("m.logon"));
|
||||
_logon.setActionCommand("logon");
|
||||
_logon.addActionListener(this);
|
||||
bar.add(_logon);
|
||||
box.add(bar);
|
||||
|
||||
box.add(new JLabel(_msgs.get("m.status")));
|
||||
_status = new JTextArea() {
|
||||
public Dimension getPreferredScrollableViewportSize ()
|
||||
{
|
||||
return new Dimension(10, 100);
|
||||
}
|
||||
};
|
||||
_status.setEditable(false);
|
||||
JScrollPane scroller = new JScrollPane(_status);
|
||||
box.add(scroller);
|
||||
|
||||
// we'll want to listen for logon failure
|
||||
_ctx.getClient().addClientObserver(this);
|
||||
|
||||
// start with focus in the username field
|
||||
_username.requestFocusInWindow();
|
||||
}
|
||||
|
||||
public void actionPerformed (ActionEvent e)
|
||||
{
|
||||
String cmd = e.getActionCommand();
|
||||
if (cmd.equals("skipToPassword")) {
|
||||
_password.requestFocusInWindow();
|
||||
|
||||
} else if (cmd.equals("logon")) {
|
||||
logon();
|
||||
|
||||
} else {
|
||||
System.out.println("Unknown action event: " + cmd);
|
||||
}
|
||||
}
|
||||
|
||||
// documentation inherited from interface
|
||||
public void clientDidLogon (Client client)
|
||||
{
|
||||
_status.append(_msgs.get("m.logon_success") + "\n");
|
||||
}
|
||||
|
||||
// documentation inherited from interface
|
||||
public void clientDidLogoff (Client client)
|
||||
{
|
||||
_status.append(_msgs.get("m.logged_off") + "\n");
|
||||
setLogonEnabled(true);
|
||||
}
|
||||
|
||||
// documentation inherited from interface
|
||||
public void clientFailedToLogon (Client client, Exception cause)
|
||||
{
|
||||
String msg;
|
||||
if (cause instanceof LogonException) {
|
||||
msg = MessageBundle.compose("m.logon_failed", cause.getMessage());
|
||||
} else {
|
||||
msg = MessageBundle.tcompose("m.logon_failed", cause.getMessage());
|
||||
}
|
||||
_status.append(_msgs.xlate(msg) + "\n");
|
||||
setLogonEnabled(true);
|
||||
}
|
||||
|
||||
// documentation inherited from interface
|
||||
public void clientObjectDidChange (Client client)
|
||||
{
|
||||
// nothing we can do here...
|
||||
}
|
||||
|
||||
// documentation inherited from interface
|
||||
public void clientConnectionFailed (Client client, Exception cause)
|
||||
{
|
||||
String msg = MessageBundle.tcompose("m.connection_failed",
|
||||
cause.getMessage());
|
||||
_status.append(_msgs.xlate(msg) + "\n");
|
||||
setLogonEnabled(true);
|
||||
}
|
||||
|
||||
// documentation inherited from interface
|
||||
public boolean clientWillLogoff (Client client)
|
||||
{
|
||||
// no vetoing here
|
||||
return true;
|
||||
}
|
||||
|
||||
protected void logon ()
|
||||
{
|
||||
// disable further logon attempts until we hear back
|
||||
setLogonEnabled(false);
|
||||
|
||||
Name username = new Name(_username.getText().trim());
|
||||
String password = new String(_password.getPassword()).trim();
|
||||
|
||||
String server = _ctx.getClient().getHostname();
|
||||
int port = _ctx.getClient().getPorts()[0];
|
||||
String msg = MessageBundle.tcompose("m.logging_on",
|
||||
server, String.valueOf(port));
|
||||
_status.append(_msgs.xlate(msg) + "\n");
|
||||
|
||||
// configure the client with some credentials and logon
|
||||
Credentials creds = new UsernamePasswordCreds(username, password);
|
||||
Client client = _ctx.getClient();
|
||||
client.setCredentials(creds);
|
||||
client.logon();
|
||||
}
|
||||
|
||||
protected void setLogonEnabled (boolean enabled)
|
||||
{
|
||||
_username.setEnabled(enabled);
|
||||
_password.setEnabled(enabled);
|
||||
_logon.setEnabled(enabled);
|
||||
}
|
||||
|
||||
protected MiCasaContext _ctx;
|
||||
protected MessageBundle _msgs;
|
||||
|
||||
protected JTextField _username;
|
||||
protected JPasswordField _password;
|
||||
protected JButton _logon;
|
||||
protected JTextArea _status;
|
||||
}
|
||||
@@ -0,0 +1,115 @@
|
||||
//
|
||||
// $Id: MiCasaApp.java 4158 2006-05-30 22:12:15Z mdb $
|
||||
//
|
||||
// Narya library - tools for developing networked games
|
||||
// Copyright (C) 2002-2004 Three Rings Design, Inc., All Rights Reserved
|
||||
// http://www.threerings.net/code/narya/
|
||||
//
|
||||
// This library is free software; you can redistribute it and/or modify it
|
||||
// under the terms of the GNU Lesser General Public License as published
|
||||
// by the Free Software Foundation; either version 2.1 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This library is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
// Lesser General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public
|
||||
// License along with this library; if not, write to the Free Software
|
||||
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
package com.threerings.micasa.client;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import com.samskivert.swing.util.SwingUtil;
|
||||
import com.threerings.util.Name;
|
||||
|
||||
import com.threerings.presents.client.Client;
|
||||
import com.threerings.presents.net.UsernamePasswordCreds;
|
||||
|
||||
import com.threerings.micasa.Log;
|
||||
|
||||
/**
|
||||
* The micasa app is the main point of entry for the MiCasa client
|
||||
* application. It creates and initializes the myriad components of the
|
||||
* client and sets all the proper wheels in motion.
|
||||
*/
|
||||
public class MiCasaApp
|
||||
{
|
||||
public void init ()
|
||||
throws IOException
|
||||
{
|
||||
// create a frame
|
||||
_frame = new MiCasaFrame();
|
||||
|
||||
// create our client instance
|
||||
String cclass = null;
|
||||
try {
|
||||
cclass = System.getProperty("client");
|
||||
} catch (Throwable t) {
|
||||
// security manager in effect, no problem
|
||||
}
|
||||
if (cclass == null) {
|
||||
cclass = MiCasaClient.class.getName();
|
||||
}
|
||||
|
||||
try {
|
||||
_client = (MiCasaClient)Class.forName(cclass).newInstance();
|
||||
} catch (Exception e) {
|
||||
Log.warning("Unable to instantiate client class " +
|
||||
"[cclass=" + cclass + "].");
|
||||
Log.logStackTrace(e);
|
||||
}
|
||||
|
||||
// initialize our client instance
|
||||
_client.init(_frame);
|
||||
}
|
||||
|
||||
public void run (String server, String username, String password)
|
||||
{
|
||||
// position everything and show the frame
|
||||
_frame.setSize(800, 600);
|
||||
SwingUtil.centerWindow(_frame);
|
||||
_frame.setVisible(true);
|
||||
|
||||
Client client = _client.getContext().getClient();
|
||||
|
||||
Log.info("Using [server=" + server + ".");
|
||||
client.setServer(server, Client.DEFAULT_SERVER_PORTS);
|
||||
|
||||
// configure the client with some credentials and logon
|
||||
if (username != null && password != null) {
|
||||
// create and set our credentials
|
||||
client.setCredentials(
|
||||
new UsernamePasswordCreds(new Name(username), password));
|
||||
client.logon();
|
||||
}
|
||||
}
|
||||
|
||||
public static void main (String[] args)
|
||||
{
|
||||
String server = "localhost";
|
||||
if (args.length > 0) {
|
||||
server = args[0];
|
||||
}
|
||||
String username = (args.length > 1) ? args[1] : null;
|
||||
String password = (args.length > 2) ? args[2] : null;
|
||||
|
||||
MiCasaApp app = new MiCasaApp();
|
||||
try {
|
||||
// initialize the app
|
||||
app.init();
|
||||
} catch (IOException ioe) {
|
||||
Log.warning("Error initializing application.");
|
||||
Log.logStackTrace(ioe);
|
||||
}
|
||||
|
||||
// and run it
|
||||
app.run(server, username, password);
|
||||
}
|
||||
|
||||
protected MiCasaClient _client;
|
||||
protected MiCasaFrame _frame;
|
||||
}
|
||||
@@ -0,0 +1,124 @@
|
||||
//
|
||||
// $Id: MiCasaApplet.java 4158 2006-05-30 22:12:15Z mdb $
|
||||
//
|
||||
// Narya library - tools for developing networked games
|
||||
// Copyright (C) 2002-2004 Three Rings Design, Inc., All Rights Reserved
|
||||
// http://www.threerings.net/code/narya/
|
||||
//
|
||||
// This library is free software; you can redistribute it and/or modify it
|
||||
// under the terms of the GNU Lesser General Public License as published
|
||||
// by the Free Software Foundation; either version 2.1 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This library is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
// Lesser General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public
|
||||
// License along with this library; if not, write to the Free Software
|
||||
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
package com.threerings.micasa.client;
|
||||
|
||||
import java.applet.Applet;
|
||||
import java.io.IOException;
|
||||
|
||||
import com.samskivert.swing.util.SwingUtil;
|
||||
import com.threerings.util.Name;
|
||||
|
||||
import com.threerings.presents.client.Client;
|
||||
import com.threerings.presents.client.ClientAdapter;
|
||||
import com.threerings.presents.net.UsernamePasswordCreds;
|
||||
|
||||
import com.threerings.micasa.Log;
|
||||
|
||||
/**
|
||||
* The MiCasa applet is used to make MiCasa games available via the web
|
||||
* browser.
|
||||
*/
|
||||
public class MiCasaApplet extends Applet
|
||||
{
|
||||
/**
|
||||
* Create the client instance and set things up.
|
||||
*/
|
||||
public void init ()
|
||||
{
|
||||
try {
|
||||
// create a frame
|
||||
_frame = new MiCasaFrame();
|
||||
|
||||
// create our client instance
|
||||
_client = new MiCasaClient();
|
||||
_client.init(_frame);
|
||||
|
||||
Name username = new Name(requireParameter("username"));
|
||||
String authkey = requireParameter("authkey");
|
||||
String server = getCodeBase().getHost();
|
||||
|
||||
Client client = _client.getContext().getClient();
|
||||
|
||||
// indicate which server to which we should connect
|
||||
client.setServer(server, Client.DEFAULT_SERVER_PORTS);
|
||||
|
||||
// create and set our credentials
|
||||
client.setCredentials(
|
||||
new UsernamePasswordCreds(username, authkey));
|
||||
|
||||
// we want to hide the client frame when we logoff
|
||||
client.addClientObserver(new ClientAdapter() {
|
||||
public void clientDidLogoff (Client c)
|
||||
{
|
||||
_frame.setVisible(false);
|
||||
}
|
||||
});
|
||||
|
||||
} catch (IOException ioe) {
|
||||
Log.warning("Unable to create client.");
|
||||
Log.logStackTrace(ioe);
|
||||
}
|
||||
}
|
||||
|
||||
protected String requireParameter (String name)
|
||||
throws IOException
|
||||
{
|
||||
String value = getParameter(name);
|
||||
if (value == null) {
|
||||
throw new IOException("Applet missing '" + name + "' parameter.");
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Display the client frame and really get things going.
|
||||
*/
|
||||
public void start ()
|
||||
{
|
||||
if (_client != null) {
|
||||
// show the frame
|
||||
_frame.setSize(800, 600);
|
||||
SwingUtil.centerWindow(_frame);
|
||||
_frame.setVisible(true);
|
||||
// and log on
|
||||
_client.getContext().getClient().logon();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Log off and shut on down.
|
||||
*/
|
||||
public void stop ()
|
||||
{
|
||||
if (_client != null) {
|
||||
// hide the frame and log off
|
||||
_frame.setVisible(false);
|
||||
Client client = _client.getContext().getClient();
|
||||
if (client.isLoggedOn()) {
|
||||
client.logoff(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected MiCasaClient _client;
|
||||
protected MiCasaFrame _frame;
|
||||
}
|
||||
@@ -0,0 +1,232 @@
|
||||
//
|
||||
// $Id: MiCasaClient.java 4158 2006-05-30 22:12:15Z mdb $
|
||||
//
|
||||
// Narya library - tools for developing networked games
|
||||
// Copyright (C) 2002-2004 Three Rings Design, Inc., All Rights Reserved
|
||||
// http://www.threerings.net/code/narya/
|
||||
//
|
||||
// This library is free software; you can redistribute it and/or modify it
|
||||
// under the terms of the GNU Lesser General Public License as published
|
||||
// by the Free Software Foundation; either version 2.1 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This library is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
// Lesser General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public
|
||||
// License along with this library; if not, write to the Free Software
|
||||
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
package com.threerings.micasa.client;
|
||||
|
||||
import java.awt.EventQueue;
|
||||
import java.awt.event.WindowAdapter;
|
||||
import java.awt.event.WindowEvent;
|
||||
import java.io.IOException;
|
||||
import javax.swing.JPanel;
|
||||
|
||||
import com.samskivert.util.Config;
|
||||
import com.samskivert.util.RunQueue;
|
||||
import com.threerings.util.MessageManager;
|
||||
|
||||
import com.threerings.presents.client.Client;
|
||||
import com.threerings.presents.dobj.DObjectManager;
|
||||
|
||||
import com.threerings.crowd.client.LocationDirector;
|
||||
import com.threerings.crowd.client.OccupantDirector;
|
||||
import com.threerings.crowd.client.PlaceView;
|
||||
|
||||
import com.threerings.crowd.chat.client.ChatDirector;
|
||||
|
||||
import com.threerings.parlor.client.ParlorDirector;
|
||||
|
||||
import com.threerings.micasa.util.MiCasaContext;
|
||||
|
||||
/**
|
||||
* The MiCasa client takes care of instantiating all of the proper
|
||||
* managers and loading up all of the necessary configuration and getting
|
||||
* the client bootstrapped. It can be extended by games that require an
|
||||
* extended context implementation.
|
||||
*/
|
||||
public class MiCasaClient
|
||||
implements RunQueue
|
||||
{
|
||||
/**
|
||||
* Initializes a new client and provides it with a frame in which to
|
||||
* display everything.
|
||||
*/
|
||||
public void init (MiCasaFrame frame)
|
||||
throws IOException
|
||||
{
|
||||
// create our context
|
||||
_ctx = createContextImpl();
|
||||
|
||||
// create the directors/managers/etc. provided by the context
|
||||
createContextServices();
|
||||
|
||||
// for test purposes, hardcode the server info
|
||||
_client.setServer("localhost", Client.DEFAULT_SERVER_PORTS);
|
||||
|
||||
// keep this for later
|
||||
_frame = frame;
|
||||
|
||||
// log off when they close the window
|
||||
_frame.addWindowListener(new WindowAdapter() {
|
||||
public void windowClosing (WindowEvent evt) {
|
||||
// if we're logged on, log off
|
||||
if (_client.isLoggedOn()) {
|
||||
_client.logoff(true);
|
||||
} else {
|
||||
// otherwise get the heck out
|
||||
System.exit(0);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
// create our client controller and stick it in the frame
|
||||
_frame.setController(new ClientController(_ctx, _frame));
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a reference to the context in effect for this client. This
|
||||
* reference is valid for the lifetime of the application.
|
||||
*/
|
||||
public MiCasaContext getContext ()
|
||||
{
|
||||
return _ctx;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates the {@link MiCasaContext} implementation that will be
|
||||
* passed around to all of the client code. Derived classes may wish
|
||||
* to override this and create some extended context implementation.
|
||||
*/
|
||||
protected MiCasaContext createContextImpl ()
|
||||
{
|
||||
return new MiCasaContextImpl();
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates and initializes the various services that are provided by
|
||||
* the context. Derived classes that provide an extended context
|
||||
* should override this method and create their own extended
|
||||
* services. They should be sure to call
|
||||
* <code>super.createContextServices</code>.
|
||||
*/
|
||||
protected void createContextServices ()
|
||||
throws IOException
|
||||
{
|
||||
// create the handles on our various services
|
||||
_client = new Client(null, this);
|
||||
|
||||
// create our managers and directors
|
||||
_locdir = new LocationDirector(_ctx);
|
||||
_occdir = new OccupantDirector(_ctx);
|
||||
_pardtr = new ParlorDirector(_ctx);
|
||||
_msgmgr = new MessageManager(MESSAGE_MANAGER_PREFIX);
|
||||
_chatdir = new ChatDirector(_ctx, _msgmgr, null);
|
||||
}
|
||||
|
||||
// documentation inherited from interface RunQueue
|
||||
public void postRunnable (Runnable run)
|
||||
{
|
||||
// queue it on up on the awt thread
|
||||
EventQueue.invokeLater(run);
|
||||
}
|
||||
|
||||
// documentation inherited from interface RunQueue
|
||||
public boolean isDispatchThread ()
|
||||
{
|
||||
return EventQueue.isDispatchThread();
|
||||
}
|
||||
|
||||
/**
|
||||
* The context implementation. This provides access to all of the
|
||||
* objects and services that are needed by the operating client.
|
||||
*/
|
||||
protected class MiCasaContextImpl implements MiCasaContext
|
||||
{
|
||||
/**
|
||||
* Apparently the default constructor has default access, rather
|
||||
* than protected access, even though this class is declared to be
|
||||
* protected. Why, I don't know, but we need to be able to extend
|
||||
* this class elsewhere, so we need this.
|
||||
*/
|
||||
protected MiCasaContextImpl ()
|
||||
{
|
||||
}
|
||||
|
||||
public Client getClient ()
|
||||
{
|
||||
return _client;
|
||||
}
|
||||
|
||||
public DObjectManager getDObjectManager ()
|
||||
{
|
||||
return _client.getDObjectManager();
|
||||
}
|
||||
|
||||
public Config getConfig ()
|
||||
{
|
||||
return _config;
|
||||
}
|
||||
|
||||
public LocationDirector getLocationDirector ()
|
||||
{
|
||||
return _locdir;
|
||||
}
|
||||
|
||||
public OccupantDirector getOccupantDirector ()
|
||||
{
|
||||
return _occdir;
|
||||
}
|
||||
|
||||
public ChatDirector getChatDirector ()
|
||||
{
|
||||
return _chatdir;
|
||||
}
|
||||
|
||||
public ParlorDirector getParlorDirector ()
|
||||
{
|
||||
return _pardtr;
|
||||
}
|
||||
|
||||
public void setPlaceView (PlaceView view)
|
||||
{
|
||||
// stick the place view into our frame
|
||||
_frame.setPanel((JPanel)view);
|
||||
}
|
||||
|
||||
public void clearPlaceView (PlaceView view)
|
||||
{
|
||||
// we'll just let the next place view replace our old one
|
||||
}
|
||||
|
||||
public MiCasaFrame getFrame ()
|
||||
{
|
||||
return _frame;
|
||||
}
|
||||
|
||||
public MessageManager getMessageManager ()
|
||||
{
|
||||
return _msgmgr;
|
||||
}
|
||||
}
|
||||
|
||||
protected MiCasaContext _ctx;
|
||||
protected MiCasaFrame _frame;
|
||||
protected Config _config = new Config("micasa");
|
||||
|
||||
protected Client _client;
|
||||
protected LocationDirector _locdir;
|
||||
protected OccupantDirector _occdir;
|
||||
protected ChatDirector _chatdir;
|
||||
protected ParlorDirector _pardtr;
|
||||
protected MessageManager _msgmgr;
|
||||
|
||||
/** The prefix prepended to localization bundle names before looking
|
||||
* them up in the classpath. */
|
||||
protected static final String MESSAGE_MANAGER_PREFIX = "rsrc.i18n";
|
||||
}
|
||||
@@ -0,0 +1,89 @@
|
||||
//
|
||||
// $Id: MiCasaFrame.java 4191 2006-06-13 22:42:20Z ray $
|
||||
//
|
||||
// Narya library - tools for developing networked games
|
||||
// Copyright (C) 2002-2004 Three Rings Design, Inc., All Rights Reserved
|
||||
// http://www.threerings.net/code/narya/
|
||||
//
|
||||
// This library is free software; you can redistribute it and/or modify it
|
||||
// under the terms of the GNU Lesser General Public License as published
|
||||
// by the Free Software Foundation; either version 2.1 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This library is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
// Lesser General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public
|
||||
// License along with this library; if not, write to the Free Software
|
||||
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
package com.threerings.micasa.client;
|
||||
|
||||
import java.awt.BorderLayout;
|
||||
|
||||
import javax.swing.JFrame;
|
||||
import javax.swing.JPanel;
|
||||
|
||||
import com.samskivert.swing.Controller;
|
||||
import com.samskivert.swing.ControllerProvider;
|
||||
|
||||
/**
|
||||
* Contains the user interface for the MiCasa client application.
|
||||
*/
|
||||
public class MiCasaFrame
|
||||
extends JFrame implements ControllerProvider
|
||||
{
|
||||
/**
|
||||
* Constructs the top-level MiCasa client frame.
|
||||
*/
|
||||
public MiCasaFrame ()
|
||||
{
|
||||
this("MiCasa Client");
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs the top-level MiCasa client frame with the specified
|
||||
* window title.
|
||||
*/
|
||||
public MiCasaFrame (String title)
|
||||
{
|
||||
super(title);
|
||||
|
||||
// we'll handle shutting things down ourselves
|
||||
setDefaultCloseOperation(DO_NOTHING_ON_CLOSE);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the panel that makes up the entire client display.
|
||||
*/
|
||||
public void setPanel (JPanel panel)
|
||||
{
|
||||
// remove the old panel
|
||||
getContentPane().removeAll();
|
||||
// add the new one
|
||||
getContentPane().add(panel, BorderLayout.CENTER);
|
||||
// swing doesn't properly repaint after adding/removing children
|
||||
panel.revalidate();
|
||||
repaint();
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the controller for the outermost scope. This controller will
|
||||
* handle all actions that aren't handled by controllers of tigher
|
||||
* scope.
|
||||
*/
|
||||
public void setController (Controller controller)
|
||||
{
|
||||
_controller = controller;
|
||||
}
|
||||
|
||||
// documentation inherited
|
||||
public Controller getController ()
|
||||
{
|
||||
return _controller;
|
||||
}
|
||||
|
||||
protected Controller _controller;
|
||||
}
|
||||
@@ -0,0 +1,101 @@
|
||||
//
|
||||
// $Id: OccupantList.java 3406 2005-03-15 02:12:03Z mdb $
|
||||
//
|
||||
// Narya library - tools for developing networked games
|
||||
// Copyright (C) 2002-2004 Three Rings Design, Inc., All Rights Reserved
|
||||
// http://www.threerings.net/code/narya/
|
||||
//
|
||||
// This library is free software; you can redistribute it and/or modify it
|
||||
// under the terms of the GNU Lesser General Public License as published
|
||||
// by the Free Software Foundation; either version 2.1 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This library is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
// Lesser General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public
|
||||
// License along with this library; if not, write to the Free Software
|
||||
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
package com.threerings.micasa.client;
|
||||
|
||||
import java.util.Iterator;
|
||||
import javax.swing.DefaultListModel;
|
||||
import javax.swing.JList;
|
||||
|
||||
import com.threerings.crowd.client.OccupantObserver;
|
||||
import com.threerings.crowd.client.PlaceView;
|
||||
import com.threerings.crowd.data.OccupantInfo;
|
||||
import com.threerings.crowd.data.PlaceObject;
|
||||
import com.threerings.crowd.util.CrowdContext;
|
||||
|
||||
/**
|
||||
* 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 (CrowdContext 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.getOccupantDirector().addOccupantObserver(this);
|
||||
}
|
||||
|
||||
// documentation inherited
|
||||
public void willEnterPlace (PlaceObject plobj)
|
||||
{
|
||||
// add all of the occupants of the place to our list
|
||||
Iterator users = plobj.occupantInfo.iterator();
|
||||
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 oinfo, OccupantInfo info)
|
||||
{
|
||||
// nothing doing
|
||||
}
|
||||
|
||||
/** Our client context. */
|
||||
protected CrowdContext _ctx;
|
||||
|
||||
/** A list model that provides a vector interface. */
|
||||
protected DefaultListModel _model;
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
//
|
||||
// $Id: MiCasaBootstrapData.java 4191 2006-06-13 22:42:20Z ray $
|
||||
//
|
||||
// Narya library - tools for developing networked games
|
||||
// Copyright (C) 2002-2004 Three Rings Design, Inc., All Rights Reserved
|
||||
// http://www.threerings.net/code/narya/
|
||||
//
|
||||
// This library is free software; you can redistribute it and/or modify it
|
||||
// under the terms of the GNU Lesser General Public License as published
|
||||
// by the Free Software Foundation; either version 2.1 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This library is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
// Lesser General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public
|
||||
// License along with this library; if not, write to the Free Software
|
||||
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
package com.threerings.micasa.data;
|
||||
|
||||
import com.threerings.presents.net.BootstrapData;
|
||||
|
||||
/**
|
||||
* Extends the basic Presents bootstrap data and provides some bootstrap
|
||||
* information specific to the MiCasa services.
|
||||
*/
|
||||
public class MiCasaBootstrapData extends BootstrapData
|
||||
{
|
||||
/** The oid of the default lobby. */
|
||||
public int defLobbyOid;
|
||||
}
|
||||
@@ -0,0 +1,59 @@
|
||||
//
|
||||
// $Id: Lobby.java 3726 2005-10-11 19:17:43Z ray $
|
||||
//
|
||||
// Narya library - tools for developing networked games
|
||||
// Copyright (C) 2002-2004 Three Rings Design, Inc., All Rights Reserved
|
||||
// http://www.threerings.net/code/narya/
|
||||
//
|
||||
// This library is free software; you can redistribute it and/or modify it
|
||||
// under the terms of the GNU Lesser General Public License as published
|
||||
// by the Free Software Foundation; either version 2.1 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This library is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
// Lesser General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public
|
||||
// License along with this library; if not, write to the Free Software
|
||||
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
package com.threerings.micasa.lobby;
|
||||
|
||||
import com.threerings.io.SimpleStreamableObject;
|
||||
|
||||
/**
|
||||
* A simple class for keeping track of information for each lobby in
|
||||
* operation on the server.
|
||||
*/
|
||||
public class Lobby extends SimpleStreamableObject
|
||||
{
|
||||
/** 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 ()
|
||||
{
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,108 @@
|
||||
//
|
||||
// $Id: LobbyConfig.java 4191 2006-06-13 22:42:20Z ray $
|
||||
//
|
||||
// Narya library - tools for developing networked games
|
||||
// Copyright (C) 2002-2004 Three Rings Design, Inc., All Rights Reserved
|
||||
// http://www.threerings.net/code/narya/
|
||||
//
|
||||
// This library is free software; you can redistribute it and/or modify it
|
||||
// under the terms of the GNU Lesser General Public License as published
|
||||
// by the Free Software Foundation; either version 2.1 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This library is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
// Lesser General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public
|
||||
// License along with this library; if not, write to the Free Software
|
||||
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
package com.threerings.micasa.lobby;
|
||||
|
||||
import javax.swing.JComponent;
|
||||
import javax.swing.JLabel;
|
||||
|
||||
import java.util.Properties;
|
||||
import com.samskivert.util.StringUtil;
|
||||
|
||||
import com.threerings.crowd.client.PlaceController;
|
||||
import com.threerings.crowd.data.PlaceConfig;
|
||||
import com.threerings.micasa.util.MiCasaContext;
|
||||
import com.threerings.parlor.game.data.GameConfig;
|
||||
|
||||
public class LobbyConfig extends PlaceConfig
|
||||
{
|
||||
// documentation inherited
|
||||
public PlaceController createController ()
|
||||
{
|
||||
return new LobbyController();
|
||||
}
|
||||
|
||||
// documentation inherited
|
||||
public String getManagerClassName ()
|
||||
{
|
||||
return "com.threerings.micasa.lobby.LobbyManager";
|
||||
}
|
||||
|
||||
/**
|
||||
* Derived classes override this function and create the appropriate
|
||||
* matchmaking user interface component.
|
||||
*/
|
||||
public JComponent createMatchMakingView (MiCasaContext ctx)
|
||||
{
|
||||
return new JLabel("Match-making view goes here.");
|
||||
}
|
||||
|
||||
/**
|
||||
* Instantiates and returns a game config instance using the game
|
||||
* config classname provided by the lobby configuration parameters.
|
||||
*
|
||||
* @exception Exception thrown if a problem occurs loading or
|
||||
* instantiating the class.
|
||||
*/
|
||||
public GameConfig getGameConfig ()
|
||||
throws Exception
|
||||
{
|
||||
return (GameConfig)Class.forName(_gameConfigClass).newInstance();
|
||||
}
|
||||
|
||||
/**
|
||||
* Initializes this lobby config object with the properties that are
|
||||
* used to configure the lobby. This is called on the server when the
|
||||
* lobby is loaded.
|
||||
*/
|
||||
public void init (Properties config)
|
||||
throws Exception
|
||||
{
|
||||
_gameConfigClass = getConfigValue(config, "game_config");
|
||||
}
|
||||
|
||||
// documentation inherited
|
||||
protected void toString (StringBuilder buf)
|
||||
{
|
||||
super.toString(buf);
|
||||
if (buf.length() > 1) {
|
||||
buf.append(", ");
|
||||
}
|
||||
buf.append("game_config=").append(_gameConfigClass);
|
||||
}
|
||||
|
||||
/** 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.isBlank(value)) {
|
||||
throw new Exception("Missing '" + key + "' definition in " +
|
||||
"lobby configuration.");
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
/** The name of the game config class that represents the type of game
|
||||
* we are matchmaking for in this lobby. */
|
||||
protected String _gameConfigClass;
|
||||
}
|
||||
@@ -0,0 +1,121 @@
|
||||
//
|
||||
// $Id: LobbyController.java 3440 2005-03-30 01:09:30Z mdb $
|
||||
//
|
||||
// Narya library - tools for developing networked games
|
||||
// Copyright (C) 2002-2004 Three Rings Design, Inc., All Rights Reserved
|
||||
// http://www.threerings.net/code/narya/
|
||||
//
|
||||
// This library is free software; you can redistribute it and/or modify it
|
||||
// under the terms of the GNU Lesser General Public License as published
|
||||
// by the Free Software Foundation; either version 2.1 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This library is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
// Lesser General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public
|
||||
// License along with this library; if not, write to the Free Software
|
||||
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
package com.threerings.micasa.lobby;
|
||||
|
||||
import com.threerings.util.Name;
|
||||
|
||||
import com.threerings.crowd.data.PlaceConfig;
|
||||
import com.threerings.crowd.data.PlaceObject;
|
||||
import com.threerings.crowd.client.PlaceController;
|
||||
import com.threerings.crowd.client.PlaceView;
|
||||
import com.threerings.crowd.util.CrowdContext;
|
||||
|
||||
import com.threerings.parlor.client.*;
|
||||
import com.threerings.parlor.game.data.GameConfig;
|
||||
|
||||
import com.threerings.micasa.Log;
|
||||
import com.threerings.micasa.util.MiCasaContext;
|
||||
|
||||
public class LobbyController extends PlaceController
|
||||
implements InvitationHandler, InvitationResponseObserver
|
||||
{
|
||||
public void init (CrowdContext ctx, PlaceConfig config)
|
||||
{
|
||||
// cast our context reference
|
||||
_ctx = (MiCasaContext)ctx;
|
||||
_config = (LobbyConfig)config;
|
||||
|
||||
super.init(ctx, config);
|
||||
|
||||
// register ourselves as the invitation handler
|
||||
_ctx.getParlorDirector().setInvitationHandler(this);
|
||||
}
|
||||
|
||||
protected PlaceView createPlaceView (CrowdContext ctx)
|
||||
{
|
||||
return new LobbyPanel(_ctx, _config);
|
||||
}
|
||||
|
||||
// documentation inherited
|
||||
public void willEnterPlace (PlaceObject plobj)
|
||||
{
|
||||
super.willEnterPlace(plobj);
|
||||
|
||||
try {
|
||||
// if a system property has been specified requesting that we
|
||||
// invite another player, do so now
|
||||
String invitee = System.getProperty("invitee");
|
||||
if (invitee != null) {
|
||||
// create a game config object
|
||||
try {
|
||||
GameConfig config = _config.getGameConfig();
|
||||
_ctx.getParlorDirector().invite(
|
||||
new Name(invitee), config, this);
|
||||
} catch (Exception e) {
|
||||
Log.warning("Error instantiating game config.");
|
||||
Log.logStackTrace(e);
|
||||
}
|
||||
}
|
||||
|
||||
} catch (SecurityException se) {
|
||||
// nothing to see here, move it along...
|
||||
}
|
||||
}
|
||||
|
||||
// documentation inherited from interface
|
||||
public void invitationReceived (Invitation invite)
|
||||
{
|
||||
Log.info("Invitation received [invite=" + invite + "].");
|
||||
|
||||
// accept the invitation. we're game...
|
||||
invite.accept();
|
||||
}
|
||||
|
||||
// documentation inherited from interface
|
||||
public void invitationCancelled (Invitation invite)
|
||||
{
|
||||
Log.info("Invitation cancelled " + invite + ".");
|
||||
}
|
||||
|
||||
// documentation inherited from interface
|
||||
public void invitationAccepted (Invitation invite)
|
||||
{
|
||||
Log.info("Invitation accepted " + invite + ".");
|
||||
}
|
||||
|
||||
// documentation inherited from interface
|
||||
public void invitationRefused (Invitation invite, String message)
|
||||
{
|
||||
Log.info("Invitation refused [invite=" + invite +
|
||||
", message=" + message + "].");
|
||||
}
|
||||
|
||||
// documentation inherited from interface
|
||||
public void invitationCountered (Invitation invite, GameConfig config)
|
||||
{
|
||||
Log.info("Invitation countered [invite=" + invite +
|
||||
", config=" + config + "].");
|
||||
}
|
||||
|
||||
protected MiCasaContext _ctx;
|
||||
protected LobbyConfig _config;
|
||||
}
|
||||
@@ -0,0 +1,78 @@
|
||||
//
|
||||
// $Id: LobbyDispatcher.java 4145 2006-05-24 01:24:24Z ray $
|
||||
//
|
||||
// Narya library - tools for developing networked games
|
||||
// Copyright (C) 2002-2006 Three Rings Design, Inc., All Rights Reserved
|
||||
// http://www.threerings.net/code/narya/
|
||||
//
|
||||
// This library is free software; you can redistribute it and/or modify it
|
||||
// under the terms of the GNU Lesser General Public License as published
|
||||
// by the Free Software Foundation; either version 2.1 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This library is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
// Lesser General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public
|
||||
// License along with this library; if not, write to the Free Software
|
||||
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
package com.threerings.micasa.lobby;
|
||||
|
||||
import com.threerings.micasa.lobby.LobbyMarshaller;
|
||||
import com.threerings.micasa.lobby.LobbyService;
|
||||
import com.threerings.presents.client.Client;
|
||||
import com.threerings.presents.data.ClientObject;
|
||||
import com.threerings.presents.data.InvocationMarshaller;
|
||||
import com.threerings.presents.server.InvocationDispatcher;
|
||||
import com.threerings.presents.server.InvocationException;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Dispatches requests to the {@link LobbyProvider}.
|
||||
*/
|
||||
public class LobbyDispatcher extends InvocationDispatcher
|
||||
{
|
||||
/**
|
||||
* Creates a dispatcher that may be registered to dispatch invocation
|
||||
* service requests for the specified provider.
|
||||
*/
|
||||
public LobbyDispatcher (LobbyProvider provider)
|
||||
{
|
||||
this.provider = provider;
|
||||
}
|
||||
|
||||
// documentation inherited
|
||||
public InvocationMarshaller createMarshaller ()
|
||||
{
|
||||
return new LobbyMarshaller();
|
||||
}
|
||||
|
||||
// documentation inherited
|
||||
public void dispatchRequest (
|
||||
ClientObject source, int methodId, Object[] args)
|
||||
throws InvocationException
|
||||
{
|
||||
switch (methodId) {
|
||||
case LobbyMarshaller.GET_CATEGORIES:
|
||||
((LobbyProvider)provider).getCategories(
|
||||
source,
|
||||
(LobbyService.CategoriesListener)args[0]
|
||||
);
|
||||
return;
|
||||
|
||||
case LobbyMarshaller.GET_LOBBIES:
|
||||
((LobbyProvider)provider).getLobbies(
|
||||
source,
|
||||
(String)args[0], (LobbyService.LobbiesListener)args[1]
|
||||
);
|
||||
return;
|
||||
|
||||
default:
|
||||
super.dispatchRequest(source, methodId, args);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,91 @@
|
||||
//
|
||||
// $Id: LobbyManager.java 3749 2005-11-09 04:00:16Z mdb $
|
||||
//
|
||||
// Narya library - tools for developing networked games
|
||||
// Copyright (C) 2002-2004 Three Rings Design, Inc., All Rights Reserved
|
||||
// http://www.threerings.net/code/narya/
|
||||
//
|
||||
// This library is free software; you can redistribute it and/or modify it
|
||||
// under the terms of the GNU Lesser General Public License as published
|
||||
// by the Free Software Foundation; either version 2.1 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This library is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
// Lesser General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public
|
||||
// License along with this library; if not, write to the Free Software
|
||||
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
package com.threerings.micasa.lobby;
|
||||
|
||||
import java.util.Properties;
|
||||
import com.samskivert.util.StringUtil;
|
||||
|
||||
import com.threerings.crowd.server.PlaceManager;
|
||||
import com.threerings.micasa.Log;
|
||||
|
||||
/**
|
||||
* Takes care of the server side of a particular lobby.
|
||||
*/
|
||||
public class LobbyManager extends PlaceManager
|
||||
{
|
||||
/**
|
||||
* Initializes this lobby manager with its configuration properties.
|
||||
*
|
||||
* @exception Exception thrown if a configuration error is detected.
|
||||
*/
|
||||
public void init (LobbyRegistry lobreg, Properties config)
|
||||
throws Exception
|
||||
{
|
||||
// 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.isBlank(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;
|
||||
}
|
||||
@@ -0,0 +1,132 @@
|
||||
//
|
||||
// $Id: LobbyMarshaller.java 4145 2006-05-24 01:24:24Z ray $
|
||||
//
|
||||
// Narya library - tools for developing networked games
|
||||
// Copyright (C) 2002-2006 Three Rings Design, Inc., All Rights Reserved
|
||||
// http://www.threerings.net/code/narya/
|
||||
//
|
||||
// This library is free software; you can redistribute it and/or modify it
|
||||
// under the terms of the GNU Lesser General Public License as published
|
||||
// by the Free Software Foundation; either version 2.1 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This library is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
// Lesser General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public
|
||||
// License along with this library; if not, write to the Free Software
|
||||
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
package com.threerings.micasa.lobby;
|
||||
|
||||
import com.threerings.micasa.lobby.LobbyService;
|
||||
import com.threerings.presents.client.Client;
|
||||
import com.threerings.presents.data.InvocationMarshaller;
|
||||
import com.threerings.presents.dobj.InvocationResponseEvent;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Provides the implementation of the {@link LobbyService} interface
|
||||
* that marshalls the arguments and delivers the request to the provider
|
||||
* on the server. Also provides an implementation of the response listener
|
||||
* interfaces that marshall the response arguments and deliver them back
|
||||
* to the requesting client.
|
||||
*/
|
||||
public class LobbyMarshaller extends InvocationMarshaller
|
||||
implements LobbyService
|
||||
{
|
||||
// documentation inherited
|
||||
public static class CategoriesMarshaller extends ListenerMarshaller
|
||||
implements CategoriesListener
|
||||
{
|
||||
/** The method id used to dispatch {@link #gotCategories}
|
||||
* responses. */
|
||||
public static final int GOT_CATEGORIES = 1;
|
||||
|
||||
// documentation inherited from interface
|
||||
public void gotCategories (String[] arg1)
|
||||
{
|
||||
_invId = null;
|
||||
omgr.postEvent(new InvocationResponseEvent(
|
||||
callerOid, requestId, GOT_CATEGORIES,
|
||||
new Object[] { arg1 }));
|
||||
}
|
||||
|
||||
// documentation inherited
|
||||
public void dispatchResponse (int methodId, Object[] args)
|
||||
{
|
||||
switch (methodId) {
|
||||
case GOT_CATEGORIES:
|
||||
((CategoriesListener)listener).gotCategories(
|
||||
(String[])args[0]);
|
||||
return;
|
||||
|
||||
default:
|
||||
super.dispatchResponse(methodId, args);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// documentation inherited
|
||||
public static class LobbiesMarshaller extends ListenerMarshaller
|
||||
implements LobbiesListener
|
||||
{
|
||||
/** The method id used to dispatch {@link #gotLobbies}
|
||||
* responses. */
|
||||
public static final int GOT_LOBBIES = 1;
|
||||
|
||||
// documentation inherited from interface
|
||||
public void gotLobbies (List arg1)
|
||||
{
|
||||
_invId = null;
|
||||
omgr.postEvent(new InvocationResponseEvent(
|
||||
callerOid, requestId, GOT_LOBBIES,
|
||||
new Object[] { arg1 }));
|
||||
}
|
||||
|
||||
// documentation inherited
|
||||
public void dispatchResponse (int methodId, Object[] args)
|
||||
{
|
||||
switch (methodId) {
|
||||
case GOT_LOBBIES:
|
||||
((LobbiesListener)listener).gotLobbies(
|
||||
(List)args[0]);
|
||||
return;
|
||||
|
||||
default:
|
||||
super.dispatchResponse(methodId, args);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/** The method id used to dispatch {@link #getCategories} requests. */
|
||||
public static final int GET_CATEGORIES = 1;
|
||||
|
||||
// documentation inherited from interface
|
||||
public void getCategories (Client arg1, LobbyService.CategoriesListener arg2)
|
||||
{
|
||||
LobbyMarshaller.CategoriesMarshaller listener2 = new LobbyMarshaller.CategoriesMarshaller();
|
||||
listener2.listener = arg2;
|
||||
sendRequest(arg1, GET_CATEGORIES, new Object[] {
|
||||
listener2
|
||||
});
|
||||
}
|
||||
|
||||
/** The method id used to dispatch {@link #getLobbies} requests. */
|
||||
public static final int GET_LOBBIES = 2;
|
||||
|
||||
// documentation inherited from interface
|
||||
public void getLobbies (Client arg1, String arg2, LobbyService.LobbiesListener arg3)
|
||||
{
|
||||
LobbyMarshaller.LobbiesMarshaller listener3 = new LobbyMarshaller.LobbiesMarshaller();
|
||||
listener3.listener = arg3;
|
||||
sendRequest(arg1, GET_LOBBIES, new Object[] {
|
||||
arg2, listener3
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
//
|
||||
// $Id: LobbyObject.java 3218 2004-11-17 23:16:56Z mdb $
|
||||
//
|
||||
// Narya library - tools for developing networked games
|
||||
// Copyright (C) 2002-2004 Three Rings Design, Inc., All Rights Reserved
|
||||
// http://www.threerings.net/code/narya/
|
||||
//
|
||||
// This library is free software; you can redistribute it and/or modify it
|
||||
// under the terms of the GNU Lesser General Public License as published
|
||||
// by the Free Software Foundation; either version 2.1 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This library is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
// Lesser General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public
|
||||
// License along with this library; if not, write to the Free Software
|
||||
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
package com.threerings.micasa.lobby;
|
||||
|
||||
import com.threerings.crowd.data.PlaceObject;
|
||||
|
||||
/**
|
||||
* Presently the lobby object contains nothing specific, but the class
|
||||
* acts as a placeholder in case lobby-wide fields are needed in the
|
||||
* future.
|
||||
*/
|
||||
public class LobbyObject extends PlaceObject
|
||||
{
|
||||
}
|
||||
@@ -0,0 +1,114 @@
|
||||
//
|
||||
// $Id: LobbyPanel.java 4191 2006-06-13 22:42:20Z ray $
|
||||
//
|
||||
// Narya library - tools for developing networked games
|
||||
// Copyright (C) 2002-2004 Three Rings Design, Inc., All Rights Reserved
|
||||
// http://www.threerings.net/code/narya/
|
||||
//
|
||||
// This library is free software; you can redistribute it and/or modify it
|
||||
// under the terms of the GNU Lesser General Public License as published
|
||||
// by the Free Software Foundation; either version 2.1 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This library is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
// Lesser General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public
|
||||
// License along with this library; if not, write to the Free Software
|
||||
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
package com.threerings.micasa.lobby;
|
||||
|
||||
import javax.swing.*;
|
||||
import com.samskivert.swing.*;
|
||||
|
||||
import com.threerings.crowd.client.PlaceView;
|
||||
import com.threerings.crowd.data.PlaceObject;
|
||||
|
||||
import com.threerings.micasa.client.*;
|
||||
import com.threerings.micasa.util.MiCasaContext;
|
||||
|
||||
/**
|
||||
* Used to display the interface for the lobbies. It contains a lobby
|
||||
* selection mechanism, a chat interface and a user interface for whatever
|
||||
* match-making mechanism is appropriate for this particular lobby.
|
||||
*/
|
||||
public class LobbyPanel
|
||||
extends JPanel implements PlaceView
|
||||
{
|
||||
/**
|
||||
* Constructs a new lobby panel and the associated user interface
|
||||
* elements.
|
||||
*/
|
||||
public LobbyPanel (MiCasaContext ctx, LobbyConfig config)
|
||||
{
|
||||
// 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);
|
||||
setLayout(gl);
|
||||
|
||||
// create our main panel
|
||||
gl = new VGroupLayout(GroupLayout.STRETCH);
|
||||
gl.setOffAxisPolicy(GroupLayout.STRETCH);
|
||||
_main = new JPanel(gl);
|
||||
|
||||
// create our match-making view
|
||||
_main.add(config.createMatchMakingView(ctx));
|
||||
|
||||
// create a chat box and stick that in as well
|
||||
_main.add(new ChatPanel(ctx));
|
||||
|
||||
// now add the main panel into the mix
|
||||
add(_main);
|
||||
|
||||
// create our sidebar panel
|
||||
gl = new VGroupLayout(GroupLayout.STRETCH);
|
||||
gl.setOffAxisPolicy(GroupLayout.STRETCH);
|
||||
JPanel sidePanel = new JPanel(gl);
|
||||
|
||||
// the sidebar contains a lobby info display...
|
||||
|
||||
// ...a lobby selector...
|
||||
JLabel label = new JLabel("Select a lobby...");
|
||||
sidePanel.add(label, GroupLayout.FIXED);
|
||||
LobbySelector selector = new LobbySelector(ctx);
|
||||
sidePanel.add(selector);
|
||||
|
||||
// and an occupants list
|
||||
label = new JLabel("People in lobby");
|
||||
sidePanel.add(label, GroupLayout.FIXED);
|
||||
_occupants = new OccupantList(ctx);
|
||||
sidePanel.add(_occupants);
|
||||
|
||||
JButton logoff = new JButton("Logoff");
|
||||
logoff.addActionListener(Controller.DISPATCHER);
|
||||
logoff.setActionCommand("logoff");
|
||||
sidePanel.add(logoff, GroupLayout.FIXED);
|
||||
|
||||
// add our sidebar panel into the mix
|
||||
add(sidePanel, GroupLayout.FIXED);
|
||||
}
|
||||
|
||||
// documentation inherited
|
||||
public void willEnterPlace (PlaceObject plobj)
|
||||
{
|
||||
}
|
||||
|
||||
// documentation inherited
|
||||
public void didLeavePlace (PlaceObject plobj)
|
||||
{
|
||||
}
|
||||
|
||||
/** Contains the match-making view and the chatbox. */
|
||||
protected JPanel _main;
|
||||
|
||||
/** Our occupant list display. */
|
||||
protected OccupantList _occupants;
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
//
|
||||
// $Id: LobbyProvider.java 4145 2006-05-24 01:24:24Z ray $
|
||||
//
|
||||
// Narya library - tools for developing networked games
|
||||
// Copyright (C) 2002-2006 Three Rings Design, Inc., All Rights Reserved
|
||||
// http://www.threerings.net/code/narya/
|
||||
//
|
||||
// This library is free software; you can redistribute it and/or modify it
|
||||
// under the terms of the GNU Lesser General Public License as published
|
||||
// by the Free Software Foundation; either version 2.1 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This library is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
// Lesser General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public
|
||||
// License along with this library; if not, write to the Free Software
|
||||
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
package com.threerings.micasa.lobby;
|
||||
|
||||
import com.threerings.micasa.lobby.LobbyService;
|
||||
import com.threerings.presents.client.Client;
|
||||
import com.threerings.presents.data.ClientObject;
|
||||
import com.threerings.presents.server.InvocationException;
|
||||
import com.threerings.presents.server.InvocationProvider;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Defines the server-side of the {@link LobbyService}.
|
||||
*/
|
||||
public interface LobbyProvider extends InvocationProvider
|
||||
{
|
||||
/**
|
||||
* Handles a {@link LobbyService#getCategories} request.
|
||||
*/
|
||||
public void getCategories (ClientObject caller, LobbyService.CategoriesListener arg1)
|
||||
throws InvocationException;
|
||||
|
||||
/**
|
||||
* Handles a {@link LobbyService#getLobbies} request.
|
||||
*/
|
||||
public void getLobbies (ClientObject caller, String arg1, LobbyService.LobbiesListener arg2)
|
||||
throws InvocationException;
|
||||
}
|
||||
@@ -0,0 +1,272 @@
|
||||
//
|
||||
// $Id: LobbyRegistry.java 3749 2005-11-09 04:00:16Z mdb $
|
||||
//
|
||||
// Narya library - tools for developing networked games
|
||||
// Copyright (C) 2002-2004 Three Rings Design, Inc., All Rights Reserved
|
||||
// http://www.threerings.net/code/narya/
|
||||
//
|
||||
// This library is free software; you can redistribute it and/or modify it
|
||||
// under the terms of the GNU Lesser General Public License as published
|
||||
// by the Free Software Foundation; either version 2.1 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This library is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
// Lesser General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public
|
||||
// License along with this library; if not, write to the Free Software
|
||||
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
package com.threerings.micasa.lobby;
|
||||
|
||||
import java.util.*;
|
||||
import com.samskivert.util.*;
|
||||
import com.threerings.util.StreamableArrayList;
|
||||
|
||||
import com.threerings.presents.data.ClientObject;
|
||||
import com.threerings.presents.server.InvocationManager;
|
||||
|
||||
import com.threerings.crowd.data.BodyObject;
|
||||
|
||||
import com.threerings.micasa.Log;
|
||||
import com.threerings.micasa.lobby.LobbyService.CategoriesListener;
|
||||
import com.threerings.micasa.lobby.LobbyService.LobbiesListener;
|
||||
import com.threerings.micasa.server.MiCasaConfig;
|
||||
import com.threerings.micasa.server.MiCasaServer;
|
||||
|
||||
/**
|
||||
* The lobby registry is the primary class that coordinates the lobby
|
||||
* services on the client. It sets up the necessary invocation services
|
||||
* and keeps track of the lobbies in operation on the server. Only one
|
||||
* lobby registry should be created on a server.
|
||||
*
|
||||
* <p> Presently, the lobby registry is configured with lobbies via the
|
||||
* server configuration. An example configuration follows:
|
||||
*
|
||||
* <pre>
|
||||
* 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>
|
||||
*
|
||||
* This information will be loaded from the MiCasa server configuration
|
||||
* which means that it should live in
|
||||
* <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
|
||||
implements LobbyProvider
|
||||
{
|
||||
/**
|
||||
* Initializes the registry. It will use the supplied configuration
|
||||
* instance to determine which lobbies to load, etc.
|
||||
*
|
||||
* @param invmgr a reference to the server's invocation manager.
|
||||
*/
|
||||
public void init (InvocationManager invmgr)
|
||||
{
|
||||
// register ourselves as an invocation service handler
|
||||
invmgr.registerDispatcher(new LobbyDispatcher(this), true);
|
||||
|
||||
// create our lobby managers
|
||||
String[] lmgrs = null;
|
||||
lmgrs = MiCasaConfig.config.getValue(LOBIDS_KEY, lmgrs);
|
||||
if (lmgrs == null || lmgrs.length == 0) {
|
||||
Log.warning("No lobbies specified in config file (via '" +
|
||||
LOBIDS_KEY + "' parameter).");
|
||||
|
||||
} else {
|
||||
for (int i = 0; i < lmgrs.length; i++) {
|
||||
loadLobby(lmgrs[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the oid of the default lobby.
|
||||
*/
|
||||
public int getDefaultLobbyOid ()
|
||||
{
|
||||
return _defLobbyOid;
|
||||
}
|
||||
|
||||
/**
|
||||
* Extracts the properties for a lobby from the server config and
|
||||
* creates and initializes the lobby manager.
|
||||
*/
|
||||
protected void loadLobby (String lobbyId)
|
||||
{
|
||||
try {
|
||||
// extract the properties for this lobby
|
||||
Properties props = MiCasaConfig.config.getSubProperties(lobbyId);
|
||||
|
||||
// get the lobby manager class and UGI
|
||||
String cfgClass = props.getProperty("config");
|
||||
if (StringUtil.isBlank(cfgClass)) {
|
||||
throw new Exception("Missing 'config' definition in " +
|
||||
"lobby configuration.");
|
||||
}
|
||||
|
||||
// create and initialize the lobby config object
|
||||
LobbyConfig config = (LobbyConfig)
|
||||
Class.forName(cfgClass).newInstance();
|
||||
config.init(props);
|
||||
|
||||
// create and initialize the lobby manager. it will call
|
||||
// lobbyReady() when it has obtained a reference to its lobby
|
||||
// object and is ready to roll
|
||||
LobbyManager lobmgr = (LobbyManager)
|
||||
MiCasaServer.plreg.createPlace(config, null);
|
||||
lobmgr.init(this, props);
|
||||
|
||||
} catch (Exception e) {
|
||||
Log.warning("Unable to create lobby manager " +
|
||||
"[lobbyId=" + lobbyId + ", error=" + e + "].");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns information about all lobbies hosting games in the
|
||||
* specified category.
|
||||
*
|
||||
* @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 void getLobbies (BodyObject requester, String category,
|
||||
List target)
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
||||
/**
|
||||
* Processes a request by the client to obtain a list of the lobby
|
||||
* categories available on this server.
|
||||
*/
|
||||
public void getCategories (ClientObject caller, CategoriesListener listener)
|
||||
{
|
||||
listener.gotCategories(getCategories((BodyObject)caller));
|
||||
}
|
||||
|
||||
/**
|
||||
* Processes a request by the client to obtain a list of lobbies
|
||||
* matching the supplied category string.
|
||||
*/
|
||||
public void getLobbies (ClientObject caller, String category,
|
||||
LobbiesListener listener)
|
||||
{
|
||||
StreamableArrayList target = new StreamableArrayList();
|
||||
ArrayList list = (ArrayList)_lobbies.get(category);
|
||||
if (list != null) {
|
||||
target.addAll(list);
|
||||
}
|
||||
listener.gotLobbies(target);
|
||||
}
|
||||
|
||||
/**
|
||||
* 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);
|
||||
|
||||
// if we don't already have a default lobby, this one is the big
|
||||
// winner
|
||||
if (_defLobbyOid == -1) {
|
||||
_defLobbyOid = placeOid;
|
||||
}
|
||||
|
||||
// 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 table containing references to all of our lobby records (in the
|
||||
* form of category lists. */
|
||||
protected HashMap _lobbies = new HashMap();
|
||||
|
||||
/** The oid of the default lobby. */
|
||||
protected int _defLobbyOid = -1;
|
||||
|
||||
/** The configuration key for the lobby managers list. */
|
||||
protected static final String LOBIDS_KEY = "lobby_ids";
|
||||
}
|
||||
@@ -0,0 +1,219 @@
|
||||
//
|
||||
// $Id: LobbySelector.java 4191 2006-06-13 22:42:20Z ray $
|
||||
//
|
||||
// Narya library - tools for developing networked games
|
||||
// Copyright (C) 2002-2004 Three Rings Design, Inc., All Rights Reserved
|
||||
// http://www.threerings.net/code/narya/
|
||||
//
|
||||
// This library is free software; you can redistribute it and/or modify it
|
||||
// under the terms of the GNU Lesser General Public License as published
|
||||
// by the Free Software Foundation; either version 2.1 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This library is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
// Lesser General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public
|
||||
// License along with this library; if not, write to the Free Software
|
||||
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
package com.threerings.micasa.lobby;
|
||||
|
||||
import java.awt.BorderLayout;
|
||||
import java.awt.Component;
|
||||
import java.awt.event.*;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
import javax.swing.*;
|
||||
|
||||
import com.threerings.crowd.data.PlaceObject;
|
||||
|
||||
import com.threerings.micasa.Log;
|
||||
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, LobbyService.CategoriesListener,
|
||||
LobbyService.LobbiesListener
|
||||
{
|
||||
/**
|
||||
* 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);
|
||||
}
|
||||
|
||||
// documentation inherited
|
||||
public void addNotify ()
|
||||
{
|
||||
super.addNotify();
|
||||
|
||||
// get a handle on our lobby service instance
|
||||
_lservice = (LobbyService)
|
||||
_ctx.getClient().requireService(LobbyService.class);
|
||||
// and use them to look up the lobby categories
|
||||
_lservice.getCategories(_ctx.getClient(), this);
|
||||
}
|
||||
|
||||
/**
|
||||
* 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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// documentation inherited from interface
|
||||
public void gotCategories (String[] categories)
|
||||
{
|
||||
// append these to our "unselected" item
|
||||
for (int i = 0; i < categories.length; i++) {
|
||||
_combo.addItem(categories[i]);
|
||||
}
|
||||
}
|
||||
|
||||
// documentation inherited from interface
|
||||
public void gotLobbies (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;
|
||||
}
|
||||
|
||||
// documentation inherited from interface
|
||||
public void requestFailed (String reason)
|
||||
{
|
||||
Log.info("Request failed [reason=" + reason + "].");
|
||||
|
||||
// clear out our pending category indicator in case this was a
|
||||
// failed getLobbies() request
|
||||
_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
|
||||
_lservice.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 LobbyService _lservice;
|
||||
|
||||
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,83 @@
|
||||
//
|
||||
// $Id: LobbyService.java 4145 2006-05-24 01:24:24Z ray $
|
||||
//
|
||||
// Narya library - tools for developing networked games
|
||||
// Copyright (C) 2002-2004 Three Rings Design, Inc., All Rights Reserved
|
||||
// http://www.threerings.net/code/narya/
|
||||
//
|
||||
// This library is free software; you can redistribute it and/or modify it
|
||||
// under the terms of the GNU Lesser General Public License as published
|
||||
// by the Free Software Foundation; either version 2.1 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This library is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
// Lesser General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public
|
||||
// License along with this library; if not, write to the Free Software
|
||||
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
package com.threerings.micasa.lobby;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import com.threerings.presents.client.Client;
|
||||
import com.threerings.presents.client.InvocationService;
|
||||
|
||||
/**
|
||||
* Provides an interface to the various parlor services that are directly
|
||||
* invokable by the client (by means of the invocation services).
|
||||
*/
|
||||
public interface LobbyService extends InvocationService
|
||||
{
|
||||
/**
|
||||
* Used to communicate the results of a {@link #getCategories}
|
||||
* request.
|
||||
*/
|
||||
public static interface CategoriesListener extends InvocationListener
|
||||
{
|
||||
/**
|
||||
* Supplies the listener with the results of a {@link
|
||||
* #getCategories} request.
|
||||
*/
|
||||
public void gotCategories (String[] categories);
|
||||
}
|
||||
|
||||
/**
|
||||
* Used to communicate the results of a {@link #getLobbies}
|
||||
* request.
|
||||
*/
|
||||
public static interface LobbiesListener extends InvocationListener
|
||||
{
|
||||
/**
|
||||
* Supplies the listener with the results of a {@link
|
||||
* #getLobbies} request.
|
||||
*/
|
||||
public void gotLobbies (List lobbies);
|
||||
}
|
||||
|
||||
/**
|
||||
* Requests the list of lobby cateogories that are available on this
|
||||
* server.
|
||||
*
|
||||
* @param client a connected, operational client instance.
|
||||
* @param listener the listener that will receive and process the
|
||||
* response.
|
||||
*/
|
||||
public void getCategories (Client client, CategoriesListener listener);
|
||||
|
||||
/**
|
||||
* 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 listener the listener that will receive and process the
|
||||
* response.
|
||||
*/
|
||||
public void getLobbies (Client client, String category,
|
||||
LobbiesListener listener);
|
||||
}
|
||||
@@ -0,0 +1,252 @@
|
||||
//
|
||||
// $Id: TableItem.java 3758 2005-11-10 23:18:58Z mdb $
|
||||
//
|
||||
// Narya library - tools for developing networked games
|
||||
// Copyright (C) 2002-2004 Three Rings Design, Inc., All Rights Reserved
|
||||
// http://www.threerings.net/code/narya/
|
||||
//
|
||||
// This library is free software; you can redistribute it and/or modify it
|
||||
// under the terms of the GNU Lesser General Public License as published
|
||||
// by the Free Software Foundation; either version 2.1 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This library is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
// Lesser General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public
|
||||
// License along with this library; if not, write to the Free Software
|
||||
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
package com.threerings.micasa.lobby.table;
|
||||
|
||||
import java.awt.Color;
|
||||
import java.awt.GridBagLayout;
|
||||
import java.awt.GridBagConstraints;
|
||||
import java.awt.Insets;
|
||||
|
||||
import java.awt.event.ActionEvent;
|
||||
import java.awt.event.ActionListener;
|
||||
|
||||
import javax.swing.BorderFactory;
|
||||
import javax.swing.JButton;
|
||||
import javax.swing.JLabel;
|
||||
import javax.swing.JPanel;
|
||||
|
||||
import com.threerings.util.Name;
|
||||
|
||||
import com.threerings.crowd.data.BodyObject;
|
||||
|
||||
import com.threerings.parlor.client.TableDirector;
|
||||
import com.threerings.parlor.client.SeatednessObserver;
|
||||
import com.threerings.parlor.data.Table;
|
||||
|
||||
import com.threerings.micasa.Log;
|
||||
import com.threerings.micasa.util.MiCasaContext;
|
||||
|
||||
/**
|
||||
* A table item displays the user interface for a single table (whether it
|
||||
* be in-play or still being matchmade).
|
||||
*/
|
||||
public class TableItem
|
||||
extends JPanel
|
||||
implements ActionListener, SeatednessObserver
|
||||
{
|
||||
/** A reference to the table we are displaying. */
|
||||
public Table table;
|
||||
|
||||
/**
|
||||
* Creates a new table item to display and interact with the supplied
|
||||
* table.
|
||||
*/
|
||||
public TableItem (MiCasaContext ctx, TableDirector tdtr, Table table)
|
||||
{
|
||||
// keep track of these
|
||||
_tdtr = tdtr;
|
||||
_ctx = ctx;
|
||||
|
||||
// add ourselves as a seatedness observer
|
||||
_tdtr.addSeatednessObserver(this);
|
||||
|
||||
// figure out who we are
|
||||
_self = ((BodyObject)ctx.getClient().getClientObject()).getVisibleName();
|
||||
|
||||
// now create our user interface
|
||||
setBorder(BorderFactory.createLineBorder(Color.black));
|
||||
setLayout(new GridBagLayout());
|
||||
GridBagConstraints gbc = new GridBagConstraints();
|
||||
|
||||
// create a label for the table
|
||||
JLabel tlabel = new JLabel("Table " + table.tableId);
|
||||
gbc.gridwidth = GridBagConstraints.REMAINDER;
|
||||
gbc.insets = new Insets(2, 0, 0, 0);
|
||||
add(tlabel, gbc);
|
||||
|
||||
// we have one button for every "seat" at the table
|
||||
int bcount = table.occupants.length;
|
||||
|
||||
// create blank buttons for now and then we'll update everything
|
||||
// with the current state when we're done
|
||||
gbc.weightx = 1.0;
|
||||
gbc.insets = new Insets(2, 0, 2, 0);
|
||||
_seats = new JButton[bcount];
|
||||
for (int i = 0; i < bcount; i++) {
|
||||
// create the button
|
||||
_seats[i] = new JButton(JOIN_LABEL);
|
||||
_seats[i].addActionListener(this);
|
||||
|
||||
// if we're on the left
|
||||
if (i % 2 == 0) {
|
||||
// if we're the last seat, then we've got an odd number
|
||||
// and need to center this final seat
|
||||
if (i == bcount-1) {
|
||||
gbc.gridwidth = GridBagConstraints.REMAINDER;
|
||||
} else {
|
||||
gbc.gridwidth = 1;
|
||||
}
|
||||
|
||||
} else {
|
||||
gbc.gridwidth = GridBagConstraints.REMAINDER;
|
||||
}
|
||||
|
||||
// adjust the insets of our last element
|
||||
if (i == bcount-1) {
|
||||
gbc.insets = new Insets(2, 0, 4, 0);
|
||||
}
|
||||
|
||||
// and add the button with the configured constraints
|
||||
add(_seats[i], gbc);
|
||||
|
||||
// if we just added the first button, add the "go" button
|
||||
// right after it
|
||||
if (i == 0) {
|
||||
_goButton = new JButton("Go");
|
||||
_goButton.setActionCommand("go");
|
||||
_goButton.addActionListener(this);
|
||||
add(_goButton, gbc);
|
||||
}
|
||||
}
|
||||
|
||||
// and update ourselves based on the contents of the occupants
|
||||
// list
|
||||
tableUpdated(table);
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when our table has been updated and we need to update the UI
|
||||
* to reflect the new information.
|
||||
*/
|
||||
public void tableUpdated (Table table)
|
||||
{
|
||||
// grab this new table reference
|
||||
this.table = table;
|
||||
|
||||
// first look to see if we're already sitting at a table
|
||||
boolean isSeated = _tdtr.isSeated();
|
||||
|
||||
// now enable and label the buttons accordingly
|
||||
int slength = _seats.length;
|
||||
for (int i = 0; i < slength; i++) {
|
||||
if (table.occupants[i] == null) {
|
||||
_seats[i].setText(JOIN_LABEL);
|
||||
_seats[i].setEnabled(!isSeated);
|
||||
_seats[i].setActionCommand("join");
|
||||
|
||||
} else if (table.occupants[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].setEnabled(false);
|
||||
}
|
||||
}
|
||||
|
||||
// show or hide our "go" button appropriately
|
||||
_goButton.setVisible(table.gameOid != -1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Called by the table list view prior to removing us. Here we clean
|
||||
* up.
|
||||
*/
|
||||
public void tableRemoved ()
|
||||
{
|
||||
// no more observy
|
||||
_tdtr.removeSeatednessObserver(this);
|
||||
}
|
||||
|
||||
// documentation inherited
|
||||
public void actionPerformed (ActionEvent event)
|
||||
{
|
||||
String cmd = event.getActionCommand();
|
||||
if (cmd.equals("join")) {
|
||||
// figure out what position this button is in
|
||||
int position = -1;
|
||||
for (int i = 0; i < _seats.length; i++) {
|
||||
if (_seats[i] == event.getSource()) {
|
||||
position = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// sanity check
|
||||
if (position == -1) {
|
||||
Log.warning("Unable to figure out what position a <join> " +
|
||||
"click came from [event=" + event + "].");
|
||||
} else {
|
||||
// otherwise, request to join the table at this position
|
||||
_tdtr.joinTable(table.getTableId(), position);
|
||||
}
|
||||
|
||||
} else if (cmd.equals("leave")) {
|
||||
// if we're not joining, we're leaving
|
||||
_tdtr.leaveTable(table.getTableId());
|
||||
|
||||
} else if (cmd.equals("go")) {
|
||||
// they want to see the game... so go there
|
||||
_ctx.getLocationDirector().moveTo(table.gameOid);
|
||||
|
||||
} else {
|
||||
Log.warning("Received unknown action [event=" + event + "].");
|
||||
}
|
||||
}
|
||||
|
||||
// documentation inherited
|
||||
public void seatednessDidChange (boolean isSeated)
|
||||
{
|
||||
// just update ourselves
|
||||
tableUpdated(table);
|
||||
|
||||
// enable or disable the go button based on our seatedness
|
||||
if (_goButton.isVisible()) {
|
||||
_goButton.setEnabled(!isSeated);
|
||||
}
|
||||
}
|
||||
|
||||
/** A reference to our context. */
|
||||
protected MiCasaContext _ctx;
|
||||
|
||||
/** Our username. */
|
||||
protected Name _self;
|
||||
|
||||
/** A reference to our table director. */
|
||||
protected TableDirector _tdtr;
|
||||
|
||||
/** We have a button for each "seat" at the table. */
|
||||
protected JButton[] _seats;
|
||||
|
||||
/** We have a button for going to games that are already in
|
||||
* progress. */
|
||||
protected JButton _goButton;
|
||||
|
||||
/** The text shown for seats at which the user can join. */
|
||||
protected static final String JOIN_LABEL = "<join>";
|
||||
|
||||
/** The text shown for the seat in which this user occupies and which
|
||||
* lets her/him know that they can leave that seat by clicking. */
|
||||
protected static final String LEAVE_LABEL = "<leave>";
|
||||
}
|
||||
@@ -0,0 +1,305 @@
|
||||
//
|
||||
// $Id: TableListView.java 3593 2005-06-10 18:10:49Z ray $
|
||||
//
|
||||
// Narya library - tools for developing networked games
|
||||
// Copyright (C) 2002-2004 Three Rings Design, Inc., All Rights Reserved
|
||||
// http://www.threerings.net/code/narya/
|
||||
//
|
||||
// This library is free software; you can redistribute it and/or modify it
|
||||
// under the terms of the GNU Lesser General Public License as published
|
||||
// by the Free Software Foundation; either version 2.1 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This library is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
// Lesser General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public
|
||||
// License along with this library; if not, write to the Free Software
|
||||
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
package com.threerings.micasa.lobby.table;
|
||||
|
||||
import java.awt.Component;
|
||||
import java.awt.event.ActionEvent;
|
||||
import java.awt.event.ActionListener;
|
||||
import java.util.Iterator;
|
||||
|
||||
import javax.swing.BorderFactory;
|
||||
import javax.swing.JButton;
|
||||
import javax.swing.JLabel;
|
||||
import javax.swing.JPanel;
|
||||
import javax.swing.JScrollPane;
|
||||
|
||||
import com.samskivert.swing.HGroupLayout;
|
||||
import com.samskivert.swing.VGroupLayout;
|
||||
import com.samskivert.swing.util.SwingUtil;
|
||||
|
||||
import com.threerings.micasa.Log;
|
||||
import com.threerings.micasa.lobby.LobbyConfig;
|
||||
import com.threerings.micasa.util.MiCasaContext;
|
||||
|
||||
import com.threerings.parlor.client.SeatednessObserver;
|
||||
import com.threerings.parlor.client.TableConfigurator;
|
||||
import com.threerings.parlor.client.TableDirector;
|
||||
import com.threerings.parlor.client.TableObserver;
|
||||
import com.threerings.parlor.data.Table;
|
||||
import com.threerings.parlor.game.client.GameConfigurator;
|
||||
import com.threerings.parlor.game.client.SwingGameConfigurator;
|
||||
import com.threerings.parlor.game.data.GameConfig;
|
||||
|
||||
import com.threerings.crowd.client.PlaceView;
|
||||
import com.threerings.crowd.data.PlaceObject;
|
||||
|
||||
/**
|
||||
* A view that displays the tables in a table lobby. It displays two
|
||||
* separate lists, one of tables being matchmade and another of games in
|
||||
* progress. These tables are updated dynamically as they proceed through
|
||||
* the matchmaking process. UI mechanisms for creating and joining tables
|
||||
* are also provided.
|
||||
*/
|
||||
public class TableListView extends JPanel
|
||||
implements PlaceView, TableObserver, ActionListener, SeatednessObserver
|
||||
{
|
||||
/**
|
||||
* Creates a new table list view, suitable for providing the user
|
||||
* interface for table-style matchmaking in a table lobby.
|
||||
*/
|
||||
public TableListView (MiCasaContext ctx, LobbyConfig config)
|
||||
{
|
||||
// keep track of these
|
||||
_config = config;
|
||||
_ctx = ctx;
|
||||
|
||||
// create our table director
|
||||
_tdtr = new TableDirector(ctx, TableLobbyObject.TABLE_SET, this);
|
||||
|
||||
// add ourselves as a seatedness observer
|
||||
_tdtr.addSeatednessObserver(this);
|
||||
|
||||
// set up a layout manager
|
||||
HGroupLayout gl = new HGroupLayout(HGroupLayout.STRETCH);
|
||||
gl.setOffAxisPolicy(HGroupLayout.STRETCH);
|
||||
setLayout(gl);
|
||||
|
||||
// we have two lists of tables, one of tables being matchmade...
|
||||
VGroupLayout pgl = new VGroupLayout(VGroupLayout.STRETCH);
|
||||
pgl.setOffAxisPolicy(VGroupLayout.STRETCH);
|
||||
JPanel panel = new JPanel(pgl);
|
||||
panel.add(new JLabel("Pending tables"), VGroupLayout.FIXED);
|
||||
|
||||
VGroupLayout mgl = new VGroupLayout(VGroupLayout.NONE);
|
||||
mgl.setOffAxisPolicy(VGroupLayout.STRETCH);
|
||||
mgl.setJustification(VGroupLayout.TOP);
|
||||
_matchList = new JPanel(mgl);
|
||||
_matchList.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));
|
||||
panel.add(new JScrollPane(_matchList));
|
||||
|
||||
// create and initialize the configurator interface
|
||||
GameConfig gconfig = null;
|
||||
try {
|
||||
gconfig = config.getGameConfig();
|
||||
|
||||
_tableFigger = gconfig.createTableConfigurator();
|
||||
if (_tableFigger == null) {
|
||||
Log.warning("Game config has not been set up to work with " +
|
||||
"tables: it needs to return non-null from " +
|
||||
"createTableConfigurator().");
|
||||
// let's just wait until we throw an NPE below
|
||||
}
|
||||
|
||||
_figger = gconfig.createConfigurator();
|
||||
_tableFigger.init(_ctx, _figger);
|
||||
if (_figger != null) {
|
||||
_figger.init(_ctx);
|
||||
_figger.setGameConfig(gconfig);
|
||||
panel.add(((SwingGameConfigurator) _figger).getPanel(),
|
||||
VGroupLayout.FIXED);
|
||||
}
|
||||
|
||||
_create = new JButton("Create table");
|
||||
_create.addActionListener(this);
|
||||
panel.add(_create, VGroupLayout.FIXED);
|
||||
|
||||
} catch (Exception e) {
|
||||
Log.warning("Unable to create configurator interface " +
|
||||
"[config=" + gconfig + "].");
|
||||
Log.logStackTrace(e);
|
||||
|
||||
// stick something in the UI to let them know we're hosed
|
||||
panel.add(new JLabel("Aiya! Can't create tables. " +
|
||||
"Configuration borked."), VGroupLayout.FIXED);
|
||||
}
|
||||
|
||||
add(panel);
|
||||
|
||||
// ...and one of games in progress
|
||||
panel = new JPanel(pgl);
|
||||
panel.add(new JLabel("Games in progress"), VGroupLayout.FIXED);
|
||||
|
||||
_playList = new JPanel(mgl);
|
||||
_playList.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));
|
||||
panel.add(new JScrollPane(_playList));
|
||||
|
||||
add(panel);
|
||||
}
|
||||
|
||||
// documentation inherited
|
||||
public void willEnterPlace (PlaceObject place)
|
||||
{
|
||||
// pass the good word on to our table director
|
||||
_tdtr.willEnterPlace(place);
|
||||
|
||||
// iterate over the tables already active in this lobby and put
|
||||
// them in their respective lists
|
||||
TableLobbyObject tlobj = (TableLobbyObject)place;
|
||||
Iterator iter = tlobj.tableSet.iterator();
|
||||
while (iter.hasNext()) {
|
||||
tableAdded((Table)iter.next());
|
||||
}
|
||||
}
|
||||
|
||||
// documentation inherited
|
||||
public void didLeavePlace (PlaceObject place)
|
||||
{
|
||||
// pass the good word on to our table director
|
||||
_tdtr.didLeavePlace(place);
|
||||
|
||||
// clear out our table lists
|
||||
_matchList.removeAll();
|
||||
_playList.removeAll();
|
||||
}
|
||||
|
||||
// documentation inherited
|
||||
public void tableAdded (Table table)
|
||||
{
|
||||
Log.info("Table added [table=" + table + "].");
|
||||
|
||||
// create a table item for this table and insert it into the
|
||||
// appropriate list
|
||||
JPanel panel = table.inPlay() ? _playList : _matchList;
|
||||
panel.add(new TableItem(_ctx, _tdtr, table));
|
||||
SwingUtil.refresh(panel);
|
||||
}
|
||||
|
||||
// documentation inherited
|
||||
public void tableUpdated (Table table)
|
||||
{
|
||||
Log.info("Table updated [table=" + table + "].");
|
||||
|
||||
// locate the table item associated with this table
|
||||
TableItem item = getTableItem(table.getTableId());
|
||||
if (item == null) {
|
||||
Log.warning("Received table updated notification for " +
|
||||
"unknown table [table=" + table + "].");
|
||||
return;
|
||||
}
|
||||
|
||||
// let the item perform any updates it finds necessary
|
||||
item.tableUpdated(table);
|
||||
|
||||
// and we may need to move the item from the match to the in-play
|
||||
// list if it just transitioned
|
||||
if (table.gameOid != -1 && item.getParent() == _matchList) {
|
||||
_matchList.remove(item);
|
||||
SwingUtil.refresh(_matchList);
|
||||
_playList.add(item);
|
||||
SwingUtil.refresh(_playList);
|
||||
}
|
||||
}
|
||||
|
||||
// documentation inherited
|
||||
public void tableRemoved (int tableId)
|
||||
{
|
||||
Log.info("Table removed [tableId=" + tableId + "].");
|
||||
|
||||
// locate the table item associated with this table
|
||||
TableItem item = getTableItem(tableId);
|
||||
if (item == null) {
|
||||
Log.warning("Received table removed notification for " +
|
||||
"unknown table [tableId=" + tableId + "].");
|
||||
return;
|
||||
}
|
||||
|
||||
// remove this item from the user interface
|
||||
JPanel panel = (JPanel)item.getParent();
|
||||
panel.remove(item);
|
||||
SwingUtil.refresh(panel);
|
||||
|
||||
// let the little fellow know that we gave him the boot
|
||||
item.tableRemoved();
|
||||
}
|
||||
|
||||
// documentation inherited
|
||||
public void actionPerformed (ActionEvent event)
|
||||
{
|
||||
// the create table button was clicked. use the game config as
|
||||
// configured by the configurator to create a table
|
||||
_tdtr.createTable(_tableFigger.getTableConfig(),
|
||||
_figger.getGameConfig());
|
||||
}
|
||||
|
||||
// documentation inherited
|
||||
public void seatednessDidChange (boolean isSeated)
|
||||
{
|
||||
// update the create table button
|
||||
_create.setEnabled(!isSeated);
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetches the table item component associated with the specified
|
||||
* table id.
|
||||
*/
|
||||
protected TableItem getTableItem (int tableId)
|
||||
{
|
||||
// first check the match list
|
||||
int ccount = _matchList.getComponentCount();
|
||||
for (int i = 0; i < ccount; i++) {
|
||||
TableItem child = (TableItem)_matchList.getComponent(i);
|
||||
if (child.table.getTableId() == tableId) {
|
||||
return child;
|
||||
}
|
||||
}
|
||||
|
||||
// then the inplay list
|
||||
ccount = _playList.getComponentCount();
|
||||
for (int i = 0; i < ccount; i++) {
|
||||
TableItem child = (TableItem)_playList.getComponent(i);
|
||||
if (child.table.getTableId() == tableId) {
|
||||
return child;
|
||||
}
|
||||
}
|
||||
|
||||
// sorry charlie
|
||||
return null;
|
||||
}
|
||||
|
||||
/** A reference to the client context. */
|
||||
protected MiCasaContext _ctx;
|
||||
|
||||
/** A reference to the lobby config for the lobby in which we are
|
||||
* doing table-style matchmaking. */
|
||||
protected LobbyConfig _config;
|
||||
|
||||
/** A reference to our table director. */
|
||||
protected TableDirector _tdtr;
|
||||
|
||||
/** The list of tables currently being matchmade. */
|
||||
protected JPanel _matchList;
|
||||
|
||||
/** The list of tables that are in play. */
|
||||
protected JPanel _playList;
|
||||
|
||||
/** The interface used to configure the table for a game. */
|
||||
protected TableConfigurator _tableFigger;
|
||||
|
||||
/** The interface used to configure a game before creating it. */
|
||||
protected GameConfigurator _figger;
|
||||
|
||||
/** Our create table button. */
|
||||
protected JButton _create;
|
||||
|
||||
/** Our number of players indicator. */
|
||||
protected JLabel _pcount;
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
//
|
||||
// $Id: TableLobbyConfig.java 4191 2006-06-13 22:42:20Z ray $
|
||||
//
|
||||
// Narya library - tools for developing networked games
|
||||
// Copyright (C) 2002-2004 Three Rings Design, Inc., All Rights Reserved
|
||||
// http://www.threerings.net/code/narya/
|
||||
//
|
||||
// This library is free software; you can redistribute it and/or modify it
|
||||
// under the terms of the GNU Lesser General Public License as published
|
||||
// by the Free Software Foundation; either version 2.1 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This library is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
// Lesser General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public
|
||||
// License along with this library; if not, write to the Free Software
|
||||
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
package com.threerings.micasa.lobby.table;
|
||||
|
||||
import javax.swing.JComponent;
|
||||
import com.threerings.micasa.lobby.LobbyConfig;
|
||||
import com.threerings.micasa.util.MiCasaContext;
|
||||
|
||||
/**
|
||||
* Instructs the lobby services to use a {@link TableListView} as the
|
||||
* matchmaking component.
|
||||
*/
|
||||
public class TableLobbyConfig extends LobbyConfig
|
||||
{
|
||||
// documentation inherited
|
||||
public String getManagerClassName ()
|
||||
{
|
||||
return "com.threerings.micasa.lobby.table.TableLobbyManager";
|
||||
}
|
||||
|
||||
// documentation inherited
|
||||
public JComponent createMatchMakingView (MiCasaContext ctx)
|
||||
{
|
||||
return new TableListView(ctx, this);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,59 @@
|
||||
//
|
||||
// $Id: TableLobbyManager.java 4191 2006-06-13 22:42:20Z ray $
|
||||
//
|
||||
// Narya library - tools for developing networked games
|
||||
// Copyright (C) 2002-2004 Three Rings Design, Inc., All Rights Reserved
|
||||
// http://www.threerings.net/code/narya/
|
||||
//
|
||||
// This library is free software; you can redistribute it and/or modify it
|
||||
// under the terms of the GNU Lesser General Public License as published
|
||||
// by the Free Software Foundation; either version 2.1 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This library is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
// Lesser General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public
|
||||
// License along with this library; if not, write to the Free Software
|
||||
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
package com.threerings.micasa.lobby.table;
|
||||
|
||||
import com.threerings.parlor.server.TableManager;
|
||||
import com.threerings.parlor.server.TableManagerProvider;
|
||||
import com.threerings.micasa.lobby.LobbyManager;
|
||||
|
||||
/**
|
||||
* Extends lobby manager only to ensure that a table lobby object is used
|
||||
* for table lobbies.
|
||||
*/
|
||||
public class TableLobbyManager
|
||||
extends LobbyManager implements TableManagerProvider
|
||||
{
|
||||
// documentation inherited
|
||||
protected void didStartup ()
|
||||
{
|
||||
super.didStartup();
|
||||
|
||||
// now that we have our place object, we can create our table
|
||||
// manager
|
||||
_tmgr = new TableManager(this);
|
||||
}
|
||||
|
||||
// documentation inherited
|
||||
protected Class getPlaceObjectClass ()
|
||||
{
|
||||
return TableLobbyObject.class;
|
||||
}
|
||||
|
||||
// documentation inherited
|
||||
public TableManager getTableManager ()
|
||||
{
|
||||
return _tmgr;
|
||||
}
|
||||
|
||||
/** A reference to our table manager. */
|
||||
protected TableManager _tmgr;
|
||||
}
|
||||
@@ -0,0 +1,111 @@
|
||||
//
|
||||
// $Id: TableLobbyObject.java 4166 2006-05-31 04:16:57Z mdb $
|
||||
//
|
||||
// Narya library - tools for developing networked games
|
||||
// Copyright (C) 2002-2004 Three Rings Design, Inc., All Rights Reserved
|
||||
// http://www.threerings.net/code/narya/
|
||||
//
|
||||
// This library is free software; you can redistribute it and/or modify it
|
||||
// under the terms of the GNU Lesser General Public License as published
|
||||
// by the Free Software Foundation; either version 2.1 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This library is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
// Lesser General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public
|
||||
// License along with this library; if not, write to the Free Software
|
||||
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
package com.threerings.micasa.lobby.table;
|
||||
|
||||
import com.threerings.presents.dobj.DSet;
|
||||
import com.threerings.parlor.data.Table;
|
||||
import com.threerings.micasa.lobby.LobbyObject;
|
||||
|
||||
public class TableLobbyObject
|
||||
extends LobbyObject
|
||||
implements com.threerings.parlor.data.TableLobbyObject
|
||||
{
|
||||
// AUTO-GENERATED: FIELDS START
|
||||
/** The field name of the <code>tableSet</code> field. */
|
||||
public static final String TABLE_SET = "tableSet";
|
||||
// AUTO-GENERATED: FIELDS END
|
||||
|
||||
/** A set containing all of the tables being managed by this lobby. */
|
||||
public DSet tableSet = new DSet();
|
||||
|
||||
// documentation inherited
|
||||
public DSet getTables ()
|
||||
{
|
||||
return tableSet;
|
||||
}
|
||||
|
||||
// documentation inherited from interface
|
||||
public void addToTables (Table table)
|
||||
{
|
||||
addToTableSet(table);
|
||||
}
|
||||
|
||||
// documentation inherited from interface
|
||||
public void updateTables (Table table)
|
||||
{
|
||||
updateTableSet(table);
|
||||
}
|
||||
|
||||
// documentation inherited from interface
|
||||
public void removeFromTables (Comparable key)
|
||||
{
|
||||
removeFromTableSet(key);
|
||||
}
|
||||
|
||||
// AUTO-GENERATED: METHODS START
|
||||
/**
|
||||
* Requests that the specified entry be added to the
|
||||
* <code>tableSet</code> set. The set will not change until the event is
|
||||
* actually propagated through the system.
|
||||
*/
|
||||
public void addToTableSet (DSet.Entry elem)
|
||||
{
|
||||
requestEntryAdd(TABLE_SET, tableSet, elem);
|
||||
}
|
||||
|
||||
/**
|
||||
* Requests that the entry matching the supplied key be removed from
|
||||
* the <code>tableSet</code> set. The set will not change until the
|
||||
* event is actually propagated through the system.
|
||||
*/
|
||||
public void removeFromTableSet (Comparable key)
|
||||
{
|
||||
requestEntryRemove(TABLE_SET, tableSet, key);
|
||||
}
|
||||
|
||||
/**
|
||||
* Requests that the specified entry be updated in the
|
||||
* <code>tableSet</code> set. The set will not change until the event is
|
||||
* actually propagated through the system.
|
||||
*/
|
||||
public void updateTableSet (DSet.Entry elem)
|
||||
{
|
||||
requestEntryUpdate(TABLE_SET, tableSet, elem);
|
||||
}
|
||||
|
||||
/**
|
||||
* Requests that the <code>tableSet</code> field be set to the
|
||||
* specified value. Generally one only adds, updates and removes
|
||||
* entries of a distributed set, but certain situations call for a
|
||||
* complete replacement of the set value. The local value will be
|
||||
* updated immediately and an event will be propagated through the
|
||||
* system to notify all listeners that the attribute did
|
||||
* change. Proxied copies of this object (on clients) will apply the
|
||||
* value change when they received the attribute changed notification.
|
||||
*/
|
||||
public void setTableSet (DSet value)
|
||||
{
|
||||
requestAttributeChange(TABLE_SET, value, this.tableSet);
|
||||
this.tableSet = (value == null) ? null : value.typedClone();
|
||||
}
|
||||
// AUTO-GENERATED: METHODS END
|
||||
}
|
||||
@@ -0,0 +1,50 @@
|
||||
//
|
||||
// $Id: MiCasaClient.java 4191 2006-06-13 22:42:20Z ray $
|
||||
//
|
||||
// Narya library - tools for developing networked games
|
||||
// Copyright (C) 2002-2004 Three Rings Design, Inc., All Rights Reserved
|
||||
// http://www.threerings.net/code/narya/
|
||||
//
|
||||
// This library is free software; you can redistribute it and/or modify it
|
||||
// under the terms of the GNU Lesser General Public License as published
|
||||
// by the Free Software Foundation; either version 2.1 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This library is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
// Lesser General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public
|
||||
// License along with this library; if not, write to the Free Software
|
||||
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
package com.threerings.micasa.server;
|
||||
|
||||
import com.threerings.presents.net.BootstrapData;
|
||||
import com.threerings.crowd.server.CrowdClient;
|
||||
|
||||
import com.threerings.micasa.data.MiCasaBootstrapData;
|
||||
|
||||
/**
|
||||
* Extends the Crowd client and provides bootstrap data specific to the
|
||||
* MiCasa services.
|
||||
*/
|
||||
public class MiCasaClient extends CrowdClient
|
||||
{
|
||||
// documentation inherited
|
||||
protected BootstrapData createBootstrapData ()
|
||||
{
|
||||
return new MiCasaBootstrapData();
|
||||
}
|
||||
|
||||
// documentation inherited
|
||||
protected void populateBootstrapData (BootstrapData data)
|
||||
{
|
||||
super.populateBootstrapData(data);
|
||||
|
||||
// let the client know their default lobby oid
|
||||
((MiCasaBootstrapData)data).defLobbyOid =
|
||||
MiCasaServer.lobreg.getDefaultLobbyOid();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
//
|
||||
// $Id: MiCasaConfig.java 4191 2006-06-13 22:42:20Z ray $
|
||||
//
|
||||
// Narya library - tools for developing networked games
|
||||
// Copyright (C) 2002-2004 Three Rings Design, Inc., All Rights Reserved
|
||||
// http://www.threerings.net/code/narya/
|
||||
//
|
||||
// This library is free software; you can redistribute it and/or modify it
|
||||
// under the terms of the GNU Lesser General Public License as published
|
||||
// by the Free Software Foundation; either version 2.1 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This library is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
// Lesser General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public
|
||||
// License along with this library; if not, write to the Free Software
|
||||
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
package com.threerings.micasa.server;
|
||||
|
||||
import com.samskivert.util.Config;
|
||||
|
||||
/**
|
||||
* Provides access to the MiCasa server configuration.
|
||||
*/
|
||||
public class MiCasaConfig
|
||||
{
|
||||
/** Provides access to configuration data for this package. */
|
||||
public static Config config = new Config("rsrc/config/micasa/server");
|
||||
}
|
||||
@@ -0,0 +1,74 @@
|
||||
//
|
||||
// $Id: MiCasaServer.java 4158 2006-05-30 22:12:15Z mdb $
|
||||
//
|
||||
// Narya library - tools for developing networked games
|
||||
// Copyright (C) 2002-2004 Three Rings Design, Inc., All Rights Reserved
|
||||
// http://www.threerings.net/code/narya/
|
||||
//
|
||||
// This library is free software; you can redistribute it and/or modify it
|
||||
// under the terms of the GNU Lesser General Public License as published
|
||||
// by the Free Software Foundation; either version 2.1 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This library is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
// Lesser General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public
|
||||
// License along with this library; if not, write to the Free Software
|
||||
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
package com.threerings.micasa.server;
|
||||
|
||||
import com.threerings.crowd.server.CrowdServer;
|
||||
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
|
||||
* that goes on in the MiCasa game server process.
|
||||
*/
|
||||
public class MiCasaServer extends CrowdServer
|
||||
{
|
||||
/** 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.
|
||||
*/
|
||||
public void init ()
|
||||
throws Exception
|
||||
{
|
||||
// do the base server initialization
|
||||
super.init();
|
||||
|
||||
// configure the client manager to use our client class
|
||||
clmgr.setClientClass(MiCasaClient.class);
|
||||
|
||||
// initialize our parlor manager
|
||||
parmgr.init(invmgr, plreg);
|
||||
|
||||
// initialize the lobby registry
|
||||
lobreg.init(invmgr);
|
||||
|
||||
Log.info("MiCasa server initialized.");
|
||||
}
|
||||
|
||||
public static void main (String[] args)
|
||||
{
|
||||
MiCasaServer server = new MiCasaServer();
|
||||
try {
|
||||
server.init();
|
||||
server.run();
|
||||
} catch (Exception e) {
|
||||
Log.warning("Unable to initialize server.");
|
||||
Log.logStackTrace(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,197 @@
|
||||
//
|
||||
// $Id: SimpleClient.java 3283 2004-12-22 19:23:00Z ray $
|
||||
//
|
||||
// Narya library - tools for developing networked games
|
||||
// Copyright (C) 2002-2004 Three Rings Design, Inc., All Rights Reserved
|
||||
// http://www.threerings.net/code/narya/
|
||||
//
|
||||
// This library is free software; you can redistribute it and/or modify it
|
||||
// under the terms of the GNU Lesser General Public License as published
|
||||
// by the Free Software Foundation; either version 2.1 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This library is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
// Lesser General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public
|
||||
// License along with this library; if not, write to the Free Software
|
||||
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
package com.threerings.micasa.simulator.client;
|
||||
|
||||
import java.awt.EventQueue;
|
||||
import java.awt.event.WindowAdapter;
|
||||
import java.awt.event.WindowEvent;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import javax.swing.JPanel;
|
||||
|
||||
import com.samskivert.util.Config;
|
||||
import com.samskivert.util.RunQueue;
|
||||
import com.threerings.util.MessageManager;
|
||||
|
||||
import com.threerings.presents.client.Client;
|
||||
import com.threerings.presents.dobj.DObjectManager;
|
||||
|
||||
import com.threerings.crowd.client.LocationDirector;
|
||||
import com.threerings.crowd.client.OccupantDirector;
|
||||
import com.threerings.crowd.client.PlaceView;
|
||||
|
||||
import com.threerings.crowd.chat.client.ChatDirector;
|
||||
|
||||
import com.threerings.parlor.client.ParlorDirector;
|
||||
import com.threerings.parlor.util.ParlorContext;
|
||||
|
||||
import com.threerings.micasa.client.MiCasaFrame;
|
||||
import com.threerings.micasa.util.MiCasaContext;
|
||||
|
||||
public class SimpleClient
|
||||
implements RunQueue, SimulatorClient
|
||||
{
|
||||
public SimpleClient (SimulatorFrame frame)
|
||||
throws IOException
|
||||
{
|
||||
// create our context
|
||||
_ctx = createContext();
|
||||
|
||||
// create the handles on our various services
|
||||
_client = new Client(null, this);
|
||||
|
||||
// create our managers and directors
|
||||
_msgmgr = new MessageManager(getMessageManagerPrefix());
|
||||
_locdir = new LocationDirector(_ctx);
|
||||
_occdir = new OccupantDirector(_ctx);
|
||||
_pardtr = new ParlorDirector(_ctx);
|
||||
_chatdir = new ChatDirector(_ctx, _msgmgr, null);
|
||||
|
||||
// keep this for later
|
||||
_frame = frame;
|
||||
|
||||
// log off when they close the window
|
||||
_frame.getFrame().addWindowListener(new WindowAdapter() {
|
||||
public void windowClosing (WindowEvent evt) {
|
||||
// if we're logged on, log off
|
||||
if (_client.isLoggedOn()) {
|
||||
_client.logoff(true);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates our context reference.
|
||||
*/
|
||||
protected MiCasaContext createContext ()
|
||||
{
|
||||
return new MiCasaContextImpl();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the prefix used by the message manager when looking for
|
||||
* translation properties files.
|
||||
*/
|
||||
protected String getMessageManagerPrefix ()
|
||||
{
|
||||
return "rsrc";
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a reference to the context in effect for this client. This
|
||||
* reference is valid for the lifetime of the application.
|
||||
*/
|
||||
public ParlorContext getParlorContext ()
|
||||
{
|
||||
return _ctx;
|
||||
}
|
||||
|
||||
// documentation inherited from interface RunQueue
|
||||
public void postRunnable (Runnable run)
|
||||
{
|
||||
// queue it on up on the awt thread
|
||||
EventQueue.invokeLater(run);
|
||||
}
|
||||
|
||||
// documentation inherited from interface RunQueue
|
||||
public boolean isDispatchThread ()
|
||||
{
|
||||
return EventQueue.isDispatchThread();
|
||||
}
|
||||
|
||||
/**
|
||||
* The context implementation. This provides access to all of the
|
||||
* objects and services that are needed by the operating client.
|
||||
*/
|
||||
protected class MiCasaContextImpl implements MiCasaContext
|
||||
{
|
||||
public Config getConfig ()
|
||||
{
|
||||
return _config;
|
||||
}
|
||||
|
||||
public Client getClient ()
|
||||
{
|
||||
return _client;
|
||||
}
|
||||
|
||||
public DObjectManager getDObjectManager ()
|
||||
{
|
||||
return _client.getDObjectManager();
|
||||
}
|
||||
|
||||
public LocationDirector getLocationDirector ()
|
||||
{
|
||||
return _locdir;
|
||||
}
|
||||
|
||||
public OccupantDirector getOccupantDirector ()
|
||||
{
|
||||
return _occdir;
|
||||
}
|
||||
|
||||
public ParlorDirector getParlorDirector ()
|
||||
{
|
||||
return _pardtr;
|
||||
}
|
||||
|
||||
public ChatDirector getChatDirector ()
|
||||
{
|
||||
return _chatdir;
|
||||
}
|
||||
|
||||
public void setPlaceView (PlaceView view)
|
||||
{
|
||||
// stick the place view into our frame
|
||||
_frame.setPanel((JPanel)view);
|
||||
}
|
||||
|
||||
public void clearPlaceView (PlaceView view)
|
||||
{
|
||||
// we'll just let the next view replace the old one
|
||||
}
|
||||
|
||||
public MiCasaFrame getFrame ()
|
||||
{
|
||||
return (MiCasaFrame)_frame;
|
||||
}
|
||||
|
||||
public MessageManager getMessageManager ()
|
||||
{
|
||||
return _msgmgr;
|
||||
}
|
||||
}
|
||||
|
||||
protected MiCasaContext _ctx;
|
||||
protected SimulatorFrame _frame;
|
||||
protected MessageManager _msgmgr;
|
||||
|
||||
protected Config _config = new Config("micasa");
|
||||
protected Client _client;
|
||||
protected LocationDirector _locdir;
|
||||
protected OccupantDirector _occdir;
|
||||
protected ParlorDirector _pardtr;
|
||||
protected ChatDirector _chatdir;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,51 @@
|
||||
//
|
||||
// $Id: SimpleFrame.java 4191 2006-06-13 22:42:20Z ray $
|
||||
//
|
||||
// Narya library - tools for developing networked games
|
||||
// Copyright (C) 2002-2004 Three Rings Design, Inc., All Rights Reserved
|
||||
// http://www.threerings.net/code/narya/
|
||||
//
|
||||
// This library is free software; you can redistribute it and/or modify it
|
||||
// under the terms of the GNU Lesser General Public License as published
|
||||
// by the Free Software Foundation; either version 2.1 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This library is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
// Lesser General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public
|
||||
// License along with this library; if not, write to the Free Software
|
||||
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
package com.threerings.micasa.simulator.client;
|
||||
|
||||
import javax.swing.JFrame;
|
||||
|
||||
import com.samskivert.swing.Controller;
|
||||
|
||||
import com.threerings.micasa.client.MiCasaFrame;
|
||||
|
||||
/**
|
||||
* Contains the user interface for the Simulator client application.
|
||||
*/
|
||||
public class SimpleFrame extends MiCasaFrame
|
||||
implements SimulatorFrame
|
||||
{
|
||||
/**
|
||||
* Constructs the top-level Simulator client frame.
|
||||
*/
|
||||
public SimpleFrame ()
|
||||
{
|
||||
super("Simulator");
|
||||
}
|
||||
|
||||
// documentation inherited
|
||||
public JFrame getFrame ()
|
||||
{
|
||||
return this;
|
||||
}
|
||||
|
||||
protected Controller _controller;
|
||||
}
|
||||
@@ -0,0 +1,227 @@
|
||||
//
|
||||
// $Id: SimulatorApp.java 4158 2006-05-30 22:12:15Z mdb $
|
||||
//
|
||||
// Narya library - tools for developing networked games
|
||||
// Copyright (C) 2002-2004 Three Rings Design, Inc., All Rights Reserved
|
||||
// http://www.threerings.net/code/narya/
|
||||
//
|
||||
// This library is free software; you can redistribute it and/or modify it
|
||||
// under the terms of the GNU Lesser General Public License as published
|
||||
// by the Free Software Foundation; either version 2.1 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This library is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
// Lesser General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public
|
||||
// License along with this library; if not, write to the Free Software
|
||||
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
package com.threerings.micasa.simulator.client;
|
||||
|
||||
import javax.swing.JFrame;
|
||||
|
||||
import com.samskivert.swing.Controller;
|
||||
import com.samskivert.swing.util.SwingUtil;
|
||||
import com.samskivert.util.Interval;
|
||||
import com.samskivert.util.ResultListener;
|
||||
|
||||
import com.threerings.util.Name;
|
||||
|
||||
import com.threerings.presents.client.Client;
|
||||
import com.threerings.presents.client.ClientAdapter;
|
||||
import com.threerings.presents.net.UsernamePasswordCreds;
|
||||
|
||||
import com.threerings.micasa.Log;
|
||||
import com.threerings.micasa.simulator.data.SimulatorInfo;
|
||||
import com.threerings.micasa.simulator.server.SimpleServer;
|
||||
import com.threerings.micasa.simulator.server.SimulatorServer;
|
||||
|
||||
/**
|
||||
* The simulator application is a test harness to facilitate development
|
||||
* and debugging of games.
|
||||
*/
|
||||
public class SimulatorApp
|
||||
{
|
||||
public void start (final String[] args) throws Exception
|
||||
{
|
||||
// create a frame
|
||||
_frame = createSimulatorFrame();
|
||||
|
||||
// create the simulator info object
|
||||
SimulatorInfo siminfo = new SimulatorInfo();
|
||||
siminfo.gameConfigClass = args[0];
|
||||
siminfo.simClass = args[1];
|
||||
siminfo.playerCount = getInt(
|
||||
System.getProperty("playercount"), DEFAULT_PLAYER_COUNT);
|
||||
|
||||
// create our client instance
|
||||
_client = createSimulatorClient(_frame);
|
||||
|
||||
// set up the top-level client controller
|
||||
Controller ctrl = createController(siminfo);
|
||||
_frame.setController(ctrl);
|
||||
|
||||
// create the server
|
||||
SimulatorServer server = createSimulatorServer();
|
||||
server.init(new ResultListener() {
|
||||
public void requestCompleted (Object result) {
|
||||
try {
|
||||
run();
|
||||
} catch (Exception e) {
|
||||
Log.warning("Simulator initialization failed " +
|
||||
"[e=" + e + "].");
|
||||
}
|
||||
}
|
||||
public void requestFailed (Exception e) {
|
||||
Log.warning("Simulator initialization failed [e=" + e + "].");
|
||||
}
|
||||
});
|
||||
|
||||
// run the server on a separate thread
|
||||
_serverThread = new ServerThread(server);
|
||||
// start up the server so that we can be notified when
|
||||
// initialization is complete
|
||||
_serverThread.start();
|
||||
}
|
||||
|
||||
protected SimulatorServer createSimulatorServer ()
|
||||
{
|
||||
return new SimpleServer();
|
||||
}
|
||||
|
||||
protected SimulatorFrame createSimulatorFrame ()
|
||||
{
|
||||
return new SimpleFrame();
|
||||
}
|
||||
|
||||
protected SimulatorClient createSimulatorClient (SimulatorFrame frame)
|
||||
throws Exception
|
||||
{
|
||||
return new SimpleClient(_frame);
|
||||
}
|
||||
|
||||
protected SimulatorController createController (SimulatorInfo siminfo)
|
||||
{
|
||||
return new SimulatorController(
|
||||
_client.getParlorContext(), _frame, siminfo);
|
||||
}
|
||||
|
||||
public void run ()
|
||||
{
|
||||
// configure and display the main frame
|
||||
JFrame frame = _frame.getFrame();
|
||||
frame.setSize(800, 600);
|
||||
SwingUtil.centerWindow(frame);
|
||||
frame.setVisible(true);
|
||||
|
||||
// start up the client
|
||||
Client client = _client.getParlorContext().getClient();
|
||||
Log.info("Connecting to localhost.");
|
||||
client.setServer("localhost", Client.DEFAULT_SERVER_PORTS);
|
||||
|
||||
// we want to exit when we logged off or failed to log on
|
||||
client.addClientObserver(new ClientAdapter() {
|
||||
public void clientFailedToLogon (Client c, Exception cause) {
|
||||
Log.info("Client failed to logon: " + cause);
|
||||
System.exit(0);
|
||||
}
|
||||
public void clientDidLogoff (Client c) {
|
||||
System.exit(0);
|
||||
}
|
||||
});
|
||||
|
||||
// configure the client with some credentials and logon
|
||||
String username = System.getProperty("username");
|
||||
if (username == null) {
|
||||
username =
|
||||
"bob" + ((int)(Math.random() * Integer.MAX_VALUE) % 500);
|
||||
}
|
||||
String password = System.getProperty("password");
|
||||
if (password == null) {
|
||||
password = "test";
|
||||
}
|
||||
|
||||
// create and set our credentials
|
||||
client.setCredentials(
|
||||
new UsernamePasswordCreds(new Name(username), password));
|
||||
|
||||
// this is a bit of a hack, but we need to give the server long
|
||||
// enough to fully initialize and start listening on its socket
|
||||
// before we try to logon; there's no good way for this otherwise
|
||||
// wholly independent thread to wait for the server to be ready as
|
||||
// in normal circumstances they are entirely different processes;
|
||||
// so we just wait half a second which does the job
|
||||
new Interval() {
|
||||
public void expired () {
|
||||
_client.getParlorContext().getClient().logon();
|
||||
}
|
||||
}.schedule(500L);
|
||||
}
|
||||
|
||||
public static void main (String[] args)
|
||||
{
|
||||
if (!checkArgs(args)) {
|
||||
return;
|
||||
}
|
||||
|
||||
SimulatorApp app = new SimulatorApp();
|
||||
try {
|
||||
app.start(args);
|
||||
} catch (Exception e) {
|
||||
Log.warning("Error starting up application.");
|
||||
Log.logStackTrace(e);
|
||||
}
|
||||
}
|
||||
|
||||
protected static boolean checkArgs (String[] args)
|
||||
{
|
||||
if (args.length < 2) {
|
||||
String msg = "Usage:\n" +
|
||||
" java com.threerings.simulator.SimulatorApp " +
|
||||
"<game config class name> <simulant class name>\n" +
|
||||
"Optional properties:\n" +
|
||||
" -Dusername=<user>\n" +
|
||||
" -Dplayercount=<number>\n" +
|
||||
" -Dwidth=<width>\n" +
|
||||
" -Dheight=<height>";
|
||||
System.out.println(msg);
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
protected int getInt (String value, int defval)
|
||||
{
|
||||
try {
|
||||
return Integer.parseInt(value);
|
||||
} catch (NumberFormatException nfe) {
|
||||
return defval;
|
||||
}
|
||||
}
|
||||
|
||||
protected static class ServerThread extends Thread
|
||||
{
|
||||
public ServerThread (SimulatorServer server)
|
||||
{
|
||||
_server = server;
|
||||
}
|
||||
|
||||
public void run ()
|
||||
{
|
||||
_server.run();
|
||||
}
|
||||
|
||||
protected SimulatorServer _server;
|
||||
}
|
||||
|
||||
protected SimulatorClient _client;
|
||||
protected SimulatorFrame _frame;
|
||||
protected ServerThread _serverThread;
|
||||
|
||||
/** The default number of players in the game. */
|
||||
protected static final int DEFAULT_PLAYER_COUNT = 2;
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
//
|
||||
// $Id: SimulatorClient.java 4191 2006-06-13 22:42:20Z ray $
|
||||
//
|
||||
// Narya library - tools for developing networked games
|
||||
// Copyright (C) 2002-2004 Three Rings Design, Inc., All Rights Reserved
|
||||
// http://www.threerings.net/code/narya/
|
||||
//
|
||||
// This library is free software; you can redistribute it and/or modify it
|
||||
// under the terms of the GNU Lesser General Public License as published
|
||||
// by the Free Software Foundation; either version 2.1 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This library is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
// Lesser General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public
|
||||
// License along with this library; if not, write to the Free Software
|
||||
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
package com.threerings.micasa.simulator.client;
|
||||
|
||||
import com.threerings.parlor.util.ParlorContext;
|
||||
|
||||
public interface SimulatorClient
|
||||
{
|
||||
public ParlorContext getParlorContext ();
|
||||
}
|
||||
@@ -0,0 +1,134 @@
|
||||
//
|
||||
// $Id: SimulatorController.java 3381 2005-03-03 19:36:34Z mdb $
|
||||
//
|
||||
// Narya library - tools for developing networked games
|
||||
// Copyright (C) 2002-2004 Three Rings Design, Inc., All Rights Reserved
|
||||
// http://www.threerings.net/code/narya/
|
||||
//
|
||||
// This library is free software; you can redistribute it and/or modify it
|
||||
// under the terms of the GNU Lesser General Public License as published
|
||||
// by the Free Software Foundation; either version 2.1 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This library is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
// Lesser General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public
|
||||
// License along with this library; if not, write to the Free Software
|
||||
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
package com.threerings.micasa.simulator.client;
|
||||
|
||||
import java.awt.event.ActionEvent;
|
||||
import com.samskivert.swing.Controller;
|
||||
|
||||
import com.threerings.presents.client.Client;
|
||||
import com.threerings.presents.client.SessionObserver;
|
||||
|
||||
import com.threerings.crowd.data.BodyObject;
|
||||
|
||||
import com.threerings.parlor.game.data.GameConfig;
|
||||
import com.threerings.parlor.util.ParlorContext;
|
||||
|
||||
import com.threerings.micasa.Log;
|
||||
import com.threerings.micasa.simulator.data.SimulatorInfo;
|
||||
|
||||
/**
|
||||
* Responsible for top-level control of the simulator client user interface.
|
||||
*/
|
||||
public class SimulatorController extends Controller
|
||||
implements SessionObserver
|
||||
{
|
||||
/** Command constant used to logoff the client. */
|
||||
public static final String LOGOFF = "logoff";
|
||||
|
||||
// 577-2028
|
||||
|
||||
/**
|
||||
* Creates a new simulator controller. The controller will set
|
||||
* everything up in preparation for logging on.
|
||||
*/
|
||||
public SimulatorController (ParlorContext ctx, SimulatorFrame frame,
|
||||
SimulatorInfo info)
|
||||
{
|
||||
// we'll want to keep these around
|
||||
_ctx = ctx;
|
||||
_frame = frame;
|
||||
_info = info;
|
||||
|
||||
// we want to know about logon/logoff
|
||||
_ctx.getClient().addClientObserver(this);
|
||||
}
|
||||
|
||||
// documentation inherited
|
||||
public boolean handleAction (ActionEvent action)
|
||||
{
|
||||
String cmd = action.getActionCommand();
|
||||
|
||||
if (cmd.equals(LOGOFF)) {
|
||||
// request that we logoff
|
||||
_ctx.getClient().logoff(true);
|
||||
return true;
|
||||
}
|
||||
|
||||
Log.info("Unhandled action: " + action);
|
||||
return false;
|
||||
}
|
||||
|
||||
// documentation inherited
|
||||
public void clientDidLogon (Client client)
|
||||
{
|
||||
Log.info("Client did logon [client=" + client + "].");
|
||||
|
||||
// keep the body object around for stuff
|
||||
_body = (BodyObject)client.getClientObject();
|
||||
|
||||
// have at it
|
||||
createGame(client);
|
||||
}
|
||||
|
||||
public void createGame (Client client)
|
||||
{
|
||||
GameConfig config = null;
|
||||
try {
|
||||
// create the game config object
|
||||
config = (GameConfig)
|
||||
Class.forName(_info.gameConfigClass).newInstance();
|
||||
|
||||
// get the simulator service and use it to request that our
|
||||
// game be created
|
||||
SimulatorService sservice = (SimulatorService)
|
||||
client.requireService(SimulatorService.class);
|
||||
sservice.createGame(
|
||||
client, config, _info.simClass, _info.playerCount);
|
||||
|
||||
// our work here is done, as the location manager will move us
|
||||
// into the game room straightaway
|
||||
|
||||
} catch (Exception e) {
|
||||
Log.warning("Failed to instantiate game config " +
|
||||
"[class=" + _info.gameConfigClass +
|
||||
", error=" + e + "].");
|
||||
}
|
||||
}
|
||||
|
||||
// documentation inherited
|
||||
public void clientObjectDidChange (Client client)
|
||||
{
|
||||
// regrab our body object
|
||||
_body = (BodyObject)client.getClientObject();
|
||||
}
|
||||
|
||||
// documentation inherited
|
||||
public void clientDidLogoff (Client client)
|
||||
{
|
||||
Log.info("Client did logoff [client=" + client + "].");
|
||||
}
|
||||
|
||||
protected ParlorContext _ctx;
|
||||
protected SimulatorFrame _frame;
|
||||
protected SimulatorInfo _info;
|
||||
protected BodyObject _body;
|
||||
}
|
||||
@@ -0,0 +1,52 @@
|
||||
//
|
||||
// $Id: SimulatorFrame.java 4191 2006-06-13 22:42:20Z ray $
|
||||
//
|
||||
// Narya library - tools for developing networked games
|
||||
// Copyright (C) 2002-2004 Three Rings Design, Inc., All Rights Reserved
|
||||
// http://www.threerings.net/code/narya/
|
||||
//
|
||||
// This library is free software; you can redistribute it and/or modify it
|
||||
// under the terms of the GNU Lesser General Public License as published
|
||||
// by the Free Software Foundation; either version 2.1 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This library is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
// Lesser General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public
|
||||
// License along with this library; if not, write to the Free Software
|
||||
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
package com.threerings.micasa.simulator.client;
|
||||
|
||||
import javax.swing.JFrame;
|
||||
import javax.swing.JPanel;
|
||||
|
||||
import com.samskivert.swing.Controller;
|
||||
import com.samskivert.swing.ControllerProvider;
|
||||
|
||||
/**
|
||||
* Contains the user interface for the Simulator client application.
|
||||
*/
|
||||
public interface SimulatorFrame extends ControllerProvider
|
||||
{
|
||||
/**
|
||||
* Returns a reference to the top-level frame that the simulator will
|
||||
* use to display everything.
|
||||
*/
|
||||
public JFrame getFrame ();
|
||||
|
||||
/**
|
||||
* Sets the panel that makes up the entire client display.
|
||||
*/
|
||||
public void setPanel (JPanel panel);
|
||||
|
||||
/**
|
||||
* Sets the controller for the outermost scope. This controller will
|
||||
* handle all actions that aren't handled by controllers of higher
|
||||
* scope.
|
||||
*/
|
||||
public void setController (Controller controller);
|
||||
}
|
||||
@@ -0,0 +1,44 @@
|
||||
//
|
||||
// $Id: SimulatorService.java 3381 2005-03-03 19:36:34Z mdb $
|
||||
//
|
||||
// Narya library - tools for developing networked games
|
||||
// Copyright (C) 2002-2004 Three Rings Design, Inc., All Rights Reserved
|
||||
// http://www.threerings.net/code/narya/
|
||||
//
|
||||
// This library is free software; you can redistribute it and/or modify it
|
||||
// under the terms of the GNU Lesser General Public License as published
|
||||
// by the Free Software Foundation; either version 2.1 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This library is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
// Lesser General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public
|
||||
// License along with this library; if not, write to the Free Software
|
||||
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
package com.threerings.micasa.simulator.client;
|
||||
|
||||
import com.threerings.presents.client.Client;
|
||||
import com.threerings.presents.client.InvocationService;
|
||||
|
||||
import com.threerings.parlor.game.data.GameConfig;
|
||||
|
||||
/**
|
||||
* Provides access to simulator invocation services.
|
||||
*/
|
||||
public interface SimulatorService extends InvocationService
|
||||
{
|
||||
/**
|
||||
* Requests that a new game be created.
|
||||
*
|
||||
* @param client a connected, operational client instance.
|
||||
* @param config the game config for the game to be created.
|
||||
* @param simClass the class name of the simulant to create.
|
||||
* @param playerCount the number of players in the game.
|
||||
*/
|
||||
public void createGame (Client client, GameConfig config,
|
||||
String simClass, int playerCount);
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
//
|
||||
// $Id: SimulatorInfo.java 4191 2006-06-13 22:42:20Z ray $
|
||||
//
|
||||
// Narya library - tools for developing networked games
|
||||
// Copyright (C) 2002-2004 Three Rings Design, Inc., All Rights Reserved
|
||||
// http://www.threerings.net/code/narya/
|
||||
//
|
||||
// This library is free software; you can redistribute it and/or modify it
|
||||
// under the terms of the GNU Lesser General Public License as published
|
||||
// by the Free Software Foundation; either version 2.1 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This library is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
// Lesser General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public
|
||||
// License along with this library; if not, write to the Free Software
|
||||
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
package com.threerings.micasa.simulator.data;
|
||||
|
||||
public class SimulatorInfo
|
||||
{
|
||||
/** The game config classname. */
|
||||
public String gameConfigClass;
|
||||
|
||||
/** The simulant classname. */
|
||||
public String simClass;
|
||||
|
||||
/** The number of players in the game. */
|
||||
public int playerCount;
|
||||
|
||||
public String toString ()
|
||||
{
|
||||
return "[gameConfigClass=" + gameConfigClass +
|
||||
", simClass=" + simClass + ", playerCount=" + playerCount + "]";
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,51 @@
|
||||
//
|
||||
// $Id: SimulatorMarshaller.java 4145 2006-05-24 01:24:24Z ray $
|
||||
//
|
||||
// Narya library - tools for developing networked games
|
||||
// Copyright (C) 2002-2006 Three Rings Design, Inc., All Rights Reserved
|
||||
// http://www.threerings.net/code/narya/
|
||||
//
|
||||
// This library is free software; you can redistribute it and/or modify it
|
||||
// under the terms of the GNU Lesser General Public License as published
|
||||
// by the Free Software Foundation; either version 2.1 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This library is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
// Lesser General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public
|
||||
// License along with this library; if not, write to the Free Software
|
||||
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
package com.threerings.micasa.simulator.data;
|
||||
|
||||
import com.threerings.micasa.simulator.client.SimulatorService;
|
||||
import com.threerings.parlor.game.data.GameConfig;
|
||||
import com.threerings.presents.client.Client;
|
||||
import com.threerings.presents.data.InvocationMarshaller;
|
||||
import com.threerings.presents.dobj.InvocationResponseEvent;
|
||||
|
||||
/**
|
||||
* Provides the implementation of the {@link SimulatorService} interface
|
||||
* that marshalls the arguments and delivers the request to the provider
|
||||
* on the server. Also provides an implementation of the response listener
|
||||
* interfaces that marshall the response arguments and deliver them back
|
||||
* to the requesting client.
|
||||
*/
|
||||
public class SimulatorMarshaller extends InvocationMarshaller
|
||||
implements SimulatorService
|
||||
{
|
||||
/** The method id used to dispatch {@link #createGame} requests. */
|
||||
public static final int CREATE_GAME = 1;
|
||||
|
||||
// documentation inherited from interface
|
||||
public void createGame (Client arg1, GameConfig arg2, String arg3, int arg4)
|
||||
{
|
||||
sendRequest(arg1, CREATE_GAME, new Object[] {
|
||||
arg2, arg3, Integer.valueOf(arg4)
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,50 @@
|
||||
//
|
||||
// $Id: SimpleServer.java 4191 2006-06-13 22:42:20Z ray $
|
||||
//
|
||||
// Narya library - tools for developing networked games
|
||||
// Copyright (C) 2002-2004 Three Rings Design, Inc., All Rights Reserved
|
||||
// http://www.threerings.net/code/narya/
|
||||
//
|
||||
// This library is free software; you can redistribute it and/or modify it
|
||||
// under the terms of the GNU Lesser General Public License as published
|
||||
// by the Free Software Foundation; either version 2.1 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This library is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
// Lesser General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public
|
||||
// License along with this library; if not, write to the Free Software
|
||||
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
package com.threerings.micasa.simulator.server;
|
||||
|
||||
import com.samskivert.util.ResultListener;
|
||||
|
||||
import com.threerings.micasa.server.MiCasaServer;
|
||||
|
||||
/**
|
||||
* A simple simulator server implementation that extends the MiCasa server
|
||||
* and provides no special functionality.
|
||||
*/
|
||||
public class SimpleServer extends MiCasaServer
|
||||
implements SimulatorServer
|
||||
{
|
||||
// documentation inherited
|
||||
public void init (ResultListener obs)
|
||||
throws Exception
|
||||
{
|
||||
super.init();
|
||||
|
||||
// create the simulator manager
|
||||
SimulatorManager simmgr = new SimulatorManager();
|
||||
simmgr.init(invmgr, plreg, clmgr, omgr, this);
|
||||
|
||||
if (obs != null) {
|
||||
// let the initialization observer know that we've started up
|
||||
obs.requestCompleted(this);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,88 @@
|
||||
//
|
||||
// $Id: Simulant.java 3381 2005-03-03 19:36:34Z mdb $
|
||||
//
|
||||
// Narya library - tools for developing networked games
|
||||
// Copyright (C) 2002-2004 Three Rings Design, Inc., All Rights Reserved
|
||||
// http://www.threerings.net/code/narya/
|
||||
//
|
||||
// This library is free software; you can redistribute it and/or modify it
|
||||
// under the terms of the GNU Lesser General Public License as published
|
||||
// by the Free Software Foundation; either version 2.1 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This library is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
// Lesser General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public
|
||||
// License along with this library; if not, write to the Free Software
|
||||
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
package com.threerings.micasa.simulator.server;
|
||||
|
||||
import com.threerings.presents.dobj.DObjectManager;
|
||||
import com.threerings.presents.dobj.MessageEvent;
|
||||
|
||||
import com.threerings.crowd.data.BodyObject;
|
||||
import com.threerings.crowd.data.PlaceObject;
|
||||
|
||||
import com.threerings.parlor.game.data.GameConfig;
|
||||
import com.threerings.parlor.game.server.GameManager;
|
||||
|
||||
public abstract class Simulant
|
||||
{
|
||||
/**
|
||||
* Initializes the simulant with a body object and the game config for
|
||||
* the game they'll be engaged in.
|
||||
*/
|
||||
public void init (BodyObject self, GameConfig config,
|
||||
GameManager gmgr, DObjectManager omgr)
|
||||
{
|
||||
_self = self;
|
||||
_config = config;
|
||||
_gmgr = gmgr;
|
||||
_omgr = omgr;
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when the simulant is about to enter the room in which it
|
||||
* will be doing all of its business. Default implementation
|
||||
* immediately notifies the game manager that the simulant is ready to
|
||||
* play. Sub-classes may wish to override this to do things like
|
||||
* subscribe to the game object, but should be sure to call this
|
||||
* method when they're finished to give the game manager the go-ahead
|
||||
* to proceed.
|
||||
*/
|
||||
public void willEnterPlace (PlaceObject plobj)
|
||||
{
|
||||
// let the game manager know that the simulant's ready
|
||||
_gmgr.playerReady(_self);
|
||||
}
|
||||
|
||||
/**
|
||||
* Posts the given message event to the server. Since the simulant
|
||||
* resides within the server itself, it has no available client
|
||||
* distributed object manager and so we must set up the source oid
|
||||
* ourselves before sending it on its merry way. Sub-classes should
|
||||
* accordingly be sure to make use of this method to send any
|
||||
* messages.
|
||||
*/
|
||||
protected void postEvent (MessageEvent mevt)
|
||||
{
|
||||
mevt.setSourceOid(_self.getOid());
|
||||
_omgr.postEvent(mevt);
|
||||
}
|
||||
|
||||
/** The game config object. */
|
||||
protected GameConfig _config;
|
||||
|
||||
/** The game manager for the game we're playing. */
|
||||
protected GameManager _gmgr;
|
||||
|
||||
/** Our body object. */
|
||||
protected BodyObject _self;
|
||||
|
||||
/** The object manager with which we're interacting. */
|
||||
protected DObjectManager _omgr;
|
||||
}
|
||||
@@ -0,0 +1,71 @@
|
||||
//
|
||||
// $Id: SimulatorDispatcher.java 4145 2006-05-24 01:24:24Z ray $
|
||||
//
|
||||
// Narya library - tools for developing networked games
|
||||
// Copyright (C) 2002-2006 Three Rings Design, Inc., All Rights Reserved
|
||||
// http://www.threerings.net/code/narya/
|
||||
//
|
||||
// This library is free software; you can redistribute it and/or modify it
|
||||
// under the terms of the GNU Lesser General Public License as published
|
||||
// by the Free Software Foundation; either version 2.1 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This library is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
// Lesser General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public
|
||||
// License along with this library; if not, write to the Free Software
|
||||
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
package com.threerings.micasa.simulator.server;
|
||||
|
||||
import com.threerings.micasa.simulator.client.SimulatorService;
|
||||
import com.threerings.micasa.simulator.data.SimulatorMarshaller;
|
||||
import com.threerings.parlor.game.data.GameConfig;
|
||||
import com.threerings.presents.client.Client;
|
||||
import com.threerings.presents.data.ClientObject;
|
||||
import com.threerings.presents.data.InvocationMarshaller;
|
||||
import com.threerings.presents.server.InvocationDispatcher;
|
||||
import com.threerings.presents.server.InvocationException;
|
||||
|
||||
/**
|
||||
* Dispatches requests to the {@link SimulatorProvider}.
|
||||
*/
|
||||
public class SimulatorDispatcher extends InvocationDispatcher
|
||||
{
|
||||
/**
|
||||
* Creates a dispatcher that may be registered to dispatch invocation
|
||||
* service requests for the specified provider.
|
||||
*/
|
||||
public SimulatorDispatcher (SimulatorProvider provider)
|
||||
{
|
||||
this.provider = provider;
|
||||
}
|
||||
|
||||
// documentation inherited
|
||||
public InvocationMarshaller createMarshaller ()
|
||||
{
|
||||
return new SimulatorMarshaller();
|
||||
}
|
||||
|
||||
// documentation inherited
|
||||
public void dispatchRequest (
|
||||
ClientObject source, int methodId, Object[] args)
|
||||
throws InvocationException
|
||||
{
|
||||
switch (methodId) {
|
||||
case SimulatorMarshaller.CREATE_GAME:
|
||||
((SimulatorProvider)provider).createGame(
|
||||
source,
|
||||
(GameConfig)args[0], (String)args[1], ((Integer)args[2]).intValue()
|
||||
);
|
||||
return;
|
||||
|
||||
default:
|
||||
super.dispatchRequest(source, methodId, args);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,237 @@
|
||||
//
|
||||
// $Id: SimulatorManager.java 3758 2005-11-10 23:18:58Z mdb $
|
||||
//
|
||||
// Narya library - tools for developing networked games
|
||||
// Copyright (C) 2002-2004 Three Rings Design, Inc., All Rights Reserved
|
||||
// http://www.threerings.net/code/narya/
|
||||
//
|
||||
// This library is free software; you can redistribute it and/or modify it
|
||||
// under the terms of the GNU Lesser General Public License as published
|
||||
// by the Free Software Foundation; either version 2.1 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This library is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
// Lesser General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public
|
||||
// License along with this library; if not, write to the Free Software
|
||||
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
package com.threerings.micasa.simulator.server;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
import com.threerings.util.Name;
|
||||
|
||||
import com.threerings.presents.data.ClientObject;
|
||||
import com.threerings.presents.dobj.RootDObjectManager;
|
||||
import com.threerings.presents.server.ClientManager;
|
||||
import com.threerings.presents.server.ClientResolutionListener;
|
||||
import com.threerings.presents.server.InvocationManager;
|
||||
|
||||
import com.threerings.crowd.data.BodyObject;
|
||||
import com.threerings.crowd.data.PlaceObject;
|
||||
import com.threerings.crowd.server.PlaceManager;
|
||||
import com.threerings.crowd.server.PlaceRegistry.CreationObserver;
|
||||
import com.threerings.crowd.server.PlaceRegistry;
|
||||
|
||||
import com.threerings.parlor.game.data.GameAI;
|
||||
import com.threerings.parlor.game.data.GameConfig;
|
||||
import com.threerings.parlor.game.data.GameObject;
|
||||
import com.threerings.parlor.game.server.GameManager;
|
||||
|
||||
import com.threerings.micasa.Log;
|
||||
|
||||
/**
|
||||
* The simulator manager is responsible for handling the simulator
|
||||
* services on the server side.
|
||||
*/
|
||||
public class SimulatorManager
|
||||
{
|
||||
/**
|
||||
* Initializes the simulator manager manager. This should be called by
|
||||
* the server that is making use of the simulator services on the
|
||||
* single instance of simulator manager that it has created.
|
||||
*
|
||||
* @param invmgr a reference to the invocation manager in use by this
|
||||
* server.
|
||||
*/
|
||||
public void init (InvocationManager invmgr, PlaceRegistry plreg,
|
||||
ClientManager clmgr, RootDObjectManager omgr,
|
||||
SimulatorServer simserv)
|
||||
{
|
||||
// register our simulator provider
|
||||
SimulatorProvider sprov = new SimulatorProvider(this);
|
||||
invmgr.registerDispatcher(new SimulatorDispatcher(sprov), true);
|
||||
|
||||
// keep these for later
|
||||
_plreg = plreg;
|
||||
_clmgr = clmgr;
|
||||
_omgr = omgr;
|
||||
_simserv = simserv;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a game along with the specified number of simulant players
|
||||
* and forcibly moves all players into the game room.
|
||||
*/
|
||||
public void createGame (
|
||||
BodyObject source, GameConfig config, String simClass, int playerCount)
|
||||
{
|
||||
new CreateGameTask(source, config, simClass, playerCount);
|
||||
}
|
||||
|
||||
public class CreateGameTask implements CreationObserver
|
||||
{
|
||||
public CreateGameTask (
|
||||
BodyObject source, GameConfig config, String simClass,
|
||||
int playerCount)
|
||||
{
|
||||
// save off game request info
|
||||
_source = source;
|
||||
_config = config;
|
||||
_simClass = simClass;
|
||||
_playerCount = playerCount;
|
||||
|
||||
try {
|
||||
// create the game manager and begin its initialization
|
||||
// process. the game manager will take care of notifying
|
||||
// the players that the game has been created once it has
|
||||
// been started up (which is done by the place registry
|
||||
// once the game object creation has completed)
|
||||
|
||||
// configure the game config with the player names
|
||||
config.players = new Name[_playerCount];
|
||||
config.players[0] = _source.getVisibleName();
|
||||
for (int ii = 1; ii < _playerCount; ii++) {
|
||||
config.players[ii] = new Name("simulant" + ii);
|
||||
}
|
||||
|
||||
// we needn't hang around and wait for game object
|
||||
// creation if it's just us
|
||||
CreationObserver obs = (_playerCount == 1) ? null : this;
|
||||
_gmgr = (GameManager)_plreg.createPlace(config, obs);
|
||||
|
||||
} catch (Exception e) {
|
||||
Log.warning("Unable to create game manager [e=" + e + "].");
|
||||
Log.logStackTrace(e);
|
||||
}
|
||||
}
|
||||
|
||||
// documentation inherited
|
||||
public void placeCreated (PlaceObject place, PlaceManager pmgr)
|
||||
{
|
||||
// cast the place to the game object for the game we're creating
|
||||
_gobj = (GameObject)place;
|
||||
|
||||
// determine the AI player skill level
|
||||
byte skill;
|
||||
try {
|
||||
skill = Byte.parseByte(System.getProperty("skill"));
|
||||
} catch (NumberFormatException nfe) {
|
||||
skill = DEFAULT_SKILL;
|
||||
}
|
||||
|
||||
for (int ii = 1; ii < _playerCount; ii++) {
|
||||
// mark all simulants as AI players
|
||||
_gmgr.setAI(ii, new GameAI(0, skill));
|
||||
}
|
||||
|
||||
// resolve the simulant body objects
|
||||
ClientResolutionListener listener = new ClientResolutionListener()
|
||||
{
|
||||
public void clientResolved (Name username, ClientObject clobj)
|
||||
{
|
||||
// hold onto the body object for later game creation
|
||||
_sims.add(clobj);
|
||||
|
||||
// create the game if we've received all body objects
|
||||
if (_sims.size() == (_playerCount - 1)) {
|
||||
createSimulants();
|
||||
}
|
||||
}
|
||||
|
||||
public void resolutionFailed (Name username, Exception cause)
|
||||
{
|
||||
Log.warning("Unable to create simulant body object " +
|
||||
"[error=" + cause + "].");
|
||||
}
|
||||
};
|
||||
|
||||
// resolve client objects for all of our simulants
|
||||
for (int ii = 1; ii < _playerCount; ii++) {
|
||||
Name username = new Name("simulant" + ii);
|
||||
_clmgr.resolveClientObject(username, listener);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when all simulant body objects are present and the
|
||||
* simulants are ready to be created.
|
||||
*/
|
||||
protected void createSimulants ()
|
||||
{
|
||||
// finish setting up the simulants
|
||||
for (int ii = 1; ii < _playerCount; ii++) {
|
||||
// create the simulant object
|
||||
Simulant sim;
|
||||
try {
|
||||
sim = (Simulant)Class.forName(_simClass).newInstance();
|
||||
} catch (Exception e) {
|
||||
Log.warning("Unable to create simulant " +
|
||||
"[class=" + _simClass + "].");
|
||||
return;
|
||||
}
|
||||
|
||||
// give the simulant its body
|
||||
BodyObject bobj = (BodyObject)_sims.get(ii - 1);
|
||||
sim.init(bobj, _config, _gmgr, _omgr);
|
||||
|
||||
// give the simulant a chance to engage in place antics
|
||||
sim.willEnterPlace(_gobj);
|
||||
|
||||
// move the simulant into the game room since they have no
|
||||
// location director to move them automagically
|
||||
try {
|
||||
_plreg.locprov.moveTo(bobj, _gobj.getOid());
|
||||
} catch (Exception e) {
|
||||
Log.warning("Failed to move simulant into room " +
|
||||
"[e=" + e + "].");
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/** The simulant body objects. */
|
||||
protected ArrayList _sims = new ArrayList();
|
||||
|
||||
/** The game object for the game being created. */
|
||||
protected GameObject _gobj;
|
||||
|
||||
/** The game manager for the game being created. */
|
||||
protected GameManager _gmgr;
|
||||
|
||||
/** The number of players in the game. */
|
||||
protected int _playerCount;
|
||||
|
||||
/** The simulant class instantiated on game creation. */
|
||||
protected String _simClass;
|
||||
|
||||
/** The game config object. */
|
||||
protected GameConfig _config;
|
||||
|
||||
/** The body object of the player requesting the game creation. */
|
||||
protected BodyObject _source;
|
||||
}
|
||||
|
||||
// needed for general operation
|
||||
protected PlaceRegistry _plreg;
|
||||
protected ClientManager _clmgr;
|
||||
protected RootDObjectManager _omgr;
|
||||
protected SimulatorServer _simserv;
|
||||
|
||||
/** The default skill level for AI players. */
|
||||
protected static final byte DEFAULT_SKILL = 50;
|
||||
}
|
||||
@@ -0,0 +1,62 @@
|
||||
//
|
||||
// $Id: SimulatorProvider.java 3381 2005-03-03 19:36:34Z mdb $
|
||||
//
|
||||
// Narya library - tools for developing networked games
|
||||
// Copyright (C) 2002-2004 Three Rings Design, Inc., All Rights Reserved
|
||||
// http://www.threerings.net/code/narya/
|
||||
//
|
||||
// This library is free software; you can redistribute it and/or modify it
|
||||
// under the terms of the GNU Lesser General Public License as published
|
||||
// by the Free Software Foundation; either version 2.1 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This library is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
// Lesser General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public
|
||||
// License along with this library; if not, write to the Free Software
|
||||
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
package com.threerings.micasa.simulator.server;
|
||||
|
||||
import com.threerings.presents.data.ClientObject;
|
||||
import com.threerings.presents.server.InvocationProvider;
|
||||
|
||||
import com.threerings.crowd.data.BodyObject;
|
||||
import com.threerings.parlor.game.data.GameConfig;
|
||||
|
||||
import com.threerings.micasa.Log;
|
||||
|
||||
/**
|
||||
* The simulator provider handles game creation requests on the server
|
||||
* side, passing them off to the {@link SimulatorManager}.
|
||||
*/
|
||||
public class SimulatorProvider
|
||||
implements InvocationProvider
|
||||
{
|
||||
/**
|
||||
* Constructs a simulator provider.
|
||||
*/
|
||||
public SimulatorProvider (SimulatorManager simmgr)
|
||||
{
|
||||
_simmgr = simmgr;
|
||||
}
|
||||
|
||||
/**
|
||||
* Processes a request from the client to create a new game.
|
||||
*/
|
||||
public void createGame (ClientObject caller, GameConfig config,
|
||||
String simClass, int playerCount)
|
||||
{
|
||||
Log.info("handleCreateGameRequest [caller=" + caller.who() +
|
||||
", config=" + config + ", simClass=" + simClass +
|
||||
", playerCount=" + playerCount + "].");
|
||||
|
||||
_simmgr.createGame((BodyObject)caller, config, simClass, playerCount);
|
||||
}
|
||||
|
||||
/** The simulator manager. */
|
||||
protected SimulatorManager _simmgr;
|
||||
}
|
||||
@@ -0,0 +1,49 @@
|
||||
//
|
||||
// $Id: SimulatorServer.java 4191 2006-06-13 22:42:20Z ray $
|
||||
//
|
||||
// Narya library - tools for developing networked games
|
||||
// Copyright (C) 2002-2004 Three Rings Design, Inc., All Rights Reserved
|
||||
// http://www.threerings.net/code/narya/
|
||||
//
|
||||
// This library is free software; you can redistribute it and/or modify it
|
||||
// under the terms of the GNU Lesser General Public License as published
|
||||
// by the Free Software Foundation; either version 2.1 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This library is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
// Lesser General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public
|
||||
// License along with this library; if not, write to the Free Software
|
||||
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
package com.threerings.micasa.simulator.server;
|
||||
|
||||
import com.samskivert.util.ResultListener;
|
||||
|
||||
/**
|
||||
* The simulator manager needs a mechanism for faking body object
|
||||
* registrations, which is provided by implementations of this interface.
|
||||
*/
|
||||
public interface SimulatorServer
|
||||
{
|
||||
/**
|
||||
* Called to initialize this server instance.
|
||||
*
|
||||
* @param obs the observer to notify when the server has finished
|
||||
* starting up, or <code>null</code> if no notification is desired.
|
||||
*
|
||||
* @exception Exception thrown if anything goes wrong initializing the
|
||||
* server.
|
||||
*/
|
||||
public void init (ResultListener obs) throws Exception;
|
||||
|
||||
/**
|
||||
* Called to perform the main body of server processing. This is
|
||||
* called from the server thread and should do the simulator server's
|
||||
* primary business.
|
||||
*/
|
||||
public void run ();
|
||||
}
|
||||
@@ -0,0 +1,44 @@
|
||||
//
|
||||
// $Id: SimulatorContext.java 4191 2006-06-13 22:42:20Z ray $
|
||||
//
|
||||
// Narya library - tools for developing networked games
|
||||
// Copyright (C) 2002-2004 Three Rings Design, Inc., All Rights Reserved
|
||||
// http://www.threerings.net/code/narya/
|
||||
//
|
||||
// This library is free software; you can redistribute it and/or modify it
|
||||
// under the terms of the GNU Lesser General Public License as published
|
||||
// by the Free Software Foundation; either version 2.1 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This library is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
// Lesser General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public
|
||||
// License along with this library; if not, write to the Free Software
|
||||
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
package com.threerings.micasa.simulator.util;
|
||||
|
||||
import com.threerings.parlor.util.ParlorContext;
|
||||
|
||||
import com.threerings.micasa.simulator.client.SimulatorFrame;
|
||||
import com.threerings.micasa.simulator.data.SimulatorInfo;
|
||||
|
||||
/**
|
||||
* The simulator context encapsulates the contexts of all of the services
|
||||
* that are used by the simulator client so that we can pass around one
|
||||
* single context implementation that provides all of the necessary
|
||||
* components to all of the services in use.
|
||||
*/
|
||||
public interface SimulatorContext
|
||||
extends ParlorContext
|
||||
{
|
||||
/** Returns a reference to the primary user interface frame. */
|
||||
public SimulatorFrame getFrame ();
|
||||
|
||||
/** Returns a reference to the simulator info describing the game and
|
||||
* other details of the simulation. */
|
||||
public SimulatorInfo getSimulatorInfo ();
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
//
|
||||
// $Id: MiCasaContext.java 4191 2006-06-13 22:42:20Z ray $
|
||||
//
|
||||
// Narya library - tools for developing networked games
|
||||
// Copyright (C) 2002-2004 Three Rings Design, Inc., All Rights Reserved
|
||||
// http://www.threerings.net/code/narya/
|
||||
//
|
||||
// This library is free software; you can redistribute it and/or modify it
|
||||
// under the terms of the GNU Lesser General Public License as published
|
||||
// by the Free Software Foundation; either version 2.1 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This library is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
// Lesser General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public
|
||||
// License along with this library; if not, write to the Free Software
|
||||
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
package com.threerings.micasa.util;
|
||||
|
||||
import com.threerings.util.MessageManager;
|
||||
import com.threerings.parlor.util.ParlorContext;
|
||||
import com.threerings.micasa.client.MiCasaFrame;
|
||||
|
||||
/**
|
||||
* The micasa context encapsulates the contexts of all of the services
|
||||
* that are used by the micasa client so that we can pass around one
|
||||
* single context implementation that provides all of the necessary
|
||||
* components to all of the services in use.
|
||||
*/
|
||||
public interface MiCasaContext
|
||||
extends ParlorContext
|
||||
{
|
||||
/** Returns a reference to the primary user interface frame. This can
|
||||
* be used to set the top-level panel when we enter a game, etc. */
|
||||
public MiCasaFrame getFrame ();
|
||||
|
||||
/**
|
||||
* Returns a reference to the message manager used by the client to
|
||||
* generate localized messages.
|
||||
*/
|
||||
public MessageManager getMessageManager ();
|
||||
}
|
||||
Reference in New Issue
Block a user