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:
Michael Bayne
2006-06-23 17:58:11 +00:00
commit a4df87e52f
317 changed files with 45818 additions and 0 deletions
@@ -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 ();
}