From 9d2505c115b0accadead5fdc4620253a441a43d5 Mon Sep 17 00:00:00 2001 From: Michael Bayne Date: Wed, 20 Apr 2005 22:30:19 +0000 Subject: [PATCH] Added a simple chat server test framework onto which I will built a JME-based client. git-svn-id: svn+ssh://src.earth.threerings.net/narya/trunk@3512 542714f4-19e9-0310-aa3c-eee0fc999fb1 --- .../threerings/crowd/client/JabberApp.java | 109 ++++++++ .../threerings/crowd/client/JabberClient.java | 238 ++++++++++++++++++ .../crowd/client/JabberController.java | 17 ++ .../threerings/crowd/client/JabberPanel.java | 40 +++ .../threerings/crowd/data/JabberConfig.java | 26 ++ .../threerings/crowd/server/JabberServer.java | 45 ++++ 6 files changed, 475 insertions(+) create mode 100644 tests/src/java/com/threerings/crowd/client/JabberApp.java create mode 100644 tests/src/java/com/threerings/crowd/client/JabberClient.java create mode 100644 tests/src/java/com/threerings/crowd/client/JabberController.java create mode 100644 tests/src/java/com/threerings/crowd/client/JabberPanel.java create mode 100644 tests/src/java/com/threerings/crowd/data/JabberConfig.java create mode 100644 tests/src/java/com/threerings/crowd/server/JabberServer.java diff --git a/tests/src/java/com/threerings/crowd/client/JabberApp.java b/tests/src/java/com/threerings/crowd/client/JabberApp.java new file mode 100644 index 000000000..2ea9cc86b --- /dev/null +++ b/tests/src/java/com/threerings/crowd/client/JabberApp.java @@ -0,0 +1,109 @@ +// +// $Id: JabberApp.java 3098 2004-08-27 02:12:55Z 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.crowd.client; + +import java.io.IOException; +import javax.swing.JFrame; + +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.crowd.Log; + +/** + * The main point of entry for the Jabber client application. It creates + * and initializes the myriad components of the client and sets all the + * proper wheels in motion. + */ +public class JabberApp +{ + public void init () + throws IOException + { + // create a frame + _frame = new JFrame("Jabber Client"); + + // initialize our client instance + _client = new JabberClient(); + _client.init(_frame); + } + + public void run (String server, int port, 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(); + + // pass them on to the client + Log.info("Using [server=" + server + ", port=" + port + "]."); + client.setServer(server, port); + + // 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]; + } + + int port = Client.DEFAULT_SERVER_PORT; + if (args.length > 1) { + try { + port = Integer.parseInt(args[1]); + } catch (NumberFormatException nfe) { + Log.warning("Invalid port specification '" + args[1] + "'."); + } + } + + String username = (args.length > 2) ? args[2] : null; + String password = (args.length > 3) ? args[3] : null; + + JabberApp app = new JabberApp(); + try { + // initialize the app + app.init(); + } catch (IOException ioe) { + Log.warning("Error initializing application."); + Log.logStackTrace(ioe); + } + + // and run it + app.run(server, port, username, password); + } + + protected JabberClient _client; + protected JFrame _frame; +} diff --git a/tests/src/java/com/threerings/crowd/client/JabberClient.java b/tests/src/java/com/threerings/crowd/client/JabberClient.java new file mode 100644 index 000000000..35c621014 --- /dev/null +++ b/tests/src/java/com/threerings/crowd/client/JabberClient.java @@ -0,0 +1,238 @@ +// +// $Id: JabberClient.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.crowd.client; + +import java.awt.BorderLayout; +import java.awt.EventQueue; +import java.awt.event.WindowAdapter; +import java.awt.event.WindowEvent; +import java.io.IOException; +import javax.swing.JFrame; +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.client.SessionObserver; +import com.threerings.presents.dobj.DObjectManager; + +import com.threerings.crowd.chat.client.ChatDirector; +import com.threerings.crowd.util.CrowdContext; + +/** + * The Jabber 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 JabberClient + implements RunQueue, SessionObserver +{ + /** + * Initializes a new client and provides it with a frame in which to + * display everything. + */ + public void init (JFrame 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", 4007); + _client.addClientObserver(this); + + // 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); + } + } + }); + } + + /** + * Returns a reference to the context in effect for this client. This + * reference is valid for the lifetime of the application. + */ + public CrowdContext getContext () + { + return _ctx; + } + + // documentation inherited from interface SessionObserver + public void clientDidLogon (Client client) + { + // enter the one and only chat room; giant hack warning: we know + // that the place we're headed to is ID 2 because there's only one + // place on the whole server; a normal client would either issue + // an invocation service request at this point or look at + // something in the BootstrapData to figure out what to do + _ctx.getLocationDirector().moveTo(2); + } + + // documentation inherited from interface SessionObserver + public void clientObjectDidChange (Client client) + { + // nada + } + + // documentation inherited from interface SessionObserver + public void clientDidLogoff (Client client) + { + System.exit(0); + } + + /** + * Creates the {@link JabberContext} 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 CrowdContext createContextImpl () + { + return new JabberContextImpl(); + } + + /** + * 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 + * super.createContextServices. + */ + 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); + _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 JabberContextImpl implements CrowdContext + { + /** + * 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 JabberContextImpl () + { + } + + 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 void setPlaceView (PlaceView view) + { + JPanel panel = (JPanel)view; + // remove the old panel + _frame.getContentPane().removeAll(); + // add the new one + _frame.getContentPane().add(panel, BorderLayout.CENTER); + // swing doesn't properly repaint after adding/removing children + panel.revalidate(); + _frame.repaint(); + } + + public void clearPlaceView (PlaceView view) + { + // we'll just let the next place view replace our old one + } + } + + protected CrowdContext _ctx; + protected JFrame _frame; + protected Config _config = new Config("jabber"); + + protected Client _client; + protected LocationDirector _locdir; + protected OccupantDirector _occdir; + protected ChatDirector _chatdir; + 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"; +} diff --git a/tests/src/java/com/threerings/crowd/client/JabberController.java b/tests/src/java/com/threerings/crowd/client/JabberController.java new file mode 100644 index 000000000..dc449a839 --- /dev/null +++ b/tests/src/java/com/threerings/crowd/client/JabberController.java @@ -0,0 +1,17 @@ +// +// $Id$ + +package com.threerings.crowd.client; + +import com.threerings.crowd.util.CrowdContext; + +/** + * Handles the basic bits for our simple chat room. + */ +public class JabberController extends PlaceController +{ + protected PlaceView createPlaceView (CrowdContext ctx) + { + return new JabberPanel(ctx); + } +} diff --git a/tests/src/java/com/threerings/crowd/client/JabberPanel.java b/tests/src/java/com/threerings/crowd/client/JabberPanel.java new file mode 100644 index 000000000..0fb474ee2 --- /dev/null +++ b/tests/src/java/com/threerings/crowd/client/JabberPanel.java @@ -0,0 +1,40 @@ +// +// $Id$ + +package com.threerings.crowd.client; + +import java.awt.BorderLayout; +import javax.swing.JPanel; + +import com.threerings.crowd.data.PlaceObject; +import com.threerings.crowd.util.CrowdContext; + +import com.threerings.micasa.client.ChatPanel; +import com.threerings.micasa.client.OccupantList; + +/** + * Displays a simple chat view. + */ +public class JabberPanel extends JPanel + implements PlaceView +{ + public JabberPanel (CrowdContext ctx) + { + _ctx = ctx; + setLayout(new BorderLayout()); + add(new ChatPanel(ctx), BorderLayout.CENTER); + add(new OccupantList(ctx), BorderLayout.EAST); + } + + // documentation inherited from interface PlaceView + public void willEnterPlace (PlaceObject plobj) + { + } + + // documentation inherited from interface PlaceView + public void didLeavePlace (PlaceObject plobj) + { + } + + protected CrowdContext _ctx; +} diff --git a/tests/src/java/com/threerings/crowd/data/JabberConfig.java b/tests/src/java/com/threerings/crowd/data/JabberConfig.java new file mode 100644 index 000000000..8c424a486 --- /dev/null +++ b/tests/src/java/com/threerings/crowd/data/JabberConfig.java @@ -0,0 +1,26 @@ +// +// $Id$ + +package com.threerings.crowd.data; + +import com.threerings.crowd.client.JabberController; +import com.threerings.crowd.data.PlaceConfig; + +/** + * Defines the necessary bits for our chat room. + */ +public class JabberConfig extends PlaceConfig +{ + // documentation inherited + public Class getControllerClass () + { + return JabberController.class; + } + + // documentation inherited + public String getManagerClassName () + { + // nothing special needed on the server side + return "com.threerings.crowd.server.PlaceManager"; + } +} diff --git a/tests/src/java/com/threerings/crowd/server/JabberServer.java b/tests/src/java/com/threerings/crowd/server/JabberServer.java new file mode 100644 index 000000000..3403a9465 --- /dev/null +++ b/tests/src/java/com/threerings/crowd/server/JabberServer.java @@ -0,0 +1,45 @@ +// +// $Id$ + +package com.threerings.crowd.server; + +import com.threerings.crowd.Log; +import com.threerings.crowd.data.JabberConfig; +import com.threerings.crowd.data.PlaceObject; + +/** + * A basic server that creates a single room and sticks everyone in it + * where they can chat with one another. + */ +public class JabberServer extends CrowdServer +{ + // documentation inherited + public void init () + throws Exception + { + super.init(); + + // create a single location + plreg.createPlace( + new JabberConfig(), new PlaceRegistry.CreationObserver() { + public void placeCreated (PlaceObject place, PlaceManager pmgr) { + Log.info("Created chat room " + pmgr.where() + "."); + _place = pmgr; + } + }); + } + + public static void main (String[] args) + { + JabberServer server = new JabberServer(); + try { + server.init(); + server.run(); + } catch (Exception e) { + Log.warning("Unable to initialize server."); + Log.logStackTrace(e); + } + } + + protected PlaceManager _place; +}